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.

637 lines
14 KiB

  1. //+-----------------------------------------------------------------------
  2. //
  3. // File: PARAM.C
  4. //
  5. // Contents: Parameter code
  6. //
  7. //
  8. // History: 28 Feb 92 RichardW Created
  9. //
  10. //------------------------------------------------------------------------
  11. #include <lsapch.hxx>
  12. extern "C"
  13. {
  14. extern PWSTR pszPreferred;
  15. }
  16. #define MACHINERIDKEY L"MACHINERID"
  17. WCHAR szLsaPath[] = L"System\\CurrentControlSet\\Control\\Lsa";
  18. WCHAR szOthersValue[] = L"Security Packages";
  19. WCHAR szOldValue[] = L"Authentication Packages";
  20. WCHAR szNonceLagValue[] = L"Clock Skew";
  21. WCHAR szHowMuchValue[] = L"How Much";
  22. WCHAR szDisableSupPopups[] = L"DisablePopups";
  23. WCHAR szPreferredPackage[] = L"Preferred";
  24. WCHAR szGeneralThreadLifespan[] = L"GeneralThreadLifespan";
  25. WCHAR szDedicatedThreadLifespan[] = L"DedicatedThreadLifespan";
  26. HKEY hDSKey;
  27. HANDLE hRegNotifyEvent;
  28. PVOID pvParamScav;
  29. PWSTR ppszDefault[] = {L"Kerberos", L"NTLM", NULL};
  30. // Will build an argv style array of DLLs to load as packages here:
  31. extern PWSTR * ppszPackages;
  32. extern PWSTR * ppszOldPkgs;
  33. extern PWSTR pszPreferred;
  34. #if DBG
  35. extern DWORD BreakFlags;
  36. extern DWORD NoUnload;
  37. #endif
  38. SECURITY_STRING ssMachineRid;
  39. //+-------------------------------------------------------------------------
  40. //
  41. // Function: GetRegistryString
  42. //
  43. // Synopsis: Gets a string from the registry
  44. //
  45. // Effects: If type is REG_EXPAND_SZ, string is expanded.
  46. // If type is REG_MULTI_SZ, string is (left alone?)
  47. //
  48. // Arguments: hRootKey -- HKEY to start at
  49. // pszSubKey -- Key to look at
  50. // pszValue -- Value to look at
  51. // pszData -- Buffer to place string
  52. // pcbData -- Size (in/out) of buffer
  53. //
  54. // Requires:
  55. //
  56. // Returns:
  57. //
  58. // Notes:
  59. //
  60. //--------------------------------------------------------------------------
  61. NTSTATUS
  62. GetRegistryString( HKEY hRootKey,
  63. PWSTR pszSubkey,
  64. PWSTR pszValue,
  65. PWSTR pszData,
  66. PDWORD pcbData)
  67. {
  68. HKEY hKey;
  69. int Status;
  70. ULONG type;
  71. DWORD dwSize = *pcbData;
  72. Status = RegOpenKey(hRootKey, pszSubkey, &hKey);
  73. if (Status != ERROR_SUCCESS)
  74. {
  75. DebugLog((DEB_ERROR, "Open of %ws failed, %d\n", pszSubkey, Status));
  76. return(STATUS_OBJECT_NAME_NOT_FOUND);
  77. }
  78. // First, call query value and make sure this is a correct type
  79. Status = RegQueryValueEx( hKey,
  80. pszValue,
  81. NULL,
  82. &type,
  83. NULL,
  84. &dwSize);
  85. if ((Status != ERROR_SUCCESS) && (Status != ERROR_MORE_DATA))
  86. {
  87. DebugLog((DEB_TRACE, "QueryValueEx of %ws failed, %d\n", pszValue, Status));
  88. (void) RegCloseKey(hKey);
  89. if (Status == ERROR_FILE_NOT_FOUND)
  90. {
  91. return(STATUS_OBJECT_NAME_NOT_FOUND);
  92. }
  93. return(STATUS_UNSUCCESSFUL);
  94. }
  95. if ((type != REG_SZ) && (type != REG_MULTI_SZ) && (type != REG_EXPAND_SZ) )
  96. {
  97. DebugLog((DEB_ERROR, "Type = %d, returning now\n", type));
  98. (void) RegCloseKey(hKey);
  99. return(STATUS_UNSUCCESSFUL);
  100. }
  101. Status = RegQueryValueEx( hKey,
  102. pszValue,
  103. NULL,
  104. &type,
  105. (PBYTE) pszData,
  106. pcbData);
  107. (void) RegCloseKey(hKey);
  108. if (Status != ERROR_SUCCESS)
  109. {
  110. if (Status == ERROR_INSUFFICIENT_BUFFER)
  111. {
  112. return(STATUS_BUFFER_TOO_SMALL);
  113. }
  114. DebugLog((DEB_ERROR, "QueryValueEx of %ws returned %d\n", pszValue, Status));
  115. return(STATUS_UNSUCCESSFUL);
  116. }
  117. if (type == REG_EXPAND_SZ)
  118. {
  119. *pcbData = ExpandEnvironmentStrings(pszData, pszData, dwSize);
  120. }
  121. return(STATUS_SUCCESS);
  122. }
  123. //+---------------------------------------------------------------------------
  124. //
  125. // Function: GetRegistryDword
  126. //
  127. // Synopsis: Gets a DWORD from the registry
  128. //
  129. // Effects:
  130. //
  131. // Arguments: [hPrimaryKey] -- Key to start from
  132. // [pszKey] -- Name of the subkey
  133. // [pszValue] -- Name of the value
  134. // [pdwValue] -- returned DWORD
  135. //
  136. // Returns: S_OK, or SEC_E_INVALID_HANDLE
  137. //
  138. // History: 3-31-93 RichardW Created
  139. //
  140. //----------------------------------------------------------------------------
  141. HRESULT
  142. GetRegistryDword(HKEY hPrimaryKey,
  143. PWSTR pszKey,
  144. PWSTR pszValue,
  145. DWORD * pdwValue)
  146. {
  147. HKEY hKey;
  148. DWORD cbDword = sizeof(DWORD);
  149. DWORD dwType;
  150. int err;
  151. err = RegOpenKey(hPrimaryKey, pszKey, &hKey);
  152. if (err) {
  153. return(SEC_E_INVALID_HANDLE);
  154. }
  155. err = RegQueryValueEx( hKey,
  156. pszValue,
  157. NULL,
  158. &dwType,
  159. (PBYTE) pdwValue,
  160. &cbDword);
  161. (void) RegCloseKey(hKey);
  162. if (err || (dwType != REG_DWORD))
  163. {
  164. return(SEC_E_INVALID_HANDLE);
  165. }
  166. return(S_OK);
  167. }
  168. HRESULT
  169. SpmGetMachineName(void)
  170. {
  171. HRESULT hr = S_OK;
  172. WCHAR wszMachName [MAX_COMPUTERNAME_LENGTH + 1];
  173. DWORD dwSize = MAX_COMPUTERNAME_LENGTH + 1;
  174. if (!GetComputerName(
  175. wszMachName,
  176. &dwSize))
  177. {
  178. return(STATUS_UNSUCCESSFUL);
  179. }
  180. MachineName.Buffer = (LPWSTR) LsapAllocateLsaHeap((wcslen(wszMachName)+1) * sizeof(WCHAR));
  181. if (MachineName.Buffer == NULL)
  182. {
  183. return(STATUS_INSUFFICIENT_RESOURCES);
  184. }
  185. wcscpy(MachineName.Buffer, wszMachName);
  186. RtlInitUnicodeString(
  187. &MachineName,
  188. MachineName.Buffer
  189. );
  190. return(STATUS_SUCCESS);
  191. }
  192. //+---------------------------------------------------------------------------
  193. //
  194. // Function: ParameterNotify
  195. //
  196. // Synopsis: Function called when the registry key for DS is changed
  197. //
  198. // Arguments: [pvEntry] -- ignored
  199. //
  200. // History: 6-08-93 RichardW Created
  201. //
  202. //----------------------------------------------------------------------------
  203. DWORD
  204. ParameterNotify(PVOID pvEntry)
  205. {
  206. ULONG NewState;
  207. HANDLE hThread = 0;
  208. DWORD tid;
  209. int err;
  210. err = RegNotifyChangeKeyValue( hDSKey, FALSE,
  211. REG_NOTIFY_CHANGE_LAST_SET,
  212. hRegNotifyEvent,
  213. TRUE);
  214. if (err)
  215. {
  216. DebugLog((DEB_WARN, "Got %d from trying to start RegNotifyChangeKeyValue again\n",
  217. err));
  218. }
  219. return(0);
  220. }
  221. //+---------------------------------------------------------------------------
  222. //
  223. // Function: LoadParameters
  224. //
  225. // Synopsis: Loads operating parameters from the registry
  226. //
  227. // Effects:
  228. //
  229. // Arguments: [void] --
  230. //
  231. // Requires:
  232. //
  233. // Returns:
  234. //
  235. // Signals:
  236. //
  237. // Modifies:
  238. //
  239. // Algorithm:
  240. //
  241. // History: 3-31-93 RichardW Created
  242. //
  243. // Notes:
  244. //
  245. //----------------------------------------------------------------------------
  246. NTSTATUS
  247. LoadParameters(
  248. VOID
  249. )
  250. {
  251. int lcPackages = 0;
  252. int cOldPkgs = 0;
  253. int iPackage = 0;
  254. PWSTR pszAlternate;
  255. PWSTR pszOldPkgs;
  256. PWSTR pszScan;
  257. DWORD dwBuffer = 64;
  258. HRESULT scRet;
  259. //
  260. // Get the parameters that can change during a boot.
  261. //
  262. //
  263. // Get the machine name
  264. //
  265. scRet = SpmGetMachineName();
  266. if (!NT_SUCCESS(scRet)) {
  267. return(scRet);
  268. }
  269. //
  270. // Get the preferred package
  271. //
  272. dwBuffer = 128 ;
  273. pszPreferred = (PWSTR) LsapAllocateLsaHeap( dwBuffer );
  274. if ( !pszPreferred )
  275. {
  276. dwBuffer = 0 ;
  277. }
  278. scRet = GetRegistryString( HKEY_LOCAL_MACHINE,
  279. szLsaPath,
  280. szPreferredPackage,
  281. pszPreferred,
  282. &dwBuffer);
  283. if (scRet == STATUS_BUFFER_TOO_SMALL)
  284. {
  285. LsapFreeLsaHeap(pszPreferred);
  286. pszPreferred = (PWSTR)LsapAllocateLsaHeap(dwBuffer);
  287. if ( pszPreferred )
  288. {
  289. scRet = GetRegistryString( HKEY_LOCAL_MACHINE,
  290. szLsaPath,
  291. szPreferredPackage,
  292. pszPreferred,
  293. &dwBuffer);
  294. }
  295. }
  296. else
  297. {
  298. if ( pszPreferred )
  299. {
  300. LsapFreeLsaHeap( pszPreferred );
  301. pszPreferred = NULL ;
  302. }
  303. }
  304. //
  305. // Set the default packages
  306. //
  307. ppszPackages = ppszDefault;
  308. //
  309. // Now, find out all the other ones. First, NT5 packages:
  310. //
  311. dwBuffer = 128;
  312. pszAlternate = (PWSTR)LsapAllocateLsaHeap(dwBuffer);
  313. if (!pszAlternate)
  314. {
  315. return(STATUS_INSUFFICIENT_RESOURCES);
  316. }
  317. *pszAlternate = L'\0';
  318. scRet = GetRegistryString( HKEY_LOCAL_MACHINE,
  319. szLsaPath,
  320. szOthersValue,
  321. pszAlternate,
  322. &dwBuffer);
  323. if (scRet == STATUS_BUFFER_TOO_SMALL)
  324. {
  325. LsapFreeLsaHeap(pszAlternate);
  326. pszAlternate = (PWSTR)LsapAllocateLsaHeap(dwBuffer);
  327. if (!pszAlternate)
  328. {
  329. return(STATUS_INSUFFICIENT_RESOURCES);
  330. }
  331. *pszAlternate = L'\0';
  332. scRet = GetRegistryString( HKEY_LOCAL_MACHINE,
  333. szLsaPath,
  334. szOthersValue,
  335. pszAlternate,
  336. &dwBuffer);
  337. if (FAILED(scRet)) {
  338. return(scRet);
  339. }
  340. }
  341. if (NT_SUCCESS(scRet))
  342. {
  343. pszScan = pszAlternate;
  344. while (*pszScan)
  345. {
  346. while (*pszScan) {
  347. pszScan++;
  348. }
  349. lcPackages++;
  350. pszScan++;
  351. }
  352. } else if (scRet != STATUS_OBJECT_NAME_NOT_FOUND) {
  353. LsapFreeLsaHeap(pszAlternate);
  354. pszAlternate = NULL;
  355. return(scRet);
  356. } else {
  357. LsapFreeLsaHeap(pszAlternate);
  358. pszAlternate = NULL;
  359. }
  360. dwBuffer = 128;
  361. pszOldPkgs = (PWSTR)LsapAllocateLsaHeap(dwBuffer);
  362. if (!pszOldPkgs)
  363. {
  364. return(STATUS_INSUFFICIENT_RESOURCES);
  365. }
  366. *pszOldPkgs = L'\0';
  367. scRet = GetRegistryString( HKEY_LOCAL_MACHINE,
  368. szLsaPath,
  369. szOldValue,
  370. pszOldPkgs,
  371. &dwBuffer);
  372. if (scRet == STATUS_BUFFER_TOO_SMALL)
  373. {
  374. LsapFreeLsaHeap(pszOldPkgs);
  375. pszOldPkgs = (PWSTR)LsapAllocateLsaHeap(dwBuffer);
  376. if (!pszOldPkgs)
  377. {
  378. return(STATUS_INSUFFICIENT_RESOURCES);
  379. }
  380. *pszOldPkgs = L'\0';
  381. scRet = GetRegistryString( HKEY_LOCAL_MACHINE,
  382. szLsaPath,
  383. szOldValue,
  384. pszOldPkgs,
  385. &dwBuffer);
  386. if (!NT_SUCCESS(scRet)) {
  387. return(scRet);
  388. }
  389. }
  390. if (NT_SUCCESS(scRet))
  391. {
  392. pszScan = pszOldPkgs;
  393. while (*pszScan)
  394. {
  395. while (*pszScan) {
  396. pszScan++;
  397. }
  398. cOldPkgs++;
  399. pszScan++;
  400. }
  401. } else if (scRet != STATUS_OBJECT_NAME_NOT_FOUND) {
  402. LsapFreeLsaHeap(pszOldPkgs);
  403. pszOldPkgs = NULL;
  404. return(scRet);
  405. } else {
  406. LsapFreeLsaHeap(pszOldPkgs);
  407. pszOldPkgs = NULL;
  408. }
  409. ppszPackages = (PWSTR *)LsapAllocateLsaHeap((lcPackages + 1) * sizeof(PWSTR));
  410. if (!ppszPackages)
  411. {
  412. return(STATUS_INSUFFICIENT_RESOURCES);
  413. }
  414. //
  415. // Add any alternate packages
  416. //
  417. if (pszAlternate != NULL)
  418. {
  419. pszScan = pszAlternate;
  420. while (*pszScan)
  421. {
  422. ppszPackages[iPackage++] = pszScan;
  423. while (*pszScan++);
  424. }
  425. }
  426. ppszPackages[iPackage] = NULL;
  427. //
  428. // Note: we don't allocate one extra, since we don't actually include
  429. // the MSV package name here (we simulate the package in msvlayer.c)
  430. //
  431. ppszOldPkgs = (PWSTR *)LsapAllocateLsaHeap((cOldPkgs+1) * sizeof(PWSTR));
  432. if (!ppszOldPkgs)
  433. {
  434. return(STATUS_INSUFFICIENT_RESOURCES);
  435. }
  436. iPackage = 0;
  437. if (pszOldPkgs != NULL)
  438. {
  439. pszScan = pszOldPkgs;
  440. while (*pszScan)
  441. {
  442. ppszOldPkgs[iPackage++] = pszScan;
  443. while (*pszScan++);
  444. }
  445. }
  446. cOldPkgs = iPackage;
  447. ppszOldPkgs[iPackage] = NULL;
  448. return(S_OK);
  449. }
  450. BOOL
  451. AddPackageToRegistry(
  452. PSECURITY_STRING Package
  453. )
  454. {
  455. PWSTR Buffer;
  456. DWORD Length;
  457. DWORD Type;
  458. int err;
  459. HKEY hKey;
  460. err = RegOpenKeyEx( HKEY_LOCAL_MACHINE,
  461. szLsaPath,
  462. 0,
  463. KEY_READ | KEY_WRITE,
  464. &hKey );
  465. if ( err )
  466. {
  467. return( FALSE );
  468. }
  469. Length = 0;
  470. err = RegQueryValueEx( hKey,
  471. szOthersValue,
  472. 0,
  473. &Type,
  474. NULL,
  475. &Length );
  476. Buffer = (PWSTR) LsapAllocateLsaHeap( Length + Package->Length + 2 );
  477. if ( !Buffer )
  478. {
  479. RegCloseKey( hKey );
  480. return FALSE ;
  481. }
  482. RegQueryValueEx( hKey,
  483. szOthersValue,
  484. 0,
  485. &Type,
  486. (PUCHAR) Buffer,
  487. &Length );
  488. CopyMemory( &Buffer[Length + 1],
  489. Package->Buffer,
  490. Package->Length + 2 );
  491. Length = Length + Package->Length + 2;
  492. RegSetValueEx( hKey,
  493. szOthersValue,
  494. 0,
  495. REG_MULTI_SZ,
  496. (PUCHAR) Buffer,
  497. Length );
  498. RegCloseKey( hKey );
  499. return( TRUE );
  500. }