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.

350 lines
10 KiB

  1. /*++
  2. Copyright (c) 1992 Microsoft Corporation
  3. Module Name:
  4. brwan.c
  5. Abstract:
  6. This module contains WAN support routines used by the
  7. Browser service.
  8. Author:
  9. Larry Osterman (LarryO) 22-Nov-1992
  10. Revision History:
  11. --*/
  12. #include "precomp.h"
  13. #pragma hdrstop
  14. //-------------------------------------------------------------------//
  15. // //
  16. // Local function prototypes //
  17. // //
  18. //-------------------------------------------------------------------//
  19. NET_API_STATUS
  20. BrAddDomainEntry(
  21. IN PINTERIM_SERVER_LIST InterimServerList,
  22. IN LPTSTR ConfigEntry
  23. );
  24. //-------------------------------------------------------------------//
  25. // //
  26. // Global variables //
  27. // //
  28. //-------------------------------------------------------------------//
  29. //-------------------------------------------------------------------//
  30. // //
  31. // Global routines //
  32. // //
  33. //-------------------------------------------------------------------//
  34. NET_API_STATUS NET_API_FUNCTION
  35. I_BrowserrQueryOtherDomains(
  36. IN BROWSER_IDENTIFY_HANDLE ServerName,
  37. IN OUT LPSERVER_ENUM_STRUCT InfoStruct,
  38. OUT LPDWORD TotalEntries
  39. )
  40. /*++
  41. Routine Description:
  42. This routine returns the list of "other domains" configured for this
  43. machine. It is only valid on primary domain controllers. If it is called
  44. on a machine that is not a PDC, it will return NERR_NotPrimary.
  45. Arguments:
  46. IN BROWSER_IDENTIFY_HANDLE ServerName - Ignored.
  47. IN LPSERVER_ENUM_STRUCT InfoStruct - Returns the list of other domains
  48. as a SERVER_INFO_100 structure.
  49. OUT LPDWORD TotalEntries - Returns the total number of other domains.
  50. Return Value:
  51. NET_API_STATUS - The status of this request.
  52. --*/
  53. {
  54. NET_API_STATUS Status;
  55. PSERVER_INFO_100 ServerInfo;
  56. ULONG NumberOfOtherDomains;
  57. if ( InfoStruct == NULL ) {
  58. return ERROR_INVALID_PARAMETER;
  59. }
  60. if (InfoStruct->Level != 100) {
  61. return(ERROR_INVALID_LEVEL);
  62. }
  63. if ( InfoStruct->ServerInfo.Level100 == NULL ) {
  64. return ERROR_INVALID_PARAMETER;
  65. }
  66. //
  67. // Use the worker routine to do the actual work.
  68. //
  69. Status = BrQueryOtherDomains( &ServerInfo, &NumberOfOtherDomains );
  70. if ( Status == NERR_Success ) {
  71. *TotalEntries = NumberOfOtherDomains;
  72. InfoStruct->ServerInfo.Level100->Buffer = ServerInfo;
  73. InfoStruct->ServerInfo.Level100->EntriesRead = NumberOfOtherDomains;
  74. }
  75. return Status;
  76. }
  77. NET_API_STATUS
  78. BrWanMasterInitialize(
  79. IN PNETWORK Network
  80. )
  81. /*++
  82. Routine Description:
  83. This routine initializes the wan information for a new master.
  84. --*/
  85. {
  86. LPBYTE Buffer = NULL;
  87. PSERVER_INFO_100 ServerInfo;
  88. NET_API_STATUS Status;
  89. ULONG i;
  90. ULONG EntriesRead;
  91. ULONG TotalEntries;
  92. PDOMAIN_CONTROLLER_INFO pDcInfo=NULL;
  93. //
  94. // If we're on the PDC, then all our initialization has been done.
  95. // Or, if we're semi-pseudo server, we don't contact the PDC/BDC
  96. //
  97. #ifdef ENABLE_PSEUDO_BROWSER
  98. if ( (Network->Flags & NETWORK_PDC) ||
  99. BrInfo.PseudoServerLevel == BROWSER_SEMI_PSEUDO_NO_DMB ) {
  100. #else
  101. if ( Network->Flags & NETWORK_PDC ) {
  102. #endif
  103. return NERR_Success;
  104. }
  105. Status = DsGetDcName( NULL, NULL, NULL, NULL,
  106. DS_PDC_REQUIRED |
  107. DS_BACKGROUND_ONLY |
  108. DS_RETURN_FLAT_NAME,
  109. &pDcInfo );
  110. //
  111. // It is not an error to not be able to contact the PDC.
  112. //
  113. if (Status != NERR_Success) {
  114. return NERR_Success;
  115. }
  116. ASSERT ( pDcInfo &&
  117. pDcInfo->DomainControllerName );
  118. Status = I_BrowserQueryOtherDomains(pDcInfo->DomainControllerName,
  119. &Buffer,
  120. &EntriesRead,
  121. &TotalEntries);
  122. //
  123. // We don't need the PDC name any more.
  124. //
  125. NetApiBufferFree((LPVOID)pDcInfo);
  126. pDcInfo = NULL;
  127. if (Status != NERR_Success) {
  128. //
  129. // We failed to get the list from supposedly the PDC.
  130. // It could be that the role has changed & DsGetDcName's cache
  131. // hasn't got refreshed.
  132. //
  133. // Force PDC discovery so that next time around we're sure
  134. // to get the real PDC.
  135. //
  136. Status = DsGetDcName( NULL, NULL, NULL, NULL,
  137. DS_PDC_REQUIRED |
  138. DS_FORCE_REDISCOVERY | // Note FORCE option
  139. DS_RETURN_FLAT_NAME,
  140. &pDcInfo );
  141. if (Status != NERR_Success) {
  142. return NERR_Success;
  143. }
  144. ASSERT ( pDcInfo &&
  145. pDcInfo->DomainControllerName );
  146. Status = I_BrowserQueryOtherDomains(pDcInfo->DomainControllerName,
  147. &Buffer,
  148. &EntriesRead,
  149. &TotalEntries);
  150. //
  151. // We don't need the PDC name any more.
  152. //
  153. NetApiBufferFree((LPVOID)pDcInfo);
  154. if (Status != NERR_Success) {
  155. return NERR_Success;
  156. }
  157. }
  158. if (!LOCK_NETWORK(Network)) {
  159. return NERR_InternalError;
  160. }
  161. try {
  162. PLIST_ENTRY Entry;
  163. PLIST_ENTRY NextEntry;
  164. //
  165. // Scan the other domains list and turn on the active bit for each
  166. // other domain.
  167. //
  168. for (Entry = Network->OtherDomainsList.Flink;
  169. Entry != &Network->OtherDomainsList ;
  170. Entry = Entry->Flink) {
  171. PNET_OTHER_DOMAIN OtherDomain = CONTAINING_RECORD(Entry, NET_OTHER_DOMAIN, Next);
  172. OtherDomain->Flags |= OTHERDOMAIN_INVALID;
  173. }
  174. ServerInfo = (PSERVER_INFO_100)Buffer;
  175. for (i = 0; i < EntriesRead; i++ ) {
  176. //
  177. // Add this as an other domain.
  178. //
  179. for (Entry = Network->OtherDomainsList.Flink;
  180. Entry != &Network->OtherDomainsList ;
  181. Entry = Entry->Flink) {
  182. PNET_OTHER_DOMAIN OtherDomain = CONTAINING_RECORD(Entry, NET_OTHER_DOMAIN, Next);
  183. //
  184. // If this name is in the other domains list, it's not invalid
  185. // and we should flag that we've seen the domain name.
  186. //
  187. // The list we're getting is over the net. Make sure serverinfo
  188. // contains a valid name for comparison (see bug 377078)
  189. // Skip processing if NULL.
  190. // If ServerInfo got NULLED out in prev run, we shouldn't
  191. // get into _wcsicmp.
  192. if (ServerInfo->sv100_name &&
  193. !_wcsicmp(OtherDomain->Name, ServerInfo->sv100_name)) {
  194. OtherDomain->Flags &= ~OTHERDOMAIN_INVALID;
  195. ServerInfo->sv100_name = NULL;
  196. }
  197. }
  198. ServerInfo ++;
  199. }
  200. //
  201. // Scan the other domains list and remove any domains that are
  202. // still marked as invalid.
  203. //
  204. for (Entry = Network->OtherDomainsList.Flink;
  205. Entry != &Network->OtherDomainsList ;
  206. Entry = NextEntry) {
  207. PNET_OTHER_DOMAIN OtherDomain = CONTAINING_RECORD(Entry, NET_OTHER_DOMAIN, Next);
  208. if (OtherDomain->Flags & OTHERDOMAIN_INVALID) {
  209. NextEntry = Entry->Flink;
  210. //
  211. // Remove this entry from the list.
  212. //
  213. RemoveEntryList(Entry);
  214. BrRemoveOtherDomain(Network, OtherDomain->Name);
  215. MIDL_user_free(OtherDomain);
  216. } else {
  217. NextEntry = Entry->Flink;
  218. }
  219. }
  220. //
  221. // Now scan the domain list from the PDC and add any entries that
  222. // weren't there already.
  223. //
  224. ServerInfo = (PSERVER_INFO_100)Buffer;
  225. for (i = 0; i < EntriesRead; i++ ) {
  226. if (ServerInfo->sv100_name != NULL) {
  227. PNET_OTHER_DOMAIN OtherDomain = MIDL_user_allocate(sizeof(NET_OTHER_DOMAIN));
  228. if (OtherDomain != NULL) {
  229. Status = BrAddOtherDomain(Network, ServerInfo->sv100_name);
  230. //
  231. // If we were able to add the other domain, add it to our
  232. // internal structure.
  233. //
  234. if (Status == NERR_Success) {
  235. wcsncpy(OtherDomain->Name, ServerInfo->sv100_name, DNLEN);
  236. OtherDomain->Flags = 0;
  237. InsertHeadList(&Network->OtherDomainsList, &OtherDomain->Next);
  238. } else {
  239. LPWSTR SubString[1];
  240. SubString[0] = ServerInfo->sv100_name;
  241. BrLogEvent(EVENT_BROWSER_OTHERDOMAIN_ADD_FAILED, Status, 1, SubString);
  242. }
  243. }
  244. }
  245. ServerInfo ++;
  246. }
  247. } finally {
  248. UNLOCK_NETWORK(Network);
  249. if (Buffer != NULL) {
  250. MIDL_user_free(Buffer);
  251. }
  252. }
  253. return NERR_Success;
  254. }