#include "pch.h" #include "userenvp.h" // needed until API becomes public 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 Size; PSID Buffer; DWORD DomainSize; PTSTR Domain; SID_NAME_USE Use; BOOL b = FALSE; Size = 1024; Buffer = (PSID) LocalAlloc (LPTR, Size); if (!Buffer) { return NULL; } DomainSize = 256; Domain = (PTSTR) LocalAlloc (LPTR, DomainSize); if (!Domain) { LocalFree (Buffer); return NULL; } b = LookupAccountName ( RemoteTo, Name, Buffer, &Size, Domain, &DomainSize, &Use ); if (Size > 1024) { LocalFree (Buffer); Buffer = (PSID) LocalAlloc (LPTR, Size); } if (DomainSize > 256) { LocalFree (Domain); Domain = (PTSTR) LocalAlloc (LPTR, DomainSize); if (!Domain) { if (Buffer) { LocalFree (Buffer); } return NULL; } } if (Size > 1024 || DomainSize > 256) { b = LookupAccountName ( RemoteTo, Name, Buffer, &Size, Domain, &DomainSize, &Use ); } LocalFree (Domain); if (!b) { if (Buffer) { LocalFree (Buffer); } return NULL; } return Buffer; } 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_PATH]; BOOL Overwrite = FALSE; INT c; BOOL b; PCTSTR RemoteTo = NULL; NTSTATUS Status; BYTE WasEnabled; DWORD Error; PCTSTR ArgArray[3]; TCHAR RemoteToBuf[MAX_PATH]; BOOL NoDecoration = FALSE; BOOL ReAdjust = FALSE; BOOL KeepLocalUser = FALSE; DWORD Flags; 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 if ((i + 1) < argc) { i++; RemoteTo = argv[i]; } else { HelpAndExit(); } if (pSkipUnc (RemoteTo) == RemoteTo) { RemoteToBuf[0] = TEXT('\\'); RemoteToBuf[1] = TEXT('\\'); lstrcpyn (RemoteToBuf + 2, RemoteTo, MAX_PATH-3); 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 = MAX_PATH; GetComputerName (Computer, &Size); if (NoDecoration || _tcschr (User1, TEXT('\\'))) { lstrcpy (FixedUser1, User1); } else { wsprintf (FixedUser1, TEXT("%s\\%s"), RemoteTo ? pSkipUnc(RemoteTo) : Computer, User1); } if (NoDecoration || _tcschr (User2, TEXT('\\'))) { lstrcpy (FixedUser2, User2); } else { wsprintf (FixedUser2, TEXT("%s\\%s"), RemoteTo ? pSkipUnc(RemoteTo) : Computer, User2); } b = TRUE; if (b) { Status = RtlAdjustPrivilege(SE_RESTORE_PRIVILEGE, TRUE, FALSE, &WasEnabled); if (Status == ERROR_SUCCESS) { ReAdjust = TRUE; } } if (b) { 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 (ReAdjust) { Error = GetLastError(); RtlAdjustPrivilege(SE_RESTORE_PRIVILEGE, WasEnabled, FALSE, &WasEnabled); SetLastError (Error); } } if (b) { PrintMessage (MSG_SUCCESS, NULL); } else { Error = GetLastError(); ArgArray[0] = (PTSTR) IntToPtr (Error); ArgArray[1] = GetErrorText (Error); if (Error < 10000) { PrintMessage (MSG_DECIMAL_ERROR, ArgArray); } else { PrintMessage (MSG_HEXADECIMAL_ERROR, ArgArray); } } return 0; }