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.

449 lines
13 KiB

  1. #include <common.h>
  2. extern BOOL g_QuietMode;
  3. extern WCHAR g_TempString[];
  4. extern WCHAR g_ErrorString[];
  5. extern WCHAR g_FailureLocation[];
  6. extern BOOL g_RemoteOperation;
  7. extern WCHAR g_RemoteComputerName[];
  8. extern BOOL g_CheckNT4Also;
  9. VOID
  10. DisplayMessage(
  11. WCHAR *MessageText)
  12. {
  13. if (!g_QuietMode) {
  14. wprintf(L"%s", MessageText);
  15. }
  16. }
  17. WCHAR*
  18. GetErrorString(
  19. DWORD dwErrorCode)
  20. {
  21. LPVOID lpMsgBuf=NULL;
  22. ZeroMemory(g_ErrorString, MAX_STRING * sizeof(WCHAR));
  23. FormatMessage(
  24. FORMAT_MESSAGE_ALLOCATE_BUFFER |
  25. FORMAT_MESSAGE_FROM_SYSTEM |
  26. FORMAT_MESSAGE_IGNORE_INSERTS,
  27. NULL,
  28. dwErrorCode,
  29. MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
  30. (LPTSTR) &lpMsgBuf,
  31. 0,
  32. NULL);
  33. // Free the bufferoa
  34. if (lpMsgBuf != NULL) {
  35. wcscpy(g_ErrorString, lpMsgBuf);
  36. LocalFree(lpMsgBuf);
  37. }
  38. return g_ErrorString;
  39. }
  40. //+---------------------------------------------------------------------------------------------------------
  41. //
  42. // Registry munging routines
  43. //
  44. //+---------------------------------------------------------------------------------------------------------
  45. DWORD
  46. GetRegValueSZ(
  47. WCHAR *ValueName,
  48. WCHAR *RegValue)
  49. {
  50. DWORD dwRetCode = ERROR_SUCCESS;
  51. HKEY hKey=NULL;
  52. DWORD dwMaxValueData = (MAX_STRING * sizeof(WCHAR)); // Longest Value data
  53. HANDLE hHeap=NULL;
  54. BYTE *bData=NULL;
  55. DWORD cbData;
  56. DWORD dwType;
  57. // ZeroMemory(RegValue, MAX_STRING * sizeof(WCHAR));
  58. // get a handle to the local or remote computer
  59. // (as specified by our global flag)
  60. dwRetCode = GetRegistryHandle(&hKey, KEY_READ);
  61. if (dwRetCode != ERROR_SUCCESS) {
  62. goto cleanup;
  63. }
  64. // create a heap
  65. hHeap = HeapCreate(0, 0, 0);
  66. if (hHeap == NULL) {
  67. dwRetCode = ERROR_NOT_ENOUGH_MEMORY;
  68. wsprintf(g_FailureLocation, L"GetRegValueSZ: HeapCreate: %s\n", GetErrorString(dwRetCode));
  69. goto cleanup;
  70. }
  71. // allocate some space on the heap for our regvalue we'll read in
  72. bData = (BYTE*)HeapAlloc(hHeap, 0, dwMaxValueData);
  73. if (bData == NULL) {
  74. dwRetCode = ERROR_NOT_ENOUGH_MEMORY;
  75. wsprintf(g_FailureLocation, L"GetRegValueSZ: HeapAlloc: %s\n", GetErrorString(dwRetCode));
  76. goto cleanup;
  77. }
  78. cbData = dwMaxValueData;
  79. // read the regkey using the handle we open above
  80. dwRetCode = RegQueryValueEx(
  81. hKey,
  82. ValueName,
  83. NULL,
  84. &dwType,
  85. bData,
  86. &cbData);
  87. if (dwRetCode != ERROR_SUCCESS) {
  88. wsprintf(g_FailureLocation, L"GetRegValueSZ: RegQueryValueEx: %s", GetErrorString(dwRetCode));
  89. goto cleanup;
  90. }
  91. // if it's not a type reg_sz, then something's wrong, so
  92. // report the error, which will cause us to stop.
  93. if (dwType != REG_SZ) {
  94. dwRetCode = ERROR_BADKEY;
  95. wsprintf(g_FailureLocation, L"GetRegValueSZ: RegQueryValueEx: %s: %s\n", ValueName, GetErrorString(dwRetCode));
  96. goto cleanup;
  97. }
  98. // copy the buffer to the registry value
  99. wcsncpy(RegValue, (WCHAR *)bData, cbData * sizeof(WCHAR));
  100. cleanup:
  101. if (bData != NULL) {
  102. ZeroMemory(bData, sizeof(bData));
  103. if (hHeap != NULL) {
  104. HeapFree(hHeap, 0, bData);
  105. HeapDestroy(hHeap);
  106. }
  107. }
  108. if (hKey != NULL) {
  109. RegCloseKey(hKey);
  110. }
  111. return dwRetCode;
  112. }
  113. DWORD
  114. ClearRegPassword()
  115. {
  116. DWORD dwRetCode = ERROR_SUCCESS;
  117. HKEY hKey=NULL;
  118. dwRetCode = GetRegistryHandle(&hKey, KEY_WRITE);
  119. if (dwRetCode != ERROR_SUCCESS) {
  120. goto cleanup;
  121. }
  122. dwRetCode = RegDeleteValue(hKey, L"DefaultPassword");
  123. if (dwRetCode != ERROR_SUCCESS) {
  124. wsprintf(g_FailureLocation, L"ClearRegPassword: RegDeleteValue: %s\n", GetErrorString(dwRetCode));
  125. // DisplayMessage(g_TempString);
  126. goto cleanup;
  127. }
  128. cleanup:
  129. if (hKey != NULL) {
  130. RegCloseKey(hKey);
  131. }
  132. return dwRetCode;
  133. }
  134. DWORD
  135. SetRegValueSZ(
  136. WCHAR *ValueName,
  137. WCHAR *ValueData)
  138. {
  139. DWORD dwRetCode = ERROR_SUCCESS;
  140. HKEY hKey=NULL;
  141. dwRetCode = GetRegistryHandle(&hKey, KEY_WRITE);
  142. if (dwRetCode != ERROR_SUCCESS) {
  143. goto cleanup;
  144. }
  145. dwRetCode = RegSetValueEx(
  146. hKey,
  147. ValueName,
  148. 0,
  149. REG_SZ,
  150. (LPSTR) ValueData,
  151. wcslen(ValueData)*sizeof(WCHAR));
  152. if (dwRetCode != ERROR_SUCCESS) {
  153. wsprintf(g_FailureLocation, L"SetRegValueSZ: RegSetValueEx: %s: %s\n", ValueName, GetErrorString(dwRetCode));
  154. goto cleanup;
  155. }
  156. cleanup:
  157. if (hKey != NULL) {
  158. RegCloseKey(hKey);
  159. }
  160. return dwRetCode;
  161. }
  162. DWORD
  163. GetRegistryHandle(
  164. HKEY *phKey,
  165. REGSAM samDesired)
  166. {
  167. HKEY RemoteRegistryHandle=NULL;
  168. DWORD dwRetCode = ERROR_SUCCESS;
  169. //
  170. // If not PRIVATE mode, ignore the access requested passed in and
  171. // request all access, even though we don't need it. This will force the
  172. // caller to need to be admin to use this tool. We don't want someone using
  173. // this tool to view the autologon passwords of all machines across the domain
  174. // as a normal domain user...
  175. //
  176. #ifndef PRIVATE_VERSION
  177. samDesired = KEY_ALL_ACCESS;
  178. #endif
  179. //
  180. // If we're connecting against a remote computer
  181. //
  182. if (g_RemoteOperation) {
  183. // open a handle to the remote registry
  184. dwRetCode = RegConnectRegistry(
  185. g_RemoteComputerName,
  186. HKEY_LOCAL_MACHINE,
  187. &RemoteRegistryHandle);
  188. if (dwRetCode != ERROR_SUCCESS) {
  189. wsprintf(g_FailureLocation, L"GetRegistryHandle: RegConnectRegistry: %s: %s\n", g_RemoteComputerName, GetErrorString(dwRetCode));
  190. goto cleanup;
  191. }
  192. // open the WINLOGON key on the remote machine
  193. dwRetCode = RegOpenKeyEx(
  194. RemoteRegistryHandle,
  195. WINLOGON_REGKEY,
  196. 0,
  197. samDesired,
  198. phKey);
  199. if (dwRetCode != ERROR_SUCCESS) {
  200. wsprintf(g_FailureLocation, L"GetRegistryHandle: RegOpenKeyEx: %s: %s\n", g_RemoteComputerName, GetErrorString(dwRetCode));
  201. goto cleanup;
  202. }
  203. } else {
  204. // open the WINLOGON key on the local machine
  205. dwRetCode = RegOpenKeyEx(
  206. HKEY_LOCAL_MACHINE,
  207. WINLOGON_REGKEY,
  208. 0,
  209. samDesired,
  210. phKey);
  211. if (dwRetCode != ERROR_SUCCESS) {
  212. wsprintf(g_FailureLocation, L"GetRegistryHandle: RegOpenKeyEx: %s\n", GetErrorString(dwRetCode));
  213. goto cleanup;
  214. }
  215. }
  216. cleanup:
  217. if (RemoteRegistryHandle != NULL) {
  218. RegCloseKey(RemoteRegistryHandle);
  219. }
  220. return dwRetCode;
  221. }
  222. //+---------------------------------------------------------------------------------------------------------
  223. //
  224. // LSASecret munging routines
  225. //
  226. //+---------------------------------------------------------------------------------------------------------
  227. DWORD
  228. GetPolicyHandle(LSA_HANDLE *LsaPolicyHandle)
  229. {
  230. LSA_OBJECT_ATTRIBUTES ObjectAttributes;
  231. NTSTATUS ntsResult;
  232. LSA_UNICODE_STRING TargetMachine;
  233. USHORT TargetMachineLength;
  234. DWORD dwRetCode = ERROR_SUCCESS;
  235. // Object attributes are reserved, so initialize to zeroes.
  236. ZeroMemory(&ObjectAttributes, sizeof(ObjectAttributes));
  237. if (g_RemoteOperation) {
  238. //Initialize an LSA_UNICODE_STRING
  239. TargetMachineLength = (USHORT)wcslen(g_RemoteComputerName);
  240. TargetMachine.Buffer = g_RemoteComputerName;
  241. TargetMachine.Length = TargetMachineLength * sizeof(WCHAR);
  242. TargetMachine.MaximumLength = (TargetMachineLength+1) * sizeof(WCHAR);
  243. // Get a handle to the Policy object.
  244. ntsResult = LsaOpenPolicy(
  245. &TargetMachine, //local machine
  246. &ObjectAttributes,
  247. POLICY_CREATE_SECRET | POLICY_GET_PRIVATE_INFORMATION,
  248. LsaPolicyHandle);
  249. } else {
  250. // Get a handle to the Policy object.
  251. ntsResult = LsaOpenPolicy(
  252. NULL, //local machine
  253. &ObjectAttributes,
  254. POLICY_CREATE_SECRET | POLICY_GET_PRIVATE_INFORMATION,
  255. LsaPolicyHandle);
  256. }
  257. if (ntsResult != STATUS_SUCCESS)
  258. {
  259. // An error occurred. Display it as a win32 error code.
  260. dwRetCode = LsaNtStatusToWinError(ntsResult);
  261. wsprintf(g_FailureLocation, L"GetPolicyHandle: LsaOpenPolicy: %s\n", GetErrorString(dwRetCode));
  262. goto cleanup;
  263. }
  264. cleanup:
  265. return dwRetCode;
  266. }
  267. DWORD
  268. SetSecret(
  269. WCHAR *Password,
  270. BOOL bClearSecret)
  271. {
  272. DWORD dwRetCode = ERROR_SUCCESS;
  273. NTSTATUS ntsResult;
  274. USHORT SecretNameLength, SecretDataLength;
  275. LSA_HANDLE LsaPolicyHandle=NULL;
  276. LSA_UNICODE_STRING lusSecretName, lusSecretData;
  277. //Initialize an LSA_UNICODE_STRING
  278. SecretNameLength = (USHORT)wcslen(L"DefaultPassword");
  279. lusSecretName.Buffer = L"DefaultPassword";
  280. lusSecretName.Length = SecretNameLength * sizeof(WCHAR);
  281. lusSecretName.MaximumLength = (SecretNameLength+1) * sizeof(WCHAR);
  282. dwRetCode = GetPolicyHandle(&LsaPolicyHandle);
  283. if (dwRetCode != ERROR_SUCCESS) {
  284. goto cleanup;
  285. }
  286. // if bClearSecret is set, then delete the secret
  287. // otherwise set the secret to Password
  288. if (bClearSecret) {
  289. ntsResult = LsaStorePrivateData(
  290. LsaPolicyHandle,
  291. &lusSecretName,
  292. NULL);
  293. if (ntsResult != STATUS_SUCCESS) {
  294. dwRetCode = LsaNtStatusToWinError(ntsResult);
  295. wsprintf(g_FailureLocation, L"SetSecret: LsaStorePrivateData: %s\n", GetErrorString(dwRetCode));
  296. goto cleanup;
  297. }
  298. } else {
  299. //Initialize the Password LSA_UNICODE_STRING
  300. SecretDataLength = (USHORT)wcslen(Password);
  301. lusSecretData.Buffer = Password;
  302. lusSecretData.Length = SecretDataLength * sizeof(WCHAR);
  303. lusSecretData.MaximumLength = (SecretDataLength+1) * sizeof(WCHAR);
  304. ntsResult = LsaStorePrivateData(
  305. LsaPolicyHandle,
  306. &lusSecretName,
  307. &lusSecretData);
  308. if (ntsResult != STATUS_SUCCESS) {
  309. dwRetCode = LsaNtStatusToWinError(ntsResult);
  310. wsprintf(g_FailureLocation, L"SetSecret: LsaStorePrivateData: %s\n", GetErrorString(dwRetCode));
  311. goto cleanup;
  312. }
  313. }
  314. cleanup:
  315. if (LsaPolicyHandle != NULL) {
  316. LsaClose(LsaPolicyHandle);
  317. }
  318. return dwRetCode;
  319. }
  320. DWORD
  321. GetSecret(
  322. WCHAR *Password)
  323. {
  324. DWORD dwRetCode = ERROR_SUCCESS;
  325. NTSTATUS ntsResult;
  326. USHORT SecretNameLength;
  327. LSA_HANDLE LsaPolicyHandle=NULL;
  328. LSA_UNICODE_STRING lusSecretName;
  329. LSA_UNICODE_STRING *PrivateData=NULL;
  330. //Initialize an LSA_UNICODE_STRING
  331. SecretNameLength = (USHORT)wcslen(L"DefaultPassword");
  332. lusSecretName.Buffer = L"DefaultPassword";
  333. lusSecretName.Length = SecretNameLength * sizeof(WCHAR);
  334. lusSecretName.MaximumLength= (SecretNameLength+1) * sizeof(WCHAR);
  335. dwRetCode = GetPolicyHandle(&LsaPolicyHandle);
  336. if (dwRetCode != ERROR_SUCCESS) {
  337. goto cleanup;
  338. }
  339. ntsResult = LsaRetrievePrivateData(
  340. LsaPolicyHandle,
  341. &lusSecretName,
  342. &PrivateData);
  343. if (ntsResult != STATUS_SUCCESS) {
  344. if (ntsResult == STATUS_OBJECT_NAME_NOT_FOUND) {
  345. return ntsResult;
  346. } else {
  347. dwRetCode = LsaNtStatusToWinError(ntsResult);
  348. wsprintf(g_FailureLocation, L"GetSecret: LsaRetrievePrivateData: %s \n", GetErrorString(dwRetCode));
  349. goto cleanup;
  350. }
  351. }
  352. // copy the buffer data to Password
  353. wcsncpy(Password, PrivateData->Buffer, (PrivateData->Length)/sizeof(WCHAR));
  354. cleanup:
  355. if (PrivateData != NULL) {
  356. ZeroMemory(PrivateData->Buffer, PrivateData->Length);
  357. LsaFreeMemory(PrivateData);
  358. }
  359. if (LsaPolicyHandle != NULL) {
  360. LsaClose(LsaPolicyHandle);
  361. }
  362. return dwRetCode;
  363. }
  364. DWORD
  365. GetMajorNTVersion(
  366. WCHAR *Server)
  367. {
  368. SERVER_INFO_101* pInf;
  369. DWORD ver = 0;
  370. if(!NetServerGetInfo(Server, 101, (BYTE**)&pInf))
  371. {
  372. if(pInf->sv101_platform_id == PLATFORM_ID_NT) {
  373. ver = pInf->sv101_version_major;
  374. } else {
  375. ver = 0;
  376. }
  377. NetApiBufferFree(pInf);
  378. } else {
  379. ver = 0;
  380. }
  381. return ver;
  382. }