2011-10-02 4 views
5

Tôi đang cố gắng sử dụng LsaLogonUser để tạo phiên đăng nhập tương tác, nhưng nó luôn trả về STATUS_INVALID_INFO_CLASS (0xc0000003). Từ những gì tôi đã tìm thấy trong việc tìm kiếm trực tuyến, bố cục bộ nhớ của cấu trúc KERB_INTERACTIVE_LOGON là khó khăn, nhưng tôi khá chắc chắn rằng tôi đã làm điều đó đúng.Làm thế nào để tôi gọi LsaLogonUser một cách chính xác cho một đăng nhập tương tác?

Tôi cũng đã thử sử dụng MSV1.0 thay vì Kerberos, với MSV1_0_INTERACTIVE_LOGON cho cấu trúc xác thực và MSV1_0_PACKAGE_NAME làm tên gói nhưng không thành công với STATUS_BAD_VALIDATION_CLASS (0xc00000a7).

Có ai biết tôi đang làm gì sai ở đây không? Đây là mã, với hầu hết các lỗi xử lý bị tước. Rõ ràng đây không phải là chất lượng sản xuất; Tôi chỉ cố gắng lấy mẫu làm việc.


// 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; 
} 

Trả lời

6

Bạn đã đăng ký một trong các tham số cho LsaLogonUser(); thay vì &authInfo bạn chỉ nên vượt qua authInfo. Xảy ra cho tất cả mọi người :)

+1

Ouch, thật là một sai lầm ngu ngốc. Nó hoạt động chính xác khi tôi sửa nó - cảm ơn! – Charlie