Hello,
I'm building an Authentication Package for Windows and I'm now just trying to make a skeleton for the package that I'm going to build.
The Package at some point in time will need to call MSV1_0 but the workflow of my authentication is forbidding me from implementing it as a SubAuthentication Package for MSV1_0.
Now, please examine this code snippet:
NTSTATUS NTAPI
LsaApLogonUserEx2(
__in PLSA_CLIENT_REQUEST ClientRequest,
__in SECURITY_LOGON_TYPE LogonType,
__in PVOID AuthenticationInformation,
__in PVOID ClientAuthenticationBase,
__in ULONG AuthenticationInformationLength,
__out PVOID *ProfileBuffer,
__out PULONG ProfileBufferLength,
__out PLUID LogonId,
__out PNTSTATUS SubStatus,
__out PLSA_TOKEN_INFORMATION_TYPE TokenInformationType,
__out PVOID *TokenInformation,
__out PUNICODE_STRING *AccountName,
__out PUNICODE_STRING *AuthenticatingAuthority,
__out PUNICODE_STRING *MachineName,
__out PSECPKG_PRIMARY_CRED PrimaryCredentials,
__out PSECPKG_SUPPLEMENTAL_CRED_ARRAY *SupplementaryCredentials
)
{
LsaApLogonUserEx2Proc LsaApLogonUserEx2Ref;
UNICODE_STRING puszUserName, puszPassword, puszDomain;
PMSV1_0_INTERACTIVE_LOGON milMSVInteractiveLogonBuffer = NULL;
NTSTATUS nstInnerCallStatus;
DWORD dwAuthInfoSize = 0;
LsaApLogonUserEx2Ref = (LsaApLogonUserEx2Proc)GetProcAddress(hMsvLibraryHandle, "LsaApLogonUserEx2");
if(LsaApLogonUserEx2Ref == NULL) {
TraceWrite(TEXT("Failed to load LsaApLogonUserEx2 procedure address"));
return STATUS_UNSUCCESSFUL;
} else {
TraceWrite(TEXT("LsaApLogonUserEx2 procedure loaded successfully"));
dwAuthInfoSize = (sizeof(MSV1_0_INTERACTIVE_LOGON)+ (3*sizeof(WCHAR)) + (11 * sizeof(WCHAR)) + (10 * sizeof(WCHAR)));
milMSVInteractiveLogonBuffer = (PMSV1_0_INTERACTIVE_LOGON)pLsaTable->AllocateLsaHeap(dwAuthInfoSize);
milMSVInteractiveLogonBuffer->MessageType = MsV1_0InteractiveLogon;
milMSVInteractiveLogonBuffer->UserName.Length = (2*sizeof(WCHAR));
milMSVInteractiveLogonBuffer->UserName.MaximumLength = (3*sizeof(WCHAR));
milMSVInteractiveLogonBuffer->UserName.Buffer = (PWSTR)(milMSVInteractiveLogonBuffer + 1);
wcscpy(milMSVInteractiveLogonBuffer->UserName.Buffer, L"a8");
milMSVInteractiveLogonBuffer->LogonDomainName.Length = (9 * sizeof(WCHAR));
milMSVInteractiveLogonBuffer->LogonDomainName.MaximumLength = (10 * sizeof(WCHAR));
milMSVInteractiveLogonBuffer->LogonDomainName.Buffer = (PWSTR)
((PBYTE)milMSVInteractiveLogonBuffer->UserName.Buffer) + milMSVInteractiveLogonBuffer->UserName.MaximumLength;
wcscpy(milMSVInteractiveLogonBuffer->LogonDomainName.Buffer, L"dev-8-PC");
milMSVInteractiveLogonBuffer->Password.Length = (10 * sizeof(WCHAR));
milMSVInteractiveLogonBuffer->Password.MaximumLength = (11 * sizeof(WCHAR));
milMSVInteractiveLogonBuffer->Password.Buffer = (PWSTR)
((PBYTE)(milMSVInteractiveLogonBuffer->LogonDomainName.Buffer) + milMSVInteractiveLogonBuffer->LogonDomainName.MaximumLength);
wcscpy(milMSVInteractiveLogonBuffer->Password.Buffer, L"wr9!-8lTqE");
TraceWrite(TEXT("LsaApLogonUserEx2: strings initialized"));
nstInnerCallStatus = LsaApLogonUserEx2Ref(
ClientRequest,
LogonType,
&milMSVInteractiveLogonBuffer,
ClientAuthenticationBase,
dwAuthInfoSize,
ProfileBuffer,
ProfileBufferLength,
LogonId,
SubStatus,
TokenInformationType,
TokenInformation,
AccountName,
AuthenticatingAuthority,
MachineName,
PrimaryCredentials,
SupplementaryCredentials);
//TODO: free this memory leak..
TraceWrite(TEXT("LsaApLogonUserEx2 returned: %u"), nstInnerCallStatus);
TraceWrite(TEXT("LsaApLogonUserEx2 returned(win32): %u"), LsaNtStatusToWinError(nstInnerCallStatus));
return nstInnerCallStatus;
}
}
Dispite the code being one big miserable hack, it should at least work, as it's just a wrapper around MSV1_0. In the package I'm implementing the rest of functions that MSV1_0 exports and each function just calls the MSV1_0 relative procedure.
The problem is, that this package fails and the error code is 1348 - STATUS_BAD_VALIDATION_CLASS.
Could anybody explain for me why is that happening? or what I'm doing wrong with here?
Thanks in advance!