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

📄 nlmain.c

📁 安全支持提供器接口(SSPI)源码
💻 C
📖 第 1 页 / 共 5 页
字号:
/*++

Copyright (c) 1989 - 1999  Microsoft Corporation

Module Name:

    nlmain.c

Abstract:

    This file contains the initialization and dispatch routines
    for the LAN Manager portions of the MSV1_0 authentication package.

Author:

    Jim Kelly 11-Apr-1991

Revision History:
    25-Apr-1991 (cliffv)
        Added interactive logon support for PDK.

    Chandana Surlu   21-Jul-1996
        Stolen from \\kernel\razzle3\src\security\msv1_0\nlmain.c

--*/

#include <global.h>

#include "msp.h"
#undef EXTERN
#define NLP_ALLOCATE
#include "nlp.h"
#undef NLP_ALLOCATE

#include <lmsname.h>    // Service Names

#include <safeboot.h>

#include "nlpcache.h"   // logon cache prototypes


NTSTATUS
NlpMapLogonDomain(
    OUT PUNICODE_STRING MappedDomain,
    IN PUNICODE_STRING LogonDomain
    );

NTSTATUS
NlInitialize(
    VOID
    )

/*++

Routine Description:

    Initialize NETLOGON portion of msv1_0 authentication package.

Arguments:

    None.

Return Status:

    STATUS_SUCCESS - Indicates NETLOGON successfully initialized.

--*/

{
    NTSTATUS Status;
    LPWSTR ComputerName;
    DWORD ComputerNameLength = MAX_COMPUTERNAME_LENGTH + 1;
    NT_PRODUCT_TYPE NtProductType;
    UNICODE_STRING TempUnicodeString;
    HKEY Key ;
    int err ;
    ULONG Size ;
    ULONG Type ;
    ULONG Value ;

    //
    // Initialize global data
    //

    NlpEnumerationHandle = 0;
    NlpLogonAttemptCount = 0;


    NlpComputerName.Buffer = NULL;
    RtlInitUnicodeString( &NlpPrimaryDomainName, NULL );
    NlpSamDomainName.Buffer = NULL;
    NlpSamDomainId = NULL;
    NlpSamDomainHandle = NULL;



    //
    // Get the name of this machine.
    //

    ComputerName = RtlAllocateHeap(
                        MspHeap, 0,
                        ComputerNameLength * sizeof(WCHAR) );

    if (ComputerName == NULL ||
        !GetComputerNameW( ComputerName, &ComputerNameLength )) {

        KdPrint(( "MsV1_0: Cannot get computername %lX\n", GetLastError() ));

        NlpLanmanInstalled = FALSE;
        RtlFreeHeap( MspHeap, 0, ComputerName );
        ComputerName = NULL;
    } else {

        NlpLanmanInstalled = TRUE;
    }

    //
    // For Safe mode boot (minimal, no networking)
    // turn off the lanmaninstalled flag, since no network components will
    // be started.
    //

    err = RegOpenKeyExW(
                HKEY_LOCAL_MACHINE,
                L"System\\CurrentControlSet\\Control\\SafeBoot\\Option",
                0,
                KEY_READ,
                &Key );

    if ( err == 0 )
    {
        Value = 0 ;
        Size = sizeof( ULONG );

        RegQueryValueExW(
                Key,
                L"OptionValue",
                0,
                &Type,
                (PUCHAR) &Value,
                &Size );

        RegCloseKey( Key );

        if ( Value == SAFEBOOT_MINIMAL )
        {
            NlpLanmanInstalled = FALSE ;
        }

    }

    RtlInitUnicodeString( &NlpComputerName, ComputerName );

    //
    // Determine if this machine is running Windows NT or Lanman NT.
    //  LanMan NT runs on a domain controller.
    //

    if ( !RtlGetNtProductType( &NtProductType ) ) {
        KdPrint(( "MsV1_0: Nt Product Type undefined (WinNt assumed)\n" ));
        NtProductType = NtProductWinNt;
    }

    NlpWorkstation = (BOOLEAN)(NtProductType != NtProductLanManNt);



    //
    // Initialize any locks.
    //

    RtlInitializeCriticalSection(&NlpActiveLogonLock);

    //
    // initialize the cache - creates a critical section is all
    //

    NlpCacheInitialize();


    //
    // Attempt to load Netlogon.dll
    //

    NlpLoadNetlogonDll();

#ifdef COMPILED_BY_DEVELOPER
    KdPrint(("msv1_0: COMPILED_BY_DEVELOPER breakpoint.\n"));
    DbgBreakPoint();
#endif // COMPILED_BY_DEVELOPER



    //
    // Initialize useful encryption constants
    //

    Status = RtlCalculateLmOwfPassword( "", &NlpNullLmOwfPassword );
    ASSERT( NT_SUCCESS(Status) );

    RtlInitUnicodeString(&TempUnicodeString, NULL);
    Status = RtlCalculateNtOwfPassword(&TempUnicodeString,
                                       &NlpNullNtOwfPassword);
    ASSERT( NT_SUCCESS(Status) );

    //
    // Initialize the SubAuthentication Dlls
    //

    Msv1_0SubAuthenticationInitialization();




#ifdef notdef
    //
    // If we weren't successful,
    //  Clean up global resources we intended to initialize.
    //

    if ( !NT_SUCCESS(Status) ) {
        if ( NlpComputerName.Buffer != NULL ) {
            MIDL_user_free( NlpComputerName.Buffer );
        }

    }
#endif // notdef

    return STATUS_SUCCESS;

}




NTSTATUS
NlWaitForEvent(
    LPWSTR EventName,
    ULONG Timeout
    )

/*++

Routine Description:

    Wait up to Timeout seconds for EventName to be triggered.

Arguments:

    EventName - Name of event to wait on

    Timeout - Timeout for event (in seconds).

Return Status:

    STATUS_SUCCESS - Indicates NETLOGON successfully initialized.
    STATUS_NETLOGON_NOT_STARTED - Timeout occurred.

--*/

{
    NTSTATUS Status;

    HANDLE EventHandle;
    OBJECT_ATTRIBUTES EventAttributes;
    UNICODE_STRING EventNameString;
    LARGE_INTEGER LocalTimeout;


    //
    // Create an event for us to wait on.
    //

    RtlInitUnicodeString( &EventNameString, EventName);
    InitializeObjectAttributes( &EventAttributes, &EventNameString, 0, 0, NULL);

    Status = NtCreateEvent(
                   &EventHandle,
                   SYNCHRONIZE,
                   &EventAttributes,
                   NotificationEvent,
                   (BOOLEAN) FALSE      // The event is initially not signaled
                   );

    if ( !NT_SUCCESS(Status)) {

        //
        // If the event already exists, the server beat us to creating it.
        // Just open it.
        //

        if( Status == STATUS_OBJECT_NAME_EXISTS ||
            Status == STATUS_OBJECT_NAME_COLLISION ) {

            Status = NtOpenEvent( &EventHandle,
                                  SYNCHRONIZE,
                                  &EventAttributes );

        }
        if ( !NT_SUCCESS(Status)) {
            KdPrint(("[MSV1_0] OpenEvent failed %lx\n", Status ));
            return Status;
        }
    }


    //
    // Wait for NETLOGON to initialize.  Wait a maximum of Timeout seconds.
    //

    LocalTimeout.QuadPart = ((LONGLONG)(Timeout)) * (-10000000);
    Status = NtWaitForSingleObject( EventHandle, (BOOLEAN)FALSE, &LocalTimeout);
    (VOID) NtClose( EventHandle );

    if ( !NT_SUCCESS(Status) || Status == STATUS_TIMEOUT ) {
        if ( Status == STATUS_TIMEOUT ) {
            Status = STATUS_NETLOGON_NOT_STARTED;   // Map to an error condition
        }
        return Status;
    }

    return STATUS_SUCCESS;
}


BOOLEAN
NlDoingSetup(
    VOID
    )

/*++

Routine Description:

    Returns TRUE if we're running setup.

Arguments:

    NONE.

Return Status:

    TRUE - We're currently running setup
    FALSE - We're not running setup or aren't sure.

--*/

{
    LONG RegStatus;

    HKEY KeyHandle = NULL;
    DWORD ValueType;
    DWORD Value;
    DWORD ValueSize;

    //
    // Open the key for HKLM\SYSTEM\Setup
    //

    RegStatus = RegOpenKeyExA(
                    HKEY_LOCAL_MACHINE,
                    "SYSTEM\\Setup",
                    0,      //Reserved
                    KEY_QUERY_VALUE,
                    &KeyHandle );

    if ( RegStatus != ERROR_SUCCESS ) {
        KdPrint(( "NlDoingSetup: Cannot open registy key 'HKLM\\SYSTEM\\Setup' %ld.\n",
                  RegStatus ));
        return FALSE;
    }

    //
    // Get the value that says whether we're doing setup.
    //

    ValueSize = sizeof(Value);
    RegStatus = RegQueryValueExA(
                    KeyHandle,
                    "SystemSetupInProgress",
                    0,
                    &ValueType,
                    (LPBYTE)&Value,
                    &ValueSize );

    RegCloseKey( KeyHandle );

    if ( RegStatus != ERROR_SUCCESS ) {
        KdPrint(( "NlDoingSetup: Cannot query value of 'HKLM\\SYSTEM\\Setup\\SystemSetupInProgress' %ld.\n",
                  RegStatus ));
        return FALSE;
    }

    if ( ValueType != REG_DWORD ) {
        KdPrint(( "NlDoingSetup: value of 'HKLM\\SYSTEM\\Setup\\SystemSetupInProgress'is not a REG_DWORD %ld.\n",
                  ValueType ));
        return FALSE;
    }

    if ( ValueSize != sizeof(Value) ) {
        KdPrint(( "NlDoingSetup: value size of 'HKLM\\SYSTEM\\Setup\\SystemSetupInProgress'is not 4 %ld.\n",
                  ValueSize ));
        return FALSE;
    }

    if ( Value != 1 ) {
        // KdPrint(( "NlDoingSetup: not doing setup\n" ));
        return FALSE;
    }

    KdPrint((  "NlDoingSetup: doing setup\n" ));
    return TRUE;

}


NTSTATUS
NlWaitForNetlogon(
    ULONG Timeout
    )

/*++

Routine Description:

    Wait up to Timeout seconds for the netlogon service to start.

Arguments:

    Timeout - Timeout for event (in seconds).

Return Status:

    STATUS_SUCCESS - Indicates NETLOGON successfully initialized.
    STATUS_NETLOGON_NOT_STARTED - Timeout occurred.

--*/

{
    NTSTATUS Status;
    NET_API_STATUS NetStatus;
    SC_HANDLE ScManagerHandle = NULL;
    SC_HANDLE ServiceHandle = NULL;
    SERVICE_STATUS ServiceStatus;
    LPQUERY_SERVICE_CONFIG ServiceConfig;
    LPQUERY_SERVICE_CONFIG AllocServiceConfig = NULL;
    QUERY_SERVICE_CONFIG DummyServiceConfig;
    DWORD ServiceConfigSize;


    //
    // If the netlogon service is currently running,
    //  skip the rest of the tests.
    //

    Status = NlWaitForEvent( L"\\NETLOGON_SERVICE_STARTED", 0 );

    if ( NT_SUCCESS(Status) ) {
        return Status;
    }

    //
    // If we're in setup,
    //  don't bother waiting for netlogon to start.
    //

    if ( NlDoingSetup() ) {

⌨️ 快捷键说明

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