Как мне правильно вызвать LsaLogonUser для интерактивного входа в систему?

#windows #windows-security #local-security-authority

#Windows #windows-безопасность #local-security-authority

Вопрос:

Я пытаюсь использовать LsaLogonUser для создания сеанса интерактивного входа в систему, но он всегда возвращает STATUS_INVALID_INFO_CLASS (0xc0000003). Из того, что я нашел при поиске в Интернете, структура KERB_INTERACTIVE_LOGON структуры в памяти сложная, но я уверен, что все сделал правильно.

Я также пытался использовать MSV1.0 вместо Kerberos, MSV1_0_INTERACTIVE_LOGON для структуры аутентификации и MSV1_0_PACKAGE_NAME в качестве имени пакета, но это не удается с STATUS_BAD_VALIDATION_CLASS (0xc00000a7).

Кто-нибудь может сказать, что я здесь делаю не так? Вот код, из которого удалена большая часть обработки ошибок. Очевидно, что это не соответствует производственному качеству; Я просто пытаюсь получить рабочий образец.

 
// see below for definitions of these
size_t wcsByteLen( const wchar_t* str );
void InitUnicodeString( UNICODE_STRINGamp; str, const wchar_t* value, BYTE* buffer, size_tamp; offset );

int main( int argc, char * argv[] )
{
    // connect to the LSA
    HANDLE lsa;
    LsaConnectUntrusted( amp;lsa );

    const wchar_t* domain = L"mydomain";
    const wchar_t* user = L"someuser";
    const wchar_t* password = L"scaryplaintextpassword";

    // prepare the authentication info
    ULONG authInfoSize = sizeof(KERB_INTERACTIVE_LOGON)  
     wcsByteLen( domain )   wcsByteLen( user )   wcsByteLen( password );
    BYTE* authInfoBuf = new BYTE[authInfoSize];
    KERB_INTERACTIVE_LOGON* authInfo = (KERB_INTERACTIVE_LOGON*)authInfoBuf;
    authInfo->MessageType = KerbInteractiveLogon;
    size_t offset = sizeof(KERB_INTERACTIVE_LOGON);
    InitUnicodeString( authInfo->LogonDomainName, domain, authInfoBuf, offset );
    InitUnicodeString( authInfo->UserName, user, authInfoBuf, offset );
    InitUnicodeString( authInfo->Password, password, authInfoBuf, offset );

    // find the Kerberos security package
    char packageNameRaw[] = MICROSOFT_KERBEROS_NAME_A;
    LSA_STRING packageName;
    packageName.Buffer = packageNameRaw;
    packageName.Length = packageName.MaximumLength = (USHORT)strlen( packageName.Buffer );
    ULONG packageId;
    LsaLookupAuthenticationPackage( lsa, amp;packageName, amp;packageId );

    // create a dummy origin and token source
    LSA_STRING origin = {};
    origin.Buffer = _strdup( "TestAppFoo" );
    origin.Length = (USHORT)strlen( origin.Buffer );
    origin.MaximumLength = origin.Length;
    TOKEN_SOURCE source = {};
    strcpy( source.SourceName, "foobar" );
    AllocateLocallyUniqueId( amp;source.SourceIdentifier );

    void* profileBuffer;
    DWORD profileBufLen;
    LUID luid;
    HANDLE token;
    QUOTA_LIMITS qlimits;
    NTSTATUS subStatus;
    NTSTATUS status = LsaLogonUser( lsa, amp;origin, Interactive, packageId,
     amp;authInfo, authInfoSize, 0, amp;source, amp;profileBuffer, amp;profileBufLen,
     amp;luid, amp;token, amp;qlimits, amp;subStatus );
    if( status != ERROR_SUCCESS )
    {
        ULONG err = LsaNtStatusToWinError( status );
        printf( "LsaLogonUser failed: %xn", status );
        return 1;
    }
}

size_t wcsByteLen( const wchar_t* str )
{
    return wcslen( str ) * sizeof(wchar_t);
}

void InitUnicodeString( UNICODE_STRINGamp; str, const wchar_t* value,
 BYTE* buffer, size_tamp; offset )
{
    size_t size = wcsByteLen( value );
    str.Length = str.MaximumLength = (USHORT)size;
    str.Buffer = (PWSTR)(buffer   offset);
    memcpy( str.Buffer, value, size );
    offset  = size;
}
  

Ответ №1:

Вы ошиблись с одним из параметров в LsaLogonUser(); вместо amp;authInfo этого вы должны передать just authInfo . Случается со всеми 🙂

Комментарии:

1. Ой, какая глупая ошибка. Он работал правильно, когда я это исправил — спасибо!