Leaked source code of windows server 2003
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.

367 lines
8.3 KiB

  1. #include "pch.h"
  2. #define ARRAYSIZE(a) (sizeof(a)/sizeof(a[0]))
  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 cbSid = 0;
  79. PSID pSid = NULL;
  80. DWORD cchDomain = 0;
  81. PWSTR szDomain;
  82. SID_NAME_USE SidUse;
  83. BOOL bRet = FALSE;
  84. bRet = LookupAccountName( RemoteTo,
  85. Name,
  86. NULL,
  87. &cbSid,
  88. NULL,
  89. &cchDomain,
  90. &SidUse );
  91. if (!bRet && GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
  92. pSid = (PSID) LocalAlloc(LPTR, cbSid);
  93. if (!pSid) {
  94. return NULL;
  95. }
  96. szDomain = (PWSTR) LocalAlloc(LPTR, cchDomain * sizeof(WCHAR));
  97. if (!szDomain) {
  98. LocalFree(pSid);
  99. return NULL;
  100. }
  101. bRet = LookupAccountName( RemoteTo,
  102. Name,
  103. pSid,
  104. &cbSid,
  105. szDomain,
  106. &cchDomain,
  107. &SidUse );
  108. LocalFree(szDomain);
  109. if (!bRet) {
  110. LocalFree(pSid);
  111. pSid = NULL;
  112. }
  113. }
  114. return pSid;
  115. }
  116. PCTSTR
  117. pSkipUnc (
  118. PCTSTR Path
  119. )
  120. {
  121. if (Path[0] == TEXT('\\') && Path[1] == TEXT('\\')) {
  122. return Path + 2;
  123. }
  124. return Path;
  125. }
  126. INT
  127. __cdecl
  128. _tmain (
  129. INT argc,
  130. PCTSTR argv[]
  131. )
  132. {
  133. INT i;
  134. DWORD Size;
  135. PCTSTR User1 = NULL;
  136. PCTSTR User2 = NULL;
  137. TCHAR FixedUser1[MAX_PATH];
  138. TCHAR FixedUser2[MAX_PATH];
  139. TCHAR Computer[MAX_COMPUTERNAME_LENGTH + 1];
  140. BOOL Overwrite = FALSE;
  141. INT c;
  142. BOOL b;
  143. PCTSTR RemoteTo = NULL;
  144. NTSTATUS Status;
  145. BYTE WasEnabled;
  146. DWORD Error = ERROR_SUCCESS;
  147. PCTSTR ArgArray[3];
  148. PTSTR pErrText;
  149. TCHAR RemoteToBuf[MAX_PATH];
  150. BOOL NoDecoration = FALSE;
  151. BOOL ReAdjust = FALSE;
  152. BOOL KeepLocalUser = FALSE;
  153. DWORD Flags;
  154. HRESULT hr;
  155. for (i = 1 ; i < argc ; i++) {
  156. if (argv[i][0] == TEXT('/') || argv[i][0] == TEXT('-')) {
  157. c = _tcsnextc (argv[i] + 1);
  158. switch (_totlower ((wint_t) c)) {
  159. case TEXT('y'):
  160. if (Overwrite) {
  161. HelpAndExit();
  162. }
  163. Overwrite = TRUE;
  164. break;
  165. case TEXT('d'):
  166. if (NoDecoration) {
  167. HelpAndExit();
  168. }
  169. NoDecoration = TRUE;
  170. break;
  171. case TEXT('k'):
  172. if (KeepLocalUser) {
  173. HelpAndExit();
  174. }
  175. KeepLocalUser = TRUE;
  176. break;
  177. case TEXT('c'):
  178. if (RemoteTo) {
  179. HelpAndExit();
  180. }
  181. if (argv[i][2] == TEXT(':')) {
  182. RemoteTo = &argv[i][3];
  183. } else {
  184. HelpAndExit();
  185. }
  186. if (pSkipUnc (RemoteTo) == RemoteTo) {
  187. RemoteToBuf[0] = TEXT('\\');
  188. RemoteToBuf[1] = TEXT('\\');
  189. hr = StringCchCopy(RemoteToBuf + 2, ARRAYSIZE(RemoteToBuf) - 2, RemoteTo);
  190. if (FAILED(hr)) {
  191. HelpAndExit();
  192. }
  193. RemoteTo = RemoteToBuf;
  194. }
  195. if (!(*RemoteTo)) {
  196. HelpAndExit();
  197. }
  198. break;
  199. default:
  200. HelpAndExit();
  201. }
  202. } else {
  203. if (!User1) {
  204. User1 = argv[i];
  205. if (!(*User1)) {
  206. HelpAndExit();
  207. }
  208. } else if (!User2) {
  209. User2 = argv[i];
  210. if (!(*User2)) {
  211. HelpAndExit();
  212. }
  213. } else {
  214. HelpAndExit();
  215. }
  216. }
  217. }
  218. if (!User2) {
  219. HelpAndExit();
  220. }
  221. Size = ARRAYSIZE(Computer);
  222. if (!GetComputerName (Computer, &Size)) {
  223. Error = GetLastError();
  224. goto Exit;
  225. }
  226. if (NoDecoration || _tcschr (User1, TEXT('\\'))) {
  227. hr = StringCchCopy(FixedUser1, ARRAYSIZE(FixedUser1), User1);
  228. if (FAILED(hr)) {
  229. Error = HRESULT_CODE(hr);
  230. goto Exit;
  231. }
  232. } else {
  233. hr = StringCchPrintf(FixedUser1, ARRAYSIZE(FixedUser1), TEXT("%s\\%s"), RemoteTo ? pSkipUnc(RemoteTo) : Computer, User1);
  234. if (FAILED(hr)) {
  235. Error = HRESULT_CODE(hr);
  236. goto Exit;
  237. }
  238. }
  239. if (NoDecoration || _tcschr (User2, TEXT('\\'))) {
  240. hr = StringCchCopy(FixedUser2, ARRAYSIZE(FixedUser2), User2);
  241. if (FAILED(hr)) {
  242. Error = HRESULT_CODE(hr);
  243. goto Exit;
  244. }
  245. } else {
  246. hr = StringCchPrintf(FixedUser2, ARRAYSIZE(FixedUser2), TEXT("%s\\%s"), RemoteTo ? pSkipUnc(RemoteTo) : Computer, User2);
  247. if (FAILED(hr)) {
  248. Error = HRESULT_CODE(hr);
  249. goto Exit;
  250. }
  251. }
  252. Status = RtlAdjustPrivilege(SE_RESTORE_PRIVILEGE, TRUE, FALSE, &WasEnabled);
  253. if (Status == STATUS_SUCCESS) {
  254. ReAdjust = TRUE;
  255. }
  256. ArgArray[0] = FixedUser1;
  257. ArgArray[1] = FixedUser2;
  258. ArgArray[2] = RemoteTo;
  259. if (!RemoteTo) {
  260. PrintMessage (MSG_MOVING_PROFILE_LOCAL, ArgArray);
  261. } else {
  262. PrintMessage (MSG_MOVING_PROFILE_REMOTE, ArgArray);
  263. }
  264. Flags = 0;
  265. if (KeepLocalUser) {
  266. Flags |= REMAP_PROFILE_KEEPLOCALACCOUNT;
  267. }
  268. if (!Overwrite) {
  269. Flags |= REMAP_PROFILE_NOOVERWRITE;
  270. }
  271. b = RemapAndMoveUser (
  272. RemoteTo,
  273. Flags,
  274. FixedUser1,
  275. FixedUser2
  276. );
  277. if (b) {
  278. PrintMessage (MSG_SUCCESS, NULL);
  279. } else {
  280. Error = GetLastError();
  281. }
  282. if (ReAdjust) {
  283. RtlAdjustPrivilege(SE_RESTORE_PRIVILEGE, WasEnabled, FALSE, &WasEnabled);
  284. }
  285. Exit:
  286. if (Error != ERROR_SUCCESS) {
  287. ArgArray[0] = (PTSTR) IntToPtr (Error);
  288. ArgArray[1] = pErrText = GetErrorText (Error);
  289. if (Error < 10000) {
  290. PrintMessage (MSG_DECIMAL_ERROR, ArgArray);
  291. } else {
  292. PrintMessage (MSG_HEXADECIMAL_ERROR, ArgArray);
  293. }
  294. if (pErrText) {
  295. LocalFree(pErrText);
  296. }
  297. }
  298. return 0;
  299. }