static extern NtStatus LsaLogonUser(SafeLsaHandle LsaHandle, LsaString OriginName, SecurityLogonType LogonType, uint AuthenticationPackage,
                                     SafeBuffer AuthenticationInformation,
                                     int AuthenticationInformationLength,
                                     IntPtr LocalGroups,
                                     TOKEN_SOURCE SourceContext,
                                     out IntPtr ProfileBuffer,
                                     out int ProfileBufferLength,
                                     out Luid LogonId,
                                     out SafeKernelObjectHandle Token,
                                     QUOTA_LIMITS Quotas,
                                     out NtStatus SubStatus
                                     );
 static extern bool LogonUserExExW(
     string lpszUsername,
     string lpszDomain,
     string lpszPassword,
     SecurityLogonType dwLogonType,
     int dwLogonProvider,
     TokenGroups pTokenGroups,
     out SafeKernelObjectHandle phToken,
     [Out] OptionalPointer ppLogonSid,
     [Out] OptionalPointer ppProfileBuffer,
     [Out] OptionalPointer pdwProfileLength,
     [Out] QUOTA_LIMITS pQuotaLimits
     );
        public static NtToken LogonS4U(string user, string realm, SecurityLogonType type)
        {
            SafeLsaHandle hlsa    = null;
            LsaString     pkgName = new LsaString("Negotiate");

            LsaConnectUntrusted(out hlsa).ToNtException();
            using (hlsa)
            {
                uint authnPkg;
                LsaLookupAuthenticationPackage(hlsa, pkgName, out authnPkg).ToNtException();
                byte[] user_bytes  = Encoding.Unicode.GetBytes(user);
                byte[] realm_bytes = Encoding.Unicode.GetBytes(realm);

                using (var buffer = new SafeStructureInOutBuffer <KERB_S4U_LOGON>(user_bytes.Length + realm_bytes.Length, true))
                {
                    KERB_S4U_LOGON logon_struct = new KERB_S4U_LOGON();
                    logon_struct.MessageType = KERB_LOGON_SUBMIT_TYPE.KerbS4ULogon;
                    SafeHGlobalBuffer data_buffer = buffer.Data;

                    logon_struct.ClientUpn.Buffer = data_buffer.DangerousGetHandle();
                    data_buffer.WriteArray(0, user_bytes, 0, user_bytes.Length);
                    logon_struct.ClientUpn.Length        = (ushort)user_bytes.Length;
                    logon_struct.ClientUpn.MaximumLength = (ushort)user_bytes.Length;

                    logon_struct.ClientRealm.Buffer = data_buffer.DangerousGetHandle() + user_bytes.Length;
                    data_buffer.WriteArray((ulong)user_bytes.Length, realm_bytes, 0, realm_bytes.Length);
                    logon_struct.ClientRealm.Length        = (ushort)realm_bytes.Length;
                    logon_struct.ClientRealm.MaximumLength = (ushort)realm_bytes.Length;

                    Marshal.StructureToPtr(logon_struct, buffer.DangerousGetHandle(), false);

                    TOKEN_SOURCE tokenSource = new TOKEN_SOURCE("NtLmSsp");
                    AllocateLocallyUniqueId(out tokenSource.SourceIdentifier);

                    LsaString              originName = new LsaString("S4U");
                    IntPtr                 profile;
                    int                    cbProfile;
                    Luid                   logon_id;
                    NtStatus               subStatus;
                    QUOTA_LIMITS           quota_limits = new QUOTA_LIMITS();
                    SafeKernelObjectHandle token_handle;

                    LsaLogonUser(hlsa, originName, type, authnPkg,
                                 buffer, buffer.Length, IntPtr.Zero,
                                 tokenSource, out profile, out cbProfile, out logon_id, out token_handle,
                                 quota_limits, out subStatus).ToNtException();
                    LsaFreeReturnBuffer(profile);
                    return(NtToken.FromHandle(token_handle));
                }
            }
        }