|
|
/*++
Copyright (c) 1991-1996 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.
--*/
// general purpose mainfests
//
// Define UserAccountControl bit to indicate an NT 5.0 interdomain trust.
//
// This is not really a SAM account. But UserAccountControl is used for all
// other trust types.
//
// Pick a bit that will never be used in the future to indicate a different
// account type.
//
#define USER_DNS_DOMAIN_TRUST_ACCOUNT USER_ACCOUNT_AUTO_LOCKED
//
// 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.
//
// The NETLOGON_SAM_LOGON_RESPONSE_EX structure isn't packed into a mailslot
// packet so it may be larger.
//
#define NETLOGON_MAX_MS_SIZE max(444, sizeof(NETLOGON_SAM_LOGON_RESPONSE_EX))
//
// Structure describing a transport supported by redir/server and browser.
//
typedef struct _NL_TRANSPORT { //
// List of all transports headed by NlTransportListHead.
// (Serialized by NlTransportCritSect)
//
LIST_ENTRY Next;
//
// True if the transport is currently enabled.
// We never delete a transport in order to avoid maintaining a reference count.
//
BOOLEAN TransportEnabled;
//
// True if transport is an IP transport.
//
BOOLEAN IsIpTransport;
//
// True if transport is direct host IPX transport
//
BOOLEAN DirectHostIpx;
//
// IP Address for this transport.
// Zero if not IP or none yet assigned.
//
ULONG IpAddress;
//
// Handle to the transport device
//
HANDLE DeviceHandle;
//
// Name of the transport.
//
WCHAR TransportName[1];
} NL_TRANSPORT, *PNL_TRANSPORT;
/////////////////////////////////////////////////////////////////////////////
//
// 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)
#define TIMER_MAX_PERIOD (MAILSLOT_WAIT_FOREVER - 1)
} TIMER, *PTIMER;
#define NL_MILLISECONDS_PER_SECOND (1000)
#define NL_MILLISECONDS_PER_MINUTE (60 * NL_MILLISECONDS_PER_SECOND)
#define NL_MILLISECONDS_PER_HOUR (60 * NL_MILLISECONDS_PER_MINUTE)
#define NL_MILLISECONDS_PER_DAY (24 * NL_MILLISECONDS_PER_HOUR)
//
// Structure the describes an API call over the secure channel
//
typedef struct _CLIENT_API {
//
// 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 DomainInfo->DomTrustListCritSect.
//
TIMER CaApiTimer;
#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 NlGlobalParameters.ShortApiCallPeriod // Max time to wait to become writer
#define IsApiActive( _ClientApi ) ((_ClientApi)->CaApiTimer.Period != MAILSLOT_WAIT_FOREVER )
//
// Handle to the thread doing the API.
//
// Access serialized by DomainInfo->DomTrustListCritSect.
//
HANDLE CaThreadHandle;
//
// Access serialized by DomainInfo->DomTrustListCritSect.
//
DWORD CaFlags;
#define CA_BINDING_CACHED 0x1 // Set if the binding handle is cached
#define CA_TCP_BINDING 0x2 // Set if the cached binding handle is TCP/IP
#define CA_BINDING_AUTHENTICATED 0x4 // Set if the binding handle is marked authenticated
#define CA_ENTRY_IN_USE 0x8 // Entry is in use by a thread
//
// Rpc context handle for this call.
//
// Access serialized by DomainInfo->DomTrustListCritSect.
//
handle_t CaRpcHandle;
//
// When an api is in progress,
// this is the CsSessionCount at the start of the API call.
//
// Access serialized by CsWriterSemaphore.
//
DWORD CaSessionCount;
//
// UNC server name
//
WCHAR CaUncServerName[DNS_MAX_NAME_LENGTH + 3];
} CLIENT_API, * PCLIENT_API;
//
// 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
// DomTrustList.
//
// Access serialized by DomTrustListCritSect.
//
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 setup 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 attempt or the discovery type (with or without account)
//
// Access serialized by NlGlobalDcDiscoveryCritSect
//
LARGE_INTEGER CsLastDiscoveryTime;
//
// Time when the last discovery attempt with account was made
// regardless of the success or failure of that attempt
//
LARGE_INTEGER CsLastDiscoveryWithAccountTime;
//
// Time when the session was refreshed last time
//
LARGE_INTEGER CsLastRefreshTime;
//
// Time when the forest trust info was refreshed last time.
// Access serialized by DomTrustListCritSect.
//
LARGE_INTEGER CsLastFtInfoRefreshTime;
//
// WorkItem for Async discovery
//
WORKER_ITEM CsAsyncDiscoveryWorkItem;
//
// Name/Guid of the domain this connection is to
//
// Access serialized by DomTrustListCritSect.
//
GUID CsDomainGuidBuffer; UNICODE_STRING CsNetbiosDomainName; CHAR CsOemNetbiosDomainName[DNLEN+1]; ULONG CsOemNetbiosDomainNameLength; UNICODE_STRING CsDnsDomainName; LPSTR CsUtf8DnsDomainName; GUID *CsDomainGuid; // NULL if domain has no GUID.
// Either the Netbios or Dns Domain name.
// Suitable for debug. Suitable for Eventlog messages.
LPWSTR CsDebugDomainName;
//
// Name of the local trusted domain object.
//
PUNICODE_STRING CsTrustName;
//
// Name of the account on the server.
// For NT 5.0 interdomain trust, this is the dns name of this domain.
//
LPWSTR CsAccountName;
//
// Domain ID of the domain this connection is to
//
// Access serialized by either DomTrustListCritSect or CsWriter.
// Modifications must lock both.
PSID CsDomainId;
//
// Hosted domain this session is for
//
PDOMAIN_INFO CsDomainInfo;
//
// 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 DomTrustListCritSect
//
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_NT5_DOMAIN_TRUST 0x04 // Trust is to an NT 5 domain.
#define CS_WRITER 0x08 // Entry is being modified
#define CS_DIRECT_TRUST 0x10 // We have a direct trust to the specified
// domain.
#define CS_CHECK_DIRECT_TRUST 0x20 // Set if we need to check the password
// and forest trust info
#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_HANDLE_API_TIMER 0x400 // Set if we need to handle API timer expiration
#define CS_NOT_IN_LSA 0x800 // Flag to delete this entry if it's
// not later proved to be in the LSA.
#define CS_ZERO_LAST_AUTH 0x2000 // Set if we need to zero CsLastAuthenticationTry
#define CS_DOMAIN_IN_FOREST 0x4000 // Set if trusted domain is in same forest as this domain.
#define CS_NEW_TRUST 0x8000 // Set on a newly allocated trusted domain
// until async discovery has been tried
#define CS_DC_PICKED_ONCE 0x10000 // Set if DC was picked at least once.
// Access serialized by writer lock
//
// Trust attributes for the trusted domain object
//
ULONG CsTrustAttributes;
//
// Pointer to client session that represents the direct trust that's
// the closest route to the domain of this client session.
//
// The pointed to client session will always be marked CS_DIRECT_TRUST.
//
// If this is a CS_DIRECT_TRUST session,
// this field will point to this client session.
//
struct _CLIENT_SESSION *CsDirectClientSession;
//
// 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 times the secure channel has been dropped.
//
// Access serialized by CsWriterSemaphore.
//
DWORD CsSessionCount;
//
// Number of threads referencing this entry.
//
// Access serialized by DomTrustListCritSect.
//
DWORD CsReferenceCount;
//
// Writer semaphore.
//
// This semaphore is locked whenever there is a writer modifying
// fields in this client session.
//
HANDLE CsWriterSemaphore;
#ifdef _DC_NETLOGON
//
// The following fields are used by the NlDiscoverDc to keep track
// of discovery state.
//
// Access serialized by NlGlobalDcDiscoveryCritSect
//
DWORD CsDiscoveryFlags; #define CS_DISCOVERY_DEAD_DOMAIN 0x001 // This is a dead domain disocvery
#define CS_DISCOVERY_ASYNCHRONOUS 0x002 // Discovery being processed in worker thread
#define CS_DISCOVERY_HAS_DS 0x004 // Discovered DS has a DS
#define CS_DISCOVERY_IS_CLOSE 0x008 // Discovered DS is in a close site
#define CS_DISCOVERY_HAS_IP 0x010 // Discovered DC has IP address
#define CS_DISCOVERY_USE_MAILSLOT 0x020 // Discovered DC should be pinged using mailslot mechanism
#define CS_DISCOVERY_USE_LDAP 0x040 // Discovered DC should be pinged using LDAP mechanism
#define CS_DISCOVERY_HAS_TIMESERV 0x080 // Discovered DC runs the Windows Time Service
#define CS_DISCOVERY_DNS_SERVER 0x100 // Discovered DC name is DNS (if off, the name is Netbios)
#define CS_DISCOVERY_NO_PWD_ATTR_MONITOR 0x200 // Discovered DC cannot process NetrServerTrustPasswordsAndAttribGet
//
// This event is set to indicate that discovery is not in progress on this
// client session.
//
HANDLE CsDiscoveryEvent; #endif // _DC_NETLOGON
//
// 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 MAX_DC_API_TIMEOUT.
//
// The count is decremented each time there are FAST_DC_API_THRESHOLD calls
// that execute in FAST_DC_API_TIMEOUT seconds.
//
//
// Access serialized by CsWriterSemaphore.
//
DWORD CsTimeoutCount;
#define MAX_DC_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_DC_REAUTHENTICATION_WAIT (long) (5L*60L*1000L) // 5 mins
#define MAX_DC_REFRESH_TIMEOUT (45 * 60 * 1000) // 45 minutes
#define FAST_DC_API_THRESHOLD 5 // Number of fast calls needed before
// we decrement timeout count
#define FAST_DC_API_TIMEOUT (1000) // 1 second
//
// Count of Fast Calls
//
// Access serialized by CsWriterSemaphore.
//
DWORD CsFastCallCount;
//
// Authentication information.
//
// Access serialized by CsWriterSemaphore.
//
NETLOGON_CREDENTIAL CsAuthenticationSeed; NETLOGON_SESSION_KEY CsSessionKey;
PVOID ClientAuthData; CredHandle CsCredHandle;
#ifdef _DC_NETLOGON
//
// Transport the server was discovered on.
//
PNL_TRANSPORT CsTransport; #endif // _DC_NETLOGON
//
// Rid of the account used to contact server
//
ULONG CsAccountRid;
//
// Know good password for this secure channel.
//
// After secure channel setup, it is the password used to setup the channel.
// After a password change, it is the password successfully set on the DC.
//
NT_OWF_PASSWORD CsNtOwfPassword;
//
// Name of the server this connection is to (may be DNS or Netbios) and its
// IP address (if any).
//
// 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.)
//
LPWSTR CsUncServerName;
SOCKET_ADDRESS CsServerSockAddr; SOCKADDR_IN CsServerSockAddrIn;
//
// API semaphore.
//
// This semaphore has one reference for each slot in CsClientApi.
// (Except the zeroth slot which is special.)
//
HANDLE CsApiSemaphore;
//
// List of API calls outstanding on this session
//
// Access serialized by DomainInfo->DomTrustListCritSect.
//
CLIENT_API CsClientApi[1];
#define ClientApiIndex( _ClientSession, _ClientApi ) \
((LONG) ((_ClientApi)-&((_ClientSession)->CsClientApi[0])) )
#define UseConcurrentRpc( _ClientSession, _ClientApi ) \
(ClientApiIndex( _ClientSession, _ClientApi ) != 0 )
} CLIENT_SESSION, * PCLIENT_SESSION;
#define LOCK_TRUST_LIST(_DI) EnterCriticalSection( &(_DI)->DomTrustListCritSect )
#define UNLOCK_TRUST_LIST(_DI) LeaveCriticalSection( &(_DI)->DomTrustListCritSect )
//
// For member workstations,
// maintain a list of domains trusted by our primary domain.
//
// Access serialized by NlGlobalDcDiscoveryCritSect
//
typedef struct { WCHAR UnicodeNetbiosDomainName[DNLEN+1]; LPSTR Utf8DnsDomainName; } TRUSTED_DOMAIN, *PTRUSTED_DOMAIN;
#ifdef _DC_NETLOGON
/////////////////////////////////////////////////////////////////////////////
//
// 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
} 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 { \ LsaIFree_LSAI_SECRET_ENUM_BUFFER ( \ (_Sync)->DBContext.Lsa.LsaEnum.Secret, \ (_Sync)->DBContext.Lsa.Count ); \ (_Sync)->DBContext.Lsa.LsaEnum.Secret = NULL; \ } \ (_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) ; \ }
//
// Server Session structure
//
// This structure represents the server side of a connection to a DC.
//
// ISSUE-2000/09/15-CliffV: This structure could be made smaller by using SsSecureChannelType
// as a discriminator. Many fields are specific to a BDC server session entry. Others
// are specific to a domain server session entry. However, most entries are member workstation
// server session entries that don't use either of the fields.
//
typedef struct _SERVER_SESSION { //
// Each server session entry is in a doubly linked list for each hash bucket.
// Indexed by SsComputerName
//
LIST_ENTRY SsHashList;
//
// Each server session entry is in a doubly linked list defined by
// DomainInfo->DomServerSessionTable.
//
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 account to authenticate with
//
ULONG SsAccountRid;
//
// The number of times there has been no response to a pulse.
//
USHORT SsPulseTimeoutCount;
//
// Hosted domain for this server session.
//
PDOMAIN_INFO SsDomainInfo;
//
// 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_BDC_FORCE_DELETE 0x0001 // Unless set, BDC server session won't be deleted
#define SS_AUTHENTICATED 0x0002 // Remote side has been 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_FOREST_TRANSITIVE 0x0020 // TDO has TRUST_ATTRIBUTE_FOREST_TRANSITIVE set
#define SS_PENDING_BDC 0x0040 // BDC is on pending BDC list.
#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
#define SS_REPL_LSA_MASK 0x2000 // BDC needs LSA replication mask
#define SS_REPL_SAM_MASK 0xC000 // BDC needs SAM replication mask
// Don't clear these on session setup
#define SS_PERMANENT_FLAGS \
( SS_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.
//
PNL_TRANSPORT SsTransport;
//
// This is 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;
//
// Each server session entry is in a doubly linked list for each hash bucket.
// Indexed by SsTdoName
//
// (This field is set only on *uplevel* interdomain trust entries.)
//
LIST_ENTRY SsTdoNameHashList;
UNICODE_STRING SsTdoName;
} SERVER_SESSION, *PSERVER_SESSION; #endif // _DC_NETLOGON
//
// 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;
//
// Macro for tranlating the negotiated database replication flags to the mask of
// which databases to replicate/
//
#define NlMaxReplMask( _NegotiatedFlags ) \
((((_NegotiatedFlags) & NETLOGON_SUPPORTS_AVOID_SAM_REPL) ? 0 : SS_REPL_SAM_MASK ) | \ (((_NegotiatedFlags) & NETLOGON_SUPPORTS_AVOID_LSA_REPL) ? 0 : SS_REPL_LSA_MASK ) )
/////////////////////////////////////////////////////////////////////////////
//
// 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
LPWSTR DBName; // Name of the database
DWORD DBSessionFlag; // SS_ Flag representing this database
} DB_INFO, *PDB_INFO;
/////////////////////////////////////////////////////////////////////////////
//
// Replication timing macros
//
/////////////////////////////////////////////////////////////////////////////
#if NETLOGONDBG
///////////////////////////////////////////////////////////////////////////////
#define DEFPACKTIMER DWORD PackTimer, PackTimerTicks
#define INITPACKTIMER PackTimer = 0;
#define STARTPACKTIMER \
IF_NL_DEBUG( REPL_OBJ_TIME ) { \ PackTimerTicks = GetTickCount(); \ }
#define STOPPACKTIMER \
IF_NL_DEBUG( REPL_OBJ_TIME ) { \ PackTimer += GetTickCount() - PackTimerTicks; \ }
#define PRINTPACKTIMER \
IF_NL_DEBUG( REPL_OBJ_TIME ) { \ NlPrint((NL_REPL_OBJ_TIME,"\tTime Taken to PACK this object = %d msecs\n", \ PackTimer )); \ }
///////////////////////////////////////////////////////////////////////////////
#define DEFSAMTIMER DWORD SamTimer, SamTimerTicks
#define INITSAMTIMER SamTimer = 0;
#define STARTSAMTIMER \
IF_NL_DEBUG( REPL_OBJ_TIME ) { \ SamTimerTicks = GetTickCount(); \ }
#define STOPSAMTIMER \
IF_NL_DEBUG( REPL_OBJ_TIME ) { \ SamTimer += GetTickCount() - SamTimerTicks; \ }
#define PRINTSAMTIMER \
IF_NL_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_NL_DEBUG( REPL_OBJ_TIME ) { \ LsaTimerTicks = GetTickCount(); \ }
#define STOPLSATIMER \
IF_NL_DEBUG( REPL_OBJ_TIME ) { \ LsaTimer += GetTickCount() - LsaTimerTicks; \ }
#define PRINTLSATIMER \
IF_NL_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_NL_DEBUG( REPL_TIME ) { \ SsiApiTimerTicks = GetTickCount(); \ }
#define STOPSSIAPITIMER \
IF_NL_DEBUG( REPL_TIME ) { \ SsiApiTimer += GetTickCount() - \ SsiApiTimerTicks; \ }
#define PRINTSSIAPITIMER \
IF_NL_DEBUG( REPL_TIME ) { \ NlPrint((NL_REPL_TIME, \ "\tTime Taken by this SSIAPI call = %d msecs\n", \ SsiApiTimer )); \ }
#else // NETLOGONDBG
#define DEFPACKTIMER
#define INITPACKTIMER
#define STARTPACKTIMER
#define STOPPACKTIMER
#define PRINTPACKTIMER
#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 // NETLOGONDBG
//
// 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)) { \ NlPrint((NL_CRITICAL, \ "LsarSetSecurityObject failed (%lx)\n", \ 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)) { \ NlPrint((NL_CRITICAL, \ "SamrSetSecurityObject failed (%lx)\n", \ 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 );
//
// Values of WorkstationFlags field of NETLOGON_WORKSTATION_INFO
//
#define NL_NEED_BIDIRECTIONAL_TRUSTS 0x0001 // Client wants inbound trusts, too
#define NL_CLIENT_HANDLES_SPN 0x0002 // Client handles updating SPN
#define NL_GET_DOMAIN_INFO_SUPPORTED 0x0003 // Mask of all bits supported
//
// Structure describing failed user logon.
// We keep a small cache of failed use logons
// with bad password.
//
typedef struct _NL_FAILED_USER_LOGON {
//
// Link to next entry in the list of failed forwarded logons
// (Serialized by DomainInfo->DomTrustListCritSect)
//
LIST_ENTRY FuNext;
//
// Last time we forwarded the logon to the PDC
//
ULONG FuLastTimeSentToPdc;
//
// Count of failed local logons
//
ULONG FuBadLogonCount;
//
// The user name (must be lat field in struct)
//
WCHAR FuUserName[ANYSIZE_ARRAY];
} NL_FAILED_USER_LOGON, *PNL_FAILED_USER_LOGON;
//
// The number of failed user logons we keep per domain.
// (The maximum number of negative cache entries we keep
// before throwing the least recently used one.)
//
#define NL_MAX_FAILED_USER_LOGONS 50
//
// Number of failed logons for a given user after which we refrain from
// forwarding subsequent user logons to the PDC for some period of time
//
#define NL_FAILED_USER_MAX_LOGON_COUNT 10
//
// Time period during which we refrain from forwarding a given
// user logon to the PDC once number of failed user logons
// reaches the above limit
//
#define NL_FAILED_USER_FORWARD_LOGON_TIMEOUT 300000 // 5 minutes
///////////////////////////////////////////////////////////////////////////////
//
// Procedure forwards.
//
///////////////////////////////////////////////////////////////////////////////
#ifdef _DC_NETLOGON
//
// srvsess.c
//
NET_API_STATUS NlTransportOpen( VOID );
BOOL NlTransportAddTransportName( IN LPWSTR TransportName, OUT PBOOLEAN IpTransportChanged );
BOOLEAN NlTransportDisableTransportName( IN LPWSTR TransportName );
PNL_TRANSPORT NlTransportLookupTransportName( IN LPWSTR TransportName );
PNL_TRANSPORT NlTransportLookup( IN LPWSTR ClientName );
VOID NlTransportClose( VOID );
ULONG NlTransportGetIpAddresses( IN ULONG HeaderSize, IN BOOLEAN ReturnOffsets, OUT PSOCKET_ADDRESS *RetIpAddresses, OUT PULONG RetIpAddressSize );
BOOLEAN NlHandleWsaPnp( VOID );
PSERVER_SESSION NlFindNamedServerSession( IN PDOMAIN_INFO DomainInfo, IN LPWSTR ComputerName );
VOID NlSetServerSessionAttributesByTdoName( IN PDOMAIN_INFO DomainInfo, IN PUNICODE_STRING TdoName, IN ULONG TrustAttributes );
NTSTATUS NlInsertServerSession( IN PDOMAIN_INFO DomainInfo, IN LPWSTR ComputerName, IN LPWSTR TdoName OPTIONAL, IN NETLOGON_SECURE_CHANNEL_TYPE SecureChannelType, IN DWORD Flags, IN ULONG AccountRid, IN ULONG NegotiatedFlags, IN PNL_TRANSPORT Transport OPTIONAL, IN PNETLOGON_SESSION_KEY SessionKey OPTIONAL, IN PNETLOGON_CREDENTIAL AuthenticationSeed OPTIONAL );
NTSTATUS NlCheckServerSession( IN ULONG ServerRid, IN PUNICODE_STRING AccountName OPTIONAL, IN NETLOGON_SECURE_CHANNEL_TYPE SecureChannelType );
NTSTATUS NlBuildNtBdcList( PDOMAIN_INFO DomainInfo );
BOOLEAN NlFreeServerSession( IN PSERVER_SESSION ServerSession );
VOID NlUnlockServerSession( IN PSERVER_SESSION ServerSession );
VOID NlFreeNamedServerSession( IN PDOMAIN_INFO DomainInfo, IN LPWSTR ComputerName, IN BOOLEAN AccountBeingDeleted );
VOID NlFreeServerSessionForAccount( IN PUNICODE_STRING AccountName );
VOID NlServerSessionScavenger( IN PDOMAIN_INFO DomainInfo ); #endif // _DC_NETLOGON
//
// ssiauth.c
//
NTSTATUS NlMakeSessionKey( IN ULONG NegotiatedFlags, IN PNT_OWF_PASSWORD CryptKey, IN PNETLOGON_CREDENTIAL ClientChallenge, IN PNETLOGON_CREDENTIAL ServerChallenge, OUT PNETLOGON_SESSION_KEY SessionKey );
#ifdef _DC_NETLOGON
NTSTATUS NlCheckAuthenticator( IN OUT PSERVER_SESSION ServerServerSession, IN PNETLOGON_AUTHENTICATOR Authenticator, OUT PNETLOGON_AUTHENTICATOR ReturnAuthenticator ); #endif _DC_NETLOGON
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 );
VOID NlPrintTrustedDomain( PDS_DOMAIN_TRUSTSW TrustedDomain, IN BOOLEAN VerbosePrint, IN BOOLEAN AnsiOutput );
//
// trustutl.c
//
//
// Extended trust information passed via I_NetLogonGetDomainInfo
//
typedef struct _NL_TRUST_EXTENSION { ULONG Flags; ULONG ParentIndex; ULONG TrustType; ULONG TrustAttributes; } NL_TRUST_EXTENSION, *PNL_TRUST_EXTENSION;
PCLIENT_SESSION NlFindNamedClientSession( IN PDOMAIN_INFO DomainInfo, IN PUNICODE_STRING DomainName, IN ULONG Flags, OUT PBOOLEAN TransitiveUsed OPTIONAL );
PCLIENT_SESSION NlAllocateClientSession( IN PDOMAIN_INFO DomainInfo, IN PUNICODE_STRING DomainName, IN PUNICODE_STRING DnsDomainName OPTIONAL, IN PSID DomainId, IN GUID *DomainGuid OPTIONAL, IN ULONG Flags, IN NETLOGON_SECURE_CHANNEL_TYPE SecureChannelType, IN ULONG TrustAttributes );
VOID NlFreeClientSession( IN PCLIENT_SESSION ClientSession );
VOID NlRefClientSession( IN PCLIENT_SESSION ClientSession );
VOID NlUnrefClientSession( IN PCLIENT_SESSION ClientSession );
PCLIENT_API NlAllocateClientApi( IN PCLIENT_SESSION ClientSession, IN DWORD Timeout );
VOID NlFreeClientApi( IN PCLIENT_SESSION ClientSession, IN PCLIENT_API ClientApi );
BOOL NlTimeoutSetWriterClientSession( IN PCLIENT_SESSION ClientSession, IN DWORD Timeout );
VOID NlResetWriterClientSession( IN PCLIENT_SESSION ClientSession );
NTSTATUS NlCaptureServerClientSession ( IN PCLIENT_SESSION ClientSession, OUT LPWSTR *UncServerName, OUT DWORD *DiscoveryFlags OPTIONAL );
NTSTATUS NlCaptureNetbiosServerClientSession ( IN PCLIENT_SESSION ClientSession, OUT WCHAR NetbiosUncServerName[UNCLEN+1] );
BOOL NlSetNamesClientSession( IN PCLIENT_SESSION ClientSession, IN PUNICODE_STRING DomainName OPTIONAL, IN PUNICODE_STRING DnsDomainName OPTIONAL, IN PSID DomainId OPTIONAL, IN GUID *DomainGuid OPTIONAL );
VOID NlSetStatusClientSession( IN PCLIENT_SESSION ClientSession, IN NTSTATUS CsConnectionStatus );
#ifdef _DC_NETLOGON
NTSTATUS NlInitTrustList( IN PDOMAIN_INFO DomainInfo );
VOID NlPickTrustedDcForEntireTrustList( IN PDOMAIN_INFO DomainInfo, IN BOOLEAN OnlyDoNewTrusts ); #endif // _DC_NETLOGON
NTSTATUS NlUpdatePrimaryDomainInfo( IN LSAPR_HANDLE PolicyHandle, IN PUNICODE_STRING NetbiosDomainName, IN PUNICODE_STRING DnsDomainName, IN PUNICODE_STRING DnsForestName, IN GUID *DomainGuid );
VOID NlSetForestTrustList ( IN PDOMAIN_INFO DomainInfo, IN OUT PDS_DOMAIN_TRUSTSW *ForestTrustList, IN ULONG ForestTrustListSize, IN ULONG ForestTrustListCount );
NET_API_STATUS NlReadRegTrustedDomainList ( IN PDOMAIN_INFO DomainInfo, IN BOOL DeleteName, OUT PDS_DOMAIN_TRUSTSW *RetForestTrustList, OUT PULONG RetForestTrustListSize, OUT PULONG RetForestTrustListCount );
NET_API_STATUS NlReadFileTrustedDomainList ( IN PDOMAIN_INFO DomainInfo, IN LPWSTR FileSuffix, IN BOOL DeleteName, IN ULONG Flags, OUT PDS_DOMAIN_TRUSTSW *RetForestTrustList, OUT PULONG RetForestTrustListSize, OUT PULONG RetForestTrustListCount );
NET_API_STATUS NlpEnumerateDomainTrusts ( IN PDOMAIN_INFO DomainInfo, IN ULONG Flags, OUT PULONG RetForestTrustListCount, OUT PDS_DOMAIN_TRUSTSW *RetForestTrustList );
BOOLEAN NlIsDomainTrusted ( IN PUNICODE_STRING DomainName );
NET_API_STATUS NlGetTrustedDomainNames ( IN PDOMAIN_INFO DomainInfo, IN LPWSTR DomainName, OUT LPWSTR *TrustedDnsDomainName, OUT LPWSTR *TrustedNetbiosDomainName );
typedef enum _DISCOVERY_TYPE { #ifdef _DC_NETLOGON
DT_DeadDomain, DT_Asynchronous, #endif // _DC_NETLOGON
DT_Synchronous } DISCOVERY_TYPE;
NET_API_STATUS NlSetServerClientSession( IN OUT PCLIENT_SESSION ClientSession, IN PNL_DC_CACHE_ENTRY NlDcCacheEntry, IN BOOL DcDiscoveredWithAccount, IN BOOL SessionRefresh );
NTSTATUS NlDiscoverDc ( IN OUT PCLIENT_SESSION ClientSession, IN DISCOVERY_TYPE DiscoveryType, IN BOOLEAN InDiscoveryThread, IN BOOLEAN DiscoverWithAccount );
VOID NlFlushCacheOnPnp ( VOID );
BOOL NlReadSamLogonResponse ( IN HANDLE ResponseMailslotHandle, IN LPWSTR AccountName, OUT LPDWORD Opcode, OUT LPWSTR *LogonServer, OUT PNL_DC_CACHE_ENTRY *NlDcCacheEntry OPTIONAL );
#ifdef _DC_NETLOGON
NTSTATUS NlPickDomainWithAccount ( IN PDOMAIN_INFO DomainInfo, IN PUNICODE_STRING InAccountNameString, IN PUNICODE_STRING InDomainNameString OPTIONAL, IN ULONG AllowableAccountControlBits, IN NETLOGON_SECURE_CHANNEL_TYPE SecureChannelType, IN BOOLEAN ExpediteToRoot, IN BOOLEAN CrossForestHop, OUT LPWSTR *RealSamAccountName, OUT LPWSTR *RealDomainName, OUT PULONG RealExtraFlags ); #endif // _DC_NETLOGON
#ifdef _NETLOGON_SERVER
NTSTATUS NlGetConfigurationName( DWORD which, DWORD *pcbName, DSNAME *pName );
NTSTATUS NlGetConfigurationNamesList( DWORD which, DWORD dwFlags, ULONG * pcbNames, DSNAME ** padsNames );
NTSTATUS NlGetDnsRootAlias( WCHAR * pDnsRootAlias, WCHAR * pRootDnsRootAlias);
DWORD NlDsGetServersAndSitesForNetLogon( WCHAR * pNDNC, SERVERSITEPAIR ** ppaRes);
VOID NlDsFreeServersAndSitesForNetLogon( SERVERSITEPAIR * paServerSites );
NTSTATUS NlCrackSingleName( DWORD formatOffered, // one of DS_NAME_FORMAT in ntdsapi.h
BOOL fPerformAtGC, // whether to go to GC or not
WCHAR *pNameIn, // name to crack
DWORD formatDesired, // one of DS_NAME_FORMAT in ntdsapi.h
DWORD *pccDnsDomain, // char count of following argument
WCHAR *pDnsDomain, // buffer for DNS domain name
DWORD *pccNameOut, // char count of following argument
WCHAR *pNameOut, // buffer for formatted name
DWORD *pErr); // one of DS_NAME_ERROR in ntdsapi.h
BOOL NlIsMangledRDNExternal( WCHAR * pszRDN, ULONG cchRDN, PULONG pcchUnMangled OPTIONAL ); #endif // _NETLOGON_SERVER
//
// Macros to wrap all API calls over the secure channel.
//
// Here's a sample calling sequence"
//
// NL_API_START( Status, ClientSession, TRUE ) {
//
// Status = /* Call the secure channel API */
//
// } NL_API_ELSE ( Status, ClientSession, FALSE ) {
//
// /* Do whatever you'd do if the secure channel was timed out */
//
// } NL_API_END;
// Loop through each of the appropriate RPC bindings for this ClientSession.
// Avoid the real API call altogether if we can't bind.
#define NL_API_START_EX( _NtStatus, _ClientSession, _QuickApiCall, _ClientApi ) \
{ \ ULONG _BindingLoopCount; \ \ _NtStatus = RPC_NT_PROTSEQ_NOT_SUPPORTED; \ for ( _BindingLoopCount=0; _BindingLoopCount<2; _BindingLoopCount++ ) { \ _NtStatus = NlStartApiClientSession( (_ClientSession), (_QuickApiCall), _BindingLoopCount, _NtStatus, _ClientApi ); \ \ if ( NT_SUCCESS(_NtStatus) ) {
#define NL_API_START( _NtStatus, _ClientSession, _QuickApiCall ) \
NL_API_START_EX( _NtStatus, _ClientSession, _QuickApiCall, &(_ClientSession)->CsClientApi[0] )
// If the real API indicates the endpoint isn't registered,
// fall back to another binding.
//
// EPT_NT_NOT_REGISTERED: from NlStartApiClientSession
// RPC_NT_SERVER_UNAVAILABLE: From server if TCP not configured at all
// RPC_NT_PROTSEQ_NOT_SUPPORTED: From client or server if TCP/IP not supported
//
#define NL_API_ELSE_EX( _NtStatus, _ClientSession, _OkToKillSession, _AmWriter, _ClientApi ) \
\ } \ \ if ( _NtStatus == EPT_NT_NOT_REGISTERED || \ _NtStatus == RPC_NT_SERVER_UNAVAILABLE || \ _NtStatus == RPC_NT_PROTSEQ_NOT_SUPPORTED ) { \ continue; \ } \ \ break; \ \ } \ \ if ( !NlFinishApiClientSession( (_ClientSession), (_OkToKillSession), (_AmWriter), (_ClientApi) ) ) {
#define NL_API_ELSE( _NtStatus, _ClientSession, _OkToKillSession ) \
NL_API_ELSE_EX( _NtStatus, _ClientSession, _OkToKillSession, TRUE, &(_ClientSession)->CsClientApi[0] ) \
#define NL_API_END \
} \ } \
NTSTATUS NlStartApiClientSession( IN PCLIENT_SESSION ClientSession, IN BOOLEAN QuickApiCall, IN ULONG RetryIndex, IN NTSTATUS DefaultStatus, IN PCLIENT_API ClientApi );
BOOLEAN NlFinishApiClientSession( IN PCLIENT_SESSION ClientSession, IN BOOLEAN OkToKillSession, IN BOOLEAN AmWriter, IN PCLIENT_API ClientApi );
VOID NlTimeoutApiClientSession( IN PDOMAIN_INFO DomainInfo );
typedef DWORD (*PDsBindW)( LPCWSTR DomainControllerName, // in, optional
LPCWSTR DnsDomainName, // in, optional
HANDLE *phDS);
typedef DWORD (*PDsUnBindW)( HANDLE *phDS); // in
typedef NTSTATUS (*PCrackSingleName)( DWORD formatOffered, DWORD dwFlags, WCHAR *pNameIn, DWORD formatDesired, DWORD *pccDnsDomain, WCHAR *pDnsDomain, DWORD *pccNameOut, WCHAR *pNameOut, DWORD *pErr);
typedef NTSTATUS (*PGetConfigurationName)( DWORD which, DWORD *pcbName, DSNAME *pName);
typedef NTSTATUS (*PGetConfigurationNamesList)( DWORD which, DWORD dwFlags, ULONG * pcbNames, DSNAME ** padsNames);
typedef NTSTATUS (*PGetDnsRootAlias)( WCHAR * pDnsRootAlias, WCHAR * pRootDnsRootAlias);
typedef DWORD (*PDsGetServersAndSitesForNetLogon)( WCHAR * pNDNC, SERVERSITEPAIR ** ppaRes);
typedef VOID (*PDsFreeServersAndSitesForNetLogon)( SERVERSITEPAIR * paServerSites);
typedef BOOL (*PIsMangledRDNExternal)( WCHAR * pszRDN, ULONG cchRDN, PULONG pcchUnMangled OPTIONAL );
NTSTATUS NlLoadNtdsaDll( VOID );
//
// secpkg.c
//
PVOID NlBuildAuthData( PCLIENT_SESSION ClientSession );
BOOL NlEqualClientSessionKey( PCLIENT_SESSION ClientSession, PVOID ClientContext );
BOOL NlStartNetlogonCall( VOID );
VOID NlEndNetlogonCall( VOID );
//
// ssiapi.c
//
NTSTATUS NlGetAnyDCName ( IN PCLIENT_SESSION ClientSession, IN BOOL RequireIp, IN BOOL DoDiscoveryWithAccount, OUT PNL_DC_CACHE_ENTRY *NlDcCacheEntry, OUT PBOOLEAN DcRediscovered );
NET_API_STATUS NlSetDsSPN( IN BOOLEAN Synchronous, IN BOOLEAN SetSpn, IN BOOLEAN SetDnsHostName, IN PDOMAIN_INFO DomainInfo, IN LPWSTR UncDcName, IN LPWSTR ComputerName, IN LPWSTR DnsHostName );
NET_API_STATUS NlPingDcName ( IN PCLIENT_SESSION ClientSession, IN ULONG DcNamePingFlags, IN BOOL CachePingedDc, IN BOOL RequireIp, IN BOOL DoPingWithAccount, IN BOOL RefreshClientSession, IN LPWSTR DcName OPTIONAL, OUT PNL_DC_CACHE_ENTRY *NlDcCacheEntry OPTIONAL );
VOID NlFreePingContext( IN PNL_GETDC_CONTEXT PingContext );
VOID NlScavengeOldChallenges( VOID );
VOID NlRemoveChallengeForClient( IN LPWSTR ClientName OPTIONAL, IN LPWSTR AccountName OPTIONAL, IN BOOL InterdomainTrustAccount );
//
// logonapi.c
//
NTSTATUS NlpUserValidateHigher ( IN PCLIENT_SESSION ClientSession, IN BOOLEAN DoingIndirectTrust, IN NETLOGON_LOGON_INFO_CLASS LogonLevel, IN LPBYTE LogonInformation, IN NETLOGON_VALIDATION_INFO_CLASS ValidationLevel, OUT LPBYTE * ValidationInformation, OUT PBOOLEAN Authoritative, IN OUT PULONG ExtraFlags );
VOID NlScavengeOldFailedLogons( IN PDOMAIN_INFO DomainInfo );
VOID DsFlagsToString( IN DWORD Flags, OUT LPSTR Buffer );
NET_API_STATUS NlInitializeAuthzRM( VOID );
VOID NlFreeAuthzRm( VOID );
//
// ftinfo.c
//
NTSTATUS NlpGetForestTrustInfoHigher( IN PCLIENT_SESSION ClientSession, IN DWORD Flags, IN BOOLEAN ImpersonateCaller, IN BOOLEAN SessionAlreadyAuthenticated, OUT PLSA_FOREST_TRUST_INFORMATION *ForestTrustInfo );
|