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

📄 ntlm.cxx

📁 安全支持提供器接口(SSPI)源码
💻 CXX
📖 第 1 页 / 共 4 页
字号:
//+--------------------------------------------------------------------
//
// Microsoft Windows
//
// Copyright (c) Microsoft Corporation 1992 - 1996
//
// File:       ntlm.cxx
//
// Contents:   main entrypoints for the ntlm security package
//               SpLsaModeInitialize
//               SpInitialize
//               SpShutdown
//               SpGetInfo
//
//             Helper functions:
//               NtLmSetPolicyInfo
//               NtLmPolicyChangeCallback
//               NtLmRegisterForPolicyChange
//               NtLmUnregisterForPolicyChange
//
// History:    ChandanS  26-Jul-1996   Stolen from kerberos\client2\kerberos.cxx
//             ChandanS  16-Apr-1998   No reboot on domain name change
//
//---------------------------------------------------------------------


// Variables with the EXTERN storage class are declared here
#define NTLM_GLOBAL
#define DEBUG_ALLOCATE

#include <global.h>

// BUGBUG Should be in the SDK?
#define MSV1_0_PACKAGE_NAMEW     L"MICROSOFT_AUTHENTICATION_PACKAGE_V1_0"
BOOLEAN NtLmCredentialInitialized;
BOOLEAN NtLmContextInitialized;
BOOLEAN NtLmRNGInitialized;

//+--------------------------------------------------------------------
//
//  Function:   SpLsaModeInitialize
//
//  Synopsis:   This function is called by the LSA when this DLL is loaded.
//              It returns security package function tables for all
//              security packages in the DLL.
//
//  Arguments:  LsaVersion - Version number of the LSA
//              PackageVersion - Returns version number of the package
//              Tables - Returns array of function tables for the package
//              TableCount - Returns number of entries in array of
//                      function tables.
//
//  Returns:    PackageVersion (as above)
//              Tables (as above)
//              TableCount (as above)
//
//  Notes:
//
//---------------------------------------------------------------------
NTSTATUS NTAPI
SpLsaModeInitialize(
    IN ULONG LsaVersion,
    OUT PULONG PackageVersion,
    OUT PSECPKG_FUNCTION_TABLE * Tables,
    OUT PULONG TableCount
    )
{
#if DBG
//     SspGlobalDbflag = SSP_CRITICAL| SSP_API| SSP_API_MORE |SSP_INIT| SSP_MISC | SSP_NO_LOCAL;
    SspGlobalDbflag = SSP_CRITICAL ;
    InitializeCriticalSection(&SspGlobalLogFileCritSect);
#endif
    SspPrint((SSP_API, "Entering SpLsaModeInitialize\n"));

    SECURITY_STATUS Status = SEC_E_OK;

    if (LsaVersion != SECPKG_INTERFACE_VERSION)
    {
        SspPrint((SSP_CRITICAL, "Invalid LSA version: %d\n", LsaVersion));
        Status = STATUS_INVALID_PARAMETER;
        goto CleanUp;
    }

    NtLmFunctionTable.InitializePackage        = NULL;
    NtLmFunctionTable.LogonUser                = NULL;
    NtLmFunctionTable.CallPackage              = LsaApCallPackage;
    NtLmFunctionTable.LogonTerminated          = LsaApLogonTerminated;
    NtLmFunctionTable.CallPackageUntrusted     = LsaApCallPackageUntrusted;
    NtLmFunctionTable.LogonUserEx              = NULL;
    NtLmFunctionTable.LogonUserEx2             = LsaApLogonUserEx2;
    NtLmFunctionTable.Initialize               = SpInitialize;
    NtLmFunctionTable.Shutdown                 = SpShutdown;
    NtLmFunctionTable.GetInfo                  = SpGetInfo;
    NtLmFunctionTable.AcceptCredentials        = SpAcceptCredentials;
    NtLmFunctionTable.AcquireCredentialsHandle = SpAcquireCredentialsHandle;
    NtLmFunctionTable.FreeCredentialsHandle    = SpFreeCredentialsHandle;
    NtLmFunctionTable.SaveCredentials          = SpSaveCredentials;
    NtLmFunctionTable.GetCredentials           = SpGetCredentials;
    NtLmFunctionTable.DeleteCredentials        = SpDeleteCredentials;
    NtLmFunctionTable.InitLsaModeContext       = SpInitLsaModeContext;
    NtLmFunctionTable.AcceptLsaModeContext     = SpAcceptLsaModeContext;
    NtLmFunctionTable.DeleteContext            = SpDeleteContext;
    NtLmFunctionTable.ApplyControlToken        = SpApplyControlToken;
    NtLmFunctionTable.GetUserInfo              = SpGetUserInfo;
    NtLmFunctionTable.QueryCredentialsAttributes = SpQueryCredentialsAttributes ;
    NtLmFunctionTable.GetExtendedInformation   = SpGetExtendedInformation ;
    NtLmFunctionTable.SetExtendedInformation   = SpSetExtendedInformation ;
    NtLmFunctionTable.CallPackagePassthrough   = LsaApCallPackagePassthrough;


    *PackageVersion = SECPKG_INTERFACE_VERSION;
    *Tables = &NtLmFunctionTable;
    *TableCount = 1;

CleanUp:

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

    return(SspNtStatusToSecStatus(Status, SEC_E_INTERNAL_ERROR));
}

//+-------------------------------------------------------------------------
//
//  Function:   NtLmSetPolicyInfo
//
//  Synopsis:   Function to be called when policy changes
//
//  Effects:
//
//  Arguments:
//
//  Requires:
//
//  Returns:
//
//  Notes:
//        if fInit is TRUE, this is called by the init routine in ntlm
//
//
//+-------------------------------------------------------------------------
NTSTATUS
NtLmSetPolicyInfo(
    IN PUNICODE_STRING DnsComputerName,
    IN PUNICODE_STRING ComputerName,
    IN PUNICODE_STRING DnsDomainName,
    IN PUNICODE_STRING DomainName,
    IN PSID DomainSid,
    IN POLICY_NOTIFICATION_INFORMATION_CLASS ChangedInfoClass,
    IN BOOLEAN fInit
    )
{
    NTSTATUS Status = STATUS_SUCCESS;

    // Buffers to delete on cleanup

    CHAR   *ComputerNameAnsi    = NULL;
    CHAR   *DomainNameAnsi    = NULL;
    //
    // Do this only if this is package init
    //

    EnterCriticalSection(&NtLmGlobalCritSect);

    if (fInit)
    {
        if (ComputerName && ComputerName->Buffer != NULL)
        {
            ULONG cLength = ComputerName->Length / sizeof(WCHAR);

            if ((ComputerName->Length + sizeof(WCHAR)) > sizeof(NtLmGlobalUnicodeComputerName))
            {
                // Bad ComputerName
                Status = STATUS_INVALID_COMPUTER_NAME;
                SspPrint((SSP_CRITICAL, "NtLmSetPolicyInfo, Bad computer name length is %d\n", cLength));
                goto CleanUp;
            }

            wcsncpy(NtLmGlobalUnicodeComputerName,
               ComputerName->Buffer,
               cLength);

            NtLmGlobalUnicodeComputerName[cLength] = UNICODE_NULL;

            // make NtlmGlobalUnicodeComputerNameString a string form

            RtlInitUnicodeString(  &NtLmGlobalUnicodeComputerNameString,
                                   NtLmGlobalUnicodeComputerName );

            // Save old buffers for deleting
            ComputerNameAnsi = NtLmGlobalOemComputerNameString.Buffer;

            Status = RtlUpcaseUnicodeStringToOemString(
                        &NtLmGlobalOemComputerNameString,
                        &NtLmGlobalUnicodeComputerNameString,
                        TRUE );

            if ( !NT_SUCCESS(Status) ) {
                Status = STATUS_SUCCESS;
                //SspPrint((SSP_CRITICAL, "NtLmSetPolicyInfo, Error from RtlUpcaseUnicodeStringToOemString is %d\n", Status));
                ComputerNameAnsi = NULL;
                // goto CleanUp;
            }

        }
    }

    //
    // Initialize various forms of the primary domain name of the local system
    // Do this only if this is package init or it's DnsDomain info
    //

    if (fInit || (ChangedInfoClass == PolicyNotifyDnsDomainInformation))
    {
        if (DnsComputerName && DnsComputerName->Buffer != NULL ) {
            ULONG cLength = DnsComputerName->Length / sizeof(WCHAR);

            if((DnsComputerName->Length + sizeof(WCHAR)) > sizeof(NtLmGlobalUnicodeDnsComputerName))
            {
                // Bad ComputerName
                Status = STATUS_INVALID_COMPUTER_NAME;
                SspPrint((SSP_CRITICAL, "NtLmSetPolicyInfo, Bad computer name length is %d\n", cLength));
                goto CleanUp;
            }

            wcsncpy(NtLmGlobalUnicodeDnsComputerName,
               DnsComputerName->Buffer,
               cLength);

            NtLmGlobalUnicodeDnsComputerName[cLength] = UNICODE_NULL;

            // make NtlmGlobalUnicodeDnsComputerNameString a string form

            RtlInitUnicodeString(  &NtLmGlobalUnicodeDnsComputerNameString,
                                   NtLmGlobalUnicodeDnsComputerName );
        }

        if (DnsDomainName && DnsDomainName->Buffer != NULL ) {
            ULONG cLength = DnsDomainName->Length / sizeof(WCHAR);

            if((DnsDomainName->Length + sizeof(WCHAR)) > sizeof(NtLmGlobalUnicodeDnsDomainName))
            {
                // Bad ComputerName
                Status = STATUS_INVALID_COMPUTER_NAME;
                SspPrint((SSP_CRITICAL, "NtLmSetPolicyInfo, Bad domain name length is %d\n", cLength));
                goto CleanUp;
            }

            wcsncpy(NtLmGlobalUnicodeDnsDomainName,
               DnsDomainName->Buffer,
               cLength);

            NtLmGlobalUnicodeDnsDomainName[cLength] = UNICODE_NULL;

            // make NtlmGlobalUnicodeDnsDomainNameString a string form

            RtlInitUnicodeString(  &NtLmGlobalUnicodeDnsDomainNameString,
                                   NtLmGlobalUnicodeDnsDomainName );
        }

        if (DomainName && DomainName->Buffer != NULL)
        {
            ULONG cLength = DomainName->Length / sizeof(WCHAR);

            if ((DomainName->Length + sizeof(WCHAR)) > sizeof(NtLmGlobalUnicodePrimaryDomainName))
            {
                Status = STATUS_NAME_TOO_LONG;
                SspPrint((SSP_CRITICAL, "NtLmSetPolicyInfo, Bad domain name length is %d\n", cLength));
                goto CleanUp;
            }
            wcsncpy(NtLmGlobalUnicodePrimaryDomainName,
               DomainName->Buffer,
               cLength);
            NtLmGlobalUnicodePrimaryDomainName[cLength] = UNICODE_NULL;

            // make NtlmGlobalUnicodePrimaryDomainNameString a string form

            RtlInitUnicodeString(  &NtLmGlobalUnicodePrimaryDomainNameString,
                                   NtLmGlobalUnicodePrimaryDomainName );

            // Save old buffers for deleting
            DomainNameAnsi = NtLmGlobalOemPrimaryDomainNameString.Buffer;

            Status = RtlUpcaseUnicodeStringToOemString(
                        &NtLmGlobalOemPrimaryDomainNameString,
                        &NtLmGlobalUnicodePrimaryDomainNameString,
                        TRUE );

            if ( !NT_SUCCESS(Status) ) {
                // SspPrint((SSP_CRITICAL, "NtLmSetPolicyInfo, Error from RtlUpcaseUnicodeStringToOemString is %d\n", Status));
                DomainNameAnsi = NULL;
                // goto CleanUp;
                Status = STATUS_SUCCESS;
            }
        }
    }

    //
    // If this is a standalone windows NT workstation,
    // use the computer name as the Target name.
    //

    if ( DomainSid != NULL)
    {
        NtLmGlobalUnicodeTargetName = NtLmGlobalUnicodePrimaryDomainNameString;
        NtLmGlobalOemTargetName = NtLmGlobalOemPrimaryDomainNameString;
        NtLmGlobalTargetFlags = NTLMSSP_TARGET_TYPE_DOMAIN;
    }
    else
    {
        NtLmGlobalUnicodeTargetName = NtLmGlobalUnicodeComputerNameString;
        NtLmGlobalOemTargetName = NtLmGlobalOemComputerNameString;
        NtLmGlobalTargetFlags = NTLMSSP_TARGET_TYPE_SERVER;
    }

    //
    // initialize the GlobalNtlm3 targetinfo.
    //

    {
        PMSV1_0_AV_PAIR pAV;
        PUNICODE_STRING pDnsTargetName;
        PUNICODE_STRING pDnsComputerName;
        ULONG cbAV;

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

        if( NtLmGlobalTargetFlags == NTLMSSP_TARGET_TYPE_DOMAIN ) {
            pDnsTargetName = &NtLmGlobalUnicodeDnsDomainNameString;
        } else {
            pDnsTargetName = &NtLmGlobalUnicodeDnsComputerNameString;
        }

        pDnsComputerName = &NtLmGlobalUnicodeDnsComputerNameString;

        cbAV = NtLmGlobalUnicodeTargetName.Length +
               NtLmGlobalUnicodeComputerNameString.Length +
               pDnsComputerName->Length +
               pDnsTargetName->Length +
               64 ;

        NtLmGlobalNtLm3TargetInfo.Buffer = (PWSTR)NtLmAllocate( cbAV );

        if( NtLmGlobalNtLm3TargetInfo.Buffer == NULL )
        {
            Status = STATUS_INSUFFICIENT_RESOURCES;
            SspPrint((SSP_CRITICAL, "NtLmSetPolicyInfo, Error from NtLmAllocate\n"));
            goto CleanUp;
        }

        pAV = MsvpAvlInit( NtLmGlobalNtLm3TargetInfo.Buffer );
        MsvpAvlAdd( pAV, MsvAvNbDomainName, &NtLmGlobalUnicodeTargetName, cbAV );
        MsvpAvlAdd( pAV, MsvAvNbComputerName, &NtLmGlobalUnicodeComputerNameString, cbAV );

        if( pDnsTargetName->Length != 0 && pDnsTargetName->Buffer != NULL )
            MsvpAvlAdd( pAV, MsvAvDnsDomainName, pDnsTargetName, cbAV );

        if( pDnsComputerName->Length != 0 && pDnsComputerName->Buffer != NULL )
            MsvpAvlAdd( pAV, MsvAvDnsComputerName, &NtLmGlobalUnicodeDnsComputerNameString, cbAV );

        NtLmGlobalNtLm3TargetInfo.Length = (USHORT)MsvpAvlLen( pAV, cbAV );
    }

CleanUp:

    LeaveCriticalSection(&NtLmGlobalCritSect);

    if (ComputerNameAnsi)
    {
        NtLmFree(ComputerNameAnsi);
    }

    if (DomainNameAnsi)
    {
        NtLmFree(DomainNameAnsi);
    }


    return Status;
}

//+-------------------------------------------------------------------------
//
//  Function:   NtLmPolicyChangeCallback
//
//  Synopsis:   Function to be called when domain policy changes
//
//  Effects:
//
//  Arguments:
//
//  Requires:
//
//  Returns:
//
//  Notes:
//
//
//--------------------------------------------------------------------------

⌨️ 快捷键说明

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