//---------------------------------------------------------------------------- // // Microsoft Windows // Copyright (C) Microsoft Corporation, 2000. // // File: policy-r.c // // Contents: Policy management for registry. // // // History: KrishnaG. // AbhisheV. // //---------------------------------------------------------------------------- #include "precomp.h" extern LPWSTR PolicyDNAttributes[]; DWORD RegEnumPolicyData( HKEY hRegistryKey, LPWSTR pszIpsecRootContainer, PIPSEC_POLICY_DATA ** pppIpsecPolicyData, PDWORD pdwNumPolicyObjects ) { DWORD dwError = 0; PIPSEC_POLICY_OBJECT * ppIpsecPolicyObjects = NULL; PIPSEC_POLICY_DATA pIpsecPolicyData = NULL; PIPSEC_POLICY_DATA * ppIpsecPolicyData = NULL; DWORD dwNumPolicyObjects = 0; DWORD i = 0; DWORD j = 0; dwError = RegEnumPolicyObjects( hRegistryKey, pszIpsecRootContainer, &ppIpsecPolicyObjects, &dwNumPolicyObjects ); BAIL_ON_WIN32_ERROR(dwError); if (dwNumPolicyObjects) { ppIpsecPolicyData = (PIPSEC_POLICY_DATA *) AllocPolMem( dwNumPolicyObjects*sizeof(PIPSEC_POLICY_DATA)); if (!ppIpsecPolicyData) { dwError = ERROR_OUTOFMEMORY; BAIL_ON_WIN32_ERROR(dwError); } } for (i = 0; i < dwNumPolicyObjects; i++) { dwError = RegUnmarshallPolicyData( *(ppIpsecPolicyObjects + i), &pIpsecPolicyData ); if (!dwError) { *(ppIpsecPolicyData + j) = pIpsecPolicyData; j++; } } if (j == 0) { if (ppIpsecPolicyData) { FreePolMem(ppIpsecPolicyData); ppIpsecPolicyData = NULL; } } *pppIpsecPolicyData = ppIpsecPolicyData; *pdwNumPolicyObjects = j; dwError = ERROR_SUCCESS; cleanup: if (ppIpsecPolicyObjects) { FreeIpsecPolicyObjects( ppIpsecPolicyObjects, dwNumPolicyObjects ); } return(dwError); error: if (ppIpsecPolicyData) { FreeMulIpsecPolicyData( ppIpsecPolicyData, i ); } *pppIpsecPolicyData = NULL; *pdwNumPolicyObjects = 0; goto cleanup; } DWORD RegEnumPolicyObjects( HKEY hRegistryKey, LPWSTR pszIpsecRootContainer, PIPSEC_POLICY_OBJECT ** pppIpsecPolicyObjects, PDWORD pdwNumPolicyObjects ) { DWORD dwError = 0; DWORD i = 0; DWORD dwCount = 0; PIPSEC_POLICY_OBJECT pIpsecPolicyObject = NULL; PIPSEC_POLICY_OBJECT * ppIpsecPolicyObjects = NULL; DWORD dwNumPolicyObjectsReturned = 0; DWORD dwIndex = 0; WCHAR szPolicyName[MAX_PATH]; DWORD dwSize = 0; *pppIpsecPolicyObjects = NULL; *pdwNumPolicyObjects = 0; while (1) { dwSize = MAX_PATH; szPolicyName[0] = L'\0'; dwError = RegEnumKeyExW( hRegistryKey, dwIndex, szPolicyName, &dwSize, NULL, NULL, 0, 0 ); if (dwError == ERROR_NO_MORE_ITEMS) { break; } BAIL_ON_WIN32_ERROR(dwError); if (!wcsstr(szPolicyName, L"ipsecPolicy")) { dwIndex++; continue; } pIpsecPolicyObject = NULL; dwError =UnMarshallRegistryPolicyObject( hRegistryKey, pszIpsecRootContainer, szPolicyName, REG_RELATIVE_NAME, &pIpsecPolicyObject ); if (dwError == ERROR_SUCCESS) { dwError = ReallocatePolMem( (LPVOID *) &ppIpsecPolicyObjects, sizeof(PIPSEC_POLICY_OBJECT)*(dwNumPolicyObjectsReturned), sizeof(PIPSEC_POLICY_OBJECT)*(dwNumPolicyObjectsReturned + 1) ); BAIL_ON_WIN32_ERROR(dwError); *(ppIpsecPolicyObjects + dwNumPolicyObjectsReturned) = pIpsecPolicyObject; dwNumPolicyObjectsReturned++; } dwIndex++; } *pppIpsecPolicyObjects = ppIpsecPolicyObjects; *pdwNumPolicyObjects = dwNumPolicyObjectsReturned; dwError = ERROR_SUCCESS; return(dwError); error: if (ppIpsecPolicyObjects) { FreeIpsecPolicyObjects( ppIpsecPolicyObjects, dwNumPolicyObjectsReturned ); } if (pIpsecPolicyObject) { FreeIpsecPolicyObject( pIpsecPolicyObject ); } *pppIpsecPolicyObjects = NULL; *pdwNumPolicyObjects = 0; return(dwError); } DWORD RegSetPolicyData( HKEY hRegistryKey, LPWSTR pszIpsecRootContainer, LPWSTR pszLocationName, PIPSEC_POLICY_DATA pIpsecPolicyData ) { DWORD dwError = 0; PIPSEC_POLICY_OBJECT pIpsecPolicyObject = NULL; LPWSTR pszAbsOldISAKMPRef = NULL; LPWSTR pszRelOldISAKMPRef = NULL; WCHAR szAbsPolicyReference[MAX_PATH]; LPWSTR pszRelISAKMPReference = NULL; DWORD dwRootPathLen = 0; BOOL bIsActive = FALSE; dwRootPathLen = wcslen(pszIpsecRootContainer); dwError = RegGetPolicyExistingISAKMPRef( hRegistryKey, pIpsecPolicyData, &pszAbsOldISAKMPRef ); // BAIL_ON_WIN32_ERROR(dwError); if (pszAbsOldISAKMPRef && *pszAbsOldISAKMPRef) { pszRelOldISAKMPRef = pszAbsOldISAKMPRef + dwRootPathLen + 1; } dwError = RegMarshallPolicyObject( pIpsecPolicyData, pszIpsecRootContainer, &pIpsecPolicyObject ); BAIL_ON_WIN32_ERROR(dwError); dwError = RegSetPolicyObject( hRegistryKey, pszIpsecRootContainer, pIpsecPolicyObject ); BAIL_ON_WIN32_ERROR(dwError); szAbsPolicyReference[0] = L'\0'; wcscpy(szAbsPolicyReference, pszIpsecRootContainer); wcscat(szAbsPolicyReference, L"\\"); wcscat(szAbsPolicyReference, pIpsecPolicyObject->pszIpsecOwnersReference); pszRelISAKMPReference = pIpsecPolicyObject->pszIpsecISAKMPReference + dwRootPathLen + 1; if (pszRelOldISAKMPRef) { dwError = RegRemovePolicyReferenceFromISAKMPObject( hRegistryKey, pszRelOldISAKMPRef, szAbsPolicyReference ); // BAIL_ON_WIN32_ERROR(dwError); } dwError = RegAddPolicyReferenceToISAKMPObject( hRegistryKey, pszRelISAKMPReference, szAbsPolicyReference ); BAIL_ON_WIN32_ERROR(dwError); dwError = RegUpdateISAKMPReferenceInPolicyObject( hRegistryKey, pIpsecPolicyObject->pszIpsecOwnersReference, pszAbsOldISAKMPRef, pIpsecPolicyObject->pszIpsecISAKMPReference ); BAIL_ON_WIN32_ERROR(dwError); dwError = IsRegPolicyCurrentlyActive( hRegistryKey, pszIpsecRootContainer, pIpsecPolicyData->PolicyIdentifier, &bIsActive ); BAIL_ON_WIN32_ERROR(dwError); if (bIsActive) { dwError = PingPolicyAgentSvc(pszLocationName); BAIL_ON_WIN32_ERROR(dwError); } error: if (pIpsecPolicyObject) { FreeIpsecPolicyObject(pIpsecPolicyObject); } if (pszAbsOldISAKMPRef) { FreePolStr(pszAbsOldISAKMPRef); } return(dwError); } DWORD RegSetPolicyObject( HKEY hRegistryKey, LPWSTR pszIpsecRootContainer, PIPSEC_POLICY_OBJECT pIpsecPolicyObject ) { DWORD dwError = 0; dwError = PersistPolicyObject( hRegistryKey, pIpsecPolicyObject ); BAIL_ON_WIN32_ERROR(dwError); error: return(dwError); } DWORD RegCreatePolicyData( HKEY hRegistryKey, LPWSTR pszIpsecRootContainer, PIPSEC_POLICY_DATA pIpsecPolicyData ) { DWORD dwError = 0; PIPSEC_POLICY_OBJECT pIpsecPolicyObject = NULL; WCHAR szAbsPolicyReference[MAX_PATH]; LPWSTR pszRelISAKMPReference = NULL; DWORD dwRootPathLen = 0; dwRootPathLen = wcslen(pszIpsecRootContainer); dwError = RegMarshallPolicyObject( pIpsecPolicyData, pszIpsecRootContainer, &pIpsecPolicyObject ); BAIL_ON_WIN32_ERROR(dwError); dwError = RegCreatePolicyObject( hRegistryKey, pszIpsecRootContainer, pIpsecPolicyObject ); BAIL_ON_WIN32_ERROR(dwError); szAbsPolicyReference[0] = L'\0'; wcscpy(szAbsPolicyReference, pszIpsecRootContainer); wcscat(szAbsPolicyReference, L"\\"); wcscat(szAbsPolicyReference, pIpsecPolicyObject->pszIpsecOwnersReference); pszRelISAKMPReference = pIpsecPolicyObject->pszIpsecISAKMPReference + dwRootPathLen + 1; // // Write the ISAKMP object reference. // dwError = RegAddPolicyReferenceToISAKMPObject( hRegistryKey, pszRelISAKMPReference, szAbsPolicyReference ); BAIL_ON_WIN32_ERROR(dwError); // // Write the Policy object reference. // dwError = RegAddISAKMPReferenceToPolicyObject( hRegistryKey, pIpsecPolicyObject->pszIpsecOwnersReference, pIpsecPolicyObject->pszIpsecISAKMPReference ); BAIL_ON_WIN32_ERROR(dwError); error: if (pIpsecPolicyObject) { FreeIpsecPolicyObject( pIpsecPolicyObject ); } return(dwError); } DWORD RegCreatePolicyObject( HKEY hRegistryKey, LPWSTR pszIpsecRootContainer, PIPSEC_POLICY_OBJECT pIpsecPolicyObject ) { DWORD dwError = 0; dwError = PersistPolicyObject( hRegistryKey, pIpsecPolicyObject ); BAIL_ON_WIN32_ERROR(dwError); error: return(dwError); } DWORD RegDeletePolicyData( HKEY hRegistryKey, LPWSTR pszIpsecRootContainer, PIPSEC_POLICY_DATA pIpsecPolicyData ) { DWORD dwError = ERROR_SUCCESS; PIPSEC_POLICY_OBJECT pIpsecPolicyObject = NULL; WCHAR szAbsPolicyReference[MAX_PATH]; LPWSTR pszRelISAKMPReference = NULL; DWORD dwRootPathLen = 0; BOOL bIsActive = FALSE; dwError = IsRegPolicyCurrentlyActive( hRegistryKey, pszIpsecRootContainer, pIpsecPolicyData->PolicyIdentifier, &bIsActive ); BAIL_ON_WIN32_ERROR(dwError); if (bIsActive) { dwError = ERROR_INVALID_PARAMETER; BAIL_ON_WIN32_ERROR(dwError); } dwRootPathLen = wcslen(pszIpsecRootContainer); dwError = RegMarshallPolicyObject( pIpsecPolicyData, pszIpsecRootContainer, &pIpsecPolicyObject ); BAIL_ON_WIN32_ERROR(dwError); szAbsPolicyReference[0] = L'\0'; wcscpy(szAbsPolicyReference, pszIpsecRootContainer); wcscat(szAbsPolicyReference, L"\\"); wcscat(szAbsPolicyReference, pIpsecPolicyObject->pszIpsecOwnersReference); pszRelISAKMPReference = pIpsecPolicyObject->pszIpsecISAKMPReference + dwRootPathLen + 1; dwError = RegRemovePolicyReferenceFromISAKMPObject( hRegistryKey, pszRelISAKMPReference, szAbsPolicyReference ); // BAIL_ON_WIN32_ERROR(dwError); dwError = RegDeleteKeyW( hRegistryKey, pIpsecPolicyObject->pszIpsecOwnersReference ); BAIL_ON_WIN32_ERROR(dwError); error: if (pIpsecPolicyObject) { FreeIpsecPolicyObject(pIpsecPolicyObject); } return(dwError); } DWORD RegUnmarshallPolicyData( PIPSEC_POLICY_OBJECT pIpsecPolicyObject, PIPSEC_POLICY_DATA * ppIpsecPolicyData ) { DWORD dwError = 0; dwError = UnmarshallPolicyObject( pIpsecPolicyObject, IPSEC_REGISTRY_PROVIDER, ppIpsecPolicyData ); return(dwError); } DWORD RegMarshallPolicyObject( PIPSEC_POLICY_DATA pIpsecPolicyData, LPWSTR pszIpsecRootContainer, PIPSEC_POLICY_OBJECT * ppIpsecPolicyObject ) { DWORD dwError = 0; PIPSEC_POLICY_OBJECT pIpsecPolicyObject = NULL; WCHAR szGuid[MAX_PATH]; WCHAR szDistinguishedName[MAX_PATH]; LPBYTE pBuffer = NULL; DWORD dwBufferLen = 0; LPWSTR pszStringUuid = NULL; LPWSTR pszIpsecISAKMPReference = NULL; time_t PresentTime; szGuid[0] = L'\0'; szDistinguishedName[0] = L'\0'; pIpsecPolicyObject = (PIPSEC_POLICY_OBJECT)AllocPolMem( sizeof(IPSEC_POLICY_OBJECT) ); if (!pIpsecPolicyObject) { dwError = ERROR_OUTOFMEMORY; BAIL_ON_WIN32_ERROR(dwError); } dwError = UuidToString( &pIpsecPolicyData->PolicyIdentifier, &pszStringUuid ); BAIL_ON_WIN32_ERROR(dwError); wcscpy(szGuid, L"{"); wcscat(szGuid, pszStringUuid); wcscat(szGuid, L"}"); // // Fill in the distinguishedName // wcscpy(szDistinguishedName,L"ipsecPolicy"); wcscat(szDistinguishedName, szGuid); pIpsecPolicyObject->pszIpsecOwnersReference = AllocPolStr( szDistinguishedName ); if (!pIpsecPolicyObject->pszIpsecOwnersReference) { dwError = ERROR_OUTOFMEMORY; BAIL_ON_WIN32_ERROR(dwError); } // // Fill in the ipsecName // if (pIpsecPolicyData->pszIpsecName && *pIpsecPolicyData->pszIpsecName) { pIpsecPolicyObject->pszIpsecName = AllocPolStr( pIpsecPolicyData->pszIpsecName ); if (!pIpsecPolicyObject->pszIpsecName) { dwError = ERROR_OUTOFMEMORY; BAIL_ON_WIN32_ERROR(dwError); } } if (pIpsecPolicyData->pszDescription && *pIpsecPolicyData->pszDescription) { pIpsecPolicyObject->pszDescription = AllocPolStr( pIpsecPolicyData->pszDescription ); if (!pIpsecPolicyObject->pszDescription) { dwError = ERROR_OUTOFMEMORY; BAIL_ON_WIN32_ERROR(dwError); } } // // Fill in the ipsecID // pIpsecPolicyObject->pszIpsecID = AllocPolStr( szGuid ); if (!pIpsecPolicyObject->pszIpsecID) { dwError = ERROR_OUTOFMEMORY; BAIL_ON_WIN32_ERROR(dwError); } // // Fill in the ipsecDataType // pIpsecPolicyObject->dwIpsecDataType = 0x100; // // Marshall the pIpsecDataBuffer and the Length // dwError = MarshallPolicyBuffer( pIpsecPolicyData, &pBuffer, &dwBufferLen ); BAIL_ON_WIN32_ERROR(dwError); pIpsecPolicyObject->pIpsecData = pBuffer; pIpsecPolicyObject->dwIpsecDataLen = dwBufferLen; dwError = ConvertGuidToISAKMPString( pIpsecPolicyData->ISAKMPIdentifier, pszIpsecRootContainer, &pszIpsecISAKMPReference ); BAIL_ON_WIN32_ERROR(dwError); pIpsecPolicyObject->pszIpsecISAKMPReference = pszIpsecISAKMPReference; time(&PresentTime); pIpsecPolicyObject->dwWhenChanged = (DWORD) PresentTime; *ppIpsecPolicyObject = pIpsecPolicyObject; cleanup: if (pszStringUuid) { RpcStringFree( &pszStringUuid ); } return(dwError); error: if (pIpsecPolicyObject) { FreeIpsecPolicyObject( pIpsecPolicyObject ); } *ppIpsecPolicyObject = NULL; goto cleanup; } DWORD MarshallPolicyBuffer( PIPSEC_POLICY_DATA pIpsecPolicyData, LPBYTE * ppBuffer, DWORD * pdwBufferLen ) { LPBYTE pBuffer = NULL; DWORD dwSize = 0; DWORD dwError = 0; DWORD dwPollingInterval = 0; LPBYTE pCurrentPos = NULL; DWORD dwEffectiveSize = 0; // {22202163-4F4C-11d1-863B-00A0248D3021} static const GUID GUID_IPSEC_POLICY_DATA_BLOB = { 0x22202163, 0x4f4c, 0x11d1, { 0x86, 0x3b, 0x0, 0xa0, 0x24, 0x8d, 0x30, 0x21 } }; dwSize += sizeof(GUID); dwSize += sizeof(DWORD); dwSize += sizeof(DWORD); dwSize++; pBuffer = AllocPolMem(dwSize); if (!pBuffer) { dwError = ERROR_OUTOFMEMORY; BAIL_ON_WIN32_ERROR(dwError); } pCurrentPos = pBuffer; memcpy(pCurrentPos, &GUID_IPSEC_POLICY_DATA_BLOB, sizeof(GUID)); pCurrentPos += sizeof(GUID); dwEffectiveSize = dwSize - sizeof(GUID) - sizeof(DWORD) - 1; memcpy(pCurrentPos, &dwEffectiveSize, sizeof(DWORD)); pCurrentPos += sizeof(DWORD); dwPollingInterval = pIpsecPolicyData->dwPollingInterval; memcpy(pCurrentPos, &dwPollingInterval, sizeof(DWORD)); *ppBuffer = pBuffer; *pdwBufferLen = dwSize; return(dwError); error: if (pBuffer) { FreePolMem(pBuffer); } *ppBuffer = NULL; *pdwBufferLen = 0; return(dwError); } DWORD ConvertGuidToISAKMPString( GUID ISAKMPIdentifier, LPWSTR pszIpsecRootContainer, LPWSTR * ppszIpsecISAKMPReference ) { DWORD dwError = 0; WCHAR szISAKMPReference[MAX_PATH]; LPWSTR pszIpsecISAKMPReference = NULL; WCHAR szGuidString[MAX_PATH]; LPWSTR pszStringUuid = NULL; dwError = UuidToString( &ISAKMPIdentifier, &pszStringUuid ); BAIL_ON_WIN32_ERROR(dwError); szGuidString[0] = L'\0'; wcscpy(szGuidString, L"{"); wcscat(szGuidString, pszStringUuid); wcscat(szGuidString, L"}"); szISAKMPReference[0] = L'\0'; SecStrCatW(szISAKMPReference, pszIpsecRootContainer, MAX_PATH); wcscat(szISAKMPReference, L"\\"); wcscat(szISAKMPReference, L"ipsecISAKMPPolicy"); wcscat(szISAKMPReference, szGuidString); pszIpsecISAKMPReference = AllocPolStr( szISAKMPReference ); if (!pszIpsecISAKMPReference) { dwError = ERROR_OUTOFMEMORY; BAIL_ON_WIN32_ERROR(dwError); } *ppszIpsecISAKMPReference = pszIpsecISAKMPReference; cleanup: if (pszStringUuid) { RpcStringFree(&pszStringUuid); } return(dwError); error: *ppszIpsecISAKMPReference = NULL; goto cleanup; } DWORD RegGetPolicyExistingISAKMPRef( HKEY hRegistryKey, PIPSEC_POLICY_DATA pIpsecPolicyData, LPWSTR * ppszISAKMPName ) { DWORD dwError = 0; LPWSTR pszStringUuid = NULL; WCHAR szRelativeName[MAX_PATH]; HKEY hRegKey = NULL; DWORD dwSize = 0; szRelativeName[0] = L'\0'; dwError = UuidToString( &pIpsecPolicyData->PolicyIdentifier, &pszStringUuid ); BAIL_ON_WIN32_ERROR(dwError); wcscpy(szRelativeName, L"ipsecPolicy"); wcscat(szRelativeName, L"{"); wcscat(szRelativeName, pszStringUuid); wcscat(szRelativeName, L"}"); dwError = RegOpenKeyExW( hRegistryKey, szRelativeName, 0, KEY_ALL_ACCESS, &hRegKey ); BAIL_ON_WIN32_ERROR(dwError); dwError = RegstoreQueryValue( hRegKey, L"ipsecISAKMPReference", REG_SZ, (LPBYTE *)ppszISAKMPName, &dwSize ); BAIL_ON_WIN32_ERROR(dwError); error: if (pszStringUuid) { RpcStringFree(&pszStringUuid); } if (hRegKey) { RegCloseKey(hRegKey); } return (dwError); } DWORD RegAssignPolicy( HKEY hHKLMKey, HKEY hRegistryKey, LPWSTR pszIpsecRootContainer, GUID PolicyIdentifier, LPWSTR pszLocationName ) { DWORD dwError = 0; WCHAR szRelativeName[MAX_PATH]; LPWSTR pszStringUuid = NULL; WCHAR szAbsPolicyRef[MAX_PATH]; DWORD dwRealProvider = 0; szRelativeName[0] = L'\0'; dwError = UuidToString( &PolicyIdentifier, &pszStringUuid ); BAIL_ON_WIN32_ERROR(dwError); wcscpy(szRelativeName, L"ipsecPolicy"); wcscat(szRelativeName, L"{"); wcscat(szRelativeName, pszStringUuid); wcscat(szRelativeName, L"}"); szAbsPolicyRef[0] = L'\0'; SecStrCatW(szAbsPolicyRef, pszIpsecRootContainer, MAX_PATH); wcscat(szAbsPolicyRef, L"\\"); wcscat(szAbsPolicyRef, szRelativeName); dwError = RegSetValueExW( hRegistryKey, L"ActivePolicy", 0, REG_SZ, (LPBYTE) szAbsPolicyRef, (wcslen(szAbsPolicyRef) + 1)*sizeof(WCHAR) ); BAIL_ON_WIN32_ERROR(dwError); // dwProvider store is actually wrong because it's set to IPSEC_REGISTRY_PROVIDER for // both perstent and registry policy. Therefore check Container to determine // actual location of store. // if (wcscmp(pszIpsecRootContainer, gpszRegPersistentContainer) == 0) { dwRealProvider = IPSEC_PERSISTENT_PROVIDER; } else { dwRealProvider = IPSEC_REGISTRY_PROVIDER; } dwError = IPSecChooseDriverBootMode( hHKLMKey, dwRealProvider, POL_ACTION_ASSIGN ); BAIL_ON_WIN32_ERROR(dwError); dwError = PingPolicyAgentSvc(pszLocationName); BAIL_ON_WIN32_ERROR(dwError); error: if (pszStringUuid) { RpcStringFree(&pszStringUuid); } return (dwError); } DWORD RegUnassignPolicy( HKEY hHKLMKey, HKEY hRegistryKey, LPWSTR pszIpsecRootContainer, GUID PolicyIdentifier, LPWSTR pszLocationName ) { DWORD dwError = 0; DWORD dwRealProvider = 0; dwError = RegDeleteValueW( hRegistryKey, L"ActivePolicy" ); BAIL_ON_WIN32_ERROR(dwError); // dwProvider in store is actually wrong because it's set to IPSEC_REGISTRY_PROVIDER for // both perstent and registry policy. Therefore check Container to determine // actual location of store. // if (wcscmp(pszIpsecRootContainer, gpszRegPersistentContainer) == 0) { dwRealProvider = IPSEC_PERSISTENT_PROVIDER; } else { dwRealProvider = IPSEC_REGISTRY_PROVIDER; } dwError = IPSecChooseDriverBootMode( hHKLMKey, dwRealProvider, POL_ACTION_UNASSIGN ); BAIL_ON_WIN32_ERROR(dwError); dwError = PingPolicyAgentSvc(pszLocationName); BAIL_ON_WIN32_ERROR(dwError); error: return (dwError); } DWORD PingPolicyAgentSvc( LPWSTR pszLocationName ) { SC_HANDLE ServiceDatabase = NULL; SC_HANDLE ServiceHandle = NULL; BOOL bStatus = FALSE; DWORD dwError = 0; SERVICE_STATUS IpsecStatus; memset(&IpsecStatus, 0, sizeof(SERVICE_STATUS)); ServiceDatabase = OpenSCManagerW( pszLocationName, NULL, SC_MANAGER_ALL_ACCESS ); if (ServiceDatabase == NULL) { dwError = GetLastError(); BAIL_ON_WIN32_ERROR(dwError); } ServiceHandle = OpenService( ServiceDatabase, "PolicyAgent", SERVICE_ALL_ACCESS ); if (ServiceHandle == NULL) { dwError = GetLastError(); BAIL_ON_WIN32_ERROR(dwError); } bStatus = QueryServiceStatus( ServiceHandle, &IpsecStatus ); if (bStatus == FALSE) { dwError = GetLastError(); BAIL_ON_WIN32_ERROR(dwError); } if (IpsecStatus.dwCurrentState == SERVICE_STOPPED) { bStatus = StartService( ServiceHandle, 0, NULL ); if (bStatus == FALSE) { dwError = GetLastError(); BAIL_ON_WIN32_ERROR(dwError); } } else if (IpsecStatus.dwCurrentState == SERVICE_RUNNING) { bStatus = ControlService( ServiceHandle, 129, &IpsecStatus ); if (bStatus == FALSE) { dwError = GetLastError(); BAIL_ON_WIN32_ERROR(dwError); } } error: if (ServiceDatabase != NULL) { CloseServiceHandle(ServiceDatabase); } if (ServiceHandle != NULL) { CloseServiceHandle(ServiceHandle); } return (dwError); } DWORD IsRegPolicyCurrentlyActive( HKEY hRegistryKey, LPWSTR pszIpsecRootContainer, GUID PolicyIdentifier, PBOOL pbIsActive ) { DWORD dwError = 0; PIPSEC_POLICY_DATA pIpsecPolicyData = NULL; *pbIsActive = FALSE; dwError = RegGetAssignedPolicyData( hRegistryKey, pszIpsecRootContainer, &pIpsecPolicyData ); if (pIpsecPolicyData) { if (!memcmp( &PolicyIdentifier, &pIpsecPolicyData->PolicyIdentifier, sizeof(GUID))) { *pbIsActive = TRUE; } FreeIpsecPolicyData(pIpsecPolicyData); } dwError = ERROR_SUCCESS; return (dwError); } DWORD RegGetPolicyData( HKEY hRegistryKey, LPWSTR pszIpsecRootContainer, GUID PolicyGUID, PIPSEC_POLICY_DATA * ppIpsecPolicyData ) { DWORD dwError = 0; PIPSEC_POLICY_OBJECT pIpsecPolicyObject = NULL; PIPSEC_POLICY_DATA pIpsecPolicyData = NULL; WCHAR szIpsecPolicyName[MAX_PATH]; LPWSTR pszPolicyName = NULL; szIpsecPolicyName[0] = L'\0'; wcscpy(szIpsecPolicyName, L"ipsecPolicy"); dwError = UuidToString(&PolicyGUID, &pszPolicyName); BAIL_ON_WIN32_ERROR(dwError); wcscat(szIpsecPolicyName, L"{"); wcscat(szIpsecPolicyName, pszPolicyName); wcscat(szIpsecPolicyName, L"}"); dwError = UnMarshallRegistryPolicyObject( hRegistryKey, pszIpsecRootContainer, szIpsecPolicyName, REG_RELATIVE_NAME, &pIpsecPolicyObject ); BAIL_ON_WIN32_ERROR(dwError); dwError = RegUnmarshallPolicyData( pIpsecPolicyObject, &pIpsecPolicyData ); BAIL_ON_WIN32_ERROR(dwError); error: if (pIpsecPolicyObject) { FreeIpsecPolicyObject( pIpsecPolicyObject ); } if (pszPolicyName) { RpcStringFree(&pszPolicyName); } *ppIpsecPolicyData = pIpsecPolicyData; return(dwError); } DWORD RegPingPASvcForActivePolicy( HKEY hRegistryKey, LPWSTR pszIpsecRootContainer, LPWSTR pszLocationName ) { DWORD dwError = 0; PIPSEC_POLICY_DATA pIpsecPolicyData = NULL; WCHAR szIpsecPolicyName[MAX_PATH]; LPWSTR pszPolicyName = NULL; WCHAR szAbsPolicyReference[MAX_PATH]; dwError = RegGetAssignedPolicyData( hRegistryKey, pszIpsecRootContainer, &pIpsecPolicyData ); BAIL_ON_WIN32_ERROR(dwError); if (!pIpsecPolicyData) { dwError = ERROR_SUCCESS; return (dwError); } szIpsecPolicyName[0] = L'\0'; wcscpy(szIpsecPolicyName, L"ipsecPolicy"); dwError = UuidToString(&pIpsecPolicyData->PolicyIdentifier, &pszPolicyName); BAIL_ON_WIN32_ERROR(dwError); wcscat(szIpsecPolicyName, L"{"); wcscat(szIpsecPolicyName, pszPolicyName); wcscat(szIpsecPolicyName, L"}"); szAbsPolicyReference[0] = L'\0'; wcscpy(szAbsPolicyReference, pszIpsecRootContainer); wcscat(szAbsPolicyReference, L"\\"); wcscat(szAbsPolicyReference, szIpsecPolicyName); dwError = RegUpdatePolicy( hRegistryKey, pszIpsecRootContainer, szAbsPolicyReference ); BAIL_ON_WIN32_ERROR(dwError); dwError = PingPolicyAgentSvc(pszLocationName); BAIL_ON_WIN32_ERROR(dwError); error: if (pIpsecPolicyData) { FreeIpsecPolicyData(pIpsecPolicyData); } if (pszPolicyName) { RpcStringFree(&pszPolicyName); } return (dwError); }