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.
349 lines
11 KiB
349 lines
11 KiB
/*++
|
|
|
|
Copyright (c) 2000 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
forcemigrate.c
|
|
|
|
Abstract:
|
|
|
|
forcemigrate.c
|
|
|
|
Author:
|
|
Jason Garms (jasong) 27 October 2000
|
|
|
|
|
|
--*/
|
|
|
|
#include <shared.h>
|
|
|
|
|
|
|
|
//+---------------------------------------------------------------------------------------------------------
|
|
//
|
|
// Prototypes
|
|
//
|
|
//+---------------------------------------------------------------------------------------------------------
|
|
|
|
DWORD
|
|
MigratePassword();
|
|
|
|
DWORD
|
|
ListAll();
|
|
|
|
VOID
|
|
DumpCmd();
|
|
|
|
|
|
//+---------------------------------------------------------------------------------------------------------
|
|
//
|
|
// Globals
|
|
//
|
|
//+---------------------------------------------------------------------------------------------------------
|
|
BOOL g_QuietMode = FALSE;
|
|
WCHAR g_TempString[MAX_STRING] = {0};
|
|
WCHAR g_ErrorString[MAX_STRING] = {0};
|
|
WCHAR g_FailureLocation[MAX_STRING] = {0};
|
|
|
|
BOOL g_RemoteOperation = FALSE;
|
|
WCHAR g_RemoteComputerName[MAX_STRING] = {0};
|
|
DWORD g_RunningUsersCreds = 0;
|
|
DWORD g_CheckNT4Also = 0;
|
|
|
|
//+---------------------------------------------------------------------------------------------------------
|
|
//
|
|
// Functions
|
|
//
|
|
//+---------------------------------------------------------------------------------------------------------
|
|
|
|
|
|
int
|
|
__cdecl
|
|
wmain(
|
|
int argc,
|
|
WCHAR *argv[]
|
|
)
|
|
{
|
|
DWORD dwCommandPosition=1;
|
|
DWORD dwRetCode=ERROR_SUCCESS;
|
|
|
|
// parse the command line params and act on them
|
|
// if there's fewer than 2 params, it's not a valid call
|
|
if (argc < 2) {
|
|
dwRetCode = ERROR_BAD_ARGUMENTS;
|
|
goto cleanup;
|
|
}
|
|
|
|
// check to see quietmode is enabled and set global flag
|
|
// and increment commandposition pointer, but only if there
|
|
// are more arguments to our right, otherwise, it's invalid
|
|
// usage
|
|
if (!wcscmp(argv[dwCommandPosition], L"-q")) {
|
|
g_QuietMode = 1;
|
|
dwCommandPosition++;
|
|
}
|
|
|
|
|
|
if ((DWORD)argc <= (dwCommandPosition)) {
|
|
dwRetCode = ERROR_BAD_ARGUMENTS;
|
|
goto cleanup;
|
|
}
|
|
|
|
// check to see if we should try the running user's credentials as well
|
|
if (!wcscmp(argv[dwCommandPosition], L"-r")) {
|
|
g_RunningUsersCreds = 1;
|
|
dwCommandPosition++;
|
|
}
|
|
|
|
if ((DWORD)argc <= (dwCommandPosition)) {
|
|
dwRetCode = ERROR_BAD_ARGUMENTS;
|
|
goto cleanup;
|
|
}
|
|
|
|
// check to see if we should run against NT4 as well
|
|
if (!wcscmp(argv[dwCommandPosition], L"-nt4")) {
|
|
g_CheckNT4Also = 1;
|
|
dwCommandPosition++;
|
|
}
|
|
|
|
if ((DWORD)argc <= (dwCommandPosition)) {
|
|
dwRetCode = ERROR_BAD_ARGUMENTS;
|
|
goto cleanup;
|
|
}
|
|
|
|
// check to see if a UNC machine name is passed in for
|
|
// remote operation and set the approprite globals
|
|
// if there is a UNC path here, then increment commandposition
|
|
// pointer, but only if there's more arguments to our right,
|
|
// otherwise it's invalid usage.
|
|
if ((*(argv[dwCommandPosition]) != '\\')) {
|
|
dwRetCode = ERROR_BAD_ARGUMENTS;
|
|
goto cleanup;
|
|
}
|
|
|
|
// make sure there's actually some chars to the right of the \\s
|
|
if (wcslen(argv[dwCommandPosition])<=2) {
|
|
dwRetCode = ERROR_BAD_ARGUMENTS;
|
|
goto cleanup;
|
|
}
|
|
|
|
// make sure the machine name fits in our buffer
|
|
if (wcslen(argv[dwCommandPosition]) >= MAX_STRING) {
|
|
dwRetCode = ERROR_BAD_ARGUMENTS;
|
|
goto cleanup;
|
|
}
|
|
|
|
g_RemoteOperation = TRUE;
|
|
wcsncpy(g_RemoteComputerName,
|
|
argv[dwCommandPosition],
|
|
wcslen(argv[dwCommandPosition]));
|
|
|
|
dwRetCode = MigratePassword();
|
|
|
|
cleanup:
|
|
if (dwRetCode == ERROR_BAD_ARGUMENTS) {
|
|
DumpCmd();
|
|
}
|
|
return dwRetCode;
|
|
}
|
|
|
|
|
|
DWORD
|
|
MigratePassword()
|
|
{
|
|
WCHAR UserName[MAX_STRING];
|
|
WCHAR DomainName[MAX_STRING];
|
|
WCHAR Password[MAX_STRING];
|
|
WCHAR ConCat[MAX_STRING];
|
|
DWORD dwRetCode = ERROR_SUCCESS;
|
|
NETRESOURCE NetResource = {0};
|
|
DWORD dwMachineVerNumber = 0;
|
|
|
|
// Connect to the remote machine to obtain the username, domain, and password
|
|
|
|
// Make sure it's a Win2k box
|
|
dwMachineVerNumber = GetMajorNTVersion(g_RemoteComputerName);
|
|
switch (dwMachineVerNumber) {
|
|
case 3:
|
|
case 4:
|
|
if ((dwMachineVerNumber == 4) && (g_CheckNT4Also)) {
|
|
break;
|
|
} else {
|
|
wprintf(L"%s: Error, target is running NT4 and -nt4 option not selected\n", g_RemoteComputerName);
|
|
dwRetCode = ERROR_OLD_WIN_VERSION;
|
|
goto cleanup;
|
|
}
|
|
case 5:
|
|
break;
|
|
default:
|
|
wprintf(L"%s: Error target's machine version is invalid\n", g_RemoteComputerName);
|
|
dwRetCode = ERROR_OLD_WIN_VERSION;
|
|
goto cleanup;
|
|
}
|
|
|
|
wsprintf(g_TempString, L"%s: Beginning Migration: System is running NT%d\n", g_RemoteComputerName, dwMachineVerNumber);
|
|
wsprintf(g_TempString, L"%s: DefaultPassword : (reg does not exist)\n", g_RemoteComputerName);
|
|
|
|
//
|
|
// Get the DefaultPassword
|
|
//
|
|
dwRetCode = GetRegValueSZ(L"DefaultPassword", Password);
|
|
switch (dwRetCode) {
|
|
// catch this case and continue
|
|
case ERROR_FILE_NOT_FOUND:
|
|
wsprintf(g_TempString, L"%s: DefaultPassword : (reg does not exist)\n", g_RemoteComputerName);
|
|
DisplayMessage(g_TempString);
|
|
goto cleanup;
|
|
|
|
// On success, print the regkey and continue to next item
|
|
case ERROR_SUCCESS:
|
|
if (!wcscmp(Password, L"")) {
|
|
dwRetCode = ERROR_FILE_NOT_FOUND;
|
|
wsprintf(g_TempString, L"%s: DefaultPassword : (exists, but is empty)\n", g_RemoteComputerName);
|
|
DisplayMessage(g_TempString);
|
|
break;
|
|
}
|
|
wsprintf(g_TempString, L"%s: DefaultPassword : %s\n", g_RemoteComputerName, Password);
|
|
DisplayMessage(g_TempString);
|
|
break;
|
|
|
|
// catch all the generic errors and end program
|
|
default:
|
|
wsprintf(g_TempString, L"DefaultPassword : Failed to query regkey: %s\n", GetErrorString(dwRetCode));
|
|
wprintf(L"Flag 3\n", dwRetCode);
|
|
goto cleanup;
|
|
}
|
|
|
|
//
|
|
// Get the username
|
|
//
|
|
dwRetCode = GetRegValueSZ(L"DefaultUserName", UserName);
|
|
switch (dwRetCode) {
|
|
// catch this case and continue
|
|
case ERROR_FILE_NOT_FOUND:
|
|
wsprintf(g_TempString, L"%s: DefaultUserName : (does not exist)\n", g_RemoteComputerName);
|
|
DisplayMessage(g_TempString);
|
|
goto cleanup;
|
|
|
|
// On success, print the regkey and continue to next item
|
|
case ERROR_SUCCESS:
|
|
wsprintf(g_TempString, L"%s: DefaultUserName : %s\n", g_RemoteComputerName, UserName);
|
|
DisplayMessage(g_TempString);
|
|
break;
|
|
|
|
// catch all the generic errors and end program
|
|
default:
|
|
wsprintf(g_TempString, L"%s: DefaultUserName : Failed to query regkey: %s\n", g_RemoteComputerName, GetErrorString(dwRetCode));
|
|
DisplayMessage(g_TempString);
|
|
goto cleanup;
|
|
}
|
|
|
|
//
|
|
// Get the DefaultDomainName
|
|
//
|
|
dwRetCode = GetRegValueSZ(L"DefaultDomainName", DomainName);
|
|
switch (dwRetCode) {
|
|
// catch this case and continue
|
|
case ERROR_FILE_NOT_FOUND:
|
|
wsprintf(g_TempString, L"%s: DefaultDomainName: (does not exist)\n", g_RemoteComputerName);
|
|
DisplayMessage(g_TempString);
|
|
goto cleanup;
|
|
|
|
// On success, print the regkey and continue to next item
|
|
case ERROR_SUCCESS:
|
|
wsprintf(g_TempString, L"%s: DefaultDomainName: %s\n", g_RemoteComputerName, DomainName);
|
|
DisplayMessage(g_TempString);
|
|
break;
|
|
|
|
// catch all the generic errors and end program
|
|
default:
|
|
wsprintf(g_TempString, L"%s: DefaultDomainName: Failed to query regkey: %s\n", g_RemoteComputerName, GetErrorString(dwRetCode));
|
|
DisplayMessage(g_TempString);
|
|
goto cleanup;
|
|
}
|
|
|
|
if ((wcslen(DomainName) + wcslen(UserName)) >= MAX_STRING) {
|
|
dwRetCode = ERROR_BUFFER_OVERFLOW;
|
|
goto cleanup;
|
|
}
|
|
|
|
wcscpy(ConCat, DomainName);
|
|
wcscat(ConCat, L"\\");
|
|
wcscat(ConCat, UserName);
|
|
|
|
NetResource.lpRemoteName = g_RemoteComputerName;
|
|
|
|
dwRetCode = WNetAddConnection2(
|
|
&NetResource, // connection details
|
|
Password, // password
|
|
ConCat, // user name
|
|
0); // connection options
|
|
|
|
if (dwRetCode != ERROR_SUCCESS) {
|
|
if (!g_RunningUsersCreds) {
|
|
wprintf(L"%s: Could not logon as %s using password %s\n", g_RemoteComputerName, ConCat, Password);
|
|
goto cleanup;
|
|
} else {
|
|
wprintf(L"Trying with your own credentials\n");
|
|
dwRetCode = WNetAddConnection2(
|
|
&NetResource, // connection details
|
|
NULL, // password
|
|
NULL, // user name
|
|
0); // connection options
|
|
if (dwRetCode != ERROR_SUCCESS) {
|
|
wprintf(L"%s: Could not logon you or as %s using password %s\n", g_RemoteComputerName, ConCat, Password);
|
|
goto cleanup;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Set the DefaultPassword LSAsecret to the value we retrieved from the registry
|
|
dwRetCode = SetSecret(Password, 0);
|
|
if (dwRetCode != ERROR_SUCCESS) {
|
|
wsprintf(g_TempString, L"%s: Migrate Failed: Could not set DefaultPassword LSASecret: %s\n", g_RemoteComputerName, GetErrorString(dwRetCode));
|
|
DisplayMessage(g_TempString);
|
|
wsprintf(g_TempString, L"%s: This is probably because the user is not the admin of the local machine\n", g_RemoteComputerName);
|
|
DisplayMessage(g_TempString);
|
|
goto cleanup;
|
|
}
|
|
|
|
// Delete the DefaultPassword registry key
|
|
dwRetCode = ClearRegPassword();
|
|
if (dwRetCode != ERROR_SUCCESS) {
|
|
wsprintf(g_TempString, L"%s: Migrate Failed: Could not delete DefaultPassword RegKey: %s\n", g_RemoteComputerName, GetErrorString(dwRetCode));
|
|
DisplayMessage(g_TempString);
|
|
goto cleanup;
|
|
}
|
|
|
|
wsprintf(g_TempString, L"%s: Password migrated from Registry to LSASecret\n", g_RemoteComputerName);
|
|
DisplayMessage(g_TempString);
|
|
|
|
cleanup:
|
|
if (dwRetCode != ERROR_SUCCESS) {
|
|
wsprintf(g_TempString, L"%s: Migrate Failed ---------\n", g_RemoteComputerName);
|
|
DisplayMessage(g_TempString);
|
|
} else {
|
|
wsprintf(g_TempString, L"%s: Migrate Success !!!!!!!!!\n", g_RemoteComputerName);
|
|
DisplayMessage(g_TempString);
|
|
}
|
|
return dwRetCode;
|
|
}
|
|
|
|
|
|
|
|
VOID
|
|
DumpCmd()
|
|
{
|
|
wprintf(L"FORCEMIGRATE v0.1: Copyright 2000, Microsoft Corporation\n\n");
|
|
wprintf(L"DESCRIPTION:\n");
|
|
wprintf(L" Force migrates DefaultPassword cleartext to LSASecret\n");
|
|
wprintf(L"USAGE:\n");
|
|
wprintf(L" FORCEMIGRATE [-q] [-r] [-nt4] \\\\machine\n");
|
|
wprintf(L" -q Enable quiet mode, which supresses all output\n");
|
|
wprintf(L" -r Try with current user's creds as well as DefaultPassword\n");
|
|
wprintf(L" -nt4 Run against NT4 boxes as well\n");
|
|
wprintf(L" \\machine If specified, the UNC name of the machine to configure\n");
|
|
} // DumpCmd
|
|
|
|
|