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.

565 lines
12 KiB

  1. #include "gptext.h"
  2. #include <initguid.h>
  3. #include <iadsp.h>
  4. #include "ipsecext.h"
  5. #define GPEXT_PATH TEXT("Software\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon\\GPExtensions\\{e437bc1c-aa7d-11d2-a382-00c04f991e27}")
  6. #define POLICY_PATH TEXT("Software\\Policies\\Microsoft\\Windows\\IPSec\\GPTIPSECPolicy")
  7. LPWSTR GetAttributes[] = {L"ipsecOwnersReference", L"ipsecName", L"description"};
  8. HRESULT
  9. RegisterIPSEC(void)
  10. {
  11. HKEY hKey;
  12. LONG lResult;
  13. DWORD dwDisp, dwValue;
  14. TCHAR szBuffer[512];
  15. lResult = RegCreateKeyEx (
  16. HKEY_LOCAL_MACHINE,
  17. GPEXT_PATH,
  18. 0,
  19. NULL,
  20. REG_OPTION_NON_VOLATILE,
  21. KEY_WRITE,
  22. NULL,
  23. &hKey,
  24. &dwDisp
  25. );
  26. if (lResult != ERROR_SUCCESS)
  27. {
  28. return lResult;
  29. }
  30. LoadString (g_hInstance, IDS_IPSEC_NAME, szBuffer, ARRAYSIZE(szBuffer));
  31. RegSetValueEx (
  32. hKey,
  33. NULL,
  34. 0,
  35. REG_SZ,
  36. (LPBYTE)szBuffer,
  37. (lstrlen(szBuffer) + 1) * sizeof(TCHAR)
  38. );
  39. RegSetValueEx (
  40. hKey,
  41. TEXT("ProcessGroupPolicy"),
  42. 0,
  43. REG_SZ,
  44. (LPBYTE)TEXT("ProcessIPSECPolicy"),
  45. (lstrlen(TEXT("ProcessIPSECPolicy")) + 1) * sizeof(TCHAR)
  46. );
  47. szBuffer[0] = L'\0';
  48. wcscpy(szBuffer, L"gptext.dll");
  49. RegSetValueEx (
  50. hKey,
  51. TEXT("DllName"),
  52. 0,
  53. REG_EXPAND_SZ,
  54. (LPBYTE)szBuffer,
  55. (lstrlen(szBuffer) + 1) * sizeof(TCHAR)
  56. );
  57. dwValue = 1;
  58. RegSetValueEx (
  59. hKey,
  60. TEXT("NoUserPolicy"),
  61. 0,
  62. REG_DWORD,
  63. (LPBYTE)&dwValue,
  64. sizeof(dwValue));
  65. RegSetValueEx (
  66. hKey,
  67. TEXT("NoGPOListChanges"),
  68. 0,
  69. REG_DWORD,
  70. (LPBYTE)&dwValue,
  71. sizeof(dwValue));
  72. RegCloseKey (hKey);
  73. return S_OK;
  74. }
  75. HRESULT
  76. UnregisterIPSEC(void)
  77. {
  78. RegDeleteKey (HKEY_LOCAL_MACHINE, GPEXT_PATH);
  79. return S_OK;
  80. }
  81. DWORD WINAPI
  82. ProcessIPSECPolicy(
  83. IN DWORD dwFlags, // GPO_INFO_FLAGS
  84. IN HANDLE hToken, // User or machine token
  85. IN HKEY hKeyRoot, // Root of registry
  86. IN PGROUP_POLICY_OBJECT pDeletedGPOList, // Linked list of deleted GPOs
  87. IN PGROUP_POLICY_OBJECT pChangedGPOList, // Linked list of changed GPOs
  88. IN ASYNCCOMPLETIONHANDLE pHandle, // For asynchronous completion
  89. IN BOOL *pbAbort, // If true, then abort GPO processing
  90. IN PFNSTATUSMESSAGECALLBACK pStatusCallback // Callback function for displaying status messages
  91. )
  92. {
  93. WCHAR szIPSECPolicy[MAX_PATH];
  94. WCHAR szIPSECPolicyName[MAX_PATH];
  95. WCHAR szIPSECPolicyDescription[512];
  96. HRESULT hr = S_OK;
  97. PGROUP_POLICY_OBJECT pGPO = NULL;
  98. //
  99. // Call CoInitialize for all the COM work we're doing
  100. //
  101. hr = CoInitializeEx(NULL,0);
  102. if (FAILED(hr)) {
  103. goto error;
  104. }
  105. memset(szIPSECPolicy, 0, sizeof(WCHAR)*MAX_PATH);
  106. memset(szIPSECPolicyName, 0, sizeof(WCHAR)*MAX_PATH);
  107. memset(szIPSECPolicyDescription, 0, sizeof(WCHAR)*512);
  108. //
  109. // First process the Deleted GPO List. If there is a single
  110. // entry on the GPO list, just delete the entire list.
  111. // Example Rex->Cassius->Brutus. If the delete List has
  112. // Cassius to be deleted, then really, we shouldn't be deleting
  113. // our registry entry because we're interested in Brutus which
  114. // has not be deleted. But in our case, the pChangedGPOList will
  115. // have all the information, so Brutus gets written back in the
  116. // next stage.
  117. //
  118. if (pDeletedGPOList) {
  119. DeleteIPSECPolicyFromRegistry();
  120. }
  121. pGPO = pChangedGPOList;
  122. //
  123. // Since IPSEC is really interested in the last
  124. // GPO only, loop through till we hit the last
  125. // GPO and write that GPO only. In this case, Brutus now
  126. // gets written back into the registry.
  127. //
  128. if (pChangedGPOList) {
  129. while (pGPO->pNext)
  130. {
  131. pGPO = pGPO->pNext;
  132. }
  133. //
  134. // Now write the last GPOs information
  135. //
  136. hr = RetrieveIPSECPolicyFromDS(
  137. pGPO,
  138. szIPSECPolicy,
  139. szIPSECPolicyName,
  140. szIPSECPolicyDescription
  141. );
  142. if (FAILED(hr)) {
  143. goto error;
  144. }
  145. hr = WriteIPSECPolicyToRegistry(
  146. szIPSECPolicy,
  147. szIPSECPolicyName,
  148. szIPSECPolicyDescription
  149. );
  150. if (FAILED(hr)) {
  151. goto error;
  152. }
  153. }
  154. PingPolicyAgent();
  155. CoUninitialize();
  156. return(ERROR_SUCCESS);
  157. error:
  158. return(ERROR_POLICY_OBJECT_NOT_FOUND);
  159. }
  160. HRESULT
  161. CreateChildPath(
  162. LPWSTR pszParentPath,
  163. LPWSTR pszChildComponent,
  164. BSTR * ppszChildPath
  165. )
  166. {
  167. HRESULT hr = S_OK;
  168. IADsPathname *pPathname = NULL;
  169. hr = CoCreateInstance(
  170. CLSID_Pathname,
  171. NULL,
  172. CLSCTX_ALL,
  173. IID_IADsPathname,
  174. (void**)&pPathname
  175. );
  176. BAIL_ON_FAILURE(hr);
  177. hr = pPathname->Set(pszParentPath, ADS_SETTYPE_FULL);
  178. BAIL_ON_FAILURE(hr);
  179. hr = pPathname->AddLeafElement(pszChildComponent);
  180. BAIL_ON_FAILURE(hr);
  181. hr = pPathname->Retrieve(ADS_FORMAT_X500, ppszChildPath);
  182. BAIL_ON_FAILURE(hr);
  183. error:
  184. if (pPathname) {
  185. pPathname->Release();
  186. }
  187. return(hr);
  188. }
  189. HRESULT
  190. RetrieveIPSECPolicyFromDS(
  191. PGROUP_POLICY_OBJECT pGPOInfo,
  192. LPWSTR pszIPSecPolicy,
  193. LPWSTR pszIPSecPolicyName,
  194. LPWSTR pszIPSecPolicyDescription
  195. )
  196. {
  197. LPWSTR pszMachinePath = NULL;
  198. BSTR pszMicrosoftPath = NULL;
  199. BSTR pszWindowsPath = NULL;
  200. BSTR pszIpsecPath = NULL;
  201. IDirectoryObject * pDirectoryObject = NULL;
  202. IDirectoryObject * pIpsecObject = NULL;
  203. BOOL bFound = FALSE;
  204. LPWSTR pszOwnersReference = L"ipsecOwnersReference";
  205. HRESULT hr = S_OK;
  206. PADS_ATTR_INFO pAttributeEntries = NULL;
  207. DWORD dwNumAttributesReturned = 0;
  208. DWORD i = 0;
  209. PADS_ATTR_INFO pAttributeEntry = NULL;
  210. pszMachinePath = pGPOInfo->lpDSPath;
  211. // Build the fully qualified ADsPath for my object
  212. hr = CreateChildPath(
  213. pszMachinePath,
  214. L"cn=Microsoft",
  215. &pszMicrosoftPath
  216. );
  217. BAIL_ON_FAILURE(hr);
  218. hr = CreateChildPath(
  219. pszMicrosoftPath,
  220. L"cn=Windows",
  221. &pszWindowsPath
  222. );
  223. BAIL_ON_FAILURE(hr);
  224. hr = CreateChildPath(
  225. pszWindowsPath,
  226. L"cn=ipsec",
  227. &pszIpsecPath
  228. );
  229. BAIL_ON_FAILURE(hr);
  230. hr = ADsGetObject(
  231. pszIpsecPath,
  232. IID_IDirectoryObject,
  233. (void **)&pIpsecObject
  234. );
  235. BAIL_ON_FAILURE(hr);
  236. hr = pIpsecObject->GetObjectAttributes(
  237. GetAttributes,
  238. 3,
  239. &pAttributeEntries,
  240. &dwNumAttributesReturned
  241. );
  242. BAIL_ON_FAILURE(hr);
  243. if (dwNumAttributesReturned == 0) {
  244. hr = E_FAIL;
  245. BAIL_ON_FAILURE(hr);
  246. }
  247. //
  248. // Process the PathName
  249. //
  250. for (i = 0; i < dwNumAttributesReturned; i++) {
  251. pAttributeEntry = pAttributeEntries + i;
  252. if (!_wcsicmp(pAttributeEntry->pszAttrName, L"ipsecOwnersReference")) {
  253. wcscpy(pszIPSecPolicy, L"LDAP://");
  254. wcscat(pszIPSecPolicy, pAttributeEntry->pADsValues->DNString);
  255. bFound = TRUE;
  256. break;
  257. }
  258. }
  259. if (!bFound) {
  260. hr = E_FAIL;
  261. BAIL_ON_FAILURE(hr);
  262. }
  263. //
  264. // Process the name
  265. //
  266. for (i = 0; i < dwNumAttributesReturned; i++) {
  267. pAttributeEntry = pAttributeEntries + i;
  268. if (!_wcsicmp(pAttributeEntry->pszAttrName, L"ipsecName")) {
  269. wcscat(pszIPSecPolicyName, pAttributeEntry->pADsValues->DNString);
  270. break;
  271. }
  272. }
  273. //
  274. // Process the description
  275. //
  276. for (i = 0; i < dwNumAttributesReturned; i++) {
  277. pAttributeEntry = pAttributeEntries + i;
  278. if (!_wcsicmp(pAttributeEntry->pszAttrName, L"description")) {
  279. wcscat(pszIPSecPolicyDescription, pAttributeEntry->pADsValues->DNString);
  280. break;
  281. }
  282. }
  283. error:
  284. if (pAttributeEntries) {
  285. FreeADsMem(pAttributeEntries);
  286. }
  287. if (pIpsecObject) {
  288. pIpsecObject->Release();
  289. }
  290. if (pszMicrosoftPath) {
  291. SysFreeString(pszMicrosoftPath);
  292. }
  293. if (pszWindowsPath) {
  294. SysFreeString(pszWindowsPath);
  295. }
  296. if (pszIpsecPath) {
  297. SysFreeString(pszIpsecPath);
  298. }
  299. return(hr);
  300. }
  301. DWORD
  302. DeleteIPSECPolicyFromRegistry(
  303. )
  304. {
  305. DWORD dwError = 0;
  306. HKEY hKey = NULL;
  307. DWORD dwDisp = 0;
  308. dwError = RegCreateKeyEx (
  309. HKEY_LOCAL_MACHINE,
  310. TEXT("Software\\Policies\\Microsoft\\Windows\\IPSec"),
  311. 0,
  312. NULL,
  313. REG_OPTION_NON_VOLATILE,
  314. KEY_ALL_ACCESS,
  315. NULL,
  316. &hKey,
  317. &dwDisp
  318. );
  319. if (dwError) {
  320. goto error;
  321. }
  322. dwError = RegDeleteKey(
  323. hKey,
  324. L"GPTIPSECPolicy"
  325. );
  326. /*
  327. dwError = RegDeleteValue(
  328. hKey,
  329. TEXT("DSIPSECPolicyPath")
  330. );
  331. dwError = RegDeleteValue(
  332. hKey,
  333. TEXT("DSIPSECPolicyName")
  334. );*/
  335. error:
  336. if (hKey) {
  337. RegCloseKey (hKey);
  338. }
  339. return(dwError);
  340. }
  341. DWORD
  342. WriteIPSECPolicyToRegistry(
  343. LPWSTR pszIPSecPolicyPath,
  344. LPWSTR pszIPSecPolicyName,
  345. LPWSTR pszIPSecPolicyDescription
  346. )
  347. {
  348. DWORD dwError = 0;
  349. DWORD dwDisp = 0;
  350. HKEY hKey = NULL;
  351. DWORD dwFlags = 1;
  352. dwError = RegCreateKeyEx (
  353. HKEY_LOCAL_MACHINE,
  354. POLICY_PATH,
  355. 0,
  356. NULL,
  357. REG_OPTION_NON_VOLATILE,
  358. KEY_ALL_ACCESS,
  359. NULL,
  360. &hKey,
  361. &dwDisp
  362. );
  363. if (dwError) {
  364. goto error;
  365. }
  366. if (pszIPSecPolicyPath && *pszIPSecPolicyPath) {
  367. dwError = RegSetValueEx (
  368. hKey,
  369. TEXT("DSIPSECPolicyPath"),
  370. 0,
  371. REG_SZ,
  372. (LPBYTE)pszIPSecPolicyPath,
  373. (lstrlen(pszIPSecPolicyPath) + 1) * sizeof(TCHAR)
  374. );
  375. dwFlags = 1;
  376. dwError = RegSetValueEx (
  377. hKey,
  378. TEXT("DSIPSECPolicyFlags"),
  379. 0,
  380. REG_DWORD,
  381. (LPBYTE)&dwFlags,
  382. sizeof(dwFlags)
  383. );
  384. }
  385. if (pszIPSecPolicyName && *pszIPSecPolicyName) {
  386. dwError = RegSetValueEx (
  387. hKey,
  388. TEXT("DSIPSECPolicyName"),
  389. 0,
  390. REG_SZ,
  391. (LPBYTE)pszIPSecPolicyName,
  392. (lstrlen(pszIPSecPolicyName) + 1) * sizeof(TCHAR)
  393. );
  394. }
  395. if (pszIPSecPolicyDescription && *pszIPSecPolicyDescription) {
  396. dwError = RegSetValueEx (
  397. hKey,
  398. TEXT("DSIPSECPolicyDescription"),
  399. 0,
  400. REG_SZ,
  401. (LPBYTE)pszIPSecPolicyDescription,
  402. (lstrlen(pszIPSecPolicyDescription) + 1) * sizeof(TCHAR)
  403. );
  404. }
  405. error:
  406. if (hKey) {
  407. RegCloseKey (hKey);
  408. }
  409. return(dwError);
  410. }
  411. VOID
  412. PingPolicyAgent(
  413. )
  414. {
  415. HANDLE hPolicyChangeEvent = NULL;
  416. hPolicyChangeEvent = OpenEvent(
  417. EVENT_ALL_ACCESS,
  418. FALSE,
  419. L"IPSEC_POLICY_CHANGE_EVENT"
  420. );
  421. if (hPolicyChangeEvent) {
  422. SetEvent(hPolicyChangeEvent);
  423. CloseHandle(hPolicyChangeEvent);
  424. }
  425. }