|
|
#include "pch.h"
#define ARRAYSIZE(a) (sizeof(a)/sizeof(a[0]))
VOID pFixSomeSidReferences ( PSID ExistingSid, PSID NewSid );
VOID PrintMessage ( IN UINT MsgId, IN PCTSTR *ArgArray ) { DWORD rc; PTSTR MsgBuf;
rc = FormatMessageW ( FORMAT_MESSAGE_ALLOCATE_BUFFER| FORMAT_MESSAGE_ARGUMENT_ARRAY| FORMAT_MESSAGE_FROM_HMODULE, (LPVOID) GetModuleHandle(NULL), (DWORD) MsgId, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPVOID) &MsgBuf, 0, (va_list *) ArgArray );
if (rc) { _tprintf (TEXT("%s"), MsgBuf); LocalFree (MsgBuf); } }
PTSTR GetErrorText ( IN UINT Error ) { DWORD rc; PTSTR MsgBuf;
if (Error == ERROR_NONE_MAPPED) { Error = ERROR_NO_SUCH_USER; } else if (Error & 0xF0000000) { Error = RtlNtStatusToDosError (Error); }
rc = FormatMessageW ( FORMAT_MESSAGE_ALLOCATE_BUFFER| FORMAT_MESSAGE_ARGUMENT_ARRAY| FORMAT_MESSAGE_FROM_SYSTEM| FORMAT_MESSAGE_IGNORE_INSERTS, NULL, (DWORD) Error, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPVOID) &MsgBuf, 0, NULL );
if (!rc) { MsgBuf = NULL; }
return MsgBuf; }
VOID HelpAndExit ( VOID ) { //
// This routine is called whenever command line args are wrong
//
PrintMessage (MSG_HELP, NULL);
exit (1); }
PSID GetSidFromName ( IN PCTSTR RemoteTo, IN PCTSTR Name ) { DWORD cbSid = 0; PSID pSid = NULL; DWORD cchDomain = 0; PWSTR szDomain; SID_NAME_USE SidUse; BOOL bRet = FALSE;
bRet = LookupAccountName( RemoteTo, Name, NULL, &cbSid, NULL, &cchDomain, &SidUse );
if (!bRet && GetLastError() == ERROR_INSUFFICIENT_BUFFER) { pSid = (PSID) LocalAlloc(LPTR, cbSid); if (!pSid) { return NULL; }
szDomain = (PWSTR) LocalAlloc(LPTR, cchDomain * sizeof(WCHAR)); if (!szDomain) { LocalFree(pSid); return NULL; }
bRet = LookupAccountName( RemoteTo, Name, pSid, &cbSid, szDomain, &cchDomain, &SidUse ); LocalFree(szDomain);
if (!bRet) { LocalFree(pSid); pSid = NULL; } }
return pSid; }
PCTSTR pSkipUnc ( PCTSTR Path ) { if (Path[0] == TEXT('\\') && Path[1] == TEXT('\\')) { return Path + 2; }
return Path; }
INT __cdecl _tmain ( INT argc, PCTSTR argv[] ) { INT i; DWORD Size; PCTSTR User1 = NULL; PCTSTR User2 = NULL; TCHAR FixedUser1[MAX_PATH]; TCHAR FixedUser2[MAX_PATH]; TCHAR Computer[MAX_COMPUTERNAME_LENGTH + 1]; BOOL Overwrite = FALSE; INT c; BOOL b; PCTSTR RemoteTo = NULL; NTSTATUS Status; BYTE WasEnabled; DWORD Error = ERROR_SUCCESS; PCTSTR ArgArray[3]; PTSTR pErrText; TCHAR RemoteToBuf[MAX_PATH]; BOOL NoDecoration = FALSE; BOOL ReAdjust = FALSE; BOOL KeepLocalUser = FALSE; DWORD Flags; HRESULT hr;
for (i = 1 ; i < argc ; i++) { if (argv[i][0] == TEXT('/') || argv[i][0] == TEXT('-')) {
c = _tcsnextc (argv[i] + 1);
switch (_totlower ((wint_t) c)) {
case TEXT('y'): if (Overwrite) { HelpAndExit(); }
Overwrite = TRUE; break;
case TEXT('d'): if (NoDecoration) { HelpAndExit(); }
NoDecoration = TRUE; break;
case TEXT('k'): if (KeepLocalUser) { HelpAndExit(); }
KeepLocalUser = TRUE; break;
case TEXT('c'): if (RemoteTo) { HelpAndExit(); }
if (argv[i][2] == TEXT(':')) { RemoteTo = &argv[i][3]; } else { HelpAndExit(); }
if (pSkipUnc (RemoteTo) == RemoteTo) { RemoteToBuf[0] = TEXT('\\'); RemoteToBuf[1] = TEXT('\\'); hr = StringCchCopy(RemoteToBuf + 2, ARRAYSIZE(RemoteToBuf) - 2, RemoteTo); if (FAILED(hr)) { HelpAndExit(); } RemoteTo = RemoteToBuf; }
if (!(*RemoteTo)) { HelpAndExit(); }
break;
default: HelpAndExit(); } } else { if (!User1) {
User1 = argv[i]; if (!(*User1)) { HelpAndExit(); }
} else if (!User2) {
User2 = argv[i]; if (!(*User2)) { HelpAndExit(); }
} else { HelpAndExit(); } } }
if (!User2) { HelpAndExit(); }
Size = ARRAYSIZE(Computer); if (!GetComputerName (Computer, &Size)) { Error = GetLastError(); goto Exit; }
if (NoDecoration || _tcschr (User1, TEXT('\\'))) { hr = StringCchCopy(FixedUser1, ARRAYSIZE(FixedUser1), User1); if (FAILED(hr)) { Error = HRESULT_CODE(hr); goto Exit; } } else { hr = StringCchPrintf(FixedUser1, ARRAYSIZE(FixedUser1), TEXT("%s\\%s"), RemoteTo ? pSkipUnc(RemoteTo) : Computer, User1); if (FAILED(hr)) { Error = HRESULT_CODE(hr); goto Exit; } }
if (NoDecoration || _tcschr (User2, TEXT('\\'))) { hr = StringCchCopy(FixedUser2, ARRAYSIZE(FixedUser2), User2); if (FAILED(hr)) { Error = HRESULT_CODE(hr); goto Exit; } } else { hr = StringCchPrintf(FixedUser2, ARRAYSIZE(FixedUser2), TEXT("%s\\%s"), RemoteTo ? pSkipUnc(RemoteTo) : Computer, User2); if (FAILED(hr)) { Error = HRESULT_CODE(hr); goto Exit; } }
Status = RtlAdjustPrivilege(SE_RESTORE_PRIVILEGE, TRUE, FALSE, &WasEnabled);
if (Status == STATUS_SUCCESS) { ReAdjust = TRUE; }
ArgArray[0] = FixedUser1; ArgArray[1] = FixedUser2; ArgArray[2] = RemoteTo;
if (!RemoteTo) { PrintMessage (MSG_MOVING_PROFILE_LOCAL, ArgArray); } else { PrintMessage (MSG_MOVING_PROFILE_REMOTE, ArgArray); }
Flags = 0;
if (KeepLocalUser) { Flags |= REMAP_PROFILE_KEEPLOCALACCOUNT; }
if (!Overwrite) { Flags |= REMAP_PROFILE_NOOVERWRITE; }
b = RemapAndMoveUser ( RemoteTo, Flags, FixedUser1, FixedUser2 );
if (b) { PrintMessage (MSG_SUCCESS, NULL); } else { Error = GetLastError(); }
if (ReAdjust) { RtlAdjustPrivilege(SE_RESTORE_PRIVILEGE, WasEnabled, FALSE, &WasEnabled); }
Exit:
if (Error != ERROR_SUCCESS) { ArgArray[0] = (PTSTR) IntToPtr (Error); ArgArray[1] = pErrText = GetErrorText (Error);
if (Error < 10000) { PrintMessage (MSG_DECIMAL_ERROR, ArgArray); } else { PrintMessage (MSG_HEXADECIMAL_ERROR, ArgArray); }
if (pErrText) { LocalFree(pErrText); } } return 0; }
|