Source code of Windows XP (NT5)
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.

371 lines
7.5 KiB

  1. #include "pch.h"
  2. #include "userenvp.h" // needed until API becomes public
  3. VOID
  4. pFixSomeSidReferences (
  5. PSID ExistingSid,
  6. PSID NewSid
  7. );
  8. VOID
  9. PrintMessage (
  10. IN UINT MsgId,
  11. IN PCTSTR *ArgArray
  12. )
  13. {
  14. DWORD rc;
  15. PTSTR MsgBuf;
  16. rc = FormatMessageW (
  17. FORMAT_MESSAGE_ALLOCATE_BUFFER|
  18. FORMAT_MESSAGE_ARGUMENT_ARRAY|
  19. FORMAT_MESSAGE_FROM_HMODULE,
  20. (LPVOID) GetModuleHandle(NULL),
  21. (DWORD) MsgId,
  22. MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
  23. (LPVOID) &MsgBuf,
  24. 0,
  25. (va_list *) ArgArray
  26. );
  27. if (rc) {
  28. _tprintf (TEXT("%s"), MsgBuf);
  29. LocalFree (MsgBuf);
  30. }
  31. }
  32. PTSTR
  33. GetErrorText (
  34. IN UINT Error
  35. )
  36. {
  37. DWORD rc;
  38. PTSTR MsgBuf;
  39. if (Error == ERROR_NONE_MAPPED) {
  40. Error = ERROR_NO_SUCH_USER;
  41. } else if (Error & 0xF0000000) {
  42. Error = RtlNtStatusToDosError (Error);
  43. }
  44. rc = FormatMessageW (
  45. FORMAT_MESSAGE_ALLOCATE_BUFFER|
  46. FORMAT_MESSAGE_ARGUMENT_ARRAY|
  47. FORMAT_MESSAGE_FROM_SYSTEM|
  48. FORMAT_MESSAGE_IGNORE_INSERTS,
  49. NULL,
  50. (DWORD) Error,
  51. MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
  52. (LPVOID) &MsgBuf,
  53. 0,
  54. NULL
  55. );
  56. if (!rc) {
  57. MsgBuf = NULL;
  58. }
  59. return MsgBuf;
  60. }
  61. VOID
  62. HelpAndExit (
  63. VOID
  64. )
  65. {
  66. //
  67. // This routine is called whenever command line args are wrong
  68. //
  69. PrintMessage (MSG_HELP, NULL);
  70. exit (1);
  71. }
  72. PSID
  73. GetSidFromName (
  74. IN PCTSTR RemoteTo,
  75. IN PCTSTR Name
  76. )
  77. {
  78. DWORD Size;
  79. PSID Buffer;
  80. DWORD DomainSize;
  81. PTSTR Domain;
  82. SID_NAME_USE Use;
  83. BOOL b = FALSE;
  84. Size = 1024;
  85. Buffer = (PSID) LocalAlloc (LPTR, Size);
  86. if (!Buffer) {
  87. return NULL;
  88. }
  89. DomainSize = 256;
  90. Domain = (PTSTR) LocalAlloc (LPTR, DomainSize);
  91. if (!Domain) {
  92. LocalFree (Buffer);
  93. return NULL;
  94. }
  95. b = LookupAccountName (
  96. RemoteTo,
  97. Name,
  98. Buffer,
  99. &Size,
  100. Domain,
  101. &DomainSize,
  102. &Use
  103. );
  104. if (Size > 1024) {
  105. LocalFree (Buffer);
  106. Buffer = (PSID) LocalAlloc (LPTR, Size);
  107. }
  108. if (DomainSize > 256) {
  109. LocalFree (Domain);
  110. Domain = (PTSTR) LocalAlloc (LPTR, DomainSize);
  111. if (!Domain) {
  112. if (Buffer) {
  113. LocalFree (Buffer);
  114. }
  115. return NULL;
  116. }
  117. }
  118. if (Size > 1024 || DomainSize > 256) {
  119. b = LookupAccountName (
  120. RemoteTo,
  121. Name,
  122. Buffer,
  123. &Size,
  124. Domain,
  125. &DomainSize,
  126. &Use
  127. );
  128. }
  129. LocalFree (Domain);
  130. if (!b) {
  131. if (Buffer) {
  132. LocalFree (Buffer);
  133. }
  134. return NULL;
  135. }
  136. return Buffer;
  137. }
  138. PCTSTR
  139. pSkipUnc (
  140. PCTSTR Path
  141. )
  142. {
  143. if (Path[0] == TEXT('\\') && Path[1] == TEXT('\\')) {
  144. return Path + 2;
  145. }
  146. return Path;
  147. }
  148. INT
  149. __cdecl
  150. _tmain (
  151. INT argc,
  152. PCTSTR argv[]
  153. )
  154. {
  155. INT i;
  156. DWORD Size;
  157. PCTSTR User1 = NULL;
  158. PCTSTR User2 = NULL;
  159. TCHAR FixedUser1[MAX_PATH];
  160. TCHAR FixedUser2[MAX_PATH];
  161. TCHAR Computer[MAX_PATH];
  162. BOOL Overwrite = FALSE;
  163. INT c;
  164. BOOL b;
  165. PCTSTR RemoteTo = NULL;
  166. NTSTATUS Status;
  167. BYTE WasEnabled;
  168. DWORD Error;
  169. PCTSTR ArgArray[3];
  170. TCHAR RemoteToBuf[MAX_PATH];
  171. BOOL NoDecoration = FALSE;
  172. BOOL ReAdjust = FALSE;
  173. BOOL KeepLocalUser = FALSE;
  174. DWORD Flags;
  175. for (i = 1 ; i < argc ; i++) {
  176. if (argv[i][0] == TEXT('/') || argv[i][0] == TEXT('-')) {
  177. c = _tcsnextc (argv[i] + 1);
  178. switch (_totlower ((wint_t) c)) {
  179. case TEXT('y'):
  180. if (Overwrite) {
  181. HelpAndExit();
  182. }
  183. Overwrite = TRUE;
  184. break;
  185. case TEXT('d'):
  186. if (NoDecoration) {
  187. HelpAndExit();
  188. }
  189. NoDecoration = TRUE;
  190. break;
  191. case TEXT('k'):
  192. if (KeepLocalUser) {
  193. HelpAndExit();
  194. }
  195. KeepLocalUser = TRUE;
  196. break;
  197. case TEXT('c'):
  198. if (RemoteTo) {
  199. HelpAndExit();
  200. }
  201. if (argv[i][2] == TEXT(':')) {
  202. RemoteTo = &argv[i][3];
  203. } else if ((i + 1) < argc) {
  204. i++;
  205. RemoteTo = argv[i];
  206. } else {
  207. HelpAndExit();
  208. }
  209. if (pSkipUnc (RemoteTo) == RemoteTo) {
  210. RemoteToBuf[0] = TEXT('\\');
  211. RemoteToBuf[1] = TEXT('\\');
  212. lstrcpyn (RemoteToBuf + 2, RemoteTo, MAX_PATH-3);
  213. RemoteTo = RemoteToBuf;
  214. }
  215. if (!(*RemoteTo)) {
  216. HelpAndExit();
  217. }
  218. break;
  219. default:
  220. HelpAndExit();
  221. }
  222. } else {
  223. if (!User1) {
  224. User1 = argv[i];
  225. if (!(*User1)) {
  226. HelpAndExit();
  227. }
  228. } else if (!User2) {
  229. User2 = argv[i];
  230. if (!(*User2)) {
  231. HelpAndExit();
  232. }
  233. } else {
  234. HelpAndExit();
  235. }
  236. }
  237. }
  238. if (!User2) {
  239. HelpAndExit();
  240. }
  241. Size = MAX_PATH;
  242. GetComputerName (Computer, &Size);
  243. if (NoDecoration || _tcschr (User1, TEXT('\\'))) {
  244. lstrcpy (FixedUser1, User1);
  245. } else {
  246. wsprintf (FixedUser1, TEXT("%s\\%s"), RemoteTo ? pSkipUnc(RemoteTo) : Computer, User1);
  247. }
  248. if (NoDecoration || _tcschr (User2, TEXT('\\'))) {
  249. lstrcpy (FixedUser2, User2);
  250. } else {
  251. wsprintf (FixedUser2, TEXT("%s\\%s"), RemoteTo ? pSkipUnc(RemoteTo) : Computer, User2);
  252. }
  253. b = TRUE;
  254. if (b) {
  255. Status = RtlAdjustPrivilege(SE_RESTORE_PRIVILEGE, TRUE, FALSE, &WasEnabled);
  256. if (Status == ERROR_SUCCESS) {
  257. ReAdjust = TRUE;
  258. }
  259. }
  260. if (b) {
  261. ArgArray[0] = FixedUser1;
  262. ArgArray[1] = FixedUser2;
  263. ArgArray[2] = RemoteTo;
  264. if (!RemoteTo) {
  265. PrintMessage (MSG_MOVING_PROFILE_LOCAL, ArgArray);
  266. } else {
  267. PrintMessage (MSG_MOVING_PROFILE_REMOTE, ArgArray);
  268. }
  269. Flags = 0;
  270. if (KeepLocalUser) {
  271. Flags |= REMAP_PROFILE_KEEPLOCALACCOUNT;
  272. }
  273. if (!Overwrite) {
  274. Flags |= REMAP_PROFILE_NOOVERWRITE;
  275. }
  276. b = RemapAndMoveUser (
  277. RemoteTo,
  278. Flags,
  279. FixedUser1,
  280. FixedUser2
  281. );
  282. if (ReAdjust) {
  283. Error = GetLastError();
  284. RtlAdjustPrivilege(SE_RESTORE_PRIVILEGE, WasEnabled, FALSE, &WasEnabled);
  285. SetLastError (Error);
  286. }
  287. }
  288. if (b) {
  289. PrintMessage (MSG_SUCCESS, NULL);
  290. } else {
  291. Error = GetLastError();
  292. ArgArray[0] = (PTSTR) IntToPtr (Error);
  293. ArgArray[1] = GetErrorText (Error);
  294. if (Error < 10000) {
  295. PrintMessage (MSG_DECIMAL_ERROR, ArgArray);
  296. } else {
  297. PrintMessage (MSG_HEXADECIMAL_ERROR, ArgArray);
  298. }
  299. }
  300. return 0;
  301. }