Inori
Inori

Reputation: 31

How to correctly call LsaLogonUser in C#?

I get 87(ERROR_INVALID_PARAMETER) when calling LsaLogonUser in C#. I tried found where I'm doing wrong but the error is too vague. Please tell me where is the mistake.

Function definition generated by CsWin32:

internal static unsafe NTSTATUS LsaLogonUser(
    SafeHandle LsaHandle, 
    in LSA_STRING OriginName, 
    SECURITY_LOGON_TYPE LogonType, 
    uint AuthenticationPackage, 
    void* AuthenticationInformation, 
    uint AuthenticationInformationLength, 
    TOKEN_GROUPS* LocalGroups, 
    in TOKEN_SOURCE SourceContext, 
    out void* ProfileBuffer, 
    out uint ProfileBufferLength, 
    ref LUID LogonId, 
    out SafeFileHandle Token, 
    out QUOTA_LIMITS Quotas, 
    out int SubStatus)

Calling:

  public static unsafe void CallLsaLogonUser()
  {
    const string MICROSOFT_KERBEROS_NAME_A = "Kerberos";
    const string
      logonProcessName = "processName",
      sourceName = "12345678",
      domain = ".",
      username = "username",
      password = "password"
      ;

    NTSTATUS ntStatus;

    EnableSeTcbPrivilege(); // The definition of this function isn't included

    var lsaLogonProcessName = CreateLsaString(logonProcessName);

    ntStatus = PInvoke.LsaRegisterLogonProcess(lsaLogonProcessName, out var logonProcess, out var securityMode);
    if (ntStatus != NTSTATUS.STATUS_SUCCESS)
    {
      var winErr = PInvoke.LsaNtStatusToWinError(ntStatus);
      Log.Error($"LsaRegisterLogonProcess: {winErr}");
      return;
    }

    var authInfo = new KERB_INTERACTIVE_LOGON
    {
      LogonDomainName = CreateLsaUnicodeString(domain),
      UserName = CreateLsaUnicodeString(username),
      Password = CreateLsaUnicodeString(password),
      MessageType = KERB_LOGON_SUBMIT_TYPE.KerbInteractiveLogon
    };
    var authInfoLength = Marshal.SizeOf(authInfo) + Encoding.Unicode.GetByteCount(domain + username + password);

    var lsaAuthPackageName = CreateLsaString(MICROSOFT_KERBEROS_NAME_A);
    var sourceNameList = sourceName.Select(item => new CHAR((sbyte)item)).ToArray();
    PInvoke.AllocateLocallyUniqueId(out var sourceId);
    var tokenSource = new TOKEN_SOURCE
    {
      SourceName = new __CHAR_8
      {
        _0 = sourceNameList[0],
        _1 = sourceNameList[1],
        _2 = sourceNameList[2],
        _3 = sourceNameList[3],
        _4 = sourceNameList[4],
        _5 = sourceNameList[5],
        _6 = sourceNameList[6],
        _7 = sourceNameList[7],
      },
      SourceIdentifier = sourceId
    };

    var logonId = new LUID();

    ntStatus = PInvoke.LsaLookupAuthenticationPackage(logonProcess, lsaAuthPackageName, out var authPackage);
    if (ntStatus != NTSTATUS.STATUS_SUCCESS)
    {
      var winErr = PInvoke.LsaNtStatusToWinError(ntStatus);
      Log.Error($"LsaLookupAuthenticationPackage: {winErr}");
      return;
    }

    ntStatus = PInvoke.LsaLogonUser(
      logonProcess,
      lsaLogonProcessName,
      SECURITY_LOGON_TYPE.Interactive,
      authPackage,
      &authInfo,
      (uint)authInfoLength,
      null,
      tokenSource,
      out var pProfileBuffer,
      out var profileBufferLength,
      ref logonId,
      out var userToken,
      out var quotas,
      out var subStatus
    );

    if (ntStatus == NTSTATUS.STATUS_SUCCESS)
    {
      Log.Information("LOGON SUCCESS");
    }
    else
    {
      var winErr = PInvoke.LsaNtStatusToWinError(ntStatus);
      Log.Error($"LsaLogonUser: {winErr}");
      return;
    }

    return;
    
    LSA_STRING CreateLsaString(string value)
    {
      var pstr = new PSTR(Marshal.StringToHGlobalAnsi(value));
      return new LSA_STRING
      {
        Buffer = pstr,
        Length = (ushort)pstr.Length,
        MaximumLength = (ushort)pstr.Length,
      };
    }

    LSA_UNICODE_STRING CreateLsaUnicodeString(string value)
    {
      var pwstr = new PWSTR(Marshal.StringToHGlobalAnsi(value));
      return new LSA_UNICODE_STRING
      {
        Buffer = pwstr,
        Length = (ushort)pwstr.Length,
        MaximumLength = (ushort)pwstr.Length,
      };
    }
  }

Upvotes: 0

Views: 58

Answers (0)

Related Questions