2011-10-02 13 views
5

私はLsaLogonUserを使用して対話型ログオンセッションを作成しようとしていますが、常にSTATUS_INVALID_INFO_CLASS(0xc0000003)を返します。私がオンラインで検索したところから、KERB_INTERACTIVE_LOGON構造のメモリレイアウトは難しいですが、私はそれを正しく行ったと確信しています。対話型ログオンのためにLsaLogonUserを正しく呼び出すにはどうすればよいですか?

私はまた、パッケージ名などの認証構造のためMSV1_0_INTERACTIVE_LOGONMSV1_0_PACKAGE_NAMEで、代わりにケルベロスのMSV1.0を使用して試してみたが、それはSTATUS_BAD_VALIDATION_CLASS(0xc00000a7)で失敗します。

誰でも私がここで間違っていることを伝えることはできますか?ここでコードがありますが、エラー処理のほとんどは取り除かれています。明らかに、これは生産品質ではありません。私はちょうど実際のサンプルを取得しようとしています。


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

int main(int argc, char * argv[]) 
{ 
    // connect to the LSA 
    HANDLE lsa; 
    LsaConnectUntrusted(&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, &packageName, &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(&source.SourceIdentifier); 

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

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

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

答えて

6

あなたはLsaLogonUser()のパラメータの1つを覚えています。 &authInfoの代わりにちょうどauthInfoを渡す必要があります。誰にも起こります:)

+1

愚かな間違い。私はそれを修正したときに正しく動作しました - ありがとう! – Charlie