views:

15

answers:

0

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!