windows-nt/Source/XPSP1/NT/ds/netapi/svcdlls/logonsrv/nltest/setprefdc.c
2020-09-26 16:20:57 +08:00

238 lines
6.1 KiB
C

/*--
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 <windows.h>
#include <shellapi.h>
#include <lmcons.h>
#include <lmerr.h>
#include <lmapibuf.h>
#include <lmaccess.h>
#include <lmuse.h>
#include <stdio.h>
#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 <TrustedDomain> <ListOfDcsInTrustedDomain>\n", argv[0]);
return 1;
}
TrustedDomainName = argvw[1];
_wcsupr( TrustedDomainName );
//
// 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<argcw; i++ ) {
//
// Grab the DC name specified by the caller.
//
DcName = argvw[i];
_wcsupr( DcName );
if ( DcName[0] == L'\\' && DcName[1] == L'\\' ) {
DcName += 2;
}
DcNameLen = wcslen(DcName);
if ( DcNameLen < 1 || DcNameLen > 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;
}