Leaked source code of windows server 2003
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.

417 lines
13 KiB

  1. /*++
  2. Copyright (c) 1994-7 Microsoft Corporation
  3. Module Name:
  4. binldef.h
  5. Abstract:
  6. This file contains manifest constants and internal data structures
  7. for the BINL service.
  8. Author:
  9. Colin Watson (colinw) 14-Apr-1997
  10. Environment:
  11. User Mode - Win32
  12. Revision History:
  13. --*/
  14. #ifndef _BINL_
  15. #define _BINL_
  16. #if DBG
  17. #define STATIC
  18. #else
  19. #define STATIC static
  20. #endif // DBG
  21. //
  22. // Globals
  23. //
  24. extern DWORD BinlRepeatSleep;
  25. // Connection information to a DC in our domain
  26. extern PLDAP DCLdapHandle;
  27. extern PWCHAR * DCBase;
  28. // Connection information to the Global Catalog for our enterprise
  29. extern PLDAP GCLdapHandle;
  30. extern PWCHAR * GCBase;
  31. //
  32. // useful macros
  33. //
  34. #define WSTRSIZE( wsz ) (( wcslen( wsz ) + 1 ) * sizeof( WCHAR ))
  35. #define STRSIZE( sz ) (( strlen( sz ) + 1 ) * sizeof( char ))
  36. #define SWAP( p1, p2 ) \
  37. { \
  38. VOID *pvTemp = p1; \
  39. p1 = p2; \
  40. p2 = pvTemp; \
  41. }
  42. //
  43. // calculates the size of a field
  44. //
  45. #define GET_SIZEOF_FIELD( struct, field ) ( sizeof(((struct*)0)->field))
  46. //
  47. // Constants
  48. //
  49. #define BINL_SERVER L"BINLSVC"
  50. //
  51. // Timeouts, this is the length of time we wait for our threads to terminate.
  52. //
  53. #define THREAD_TERMINATION_TIMEOUT INFINITE // wait a long time,
  54. // but don't AV
  55. #define BINL_HYPERMODE_TIMEOUT 60*1000 // in msecs. 1 min
  56. #define BINL_HYPERMODE_RETRY_COUNT 30 // do it for 30 mins
  57. //
  58. // message queue length.
  59. //
  60. #define BINL_RECV_QUEUE_LENGTH 50
  61. #define BINL_MAX_PROCESSING_THREADS 20
  62. #define BINL_MESSAGE_SIZE 1500
  63. //
  64. // macros
  65. //
  66. #define LOCK_INPROGRESS_LIST() EnterCriticalSection(&BinlGlobalInProgressCritSect)
  67. #define UNLOCK_INPROGRESS_LIST() LeaveCriticalSection(&BinlGlobalInProgressCritSect)
  68. #define LOCK_RECV_LIST() EnterCriticalSection(&BinlGlobalRecvListCritSect)
  69. #define UNLOCK_RECV_LIST() LeaveCriticalSection(&BinlGlobalRecvListCritSect)
  70. //
  71. // An endpoint represents a socket and the addresses associated with
  72. // the socket.
  73. //
  74. typedef struct _ENDPOINT {
  75. SOCKET Socket;
  76. DWORD Port;
  77. DHCP_IP_ADDRESS IpAddress;
  78. DHCP_IP_ADDRESS SubnetMask;
  79. DHCP_IP_ADDRESS SubnetAddress;
  80. } ENDPOINT, *LPENDPOINT, *PENDPOINT;
  81. //
  82. // A request context, one per processing thread.
  83. //
  84. typedef struct _BINL_REQUEST_CONTEXT {
  85. //
  86. // list pointer.
  87. //
  88. LIST_ENTRY ListEntry;
  89. //
  90. // pointer to a received buffer.
  91. //
  92. LPBYTE ReceiveBuffer;
  93. //
  94. // A buffer to send response.
  95. //
  96. LPBYTE SendBuffer;
  97. //
  98. // The actual amount of data received in the buffer.
  99. //
  100. DWORD ReceiveMessageSize;
  101. //
  102. // The actual amount of data send in the buffer.
  103. //
  104. DWORD SendMessageSize;
  105. //
  106. // The source of the current message
  107. //
  108. PENDPOINT ActiveEndpoint;
  109. struct sockaddr SourceName;
  110. DWORD SourceNameLength;
  111. DWORD TimeArrived;
  112. BYTE MessageType;
  113. } BINL_REQUEST_CONTEXT, *LPBINL_REQUEST_CONTEXT, *PBINL_REQUEST_CONTEXT;
  114. #define BOOT_FILE_SIZE 128
  115. #define BOOT_SERVER_SIZE 64
  116. #define BOOT_FILE_SIZE_W ( BOOT_FILE_SIZE * sizeof( WCHAR ))
  117. #define BOOT_SERVER_SIZE_W ( BOOT_SERVER_SIZE * sizeof( WCHAR ))
  118. //
  119. // Registry data
  120. //
  121. #define BINL_PARAMETERS_KEY L"System\\CurrentControlSet\\Services\\Binlsvc\\Parameters"
  122. #define BINL_PORT_NAME L"Port"
  123. #define BINL_DEFAULT_PORT 4011
  124. #define BINL_DEBUG_KEY L"Debug"
  125. #if DBG
  126. #define BINL_REPEAT_RESPONSE L"RepeatResponse"
  127. #endif // DBG
  128. #define BINL_LDAP_OPT_REFERRALS L"LdapOptReferrals"
  129. #define BINL_MIN_RESPONSE_TIME L"ResponseDelay"
  130. #define BINL_LDAP_SEARCH_TIMEOUT L"LdapTimeout"
  131. #define BINL_CACHE_EXPIRE L"CacheExpire"
  132. #define BINL_CACHE_MAX_COUNT L"CacheMaxCount"
  133. #define BINL_ALLOW_NEW_CLIENTS L"AllowNewClients"
  134. #define BINL_DEFAULT_CONTAINER L"DefaultContainer"
  135. #define BINL_DEFAULT_DOMAIN L"DefaultDomain"
  136. #define BINL_DEFAULT_DS L"DefaultServer"
  137. #define BINL_DEFAULT_GC L"DefaultGCServer"
  138. #define BINL_CLIENT_TIMEOUT L"ClientTimeout"
  139. #define BINL_SCAVENGER_SLEEP L"ScavengerSleep"
  140. #define BINL_SCAVENGER_SIFFILE L"SifFileSleep"
  141. #define BINL_DEFAULT_LANGUAGE L"DefaultLanguage"
  142. #define BINL_UPDATE_PARAMETER_POLL L"UpdateParameterPoll"
  143. #define BINL_DS_ERROR_COUNT_PARAMETER L"MaxDSErrorsToLog"
  144. #define BINL_DS_ERROR_SLEEP L"DSErrorInterval"
  145. #define BINL_ASSIGN_NEW_CLIENTS_TO_SERVER L"AssignNewClientsToServer"
  146. #define BINL_NTLMV2_AUTHENTICATE L"UseNTLMV2Authentication"
  147. #define BINL_SCP_CREATED L"ScpCreated"
  148. #define BINL_SCP_NEWCLIENTS L"netbootAllowNewClients"
  149. #define BINL_SCP_LIMITCLIENTS L"netbootLimitClients"
  150. #define BINL_SCP_CURRENTCLIENTCOUNT L"netbootCurrentClientCount"
  151. #define BINL_SCP_MAXCLIENTS L"netbootMaxClients"
  152. #define BINL_SCP_ANSWER_REQUESTS L"netbootAnswerRequests"
  153. #define BINL_SCP_ANSWER_VALID L"netbootAnswerOnlyValidClients"
  154. #define BINL_SCP_NEWMACHINENAMEPOLICY L"netbootNewMachineNamingPolicy"
  155. #define BINL_SCP_NEWMACHINEOU L"netbootNewMachineOU"
  156. #define BINL_SCP_NETBOOTSERVER L"netbootServer"
  157. typedef struct _DHCP_BINARY_DATA {
  158. DWORD DataLength;
  159. #if defined(MIDL_PASS)
  160. [size_is(DataLength)]
  161. #endif // MIDL_PASS
  162. BYTE *Data;
  163. } DHCP_BINARY_DATA, *LPDHCP_BINARY_DATA;
  164. //
  165. // Structure that defines the state of a client.
  166. //
  167. // The reason we use a separate Positive and Negative RefCount is so that
  168. // we don't have to re-acquire the global ClientsCriticalSection when
  169. // we are done with a CLIENT_STATE, just to decrement the ref count.
  170. // Instead we guard the NegativeRefCount with just the CLIENT_STATE's
  171. // CriticalSection. Then we compare Positive and Negative and if they
  172. // are equal we delete the CLIENT_STATE. Even if PositiveRefCount is
  173. // being added to just as we do this comparison, it won't ever be equal
  174. // to Negative RefCount unless we really are the last thread to use the
  175. // CLIENT_STATE.
  176. //
  177. // Padding is in the structure so that the first two elements, which are
  178. // guarded by ClientsCriticalSection, aren't in the same quadword as
  179. // anything else.
  180. //
  181. // search and replace structure
  182. typedef struct {
  183. LPSTR pszToken;
  184. struct {
  185. LPSTR pszStringA;
  186. LPWSTR pszStringW;
  187. };
  188. } SAR, * LPSAR;
  189. #define MAX_VARIABLES 64
  190. typedef struct _CLIENT_STATE {
  191. LIST_ENTRY Linkage; // in ClientsQueue
  192. ULONG PositiveRefCount; // guarded by global ClientsCriticalSection
  193. ULONG Padding;
  194. CRITICAL_SECTION CriticalSection; // prevents two messages processed at once
  195. ULONG NegativeRefCount; // guarded by our CriticalSection; delete when equal to PositiveRC
  196. ULONG RemoteIp; // IP address of the client
  197. CtxtHandle ServerContextHandle;
  198. PLDAP AuthenticatedDCLdapHandle; // returned by ldap_bind (with credentials)
  199. HANDLE UserToken; // returned by LogonUser with same credentials
  200. ULONG ContextAttributes;
  201. UCHAR Seed; // seed used for run encoding-decoding
  202. BOOL NegotiateProcessed;
  203. BOOL CustomInstall; // true if custom, false if auto
  204. BOOL AuthenticateProcessed; // if TRUE, then AuthenticateStatus is valid
  205. BOOL CriticalSectionHeld; // just a quick check, not 100% accurate.
  206. BOOL InitializeOnFirstRequest; // call OscInitializeClientVariables on initial request?
  207. SECURITY_STATUS AuthenticateStatus;
  208. ULONG LastSequenceNumber;
  209. PUCHAR LastResponse; // buffer holding the last packet sent
  210. ULONG LastResponseAllocated; // size LastResponse is allocated at
  211. ULONG LastResponseLength; // size of current data in LastResponse
  212. DWORD LastUpdate; // Last time this client state was entered
  213. ULONG nVariables; // current number of defined varaibles
  214. SAR Variables[ MAX_VARIABLES ]; // "variables" that are replaced in OSCs and SIFs
  215. INT nCreateAccountCounter; // Counts up each time a different computer name was tired
  216. BOOL fCreateNewAccount; // FALSE if a pre-staged account exists
  217. BOOL fAutomaticMachineName; // TRUE is BINL generated the machine name
  218. BOOL fHaveSetupMachineDN; // TRUE if we've already called OscCheckMachineDN
  219. WCHAR MachineAccountPassword[LM20_PWLEN+1];
  220. DWORD MachineAccountPasswordLength;
  221. } CLIENT_STATE, *PCLIENT_STATE;
  222. //
  223. // The structure that tracks info based on GUID.
  224. //
  225. // Because checking the DS is a expensive, we track the results we received
  226. // from the DS per GUID in this structure. This also allows us to ignore
  227. // duplicate requests from clients when we're already working on them.
  228. //
  229. // These cache entries are very short lived, on the order of a minute or so.
  230. // We'd hold them longer except we have no idea when they get stale in the DS.
  231. //
  232. // The list of cache entries is protected by BinlCacheListLock. An entry
  233. // is in use when the InProgress flag is set. If this flag is set, it means
  234. // that a thread is actively using it and the entry shouldn't be touched.
  235. //
  236. // If the hostname is not filled in and the NotMyClient flag is set to FALSE,
  237. // then the entry, though allocated, hasn't been fully filled in.
  238. //
  239. // The XXX_ALLOC bits indicate that the corresponding field was allocated
  240. // and needs to be freed when the cache entry is freed.
  241. //
  242. #define BINL_GUID_LENGTH 16
  243. #define MI_NAME 0x00000001
  244. #define MI_SETUPPATH 0x00000002
  245. #define MI_HOSTNAME 0x00000004
  246. #define MI_BOOTFILENAME 0x00000008
  247. #define MI_SAMNAME 0x00000010
  248. #define MI_PASSWORD 0x00000020
  249. #define MI_DOMAIN 0x00000040
  250. #define MI_HOSTIP 0x00000080
  251. #define MI_MACHINEDN 0x00000100
  252. #define MI_NAME_ALLOC 0x00010000
  253. #define MI_SETUPPATH_ALLOC 0x00020000
  254. #define MI_HOSTNAME_ALLOC 0x00040000
  255. #define MI_BOOTFILENAME_ALLOC 0x00080000
  256. #define MI_SAMNAME_ALLOC 0x00100000
  257. #define MI_DOMAIN_ALLOC 0x00400000
  258. #define MI_SIFFILENAME_ALLOC 0x00800000
  259. #define MI_MACHINEDN_ALLOC 0x01000000
  260. #define MI_ALL_ALLOC 0x03ff0000
  261. #define MI_GUID 0x80000000 // UpdateCreate forces a new guid to be written
  262. typedef struct _MACHINE_INFO {
  263. LIST_ENTRY CacheListEntry; // global is BinlCacheList
  264. DWORD TimeCreated; // from GetTickCount
  265. BOOLEAN InProgress; // is a thread currently working on this?
  266. BOOLEAN MyClient; // do we not respond to this client?
  267. BOOLEAN EntryExists; // does the entry exist in the DS?
  268. DWORD dwFlags; // "MI_" bits saying what information is currently valid
  269. UCHAR Guid[BINL_GUID_LENGTH]; // client's GUID
  270. PWCHAR Name; // client's name
  271. PWCHAR MachineDN; // client's FQ Distinguished Name
  272. PWCHAR SetupPath; // client's orginal installation path
  273. PWCHAR HostName; // client's host server name
  274. DHCP_IP_ADDRESS HostAddress; // address of host - this is filled when HostName is filled
  275. PWCHAR BootFileName; // client's boot filename
  276. PWCHAR SamName; // client's SAM name
  277. PWCHAR Password; // client's password (for setting only)
  278. ULONG PasswordLength; // client's password length (for setting only)
  279. PWCHAR Domain; // client's domain
  280. LIST_ENTRY DNsWithSameGuid; // list of DNs with same GUID, except for MachineDN above.
  281. PWCHAR ForcedSifFileName; // client's sif file it must use.
  282. } MACHINE_INFO, *PMACHINE_INFO;
  283. //
  284. // Structure that tracks duplicate DNs for this machine account. The structure
  285. // is allocated with room for the two strings at the end.
  286. //
  287. typedef struct _DUP_GUID_DN {
  288. LIST_ENTRY ListEntry;
  289. ULONG DuplicateDNOffset; // offset from the start of DuplicateName to DuplicateDN
  290. WCHAR DuplicateName[ANYSIZE_ARRAY]; // name of the duplicate account (without final '$')
  291. // WCHAR DuplicateDN[]; // this follows at DuplicateDNOffset
  292. } DUP_GUID_DN, *PDUP_GUID_DN;
  293. //
  294. // The largest size of any client architecture name
  295. // (current choices: i386 alpha mips ia64 ppc arci386) --
  296. // assume it won't exceed 8 chars for now.
  297. //
  298. #define MAX_ARCHITECTURE_LENGTH 8
  299. #define DHCP_OPTION_CLIENT_ARCHITECTURE_X86 0
  300. #define DHCP_OPTION_CLIENT_ARCHITECTURE_NEC98 1
  301. #define DHCP_OPTION_CLIENT_ARCHITECTURE_IA64 2
  302. #define DHCP_OPTION_CLIENT_ARCHITECTURE_ALPHA 3
  303. #define DHCP_OPTION_CLIENT_ARCHITECTURE_ARCX86 4
  304. #define DHCP_OPTION_CLIENT_ARCHITECTURE_INTELLEAN 5
  305. //
  306. // Structure that tracks the queued DS Names that we want to register
  307. // with the DS, but havent yet. Keeping a running list of queued DS names
  308. // prevents multi-threaded collisions on the same name.
  309. //
  310. typedef struct _QUEUED_DS_NAME_NODE {
  311. LIST_ENTRY ListEntry;
  312. WCHAR Name[ANYSIZE_ARRAY];
  313. } QUEUED_DS_NAME_NODE, *PQUEUED_DS_NAME_NODE;
  314. #endif _BINL_