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