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());
            }
        }
        /// <summary>
        /// Logon a user.
        /// </summary>
        /// <param name="type">The type of logon.</param>
        /// <param name="auth_package">The authentication package to use.</param>
        /// <param name="origin_name">The name of the origin.</param>
        /// <param name="source_context">The token source context.</param>
        /// <param name="buffer">The authentication credentials buffer.</param>
        /// <param name="local_groups">Additional local groups.</param>
        /// <param name="throw_on_error">True to throw on error.</param>
        /// <returns>The LSA logon result.</returns>
        public NtResult <LsaLogonResult> LsaLogonUser(SecurityLogonType type, string auth_package, string origin_name,
                                                      TokenSource source_context, SafeBuffer buffer, IEnumerable <UserGroup> local_groups, bool throw_on_error)
        {
            using (var list = new DisposableList())
            {
                var auth_pkg = _handle.LookupAuthPackage(auth_package, throw_on_error);
                if (!auth_pkg.IsSuccess)
                {
                    return(auth_pkg.Cast <LsaLogonResult>());
                }

                var groups = local_groups == null ? SafeTokenGroupsBuffer.Null
                    : list.AddResource(SafeTokenGroupsBuffer.Create(local_groups));

                QUOTA_LIMITS quota_limits = new QUOTA_LIMITS();
                return(SecurityNativeMethods.LsaLogonUser(_handle, new LsaString(origin_name),
                                                          type, auth_pkg.Result, buffer, buffer.GetLength(), groups,
                                                          source_context, out SafeLsaReturnBufferHandle profile,
                                                          out int cbProfile, out Luid logon_id, out SafeKernelObjectHandle token_handle,
                                                          quota_limits, out NtStatus subStatus).CreateResult(throw_on_error, () =>
                {
                    profile.InitializeLength(cbProfile);
                    return new LsaLogonResult(NtToken.FromHandle(token_handle), profile, logon_id, quota_limits);
                }));
            }
        }
        private static NtResult <KerberosTicketCacheInfo[]> QueryTicketCacheList(SafeLsaLogonHandle handle, Luid logon_id, bool throw_on_error)
        {
            var package = handle.LookupAuthPackage(AuthenticationPackage.KERBEROS_NAME, throw_on_error);

            if (!package.IsSuccess)
            {
                return(package.Cast <KerberosTicketCacheInfo[]>());
            }
            var request_struct = new KERB_QUERY_TKT_CACHE_REQUEST()
            {
                LogonId     = logon_id,
                MessageType = KERB_PROTOCOL_MESSAGE_TYPE.KerbQueryTicketCacheMessage
            };

            using (var request = request_struct.ToBuffer())
            {
                using (var result = handle.CallPackage(package.Result, request, throw_on_error))
                {
                    if (!result.IsSuccess)
                    {
                        return(result.Cast <KerberosTicketCacheInfo[]>());
                    }
                    if (!result.Result.Status.IsSuccess())
                    {
                        return(result.Result.Status.CreateResultFromError <KerberosTicketCacheInfo[]>(throw_on_error));
                    }
                    var response = result.Result.Buffer.Read <KERB_QUERY_TKT_CACHE_RESPONSE_HEADER>(0);
                    if (response.CountOfTickets == 0)
                    {
                        return(new KerberosTicketCacheInfo[0].CreateResult());
                    }
                    var buffer = BufferUtils.GetStructAtOffset <KERB_QUERY_TKT_CACHE_RESPONSE>(result.Result.Buffer, 0);
                    KERB_TICKET_CACHE_INFO[] infos = new KERB_TICKET_CACHE_INFO[response.CountOfTickets];
                    buffer.Data.ReadArray(0, infos, 0, response.CountOfTickets);
                    return(infos.Select(i => new KerberosTicketCacheInfo(i)).ToArray().CreateResult());
                }
            }
        }