Windows NT 4.0 source code leak
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

1375 lines
33 KiB

/*++
Copyright (c) 1991 Microsoft Corporation
Module Name:
ssiinit.h
Abstract:
Private global variables, defines, and routine declarations used for
to implement SSI.
Author:
Cliff Van Dyke (cliffv) 25-Jul-1991
Environment:
User mode only.
Contains NT-specific code.
Requires ANSI C extensions: slash-slash comments, long external names.
Revision History:
02-Jan-1992 (madana)
added support for builtin/multidomain replication.
04-10-1992 (madana)
added support for LSA replication.
--*/
//
// srvsess.c will #include this file with INITSSI_ALLOCATE defined.
// That will cause each of these variables to be allocated.
//
#ifdef INITSSI_ALLOCATE
#define EXTERN
#else
#define EXTERN extern
#endif
// general purpose mainfests
//
// How frequently we scavenge the LogonTable.
//
#define LOGON_INTERROGATE_PERIOD (15*60*1000) // make it 15 mins
//
// How long we wait for a discovery response.
//
#define DISCOVERY_PERIOD (5*1000) // 5 seconds
//
// Maximum time we'll wait during full sync in an attempt to decrease
// wan link utilization.
//
#define MAX_SYNC_SLEEP_TIME (60*60*1000) // 1 hour
//
// How big a buffer we request on a SAM delta or a SAM sync.
//
#define SAM_DELTA_BUFFER_SIZE (128*1024)
//
// The size of the largest mailslot message.
//
// All mailslot messages we receive are broadcast. The Win32 spec says
// the limit on broadcast mailslot is 400 bytes. Really it is
// 444 bytes (512 minus SMB header etc) - size of the mailslot name.
// I'll use 444 to ensure this size is the largest I'll ever need.
//
#define NETLOGON_MAX_MS_SIZE 444
/////////////////////////////////////////////////////////////////////////////
//
// Client Session definitions
//
/////////////////////////////////////////////////////////////////////////////
//
// An internal timer used to schedule a periodic event.
//
typedef struct _TIMER {
LARGE_INTEGER StartTime; // Start of period (NT absolute time)
DWORD Period; // length of period (miliseconds)
} TIMER, *PTIMER;
//
// Client session.
//
// Structure to define the client side of a session to a DC.
//
typedef struct _CLIENT_SESSION {
//
// Each client session entry is in a doubly linked list defined by
// NlGlobalTrustList.
//
// Access serialized by NlGlobalTrustListCritSect.
//
LIST_ENTRY CsNext;
//
// Time when the last authentication attempt was made.
//
// When the CsState is CS_AUTHENTICATED, this field is the time the
// secure channel was setup.
//
// When the CsState is CS_IDLE, this field is the time of the last
// failed discovery or session setup. Or it may be zero, to indicate
// that it is OK to do another discovery at any time.
//
// When the CsState is CS_DC_PICKED, this field is zero indicating it is
// OK to do the session setup at any time. Or it may be the time of the
// last failed session set if different threads did the setup/discovery.
//
// Access serialized by NlGlobalDcDiscoveryCritSect
//
LARGE_INTEGER CsLastAuthenticationTry;
//
// Time when the last discovery attempt was made.
//
// The time is the time of completion of the last discovery attempt regardless
// of the success or failure of that attemp.
//
// Access serialized by NlGlobalDcDiscoveryCritSect
//
LARGE_INTEGER CsLastDiscoveryTime;
//
// Each API call made across this secure channel is timed by this timer.
// If the timer expires, the session to the server is forcefully
// terminated to ensure the client doesn't hang for a dead server.
//
// Access serialized by NlGlobalTrustListCritSect.
//
TIMER CsApiTimer;
#define SHORT_API_CALL_PERIOD (45*1000) // Logon API lasts 45 seconds
#define LONG_API_CALL_PERIOD (15*60*1000) // Replication API 15 minute
#define BINDING_CACHE_PERIOD (3*60*1000) // Cache RPC handle for 3 minutes
#define WRITER_WAIT_PERIOD NlGlobalShortApiCallPeriod // Max time to wait to become writer
//
// Name of the domain this connection is to
//
UNICODE_STRING CsDomainName;
//
// Domain ID of the domain this connection is to
//
PSID CsDomainId;
//
// Type of CsAccountName
//
NETLOGON_SECURE_CHANNEL_TYPE CsSecureChannelType;
//
// State of the connection to the server.
//
// Access serialized by NlGlobalDcDiscoveryCritSect
// This field can be read without the crit sect locked if
// the answer will only be used as a hint.
//
DWORD CsState;
#define CS_IDLE 0 // No session is currently active
#define CS_DC_PICKED 1 // The session has picked a DC for session
#define CS_AUTHENTICATED 2 // The session is currently active
//
// Status of latest attempt to contact the server.
//
// When the CsState is CS_AUTHENTICATED, this field is STATUS_SUCCESS.
//
// When the CsState is CS_IDLE, this field is a non-successful status.
//
// When the CsState is CS_DC_PICKED, this field is the same non-successful
// status from when the CsState was last CS_IDLE.
//
// Access serialized by NlGlobalDcDiscoveryCritSect
// This field can be read without the crit sect locked if
// the answer will only be used as a hint.
//
NTSTATUS CsConnectionStatus;
//
// Access serialized by NlGlobalTrustListCritSect.
//
DWORD CsFlags;
#define CS_UPDATE_PASSWORD 0x01 // Set if the password has already
// been changed on the client and
// needs changing on the server.
#define CS_PASSWORD_REFUSED 0x02 // Set if DC refused a password change.
#define CS_DELETE_ON_UNREF 0x04 // Delete entry when CsReferenceCount
// reaches zero.
#define CS_WRITER 0x08 // Entry is being modified
#define CS_HANDLE_TIMER 0x10 // Set if we need to handle timer expiration
#define CS_CHECK_PASSWORD 0x20 // Set if we need to check the password
#define CS_PICK_DC 0x40 // Set if we need to Pick a DC
#define CS_REDISCOVER_DC 0x80 // Set when we need to Rediscover a DC
#define CS_BINDING_CACHED 0x100 // Set if the binding handle is cached
#define CS_HANDLE_API_TIMER 0x200 // Set if we need to handle API timer expiration
//
// Flags describing capabilities of both client and server.
//
ULONG CsNegotiatedFlags;
//
// Time Number of authentication attempts since last success.
//
// Access serialized by CsWriterSemaphore.
//
DWORD CsAuthAlertCount;
//
// Number of threads referencing this entry.
//
// Access serialized by NlGlobalTrustListCritSect.
//
DWORD CsReferenceCount;
//
// Writer semaphore.
//
// This semaphore is locked whenever there is a writer modifying
// fields in this client session.
//
HANDLE CsWriterSemaphore;
//
// The following fields are used by the NlDcDiscoveryMachine to keep track
// of discovery state.
//
// Access serialized by NlGlobalDcDiscoveryCritSect
//
DWORD CsDiscoveryRetryCount;
DWORD CsDiscoveryFlags;
#define CS_DISCOVERY_IN_PROGRESS 0x01 // Discovery is currently happening
#define CS_DISCOVERY_ASYNCHRONOUS 0x02 // Waiting on NlGlobalDiscoveryTimer
//
// This event is set to indicate that discovery is not in progress on this
// client session.
//
HANDLE CsDiscoveryEvent;
//
// API timout count. After each logon/logoff API call made to the
// server this count is incremented if the time taken to execute the
// this API is more than the specified TIMEOUT.
//
// Access serialized by CsWriterSemaphore.
//
DWORD CsTimeoutCount;
#define MAX_DC_TIMEOUT_COUNT 2
#define MAX_WKSTA_TIMEOUT_COUNT 2 // drop the session after this
// many timeouts and when it is
// time to reauthenticate.
#define MAX_DC_API_TIMEOUT (long) (15L*1000L) // 15 seconds
#define MAX_WKSTA_API_TIMEOUT (long) (15L*1000L) // 15 seconds
#define MAX_DC_REAUTHENTICATION_WAIT (long) (5L*60L*1000L) // 5 mins
#define MAX_WKSTA_REAUTHENTICATION_WAIT (long) (5L*60L*1000L) // 5 mins
//
// Authentication information.
//
// Access serialized by CsWriterSemaphore.
//
NETLOGON_CREDENTIAL CsAuthenticationSeed;
NETLOGON_SESSION_KEY CsSessionKey;
//
// Transport the server was discovered on.
//
LPWSTR CsTransportName;
//
// Name of the server this connection is to.
//
// Access serialized by CsWriterSemaphore or NlGlobalDcDiscoveryCritSect.
// Modification from Null to non-null serialized by
// NlGlobalDcDiscoveryCritSect
// (Modification from non-null to null requires both to be locked.)
//
WCHAR CsUncServerName[UNCLEN+1];
//
// Name of the account used to contact server
//
WCHAR CsAccountName[SSI_ACCOUNT_NAME_LENGTH+1];
} CLIENT_SESSION, * PCLIENT_SESSION;
//
// To serialize access to trust list and NlGlobalClientSession
//
EXTERN CRITICAL_SECTION NlGlobalTrustListCritSect;
//
// The list of trusted domains
//
EXTERN LIST_ENTRY NlGlobalTrustList;
EXTERN DWORD NlGlobalTrustListLength; // Number of entries in NlGlobalTrustList
//
// For workstations and non-DC servers,
// maintain a list of domains trusted by our primary domain.
//
typedef struct {
CHAR DomainName[DNLEN+1];
} TRUSTED_DOMAIN, *PTRUSTED_DOMAIN;
EXTERN PTRUSTED_DOMAIN NlGlobalTrustedDomainList;
EXTERN DWORD NlGlobalTrustedDomainCount;
EXTERN BOOL NlGlobalTrustedDomainListKnown;
EXTERN LARGE_INTEGER NlGlobalTrustedDomainListTime;
//
// For BDC, these are the credentials used to communicate with the PDC.
// For a workstation, these are the credentials used to communicate with a DC.
//
EXTERN PCLIENT_SESSION NlGlobalClientSession;
#define LOCK_TRUST_LIST() EnterCriticalSection( &NlGlobalTrustListCritSect )
#define UNLOCK_TRUST_LIST() LeaveCriticalSection( &NlGlobalTrustListCritSect )
//
// Serialize DC Discovery activities
//
EXTERN CRITICAL_SECTION NlGlobalDcDiscoveryCritSect;
//
// Timer for timing out async DC discovery
//
EXTERN TIMER NlGlobalDcDiscoveryTimer;
EXTERN DWORD NlGlobalDcDiscoveryCount;
//
// Timer for timing out API calls to trusted domains
//
// Serialized using NlGlobalTrustListCritSect.
//
EXTERN TIMER NlGlobalApiTimer;
EXTERN DWORD NlGlobalBindingHandleCount;
/////////////////////////////////////////////////////////////////////////////
//
// Server Session definitions
//
/////////////////////////////////////////////////////////////////////////////
//
// Sam Sync Context.
//
// A Sam sync context is maintained on the PDC for each BDC/member currently
// doing a full sync.
//
typedef struct _SAM_SYNC_CONTEXT {
//
// The Sync state indicates tracks the progression of the sync.
//
SYNC_STATE SyncState;
//
// A serial number indicating the number of times the BDC/member
// has called us. We use this as a resume handle.
//
ULONG SyncSerial;
//
// The current Sam Enumeration information
//
SAM_ENUMERATE_HANDLE SamEnumHandle; // Current Sam Enum Handle
PSAMPR_ENUMERATION_BUFFER SamEnum; // Sam returned buffer
PULONG RidArray; // Array of enumerated Rids
ULONG Index; // Index to current entry
ULONG Count; // Total Number of entries
BOOL SamAllDone; // True, if Sam has completed
#define UAS_BUILTIN_ADMINS_GROUP 0x01 // bit 0
#define UAS_BUILTIN_USERS_GROUP 0x02 // bit 1
#define UAS_BUILTIN_GUESTS_GROUP 0x04 // bit 2
#define UAS_BUILTIN_GROUPS_COUNT 0x03
#define UAS_BUILTIN_ADMINS_GROUP_NAME L"ADMINS"
#define UAS_BUILTIN_USERS_GROUP_NAME L"USERS"
#define UAS_BUILTIN_GUESTS_GROUP_NAME L"GUESTS"
DWORD UasBuiltinGroups; // flag to determine the
// presence of uas builtin
// groups
} SAM_SYNC_CONTEXT, *PSAM_SYNC_CONTEXT;
#define SAM_SYNC_PREF_MAX 1024 // Preferred max for Sam Sync
//
// Lsa Sync Context.
//
// A Lsa sync context is maintained on the PDC for each BDC/member
// currently doing a full sync.
//
typedef struct _LSA_SYNC_CONTEXT {
//
// The Sync state indicates tracks the progression of the sync.
//
enum {
AccountState,
TDomainState,
SecretState,
LsaDoneState
} SyncState;
//
// A serial number indicating the number of times the BDC/member
// has called us. We use this as a resume handle.
//
ULONG SyncSerial;
//
// The current Lsa Enumeration information
//
LSA_ENUMERATION_HANDLE LsaEnumHandle; // Current Lsa Enum Handle
enum {
AccountEnumBuffer,
TDomainEnumBuffer,
SecretEnumBuffer,
EmptyEnumBuffer
} LsaEnumBufferType;
union {
LSAPR_ACCOUNT_ENUM_BUFFER Account;
LSAPR_TRUSTED_ENUM_BUFFER TDomain;
PVOID Secret;
} LsaEnum; // Lsa returned buffer
ULONG Index; // Index to current entry
ULONG Count; // Total Number of entries
BOOL LsaAllDone; // True, if Lsa has completed
} LSA_SYNC_CONTEXT, *PLSA_SYNC_CONTEXT;
//
// union of lsa and sam context
//
typedef struct _SYNC_CONTEXT {
enum {
LsaDBContextType,
SamDBContextType
} DBContextType;
union {
LSA_SYNC_CONTEXT Lsa;
SAM_SYNC_CONTEXT Sam;
} DBContext;
} SYNC_CONTEXT, *PSYNC_CONTEXT;
//
// Macro used to free any resources allocated by SAM.
//
// ?? check LsaIFree_LSAPR_* call parameters.
//
#define CLEAN_SYNC_CONTEXT( _Sync ) { \
if ( (_Sync)->DBContextType == LsaDBContextType ) { \
if ( (_Sync)->DBContext.Lsa.LsaEnumBufferType != \
EmptyEnumBuffer) { \
if ( (_Sync)->DBContext.Lsa.LsaEnumBufferType == \
AccountEnumBuffer) { \
LsaIFree_LSAPR_ACCOUNT_ENUM_BUFFER( \
&((_Sync)->DBContext.Lsa.LsaEnum.Account) ); \
} \
else if ( (_Sync)->DBContext.Lsa.LsaEnumBufferType == \
TDomainEnumBuffer) { \
LsaIFree_LSAPR_TRUSTED_ENUM_BUFFER( \
&((_Sync)->DBContext.Lsa.LsaEnum.TDomain) ); \
} \
else { \
MIDL_user_free( (_Sync)->DBContext.Lsa.LsaEnum.Secret );\
} \
(_Sync)->DBContext.Lsa.LsaEnumBufferType = \
EmptyEnumBuffer; \
} \
} else { \
if ( (_Sync)->DBContext.Sam.SamEnum != NULL ) { \
SamIFree_SAMPR_ENUMERATION_BUFFER( \
(_Sync)->DBContext.Sam.SamEnum ); \
(_Sync)->DBContext.Sam.SamEnum = NULL; \
} \
if ( (_Sync)->DBContext.Sam.RidArray != NULL ) { \
MIDL_user_free( (_Sync)->DBContext.Sam.RidArray );\
(_Sync)->DBContext.Sam.RidArray = NULL; \
} \
} \
}
//
// Macro to initialize Sync Context
//
#define INIT_SYNC_CONTEXT( _Sync, _ContextType ) { \
RtlZeroMemory( (_Sync), sizeof( *(_Sync) ) ) ; \
(_Sync)->DBContextType = (_ContextType) ; \
}
//
// macros for dynamic tuning.
//
#define IS_BDC_CHANNEL( _ChannelType ) \
( (_ChannelType) == ServerSecureChannel || \
(_ChannelType) == UasServerSecureChannel )
//
// Server Session structure
//
// This structure represents the server side of a connection to a DC.
//
typedef struct _SERVER_SESSION {
//
// Each server session entry is in a doubly linked list for each hash bucket.
//
LIST_ENTRY SsHashList;
//
// Each server session entry is in a doubly linked list defined by
// NlGlobalServerSessionTable.
//
LIST_ENTRY SsSeqList;
//
// List of all BDCs headed by NlGlobalBdcServerSessionList.
//
// (The field is set only on BDC server session entries)
//
// Access serialized by NlGlobalServerSessionTableCritSect.
//
LIST_ENTRY SsBdcList;
//
// List of BDC's which have a pulse pending.
//
LIST_ENTRY SsPendingBdcList;
//
// Time when the last pulse was sent to this machine
//
// (The field is set only on BDC server session entries)
//
LARGE_INTEGER SsLastPulseTime;
//
// Current serial numbers of each database on the BDC.
//
// (The field is set only on BDC server session entries)
//
LARGE_INTEGER SsBdcDbSerialNumber[NUM_DBS];
//
// The computername uniquely identifies this server session entry.
//
NETLOGON_SECURE_CHANNEL_TYPE SsSecureChannelType;
CHAR SsComputerName[CNLEN+1];
//
// Rid of the server account
//
// (The field is set only on BDC server session entries)
//
ULONG SsLmBdcAccountRid;
ULONG SsNtBdcAccountRid;
//
// The number of times there has been no response to a pulse.
//
USHORT SsPulseTimeoutCount;
//
// The number of times this entry has been scavanged.
//
USHORT SsCheck;
//
// Flags describing the state of the current entry.
// See the SS_ defines below.
//
USHORT SsFlags;
#define SS_CHALLENGE 0x0001 // Challenge is in progress
#define SS_AUTHENTICATED 0x0002 // Remote side has be authenticated
#define SS_LOCKED 0x0004 // Delay deletion requests for this entry
// While set, SsSessionKey may be referenced
#define SS_DELETE_ON_UNLOCK 0x0008 // Delete entry when it is unlocked
#define SS_BDC 0x0010 // BDC account exists for this Client
#define SS_LM_BDC 0x0020 // Lanman BDC account exists for this entry is a
#define SS_PENDING_BDC 0x0040 // BDC is on pending BDC list.
#define SS_UAS_BUFFER_OVERFLOW 0x0100 // Previous downlevel API call
// returned STATUS_BUFFER_TOO_SMALL
#define SS_FORCE_PULSE 0x0200 // Force a pulse message to this BDC.
#define SS_PULSE_SENT 0x0400 // Pulse has been sent but has not
// been responded to yet
#define SS_LSA_REPL_NEEDED 0x2000 // BDC needs LSA DB replicated
#define SS_ACCOUNT_REPL_NEEDED 0x4000 // BDC needs SAM Account DB replicated
#define SS_BUILTIN_REPL_NEEDED 0x8000 // BDC needs SAM Builtin DB replicated
#define SS_REPL_MASK 0xE000 // BDC needs replication mask
// Don't clear these on session setup
#define SS_PERMANENT_FLAGS \
( SS_BDC | SS_LM_BDC | SS_PENDING_BDC | SS_FORCE_PULSE | SS_REPL_MASK )
//
// Flags describing capabilities of both client and server.
//
ULONG SsNegotiatedFlags;
//
// Transport the client connected over.
//
LPWSTR SsTransportName;
//
// This is the ClientChallenge (during the challenge phase) and later
// the ClientCredential (after authentication is complete).
//
NETLOGON_CREDENTIAL SsAuthenticationSeed;
//
// This is the ServerChallenge (during the challenge phase) and later
// the SessionKey (after authentication is complete).
//
NETLOGON_SESSION_KEY SsSessionKey;
//
// A pointer to the Sync context.
//
// (The field is set only on BDC server session entries)
//
PSYNC_CONTEXT SsSync;
} SERVER_SESSION, *PSERVER_SESSION;
//
// Structure shared by all PDC and BDC sync routines.
// (And other users of secure channels.)
//
typedef struct _SESSION_INFO {
//
// Session Key shared by both client and server.
//
NETLOGON_SESSION_KEY SessionKey;
//
// Flags describing capabilities of both client and server.
//
ULONG NegotiatedFlags;
} SESSION_INFO, *PSESSION_INFO;
/////////////////////////////////////////////////////////////////////////////
//
// Structures and variables describing the database info.
//
/////////////////////////////////////////////////////////////////////////////
typedef struct _DB_Info {
LARGE_INTEGER CreationTime; // database creation time
DWORD DBIndex; // index of Database table
SAM_HANDLE DBHandle; // database handle to access
PSID DBId; // database ID
LPWSTR DBName; // Name of the database
DWORD DBSessionFlag; // SS_ Flag representing this database
// Access to the following three fields are serialized by
// the NlGlobalDbInfoCritSect.
BOOLEAN UpdateRqd; // need to update the database
BOOLEAN FullSyncRequired; // Full sync needed on this database
BOOLEAN SyncDone; // Full sync has already been done on database
WCHAR PrimaryName[CNLEN+1]; // Primary this database last replicated from
} DB_INFO, *PDB_INFO;
EXTERN CRITICAL_SECTION NlGlobalDbInfoCritSect;
////////////////////////////////////////////////////////////////////////////////
//
// Global variables
//
////////////////////////////////////////////////////////////////////////////////
//
// Critical section serializing startup and stopping of the replicator thread.
//
EXTERN CRITICAL_SECTION NlGlobalReplicatorCritSect;
EXTERN BOOL NlGlobalSSICritSectInit;
//
// Table of all Server Sessions
// The size of the hash table must be a power-of-2.
//
#define SERVER_SESSION_HASH_TABLE_SIZE 64
EXTERN CRITICAL_SECTION NlGlobalServerSessionTableCritSect;
EXTERN PLIST_ENTRY NlGlobalServerSessionHashTable;
EXTERN LIST_ENTRY NlGlobalServerSessionTable;
EXTERN LIST_ENTRY NlGlobalBdcServerSessionList;
EXTERN ULONG NlGlobalBdcServerSessionCount;
//
// List of all BDC's the PDC has sent a pulse to.
//
EXTERN LIST_ENTRY NlGlobalPendingBdcList;
EXTERN ULONG NlGlobalPendingBdcCount;
EXTERN TIMER NlGlobalPendingBdcTimer;
#define LOCK_SERVER_SESSION_TABLE() \
EnterCriticalSection( &NlGlobalServerSessionTableCritSect )
#define UNLOCK_SERVER_SESSION_TABLE() \
LeaveCriticalSection( &NlGlobalServerSessionTableCritSect )
//
// List of transports clients might connect to
//
EXTERN LPWSTR *NlGlobalTransportList;
EXTERN DWORD NlGlobalTransportCount;
#if DBG
///////////////////////////////////////////////////////////////////////////////
#define DEFPACKTIMER DWORD PackTimer, PackTimerTicks
#define INITPACKTIMER PackTimer = 0;
#define STARTPACKTIMER \
IF_DEBUG( REPL_OBJ_TIME ) { \
PackTimerTicks = GetTickCount(); \
}
#define STOPPACKTIMER \
IF_DEBUG( REPL_OBJ_TIME ) { \
PackTimer += GetTickCount() - PackTimerTicks; \
}
#define PRINTPACKTIMER \
IF_DEBUG( REPL_OBJ_TIME ) { \
NlPrint((NL_REPL_OBJ_TIME,"\tTime Taken to PACK this object = %d msecs\n", \
PackTimer )); \
}
///////////////////////////////////////////////////////////////////////////////
#define DEFUNPACKTIMER DWORD UnpackTimer, UnpackTimerTicks
#define INITUNPACKTIMER UnpackTimer = 0;
#define STARTUNPACKTIMER \
IF_DEBUG( REPL_OBJ_TIME ) { \
UnpackTimerTicks = GetTickCount(); \
}
#define STOPUNPACKTIMER \
IF_DEBUG( REPL_OBJ_TIME ) { \
UnpackTimer += GetTickCount() - \
UnpackTimerTicks; \
}
#define PRINTUNPACKTIMER \
IF_DEBUG( REPL_OBJ_TIME ) { \
NlPrint((NL_REPL_OBJ_TIME,"\tTime Taken to UNPACK this object = %d msecs\n", \
UnpackTimer )); \
}
///////////////////////////////////////////////////////////////////////////////
#define DEFSAMTIMER DWORD SamTimer, SamTimerTicks
#define INITSAMTIMER SamTimer = 0;
#define STARTSAMTIMER \
IF_DEBUG( REPL_OBJ_TIME ) { \
SamTimerTicks = GetTickCount(); \
}
#define STOPSAMTIMER \
IF_DEBUG( REPL_OBJ_TIME ) { \
SamTimer += GetTickCount() - SamTimerTicks; \
}
#define PRINTSAMTIMER \
IF_DEBUG( REPL_OBJ_TIME ) { \
NlPrint((NL_REPL_OBJ_TIME,"\tTime spent in SAM calls = %d msecs\n", \
SamTimer )); \
}
///////////////////////////////////////////////////////////////////////////////
#define DEFLSATIMER DWORD LsaTimer, LsaTimerTicks
#define INITLSATIMER LsaTimer = 0;
#define STARTLSATIMER \
IF_DEBUG( REPL_OBJ_TIME ) { \
LsaTimerTicks = GetTickCount(); \
}
#define STOPLSATIMER \
IF_DEBUG( REPL_OBJ_TIME ) { \
LsaTimer += GetTickCount() - LsaTimerTicks; \
}
#define PRINTLSATIMER \
IF_DEBUG( REPL_OBJ_TIME ) { \
NlPrint((NL_REPL_OBJ_TIME,"\tTime spent in LSA calls = %d msecs\n", \
LsaTimer )); \
}
///////////////////////////////////////////////////////////////////////////////
#define DEFSSIAPITIMER DWORD SsiApiTimer, SsiApiTimerTicks
#define INITSSIAPITIMER SsiApiTimer = 0;
#define STARTSSIAPITIMER \
IF_DEBUG( REPL_TIME ) { \
SsiApiTimerTicks = GetTickCount(); \
}
#define STOPSSIAPITIMER \
IF_DEBUG( REPL_TIME ) { \
SsiApiTimer += GetTickCount() - \
SsiApiTimerTicks; \
}
#define PRINTSSIAPITIMER \
IF_DEBUG( REPL_TIME ) { \
NlPrint((NL_REPL_TIME,"\tTime Taken by this SSIAPI call = %d msecs\n", \
SsiApiTimer )); \
}
#else // DBG
#define DEFPACKTIMER
#define INITPACKTIMER
#define STARTPACKTIMER
#define STOPPACKTIMER
#define PRINTPACKTIMER
#define DEFUNPACKTIMER
#define DEFUNPACKTICKS
#define INITUNPACKTIMER
#define STARTUNPACKTIMER
#define STOPUNPACKTIMER
#define PRINTUNPACKTIMER
#define DEFSAMTIMER
#define INITSAMTIMER
#define STARTSAMTIMER
#define STOPSAMTIMER
#define PRINTSAMTIMER
#define DEFLSATIMER
#define INITLSATIMER
#define STARTLSATIMER
#define STOPLSATIMER
#define PRINTLSATIMER
#define DEFSSIAPITIMER
#define INITSSIAPITIMER
#define STARTSSIAPITIMER
#define STOPSSIAPITIMER
#define PRINTSSIAPITIMER
#endif // DBG
//
// macros used in pack and unpack routines
//
#define SECURITYINFORMATION OWNER_SECURITY_INFORMATION | \
GROUP_SECURITY_INFORMATION | \
SACL_SECURITY_INFORMATION | \
DACL_SECURITY_INFORMATION
#define INIT_PLACE_HOLDER(_x) \
RtlInitString( (PSTRING) &(_x)->DummyString1, NULL ); \
RtlInitString( (PSTRING) &(_x)->DummyString2, NULL ); \
RtlInitString( (PSTRING) &(_x)->DummyString3, NULL ); \
RtlInitString( (PSTRING) &(_x)->DummyString4, NULL ); \
(_x)->DummyLong1 = 0; \
(_x)->DummyLong2 = 0; \
(_x)->DummyLong3 = 0; \
(_x)->DummyLong4 = 0;
#define QUERY_LSA_SECOBJ_INFO(_x) \
STARTLSATIMER; \
Status = LsarQuerySecurityObject( \
(_x), \
SECURITYINFORMATION, \
&SecurityDescriptor );\
STOPLSATIMER; \
\
if (!NT_SUCCESS(Status)) { \
SecurityDescriptor = NULL; \
goto Cleanup; \
}
#define QUERY_SAM_SECOBJ_INFO(_x) \
STARTSAMTIMER; \
Status = SamrQuerySecurityObject( \
(_x), \
SECURITYINFORMATION, \
&SecurityDescriptor );\
STOPSAMTIMER; \
\
if (!NT_SUCCESS(Status)) { \
SecurityDescriptor = NULL; \
goto Cleanup; \
}
#define SET_LSA_SECOBJ_INFO(_x, _y) \
SecurityDescriptor.Length = (_x)->SecuritySize; \
SecurityDescriptor.SecurityDescriptor = (_x)->SecurityDescriptor; \
\
STARTLSATIMER; \
Status = LsarSetSecurityObject( \
(_y), \
(_x)->SecurityInformation, \
&SecurityDescriptor ); \
STOPLSATIMER; \
\
if (!NT_SUCCESS(Status)) { \
goto Cleanup; \
}
#define SET_SAM_SECOBJ_INFO(_x, _y) \
SecurityDescriptor.Length = (_x)->SecuritySize; \
SecurityDescriptor.SecurityDescriptor = (_x)->SecurityDescriptor; \
\
STARTSAMTIMER; \
Status = SamrSetSecurityObject( \
(_y), \
(_x)->SecurityInformation, \
&SecurityDescriptor ); \
STOPSAMTIMER; \
\
if (!NT_SUCCESS(Status)) { \
goto Cleanup; \
}
#define DELTA_SECOBJ_INFO(_x) \
(_x)->SecurityInformation = SECURITYINFORMATION;\
(_x)->SecuritySize = SecurityDescriptor->Length;\
\
*BufferSize += NlCopyData( \
(LPBYTE *)&SecurityDescriptor->SecurityDescriptor, \
(LPBYTE *)&(_x)->SecurityDescriptor, \
SecurityDescriptor->Length );
///////////////////////////////////////////////////////////////////////////////
//
// Procedure forwards.
//
///////////////////////////////////////////////////////////////////////////////
//
// ssiapi.c
//
NTSTATUS
NlVerifyWorkstation(
IN LPWSTR PrimaryName OPTIONAL
);
//
// srvsess.c
//
LPWSTR
NlTransportLookupTransportName(
IN LPWSTR TransportName
);
LPWSTR
NlTransportLookup(
IN LPWSTR ClientName
);
VOID
NlTransportClose(
VOID
);
NTSTATUS
NlInitSSI(
VOID
);
PSERVER_SESSION
NlFindNamedServerSession(
IN LPWSTR ComputerName
);
NTSTATUS
NlInsertServerSession(
IN LPWSTR ComputerName,
IN DWORD Flags,
IN ULONG AccountRid,
IN PNETLOGON_CREDENTIAL AuthenticationSeed OPTIONAL,
IN PNETLOGON_CREDENTIAL AuthenticationResponse OPTIONAL
);
NTSTATUS
NlAddBdcServerSession(
IN ULONG ServerRid,
IN PUNICODE_STRING AccountName OPTIONAL,
IN DWORD Flags
);
VOID
NlFreeServerSession(
IN PSERVER_SESSION ServerSession
);
VOID
NlUnlockServerSession(
IN PSERVER_SESSION ServerSession
);
VOID
NlFreeLmBdcServerSession(
IN ULONG ServerRid
);
VOID
NlFreeNamedServerSession(
IN LPWSTR ComputerName,
IN BOOLEAN AccountBeingDeleted
);
VOID
NlFreeServerSessionForAccount(
IN PUNICODE_STRING AccountName
);
VOID
NlServerSessionScavenger(
VOID
);
//
// ssiauth.c
//
VOID
NlMakeSessionKey(
IN PNT_OWF_PASSWORD CryptKey,
IN PNETLOGON_CREDENTIAL ClientChallenge,
IN PNETLOGON_CREDENTIAL ServerChallenge,
OUT PNETLOGON_SESSION_KEY SessionKey
);
NTSTATUS
NlCheckAuthenticator(
IN OUT PSERVER_SESSION ServerServerSession,
IN PNETLOGON_AUTHENTICATOR Authenticator,
OUT PNETLOGON_AUTHENTICATOR ReturnAuthenticator
);
VOID
NlComputeCredentials(
IN PNETLOGON_CREDENTIAL Challenge,
OUT PNETLOGON_CREDENTIAL Credential,
IN PNETLOGON_SESSION_KEY SessionKey
);
VOID
NlComputeChallenge(
OUT PNETLOGON_CREDENTIAL Challenge
);
VOID
NlBuildAuthenticator(
IN OUT PNETLOGON_CREDENTIAL AuthenticationSeed,
IN PNETLOGON_SESSION_KEY SessionKey,
OUT PNETLOGON_AUTHENTICATOR Authenticator
);
BOOL
NlUpdateSeed(
IN OUT PNETLOGON_CREDENTIAL AuthenticationSeed,
IN PNETLOGON_CREDENTIAL TargetCredential,
IN PNETLOGON_SESSION_KEY SessionKey
);
VOID
NlEncryptRC4(
IN OUT PVOID Buffer,
IN ULONG BufferSize,
IN PSESSION_INFO SessionInfo
);
VOID
NlDecryptRC4(
IN OUT PVOID Buffer,
IN ULONG BufferSize,
IN PSESSION_INFO SessionInfo
);
//
// trustutl.c
//
PCLIENT_SESSION
NlFindNamedClientSession(
IN PUNICODE_STRING DomainName
);
PCLIENT_SESSION
NlAllocateClientSession(
IN PUNICODE_STRING DomainName,
IN PSID DomainId,
IN NETLOGON_SECURE_CHANNEL_TYPE SecureChannelType
);
VOID
NlFreeClientSession(
IN PCLIENT_SESSION ClientSession
);
VOID
NlRefClientSession(
IN PCLIENT_SESSION ClientSession
);
VOID
NlUnrefClientSession(
IN PCLIENT_SESSION ClientSession
);
BOOL
NlTimeoutSetWriterClientSession(
IN PCLIENT_SESSION ClientSession,
IN DWORD Timeout
);
VOID
NlResetWriterClientSession(
IN PCLIENT_SESSION ClientSession
);
NTSTATUS
NlCaptureServerClientSession (
IN PCLIENT_SESSION ClientSession,
OUT WCHAR UncServerName[UNCLEN+1]
);
VOID
NlSetStatusClientSession(
IN PCLIENT_SESSION ClientSession,
IN NTSTATUS CsConnectionStatus
);
NTSTATUS
NlInitTrustList(
VOID
);
NTSTATUS
NlUpdateTrustListBySid (
IN PSID DomainId,
IN PUNICODE_STRING DomainName OPTIONAL
);
VOID
NlPickTrustedDcForEntireTrustList(
VOID
);
NTSTATUS
NlSetTrustedDomainList (
IN LPWSTR TrustedDomainList,
IN BOOL TrustedDomainListKnown
);
VOID
NlSaveTrustedDomainList (
IN LPWSTR TrustedDomainList
);
NET_API_STATUS
NlReadRegTrustedDomainList (
IN LPWSTR NewDomainName OPTIONAL,
IN BOOL DeleteName,
OUT LPWSTR *TrustedDomainList,
OUT PBOOL TrustedDomainListKnown
);
BOOLEAN
NlIsDomainTrusted (
IN PUNICODE_STRING DomainName
);
typedef enum _DISCOVERY_TYPE {
DT_Asynchronous,
DT_Synchronous,
DT_DeadDomain
} DISCOVERY_TYPE;
NTSTATUS
NlDiscoverDc (
IN OUT PCLIENT_SESSION ClientSession,
IN DISCOVERY_TYPE DiscoveryType
);
VOID
NlDcDiscoveryExpired (
IN BOOLEAN Exitting
);
NTSTATUS
NlDcDiscoveryHandler (
IN PNETLOGON_SAM_LOGON_RESPONSE Message,
IN DWORD MessageSize,
IN LPWSTR TransportName,
IN DWORD Version
);
PCLIENT_SESSION
NlPickDomainWithAccount (
IN LPWSTR AccountName,
IN ULONG AllowableAccountControlBits
);
NTSTATUS
NlStartApiClientSession(
IN PCLIENT_SESSION ClientSession,
IN BOOLEAN QuickApiCall
);
BOOLEAN
NlFinishApiClientSession(
IN PCLIENT_SESSION ClientSession,
IN BOOLEAN OkToKillSession
);
VOID
NlTimeoutApiClientSession(
VOID
);
#undef EXTERN