/*-- Copyright (c) 1997 Microsoft Corporation Module Name: setprefdc.c Abstract: Program to set the preferred trusted DC to a particular DC. Author: 13-Mar-1997 (Cliff Van Dyke) --*/ #define UNICODE 1 #include #include #include #include #include #include #include #include #define OneStatus( _x ) \ case _x: \ fprintf( stderr, #_x "\n" ); \ break; VOID PrintError( NET_API_STATUS NetStatus ) { switch ( NetStatus ) { OneStatus(ERROR_NO_SUCH_DOMAIN); OneStatus(ERROR_BAD_NETPATH); OneStatus(ERROR_ACCESS_DENIED); OneStatus(ERROR_NOT_SUPPORTED); OneStatus(ERROR_NO_TRUST_SAM_ACCOUNT); OneStatus(ERROR_NO_TRUST_LSA_SECRET); OneStatus(ERROR_TRUSTED_DOMAIN_FAILURE); OneStatus(ERROR_TRUSTED_RELATIONSHIP_FAILURE); OneStatus(ERROR_NETLOGON_NOT_STARTED); OneStatus(NO_ERROR); default: fprintf( stderr, "%ld\n", NetStatus ); break; } } _cdecl main(int argc, char **argv) { NET_API_STATUS NetStatus; LPWSTR CommandLine; LPWSTR *argvw; int argcw; LPWSTR ServerName = NULL; // Make local calls LPWSTR TrustedDomainName; PNETLOGON_INFO_2 OrigNetlogonInfo2 = NULL; PNETLOGON_INFO_2 NewNetlogonInfo2 = NULL; USE_INFO_2 UseInfo2; int i; WCHAR UncDcName[UNCLEN+1]; WCHAR ShareName[UNCLEN+1+NNLEN+1]; WCHAR NewDomainAndDc[DNLEN+1+CNLEN+1]; LPWSTR NewDomainAndDcPtr; LPWSTR DcName; ULONG DcNameLen; // // Get the command line in Unicode // CommandLine = GetCommandLine(); argvw = CommandLineToArgvW( CommandLine, &argcw ); if ( argvw == NULL ) { fprintf( stderr, "Can't convert command line to Unicode: %ld\n", GetLastError() ); return 1; } // // Get the arguments // if ( argcw < 3 ) { Usage: fprintf( stderr, "Usage: %s \n", argv[0]); return 1; } TrustedDomainName = argvw[1]; _wcsupr( TrustedDomainName ); if ( wcslen(TrustedDomainName) > DNLEN ) { fprintf( stderr, "TrustedDomain '%ws' is invalid.\n", TrustedDomainName ); goto Usage; } // // Query the secure channel to find out the current DC being used. // NetStatus = I_NetLogonControl2( ServerName, NETLOGON_CONTROL_TC_QUERY, 2, (LPBYTE) &TrustedDomainName, (LPBYTE *)&OrigNetlogonInfo2 ); if ( NetStatus != NERR_Success ) { fprintf( stderr, "Cannot determine current trusted DC of domain '%ws': ", TrustedDomainName ); PrintError( NetStatus ); return 1; } // // Loop handling each preferred DC. // for ( i=2; i CNLEN ) { fprintf( stderr, "DcName '%ws' is invalid.\n", DcName ); goto Usage; } wcscpy( UncDcName, L"\\\\" ); wcscat( UncDcName, DcName ); // // If the named DC is already the current DC, // just tell the caller. // if ( OrigNetlogonInfo2->netlog2_trusted_dc_name != NULL && _wcsicmp( OrigNetlogonInfo2->netlog2_trusted_dc_name, UncDcName) == 0 ) { fprintf( stderr, "DC already is '%ws'.\n", UncDcName ); return 0; } // // Test if this DC is up. // wcscpy( ShareName, UncDcName ); wcscat( ShareName, L"\\IPC$" ); UseInfo2.ui2_local = NULL; UseInfo2.ui2_remote = ShareName; UseInfo2.ui2_password = NULL; UseInfo2.ui2_asg_type = USE_IPC; UseInfo2.ui2_username = NULL; UseInfo2.ui2_domainname = NULL; NetStatus = NetUseAdd( NULL, 2, (LPBYTE) &UseInfo2, NULL ); if ( NetStatus == NERR_Success ) { NetStatus = NetUseDel( NULL, ShareName, FALSE ); if ( NetStatus != NERR_Success ) { fprintf( stderr, "Cannot remove connection to '%ws' (Continuing): ", UncDcName ); PrintError( NetStatus ); } } else if ( NetStatus == ERROR_ACCESS_DENIED ) { /* Server really is up */ } else if ( NetStatus == ERROR_SESSION_CREDENTIAL_CONFLICT ) { /* We can only assume the server is up */ } else { fprintf( stderr, "Cannot connect to '%ws': ", UncDcName ); PrintError( NetStatus ); continue; } // // This DC is up. Try to use it. // wcscpy( NewDomainAndDc, TrustedDomainName ); wcscat( NewDomainAndDc, L"\\" ); wcscat( NewDomainAndDc, UncDcName+2 ); NewDomainAndDcPtr = NewDomainAndDc; NetStatus = I_NetLogonControl2( ServerName, NETLOGON_CONTROL_REDISCOVER, 2, (LPBYTE) &NewDomainAndDcPtr, (LPBYTE *)&NewNetlogonInfo2 ); if ( NetStatus != NERR_Success ) { fprintf( stderr, "Cannot set new trusted DC to '%ws': ", UncDcName ); PrintError( NetStatus ); continue; } // // If the named DC is now the DC, // tell the caller. // if ( NewNetlogonInfo2->netlog2_trusted_dc_name != NULL && _wcsicmp( NewNetlogonInfo2->netlog2_trusted_dc_name, UncDcName) == 0 ) { fprintf( stderr, "Successfully set DC to '%ws'.\n", UncDcName ); return 0; } fprintf( stderr, "Cannot set trusted DC to '%ws' it is '%ws': \n", UncDcName, NewNetlogonInfo2->netlog2_trusted_dc_name, NewNetlogonInfo2->netlog2_tc_connection_status ); PrintError( NetStatus ); } fprintf( stderr, "Failed to set the DC.\n" ); return 1; }