私はLsaLogonUserを使用して対話型ログオンセッションを作成しようとしていますが、常にSTATUS_INVALID_INFO_CLASS
(0xc0000003)を返します。私がオンラインで検索したところから、KERB_INTERACTIVE_LOGON
構造のメモリレイアウトは難しいですが、私はそれを正しく行ったと確信しています。対話型ログオンのためにLsaLogonUserを正しく呼び出すにはどうすればよいですか?
私はまた、パッケージ名などの認証構造のためMSV1_0_INTERACTIVE_LOGON
とMSV1_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;
}
愚かな間違い。私はそれを修正したときに正しく動作しました - ありがとう! – Charlie