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.

348 lines
8.3 KiB

  1. //
  2. // keymigrt.c
  3. //
  4. // Copyright (c) Microsoft Corp, 2000
  5. //
  6. //
  7. #include <nt.h>
  8. #include <ntrtl.h>
  9. #include <nturtl.h>
  10. #include <windows.h>
  11. #include <rpc.h>
  12. #include <shlobj.h>
  13. #include <wincrypt.h>
  14. #define SECURITY_WIN32
  15. #include <security.h>
  16. #include <secext.h>
  17. #include "passrec.h"
  18. #include <stdio.h>
  19. extern BOOL GetUserSid(HANDLE hClientToken,
  20. PSID* ppSid,
  21. DWORD* lpcbSid);
  22. extern DWORD GetLocalSystemToken(HANDLE* phRet);
  23. void Usage();
  24. int __cdecl wmain(int cArg, wchar_t *rgszArg[])
  25. {
  26. DWORD dwBehavior = 0;
  27. DWORD dwError = ERROR_SUCCESS;
  28. HCRYPTPROV hProv = 0;
  29. HANDLE hToken = NULL;
  30. int i;
  31. LPWSTR wszFilename = NULL;
  32. LPWSTR wszPassword = NULL;
  33. BOOL fGenerate = FALSE;
  34. PSID pCurrentSid = NULL;
  35. DWORD cbCurrentSid = 0;
  36. UNICODE_STRING UserName;
  37. UNICODE_STRING Password;
  38. WCHAR UserNameBuffer[MAX_PATH];
  39. PBYTE pbRecoveryPrivate = NULL;
  40. DWORD cbRecoveryPrivate = 0;
  41. HANDLE hPrivate = INVALID_HANDLE_VALUE;
  42. if(cArg < 2)
  43. {
  44. Usage();
  45. }
  46. // Parse command line
  47. for(i=1; i < cArg; i++)
  48. {
  49. LPWSTR szCurrentArg = rgszArg[i];
  50. if((*szCurrentArg != L'-') &&
  51. (*szCurrentArg != L'/'))
  52. {
  53. Usage();
  54. goto error;
  55. }
  56. szCurrentArg++;
  57. while(*szCurrentArg)
  58. {
  59. switch(*szCurrentArg++)
  60. {
  61. case L'n':
  62. case L'N':
  63. if(cArg < i+2)
  64. {
  65. Usage();
  66. goto error;
  67. }
  68. if(*szCurrentArg)
  69. {
  70. if(cArg < i+1)
  71. {
  72. Usage();
  73. goto error;
  74. }
  75. wszFilename = szCurrentArg;
  76. }
  77. else
  78. {
  79. if(cArg < i+2)
  80. {
  81. Usage();
  82. goto error;
  83. }
  84. i++;
  85. wszFilename = rgszArg[i];
  86. }
  87. i++;
  88. wszPassword = rgszArg[i];
  89. fGenerate = TRUE;
  90. break;
  91. case L'r':
  92. case L'R':
  93. if(cArg < i+1)
  94. {
  95. Usage();
  96. goto error;
  97. }
  98. if(*szCurrentArg)
  99. {
  100. wszFilename = szCurrentArg;
  101. }
  102. else
  103. {
  104. if(cArg < i+1)
  105. {
  106. Usage();
  107. goto error;
  108. }
  109. i++;
  110. wszFilename = rgszArg[i];
  111. }
  112. break;
  113. default:
  114. Usage();
  115. goto error;
  116. }
  117. }
  118. }
  119. if(fGenerate)
  120. {
  121. ULONG Length = MAX_PATH;
  122. Password.Buffer = wszPassword;
  123. Password.Length = wcslen(wszPassword)*sizeof(WCHAR);
  124. Password.MaximumLength = Password.Length + sizeof(WCHAR);
  125. UserName.Buffer = UserNameBuffer;
  126. UserName.Length = MAX_PATH;
  127. UserName.MaximumLength = MAX_PATH*sizeof(WCHAR);
  128. if(!GetUserNameW(UserNameBuffer, &Length))
  129. {
  130. dwError = GetLastError();
  131. printf("Could not get user name:%lx\n", dwError);
  132. goto error;
  133. }
  134. UserName.Length = (USHORT)Length*sizeof(WCHAR);
  135. if(!GetUserSid(NULL,
  136. &pCurrentSid,
  137. &cbCurrentSid))
  138. {
  139. printf("Could not get user sid:%lx\n", dwError);
  140. dwError = GetLastError();
  141. goto error;
  142. }
  143. dwError = GetLocalSystemToken(&hToken);
  144. if(ERROR_SUCCESS != dwError)
  145. {
  146. printf("Could not retrieve local system token:%lx\n", dwError);
  147. goto error;
  148. }
  149. if(!ImpersonateLoggedOnUser(hToken))
  150. {
  151. dwError = GetLastError();
  152. printf("Could not impersonate local system:%lx\n", dwError);
  153. goto error;
  154. }
  155. dwError = PRGenerateRecoveryKey(
  156. pCurrentSid,
  157. &UserName,
  158. &Password,
  159. &pbRecoveryPrivate,
  160. &cbRecoveryPrivate);
  161. RevertToSelf();
  162. if(ERROR_SUCCESS != dwError)
  163. {
  164. printf("Could not generate recovery key:%lx\n", dwError);
  165. goto error;
  166. }
  167. hPrivate = CreateFileW(wszFilename,
  168. GENERIC_WRITE,
  169. 0,
  170. NULL,
  171. CREATE_ALWAYS,
  172. 0,
  173. NULL);
  174. if(INVALID_HANDLE_VALUE == hPrivate)
  175. {
  176. dwError = GetLastError();
  177. printf("Could not open recovery key file:%lx\n", dwError);
  178. goto error;
  179. }
  180. if(!WriteFile(hPrivate, pbRecoveryPrivate, cbRecoveryPrivate, &cbRecoveryPrivate, NULL))
  181. {
  182. dwError = GetLastError();
  183. printf("Could not write recovery key file:%lx\n", dwError);
  184. goto error;
  185. }
  186. }
  187. else
  188. {
  189. if(!ImpersonateSelf(SecurityImpersonation))
  190. {
  191. dwError = GetLastError();
  192. printf("Could not impersonate self:%lx\n", dwError);
  193. goto error;
  194. }
  195. hPrivate = CreateFileW(wszFilename,
  196. GENERIC_READ,
  197. 0,
  198. NULL,
  199. OPEN_EXISTING,
  200. 0,
  201. NULL);
  202. if(INVALID_HANDLE_VALUE == hPrivate)
  203. {
  204. dwError = GetLastError();
  205. printf("Could not open recovery key file:%lx\n", dwError);
  206. goto error;
  207. }
  208. cbRecoveryPrivate = GetFileSize(hPrivate, NULL);
  209. if(-1 == cbRecoveryPrivate)
  210. {
  211. dwError = GetLastError();
  212. printf("Could not retrieve recovery key file size:%lx\n", dwError);
  213. goto error;
  214. }
  215. pbRecoveryPrivate = (PBYTE)LocalAlloc(LMEM_FIXED, cbRecoveryPrivate);
  216. if(NULL == pbRecoveryPrivate)
  217. {
  218. dwError = ERROR_NOT_ENOUGH_MEMORY;
  219. printf("Memory allocation failure:%lx\n", dwError);
  220. goto error;
  221. }
  222. if(!ReadFile(hPrivate, pbRecoveryPrivate, cbRecoveryPrivate, &cbRecoveryPrivate, NULL))
  223. {
  224. dwError = GetLastError();
  225. printf("Could not read recovery key file:%lx\n", dwError);
  226. goto error;
  227. }
  228. dwError = PRRecoverPassword(
  229. pbRecoveryPrivate,
  230. cbRecoveryPrivate,
  231. &Password);
  232. if(ERROR_SUCCESS == dwError)
  233. {
  234. printf("Recovered Password: %S\n", Password.Buffer);
  235. ZeroMemory(Password.Buffer, Password.MaximumLength);
  236. LocalFree(Password.Buffer);
  237. }
  238. RevertToSelf();
  239. }
  240. error:
  241. if(hToken)
  242. {
  243. CloseHandle(hToken);
  244. }
  245. if(hPrivate != INVALID_HANDLE_VALUE)
  246. {
  247. CloseHandle(hPrivate);
  248. }
  249. if(pbRecoveryPrivate)
  250. {
  251. ZeroMemory(pbRecoveryPrivate, cbRecoveryPrivate);
  252. LocalFree(pbRecoveryPrivate);
  253. }
  254. if(pCurrentSid)
  255. {
  256. LocalFree(pCurrentSid);
  257. }
  258. return (ERROR_SUCCESS == dwError)?0:-1;
  259. }
  260. void Usage()
  261. {
  262. printf("Password Recovery Utility\n");
  263. printf("Usage: passrec -n filename password\n");
  264. printf(" passrec -r filename \n\n");
  265. }