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.

775 lines
18 KiB

  1. /*
  2. File: radius.c
  3. Upgrades radius configuration from nt4 steelhead to win2k rras.
  4. Paul Mayfield, 2/8/99
  5. */
  6. #include "upgrade.h"
  7. //
  8. // Information describing a radius server
  9. //
  10. typedef struct _RAD_SERVER_NODE
  11. {
  12. PWCHAR pszName;
  13. DWORD dwTimeout;
  14. DWORD dwAuthPort;
  15. DWORD dwAcctPort;
  16. DWORD dwScore;
  17. BOOL bEnableAuth;
  18. BOOL bEnableAcct;
  19. BOOL bAccountingOnOff;
  20. struct _RAD_SERVER_NODE * pNext;
  21. } RAD_SERVER_NODE;
  22. //
  23. // A radius server list
  24. //
  25. typedef struct _RAD_SERVER_LIST
  26. {
  27. RAD_SERVER_NODE* pHead;
  28. DWORD dwCount;
  29. } RAD_SERVER_LIST;
  30. //
  31. // Info used by routines that manipulate the nt5 radius registry hive
  32. //
  33. typedef struct _RAD_CONFIG_INFO
  34. {
  35. HKEY hkAuthServers;
  36. HKEY hkAuthProviders;
  37. HKEY hkAcctServers;
  38. HKEY hkAcctProviders;
  39. } RAD_CONFIG_INFO;
  40. //
  41. // Registry value names
  42. //
  43. // The all caps ones were taken from nt40 src.
  44. //
  45. static const WCHAR PSZTIMEOUT[] = L"Timeout";
  46. static const WCHAR PSZAUTHPORT[] = L"AuthPort";
  47. static const WCHAR PSZACCTPORT[] = L"AcctPort";
  48. static const WCHAR PSZENABLEACCT[] = L"EnableAccounting";
  49. static const WCHAR PSZENABLEACCTONOFF[] = L"EnableAccountingOnOff";
  50. static const WCHAR PSZENABLEAUTH[] = L"EnableAuthentication";
  51. static const WCHAR PSZSCORE[] = L"Score";
  52. static const WCHAR pszTempRegKey[] = L"Temp";
  53. static const WCHAR pszAccounting[] = L"Accounting\\Providers";
  54. static const WCHAR pszAuthentication[] = L"Authentication\\Providers";
  55. static const WCHAR pszActiveProvider[] = L"ActiveProvider";
  56. static const WCHAR pszRadServersFmt[] = L"%s\\Servers";
  57. static const WCHAR pszServers[] = L"Servers";
  58. static const WCHAR pszGuidRadAuth[] =
  59. L"{1AA7F83F-C7F5-11D0-A376-00C04FC9DA04}";
  60. static const WCHAR pszGuidRadAcct[] =
  61. L"{1AA7F840-C7F5-11D0-A376-00C04FC9DA04}";
  62. // Defaults
  63. //
  64. #define DEFTIMEOUT 5
  65. #define DEFAUTHPORT 1645
  66. #define DEFACCTPORT 1646
  67. #define MAXSCORE 30
  68. RAD_SERVER_NODE g_DefaultRadNode =
  69. {
  70. NULL,
  71. DEFTIMEOUT,
  72. DEFAUTHPORT,
  73. DEFACCTPORT,
  74. MAXSCORE,
  75. TRUE,
  76. TRUE,
  77. TRUE,
  78. NULL
  79. };
  80. //
  81. // Loads a radius server node's configuration from the registry
  82. // (assumed nt4 format and that defaults are assigned to pNode)
  83. //
  84. DWORD
  85. RadNodeLoad(
  86. IN HKEY hKey,
  87. OUT RAD_SERVER_NODE* pNode)
  88. {
  89. RTL_QUERY_REGISTRY_TABLE paramTable[8];
  90. BOOL bTrue = TRUE;
  91. DWORD i;
  92. // Initialize the table of parameters
  93. RtlZeroMemory(&paramTable[0], sizeof(paramTable));
  94. paramTable[0].Name = (PWCHAR)PSZTIMEOUT;
  95. paramTable[0].EntryContext = &(pNode->dwTimeout);
  96. paramTable[1].Name = (PWCHAR)PSZAUTHPORT;
  97. paramTable[1].EntryContext = &(pNode->dwAuthPort);
  98. paramTable[2].Name = (PWCHAR)PSZACCTPORT;
  99. paramTable[2].EntryContext = &(pNode->dwAcctPort);
  100. paramTable[3].Name = (PWCHAR)PSZENABLEAUTH;
  101. paramTable[3].EntryContext = &(pNode->bEnableAuth);
  102. paramTable[4].Name = (PWCHAR)PSZENABLEACCT;
  103. paramTable[4].EntryContext = &(pNode->bEnableAcct);
  104. paramTable[5].Name = (PWCHAR)PSZENABLEACCTONOFF;
  105. paramTable[5].EntryContext = &(pNode->bAccountingOnOff);
  106. paramTable[6].Name = (PWCHAR)PSZSCORE;
  107. paramTable[6].EntryContext = &(pNode->dwScore);
  108. // We're reading all dwords, set the types
  109. // accordingly
  110. //
  111. for (i = 0; i < (sizeof(paramTable) / sizeof(*paramTable)) - 1; i++)
  112. {
  113. paramTable[i].Flags = RTL_QUERY_REGISTRY_DIRECT;
  114. paramTable[i].DefaultType = REG_DWORD;
  115. paramTable[i].DefaultLength = sizeof(DWORD);
  116. paramTable[i].DefaultData = paramTable[i].EntryContext;
  117. }
  118. // Read in the values
  119. //
  120. RtlQueryRegistryValues(
  121. RTL_REGISTRY_HANDLE,
  122. (PWSTR)hKey,
  123. paramTable,
  124. NULL,
  125. NULL);
  126. return NO_ERROR;
  127. }
  128. // Add the authentication server node
  129. //
  130. DWORD
  131. RadNodeSave(
  132. IN HKEY hKey,
  133. IN RAD_SERVER_NODE* pNode,
  134. IN BOOL bAuth)
  135. {
  136. DWORD dwErr = NO_ERROR;
  137. HKEY hkServer = NULL;
  138. do
  139. {
  140. // Create the server key in which to store the info
  141. //
  142. dwErr = RegCreateKeyExW(
  143. hKey,
  144. pNode->pszName,
  145. 0,
  146. NULL,
  147. REG_OPTION_NON_VOLATILE,
  148. KEY_ALL_ACCESS,
  149. NULL,
  150. &hkServer,
  151. NULL);
  152. if (dwErr != ERROR_SUCCESS)
  153. {
  154. break;
  155. }
  156. if (bAuth)
  157. {
  158. RegSetValueExW(
  159. hkServer,
  160. (PWCHAR)PSZAUTHPORT,
  161. 0,
  162. REG_DWORD,
  163. (BYTE*)&pNode->dwAuthPort,
  164. sizeof(DWORD));
  165. RegSetValueExW(
  166. hkServer,
  167. (PWCHAR)PSZSCORE,
  168. 0,
  169. REG_DWORD,
  170. (BYTE*)&pNode->dwScore,
  171. sizeof(DWORD));
  172. RegSetValueExW(
  173. hkServer,
  174. (PWCHAR)PSZTIMEOUT,
  175. 0,
  176. REG_DWORD,
  177. (BYTE*)&pNode->dwTimeout,
  178. sizeof(DWORD));
  179. }
  180. else
  181. {
  182. RegSetValueExW(
  183. hkServer,
  184. (PWCHAR)PSZACCTPORT,
  185. 0,
  186. REG_DWORD,
  187. (BYTE*)&pNode->dwAcctPort,
  188. sizeof(DWORD));
  189. RegSetValueExW(
  190. hkServer,
  191. (PWCHAR)PSZSCORE,
  192. 0,
  193. REG_DWORD,
  194. (BYTE*)&pNode->dwScore,
  195. sizeof(DWORD));
  196. RegSetValueExW(
  197. hkServer,
  198. (PWCHAR)PSZTIMEOUT,
  199. 0,
  200. REG_DWORD,
  201. (BYTE*)&pNode->dwTimeout,
  202. sizeof(DWORD));
  203. RegSetValueExW(
  204. hkServer,
  205. (PWCHAR)PSZENABLEACCTONOFF,
  206. 0,
  207. REG_DWORD,
  208. (BYTE*)&pNode->bAccountingOnOff,
  209. sizeof(DWORD));
  210. }
  211. } while (FALSE);
  212. // Cleanup
  213. {
  214. if (hkServer)
  215. {
  216. RegCloseKey(hkServer);
  217. }
  218. }
  219. return dwErr;
  220. }
  221. //
  222. // Callback from registry key enumerator that adds the server at the given key
  223. // to the list of radius servers.
  224. //
  225. DWORD
  226. RadSrvListAddNodeFromKey(
  227. IN PWCHAR pszName, // sub key name
  228. IN HKEY hKey, // sub key
  229. IN HANDLE hData)
  230. {
  231. DWORD dwErr = NO_ERROR;
  232. RAD_SERVER_LIST * pList = (RAD_SERVER_LIST*)hData;
  233. RAD_SERVER_NODE * pNode = NULL;
  234. do
  235. {
  236. // Initialize the new node
  237. //
  238. pNode = (RAD_SERVER_NODE*) UtlAlloc(sizeof(RAD_SERVER_NODE));
  239. if (pNode == NULL)
  240. {
  241. dwErr = ERROR_NOT_ENOUGH_MEMORY;
  242. break;
  243. }
  244. CopyMemory(pNode, &g_DefaultRadNode, sizeof(RAD_SERVER_NODE));
  245. // Initialize the name
  246. //
  247. pNode->pszName = UtlDupString(pszName);
  248. if (pNode->pszName == NULL)
  249. {
  250. dwErr = ERROR_NOT_ENOUGH_MEMORY;
  251. break;
  252. }
  253. // Load in the registry settings
  254. //
  255. dwErr = RadNodeLoad(hKey, pNode);
  256. if (dwErr != NO_ERROR)
  257. {
  258. break;
  259. }
  260. // Add the node to the list
  261. //
  262. pNode->pNext = pList->pHead;
  263. pList->pHead = pNode;
  264. pList->dwCount += 1;
  265. } while (FALSE);
  266. // Cleanup
  267. {
  268. }
  269. return dwErr;
  270. }
  271. //
  272. // Generates a RAD_SERVER_LIST based on the configuration (assumed
  273. // nt4 format) in the given registry key
  274. //
  275. DWORD
  276. RadSrvListGenerate(
  277. IN HKEY hkSettings,
  278. OUT RAD_SERVER_LIST** ppList)
  279. {
  280. RAD_SERVER_LIST* pList = NULL;
  281. DWORD dwErr = NO_ERROR;
  282. do
  283. {
  284. // Alloc/Init the list
  285. pList = (RAD_SERVER_LIST*) UtlAlloc(sizeof(RAD_SERVER_LIST));
  286. if (pList == NULL)
  287. {
  288. dwErr = ERROR_NOT_ENOUGH_MEMORY;
  289. break;
  290. }
  291. ZeroMemory(pList, sizeof(RAD_SERVER_LIST));
  292. // Build the list
  293. //
  294. dwErr = UtlEnumRegistrySubKeys(
  295. hkSettings,
  296. NULL,
  297. RadSrvListAddNodeFromKey,
  298. (HANDLE)pList);
  299. if (dwErr != NO_ERROR)
  300. {
  301. break;
  302. }
  303. // Assign the return value
  304. //
  305. *ppList = pList;
  306. } while (FALSE);
  307. // Cleanup
  308. {
  309. }
  310. return dwErr;
  311. }
  312. //
  313. // Cleans up a radius server list
  314. //
  315. DWORD
  316. RadSrvListCleanup(
  317. IN RAD_SERVER_LIST* pList)
  318. {
  319. RAD_SERVER_NODE* pNode = NULL;
  320. if (pList)
  321. {
  322. for (pNode = pList->pHead; pNode; pNode = pList->pHead)
  323. {
  324. if (pNode->pszName)
  325. {
  326. UtlFree(pNode->pszName);
  327. }
  328. pList->pHead = pNode->pNext;
  329. UtlFree(pNode);
  330. }
  331. UtlFree(pList);
  332. }
  333. return NO_ERROR;
  334. }
  335. //
  336. // Opens the registry keys required by pNode
  337. //
  338. DWORD
  339. RadOpenRegKeys(
  340. IN HKEY hkRouter,
  341. IN RAD_SERVER_NODE* pNode,
  342. IN OUT RAD_CONFIG_INFO* pInfo)
  343. {
  344. DWORD dwErr = NO_ERROR;
  345. WCHAR pszPath[MAX_PATH];
  346. do
  347. {
  348. // Open the authentication keys as needed
  349. //
  350. if (pNode->bEnableAuth)
  351. {
  352. if (pInfo->hkAuthProviders == NULL)
  353. {
  354. // Open the auth providers key
  355. //
  356. dwErr = RegOpenKeyExW(
  357. hkRouter,
  358. pszAuthentication,
  359. 0,
  360. KEY_ALL_ACCESS,
  361. &pInfo->hkAuthProviders);
  362. if (dwErr != NO_ERROR)
  363. {
  364. break;
  365. }
  366. // Generate the servers key name
  367. //
  368. wsprintfW(pszPath, pszRadServersFmt, pszGuidRadAuth);
  369. // Open the auth servers key
  370. //
  371. dwErr = RegCreateKeyExW(
  372. pInfo->hkAuthProviders,
  373. pszPath,
  374. 0,
  375. NULL,
  376. REG_OPTION_NON_VOLATILE,
  377. KEY_ALL_ACCESS,
  378. NULL,
  379. &pInfo->hkAuthServers,
  380. NULL);
  381. if (dwErr != NO_ERROR)
  382. {
  383. break;
  384. }
  385. }
  386. }
  387. // Open the accounting keys
  388. //
  389. if (pNode->bEnableAcct)
  390. {
  391. if (pInfo->hkAcctProviders == NULL)
  392. {
  393. // Open the auth providers key
  394. //
  395. dwErr = RegOpenKeyExW(
  396. hkRouter,
  397. pszAccounting,
  398. 0,
  399. KEY_ALL_ACCESS,
  400. &pInfo->hkAcctProviders);
  401. if (dwErr != NO_ERROR)
  402. {
  403. break;
  404. }
  405. // Generate the servers key name
  406. //
  407. wsprintfW(pszPath, pszRadServersFmt, pszGuidRadAcct);
  408. // Open the auth servers key
  409. //
  410. dwErr = RegCreateKeyExW(
  411. pInfo->hkAcctProviders,
  412. pszPath,
  413. 0,
  414. NULL,
  415. REG_OPTION_NON_VOLATILE,
  416. KEY_ALL_ACCESS,
  417. NULL,
  418. &pInfo->hkAcctServers,
  419. NULL);
  420. if (dwErr != NO_ERROR)
  421. {
  422. break;
  423. }
  424. }
  425. }
  426. } while (FALSE);
  427. // Cleanup
  428. {
  429. }
  430. return dwErr;
  431. }
  432. //
  433. // Cleans up info from radius installation
  434. //
  435. DWORD
  436. RadCloseRegKeys(
  437. IN RAD_CONFIG_INFO* pInfo)
  438. {
  439. if (pInfo)
  440. {
  441. if (pInfo->hkAuthServers)
  442. {
  443. RegCloseKey(pInfo->hkAuthServers);
  444. pInfo->hkAuthServers = NULL;
  445. }
  446. if (pInfo->hkAuthProviders)
  447. {
  448. RegCloseKey(pInfo->hkAuthProviders);
  449. pInfo->hkAuthProviders = NULL;
  450. }
  451. if (pInfo->hkAcctServers)
  452. {
  453. RegCloseKey(pInfo->hkAcctServers);
  454. pInfo->hkAcctServers = NULL;
  455. }
  456. if (pInfo->hkAcctProviders)
  457. {
  458. RegCloseKey(pInfo->hkAcctProviders);
  459. pInfo->hkAcctProviders = NULL;
  460. }
  461. }
  462. return NO_ERROR;
  463. }
  464. //
  465. // Adds the given server to the win2k section of the registry
  466. //
  467. DWORD
  468. RadInstallServer(
  469. IN HKEY hkRouter,
  470. IN RAD_SERVER_NODE* pNode,
  471. IN OUT RAD_CONFIG_INFO* pInfo)
  472. {
  473. DWORD dwErr = NO_ERROR;
  474. do
  475. {
  476. // Based on the node, open or create any neccessary
  477. // registry keys.
  478. //
  479. dwErr = RadOpenRegKeys(hkRouter, pNode, pInfo);
  480. if (dwErr != NO_ERROR)
  481. {
  482. break;
  483. }
  484. if (pNode->bEnableAuth)
  485. {
  486. // Add the authentication server node
  487. //
  488. dwErr = RadNodeSave(
  489. pInfo->hkAuthServers,
  490. pNode,
  491. TRUE);
  492. if (dwErr != NO_ERROR)
  493. {
  494. break;
  495. }
  496. // Set the active authentication provider
  497. //
  498. dwErr = RegSetValueExW(
  499. pInfo->hkAuthProviders,
  500. (PWCHAR)pszActiveProvider,
  501. 0,
  502. REG_SZ,
  503. (BYTE*)pszGuidRadAuth,
  504. (wcslen(pszGuidRadAuth) + 1) * sizeof(WCHAR));
  505. if (dwErr != NO_ERROR)
  506. {
  507. break;
  508. }
  509. }
  510. if (pNode->bEnableAcct)
  511. {
  512. // Add the accounting server node
  513. //
  514. dwErr = RadNodeSave(
  515. pInfo->hkAcctServers,
  516. pNode,
  517. FALSE);
  518. if (dwErr != NO_ERROR)
  519. {
  520. break;
  521. }
  522. // Set the active accounting provider
  523. //
  524. dwErr = RegSetValueExW(
  525. pInfo->hkAcctProviders,
  526. (PWCHAR)pszActiveProvider,
  527. 0,
  528. REG_SZ,
  529. (BYTE*)pszGuidRadAcct,
  530. (wcslen(pszGuidRadAcct) + 1) * sizeof(WCHAR));
  531. if (dwErr != NO_ERROR)
  532. {
  533. break;
  534. }
  535. }
  536. } while (FALSE);
  537. // Cleanup
  538. {
  539. }
  540. return dwErr;
  541. }
  542. //
  543. // Migrates radius settings from the settings key into the
  544. // router key.
  545. //
  546. DWORD
  547. RadMigrateSettings(
  548. IN HKEY hkRouter,
  549. IN HKEY hkSettings)
  550. {
  551. DWORD dwErr = NO_ERROR;
  552. RAD_SERVER_LIST* pList = NULL;
  553. RAD_CONFIG_INFO* pInfo = NULL;
  554. RAD_SERVER_NODE* pNode = NULL;
  555. do
  556. {
  557. // Generate the list of servers based on
  558. // the loaded settings
  559. dwErr = RadSrvListGenerate(hkSettings, &pList);
  560. if (dwErr != NO_ERROR)
  561. {
  562. break;
  563. }
  564. // If there were no servers, then there's nothing
  565. // to do
  566. //
  567. if (pList->pHead == NULL)
  568. {
  569. dwErr = NO_ERROR;
  570. break;
  571. }
  572. // Allocate and init the info blob that will be
  573. // used by the install funcs.
  574. //
  575. pInfo = (RAD_CONFIG_INFO*) UtlAlloc(sizeof(RAD_CONFIG_INFO));
  576. if (pInfo == NULL)
  577. {
  578. dwErr = ERROR_NOT_ENOUGH_MEMORY;
  579. break;
  580. }
  581. ZeroMemory(pInfo, sizeof(RAD_CONFIG_INFO));
  582. // Install all of the servers
  583. //
  584. for (pNode = pList->pHead; pNode; pNode = pNode->pNext)
  585. {
  586. RadInstallServer(hkRouter, pNode, pInfo);
  587. }
  588. } while (FALSE);
  589. // Cleanup
  590. {
  591. if (pList)
  592. {
  593. RadSrvListCleanup(pList);
  594. }
  595. if (pInfo)
  596. {
  597. RadCloseRegKeys(pInfo);
  598. UtlFree(pInfo);
  599. }
  600. }
  601. return dwErr;
  602. }
  603. //
  604. // Performs the upgrade work
  605. //
  606. DWORD
  607. RadiusToRouterUpgrade(
  608. IN PWCHAR pszFile)
  609. {
  610. DWORD dwErr = NO_ERROR;
  611. HKEY hkRouter = NULL, hkTemp = NULL, hkSettings = NULL;
  612. do
  613. {
  614. // Get the Router subkey
  615. //
  616. dwErr = UtlAccessRouterKey(&hkRouter);
  617. if (dwErr != NO_ERROR)
  618. {
  619. break;
  620. }
  621. // Load registry data that has been saved off
  622. //
  623. dwErr = UtlLoadSavedSettings(
  624. hkRouter,
  625. (PWCHAR)pszTempRegKey,
  626. pszFile,
  627. &hkTemp);
  628. if (dwErr != NO_ERROR)
  629. {
  630. PrintMessage(L"Unable to load radius settings.\n");
  631. break;
  632. }
  633. // Load the settings key
  634. //
  635. dwErr = RegOpenKeyExW(
  636. hkTemp,
  637. pszServers,
  638. 0,
  639. KEY_ALL_ACCESS,
  640. &hkSettings);
  641. if (dwErr != NO_ERROR)
  642. {
  643. break;
  644. }
  645. // Migrate radius information
  646. //
  647. dwErr = RadMigrateSettings(hkRouter, hkSettings);
  648. if (dwErr != NO_ERROR)
  649. {
  650. PrintMessage(L"Unable to migrate radius settings.\n");
  651. break;
  652. }
  653. } while (FALSE);
  654. // Cleanup
  655. {
  656. if (hkSettings)
  657. {
  658. RegCloseKey(hkSettings);
  659. }
  660. if (hkTemp)
  661. {
  662. UtlDeleteRegistryTree(hkTemp);
  663. RegCloseKey(hkTemp);
  664. RegDeleteKey(hkRouter, pszTempRegKey);
  665. }
  666. if (hkRouter)
  667. {
  668. RegCloseKey(hkRouter);
  669. }
  670. }
  671. return dwErr;
  672. }