/// <summary> /// Get a Kerberos Ticket. /// </summary> /// <param name="target_name">The target service for the Ticket.</param> /// <param name="cached_only">True to only query for cached tickets.</param> /// <param name="throw_on_error">True to throw on error.</param> /// <returns>The Kerberos Ticket.</returns> public static NtResult <KerberosExternalTicket> GetTicket(string target_name, bool cached_only, bool throw_on_error) { using (var handle = SafeLsaLogonHandle.Connect(throw_on_error)) { if (!handle.IsSuccess) { return(handle.Cast <KerberosExternalTicket>()); } Luid luid = NtToken.PseudoEffectiveToken.AuthenticationId; KERB_RETRIEVE_TICKET_FLAGS flags = cached_only ? KERB_RETRIEVE_TICKET_FLAGS.UseCacheOnly : KERB_RETRIEVE_TICKET_FLAGS.Default; return(QueryCachedTicket(handle.Result, target_name, flags, luid, new SecHandle(), throw_on_error)); } }
private static NtResult <KerberosExternalTicket> QueryCachedTicket(SafeLsaLogonHandle handle, string target_name, KERB_RETRIEVE_TICKET_FLAGS flags, Luid logon_id, SecHandle sec_handle, bool throw_on_error) { var package = handle.LookupAuthPackage(AuthenticationPackage.KERBEROS_NAME, throw_on_error); if (!package.IsSuccess) { return(package.Cast <KerberosExternalTicket>()); } using (var buffer = QueryCachedTicket(handle, package.Result, target_name, flags, logon_id, sec_handle, throw_on_error)) { if (!buffer.IsSuccess) { return(buffer.Cast <KerberosExternalTicket>()); } KERB_EXTERNAL_TICKET ticket = buffer.Result.Read <KERB_EXTERNAL_TICKET>(0); if (!KerberosExternalTicket.TryParse(ticket, out KerberosExternalTicket ret)) { return(NtStatus.STATUS_INVALID_PARAMETER.CreateResultFromError <KerberosExternalTicket>(throw_on_error)); } return(ret.CreateResult()); } }
private static NtResult <SafeLsaReturnBufferHandle> QueryCachedTicket(SafeLsaLogonHandle handle, uint auth_package, string target_name, KERB_RETRIEVE_TICKET_FLAGS flags, Luid logon_id, SecHandle sec_handle, bool throw_on_error) { int string_length = (target_name.Length) * 2; int max_string_length = string_length + 2; using (var request = new SafeStructureInOutBuffer <KERB_RETRIEVE_TKT_REQUEST>(max_string_length, true)) { request.Data.WriteUnicodeString(target_name + '\0'); var request_str = new KERB_RETRIEVE_TKT_REQUEST() { CacheOptions = flags, CredentialsHandle = sec_handle, LogonId = logon_id, MessageType = KERB_PROTOCOL_MESSAGE_TYPE.KerbRetrieveEncodedTicketMessage, TargetName = new UnicodeStringOut() { Length = (ushort)string_length, MaximumLength = (ushort)max_string_length, Buffer = request.Data.DangerousGetHandle() } }; request.Result = request_str; using (var result = handle.CallPackage(auth_package, request, throw_on_error)) { if (!result.IsSuccess) { return(result.Cast <SafeLsaReturnBufferHandle>()); } if (!result.Result.Status.IsSuccess()) { return(result.Result.Status.CreateResultFromError <SafeLsaReturnBufferHandle>(throw_on_error)); } return(result.Result.Buffer.Detach().CreateResult()); } } }