1759 lines
58 KiB
C
1759 lines
58 KiB
C
|
/*++
|
|||
|
|
|||
|
Copyright (c) 1987-1996 Microsoft Corporation
|
|||
|
|
|||
|
Module Name:
|
|||
|
|
|||
|
parse.c
|
|||
|
|
|||
|
Abstract:
|
|||
|
|
|||
|
Routine to parse the command line.
|
|||
|
|
|||
|
Author:
|
|||
|
|
|||
|
Ported from Lan Man 2.0
|
|||
|
|
|||
|
Environment:
|
|||
|
|
|||
|
User mode only.
|
|||
|
Contains NT-specific code.
|
|||
|
Requires ANSI C extensions: slash-slash comments, long external names.
|
|||
|
|
|||
|
Revision History:
|
|||
|
|
|||
|
01-Aug-1991 (cliffv)
|
|||
|
Ported to NT. Converted to NT style.
|
|||
|
09-May-1992 JohnRo
|
|||
|
Enable use of win32 registry.
|
|||
|
Use net config helpers for NetLogon.
|
|||
|
Fixed UNICODE bug handling debug file name.
|
|||
|
Use <prefix.h> equates.
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
//
|
|||
|
// Common include files.
|
|||
|
//
|
|||
|
|
|||
|
#include "logonsrv.h" // Include files common to entire service
|
|||
|
#pragma hdrstop
|
|||
|
|
|||
|
#include <configp.h> // USE_WIN32_CONFIG (if defined), etc.
|
|||
|
#include <prefix.h> // PREFIX_ equates.
|
|||
|
|
|||
|
//
|
|||
|
// Include files specific to this .c file
|
|||
|
//
|
|||
|
|
|||
|
#include <string.h> // strnicmp
|
|||
|
|
|||
|
NET_API_STATUS
|
|||
|
NlParseOne(
|
|||
|
IN LPNET_CONFIG_HANDLE SectionHandle,
|
|||
|
IN BOOL GpSection,
|
|||
|
IN LPWSTR Keyword,
|
|||
|
IN ULONG DefaultValue,
|
|||
|
IN ULONG MinimumValue,
|
|||
|
IN ULONG MaximumValue,
|
|||
|
OUT PULONG Value
|
|||
|
)
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Get a single numeric parameter from the netlogon section of the registry.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
SectionHandle - Handle into the registry.
|
|||
|
|
|||
|
GpSection - TRUE iff the section is the group policy section.
|
|||
|
|
|||
|
Keyword - Name of the value to read.
|
|||
|
|
|||
|
DefaultValue - Default value if parameter doesn't exist.
|
|||
|
|
|||
|
MinimumValue - Minumin valid value.
|
|||
|
|
|||
|
MaximumValue - Maximum valid value.
|
|||
|
|
|||
|
Value - Returns the value parsed.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
Status of the operation
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
NET_API_STATUS NetStatus;
|
|||
|
LPWSTR ValueT = NULL;
|
|||
|
|
|||
|
//
|
|||
|
// Always return a reasonable value.
|
|||
|
//
|
|||
|
*Value = DefaultValue;
|
|||
|
|
|||
|
//
|
|||
|
// Determine if the value is specified in the registry at all.
|
|||
|
//
|
|||
|
|
|||
|
NetStatus = NetpGetConfigValue (
|
|||
|
SectionHandle,
|
|||
|
Keyword,
|
|||
|
&ValueT );
|
|||
|
|
|||
|
if( ValueT != NULL ) {
|
|||
|
NetApiBufferFree( ValueT );
|
|||
|
ValueT = NULL;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// If the value wasn't specified,
|
|||
|
// use the default.
|
|||
|
//
|
|||
|
|
|||
|
if ( NetStatus == NERR_CfgParamNotFound ) {
|
|||
|
*Value = DefaultValue;
|
|||
|
|
|||
|
//
|
|||
|
// If the value was specifed,
|
|||
|
// get it from the registry.
|
|||
|
//
|
|||
|
|
|||
|
} else {
|
|||
|
|
|||
|
NetStatus = NetpGetConfigDword (
|
|||
|
SectionHandle,
|
|||
|
Keyword, // keyword wanted
|
|||
|
DefaultValue,
|
|||
|
Value );
|
|||
|
|
|||
|
if (NetStatus == NO_ERROR) {
|
|||
|
if ( *Value > MaximumValue || *Value < MinimumValue ) {
|
|||
|
ULONG InvalidValue;
|
|||
|
LPWSTR MsgStrings[6];
|
|||
|
// Each byte of the status code will transform into one character 0-F
|
|||
|
WCHAR InvalidValueString[sizeof(WCHAR) * (sizeof(InvalidValue) + 1)];
|
|||
|
WCHAR MinimumValueString[sizeof(WCHAR) * (sizeof(MinimumValue) + 1)];
|
|||
|
WCHAR MaximumValueString[sizeof(WCHAR) * (sizeof(MaximumValue) + 1)];
|
|||
|
WCHAR AssignedValueString[sizeof(WCHAR) * (sizeof(*Value) + 1)];
|
|||
|
|
|||
|
InvalidValue = *Value;
|
|||
|
|
|||
|
if ( *Value > MaximumValue ) {
|
|||
|
*Value = MaximumValue;
|
|||
|
} else if ( *Value < MinimumValue ) {
|
|||
|
*Value = MinimumValue;
|
|||
|
}
|
|||
|
|
|||
|
swprintf( InvalidValueString, L"%lx", InvalidValue );
|
|||
|
swprintf( MinimumValueString, L"%lx", MinimumValue );
|
|||
|
swprintf( MaximumValueString, L"%lx", MaximumValue );
|
|||
|
swprintf( AssignedValueString, L"%lx", *Value );
|
|||
|
|
|||
|
if ( GpSection ) {
|
|||
|
MsgStrings[0] = L"Group Policy";
|
|||
|
} else {
|
|||
|
MsgStrings[0] = L"Parameters";
|
|||
|
}
|
|||
|
|
|||
|
MsgStrings[1] = InvalidValueString;
|
|||
|
MsgStrings[2] = Keyword;
|
|||
|
MsgStrings[3] = MinimumValueString;
|
|||
|
MsgStrings[4] = MaximumValueString;
|
|||
|
MsgStrings[5] = AssignedValueString;
|
|||
|
|
|||
|
NlpWriteEventlog( NELOG_NetlogonInvalidDwordParameterValue,
|
|||
|
EVENTLOG_WARNING_TYPE,
|
|||
|
NULL,
|
|||
|
0,
|
|||
|
MsgStrings,
|
|||
|
6 );
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
} else {
|
|||
|
return NetStatus;
|
|||
|
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
return NERR_Success;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
NET_API_STATUS
|
|||
|
NlParseOnePath(
|
|||
|
IN LPNET_CONFIG_HANDLE SectionHandle,
|
|||
|
IN LPWSTR Keyword,
|
|||
|
IN LPWSTR DefaultValue1 OPTIONAL,
|
|||
|
OUT LPWSTR *Value
|
|||
|
)
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Get a single path parameter from the netlogon section of the registry.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
SectionHandle - Handle into the registry.
|
|||
|
|
|||
|
Keyword - Name of the value to read.
|
|||
|
|
|||
|
DefaultValue1 - Default value if parameter doesn't exist.
|
|||
|
If NULL, Value will be set to NULL to indicate there is no default.
|
|||
|
|
|||
|
Value - Returns the value parsed.
|
|||
|
Must be freed using NetApiBufferFree.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
Status of the operation
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
NET_API_STATUS NetStatus;
|
|||
|
WCHAR OutPathname[MAX_PATH+1];
|
|||
|
WCHAR TempPathname[MAX_PATH*2+1];
|
|||
|
LPWSTR ValueT = NULL;
|
|||
|
ULONG type;
|
|||
|
|
|||
|
//
|
|||
|
// Get the configured parameter
|
|||
|
//
|
|||
|
|
|||
|
*Value = NULL;
|
|||
|
NetStatus = NetpGetConfigValue (
|
|||
|
SectionHandle,
|
|||
|
Keyword, // key wanted
|
|||
|
&ValueT ); // Must be freed by NetApiBufferFree().
|
|||
|
|
|||
|
|
|||
|
if (NetStatus != NO_ERROR) {
|
|||
|
//
|
|||
|
// Handle the default
|
|||
|
//
|
|||
|
if (NetStatus == NERR_CfgParamNotFound) {
|
|||
|
|
|||
|
//
|
|||
|
// If there is no default,
|
|||
|
// we're done.
|
|||
|
//
|
|||
|
|
|||
|
if ( DefaultValue1 == NULL ) {
|
|||
|
*Value = NULL;
|
|||
|
NetStatus = NO_ERROR;
|
|||
|
goto Cleanup;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Build the default value.
|
|||
|
//
|
|||
|
|
|||
|
ValueT = NetpAllocWStrFromWStr( DefaultValue1 );
|
|||
|
if ( ValueT == NULL ) {
|
|||
|
NetStatus = ERROR_NOT_ENOUGH_MEMORY;
|
|||
|
goto Cleanup;
|
|||
|
}
|
|||
|
|
|||
|
} else {
|
|||
|
goto Cleanup;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
NlAssert( ValueT != NULL );
|
|||
|
|
|||
|
//
|
|||
|
// Convert the configured sysvol path to a full pathname.
|
|||
|
//
|
|||
|
|
|||
|
type = 0; // Let the API figure out the type.
|
|||
|
NetStatus = I_NetPathCanonicalize( NULL,
|
|||
|
ValueT,
|
|||
|
OutPathname,
|
|||
|
sizeof(OutPathname),
|
|||
|
NULL,
|
|||
|
&type,
|
|||
|
0L );
|
|||
|
if (NetStatus != NERR_Success ) {
|
|||
|
goto Cleanup;
|
|||
|
}
|
|||
|
|
|||
|
if (type == ITYPE_PATH_ABSD) {
|
|||
|
NetpCopyTStrToWStr(TempPathname, OutPathname);
|
|||
|
} else if (type == ITYPE_PATH_RELND) {
|
|||
|
if ( !GetSystemWindowsDirectoryW(
|
|||
|
TempPathname,
|
|||
|
sizeof(TempPathname)/sizeof(WCHAR) ) ) {
|
|||
|
NetStatus = GetLastError();
|
|||
|
goto Cleanup;
|
|||
|
}
|
|||
|
wcscat( TempPathname, L"\\" );
|
|||
|
wcscat( TempPathname, OutPathname );
|
|||
|
} else {
|
|||
|
NetStatus = NERR_BadComponent;
|
|||
|
goto Cleanup;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Return the pathname in an allocated buffer
|
|||
|
//
|
|||
|
|
|||
|
*Value = NetpAllocWStrFromWStr( TempPathname );
|
|||
|
|
|||
|
if ( *Value == NULL ) {
|
|||
|
NetStatus = ERROR_NOT_ENOUGH_MEMORY;
|
|||
|
goto Cleanup;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Cleanup:
|
|||
|
if ( ValueT != NULL ) {
|
|||
|
(VOID) NetApiBufferFree( ValueT );
|
|||
|
}
|
|||
|
return NetStatus;
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
//
|
|||
|
// Table of numeric parameters to parse.
|
|||
|
//
|
|||
|
#define getoffset( _x ) offsetof( NETLOGON_PARAMETERS, _x )
|
|||
|
struct {
|
|||
|
LPWSTR Keyword;
|
|||
|
ULONG DefaultValue;
|
|||
|
ULONG MinimumValue;
|
|||
|
ULONG MaximumValue;
|
|||
|
ULONG ValueOffset;
|
|||
|
BOOLEAN ChangesDnsRegistration;
|
|||
|
} ParseTable[] =
|
|||
|
{
|
|||
|
{ NETLOGON_KEYWORD_PULSE, DEFAULT_PULSE, MIN_PULSE, MAX_PULSE, getoffset( Pulse ), FALSE },
|
|||
|
{ NETLOGON_KEYWORD_RANDOMIZE, DEFAULT_RANDOMIZE, MIN_RANDOMIZE, MAX_RANDOMIZE, getoffset( Randomize ), FALSE },
|
|||
|
{ NETLOGON_KEYWORD_PULSEMAXIMUM, DEFAULT_PULSEMAXIMUM, MIN_PULSEMAXIMUM, MAX_PULSEMAXIMUM, getoffset( PulseMaximum ), FALSE },
|
|||
|
{ NETLOGON_KEYWORD_PULSECONCURRENCY, DEFAULT_PULSECONCURRENCY, MIN_PULSECONCURRENCY, MAX_PULSECONCURRENCY, getoffset( PulseConcurrency ), FALSE },
|
|||
|
{ NETLOGON_KEYWORD_PULSETIMEOUT1, DEFAULT_PULSETIMEOUT1, MIN_PULSETIMEOUT1, MAX_PULSETIMEOUT1, getoffset( PulseTimeout1 ), FALSE },
|
|||
|
{ NETLOGON_KEYWORD_PULSETIMEOUT2, DEFAULT_PULSETIMEOUT2, MIN_PULSETIMEOUT2, MAX_PULSETIMEOUT2, getoffset( PulseTimeout2 ), FALSE },
|
|||
|
{ NETLOGON_KEYWORD_MAXIMUMMAILSLOTMESSAGES, DEFAULT_MAXIMUMMAILSLOTMESSAGES, MIN_MAXIMUMMAILSLOTMESSAGES, MAX_MAXIMUMMAILSLOTMESSAGES, getoffset( MaximumMailslotMessages ), FALSE },
|
|||
|
{ NETLOGON_KEYWORD_MAILSLOTMESSAGETIMEOUT, DEFAULT_MAILSLOTMESSAGETIMEOUT, MIN_MAILSLOTMESSAGETIMEOUT, MAX_MAILSLOTMESSAGETIMEOUT, getoffset( MailslotMessageTimeout ), FALSE },
|
|||
|
{ NETLOGON_KEYWORD_MAILSLOTDUPLICATETIMEOUT,DEFAULT_MAILSLOTDUPLICATETIMEOUT,MIN_MAILSLOTDUPLICATETIMEOUT,MAX_MAILSLOTDUPLICATETIMEOUT,getoffset( MailslotDuplicateTimeout ),FALSE },
|
|||
|
{ NETLOGON_KEYWORD_EXPECTEDDIALUPDELAY, DEFAULT_EXPECTEDDIALUPDELAY, MIN_EXPECTEDDIALUPDELAY, MAX_EXPECTEDDIALUPDELAY, getoffset( ExpectedDialupDelay ), FALSE },
|
|||
|
{ NETLOGON_KEYWORD_SCAVENGEINTERVAL, DEFAULT_SCAVENGEINTERVAL, MIN_SCAVENGEINTERVAL, MAX_SCAVENGEINTERVAL, getoffset( ScavengeInterval ), FALSE },
|
|||
|
{ NETLOGON_KEYWORD_MAXIMUMPASSWORDAGE, DEFAULT_MAXIMUMPASSWORDAGE, MIN_MAXIMUMPASSWORDAGE, MAX_MAXIMUMPASSWORDAGE, getoffset( MaximumPasswordAge ), FALSE },
|
|||
|
{ NETLOGON_KEYWORD_LDAPSRVPRIORITY, DEFAULT_LDAPSRVPRIORITY, MIN_LDAPSRVPRIORITY, MAX_LDAPSRVPRIORITY, getoffset( LdapSrvPriority ), TRUE },
|
|||
|
{ NETLOGON_KEYWORD_LDAPSRVWEIGHT, DEFAULT_LDAPSRVWEIGHT, MIN_LDAPSRVWEIGHT, MAX_LDAPSRVWEIGHT, getoffset( LdapSrvWeight ), TRUE },
|
|||
|
{ NETLOGON_KEYWORD_LDAPSRVPORT, DEFAULT_LDAPSRVPORT, MIN_LDAPSRVPORT, MAX_LDAPSRVPORT, getoffset( LdapSrvPort ), TRUE },
|
|||
|
{ NETLOGON_KEYWORD_LDAPGCSRVPORT, DEFAULT_LDAPGCSRVPORT, MIN_LDAPGCSRVPORT, MAX_LDAPGCSRVPORT, getoffset( LdapGcSrvPort ), TRUE },
|
|||
|
{ L"KdcSrvPort", DEFAULT_KDCSRVPORT, MIN_KDCSRVPORT, MAX_KDCSRVPORT, getoffset( KdcSrvPort ), TRUE },
|
|||
|
{ NETLOGON_KEYWORD_KERBISDDONEWITHJOIN, DEFAULT_KERBISDDONEWITHJOIN, MIN_KERBISDDONEWITHJOIN, MAX_KERBISDDONEWITHJOIN, getoffset( KerbIsDoneWithJoinDomainEntry),FALSE},
|
|||
|
{ NETLOGON_KEYWORD_DNSTTL, DEFAULT_DNSTTL, MIN_DNSTTL, MAX_DNSTTL, getoffset( DnsTtl ), TRUE },
|
|||
|
{ NETLOGON_KEYWORD_DNSREFRESHINTERVAL, DEFAULT_DNSREFRESHINTERVAL, MIN_DNSREFRESHINTERVAL, MAX_DNSREFRESHINTERVAL, getoffset( DnsRefreshInterval ), TRUE },
|
|||
|
{ L"CloseSiteTimeout", DEFAULT_CLOSESITETIMEOUT, MIN_CLOSESITETIMEOUT, MAX_CLOSESITETIMEOUT, getoffset( CloseSiteTimeout ), FALSE },
|
|||
|
{ L"SiteNameTimeout", DEFAULT_SITENAMETIMEOUT, MIN_SITENAMETIMEOUT, MAX_SITENAMETIMEOUT, getoffset( SiteNameTimeout ), FALSE },
|
|||
|
{ L"DuplicateEventlogTimeout", DEFAULT_DUPLICATEEVENTLOGTIMEOUT,MIN_DUPLICATEEVENTLOGTIMEOUT,MAX_DUPLICATEEVENTLOGTIMEOUT,getoffset( DuplicateEventlogTimeout ),FALSE },
|
|||
|
{ L"MaxConcurrentApi", DEFAULT_MAXCONCURRENTAPI, MIN_MAXCONCURRENTAPI, MAX_MAXCONCURRENTAPI, getoffset( MaxConcurrentApi ), FALSE },
|
|||
|
{ L"NegativeCachePeriod", DEFAULT_NEGATIVECACHEPERIOD, MIN_NEGATIVECACHEPERIOD, MAX_NEGATIVECACHEPERIOD, getoffset( NegativeCachePeriod ), FALSE },
|
|||
|
{ L"BackgroundRetryInitialPeriod", DEFAULT_BACKGROUNDRETRYINITIALPERIOD,MIN_BACKGROUNDRETRYINITIALPERIOD,MAX_BACKGROUNDRETRYINITIALPERIOD,getoffset( BackgroundRetryInitialPeriod ),FALSE },
|
|||
|
{ L"BackgroundRetryMaximumPeriod", DEFAULT_BACKGROUNDRETRYMAXIMUMPERIOD,MIN_BACKGROUNDRETRYMAXIMUMPERIOD,MAX_BACKGROUNDRETRYMAXIMUMPERIOD,getoffset( BackgroundRetryMaximumPeriod ),FALSE },
|
|||
|
{ L"BackgroundRetryQuitTime", DEFAULT_BACKGROUNDRETRYQUITTIME, MIN_BACKGROUNDRETRYQUITTIME, MAX_BACKGROUNDRETRYQUITTIME, getoffset( BackgroundRetryQuitTime ), FALSE },
|
|||
|
{ L"BackgroundSuccessfulRefreshPeriod", DEFAULT_BACKGROUNDREFRESHPERIOD, MIN_BACKGROUNDREFRESHPERIOD, MAX_BACKGROUNDREFRESHPERIOD, getoffset( BackgroundSuccessfulRefreshPeriod ), FALSE },
|
|||
|
{ L"NonBackgroundSuccessfulRefreshPeriod", DEFAULT_NONBACKGROUNDREFRESHPERIOD, MIN_NONBACKGROUNDREFRESHPERIOD, MAX_NONBACKGROUNDREFRESHPERIOD, getoffset( NonBackgroundSuccessfulRefreshPeriod ), FALSE },
|
|||
|
{ L"DnsFailedDeregisterTimeout", DEFAULT_DNSFAILEDDEREGTIMEOUT, MIN_DNSFAILEDDEREGTIMEOUT, MAX_DNSFAILEDDEREGTIMEOUT, getoffset( DnsFailedDeregisterTimeout ), FALSE },
|
|||
|
{ L"MaxLdapServersPinged", DEFAULT_MAXLDAPSERVERSPINGED, MIN_MAXLDAPSERVERSPINGED, MAX_MAXLDAPSERVERSPINGED, getoffset( MaxLdapServersPinged ), FALSE },
|
|||
|
#if NETLOGONDBG
|
|||
|
{ NETLOGON_KEYWORD_DBFLAG, 0, 0, 0xFFFFFFFF, getoffset( DbFlag ), FALSE },
|
|||
|
{ NETLOGON_KEYWORD_MAXIMUMLOGFILESIZE, DEFAULT_MAXIMUM_LOGFILE_SIZE, 0, 0xFFFFFFFF, getoffset( LogFileMaxSize ), FALSE },
|
|||
|
#endif // NETLOGONDBG
|
|||
|
};
|
|||
|
|
|||
|
//
|
|||
|
// Table of boolean to parse.
|
|||
|
//
|
|||
|
|
|||
|
struct {
|
|||
|
LPWSTR Keyword;
|
|||
|
BOOL DefaultValue;
|
|||
|
ULONG ValueOffset;
|
|||
|
BOOLEAN ChangesDnsRegistration;
|
|||
|
} BoolParseTable[] =
|
|||
|
{
|
|||
|
#ifdef _DC_NETLOGON
|
|||
|
{ NETLOGON_KEYWORD_REFUSEPASSWORDCHANGE, DEFAULT_REFUSE_PASSWORD_CHANGE, getoffset( RefusePasswordChange ), FALSE },
|
|||
|
{ NETLOGON_KEYWORD_ALLOWREPLINNONMIXED, DEFAULT_ALLOWREPLINNONMIXED, getoffset( AllowReplInNonMixed ), FALSE },
|
|||
|
{ L"AvoidSamRepl", TRUE, getoffset( AvoidSamRepl ), FALSE },
|
|||
|
{ L"AvoidLsaRepl", TRUE, getoffset( AvoidLsaRepl ), FALSE },
|
|||
|
{ L"SignSecureChannel", TRUE, getoffset( SignSecureChannel ), FALSE },
|
|||
|
{ L"SealSecureChannel", TRUE, getoffset( SealSecureChannel ), FALSE },
|
|||
|
{ L"RequireSignOrSeal", FALSE, getoffset( RequireSignOrSeal ), FALSE },
|
|||
|
{ L"RequireStrongKey", FALSE, getoffset( RequireStrongKey ), FALSE },
|
|||
|
{ L"SysVolReady", TRUE, getoffset( SysVolReady ), FALSE },
|
|||
|
{ L"UseDynamicDns", TRUE, getoffset( UseDynamicDns ), TRUE },
|
|||
|
{ L"RegisterDnsARecords", TRUE, getoffset( RegisterDnsARecords ), TRUE },
|
|||
|
{ L"AvoidPdcOnWan", FALSE, getoffset( AvoidPdcOnWan ), FALSE },
|
|||
|
{ L"AutoSiteCoverage", TRUE, getoffset( AutoSiteCoverage ), TRUE },
|
|||
|
{ L"AvoidDnsDeregOnShutdown", TRUE, getoffset(AvoidDnsDeregOnShutdown), TRUE },
|
|||
|
{ L"DnsUpdateOnAllAdapters", FALSE, getoffset(DnsUpdateOnAllAdapters), TRUE },
|
|||
|
{ NETLOGON_KEYWORD_NT4EMULATOR, FALSE, getoffset(Nt4Emulator), FALSE },
|
|||
|
#endif // _DC_NETLOGON
|
|||
|
{ NETLOGON_KEYWORD_DISABLEPASSWORDCHANGE, DEFAULT_DISABLE_PASSWORD_CHANGE, getoffset( DisablePasswordChange ), FALSE },
|
|||
|
{ NETLOGON_KEYWORD_NEUTRALIZENT4EMULATOR, FALSE,/* default is set later */ getoffset( NeutralizeNt4Emulator ), FALSE },
|
|||
|
{ L"AllowSingleLabelDnsDomain", FALSE, getoffset(AllowSingleLabelDnsDomain), FALSE },
|
|||
|
};
|
|||
|
|
|||
|
|
|||
|
VOID
|
|||
|
NlParseRecompute(
|
|||
|
IN PNETLOGON_PARAMETERS NlParameters
|
|||
|
)
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
This routine recomputes globals that are simple functions of registry
|
|||
|
parameters.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
NlParameters - Structure describing all parameters
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
None.
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
ULONG RandomMinutes;
|
|||
|
|
|||
|
//
|
|||
|
// Adjust values that are functions of each other.
|
|||
|
//
|
|||
|
|
|||
|
if ( NlParameters->BackgroundRetryInitialPeriod < NlParameters->NegativeCachePeriod ) {
|
|||
|
NlParameters->BackgroundRetryInitialPeriod = NlParameters->NegativeCachePeriod;
|
|||
|
}
|
|||
|
if ( NlParameters->BackgroundRetryMaximumPeriod < NlParameters->BackgroundRetryInitialPeriod ) {
|
|||
|
NlParameters->BackgroundRetryMaximumPeriod = NlParameters->BackgroundRetryInitialPeriod;
|
|||
|
}
|
|||
|
if ( NlParameters->BackgroundRetryQuitTime != 0 &&
|
|||
|
NlParameters->BackgroundRetryQuitTime < NlParameters->BackgroundRetryMaximumPeriod ) {
|
|||
|
NlParameters->BackgroundRetryQuitTime = NlParameters->BackgroundRetryMaximumPeriod;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Convert from seconds to 100ns
|
|||
|
//
|
|||
|
NlParameters->PulseMaximum_100ns.QuadPart =
|
|||
|
Int32x32To64( NlParameters->PulseMaximum, 10000000 );
|
|||
|
NlParameters->PulseTimeout1_100ns.QuadPart =
|
|||
|
Int32x32To64( NlParameters->PulseTimeout1, 10000000 );
|
|||
|
NlParameters->PulseTimeout2_100ns.QuadPart =
|
|||
|
Int32x32To64( NlParameters->PulseTimeout2, 10000000 );
|
|||
|
NlParameters->MailslotMessageTimeout_100ns.QuadPart =
|
|||
|
Int32x32To64( NlParameters->MailslotMessageTimeout, 10000000 );
|
|||
|
NlParameters->MailslotDuplicateTimeout_100ns.QuadPart =
|
|||
|
Int32x32To64( NlParameters->MailslotDuplicateTimeout, 10000000 );
|
|||
|
NlParameters->BackgroundRetryQuitTime_100ns.QuadPart =
|
|||
|
Int32x32To64( NlParameters->BackgroundRetryQuitTime, 10000000 );
|
|||
|
|
|||
|
|
|||
|
//
|
|||
|
// Convert from days to 100ns
|
|||
|
//
|
|||
|
NlParameters->MaximumPasswordAge_100ns.QuadPart =
|
|||
|
((LONGLONG) NlParameters->MaximumPasswordAge) *
|
|||
|
((LONGLONG) 10000000) *
|
|||
|
((LONGLONG) 24*60*60);
|
|||
|
|
|||
|
//
|
|||
|
// Add a fraction of a day to prevent all machines created at the same time
|
|||
|
// from changing their password at the same time.
|
|||
|
RandomMinutes = (DWORD) rand() % (24*60);
|
|||
|
NlParameters->MaximumPasswordAge_100ns.QuadPart +=
|
|||
|
((LONGLONG) RandomMinutes) *
|
|||
|
((LONGLONG) 10000000) *
|
|||
|
((LONGLONG) 60);
|
|||
|
#ifdef notdef
|
|||
|
NlPrint((NL_INIT," RandomMinutes = %lu (0x%lx)\n",
|
|||
|
RandomMinutes,
|
|||
|
RandomMinutes ));
|
|||
|
#endif // notdef
|
|||
|
|
|||
|
|
|||
|
NlParameters->ShortApiCallPeriod =
|
|||
|
SHORT_API_CALL_PERIOD + NlParameters->ExpectedDialupDelay * 1000;
|
|||
|
NlParameters->DnsRefreshIntervalPeriod =
|
|||
|
NlParameters->DnsRefreshInterval * 1000;
|
|||
|
if ( NlParameters->RequireSignOrSeal ) {
|
|||
|
NlParameters->SignSecureChannel = TRUE;
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
NET_API_STATUS
|
|||
|
NlParseTStr(
|
|||
|
IN LPNET_CONFIG_HANDLE SectionHandle,
|
|||
|
IN LPWSTR Keyword,
|
|||
|
IN BOOL MultivaluedParameter,
|
|||
|
IN OUT LPWSTR *DefaultValue,
|
|||
|
OUT LPWSTR *Parameter
|
|||
|
)
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
This routine parses a null or doubly-null terminated string
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
SectionHandle - Handle to a section in registry
|
|||
|
|
|||
|
Keyword - The name of the parameter to read
|
|||
|
|
|||
|
MultivaluedParameter - If TRUE, the keyword is a multiple
|
|||
|
string where elements are separated by a single null
|
|||
|
character and the array is ended with two null characters.
|
|||
|
If FALSE, the keyword is a single string ended with one
|
|||
|
null terminator.
|
|||
|
|
|||
|
DefaultValue - The default value of the parameter.
|
|||
|
|
|||
|
If NULL, the section handle passed is that of the Netlogon Parameters section.
|
|||
|
If non-NULL, the section handle passed is that of the GP section.
|
|||
|
If specified and used by this routine, it is set to NULL to indicate
|
|||
|
that it has been consumed by this routine.
|
|||
|
|
|||
|
Parameter - Returns the parameter read.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
Status returned by NetpGetConfigTStrArray.
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
NET_API_STATUS NetStatus;
|
|||
|
|
|||
|
//
|
|||
|
// Get the configured parameter
|
|||
|
//
|
|||
|
// GP doesn't support multivalued strings. Instead a single
|
|||
|
// string is used where individual strings are separated
|
|||
|
// by spaces.
|
|||
|
//
|
|||
|
|
|||
|
if ( MultivaluedParameter && DefaultValue == NULL ) {
|
|||
|
NetStatus = NetpGetConfigTStrArray (
|
|||
|
SectionHandle,
|
|||
|
Keyword,
|
|||
|
Parameter ); // Must be freed by NetApiBufferFree().
|
|||
|
} else {
|
|||
|
NetStatus = NetpGetConfigValue (
|
|||
|
SectionHandle,
|
|||
|
Keyword,
|
|||
|
Parameter ); // Must be freed by NetApiBufferFree().
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// If the parameter is empty string,
|
|||
|
// set it to NULL
|
|||
|
//
|
|||
|
|
|||
|
if ( NetStatus == NERR_Success &&
|
|||
|
(*Parameter)[0] == UNICODE_NULL ) {
|
|||
|
NetApiBufferFree( *Parameter );
|
|||
|
*Parameter = NULL;
|
|||
|
NetStatus = NERR_CfgParamNotFound;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Convert the single valued string into the multivalued form
|
|||
|
//
|
|||
|
|
|||
|
if ( NetStatus == NERR_Success && // we successfully read the registry
|
|||
|
MultivaluedParameter && // this is multivalued parameter
|
|||
|
DefaultValue != NULL ) { // we are parsing the GP section
|
|||
|
|
|||
|
ULONG ParameterLength = 0;
|
|||
|
LPWSTR LocalParameter = NULL;
|
|||
|
|
|||
|
//
|
|||
|
// The multivalued string will have two NULL terminator
|
|||
|
// characters at the end, so allocate enough storage
|
|||
|
//
|
|||
|
ParameterLength = wcslen(*Parameter);
|
|||
|
NetStatus = NetApiBufferAllocate( (ParameterLength + 2) * sizeof(WCHAR),
|
|||
|
&LocalParameter );
|
|||
|
|
|||
|
if ( NetStatus == NO_ERROR ) {
|
|||
|
LPWSTR ParameterPtr = NULL;
|
|||
|
LPWSTR LocalParameterPtr = NULL;
|
|||
|
|
|||
|
RtlZeroMemory( LocalParameter, (ParameterLength + 2) * sizeof(WCHAR) );
|
|||
|
|
|||
|
ParameterPtr = *Parameter;
|
|||
|
LocalParameterPtr = LocalParameter;
|
|||
|
while ( *ParameterPtr != UNICODE_NULL ) {
|
|||
|
|
|||
|
//
|
|||
|
// Disregard spaces in the input string. Note that
|
|||
|
// the user may have used several spaces to separate
|
|||
|
// two adjacent strings.
|
|||
|
//
|
|||
|
while ( *ParameterPtr == L' ' && *ParameterPtr != UNICODE_NULL ) {
|
|||
|
ParameterPtr ++;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Copy non-space characters
|
|||
|
//
|
|||
|
while ( *ParameterPtr != L' ' && *ParameterPtr != UNICODE_NULL ) {
|
|||
|
*LocalParameterPtr++ = *ParameterPtr++;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Insert one NULL character between single values
|
|||
|
//
|
|||
|
*LocalParameterPtr++ = UNICODE_NULL;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Free the value read from registry
|
|||
|
//
|
|||
|
NetApiBufferFree( *Parameter );
|
|||
|
*Parameter = NULL;
|
|||
|
|
|||
|
//
|
|||
|
// If the resulting multivalued string is not empty,
|
|||
|
// use it. The resulting string may need smaller
|
|||
|
// storage that we have allocated, so allocate again
|
|||
|
// exactly what's needed to (potentially) save memory.
|
|||
|
//
|
|||
|
ParameterLength = NetpTStrArraySize( LocalParameter ); // this includes all storage
|
|||
|
if ( ParameterLength > 2*sizeof(WCHAR) ) {
|
|||
|
NetStatus = NetApiBufferAllocate( ParameterLength, Parameter );
|
|||
|
if ( NetStatus == NO_ERROR ) {
|
|||
|
RtlCopyMemory( *Parameter, LocalParameter, ParameterLength );
|
|||
|
}
|
|||
|
|
|||
|
} else {
|
|||
|
NetStatus = ERROR_INVALID_PARAMETER;
|
|||
|
}
|
|||
|
|
|||
|
if ( LocalParameter != NULL ) {
|
|||
|
NetApiBufferFree( LocalParameter );
|
|||
|
LocalParameter = NULL;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Handle the default
|
|||
|
//
|
|||
|
|
|||
|
if ( NetStatus != NERR_Success ) {
|
|||
|
if ( DefaultValue == NULL ) {
|
|||
|
*Parameter = NULL;
|
|||
|
} else {
|
|||
|
*Parameter = *DefaultValue;
|
|||
|
|
|||
|
//
|
|||
|
// Indicate that we have consumed the
|
|||
|
// value from the default parameters
|
|||
|
//
|
|||
|
*DefaultValue = NULL;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Write event log on error
|
|||
|
//
|
|||
|
|
|||
|
if ( NetStatus != NERR_Success && NetStatus != NERR_CfgParamNotFound ) {
|
|||
|
LPWSTR MsgStrings[3];
|
|||
|
|
|||
|
if ( DefaultValue == NULL ) {
|
|||
|
MsgStrings[0] = L"Parameters";
|
|||
|
} else {
|
|||
|
MsgStrings[0] = L"Group Policy";
|
|||
|
}
|
|||
|
MsgStrings[1] = Keyword;
|
|||
|
MsgStrings[2] = (LPWSTR) ULongToPtr( NetStatus );
|
|||
|
|
|||
|
NlpWriteEventlog( NELOG_NetlogonInvalidGenericParameterValue,
|
|||
|
EVENTLOG_WARNING_TYPE,
|
|||
|
(LPBYTE)&NetStatus,
|
|||
|
sizeof(NetStatus),
|
|||
|
MsgStrings,
|
|||
|
3 | NETP_LAST_MESSAGE_IS_NETSTATUS );
|
|||
|
/* Not Fatal */
|
|||
|
}
|
|||
|
|
|||
|
return NetStatus;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
BOOL
|
|||
|
Nlparse(
|
|||
|
IN PNETLOGON_PARAMETERS NlParameters,
|
|||
|
IN PNETLOGON_PARAMETERS DefaultParameters OPTIONAL,
|
|||
|
IN BOOLEAN IsChangeNotify
|
|||
|
)
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Get parameters from the group policy or registry.
|
|||
|
|
|||
|
All of the parameters are described in iniparm.h.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
NlParameters - Structure describing all parameters
|
|||
|
|
|||
|
DefaultParameters - Structure describing default values for all parameters
|
|||
|
If NULL, the values are read from the Netlogon Parameters section and
|
|||
|
the default values specified in the parse table are used. If non-NULL,
|
|||
|
the values are read from the Group Policy section and the specified
|
|||
|
defaults are used.
|
|||
|
|
|||
|
IsChangeNotify - TRUE if this call is the result of a change notification
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
TRUE -- the registry was opened successfully and parameters
|
|||
|
were read.
|
|||
|
FALSE -- iff we couldn't open the appropriate registry section
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
BOOLEAN RetVal = TRUE;
|
|||
|
NET_API_STATUS NetStatus;
|
|||
|
NET_API_STATUS TempNetStatus;
|
|||
|
|
|||
|
LPWSTR ValueT = NULL;
|
|||
|
|
|||
|
LPWSTR Keyword = NULL;
|
|||
|
LPWSTR MsgStrings[3];
|
|||
|
ULONG i;
|
|||
|
|
|||
|
|
|||
|
//
|
|||
|
// Variables for scanning the configuration data.
|
|||
|
//
|
|||
|
|
|||
|
LPNET_CONFIG_HANDLE SectionHandle = NULL;
|
|||
|
LPNET_CONFIG_HANDLE WriteSectionHandle = NULL;
|
|||
|
RtlZeroMemory( NlParameters, sizeof(NlParameters) );
|
|||
|
|
|||
|
//
|
|||
|
// Open the appropriate configuration section
|
|||
|
//
|
|||
|
|
|||
|
NetStatus = NetpOpenConfigDataWithPathEx(
|
|||
|
&SectionHandle,
|
|||
|
NULL, // no server name.
|
|||
|
(DefaultParameters == NULL) ?
|
|||
|
L"SYSTEM\\CurrentControlSet\\Services\\Netlogon" :
|
|||
|
TEXT(NL_GP_KEY),
|
|||
|
NULL, // default Parameters area
|
|||
|
TRUE ); // we only want readonly access
|
|||
|
|
|||
|
if ( NetStatus != NO_ERROR ) {
|
|||
|
SectionHandle = NULL;
|
|||
|
|
|||
|
//
|
|||
|
// The Netlogon Parameters section must always
|
|||
|
// exist. Write event log if we can't open it.
|
|||
|
//
|
|||
|
if ( DefaultParameters == NULL ) {
|
|||
|
MsgStrings[0] = L"Parameters";
|
|||
|
MsgStrings[1] = L"Parameters";
|
|||
|
MsgStrings[2] = (LPWSTR) ULongToPtr( NetStatus );
|
|||
|
|
|||
|
NlpWriteEventlog( NELOG_NetlogonInvalidGenericParameterValue,
|
|||
|
EVENTLOG_WARNING_TYPE,
|
|||
|
(LPBYTE)&NetStatus,
|
|||
|
sizeof(NetStatus),
|
|||
|
MsgStrings,
|
|||
|
3 | NETP_LAST_MESSAGE_IS_NETSTATUS );
|
|||
|
}
|
|||
|
|
|||
|
RetVal = FALSE;
|
|||
|
goto Cleanup;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Loop parsing all the numeric parameters.
|
|||
|
//
|
|||
|
|
|||
|
for ( i=0; i<sizeof(ParseTable)/sizeof(ParseTable[0]); i++ ) {
|
|||
|
|
|||
|
NetStatus = NlParseOne(
|
|||
|
SectionHandle,
|
|||
|
(DefaultParameters != NULL),
|
|||
|
ParseTable[i].Keyword,
|
|||
|
(DefaultParameters == NULL) ?
|
|||
|
ParseTable[i].DefaultValue :
|
|||
|
*((PULONG)(((LPBYTE)DefaultParameters)+ParseTable[i].ValueOffset)),
|
|||
|
ParseTable[i].MinimumValue,
|
|||
|
ParseTable[i].MaximumValue,
|
|||
|
(PULONG)(((LPBYTE)NlParameters)+ParseTable[i].ValueOffset) );
|
|||
|
|
|||
|
if ( NetStatus != NERR_Success ) {
|
|||
|
|
|||
|
if ( DefaultParameters == NULL ) {
|
|||
|
MsgStrings[0] = L"Parameters";
|
|||
|
} else {
|
|||
|
MsgStrings[0] = L"Group Policy";
|
|||
|
}
|
|||
|
MsgStrings[1] = ParseTable[i].Keyword;
|
|||
|
MsgStrings[2] = (LPWSTR) ULongToPtr( NetStatus );
|
|||
|
|
|||
|
NlpWriteEventlog( NELOG_NetlogonInvalidGenericParameterValue,
|
|||
|
EVENTLOG_WARNING_TYPE,
|
|||
|
(LPBYTE)&NetStatus,
|
|||
|
sizeof(NetStatus),
|
|||
|
MsgStrings,
|
|||
|
3 | NETP_LAST_MESSAGE_IS_NETSTATUS );
|
|||
|
/* Not Fatal */
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Loop parsing all the boolean parameters.
|
|||
|
//
|
|||
|
|
|||
|
for ( i=0; i<sizeof(BoolParseTable)/sizeof(BoolParseTable[0]); i++ ) {
|
|||
|
|
|||
|
NetStatus = NetpGetConfigBool (
|
|||
|
SectionHandle,
|
|||
|
BoolParseTable[i].Keyword,
|
|||
|
(DefaultParameters == NULL) ?
|
|||
|
BoolParseTable[i].DefaultValue :
|
|||
|
*((PBOOL)(((LPBYTE)DefaultParameters)+BoolParseTable[i].ValueOffset)),
|
|||
|
(PBOOL)(((LPBYTE)NlParameters)+BoolParseTable[i].ValueOffset) );
|
|||
|
|
|||
|
//
|
|||
|
// NeutralizeNt4Emulator is a special case: it must be TRUE on DC
|
|||
|
//
|
|||
|
if ( NetStatus == NO_ERROR &&
|
|||
|
!NlGlobalMemberWorkstation &&
|
|||
|
wcscmp(BoolParseTable[i].Keyword, NETLOGON_KEYWORD_NEUTRALIZENT4EMULATOR) == 0 &&
|
|||
|
!(*((PBOOL)(((LPBYTE)NlParameters)+BoolParseTable[i].ValueOffset))) ) {
|
|||
|
|
|||
|
//
|
|||
|
// The code below will handle this error
|
|||
|
//
|
|||
|
NetStatus = ERROR_INVALID_PARAMETER;
|
|||
|
}
|
|||
|
|
|||
|
if (NetStatus != NO_ERROR) {
|
|||
|
|
|||
|
// Use a reasonable default
|
|||
|
if ( DefaultParameters == NULL ) {
|
|||
|
*(PBOOL)(((LPBYTE)NlParameters)+BoolParseTable[i].ValueOffset) =
|
|||
|
BoolParseTable[i].DefaultValue;
|
|||
|
} else {
|
|||
|
*(PBOOL)(((LPBYTE)NlParameters)+BoolParseTable[i].ValueOffset) =
|
|||
|
*((PBOOL)(((LPBYTE)DefaultParameters)+BoolParseTable[i].ValueOffset));
|
|||
|
}
|
|||
|
|
|||
|
if ( DefaultParameters == NULL ) {
|
|||
|
MsgStrings[0] = L"Parameters";
|
|||
|
} else {
|
|||
|
MsgStrings[0] = L"Group Policy";
|
|||
|
}
|
|||
|
MsgStrings[1] = BoolParseTable[i].Keyword;
|
|||
|
MsgStrings[2] = (LPWSTR) ULongToPtr( NetStatus );
|
|||
|
|
|||
|
NlpWriteEventlog( NELOG_NetlogonInvalidGenericParameterValue,
|
|||
|
EVENTLOG_WARNING_TYPE,
|
|||
|
(LPBYTE)&NetStatus,
|
|||
|
sizeof(NetStatus),
|
|||
|
MsgStrings,
|
|||
|
3 | NETP_LAST_MESSAGE_IS_NETSTATUS );
|
|||
|
/* Not Fatal */
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
#ifdef _DC_NETLOGON
|
|||
|
//
|
|||
|
// Get the "SysVol" configured parameter
|
|||
|
//
|
|||
|
|
|||
|
NetStatus = NlParseOnePath(
|
|||
|
SectionHandle,
|
|||
|
NETLOGON_KEYWORD_SYSVOL, // key wanted
|
|||
|
(DefaultParameters == NULL) ?
|
|||
|
DEFAULT_SYSVOL :
|
|||
|
DefaultParameters->UnicodeSysvolPath,
|
|||
|
&NlParameters->UnicodeSysvolPath );
|
|||
|
|
|||
|
|
|||
|
if ( NetStatus != NO_ERROR ) {
|
|||
|
NlParameters->UnicodeSysvolPath = NULL;
|
|||
|
|
|||
|
if ( DefaultParameters == NULL ) {
|
|||
|
MsgStrings[0] = L"Parameters";
|
|||
|
} else {
|
|||
|
MsgStrings[0] = L"Group Policy";
|
|||
|
}
|
|||
|
MsgStrings[1] = NETLOGON_KEYWORD_SYSVOL;
|
|||
|
MsgStrings[2] = (LPWSTR) ULongToPtr( NetStatus );
|
|||
|
|
|||
|
NlpWriteEventlog( NELOG_NetlogonInvalidGenericParameterValue,
|
|||
|
EVENTLOG_WARNING_TYPE,
|
|||
|
(LPBYTE)&NetStatus,
|
|||
|
sizeof(NetStatus),
|
|||
|
MsgStrings,
|
|||
|
3 | NETP_LAST_MESSAGE_IS_NETSTATUS );
|
|||
|
/* Not Fatal */
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Get the "SCRIPTS" configured parameter
|
|||
|
//
|
|||
|
// Default Script path is relative to Sysvol
|
|||
|
//
|
|||
|
|
|||
|
NetStatus = NlParseOnePath(
|
|||
|
SectionHandle,
|
|||
|
NETLOGON_KEYWORD_SCRIPTS, // key wanted
|
|||
|
(DefaultParameters == NULL) ?
|
|||
|
NULL : // No default (Default computed later)
|
|||
|
DefaultParameters->UnicodeScriptPath,
|
|||
|
&NlParameters->UnicodeScriptPath );
|
|||
|
|
|||
|
if ( NetStatus != NO_ERROR ) {
|
|||
|
NlParameters->UnicodeScriptPath = NULL;
|
|||
|
|
|||
|
if ( DefaultParameters == NULL ) {
|
|||
|
MsgStrings[0] = L"Parameters";
|
|||
|
} else {
|
|||
|
MsgStrings[0] = L"Group Policy";
|
|||
|
}
|
|||
|
MsgStrings[1] = NETLOGON_KEYWORD_SCRIPTS;
|
|||
|
MsgStrings[2] = (LPWSTR) ULongToPtr( NetStatus );
|
|||
|
|
|||
|
NlpWriteEventlog( NELOG_NetlogonInvalidGenericParameterValue,
|
|||
|
EVENTLOG_WARNING_TYPE,
|
|||
|
(LPBYTE)&NetStatus,
|
|||
|
sizeof(NetStatus),
|
|||
|
MsgStrings,
|
|||
|
3 | NETP_LAST_MESSAGE_IS_NETSTATUS );
|
|||
|
/* Not Fatal */
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
//
|
|||
|
// Get the "SiteName" configured parameter
|
|||
|
//
|
|||
|
|
|||
|
NetStatus = NlParseTStr( SectionHandle,
|
|||
|
NETLOGON_KEYWORD_SITENAME,
|
|||
|
FALSE, // single valued parameter
|
|||
|
(DefaultParameters == NULL) ?
|
|||
|
NULL :
|
|||
|
&DefaultParameters->SiteName,
|
|||
|
&NlParameters->SiteName );
|
|||
|
|
|||
|
NlParameters->SiteNameConfigured = (NetStatus == NO_ERROR);
|
|||
|
|
|||
|
//
|
|||
|
// If we are reading the Netlogon Parameters section ...
|
|||
|
//
|
|||
|
|
|||
|
if ( DefaultParameters == NULL ) {
|
|||
|
|
|||
|
//
|
|||
|
// If the site name is not configured, default it to the
|
|||
|
// dynamic site name determined by Netlogon
|
|||
|
//
|
|||
|
if ( NetStatus == NERR_CfgParamNotFound ) {
|
|||
|
NetStatus = NlParseTStr( SectionHandle,
|
|||
|
NETLOGON_KEYWORD_DYNAMICSITENAME,
|
|||
|
FALSE, // single valued parameter
|
|||
|
NULL,
|
|||
|
&NlParameters->SiteName );
|
|||
|
}
|
|||
|
//
|
|||
|
// If we are reading the GP section ...
|
|||
|
//
|
|||
|
|
|||
|
} else {
|
|||
|
|
|||
|
//
|
|||
|
// If the site name is not configured in the GP section,
|
|||
|
// may be it was configured in the Netlogon parameters section
|
|||
|
//
|
|||
|
if ( !NlParameters->SiteNameConfigured ) {
|
|||
|
NlParameters->SiteNameConfigured = DefaultParameters->SiteNameConfigured;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Get the "SiteCoverage" configured parameter
|
|||
|
//
|
|||
|
|
|||
|
NetStatus = NlParseTStr( SectionHandle,
|
|||
|
NETLOGON_KEYWORD_SITECOVERAGE,
|
|||
|
TRUE, // multivalued parameter
|
|||
|
(DefaultParameters == NULL) ?
|
|||
|
NULL :
|
|||
|
&DefaultParameters->SiteCoverage,
|
|||
|
&NlParameters->SiteCoverage );
|
|||
|
|
|||
|
//
|
|||
|
// Get the "GcSiteCoverage" configured parameter
|
|||
|
//
|
|||
|
|
|||
|
NetStatus = NlParseTStr( SectionHandle,
|
|||
|
NETLOGON_KEYWORD_GCSITECOVERAGE,
|
|||
|
TRUE, // multivalued parameter
|
|||
|
(DefaultParameters == NULL) ?
|
|||
|
NULL :
|
|||
|
&DefaultParameters->GcSiteCoverage,
|
|||
|
&NlParameters->GcSiteCoverage );
|
|||
|
|
|||
|
//
|
|||
|
// Get the "NdncSiteCoverage" configured parameter
|
|||
|
//
|
|||
|
|
|||
|
NetStatus = NlParseTStr( SectionHandle,
|
|||
|
NETLOGON_KEYWORD_NDNCSITECOVERAGE,
|
|||
|
TRUE, // multivalued parameter
|
|||
|
(DefaultParameters == NULL) ?
|
|||
|
NULL :
|
|||
|
&DefaultParameters->NdncSiteCoverage,
|
|||
|
&NlParameters->NdncSiteCoverage );
|
|||
|
|
|||
|
//
|
|||
|
// Get the "DnsAvoidRegisterRecords" configured parameter
|
|||
|
//
|
|||
|
|
|||
|
NetStatus = NlParseTStr( SectionHandle,
|
|||
|
NETLOGON_KEYWORD_DNSAVOIDNAME,
|
|||
|
TRUE, // multivalued parameter
|
|||
|
(DefaultParameters == NULL) ?
|
|||
|
NULL :
|
|||
|
&DefaultParameters->DnsAvoidRegisterRecords,
|
|||
|
&NlParameters->DnsAvoidRegisterRecords );
|
|||
|
#endif // _DC_NETLOGON
|
|||
|
|
|||
|
|
|||
|
//
|
|||
|
// Convert parameters to a more convenient form.
|
|||
|
//
|
|||
|
|
|||
|
NlParseRecompute( NlParameters );
|
|||
|
|
|||
|
|
|||
|
//
|
|||
|
// If the KerbIsDoneWithJoinDomainEntry key value is 1, delete the
|
|||
|
// Netlogon\JoinDomain entry. Also delete this entry if this machine is
|
|||
|
// a DC in which case neither we nor Kerberos needs this entry. (As a
|
|||
|
// matter of fact, Kerberos won't even create KerbIsDoneWithJoinDomainEntry
|
|||
|
// on a DC.)
|
|||
|
// Always delete KerbIsDoneWithJoinDomainEntry
|
|||
|
// Ignore errors
|
|||
|
//
|
|||
|
// Do this only on the change notify since netlogon needs this info
|
|||
|
// to set the client session first time after a reboot.
|
|||
|
//
|
|||
|
|
|||
|
if ( IsChangeNotify &&
|
|||
|
DefaultParameters == NULL ) { // KerbIsDoneWithJoinDomainEntry is in netlogon params
|
|||
|
|
|||
|
if ( NlParameters->KerbIsDoneWithJoinDomainEntry == 1 ||
|
|||
|
!NlGlobalMemberWorkstation )
|
|||
|
{
|
|||
|
ULONG WinError = ERROR_SUCCESS;
|
|||
|
HKEY hJoinKey = NULL;
|
|||
|
|
|||
|
|
|||
|
WinError = RegOpenKeyEx( HKEY_LOCAL_MACHINE,
|
|||
|
NETSETUPP_NETLOGON_JD_PATH,
|
|||
|
0,
|
|||
|
KEY_ALL_ACCESS,
|
|||
|
&hJoinKey);
|
|||
|
|
|||
|
if ( WinError == ERROR_SUCCESS)
|
|||
|
{
|
|||
|
WinError = RegDeleteKey( hJoinKey,
|
|||
|
NETSETUPP_NETLOGON_JD );
|
|||
|
|
|||
|
if ( WinError == ERROR_SUCCESS ) {
|
|||
|
NlPrint(( NL_INIT, "NlParse: Deleted JoinDomain reg key\n" ));
|
|||
|
}
|
|||
|
if (hJoinKey)
|
|||
|
{
|
|||
|
WinError = RegCloseKey(hJoinKey);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
TempNetStatus = NetpOpenConfigData(
|
|||
|
&WriteSectionHandle,
|
|||
|
NULL, // no server name.
|
|||
|
SERVICE_NETLOGON,
|
|||
|
FALSE); // writable, we are deleting it.
|
|||
|
|
|||
|
if ( TempNetStatus == NO_ERROR ) {
|
|||
|
TempNetStatus = NetpDeleteConfigKeyword ( WriteSectionHandle,
|
|||
|
NETLOGON_KEYWORD_KERBISDDONEWITHJOIN );
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
NetStatus = NERR_Success;
|
|||
|
|
|||
|
Cleanup:
|
|||
|
|
|||
|
//
|
|||
|
// Free any locally used resources
|
|||
|
//
|
|||
|
|
|||
|
if ( ValueT != NULL) {
|
|||
|
(VOID) NetApiBufferFree( ValueT );
|
|||
|
}
|
|||
|
if ( SectionHandle != NULL ) {
|
|||
|
(VOID) NetpCloseConfigData( SectionHandle );
|
|||
|
}
|
|||
|
|
|||
|
if ( WriteSectionHandle != NULL ) {
|
|||
|
(VOID) NetpCloseConfigData( WriteSectionHandle );
|
|||
|
}
|
|||
|
|
|||
|
return RetVal;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
BOOL
|
|||
|
NlparseAllSections(
|
|||
|
IN PNETLOGON_PARAMETERS NlParameters,
|
|||
|
IN BOOLEAN IsChangeNotify
|
|||
|
)
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Get parameters from both the Group Policy and the
|
|||
|
Netlogon Parameters registry sections.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
NlParameters - Structure describing all parameters
|
|||
|
|
|||
|
IsChangeNotify - TRUE if this call is the result of a change notification
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
TRUE -- iff the parse was successful.
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
NETLOGON_PARAMETERS NlLocalParameters;
|
|||
|
NETLOGON_PARAMETERS GpParameters;
|
|||
|
|
|||
|
RtlZeroMemory( &NlLocalParameters, sizeof(NlLocalParameters) );
|
|||
|
RtlZeroMemory( &GpParameters, sizeof(GpParameters) );
|
|||
|
|
|||
|
//
|
|||
|
// Do the one time initialization here
|
|||
|
//
|
|||
|
|
|||
|
if ( !IsChangeNotify ) {
|
|||
|
NT_PRODUCT_TYPE NtProductType;
|
|||
|
ULONG i;
|
|||
|
|
|||
|
//
|
|||
|
// Flag if this is a workstation (or member server)
|
|||
|
//
|
|||
|
|
|||
|
if ( !RtlGetNtProductType( &NtProductType ) ) {
|
|||
|
NtProductType = NtProductWinNt;
|
|||
|
}
|
|||
|
|
|||
|
if ( NtProductType == NtProductLanManNt ) {
|
|||
|
NlGlobalMemberWorkstation = FALSE;
|
|||
|
} else {
|
|||
|
NlGlobalMemberWorkstation = TRUE;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Set the right default for NeutralizeNt4Emulator that depends
|
|||
|
// on whether we are a DC or not
|
|||
|
//
|
|||
|
|
|||
|
for ( i=0; i<sizeof(BoolParseTable)/sizeof(BoolParseTable[0]); i++ ) {
|
|||
|
if ( wcscmp(BoolParseTable[i].Keyword, NETLOGON_KEYWORD_NEUTRALIZENT4EMULATOR) == 0 ) {
|
|||
|
if ( NlGlobalMemberWorkstation ) {
|
|||
|
BoolParseTable[i].DefaultValue = FALSE; // FALSE for a workstation
|
|||
|
} else {
|
|||
|
BoolParseTable[i].DefaultValue = TRUE; // TRUE for a DC
|
|||
|
}
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// First parse the new parameters from the Netlogon Parameters section
|
|||
|
//
|
|||
|
|
|||
|
if ( !Nlparse( &NlLocalParameters, NULL, IsChangeNotify ) ) {
|
|||
|
return FALSE; // error here is critical
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Next parse from the GP section using the parameters from the
|
|||
|
// Netlogon Parameters section as default
|
|||
|
//
|
|||
|
|
|||
|
if ( !Nlparse( &GpParameters, &NlLocalParameters, IsChangeNotify ) ) {
|
|||
|
|
|||
|
//
|
|||
|
// If the GP is not defined, use the parameters from
|
|||
|
// the Netlogon Parameters section
|
|||
|
//
|
|||
|
|
|||
|
*NlParameters = NlLocalParameters;
|
|||
|
NlPrint((NL_INIT, "Group Policy is not defined for Netlogon\n"));
|
|||
|
|
|||
|
} else {
|
|||
|
|
|||
|
*NlParameters = GpParameters;
|
|||
|
NlPrint((NL_INIT, "Group Policy is defined for Netlogon\n"));
|
|||
|
|
|||
|
//
|
|||
|
// Free whatever is left in the local Netlogon parameters
|
|||
|
//
|
|||
|
NlParseFree( &NlLocalParameters );
|
|||
|
}
|
|||
|
|
|||
|
#if NETLOGONDBG
|
|||
|
|
|||
|
//
|
|||
|
// Dump all the values on first invocation
|
|||
|
//
|
|||
|
|
|||
|
if ( !IsChangeNotify ) {
|
|||
|
ULONG i;
|
|||
|
|
|||
|
//
|
|||
|
// Be Verbose
|
|||
|
//
|
|||
|
|
|||
|
NlPrint((NL_INIT, "Following are the effective values after parsing\n"));
|
|||
|
|
|||
|
NlPrint((NL_INIT," Sysvol = " FORMAT_LPWSTR "\n",
|
|||
|
NlParameters->UnicodeSysvolPath));
|
|||
|
|
|||
|
NlPrint((NL_INIT," Scripts = " FORMAT_LPWSTR "\n",
|
|||
|
NlParameters->UnicodeScriptPath));
|
|||
|
|
|||
|
NlPrint((NL_INIT," SiteName (%ld) = " FORMAT_LPWSTR "\n",
|
|||
|
NlParameters->SiteNameConfigured,
|
|||
|
NlParameters->SiteName ));
|
|||
|
|
|||
|
{
|
|||
|
LPTSTR_ARRAY TStrArray;
|
|||
|
if ( NlParameters->SiteCoverage != NULL ) {
|
|||
|
NlPrint((NL_INIT," SiteCoverage = " ));
|
|||
|
TStrArray = NlParameters->SiteCoverage;
|
|||
|
while (!NetpIsTStrArrayEmpty(TStrArray)) {
|
|||
|
NlPrint((NL_INIT," '%ws'", TStrArray ));
|
|||
|
TStrArray = NetpNextTStrArrayEntry(TStrArray);
|
|||
|
}
|
|||
|
NlPrint((NL_INIT,"\n" ));
|
|||
|
}
|
|||
|
}
|
|||
|
{
|
|||
|
LPTSTR_ARRAY TStrArray;
|
|||
|
if ( NlParameters->GcSiteCoverage != NULL ) {
|
|||
|
NlPrint((NL_INIT," GcSiteCoverage = " ));
|
|||
|
TStrArray = NlParameters->GcSiteCoverage;
|
|||
|
while (!NetpIsTStrArrayEmpty(TStrArray)) {
|
|||
|
NlPrint((NL_INIT," '%ws'", TStrArray ));
|
|||
|
TStrArray = NetpNextTStrArrayEntry(TStrArray);
|
|||
|
}
|
|||
|
NlPrint((NL_INIT,"\n" ));
|
|||
|
}
|
|||
|
}
|
|||
|
{
|
|||
|
LPTSTR_ARRAY TStrArray;
|
|||
|
if ( NlParameters->NdncSiteCoverage != NULL ) {
|
|||
|
NlPrint((NL_INIT," NdncSiteCoverage = " ));
|
|||
|
TStrArray = NlParameters->NdncSiteCoverage;
|
|||
|
while (!NetpIsTStrArrayEmpty(TStrArray)) {
|
|||
|
NlPrint((NL_INIT," '%ws'", TStrArray ));
|
|||
|
TStrArray = NetpNextTStrArrayEntry(TStrArray);
|
|||
|
}
|
|||
|
NlPrint((NL_INIT,"\n" ));
|
|||
|
}
|
|||
|
}
|
|||
|
{
|
|||
|
LPTSTR_ARRAY TStrArray;
|
|||
|
if ( NlParameters->DnsAvoidRegisterRecords != NULL ) {
|
|||
|
NlPrint((NL_INIT," DnsAvoidRegisterRecords = " ));
|
|||
|
TStrArray = NlParameters->DnsAvoidRegisterRecords;
|
|||
|
while (!NetpIsTStrArrayEmpty(TStrArray)) {
|
|||
|
NlPrint((NL_INIT," '%ws'", TStrArray ));
|
|||
|
TStrArray = NetpNextTStrArrayEntry(TStrArray);
|
|||
|
}
|
|||
|
NlPrint((NL_INIT,"\n" ));
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
for ( i=0; i<sizeof(ParseTable)/sizeof(ParseTable[0]); i++ ) {
|
|||
|
NlPrint((NL_INIT,
|
|||
|
" %ws = %lu (0x%lx)\n",
|
|||
|
ParseTable[i].Keyword,
|
|||
|
*(PULONG)(((LPBYTE)NlParameters)+ParseTable[i].ValueOffset),
|
|||
|
*(PULONG)(((LPBYTE)NlParameters)+ParseTable[i].ValueOffset) ));
|
|||
|
}
|
|||
|
|
|||
|
for ( i=0; i<sizeof(BoolParseTable)/sizeof(BoolParseTable[0]); i++ ) {
|
|||
|
NlPrint(( NL_INIT,
|
|||
|
" %ws = %s\n",
|
|||
|
BoolParseTable[i].Keyword,
|
|||
|
(*(PBOOL)(((LPBYTE)NlParameters)+BoolParseTable[i].ValueOffset)) ?
|
|||
|
"TRUE":"FALSE" ));
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
#endif // NETLOGONDBG
|
|||
|
|
|||
|
return TRUE;
|
|||
|
}
|
|||
|
|
|||
|
VOID
|
|||
|
NlParseFree(
|
|||
|
IN PNETLOGON_PARAMETERS NlParameters
|
|||
|
)
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Free any allocated parameters.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
NlParameters - Structure describing all parameters
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
None.
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
if ( NlParameters->SiteName != NULL) {
|
|||
|
(VOID) NetApiBufferFree( NlParameters->SiteName );
|
|||
|
NlParameters->SiteName = NULL;
|
|||
|
}
|
|||
|
|
|||
|
if ( NlParameters->SiteCoverage != NULL) {
|
|||
|
(VOID) NetApiBufferFree( NlParameters->SiteCoverage );
|
|||
|
NlParameters->SiteCoverage = NULL;
|
|||
|
}
|
|||
|
|
|||
|
if ( NlParameters->GcSiteCoverage != NULL) {
|
|||
|
(VOID) NetApiBufferFree( NlParameters->GcSiteCoverage );
|
|||
|
NlParameters->GcSiteCoverage = NULL;
|
|||
|
}
|
|||
|
|
|||
|
if ( NlParameters->NdncSiteCoverage != NULL) {
|
|||
|
(VOID) NetApiBufferFree( NlParameters->NdncSiteCoverage );
|
|||
|
NlParameters->NdncSiteCoverage = NULL;
|
|||
|
}
|
|||
|
|
|||
|
if ( NlParameters->DnsAvoidRegisterRecords != NULL) {
|
|||
|
(VOID) NetApiBufferFree( NlParameters->DnsAvoidRegisterRecords );
|
|||
|
NlParameters->DnsAvoidRegisterRecords = NULL;
|
|||
|
}
|
|||
|
|
|||
|
if ( NlParameters->UnicodeScriptPath != NULL) {
|
|||
|
(VOID) NetApiBufferFree( NlParameters->UnicodeScriptPath );
|
|||
|
NlParameters->UnicodeScriptPath = NULL;
|
|||
|
}
|
|||
|
|
|||
|
if ( NlParameters->UnicodeSysvolPath != NULL) {
|
|||
|
(VOID) NetApiBufferFree( NlParameters->UnicodeSysvolPath );
|
|||
|
NlParameters->UnicodeSysvolPath = NULL;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
VOID
|
|||
|
NlReparse(
|
|||
|
VOID
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
|
|||
|
This routine handle a registry change notification.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
None.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
None
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
NETLOGON_PARAMETERS LocalParameters;
|
|||
|
ULONG i;
|
|||
|
LPWSTR TempString;
|
|||
|
|
|||
|
BOOLEAN UpdateDns = FALSE;
|
|||
|
BOOLEAN UpdateShares = FALSE;
|
|||
|
BOOLEAN UpdateSiteName = FALSE;
|
|||
|
|
|||
|
ULONG OldDnsTtl;
|
|||
|
BOOL OldSysVolReady;
|
|||
|
|
|||
|
BOOL OldDisablePasswordChange;
|
|||
|
ULONG OldScavengeInterval;
|
|||
|
ULONG OldMaximumPasswordAge;
|
|||
|
|
|||
|
//
|
|||
|
// Grab any old values that might be interesting.
|
|||
|
//
|
|||
|
|
|||
|
OldDnsTtl = NlGlobalParameters.DnsTtl;
|
|||
|
OldSysVolReady = NlGlobalParameters.SysVolReady;
|
|||
|
OldDisablePasswordChange = NlGlobalParameters.DisablePasswordChange;
|
|||
|
OldScavengeInterval = NlGlobalParameters.ScavengeInterval;
|
|||
|
OldMaximumPasswordAge = NlGlobalParameters.MaximumPasswordAge;
|
|||
|
|
|||
|
|
|||
|
//
|
|||
|
// Parse both sections in registry relevant to us
|
|||
|
//
|
|||
|
|
|||
|
if (! NlparseAllSections( &LocalParameters, TRUE ) ) {
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Be Verbose
|
|||
|
//
|
|||
|
|
|||
|
NlPrint((NL_INIT, "Following are the effective values after parsing\n"));
|
|||
|
|
|||
|
if ( (LocalParameters.UnicodeSysvolPath == NULL && NlGlobalParameters.UnicodeSysvolPath != NULL ) ||
|
|||
|
(LocalParameters.UnicodeSysvolPath != NULL && NlGlobalParameters.UnicodeSysvolPath == NULL ) ||
|
|||
|
(LocalParameters.UnicodeSysvolPath != NULL && NlGlobalParameters.UnicodeSysvolPath != NULL ) && _wcsicmp( LocalParameters.UnicodeSysvolPath, NlGlobalParameters.UnicodeSysvolPath) != 0 ) {
|
|||
|
NlPrint((NL_INIT," Sysvol = " FORMAT_LPWSTR "\n",
|
|||
|
LocalParameters.UnicodeSysvolPath));
|
|||
|
|
|||
|
// We can get away with this since only Netlogon's main thread touches
|
|||
|
// this variable.
|
|||
|
TempString = LocalParameters.UnicodeSysvolPath;
|
|||
|
LocalParameters.UnicodeSysvolPath = NlGlobalParameters.UnicodeSysvolPath;
|
|||
|
NlGlobalParameters.UnicodeSysvolPath = TempString;
|
|||
|
UpdateShares = TRUE;
|
|||
|
}
|
|||
|
|
|||
|
if ( (LocalParameters.UnicodeScriptPath == NULL && NlGlobalParameters.UnicodeScriptPath != NULL ) ||
|
|||
|
(LocalParameters.UnicodeScriptPath != NULL && NlGlobalParameters.UnicodeScriptPath == NULL ) ||
|
|||
|
(LocalParameters.UnicodeScriptPath != NULL && NlGlobalParameters.UnicodeScriptPath != NULL ) && _wcsicmp( LocalParameters.UnicodeScriptPath, NlGlobalParameters.UnicodeScriptPath) != 0 ) {
|
|||
|
|
|||
|
NlPrint((NL_INIT," Scripts = " FORMAT_LPWSTR "\n",
|
|||
|
LocalParameters.UnicodeScriptPath));
|
|||
|
|
|||
|
// We can get away with this since only Netlogon's main thread touches
|
|||
|
// this variable.
|
|||
|
TempString = LocalParameters.UnicodeScriptPath;
|
|||
|
LocalParameters.UnicodeScriptPath = NlGlobalParameters.UnicodeScriptPath;
|
|||
|
NlGlobalParameters.UnicodeScriptPath = TempString;
|
|||
|
UpdateShares = TRUE;
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
if ( (LocalParameters.SiteNameConfigured != NlGlobalParameters.SiteNameConfigured ) ||
|
|||
|
(LocalParameters.SiteName == NULL && NlGlobalParameters.SiteName != NULL ) ||
|
|||
|
(LocalParameters.SiteName != NULL && NlGlobalParameters.SiteName == NULL ) ||
|
|||
|
(LocalParameters.SiteName != NULL && NlGlobalParameters.SiteName != NULL ) && _wcsicmp( LocalParameters.SiteName, NlGlobalParameters.SiteName) != 0 ) {
|
|||
|
|
|||
|
NlPrint((NL_INIT," SiteName (%ld) = " FORMAT_LPWSTR "\n",
|
|||
|
LocalParameters.SiteNameConfigured,
|
|||
|
LocalParameters.SiteName ));
|
|||
|
|
|||
|
// We can get away with this since only Netlogon's main thread touches
|
|||
|
// this variable.
|
|||
|
TempString = LocalParameters.SiteName;
|
|||
|
LocalParameters.SiteName = NlGlobalParameters.SiteName;
|
|||
|
NlGlobalParameters.SiteName = TempString;
|
|||
|
NlGlobalParameters.SiteNameConfigured = LocalParameters.SiteNameConfigured;
|
|||
|
UpdateSiteName = TRUE;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Handle SiteCoverage changing
|
|||
|
//
|
|||
|
|
|||
|
if ( NlSitesSetSiteCoverageParam( DOM_REAL_DOMAIN, LocalParameters.SiteCoverage ) ) {
|
|||
|
|
|||
|
LPTSTR_ARRAY TStrArray;
|
|||
|
|
|||
|
NlPrint((NL_INIT," SiteCoverage = " ));
|
|||
|
|
|||
|
TStrArray = LocalParameters.SiteCoverage;
|
|||
|
if ( TStrArray == NULL ) {
|
|||
|
NlPrint((NL_INIT,"<NULL>" ));
|
|||
|
} else {
|
|||
|
while (!NetpIsTStrArrayEmpty(TStrArray)) {
|
|||
|
NlPrint((NL_INIT," '%ws'", TStrArray ));
|
|||
|
TStrArray = NetpNextTStrArrayEntry(TStrArray);
|
|||
|
}
|
|||
|
}
|
|||
|
NlPrint((NL_INIT,"\n" ));
|
|||
|
|
|||
|
// NlSitesSetSiteCoverageParam used this allocated buffer
|
|||
|
LocalParameters.SiteCoverage = NULL;
|
|||
|
|
|||
|
UpdateDns = TRUE;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Handle GcSiteCoverage changing
|
|||
|
//
|
|||
|
|
|||
|
if ( NlSitesSetSiteCoverageParam( DOM_FOREST, LocalParameters.GcSiteCoverage ) ) {
|
|||
|
|
|||
|
LPTSTR_ARRAY TStrArray;
|
|||
|
|
|||
|
NlPrint((NL_INIT," GcSiteCoverage = " ));
|
|||
|
|
|||
|
TStrArray = LocalParameters.GcSiteCoverage;
|
|||
|
if ( TStrArray == NULL ) {
|
|||
|
NlPrint((NL_INIT,"<NULL>" ));
|
|||
|
} else {
|
|||
|
while (!NetpIsTStrArrayEmpty(TStrArray)) {
|
|||
|
NlPrint((NL_INIT," '%ws'", TStrArray ));
|
|||
|
TStrArray = NetpNextTStrArrayEntry(TStrArray);
|
|||
|
}
|
|||
|
}
|
|||
|
NlPrint((NL_INIT,"\n" ));
|
|||
|
|
|||
|
// NlSitesSetSiteCoverageParam used this allocated buffer
|
|||
|
LocalParameters.GcSiteCoverage = NULL;
|
|||
|
|
|||
|
UpdateDns = TRUE;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Handle NdncSiteCoverage changing
|
|||
|
//
|
|||
|
|
|||
|
if ( NlSitesSetSiteCoverageParam( DOM_NON_DOMAIN_NC, LocalParameters.NdncSiteCoverage ) ) {
|
|||
|
|
|||
|
LPTSTR_ARRAY TStrArray;
|
|||
|
|
|||
|
NlPrint((NL_INIT," NdncSiteCoverage = " ));
|
|||
|
|
|||
|
TStrArray = LocalParameters.NdncSiteCoverage;
|
|||
|
if ( TStrArray == NULL ) {
|
|||
|
NlPrint((NL_INIT,"<NULL>" ));
|
|||
|
} else {
|
|||
|
while (!NetpIsTStrArrayEmpty(TStrArray)) {
|
|||
|
NlPrint((NL_INIT," '%ws'", TStrArray ));
|
|||
|
TStrArray = NetpNextTStrArrayEntry(TStrArray);
|
|||
|
}
|
|||
|
}
|
|||
|
NlPrint((NL_INIT,"\n" ));
|
|||
|
|
|||
|
// NlSitesSetSiteCoverageParam used this allocated buffer
|
|||
|
LocalParameters.NdncSiteCoverage = NULL;
|
|||
|
|
|||
|
UpdateDns = TRUE;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Handle DnsAvoidRegisterRecords changing
|
|||
|
//
|
|||
|
|
|||
|
if ( NlDnsSetAvoidRegisterNameParam( LocalParameters.DnsAvoidRegisterRecords ) ) {
|
|||
|
|
|||
|
LPTSTR_ARRAY TStrArray;
|
|||
|
|
|||
|
NlPrint((NL_INIT," DnsAvoidRegisterRecords = " ));
|
|||
|
|
|||
|
TStrArray = LocalParameters.DnsAvoidRegisterRecords;
|
|||
|
if ( TStrArray == NULL ) {
|
|||
|
NlPrint((NL_INIT,"<NULL>" ));
|
|||
|
} else {
|
|||
|
while (!NetpIsTStrArrayEmpty(TStrArray)) {
|
|||
|
NlPrint((NL_INIT," '%ws'", TStrArray ));
|
|||
|
TStrArray = NetpNextTStrArrayEntry(TStrArray);
|
|||
|
}
|
|||
|
}
|
|||
|
NlPrint((NL_INIT,"\n" ));
|
|||
|
|
|||
|
// NlSitesSetSiteCoverageParam used this allocated buffer
|
|||
|
LocalParameters.DnsAvoidRegisterRecords = NULL;
|
|||
|
|
|||
|
UpdateDns = TRUE;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Install all the numeric parameters.
|
|||
|
//
|
|||
|
|
|||
|
for ( i=0; i<sizeof(ParseTable)/sizeof(ParseTable[0]); i++ ) {
|
|||
|
if ( (*(PULONG)(((LPBYTE)(&LocalParameters))+ParseTable[i].ValueOffset) !=
|
|||
|
*(PULONG)(((LPBYTE)(&NlGlobalParameters))+ParseTable[i].ValueOffset) ) ) {
|
|||
|
NlPrint((NL_INIT,
|
|||
|
" %ws = %lu (0x%lx)\n",
|
|||
|
ParseTable[i].Keyword,
|
|||
|
*(PULONG)(((LPBYTE)(&LocalParameters))+ParseTable[i].ValueOffset),
|
|||
|
*(PULONG)(((LPBYTE)(&LocalParameters))+ParseTable[i].ValueOffset) ));
|
|||
|
|
|||
|
//
|
|||
|
// Actually set the value
|
|||
|
//
|
|||
|
*(PULONG)(((LPBYTE)(&NlGlobalParameters))+ParseTable[i].ValueOffset) =
|
|||
|
*(PULONG)(((LPBYTE)(&LocalParameters))+ParseTable[i].ValueOffset);
|
|||
|
|
|||
|
//
|
|||
|
// If this changed value affects DNS,
|
|||
|
// note that fact.
|
|||
|
//
|
|||
|
|
|||
|
if ( ParseTable[i].ChangesDnsRegistration ) {
|
|||
|
UpdateDns = TRUE;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
for ( i=0; i<sizeof(BoolParseTable)/sizeof(BoolParseTable[0]); i++ ) {
|
|||
|
if ( (*(PULONG)(((LPBYTE)(&LocalParameters))+BoolParseTable[i].ValueOffset) !=
|
|||
|
*(PULONG)(((LPBYTE)(&NlGlobalParameters))+BoolParseTable[i].ValueOffset) ) ) {
|
|||
|
|
|||
|
NlPrint(( NL_INIT,
|
|||
|
" %ws = %s\n",
|
|||
|
BoolParseTable[i].Keyword,
|
|||
|
(*(PBOOL)(((LPBYTE)(&LocalParameters))+BoolParseTable[i].ValueOffset)) ?
|
|||
|
"TRUE":"FALSE" ));
|
|||
|
|
|||
|
//
|
|||
|
// Actually set the value
|
|||
|
//
|
|||
|
*(PULONG)(((LPBYTE)(&NlGlobalParameters))+BoolParseTable[i].ValueOffset) =
|
|||
|
*(PULONG)(((LPBYTE)(&LocalParameters))+BoolParseTable[i].ValueOffset);
|
|||
|
|
|||
|
//
|
|||
|
// If this changed value affects DNS,
|
|||
|
// note that fact.
|
|||
|
//
|
|||
|
|
|||
|
if ( BoolParseTable[i].ChangesDnsRegistration ) {
|
|||
|
UpdateDns = TRUE;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// If this changed value affects LSA, inform it
|
|||
|
//
|
|||
|
if ( !NlGlobalMemberWorkstation &&
|
|||
|
wcscmp(BoolParseTable[i].Keyword, NETLOGON_KEYWORD_NT4EMULATOR) == 0 ) {
|
|||
|
|
|||
|
LsaINotifyNetlogonParametersChangeW(
|
|||
|
LsaEmulateNT4,
|
|||
|
REG_DWORD,
|
|||
|
(PWSTR)&NlGlobalParameters.Nt4Emulator,
|
|||
|
sizeof(NlGlobalParameters.Nt4Emulator) );
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Convert parameters to a more convenient form.
|
|||
|
//
|
|||
|
|
|||
|
NlParseRecompute( &NlGlobalParameters );
|
|||
|
|
|||
|
//
|
|||
|
// Notify other components of parameters that have changed.
|
|||
|
//
|
|||
|
|
|||
|
//
|
|||
|
// Enable detection of duplicate event log messages
|
|||
|
//
|
|||
|
NetpEventlogSetTimeout ( NlGlobalEventlogHandle,
|
|||
|
NlGlobalParameters.DuplicateEventlogTimeout*1000 );
|
|||
|
|
|||
|
|
|||
|
//
|
|||
|
// Do member workstation specific updates
|
|||
|
//
|
|||
|
|
|||
|
if ( NlGlobalMemberWorkstation ) {
|
|||
|
|
|||
|
//
|
|||
|
// Update site name
|
|||
|
//
|
|||
|
if ( UpdateSiteName ) {
|
|||
|
(VOID) NlSetSiteName( NlGlobalParameters.SiteName, NULL );
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Do DC specific updates
|
|||
|
//
|
|||
|
} else {
|
|||
|
//
|
|||
|
// Re-register DNS records
|
|||
|
//
|
|||
|
// If DnsTtl has changed,
|
|||
|
// force all records to be registered.
|
|||
|
//
|
|||
|
|
|||
|
if ( UpdateDns ) {
|
|||
|
NlDnsPnp( NlGlobalParameters.DnsTtl != OldDnsTtl );
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Update the Netlogon and Sysvol shares
|
|||
|
//
|
|||
|
|
|||
|
if ( UpdateShares || OldSysVolReady != NlGlobalParameters.SysVolReady ) {
|
|||
|
NlCreateSysvolShares();
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// If the settings that affect the scavenger have changed,
|
|||
|
// trigger it now.
|
|||
|
//
|
|||
|
|
|||
|
if ( OldDisablePasswordChange != NlGlobalParameters.DisablePasswordChange ||
|
|||
|
OldScavengeInterval != NlGlobalParameters.ScavengeInterval ||
|
|||
|
OldMaximumPasswordAge != NlGlobalParameters.MaximumPasswordAge ) {
|
|||
|
|
|||
|
//
|
|||
|
// We don't need to set NlGlobalTimerEvent since we're already processing
|
|||
|
// a registry notification event. That'll make NlMainLoop notice the change.
|
|||
|
//
|
|||
|
EnterCriticalSection( &NlGlobalScavengerCritSect );
|
|||
|
NlGlobalScavengerTimer.Period = 0;
|
|||
|
LeaveCriticalSection( &NlGlobalScavengerCritSect );
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
// Cleanup:
|
|||
|
NlParseFree( &LocalParameters );
|
|||
|
return;
|
|||
|
|
|||
|
}
|