📄 nlmain.c
字号:
/*++
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 + -