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.

241 lines
6.5 KiB

  1. /*--
  2. Copyright (c) 1997 Microsoft Corporation
  3. Module Name:
  4. setprefdc.c
  5. Abstract:
  6. Program to set the preferred trusted DC to a particular DC.
  7. Author:
  8. 13-Mar-1997 (Cliff Van Dyke)
  9. --*/
  10. #define UNICODE 1
  11. #include <windows.h>
  12. #include <shellapi.h>
  13. #include <lmcons.h>
  14. #include <lmerr.h>
  15. #include <lmapibuf.h>
  16. #include <lmaccess.h>
  17. #include <lmuse.h>
  18. #include <stdio.h>
  19. #define OneStatus( _x ) \
  20. case _x: \
  21. fprintf( stderr, #_x "\n" ); \
  22. break;
  23. VOID
  24. PrintError( NET_API_STATUS NetStatus )
  25. {
  26. switch ( NetStatus ) {
  27. OneStatus(ERROR_NO_SUCH_DOMAIN);
  28. OneStatus(ERROR_BAD_NETPATH);
  29. OneStatus(ERROR_ACCESS_DENIED);
  30. OneStatus(ERROR_NOT_SUPPORTED);
  31. OneStatus(ERROR_NO_TRUST_SAM_ACCOUNT);
  32. OneStatus(ERROR_NO_TRUST_LSA_SECRET);
  33. OneStatus(ERROR_TRUSTED_DOMAIN_FAILURE);
  34. OneStatus(ERROR_TRUSTED_RELATIONSHIP_FAILURE);
  35. OneStatus(ERROR_NETLOGON_NOT_STARTED);
  36. OneStatus(NO_ERROR);
  37. default:
  38. fprintf( stderr, "%ld\n", NetStatus );
  39. break;
  40. }
  41. }
  42. _cdecl
  43. main(int argc, char **argv)
  44. {
  45. NET_API_STATUS NetStatus;
  46. LPWSTR CommandLine;
  47. LPWSTR *argvw;
  48. int argcw;
  49. LPWSTR ServerName = NULL; // Make local calls
  50. LPWSTR TrustedDomainName;
  51. PNETLOGON_INFO_2 OrigNetlogonInfo2 = NULL;
  52. PNETLOGON_INFO_2 NewNetlogonInfo2 = NULL;
  53. USE_INFO_2 UseInfo2;
  54. int i;
  55. WCHAR UncDcName[UNCLEN+1];
  56. WCHAR ShareName[UNCLEN+1+NNLEN+1];
  57. WCHAR NewDomainAndDc[DNLEN+1+CNLEN+1];
  58. LPWSTR NewDomainAndDcPtr;
  59. LPWSTR DcName;
  60. ULONG DcNameLen;
  61. //
  62. // Get the command line in Unicode
  63. //
  64. CommandLine = GetCommandLine();
  65. argvw = CommandLineToArgvW( CommandLine, &argcw );
  66. if ( argvw == NULL ) {
  67. fprintf( stderr, "Can't convert command line to Unicode: %ld\n", GetLastError() );
  68. return 1;
  69. }
  70. //
  71. // Get the arguments
  72. //
  73. if ( argcw < 3 ) {
  74. Usage:
  75. fprintf( stderr, "Usage: %s <TrustedDomain> <ListOfDcsInTrustedDomain>\n", argv[0]);
  76. return 1;
  77. }
  78. TrustedDomainName = argvw[1];
  79. _wcsupr( TrustedDomainName );
  80. if ( wcslen(TrustedDomainName) > DNLEN ) {
  81. fprintf( stderr, "TrustedDomain '%ws' is invalid.\n", TrustedDomainName );
  82. goto Usage;
  83. }
  84. //
  85. // Query the secure channel to find out the current DC being used.
  86. //
  87. NetStatus = I_NetLogonControl2( ServerName,
  88. NETLOGON_CONTROL_TC_QUERY,
  89. 2,
  90. (LPBYTE) &TrustedDomainName,
  91. (LPBYTE *)&OrigNetlogonInfo2 );
  92. if ( NetStatus != NERR_Success ) {
  93. fprintf( stderr, "Cannot determine current trusted DC of domain '%ws': ", TrustedDomainName );
  94. PrintError( NetStatus );
  95. return 1;
  96. }
  97. //
  98. // Loop handling each preferred DC.
  99. //
  100. for ( i=2; i<argcw; i++ ) {
  101. //
  102. // Grab the DC name specified by the caller.
  103. //
  104. DcName = argvw[i];
  105. _wcsupr( DcName );
  106. if ( DcName[0] == L'\\' && DcName[1] == L'\\' ) {
  107. DcName += 2;
  108. }
  109. DcNameLen = wcslen(DcName);
  110. if ( DcNameLen < 1 || DcNameLen > CNLEN ) {
  111. fprintf( stderr, "DcName '%ws' is invalid.\n", DcName );
  112. goto Usage;
  113. }
  114. wcscpy( UncDcName, L"\\\\" );
  115. wcscat( UncDcName, DcName );
  116. //
  117. // If the named DC is already the current DC,
  118. // just tell the caller.
  119. //
  120. if ( OrigNetlogonInfo2->netlog2_trusted_dc_name != NULL &&
  121. _wcsicmp( OrigNetlogonInfo2->netlog2_trusted_dc_name,
  122. UncDcName) == 0 ) {
  123. fprintf( stderr, "DC already is '%ws'.\n", UncDcName );
  124. return 0;
  125. }
  126. //
  127. // Test if this DC is up.
  128. //
  129. wcscpy( ShareName, UncDcName );
  130. wcscat( ShareName, L"\\IPC$" );
  131. UseInfo2.ui2_local = NULL;
  132. UseInfo2.ui2_remote = ShareName;
  133. UseInfo2.ui2_password = NULL;
  134. UseInfo2.ui2_asg_type = USE_IPC;
  135. UseInfo2.ui2_username = NULL;
  136. UseInfo2.ui2_domainname = NULL;
  137. NetStatus = NetUseAdd( NULL, 2, (LPBYTE) &UseInfo2, NULL );
  138. if ( NetStatus == NERR_Success ) {
  139. NetStatus = NetUseDel( NULL, ShareName, FALSE );
  140. if ( NetStatus != NERR_Success ) {
  141. fprintf( stderr, "Cannot remove connection to '%ws' (Continuing): ", UncDcName );
  142. PrintError( NetStatus );
  143. }
  144. } else if ( NetStatus == ERROR_ACCESS_DENIED ) {
  145. /* Server really is up */
  146. } else if ( NetStatus == ERROR_SESSION_CREDENTIAL_CONFLICT ) {
  147. /* We can only assume the server is up */
  148. } else {
  149. fprintf( stderr, "Cannot connect to '%ws': ", UncDcName );
  150. PrintError( NetStatus );
  151. continue;
  152. }
  153. //
  154. // This DC is up. Try to use it.
  155. //
  156. wcscpy( NewDomainAndDc, TrustedDomainName );
  157. wcscat( NewDomainAndDc, L"\\" );
  158. wcscat( NewDomainAndDc, UncDcName+2 );
  159. NewDomainAndDcPtr = NewDomainAndDc;
  160. NetStatus = I_NetLogonControl2( ServerName,
  161. NETLOGON_CONTROL_REDISCOVER,
  162. 2,
  163. (LPBYTE) &NewDomainAndDcPtr,
  164. (LPBYTE *)&NewNetlogonInfo2 );
  165. if ( NetStatus != NERR_Success ) {
  166. fprintf( stderr, "Cannot set new trusted DC to '%ws': ", UncDcName );
  167. PrintError( NetStatus );
  168. continue;
  169. }
  170. //
  171. // If the named DC is now the DC,
  172. // tell the caller.
  173. //
  174. if ( NewNetlogonInfo2->netlog2_trusted_dc_name != NULL &&
  175. _wcsicmp( NewNetlogonInfo2->netlog2_trusted_dc_name,
  176. UncDcName) == 0 ) {
  177. fprintf( stderr, "Successfully set DC to '%ws'.\n", UncDcName );
  178. return 0;
  179. }
  180. fprintf( stderr,
  181. "Cannot set trusted DC to '%ws' it is '%ws': \n",
  182. UncDcName,
  183. NewNetlogonInfo2->netlog2_trusted_dc_name,
  184. NewNetlogonInfo2->netlog2_tc_connection_status );
  185. PrintError( NetStatus );
  186. }
  187. fprintf( stderr, "Failed to set the DC.\n" );
  188. return 1;
  189. }