⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 credapi.cxx

📁 安全支持提供器接口(SSPI)源码
💻 CXX
📖 第 1 页 / 共 3 页
字号:
    }

    //
    // Copy over the authorization data into out address
    // space and make a local copy of the strings.
    //


    if (AuthorizationData != NULL)
    {
        pAuthIdentityEx = (PSEC_WINNT_AUTH_IDENTITY_EXW) NtLmAllocate(sizeof(SEC_WINNT_AUTH_IDENTITY_EXW));


        if (pAuthIdentityEx != NULL)
        {
            Status = LsaFunctions->CopyFromClientBuffer(
                        NULL,
                        sizeof(SEC_WINNT_AUTH_IDENTITY),
                        pAuthIdentityEx,
                        AuthorizationData);

            if (!NT_SUCCESS(Status))
            {
                SspPrint((SSP_CRITICAL,"SpAcquireCredentialsHandle, Error from LsaFunctions->CopyFromClientBuffer is 0x%lx\n", Status));
                goto Cleanup;
            }
        }
        else
        {
            Status = STATUS_INSUFFICIENT_RESOURCES;
            SspPrint((SSP_CRITICAL,"SpAcquireCredentialsHandle, Error from NtLmAllocate is 0x%lx\n", Status));
            goto Cleanup;
        }

        //
        // Check for the ex version
        //

        if (pAuthIdentityEx->Version == SEC_WINNT_AUTH_IDENTITY_VERSION)
        {
            Status = LsaFunctions->CopyFromClientBuffer(
                        NULL,
                        sizeof(SEC_WINNT_AUTH_IDENTITY_EXW),
                        pAuthIdentityEx,
                        AuthorizationData);

            if (!NT_SUCCESS(Status))
            {
                SspPrint((SSP_CRITICAL,"SpAcquireCredentialsHandle, Error from LsaFunctions->CopyFromClientBuffer is 0x%lx\n", Status));
                goto Cleanup;
            }
            pAuthIdentity = (PSEC_WINNT_AUTH_IDENTITY) &pAuthIdentityEx->User;
            CredSize = pAuthIdentityEx->Length;
            Offset = FIELD_OFFSET(SEC_WINNT_AUTH_IDENTITY_EXW, User);
        }
        else
        {
            pAuthIdentity = (PSEC_WINNT_AUTH_IDENTITY_W) pAuthIdentityEx;
            CredSize = sizeof(SEC_WINNT_AUTH_IDENTITY_W);
        }

        if ((pAuthIdentity->Flags & SEC_WINNT_AUTH_IDENTITY_ANSI) != 0)
        {
            DoUnicode = FALSE;
            //
            // Turn off the marshalled flag because we don't support marshalling
            // with ansi.
            //

            pAuthIdentity->Flags &= ~SEC_WINNT_AUTH_IDENTITY_MARSHALLED;
        }
        else if ((pAuthIdentity->Flags & SEC_WINNT_AUTH_IDENTITY_UNICODE) == 0)
        {
            Status = SEC_E_INVALID_TOKEN;
            SspPrint((SSP_CRITICAL,"SpAcquireCredentialsHandle, Error from pAuthIdentity->Flags is 0x%lx\n", pAuthIdentity->Flags));
            goto Cleanup;
        }

        // This is the only place where we can figure out whether null
        // session was requested

        if ((pAuthIdentity->UserLength == 0) &&
            (pAuthIdentity->DomainLength == 0) &&
            (pAuthIdentity->PasswordLength == 0) &&
            (pAuthIdentity->User != NULL) &&
            (pAuthIdentity->Domain != NULL) &&
            (pAuthIdentity->Password != NULL))
        {
            NewCredentialUseFlags |= NTLM_CRED_NULLSESSION;
        }

        //
        // Copy over the strings
        //
        if( (pAuthIdentity->Flags & SEC_WINNT_AUTH_IDENTITY_MARSHALLED) != 0 ) {
            ULONG TmpCredentialSize;
            ULONG_PTR EndOfCreds;
            ULONG_PTR TmpUser;
            ULONG_PTR TmpDomain;
            ULONG_PTR TmpPassword;

            if( pAuthIdentity->UserLength > UNLEN ||
                pAuthIdentity->PasswordLength > PWLEN ||
                pAuthIdentity->DomainLength > DNS_MAX_NAME_LENGTH ) {

                SspPrint((SSP_CRITICAL,"Supplied credentials illegal length.\n"));
                Status = STATUS_INVALID_PARAMETER;
                goto Cleanup;
            }

            //
            // The callers can set the length of field to n chars, but they
            // will really occupy n+1 chars (null-terminator).
            //

            TmpCredentialSize = CredSize +
                             (  pAuthIdentity->UserLength +
                                pAuthIdentity->DomainLength +
                                pAuthIdentity->PasswordLength +
                             (((pAuthIdentity->User != NULL) ? 1 : 0) +
                             ((pAuthIdentity->Domain != NULL) ? 1 : 0) +
                             ((pAuthIdentity->Password != NULL) ? 1 : 0)) ) * sizeof(WCHAR);

            EndOfCreds = (ULONG_PTR) AuthorizationData + TmpCredentialSize;

            //
            // Verify that all the offsets are valid and no overflow will happen
            //

            TmpUser = (ULONG_PTR) pAuthIdentity->User;

            if ((TmpUser != NULL) &&
                ( (TmpUser < (ULONG_PTR) AuthorizationData) ||
                  (TmpUser > EndOfCreds) ||
                  ((TmpUser + (pAuthIdentity->UserLength) * sizeof(WCHAR)) > EndOfCreds ) ||
                  ((TmpUser + (pAuthIdentity->UserLength * sizeof(WCHAR))) < TmpUser)))
            {
                SspPrint((SSP_CRITICAL,"Username in supplied credentials has invalid pointer or length.\n"));
                Status = STATUS_INVALID_PARAMETER;
                goto Cleanup;
            }

            TmpDomain = (ULONG_PTR) pAuthIdentity->Domain;

            if ((TmpDomain != NULL) &&
                ( (TmpDomain < (ULONG_PTR) AuthorizationData) ||
                  (TmpDomain > EndOfCreds) ||
                  ((TmpDomain + (pAuthIdentity->DomainLength) * sizeof(WCHAR)) > EndOfCreds ) ||
                  ((TmpDomain + (pAuthIdentity->DomainLength * sizeof(WCHAR))) < TmpDomain)))
            {
                SspPrint((SSP_CRITICAL,"Domainname in supplied credentials has invalid pointer or length.\n"));
                Status = STATUS_INVALID_PARAMETER;
                goto Cleanup;
            }

            TmpPassword = (ULONG_PTR) pAuthIdentity->Password;

            if ((TmpPassword != NULL) &&
                ( (TmpPassword < (ULONG_PTR) AuthorizationData) ||
                  (TmpPassword > EndOfCreds) ||
                  ((TmpPassword + (pAuthIdentity->PasswordLength) * sizeof(WCHAR)) > EndOfCreds ) ||
                  ((TmpPassword + (pAuthIdentity->PasswordLength * sizeof(WCHAR))) < TmpPassword)))
            {
                SspPrint((SSP_CRITICAL,"Password in supplied credentials has invalid pointer or length.\n"));
                Status = STATUS_INVALID_PARAMETER;
                goto Cleanup;
            }

            //
            // Allocate a chunk of memory for the credentials
            //

            TmpCredentials = (PSEC_WINNT_AUTH_IDENTITY_W) NtLmAllocate(TmpCredentialSize - Offset);
            if (TmpCredentials == NULL)
            {
                Status = STATUS_INSUFFICIENT_RESOURCES;
                goto Cleanup;
            }

            //
            // Copy the credentials from the client
            //

            Status = LsaFunctions->CopyFromClientBuffer(
                        NULL,
                        TmpCredentialSize - Offset,
                        TmpCredentials,
                        (PUCHAR) AuthorizationData + Offset
                        );
            if (!NT_SUCCESS(Status))
            {
                SspPrint((SSP_CRITICAL,"Failed to copy whole auth identity\n"));
                goto Cleanup;
            }

            //
            // Now convert all the offsets to pointers.
            //

            if (TmpCredentials->User != NULL)
            {
                USHORT cbUser;

                TmpCredentials->User = (LPWSTR) RtlOffsetToPointer(
                                                TmpCredentials->User,
                                                (PUCHAR) TmpCredentials - (PUCHAR) AuthorizationData - Offset
                                                );

                ASSERT( (TmpCredentials->UserLength*sizeof(WCHAR)) <= 0xFFFF );

                cbUser = (USHORT)(TmpCredentials->UserLength * sizeof(WCHAR));
                UserName.Buffer = (PWSTR)NtLmAllocate( cbUser );

                if (UserName.Buffer == NULL ) {
                    Status = STATUS_INSUFFICIENT_RESOURCES;
                    goto Cleanup;
                }

                CopyMemory( UserName.Buffer, TmpCredentials->User, cbUser );
                UserName.Length = cbUser;
                UserName.MaximumLength = cbUser;
            }

            if (TmpCredentials->Domain != NULL)
            {
                USHORT cbDomain;

                TmpCredentials->Domain = (LPWSTR) RtlOffsetToPointer(
                                                    TmpCredentials->Domain,
                                                    (PUCHAR) TmpCredentials - (PUCHAR) AuthorizationData - Offset
                                                    );

                ASSERT( (TmpCredentials->DomainLength*sizeof(WCHAR)) <= 0xFFFF );
                cbDomain = (USHORT)(TmpCredentials->DomainLength * sizeof(WCHAR));
                DomainName.Buffer = (PWSTR)NtLmAllocate( cbDomain );

                if (DomainName.Buffer == NULL ) {
                    Status = STATUS_INSUFFICIENT_RESOURCES;
                    goto Cleanup;
                }

                CopyMemory( DomainName.Buffer, TmpCredentials->Domain, cbDomain );
                DomainName.Length = cbDomain;
                DomainName.MaximumLength = cbDomain;
            }

            if (TmpCredentials->Password != NULL)
            {
                USHORT cbPassword;

                TmpCredentials->Password = (LPWSTR) RtlOffsetToPointer(
                                                    TmpCredentials->Password,
                                                    (PUCHAR) TmpCredentials - (PUCHAR) AuthorizationData - Offset
                                                    );


                ASSERT( (TmpCredentials->PasswordLength*sizeof(WCHAR)) <= 0xFFFF );
                cbPassword = (USHORT)(TmpCredentials->PasswordLength * sizeof(WCHAR));
                Password.Buffer = (PWSTR)NtLmAllocate( cbPassword );

                if (Password.Buffer == NULL ) {
                    ZeroMemory( TmpCredentials->Password, cbPassword );
                    Status = STATUS_INSUFFICIENT_RESOURCES;
                    goto Cleanup;
                }

                CopyMemory( Password.Buffer, TmpCredentials->Password, cbPassword );
                Password.Length = cbPassword;
                Password.MaximumLength = cbPassword;

                ZeroMemory( TmpCredentials->Password, cbPassword );
            }


        } else {

            if (pAuthIdentity->Password != NULL)
            {
                Status = CopyClientString(
                                pAuthIdentity->Password,
                                pAuthIdentity->PasswordLength,
                                DoUnicode,
                                &Password
                                );
                if (!NT_SUCCESS(Status))
                {
                    SspPrint((SSP_CRITICAL,"SpAcquireCredentialsHandle, Error from CopyClientString is 0x%lx\n", Status));
                    goto Cleanup;
                }

            }

            if (pAuthIdentity->User != NULL)
            {
                Status = CopyClientString(
                                pAuthIdentity->User,
                                pAuthIdentity->UserLength,
                                DoUnicode,
                                &UserName
                                );
                if (!NT_SUCCESS(Status))
                {
                    SspPrint((SSP_CRITICAL, "SpAcquireCredentialsHandle, Error from CopyClientString is 0x%lx\n", Status));
                    goto Cleanup;
                }

            }

            if (pAuthIdentity->Domain != NULL)
            {
                Status = CopyClientString(
                                pAuthIdentity->Domain,
                                pAuthIdentity->DomainLength,
                                DoUnicode,
                                &DomainName
                                );
                if (!NT_SUCCESS(Status))
                {
                    SspPrint((SSP_CRITICAL, "SpAcquireCredentialsHandle, Error from CopyClientString is 0x%lx\n", Status));
                    goto Cleanup;
                }

                //
                // Make sure that the domain name length is not greater
                // than the allowed dns domain name
                //

                if (DomainName.Length > DNS_MAX_NAME_LENGTH * sizeof(WCHAR))
                {
                    SspPrint((SSP_CRITICAL, "SpAcquireCredentialsHandle: Invalid supplied domain name %wZ\n",
                        &DomainName ));
                    Status = SEC_E_UNKNOWN_CREDENTIALS;
                    goto Cleanup;
                }

            }
        }
    }   // AuthorizationData != NULL

    Status = SsprAcquireCredentialHandle(
                                &TokenHandle,
                                LogonIdToUse,
                                ClientInfo.ProcessID,
                                NewCredentialUseFlags,
                                CredentialHandle,
                                ExpirationTime,
                                &DomainName,
                                &UserName,
                                &Password );

    if (!NT_SUCCESS(Status))
    {
        SspPrint((SSP_CRITICAL, "SpAcquireCredentialsHandle, Error from SsprAcquireCredentialsHandle is 0x%lx\n", Status));
        goto Cleanup;
    }

//  These will be kept in the Credential structure and freed
//  when the Credential structure is freed

    if (DomainName.Buffer != NULL)
    {
        DomainName.Buffer = NULL;
    }

    if (UserName.Buffer != NULL)
    {
        UserName.Buffer = NULL;
    }

    if (Password.Buffer != NULL)
    {
        Password.Buffer = NULL;
    }

Cleanup:

    if (TmpCredentials != NULL)
    {
        NtLmFree(TmpCredentials);
    }

    if (DomainName.Buffer != NULL)
    {
        NtLmFree(DomainName.Buffer);
    }

    if (UserName.Buffer != NULL)
    {
        NtLmFree(UserName.Buffer);
    }

    if (Password.Buffer != NULL)
    {
        ZeroMemory(Password.Buffer, Password.Length);
        NtLmFree(Password.Buffer);
    }

    if ( TokenHandle != NULL)
    {
        (VOID) NtClose(TokenHandle);
    }
    if (pAuthIdentityEx != NULL)
    {
        NtLmFree(pAuthIdentityEx);
    }

    SspPrint((SSP_API, "Leaving SpAcquireCredentialsHandle, Status is %d\n", Status));
    return(SspNtStatusToSecStatus(Status, SEC_E_INTERNAL_ERROR));
}


//+-------------------------------------------------------------------------
//
//  Function:   SpFreeCredentialsHandle
//
//  Synopsis:   Frees a credential created by AcquireCredentialsHandle.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -