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

📄 credapi.cxx

📁 安全支持提供器接口(SSPI)源码
💻 CXX
📖 第 1 页 / 共 3 页
字号:
//+-----------------------------------------------------------------------
//
// Microsoft Windows
//
// Copyright (c) Microsoft Corporation 1992 - 1996
//
// File:        credapi.cxx
//
// Contents:    Code for credentials APIs for the NtLm package
//              Main entry points into this dll:
//                SpAcceptCredentials
//                SpAcquireCredentialsHandle
//                SpFreeCredentialsHandle
//                SpQueryCredentialsAttributes
//                SpSaveCredentials
//                SpGetCredentials
//                SpDeleteCredentials
//
//              Helper functions:
//                CopyClientString
//
// History:     ChandanS   26-Jul-1996   Stolen from kerberos\client2\credapi.cxx
//
//------------------------------------------------------------------------
#define NTLM_CREDAPI
#include <global.h>
extern "C"
{
// BUGBUG Move to a header

NTSTATUS
SspAcceptCredentials(
    IN SECURITY_LOGON_TYPE LogonType,
    IN PSECPKG_PRIMARY_CRED PrimaryCredentials,
    IN PSECPKG_SUPPLEMENTAL_CRED SupplementalCredentials
    );


#include <nlp.h>

}



//+-------------------------------------------------------------------------
//
//  Function:   CopyClientString
//
//  Synopsis:   copies a client string to local memory, including
//              allocating space for it locally.
//
//  Arguments:
//              SourceString  - Could be Oem or Wchar in client process
//              SourceLength  - bytes
//              DoUnicode     - whether the string is Wchar
//
//  Returns:
//              DestinationString - Unicode String in Lsa Process
//
//  Notes:
//
//--------------------------------------------------------------------------
HRESULT
CopyClientString(
    IN PWSTR SourceString,
    IN ULONG SourceLength,
    IN BOOLEAN DoUnicode,
    OUT PUNICODE_STRING DestinationString
    )
{
    SspPrint((SSP_API_MORE,"Entering CopyClientString\n"));

    NTSTATUS Status = STATUS_SUCCESS;
    STRING TemporaryString;
    ULONG SourceSize = 0;
    ULONG CharacterSize = sizeof(CHAR);

    //
    // First initialize the string to zero, in case the source is a null
    // string
    //

    DestinationString->Length = DestinationString->MaximumLength = 0;
    DestinationString->Buffer = NULL;
    TemporaryString.Buffer = NULL;


    if (SourceString != NULL)
    {

        //
        // If the length is zero, allocate one byte for a "\0" terminator
        //

        if (SourceLength == 0)
        {
            DestinationString->Buffer = (LPWSTR) NtLmAllocate(sizeof(WCHAR));
            if (DestinationString->Buffer == NULL)
            {
                SspPrint((SSP_CRITICAL,"CopyClientString, Error from NtLmAllocate is 0x%lx\n", Status));
                Status = STATUS_NO_MEMORY;
                goto Cleanup;
            }
            DestinationString->MaximumLength = sizeof(WCHAR);
            *DestinationString->Buffer = L'\0';

        }
        else
        {
            //
            // Allocate a temporary buffer to hold the client string. We may
            // then create a buffer for the unicode version. The length
            // is the length in characters, so  possible expand to hold unicode
            // characters and a null terminator.
            //

            if (DoUnicode)
            {
                CharacterSize = sizeof(WCHAR);
            }

            SourceSize = (SourceLength + 1) * CharacterSize;

            //
            // insure no overflow aggainst UNICODE_STRING
            //

            if ( (SourceSize > 0xFFFF) ||
                 ((SourceSize - CharacterSize) > 0xFFFF)
                 )
            {
                Status = STATUS_INVALID_PARAMETER;
                SspPrint((SSP_CRITICAL,"CopyClientString, SourceSize is too large\n"));
                goto Cleanup;
            }


            TemporaryString.Buffer = (LPSTR) NtLmAllocate(SourceSize);
            if (TemporaryString.Buffer == NULL)
            {
                Status = STATUS_NO_MEMORY;
                SspPrint((SSP_CRITICAL,"CopyClientString, Error from NtLmAllocate is 0x%lx\n", Status));
                goto Cleanup;
            }
            TemporaryString.Length = (USHORT) (SourceSize - CharacterSize);
            TemporaryString.MaximumLength = (USHORT) SourceSize;


            //
            // Finally copy the string from the client
            //

            Status = LsaFunctions->CopyFromClientBuffer(
                            NULL,
                            SourceSize - CharacterSize,
                            TemporaryString.Buffer,
                            SourceString
                            );

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

            //
            // If we are doing unicode, finish up now
            //
            if (DoUnicode)
            {
                DestinationString->Buffer = (LPWSTR) TemporaryString.Buffer;
                DestinationString->Length = (USHORT) (SourceSize - CharacterSize);
                DestinationString->MaximumLength = (USHORT) SourceSize;
            }
            else
            {
                NTSTATUS Status1;
                Status1 = RtlOemStringToUnicodeString(
                            DestinationString,
                            &TemporaryString,
                            TRUE
                            );      // allocate destination
                if (!NT_SUCCESS(Status1))
                {
                    Status = STATUS_NO_MEMORY;
                    SspPrint((SSP_CRITICAL,"CopyClientString, Error from RtlOemStringToUnicodeString is 0x%lx\n", Status));
                    goto Cleanup;
                }
            }
        }
    }

Cleanup:

    if (TemporaryString.Buffer != NULL)
    {
        //
        // Free this if we failed and were doing unicode or if we weren't
        // doing unicode
        //

        if ((DoUnicode && !NT_SUCCESS(Status)) || !DoUnicode)
        {
            NtLmFree(TemporaryString.Buffer);
        }
    }

    SspPrint((SSP_API_MORE,"Leaving CopyClientString\n"));

    return(Status);
}


//+-------------------------------------------------------------------------
//
//  Function:   SpAcceptCredentials
//
//  Synopsis:   This routine is called after another package has logged
//              a user on.  The other package provides a user name and
//              password and the NtLm package will create a logon
//              session for this user.
//
//  Effects:    Creates a logon session
//
//  Arguments:  LogonType - Type of logon, such as network or interactive
//              Accountname - Name of the account that logged on
//              PrimaryCredentials - Primary credentials for the account,
//                  containing a domain name, password, SID, etc.
//              SupplementalCredentials - NtLm -Specific blob of
//                  supplemental credentials.
//
//  Returns:    None
//
//  Notes:
//
//--------------------------------------------------------------------------
NTSTATUS NTAPI
SpAcceptCredentials(
    IN SECURITY_LOGON_TYPE LogonType,
    IN PUNICODE_STRING AccountName,
    IN PSECPKG_PRIMARY_CRED PrimaryCredentials,
    IN PSECPKG_SUPPLEMENTAL_CRED SupplementalCredentials
    )
{
    NTSTATUS Status = S_OK;
    SspPrint((SSP_API,"Entering SpAcceptCredentials\n"));

    Status = SspAcceptCredentials(
                LogonType,
                PrimaryCredentials,
                SupplementalCredentials
                );

    SspPrint((SSP_API,"Leaving SpAcceptCredentials\n"));

    return(SspNtStatusToSecStatus(Status, SEC_E_INTERNAL_ERROR));
    UNREFERENCED_PARAMETER( AccountName );
}


//+-------------------------------------------------------------------------
//
//  Function:   SpAcquireCredentialsHandle
//
//  Synopsis:   Contains NtLm Code for AcquireCredentialsHandle which
//              creates a Credential associated with a logon session.
//
//  Effects:    Creates a SSP_CREDENTIAL
//
//  Arguments:  PrincipalName - Name of logon session for which to create credential
//              CredentialUseFlags - Flags indicating whether the credentials
//                  is for inbound or outbound use.
//              LogonId - The logon ID of logon session for which to create
//                  a credential.
//              AuthorizationData - Unused blob of NtLm-specific data
//              GetKeyFunction - Unused function to retrieve a session key
//              GetKeyArgument - Argument for GetKeyFunction
//              CredentialHandle - Receives handle to new credential
//              ExpirationTime - Receives expiration time for credential
//
//  Returns:
//    STATUS_SUCCESS -- Call completed successfully
//    SEC_E_NO_SPM -- Security Support Provider is not running
//    SEC_E_PACKAGE_UNKNOWN -- Package being queried is not this package
//    SEC_E_PRINCIPAL_UNKNOWN -- No such principal
//    SEC_E_NOT_OWNER -- caller does not own the specified credentials
//    SEC_E_INSUFFICIENT_MEMORY -- Not enough memory
//
//  Notes:
//
//--------------------------------------------------------------------------

NTSTATUS NTAPI
SpAcquireCredentialsHandle(
    IN OPTIONAL PUNICODE_STRING PrincipalName,
    IN ULONG CredentialUseFlags,
    IN OPTIONAL PLUID LogonId,
    IN PVOID AuthorizationData,
    IN PVOID GetKeyFunction,
    IN PVOID GetKeyArgument,
    OUT PULONG_PTR CredentialHandle,
    OUT PTimeStamp ExpirationTime
    )
{
    SspPrint((SSP_API,"Entering SpAcquireCredentialsHandle\n"));

    NTSTATUS Status = STATUS_SUCCESS;

    UNICODE_STRING UserName;
    UNICODE_STRING DomainName;
    UNICODE_STRING Password;
    HANDLE TokenHandle = NULL;
    ULONG NewCredentialUseFlags = CredentialUseFlags;
    PSEC_WINNT_AUTH_IDENTITY pAuthIdentity = NULL;
    BOOLEAN DoUnicode = TRUE;
    PSEC_WINNT_AUTH_IDENTITY_EXW pAuthIdentityEx = NULL;

    PSEC_WINNT_AUTH_IDENTITY_W TmpCredentials = NULL;
    ULONG CredSize = 0;
    ULONG Offset = 0;

    //
    // Initialization
    //

    RtlInitUnicodeString(
        &UserName,
        NULL);

    RtlInitUnicodeString(
        &DomainName,
        NULL);

    RtlInitUnicodeString(
        &Password,
        NULL);

    //
    // BUGBUG Check args specific to NTLM
    // Validate the arguments
    //

    if ( (CredentialUseFlags & (SECPKG_CRED_OUTBOUND |SECPKG_CRED_INBOUND)) == 0)
    {
        Status = SEC_E_INVALID_CREDENTIAL_USE;
        goto Cleanup;
    }

    if ( ARGUMENT_PRESENT(GetKeyFunction) ) {
        Status = SEC_E_UNSUPPORTED_FUNCTION;
        SspPrint((SSP_CRITICAL,"Error from SpAquireCredentialsHandle is 0x%lx\n", Status));
        goto Cleanup;
    }

    // RDR2 passes in a 1 while talking to down level clients

    if ( ARGUMENT_PRESENT(GetKeyArgument) && (GetKeyArgument != (PVOID) 1)) {
        Status = SEC_E_UNSUPPORTED_FUNCTION;
        SspPrint((SSP_CRITICAL,"Error from SpAquireCredentialsHandle is 0x%lx\n", Status));
        goto Cleanup;
    }

    //
    // First get information about the caller.
    //

    SECPKG_CLIENT_INFO ClientInfo;
    PLUID LogonIdToUse;

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

    //
    // If the caller supplied a logon ID, and it doesn't match the caller,
    // they must have the TCB privilege
    //


    if (ARGUMENT_PRESENT(LogonId) &&
        ((LogonId->LowPart != 0) || (LogonId->HighPart != 0)) &&
        !RtlEqualLuid( LogonId, &ClientInfo.LogonId)
        )
    {
        if (!ClientInfo.HasTcbPrivilege)
        {
            Status = STATUS_PRIVILEGE_NOT_HELD;
            SspPrint((SSP_CRITICAL,"SpAcquireCredentialsHandle, Error from ClientInfo.HasTcbPrivilege is 0x%lx\n", Status));
            goto Cleanup;
        }
        LogonIdToUse = LogonId;

        // note: there is a special case where the LogonIdToUse specifies
        // the SYSTEM token, and there may not be a credential (and access token)
        // for that Luid yet.  This special case is handled in SsprAcquireCredentialsHandle()

    }
    else
    {
        //
        // Use the callers logon id.
        //

        LogonIdToUse = &ClientInfo.LogonId;
        // extract the token

        Status = SspGetToken (&TokenHandle);

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

⌨️ 快捷键说明

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