Source code of Windows XP (NT5)
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.

334 lines
8.3 KiB

  1. /*++
  2. Copyright (c) 1997 Microsoft Corporation
  3. Module Name:
  4. netname.c
  5. Abstract:
  6. Miscellaneous network naming helper functions
  7. Author:
  8. Mac McLain (MacM) Oct 16, 1997
  9. Environment:
  10. User Mode
  11. Revision History:
  12. --*/
  13. #include <setpch.h>
  14. #include <dssetp.h>
  15. #include <lmcons.h>
  16. #include <lmaccess.h>
  17. #include <lmapibuf.h>
  18. #include <lmerr.h>
  19. #include <lmjoin.h>
  20. #include <netsetup.h>
  21. #include <lsarpc.h>
  22. #include <db.h>
  23. #include <lsasrvmm.h>
  24. #include <lsaisrv.h>
  25. #include <dns.h>
  26. #include <dnsapi.h>
  27. #define MAX_NAME_ATTEMPTS 260
  28. DWORD
  29. WINAPI
  30. DsRolepDnsNameToFlatName(
  31. IN LPWSTR DnsName,
  32. OUT LPWSTR *FlatName,
  33. OUT PULONG StatusFlag
  34. )
  35. /*++
  36. Routine Description:
  37. Determines the suggested netbios domain name for the given dns name
  38. Arguments:
  39. DnsName - The Dns domain name to generate a flat name for
  40. FlatName - Where the flat name is to be returned
  41. StatusFlag - Where the status is returned
  42. Returns:
  43. STATUS_SUCCESS - Success
  44. --*/
  45. {
  46. DWORD Win32Error = ERROR_SUCCESS;
  47. NTSTATUS Status;
  48. PPOLICY_DNS_DOMAIN_INFO DnsDomainInfo = NULL;
  49. PPOLICY_ACCOUNT_DOMAIN_INFO AccountDomainInfo;
  50. BOOLEAN FindFromDns = TRUE;
  51. WCHAR NbDomainName[ DNLEN + 1], NbNameAdd[ 4 ];
  52. PWSTR Current = NULL;
  53. WCHAR BaseChar;
  54. ULONG CurrentAttempt = 0;
  55. ULONG i,j;
  56. *StatusFlag = 0;
  57. DsRolepLogPrint(( DEB_TRACE,
  58. "Getting NetBIOS name for Dns name %ws\n",
  59. DnsName ));
  60. //
  61. // First, see if we are part of domain currently or not. If we are, then it's a simple
  62. // matter of returning the current Netbios domain name.
  63. //
  64. Status = LsaIQueryInformationPolicyTrusted(
  65. PolicyAccountDomainInformation,
  66. ( PLSAPR_POLICY_INFORMATION * )&AccountDomainInfo );
  67. if ( NT_SUCCESS( Status ) ) {
  68. Status = LsaIQueryInformationPolicyTrusted(
  69. PolicyDnsDomainInformation,
  70. ( PLSAPR_POLICY_INFORMATION * )&DnsDomainInfo );
  71. if ( !NT_SUCCESS( Status ) ) {
  72. LsaIFree_LSAPR_POLICY_INFORMATION(
  73. PolicyAccountDomainInformation,
  74. ( PLSAPR_POLICY_INFORMATION )AccountDomainInfo );
  75. }
  76. }
  77. if ( NT_SUCCESS( Status ) ) {
  78. if ( DnsDomainInfo->Sid == NULL || AccountDomainInfo->DomainSid == NULL ||
  79. !RtlEqualSid( AccountDomainInfo->DomainSid, DnsDomainInfo->Sid ) ) {
  80. //
  81. // We're not a member of the domain
  82. //
  83. FindFromDns = TRUE;
  84. } else {
  85. //
  86. // We are a domain member
  87. //
  88. WCHAR *BufDomainName = NULL;
  89. BufDomainName = (WCHAR*)malloc(DnsDomainInfo->Name.Length+sizeof(WCHAR));
  90. if (BufDomainName) {
  91. CopyMemory(BufDomainName,DnsDomainInfo->Name.Buffer,DnsDomainInfo->Name.Length);
  92. BufDomainName[DnsDomainInfo->Name.Length/sizeof(WCHAR)] = L'\0';
  93. DsRolepLogPrint(( DEB_TRACE,
  94. "Using existing NetBIOS domain name %ws\n",
  95. BufDomainName ));
  96. free(BufDomainName);
  97. }
  98. *FlatName = MIDL_user_allocate(
  99. ( DnsDomainInfo->Name.Length + 1 ) * sizeof( WCHAR ) );
  100. if ( *FlatName == NULL ) {
  101. Status = STATUS_INSUFFICIENT_RESOURCES;
  102. } else {
  103. RtlCopyMemory( *FlatName, DnsDomainInfo->Name.Buffer,
  104. DnsDomainInfo->Name.Length );
  105. ( *FlatName )[DnsDomainInfo->Name.Length / sizeof( WCHAR )] = UNICODE_NULL;
  106. *StatusFlag = DSROLE_FLATNAME_UPGRADE;
  107. *StatusFlag |= DSROLE_FLATNAME_DEFAULT;
  108. FindFromDns = FALSE;
  109. }
  110. }
  111. LsaIFree_LSAPR_POLICY_INFORMATION(
  112. PolicyAccountDomainInformation,
  113. ( PLSAPR_POLICY_INFORMATION )AccountDomainInfo );
  114. LsaIFree_LSAPR_POLICY_INFORMATION(
  115. PolicyDnsDomainInformation,
  116. ( PLSAPR_POLICY_INFORMATION )DnsDomainInfo );
  117. }
  118. //
  119. // If there was no domain name defined, we'll have to get one from the dns name
  120. //
  121. if ( Win32Error == ERROR_SUCCESS && FindFromDns ) {
  122. //
  123. // Ok, to start with, pull off the first DNLEN characters from the DNS name
  124. //
  125. RtlZeroMemory(NbDomainName, sizeof(WCHAR)*(DNLEN+1) );
  126. wcsncpy( NbDomainName, DnsName, DNLEN );
  127. Current = wcschr( NbDomainName, L'.' );
  128. if ( Current ) {
  129. *Current = UNICODE_NULL;
  130. }
  131. //
  132. // See if the name is currently in use or not
  133. //
  134. DsRolepLogPrint(( DEB_TRACE,
  135. "Testing default NetBIOS name %ws\n",
  136. NbDomainName ));
  137. Win32Error = NetpValidateName( NULL,
  138. NbDomainName,
  139. NULL,
  140. NULL,
  141. NetSetupNonExistentDomain );
  142. if ( Win32Error == ERROR_SUCCESS ) {
  143. *StatusFlag = DSROLE_FLATNAME_DEFAULT;
  144. } else if ( Win32Error == ERROR_DUP_NAME ) {
  145. //
  146. // Position on the last character in the name
  147. //
  148. Current = NbDomainName + wcslen( NbDomainName ) - 1;
  149. ASSERT(Current <= (NbDomainName + DNLEN - 1));
  150. //
  151. // If our name is less than the max. Set our current next to the last character
  152. //
  153. if ( (NbDomainName + DNLEN - 1) != Current ) {
  154. Current++;
  155. *( Current + 1 ) = UNICODE_NULL;
  156. }
  157. while ( CurrentAttempt < MAX_NAME_ATTEMPTS ) {
  158. _ultow( CurrentAttempt, NbNameAdd, 10 );
  159. ASSERT( wcslen( NbNameAdd ) < 4 );
  160. //
  161. // See if we need to adjust the position of where we copy
  162. //
  163. if ( CurrentAttempt == 10 || CurrentAttempt == 100 ) {
  164. if ( (NbDomainName + DNLEN) < (Current + wcslen(NbNameAdd)) ) {
  165. Current--;
  166. }
  167. }
  168. wcscpy( Current, NbNameAdd );
  169. DsRolepLogPrint(( DEB_TRACE,
  170. "Testing default NetBIOS name %ws\n",
  171. NbDomainName ));
  172. Win32Error = NetpValidateName( NULL,
  173. NbDomainName,
  174. NULL,
  175. NULL,
  176. NetSetupNonExistentDomain );
  177. //
  178. // If we've found a name that is in use, try again
  179. //
  180. if ( Win32Error != ERROR_DUP_NAME ) {
  181. break;
  182. }
  183. CurrentAttempt++;
  184. }
  185. }
  186. //
  187. // If we found a valid name, return it
  188. //
  189. if ( Win32Error == ERROR_SUCCESS ) {
  190. *FlatName = MIDL_user_allocate( ( wcslen( NbDomainName ) + 1 ) * sizeof( WCHAR ) );
  191. if ( *FlatName == NULL ) {
  192. Status = STATUS_INSUFFICIENT_RESOURCES;
  193. } else {
  194. wcscpy( *FlatName, NbDomainName );
  195. DsRolepLogPrint(( DEB_TRACE,
  196. "Found usable NetBIOS domain name %ws\n",
  197. NbDomainName ));
  198. }
  199. }
  200. }
  201. return( Win32Error );
  202. }
  203. DWORD
  204. DsRolepIsDnsNameChild(
  205. IN LPWSTR ParentDnsName,
  206. IN LPWSTR ChildDnsName
  207. )
  208. /*++
  209. Routine Description:
  210. Determines whether the child dns domain name is indeed a child of the parent. This means
  211. that the only difference between the names is the left most component of the child dns name.
  212. Arguments:
  213. ParentDnsName - The Dns domain name of the parent
  214. ChildDnsName - The Dns name of the childe .
  215. Returns:
  216. STATUS_SUCCESS - Success
  217. ERROR_INVALID_DOMAINNAME - The child dns name is not a child of the parent dns name
  218. --*/
  219. {
  220. DWORD Win32Err = ERROR_SUCCESS;
  221. PWSTR Sep = wcschr( ChildDnsName, L'.' );
  222. if ( Sep == NULL || !DnsNameCompare_W( Sep + 1, ParentDnsName ) ) {
  223. Win32Err = ERROR_INVALID_DOMAINNAME;
  224. }
  225. return( Win32Err );
  226. }