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.
 
 
 
 
 
 

2780 lines
70 KiB

#include "precomp.h"
#ifdef TRACE_ON
#include "pastore.tmh"
#endif
VOID
InitializePolicyStateBlock(
PIPSEC_POLICY_STATE pIpsecPolicyState
)
{
memset(pIpsecPolicyState, 0, sizeof(IPSEC_POLICY_STATE));
pIpsecPolicyState->DefaultPollingInterval = gDefaultPollingInterval;
}
DWORD
StartStatePollingManager(
PIPSEC_POLICY_STATE pIpsecPolicyState
)
{
DWORD dwError = 0;
if (IsDirectoryPolicySpecified()) {
dwError = PlumbDirectoryPolicy(
pIpsecPolicyState
);
if (dwError) {
dwError = PlumbCachePolicy(
pIpsecPolicyState
);
}
} else if (IsLocalPolicySpecified()) {
dwError = PlumbLocalPolicy(
pIpsecPolicyState
);
BAIL_ON_WIN32_ERROR(dwError);
}
#ifdef TRACE_ON
else {
TRACE(TRC_INFORMATION, ("Pastore did not detect any local or domain policy assigned."));
}
#endif
//
// The new polling interval has been set by either the
// registry code or the DS code or remains at initialized value.
//
gCurrentPollingInterval = pIpsecPolicyState->CurrentPollingInterval;
TRACE(
TRC_INFORMATION,
("Set global polling interval to %d",
gCurrentPollingInterval)
);
return (dwError);
error:
return (dwError);
}
DWORD
PlumbDirectoryPolicy(
PIPSEC_POLICY_STATE pIpsecPolicyState
)
{
DWORD dwError = 0;
LPWSTR pszDirectoryPolicyDN = NULL;
PIPSEC_POLICY_OBJECT pIpsecPolicyObject = NULL;
PIPSEC_POLICY_DATA pIpsecPolicyData = NULL;
DWORD dwStoreType = IPSEC_DIRECTORY_PROVIDER;
DWORD dwSlientErrorCode = 0;
BOOL bIsActivePolicy = FALSE;
SPD_ACTION SpdAction = SPD_POLICY_LOAD;
TRACE(TRC_INFORMATION, (L"Plumbing directory policy"));
dwError = GetDirectoryPolicyDN(
&pszDirectoryPolicyDN
);
BAIL_ON_WIN32_ERROR(dwError);
bIsActivePolicy = TRUE;
dwError = LoadDirectoryPolicy(
pszDirectoryPolicyDN,
&pIpsecPolicyObject
);
BAIL_ON_WIN32_ERROR(dwError);
dwError = ProcessNFAs(
pIpsecPolicyObject,
dwStoreType,
&dwSlientErrorCode,
&pIpsecPolicyData
);
BAIL_ON_WIN32_ERROR(dwError);
AuditIPSecPolicyEvent(
SE_CATEGID_POLICY_CHANGE,
SE_AUDITID_IPSEC_POLICY_CHANGED,
PASTORE_LOAD_DS_POLICY_SUCCESS,
pIpsecPolicyData->pszIpsecName,
TRUE,
TRUE
);
SpdAction = SPD_POLICY_APPLY;
if (pIpsecPolicyState->pIpsecPolicyObject) {
FreeIpsecPolicyObject(pIpsecPolicyState->pIpsecPolicyObject);
}
if (pIpsecPolicyState->pIpsecPolicyData) {
FreeIpsecPolicyData(pIpsecPolicyState->pIpsecPolicyData);
}
if (pIpsecPolicyState->pszDirectoryPolicyDN) {
FreeSPDStr(pIpsecPolicyState->pszDirectoryPolicyDN);
}
pIpsecPolicyState->pIpsecPolicyObject = pIpsecPolicyObject;
pIpsecPolicyObject = NULL;
pIpsecPolicyState->pIpsecPolicyData = pIpsecPolicyData;
pIpsecPolicyData = NULL;
pIpsecPolicyState->pszDirectoryPolicyDN = pszDirectoryPolicyDN;
pszDirectoryPolicyDN = NULL;
//
// Plumb the DS policy.
//
dwError = ApplyLoadedDirectoryPolicy(
pIpsecPolicyState
);
// If error rollback. Ignoring rollback errors, because nothing can be done.
//
if (dwError) {
TRACE(TRC_INFORMATION, ("Pastore rolling back policy application due to previous errors"));
(VOID) DeletePolicyInformation(
pIpsecPolicyState->pIpsecPolicyData
);
}
BAIL_ON_WIN32_ERROR(dwError);
dwError = ERROR_SUCCESS;
if (dwSlientErrorCode) {
AuditIPSecPolicyErrorEvent(
SE_CATEGID_POLICY_CHANGE,
SE_AUDITID_IPSEC_POLICY_CHANGED,
PASTORE_FAILED_SOME_NFA_APPLICATION,
pIpsecPolicyState->pIpsecPolicyData->pszIpsecName,
dwSlientErrorCode,
FALSE,
TRUE
);
TRACE(
TRC_WARNING,
("Pastore failed to process one or more NFAs. Please compare active policy in SPD with static policy in storage: %!winerr!",
dwSlientErrorCode)
);
}
return (dwError);
error:
SetSpdStateOnError(
IPSEC_SOURCE_DOMAIN,
SpdAction,
dwError,
&pIpsecPolicyState->CurrentState
);
//
// Audit if we had an error loading policy (ApplyLoadedDirectoryPolicy handles
// auditing for policy pplication)
//
if (bIsActivePolicy && pszDirectoryPolicyDN &&
SpdAction == SPD_POLICY_LOAD)
{
AuditIPSecPolicyErrorEvent(
SE_CATEGID_POLICY_CHANGE,
SE_AUDITID_IPSEC_POLICY_CHANGED,
PASTORE_LOAD_DS_POLICY_FAIL,
pszDirectoryPolicyDN,
dwError,
FALSE,
TRUE
);
}
if (pszDirectoryPolicyDN) {
FreeSPDStr(pszDirectoryPolicyDN);
}
if (pIpsecPolicyObject) {
FreeIpsecPolicyObject(pIpsecPolicyObject);
}
if (pIpsecPolicyData) {
FreeIpsecPolicyData(pIpsecPolicyData);
}
// ASSERT: if ApplyLoadedDirectoryPolicy failed, then pIpsecPolicyState->pIpsecPolicyObject, are set to the
// pIpsecPolicyState->pIpsecPolicyData and pIpsecPolicyState->pszCachePolicyDN are filled
// with the values of the loaded BUT Unapplied policy.
return (dwError);
}
DWORD
GetDirectoryPolicyDN(
LPWSTR * ppszDirectoryPolicyDN
)
{
DWORD dwError = 0;
HKEY hPolicyKey = NULL;
LPWSTR pszIpsecPolicyName = NULL;
DWORD dwSize = 0;
LPWSTR pszPolicyDN = NULL;
LPWSTR pszDirectoryPolicyDN = NULL;
*ppszDirectoryPolicyDN = NULL;
dwError = RegOpenKeyExW(
HKEY_LOCAL_MACHINE,
gpszIpsecDSPolicyKey,
0,
KEY_ALL_ACCESS,
&hPolicyKey
);
BAIL_ON_WIN32_ERROR(dwError);
dwError = RegstoreQueryValue(
hPolicyKey,
L"DSIPSECPolicyPath",
REG_SZ,
(LPBYTE *)&pszIpsecPolicyName,
&dwSize
);
BAIL_ON_WIN32_ERROR(dwError);
//
// Move by LDAP:// to get the real DN and allocate
// this string.
// Fix this by fixing the gpo extension.
//
pszPolicyDN = pszIpsecPolicyName + wcslen(L"LDAP://");
pszDirectoryPolicyDN = AllocSPDStr(pszPolicyDN);
if (!pszDirectoryPolicyDN) {
dwError = ERROR_OUTOFMEMORY;
BAIL_ON_WIN32_ERROR(dwError);
}
*ppszDirectoryPolicyDN = pszDirectoryPolicyDN;
error:
#ifdef TRACE_ON
if (dwError) {
TRACE(TRC_ERROR, ("Failed to determine directory policy DN: %!winerr!", dwError));
}
#endif
if (pszIpsecPolicyName) {
FreeSPDStr(pszIpsecPolicyName);
}
if (hPolicyKey) {
CloseHandle(hPolicyKey);
}
return (dwError);
}
DWORD
LoadDirectoryPolicy(
LPWSTR pszDirectoryPolicyDN,
PIPSEC_POLICY_OBJECT * ppIpsecPolicyObject
)
{
DWORD dwError = 0;
LPWSTR pszDefaultDirectory = NULL;
HLDAP hLdapBindHandle = NULL;
PIPSEC_POLICY_OBJECT pIpsecPolicyObject = NULL;
TRACE(TRC_INFORMATION, (L"Loading directory policy."));
dwError = ComputeDefaultDirectory(
&pszDefaultDirectory
);
BAIL_ON_WIN32_ERROR(dwError);
dwError = OpenDirectoryServerHandle(
pszDefaultDirectory,
389,
&hLdapBindHandle
);
BAIL_ON_WIN32_ERROR(dwError);
dwError = ReadPolicyObjectFromDirectory(
hLdapBindHandle,
pszDirectoryPolicyDN,
&pIpsecPolicyObject
);
BAIL_ON_WIN32_ERROR(dwError);
*ppIpsecPolicyObject = pIpsecPolicyObject;
TRACE(TRC_INFORMATION, (L"Loaded directory policy from \"%ls\"", pszDirectoryPolicyDN));
cleanup:
if (pszDefaultDirectory) {
FreeSPDStr(pszDefaultDirectory);
}
if (hLdapBindHandle) {
CloseDirectoryServerHandle(hLdapBindHandle);
}
return (dwError);
error:
TRACE(
TRC_ERROR,
(L"Failed to load directory policy from \"%ls\": %!winerr!",
pszDirectoryPolicyDN,
dwError)
);
*ppIpsecPolicyObject = NULL;
goto cleanup;
}
DWORD
ApplyLoadedDirectoryPolicy(
PIPSEC_POLICY_STATE pIpsecPolicyState
)
{
DWORD dwError = 0;
PIPSEC_POLICY_DATA pIpsecPolicyData = NULL;
TRACE(TRC_INFORMATION, (L"Applying loaded directory policy."));
pIpsecPolicyData = pIpsecPolicyState->pIpsecPolicyData;
//
// Plumb the DS policy.
//
dwError = AddPolicyInformation(
pIpsecPolicyData,
IPSEC_SOURCE_DOMAIN
);
BAIL_ON_WIN32_ERROR(dwError);
//
// Delete the old cache and write the new one in.
//
DeleteRegistryCache();
CacheDirectorytoRegistry(pIpsecPolicyState->pIpsecPolicyObject);
//
// Set the state to DS_DOWNLOADED.
//
SetSpdStateOnError(
IPSEC_SOURCE_DOMAIN,
SPD_POLICY_APPLY,
ERROR_SUCCESS,
&pIpsecPolicyState->CurrentState
);
//
// Compute the new polling interval.
//
pIpsecPolicyState->CurrentPollingInterval = pIpsecPolicyData->dwPollingInterval;
pIpsecPolicyState->DSIncarnationNumber = pIpsecPolicyData->dwWhenChanged;
pIpsecPolicyState->RegIncarnationNumber = 0;
gCurrentPollingInterval = pIpsecPolicyState->CurrentPollingInterval;
TRACE(
TRC_INFORMATION,
("Set global polling interval to %d",
gCurrentPollingInterval)
);
dwError = ERROR_SUCCESS;
AuditIPSecPolicyEvent(
SE_CATEGID_POLICY_CHANGE,
SE_AUDITID_IPSEC_POLICY_CHANGED,
PASTORE_APPLIED_DS_POLICY,
pIpsecPolicyData->pszIpsecName,
TRUE,
TRUE
);
TRACE(
TRC_INFORMATION,
(L"Applied directory policy %ls loaded from %ls",
pIpsecPolicyData->pszIpsecName,
pIpsecPolicyState->pszDirectoryPolicyDN)
);
return (dwError);
error:
TRACE(
TRC_ERROR,
(L"Failed to apply directory policy %ls loaded from %ls",
pIpsecPolicyData->pszIpsecName,
pIpsecPolicyState->pszDirectoryPolicyDN)
);
SetSpdStateOnError(
IPSEC_SOURCE_DOMAIN,
SPD_POLICY_APPLY,
dwError,
&pIpsecPolicyState->CurrentState
);
AuditIPSecPolicyErrorEvent(
SE_CATEGID_POLICY_CHANGE,
SE_AUDITID_IPSEC_POLICY_CHANGED,
PASTORE_FAILED_DS_POLICY_APPLICATION,
pIpsecPolicyData->pszIpsecName,
dwError,
FALSE,
TRUE
);
return (dwError);
}
DWORD
PlumbCachePolicy(
PIPSEC_POLICY_STATE pIpsecPolicyState
)
{
DWORD dwError = 0;
LPWSTR pszCachePolicyDN = NULL;
PIPSEC_POLICY_OBJECT pIpsecPolicyObject = NULL;
PIPSEC_POLICY_DATA pIpsecPolicyData = NULL;
DWORD dwStoreType = IPSEC_REGISTRY_PROVIDER;
DWORD dwSlientErrorCode = 0;
BOOL bIsActivePolicy = FALSE;
SPD_ACTION SpdAction = SPD_POLICY_LOAD;
TRACE(TRC_INFORMATION, (L"Plumbing cache policy."));
dwError = GetCachePolicyDN(
&pszCachePolicyDN
);
BAIL_ON_WIN32_ERROR(dwError);
bIsActivePolicy = TRUE;
dwError = LoadCachePolicy(
pszCachePolicyDN,
&pIpsecPolicyObject
);
BAIL_ON_WIN32_ERROR(dwError);
dwError = ProcessNFAs(
pIpsecPolicyObject,
dwStoreType,
&dwSlientErrorCode,
&pIpsecPolicyData
);
BAIL_ON_WIN32_ERROR(dwError);
SpdAction = SPD_POLICY_APPLY;
dwError = AddPolicyInformation(
pIpsecPolicyData,
IPSEC_SOURCE_CACHE
);
// If error rollback. Ignoring rollback errors, because nothing can be done.
//
if (dwError) {
TRACE(TRC_INFORMATION, ("Pastore rolling back policy application due to previous errors"));
(VOID) DeletePolicyInformation(
pIpsecPolicyData
);
}
BAIL_ON_WIN32_ERROR(dwError);
if (pIpsecPolicyState->pIpsecPolicyObject) {
FreeIpsecPolicyObject(pIpsecPolicyState->pIpsecPolicyObject);
}
if (pIpsecPolicyState->pIpsecPolicyData) {
FreeIpsecPolicyData(pIpsecPolicyState->pIpsecPolicyData);
}
if (pIpsecPolicyState->pszCachePolicyDN) {
FreeSPDStr(pIpsecPolicyState->pszCachePolicyDN);
}
pIpsecPolicyState->pIpsecPolicyObject = pIpsecPolicyObject;
pIpsecPolicyState->pIpsecPolicyData = pIpsecPolicyData;
pIpsecPolicyState->pszCachePolicyDN = pszCachePolicyDN;
//
// Set the state to SPD_STATE_CACHE_APPLY_SUCCESS.
//
//
SetSpdStateOnError(
IPSEC_SOURCE_CACHE,
SPD_POLICY_APPLY,
ERROR_SUCCESS,
&pIpsecPolicyState->CurrentState
);
//
// Compute the new polling interval.
//
pIpsecPolicyState->CurrentPollingInterval = pIpsecPolicyData->dwPollingInterval;
pIpsecPolicyState->DSIncarnationNumber = 0;
pIpsecPolicyState->RegIncarnationNumber = pIpsecPolicyData->dwWhenChanged;
gCurrentPollingInterval = pIpsecPolicyState->CurrentPollingInterval;
TRACE(
TRC_INFORMATION,
("Set global polling interval to %d",
gCurrentPollingInterval)
);
dwError = ERROR_SUCCESS;
if (dwSlientErrorCode) {
AuditIPSecPolicyErrorEvent(
SE_CATEGID_POLICY_CHANGE,
SE_AUDITID_IPSEC_POLICY_CHANGED,
PASTORE_FAILED_SOME_NFA_APPLICATION,
pIpsecPolicyData->pszIpsecName,
dwSlientErrorCode,
FALSE,
TRUE
);
TRACE(
TRC_WARNING,
("Pastore failed to process one or more NFAs. Please compare active policy in SPD with policy in storage: %!winerr!",
dwSlientErrorCode)
);
}
AuditIPSecPolicyEvent(
SE_CATEGID_POLICY_CHANGE,
SE_AUDITID_IPSEC_POLICY_CHANGED,
PASTORE_APPLIED_CACHED_POLICY,
pIpsecPolicyData->pszIpsecName,
TRUE,
TRUE
);
TRACE(
TRC_INFORMATION,
(L"Applied cache policy %ls loaded from %ls",
pIpsecPolicyData->pszIpsecName,
pIpsecPolicyState->pszCachePolicyDN)
);
return (dwError);
error:
TRACE(
TRC_ERROR,
(L"Failed to plumb cache policy.")
);
SetSpdStateOnError(
IPSEC_SOURCE_CACHE,
SpdAction,
dwError,
&pIpsecPolicyState->CurrentState
);
//
// Check pszCachePolicyDN for non-NULL.
//
if (bIsActivePolicy && pszCachePolicyDN) {
AuditIPSecPolicyErrorEvent(
SE_CATEGID_POLICY_CHANGE,
SE_AUDITID_IPSEC_POLICY_CHANGED,
PASTORE_FAILED_CACHED_POLICY_APPLICATION,
pszCachePolicyDN,
dwError,
FALSE,
TRUE
);
}
if (pszCachePolicyDN) {
FreeSPDStr(pszCachePolicyDN);
}
if (pIpsecPolicyObject) {
FreeIpsecPolicyObject(pIpsecPolicyObject);
}
if (pIpsecPolicyData) {
FreeIpsecPolicyData(pIpsecPolicyData);
}
return (dwError);
}
DWORD
GetCachePolicyDN(
LPWSTR * ppszCachePolicyDN
)
{
DWORD dwError = 0;
LPWSTR pszDirectoryPolicyDN = NULL;
LPWSTR pszCachePolicyDN = NULL;
*ppszCachePolicyDN = NULL;
dwError = GetDirectoryPolicyDN(
&pszDirectoryPolicyDN
);
BAIL_ON_WIN32_ERROR(dwError);
dwError = CopyPolicyDSToFQRegString(
pszDirectoryPolicyDN,
&pszCachePolicyDN
);
BAIL_ON_WIN32_ERROR(dwError);
*ppszCachePolicyDN = pszCachePolicyDN;
error:
#ifdef TRACE_ON
if (dwError) {
TRACE(TRC_ERROR, ("Failed to determine cache policy DN: %!winerr!", dwError));
}
#endif
if (pszDirectoryPolicyDN) {
FreeSPDStr(pszDirectoryPolicyDN);
}
return (dwError);
}
DWORD
LoadCachePolicy(
LPWSTR pszCachePolicyDN,
PIPSEC_POLICY_OBJECT * ppIpsecPolicyObject
)
{
DWORD dwError = 0;
HKEY hRegistryKey = NULL;
PIPSEC_POLICY_OBJECT pIpsecPolicyObject = NULL;
TRACE(TRC_INFORMATION, (L"Loading cache policy."));
dwError = OpenRegistryIPSECRootKey(
NULL,
gpszIpsecCachePolicyKey,
&hRegistryKey
);
BAIL_ON_WIN32_ERROR(dwError);
dwError = ReadPolicyObjectFromRegistry(
hRegistryKey,
pszCachePolicyDN,
gpszIpsecCachePolicyKey,
&pIpsecPolicyObject
);
BAIL_ON_WIN32_ERROR(dwError);
*ppIpsecPolicyObject = pIpsecPolicyObject;
cleanup:
if (hRegistryKey) {
CloseHandle(hRegistryKey);
}
return (dwError);
error:
TRACE(
TRC_ERROR,
(L"Failed to load cache policy from \"%ls\": %!winerr!",
pszCachePolicyDN,
dwError)
);
*ppIpsecPolicyObject = NULL;
goto cleanup;
}
DWORD
PlumbLocalPolicy(
PIPSEC_POLICY_STATE pIpsecPolicyState
)
{
DWORD dwError = 0;
LPWSTR pszRegistryPolicyDN = NULL;
PIPSEC_POLICY_OBJECT pIpsecPolicyObject = NULL;
PIPSEC_POLICY_DATA pIpsecPolicyData = NULL;
DWORD dwStoreType = IPSEC_REGISTRY_PROVIDER;
DWORD dwSlientErrorCode = 0;
BOOL bIsActivePolicy = FALSE;
SPD_ACTION SpdAction = SPD_POLICY_LOAD;
TRACE(TRC_INFORMATION, (L"Plumbing local policy."));
dwError = GetRegistryPolicyDN(
&pszRegistryPolicyDN,
IPSEC_STORE_LOCAL
);
BAIL_ON_WIN32_ERROR(dwError);
bIsActivePolicy = TRUE;
dwError = LoadRegistryPolicy(
pszRegistryPolicyDN,
&pIpsecPolicyObject,
IPSEC_STORE_LOCAL
);
BAIL_ON_WIN32_ERROR(dwError);
dwError = ProcessNFAs(
pIpsecPolicyObject,
dwStoreType,
&dwSlientErrorCode,
&pIpsecPolicyData
);
BAIL_ON_WIN32_ERROR(dwError);
AuditIPSecPolicyEvent(
SE_CATEGID_POLICY_CHANGE,
SE_AUDITID_IPSEC_POLICY_CHANGED,
PASTORE_LOAD_LOCAL_POLICY_SUCCESS,
pIpsecPolicyData->pszIpsecName,
TRUE,
TRUE
);
SpdAction = SPD_POLICY_APPLY;
if (pIpsecPolicyState->pIpsecPolicyObject) {
FreeIpsecPolicyObject(pIpsecPolicyState->pIpsecPolicyObject);
}
if (pIpsecPolicyState->pIpsecPolicyData) {
FreeIpsecPolicyData(pIpsecPolicyState->pIpsecPolicyData);
}
if (pIpsecPolicyState->pszRegistryPolicyDN) {
FreeSPDStr(pIpsecPolicyState->pszRegistryPolicyDN);
}
pIpsecPolicyState->pIpsecPolicyObject = pIpsecPolicyObject;
pIpsecPolicyObject = NULL;
pIpsecPolicyState->pIpsecPolicyData = pIpsecPolicyData;
pIpsecPolicyData = NULL;
pIpsecPolicyState->pszRegistryPolicyDN = pszRegistryPolicyDN;
pszRegistryPolicyDN = NULL;
dwError = ApplyLoadedLocalPolicy(
pIpsecPolicyState
);
// If error rollback. Ignoring rollback errors, because nothing can be done.
//
if (dwError) {
TRACE(TRC_INFORMATION, ("Pastore rolling back policy application due to previous errors"));
(VOID) DeletePolicyInformation(
pIpsecPolicyState->pIpsecPolicyData
);
}
BAIL_ON_WIN32_ERROR(dwError);
dwError = ERROR_SUCCESS;
if (dwSlientErrorCode) {
AuditIPSecPolicyErrorEvent(
SE_CATEGID_POLICY_CHANGE,
SE_AUDITID_IPSEC_POLICY_CHANGED,
PASTORE_FAILED_SOME_NFA_APPLICATION,
pIpsecPolicyState->pIpsecPolicyData->pszIpsecName,
dwSlientErrorCode,
FALSE,
TRUE
);
TRACE(
TRC_WARNING,
("Pastore failed to process one or more NFAs. Please compare active policy in SPD with policy in storage: %!winerr!",
dwSlientErrorCode)
);
}
return (dwError);
error:
SetSpdStateOnError(
IPSEC_SOURCE_LOCAL,
SpdAction,
dwError,
&pIpsecPolicyState->CurrentState
);
//
// Audit if we had an error loading policy (ApplyLoadedDirectoryPolicy handles
// auditing for policy pplication)
//
if (bIsActivePolicy && pszRegistryPolicyDN &&
SpdAction == SPD_POLICY_LOAD)
{
AuditIPSecPolicyErrorEvent(
SE_CATEGID_POLICY_CHANGE,
SE_AUDITID_IPSEC_POLICY_CHANGED,
PASTORE_LOAD_LOCAL_POLICY_FAIL,
pszRegistryPolicyDN,
dwError,
FALSE,
TRUE
);
}
if (pszRegistryPolicyDN) {
FreeSPDStr(pszRegistryPolicyDN);
}
if (pIpsecPolicyObject) {
FreeIpsecPolicyObject(pIpsecPolicyObject);
}
if (pIpsecPolicyData) {
FreeIpsecPolicyData(pIpsecPolicyData);
}
// ASSERT: if ApplyLoadedLocalPolicy failed, then pIpsecPolicyState->pIpsecPolicyObject, are set to the
// pIpsecPolicyState->pIpsecPolicyData and pIpsecPolicyState->pszCachePolicyDN are filled
// with the values of the loaded BUT Unapplied policy.
return (dwError);
}
DWORD
ApplyLoadedLocalPolicy(
PIPSEC_POLICY_STATE pIpsecPolicyState
)
{
DWORD dwError = 0;
PIPSEC_POLICY_DATA pIpsecPolicyData = NULL;
TRACE(TRC_INFORMATION, (L"Applying loaded local policy."));
pIpsecPolicyData = pIpsecPolicyState->pIpsecPolicyData;
dwError = AddPolicyInformation(
pIpsecPolicyData,
IPSEC_SOURCE_LOCAL
);
BAIL_ON_WIN32_ERROR(dwError);
SetSpdStateOnError(
IPSEC_SOURCE_LOCAL,
SPD_POLICY_APPLY,
ERROR_SUCCESS,
&pIpsecPolicyState->CurrentState
);
//
// Compute the new polling interval.
//
pIpsecPolicyState->CurrentPollingInterval = pIpsecPolicyData->dwPollingInterval;
pIpsecPolicyState->DSIncarnationNumber = 0;
pIpsecPolicyState->RegIncarnationNumber = pIpsecPolicyData->dwWhenChanged;
gCurrentPollingInterval = pIpsecPolicyState->CurrentPollingInterval;
TRACE(
TRC_INFORMATION,
("Set global polling interval to %d",
gCurrentPollingInterval)
);
dwError = ERROR_SUCCESS;
AuditIPSecPolicyEvent(
SE_CATEGID_POLICY_CHANGE,
SE_AUDITID_IPSEC_POLICY_CHANGED,
PASTORE_APPLIED_LOCAL_POLICY,
pIpsecPolicyData->pszIpsecName,
TRUE,
TRUE
);
TRACE(
TRC_INFORMATION,
(L"Applied local policy %ls loaded from %ls",
pIpsecPolicyData->pszIpsecName,
pIpsecPolicyState->pszRegistryPolicyDN)
);
return (dwError);
error:
TRACE(
TRC_ERROR,
(L"Failed to apply local policy %ls loaded from %ls",
pIpsecPolicyData->pszIpsecName,
pIpsecPolicyState->pszDirectoryPolicyDN)
);
SetSpdStateOnError(
IPSEC_SOURCE_LOCAL,
SPD_POLICY_APPLY,
dwError,
&pIpsecPolicyState->CurrentState
);
AuditIPSecPolicyErrorEvent(
SE_CATEGID_POLICY_CHANGE,
SE_AUDITID_IPSEC_POLICY_CHANGED,
PASTORE_FAILED_LOCAL_POLICY_APPLICATION,
pIpsecPolicyData->pszIpsecName,
dwError,
FALSE,
TRUE
);
return (dwError);
}
DWORD
PlumbPersistentPolicy(
PIPSEC_POLICY_STATE pIpsecPolicyState
)
{
DWORD dwError = 0;
LPWSTR pszRegistryPolicyDN = NULL;
PIPSEC_POLICY_OBJECT pIpsecPolicyObject = NULL;
PIPSEC_POLICY_DATA pIpsecPolicyData = NULL;
DWORD dwStoreType = IPSEC_REGISTRY_PROVIDER;
DWORD dwSlientErrorCode = 0;
BOOL bIsActivePolicy = FALSE;
SPD_ACTION SpdAction = SPD_POLICY_LOAD;
TRACE(TRC_INFORMATION, (L"Plumbing local policy."));
dwError = GetRegistryPolicyDN(
&pszRegistryPolicyDN,
IPSEC_STORE_PERSISTENT
);
BAIL_ON_WIN32_ERROR(dwError);
bIsActivePolicy = TRUE;
dwError = LoadRegistryPolicy(
pszRegistryPolicyDN,
&pIpsecPolicyObject,
IPSEC_STORE_PERSISTENT
);
BAIL_ON_WIN32_ERROR(dwError);
dwError = ProcessNFAs(
pIpsecPolicyObject,
dwStoreType,
&dwSlientErrorCode,
&pIpsecPolicyData
);
BAIL_ON_WIN32_ERROR(dwError);
AuditIPSecPolicyEvent(
SE_CATEGID_POLICY_CHANGE,
SE_AUDITID_IPSEC_POLICY_CHANGED,
PASTORE_LOAD_PERSISTENT_POLICY_SUCCESS,
pIpsecPolicyData->pszIpsecName,
TRUE,
TRUE
);
SpdAction = SPD_POLICY_APPLY;
dwError = AddPolicyInformation(
pIpsecPolicyData,
IPSEC_SOURCE_PERSISTENT
);
BAIL_ON_WIN32_ERROR(dwError);
if (pIpsecPolicyState->pIpsecPolicyObject) {
FreeIpsecPolicyObject(pIpsecPolicyState->pIpsecPolicyObject);
}
if (pIpsecPolicyState->pIpsecPolicyData) {
FreeIpsecPolicyData(pIpsecPolicyState->pIpsecPolicyData);
}
if (pIpsecPolicyState->pszRegistryPolicyDN) {
FreeSPDStr(pIpsecPolicyState->pszRegistryPolicyDN);
}
pIpsecPolicyState->pIpsecPolicyObject = pIpsecPolicyObject;
pIpsecPolicyState->pIpsecPolicyData = pIpsecPolicyData;
pIpsecPolicyState->pszRegistryPolicyDN = pszRegistryPolicyDN;
SetSpdStateOnError(
IPSEC_SOURCE_PERSISTENT,
SPD_POLICY_APPLY,
ERROR_SUCCESS,
&gpIpsecPolicyState->CurrentState
);
gbPersistentPolicyApplied = TRUE;
pIpsecPolicyState->PersIncarnationNumber = pIpsecPolicyData->dwWhenChanged;
dwError = ERROR_SUCCESS;
if (dwSlientErrorCode) {
AuditIPSecPolicyErrorEvent(
SE_CATEGID_POLICY_CHANGE,
SE_AUDITID_IPSEC_POLICY_CHANGED,
PASTORE_FAILED_SOME_NFA_APPLICATION,
pIpsecPolicyData->pszIpsecName,
dwSlientErrorCode,
FALSE,
TRUE
);
TRACE(
TRC_WARNING,
("Pastore failed to process one or more NFAs. Please compare active policy in SPD policy in storage: %!winerr!",
dwSlientErrorCode)
);
}
AuditIPSecPolicyEvent(
SE_CATEGID_POLICY_CHANGE,
SE_AUDITID_IPSEC_POLICY_CHANGED,
PASTORE_APPLIED_PERSISTENT_POLICY,
pIpsecPolicyData->pszIpsecName,
TRUE,
TRUE
);
TRACE(TRC_INFORMATION, ("Plumbed persistent policy"));
return (dwError);
error:
TRACE(
TRC_ERROR,
(L"Failed to plumb persistent policy.")
);
SetSpdStateOnError(
IPSEC_SOURCE_PERSISTENT,
SpdAction,
dwError,
&gpIpsecPolicyState->CurrentState
);
gbPersistentPolicyApplied = FALSE;
//
// Check pszRegistryPolicyDN for non-NULL.
//
if (bIsActivePolicy && pszRegistryPolicyDN &&
SpdAction == SPD_POLICY_LOAD)
{
AuditIPSecPolicyErrorEvent(
SE_CATEGID_POLICY_CHANGE,
SE_AUDITID_IPSEC_POLICY_CHANGED,
PASTORE_LOAD_PERSISTENT_POLICY_FAIL,
pszRegistryPolicyDN,
dwError,
FALSE,
TRUE
);
} else if (SpdAction == SPD_POLICY_APPLY && pIpsecPolicyData) {
// (Above pIPsecPolicyData can't be null if SPD_POLICY_APPLY,
// but needed check to get prefast off our back)
AuditIPSecPolicyErrorEvent(
SE_CATEGID_POLICY_CHANGE,
SE_AUDITID_IPSEC_POLICY_CHANGED,
PASTORE_FAILED_PERSISTENT_POLICY_APPLICATION,
pIpsecPolicyData->pszIpsecName,
dwError,
FALSE,
TRUE
);
}
if (pszRegistryPolicyDN) {
FreeSPDStr(pszRegistryPolicyDN);
}
if (pIpsecPolicyObject) {
FreeIpsecPolicyObject(pIpsecPolicyObject);
}
if (pIpsecPolicyData) {
FreeIpsecPolicyData(pIpsecPolicyData);
}
return (dwError);
}
LPWSTR
GetRegPathForStore(
IN DWORD dwStore)
{
if (dwStore == IPSEC_STORE_PERSISTENT) {
return gpszIpsecPersistentPolicyKey;
}
else if (dwStore == IPSEC_STORE_LOCAL) {
return gpszIpsecLocalPolicyKey;
}
return NULL;
}
DWORD
GetRegistryPolicyDN(
LPWSTR * ppszRegistryPolicyDN,
IN DWORD dwStore
)
{
DWORD dwError = 0;
HKEY hPolicyKey = NULL;
LPWSTR pszIpsecPolicyName = NULL;
DWORD dwSize = 0;
LPWSTR pszRegPath = NULL;
pszRegPath = GetRegPathForStore(dwStore);
if (pszRegPath == NULL) {
dwError = ERROR_INVALID_PARAMETER;
BAIL_ON_WIN32_ERROR(dwError);
}
dwError = RegOpenKeyExW(
HKEY_LOCAL_MACHINE,
pszRegPath,
0,
KEY_ALL_ACCESS,
&hPolicyKey
);
BAIL_ON_WIN32_ERROR(dwError);
dwError = RegstoreQueryValue(
hPolicyKey,
L"ActivePolicy",
REG_SZ,
(LPBYTE *)&pszIpsecPolicyName,
&dwSize
);
BAIL_ON_WIN32_ERROR(dwError);
if (!pszIpsecPolicyName || !*pszIpsecPolicyName) {
dwError = ERROR_OUTOFMEMORY;
BAIL_ON_WIN32_ERROR(dwError);
}
*ppszRegistryPolicyDN = pszIpsecPolicyName;
cleanup:
if (hPolicyKey) {
CloseHandle(hPolicyKey);
}
return (dwError);
error:
TRACE(
TRC_ERROR,
(L"Failed to get %ls policy DN: %!winerr!",
dwStore == IPSEC_STORE_LOCAL ? L"local" : L"persistent",
dwError)
);
if (pszIpsecPolicyName) {
FreeSPDStr(pszIpsecPolicyName);
}
*ppszRegistryPolicyDN = NULL;
goto cleanup;
}
DWORD
LoadRegistryPolicy(
LPWSTR pszRegistryPolicyDN,
PIPSEC_POLICY_OBJECT * ppIpsecPolicyObject,
IN DWORD dwStore
)
{
DWORD dwError = 0;
HKEY hRegistryKey = NULL;
PIPSEC_POLICY_OBJECT pIpsecPolicyObject = NULL;
LPWSTR pszRegPath = NULL;
TRACE(TRC_INFORMATION, (L"Loading registry policy."));
pszRegPath = GetRegPathForStore(dwStore);
if (pszRegPath == NULL) {
dwError = ERROR_INVALID_PARAMETER;
BAIL_ON_WIN32_ERROR(dwError);
}
dwError = OpenRegistryIPSECRootKey(
NULL,
pszRegPath,
&hRegistryKey
);
BAIL_ON_WIN32_ERROR(dwError);
dwError = ReadPolicyObjectFromRegistry(
hRegistryKey,
pszRegistryPolicyDN,
pszRegPath,
&pIpsecPolicyObject
);
BAIL_ON_WIN32_ERROR(dwError);
*ppIpsecPolicyObject = pIpsecPolicyObject;
cleanup:
if (hRegistryKey) {
CloseHandle(hRegistryKey);
}
return (dwError);
error:
TRACE(
TRC_ERROR,
(L"Failed to load %ls policy from \"%ls\": %!winerr!",
dwStore == IPSEC_STORE_LOCAL ? L"local" : L"persistent",
pszRegistryPolicyDN,
dwError)
);
*ppIpsecPolicyObject = NULL;
goto cleanup;
}
DWORD
LoadPersistedIPSecInformation(
)
{
DWORD dwError = ERROR_SUCCESS;
IPSEC_POLICY_STATE IpsecPolicyState;
// Initialize Policy State Block.
//
InitializePolicyStateBlock(&IpsecPolicyState);
// Load and apply the persisted store
//
if (IsPersistentPolicySpecified()) {
dwError = PlumbPersistentPolicy(
&IpsecPolicyState
);
BAIL_ON_WIN32_ERROR(dwError);
}
#ifdef TRACE_ON
else {
TRACE(TRC_INFORMATION, (L"No persistent policy specified."));
}
#endif
cleanup:
ClearPolicyStateBlock(&IpsecPolicyState);
return (dwError);
error:
goto cleanup;
}
DWORD
AddPolicyInformation(
PIPSEC_POLICY_DATA pIpsecPolicyData,
IN DWORD dwSource
)
{
DWORD dwError = 0;
BOOL bHardError = FALSE;
dwError = AddMMPolicyInformation(
pIpsecPolicyData,
dwSource
);
dwError = AddQMPolicyInformation(
pIpsecPolicyData,
dwSource,
&bHardError
);
if (bHardError) {
return (dwError);
} else {
return ERROR_SUCCESS;
}
}
DWORD
AddMMPolicyInformation(
PIPSEC_POLICY_DATA pIpsecPolicyData,
IN DWORD dwSource
)
{
DWORD dwError = 0;
dwError = PAAddMMPolicies(
&(pIpsecPolicyData->pIpsecISAKMPData),
1,
dwSource
);
dwError = PAAddMMAuthMethods(
pIpsecPolicyData->ppIpsecNFAData,
pIpsecPolicyData->dwNumNFACount,
dwSource
);
dwError = PAAddMMFilters(
pIpsecPolicyData->pIpsecISAKMPData,
pIpsecPolicyData->ppIpsecNFAData,
pIpsecPolicyData->dwNumNFACount,
dwSource
);
BAIL_ON_WIN32_ERROR(dwError);
error:
return (dwError);
}
DWORD
AddQMPolicyInformation(
PIPSEC_POLICY_DATA pIpsecPolicyData,
IN DWORD dwSource,
BOOL * pbHardError
)
{
DWORD dwError = 0;
BOOL bHardError = FALSE;
dwError = PAAddQMPolicies(
pIpsecPolicyData->ppIpsecNFAData,
pIpsecPolicyData->dwNumNFACount,
dwSource
);
dwError = PAAddQMFilters(
pIpsecPolicyData->ppIpsecNFAData,
pIpsecPolicyData->dwNumNFACount,
dwSource,
&bHardError
);
BAIL_ON_WIN32_ERROR(dwError);
error:
*pbHardError = bHardError;
return (dwError);
}
DWORD
OnPolicyChanged(
PIPSEC_POLICY_STATE pIpsecPolicyState
)
{
DWORD dwError = 0;
//
// Remove all the old policy that was plumbed.
//
TRACE(TRC_INFORMATION, ("Pastore deleting existing policy since policy assignment change detected or forced."));
dwError = DeletePolicyInformation(
pIpsecPolicyState->pIpsecPolicyData
);
ClearPolicyStateBlock(
pIpsecPolicyState
);
// Don't lose track of the fact that we've loaded Persistent policy.
if (gbPersistentPolicyApplied) {
SetSpdStateOnError(
IPSEC_SOURCE_PERSISTENT,
SPD_POLICY_APPLY,
ERROR_SUCCESS,
&pIpsecPolicyState->CurrentState
);
}
//
// Calling the Initializer again.
//
dwError = StartStatePollingManager(
pIpsecPolicyState
);
return (dwError);
}
DWORD
DeletePolicyInformation(
PIPSEC_POLICY_DATA pIpsecPolicyData
)
{
DWORD dwError = 0;
if (!pIpsecPolicyData) {
dwError = ERROR_SUCCESS;
return (dwError);
}
dwError = DeleteMMPolicyInformation(pIpsecPolicyData);
dwError = DeleteQMPolicyInformation(pIpsecPolicyData);
dwError = ERROR_SUCCESS;
return (dwError);
}
DWORD
DeleteMMPolicyInformation(
PIPSEC_POLICY_DATA pIpsecPolicyData
)
{
DWORD dwError = 0;
dwError = PADeleteMMFilters(
pIpsecPolicyData->pIpsecISAKMPData,
pIpsecPolicyData->ppIpsecNFAData,
pIpsecPolicyData->dwNumNFACount
);
dwError = PADeleteMMAuthMethods(
pIpsecPolicyData->ppIpsecNFAData,
pIpsecPolicyData->dwNumNFACount
);
dwError = PADeleteMMPolicies(
&(pIpsecPolicyData->pIpsecISAKMPData),
1
);
return (dwError);
}
DWORD
DeleteQMPolicyInformation(
PIPSEC_POLICY_DATA pIpsecPolicyData
)
{
DWORD dwError = 0;
dwError = PADeleteQMFilters(
pIpsecPolicyData->ppIpsecNFAData,
pIpsecPolicyData->dwNumNFACount
);
dwError = PADeleteQMPolicies(
pIpsecPolicyData->ppIpsecNFAData,
pIpsecPolicyData->dwNumNFACount
);
return (dwError);
}
DWORD
DeleteAllPolicyInformation(
)
{
DWORD dwError = 0;
TRACE(TRC_INFORMATION, (L"Deleting all policy information"));
dwError = DeleteAllMMPolicyInformation();
dwError = DeleteAllQMPolicyInformation();
dwError = ERROR_SUCCESS;
return (dwError);
}
DWORD
DeleteAllMMPolicyInformation(
)
{
DWORD dwError = 0;
dwError = PADeleteAllMMFilters();
dwError = PADeleteAllMMAuthMethods();
dwError = PADeleteAllMMPolicies();
return (dwError);
}
DWORD
DeleteAllQMPolicyInformation(
)
{
DWORD dwError = 0;
dwError = PADeleteAllTxFilters();
dwError = PADeleteAllTnFilters();
dwError = PADeleteAllQMPolicies();
return (dwError);
}
VOID
ClearPolicyStateBlock(
PIPSEC_POLICY_STATE pIpsecPolicyState
)
{
if (pIpsecPolicyState->pIpsecPolicyObject) {
FreeIpsecPolicyObject(
pIpsecPolicyState->pIpsecPolicyObject
);
pIpsecPolicyState->pIpsecPolicyObject = NULL;
}
if (pIpsecPolicyState->pIpsecPolicyData) {
FreeIpsecPolicyData(
pIpsecPolicyState->pIpsecPolicyData
);
pIpsecPolicyState->pIpsecPolicyData = NULL;
}
if (pIpsecPolicyState->pszDirectoryPolicyDN) {
FreeSPDStr(pIpsecPolicyState->pszDirectoryPolicyDN);
pIpsecPolicyState->pszDirectoryPolicyDN = NULL;
}
pIpsecPolicyState->CurrentPollingInterval = gDefaultPollingInterval;
pIpsecPolicyState->DefaultPollingInterval = gDefaultPollingInterval;
pIpsecPolicyState->DSIncarnationNumber = 0;
pIpsecPolicyState->RegIncarnationNumber = 0;
pIpsecPolicyState->CurrentState = SPD_STATE_INITIAL;
}
DWORD
OnPolicyPoll(
PIPSEC_POLICY_STATE pIpsecPolicyState
)
{
DWORD dwError = 0;
switch (pIpsecPolicyState->CurrentState) {
case SPD_STATE_DS_APPLY_SUCCESS:
// Tell group policy to refresh machine policy.
// Our GP extension will ping us with NEW_DS_POLICY_EVENT
// or GPUPDATE_REFRESH_EVENT when it's finished.
TRACE(TRC_INFORMATION, (L"Requesting group policy to notify policy agent to check for policy changes."));
RefreshPolicy(TRUE);
break;
case SPD_STATE_CACHE_APPLY_SUCCESS:
dwError = ProcessCachePolicyPollState(pIpsecPolicyState);
break;
case SPD_STATE_LOCAL_APPLY_SUCCESS:
dwError = ProcessLocalPolicyPollState(pIpsecPolicyState);
break;
case SPD_STATE_INITIAL:
case SPD_STATE_PERSISTENT_APPLY_SUCCESS:
// For these following states need to try to reload polcies from the start.
//
dwError = OnPolicyChanged(pIpsecPolicyState);
break;
case SPD_STATE_DS_APPLY_FAIL:
// If DS apply failed, then still have loaded DS data so to reapply loaded data.
//
dwError = ApplyLoadedDirectoryPolicy(pIpsecPolicyState);
// If error rollback. Ignoring rollback errors, because nothing can be done.
//
if (dwError) {
TRACE(TRC_INFORMATION, ("Pastore rolling back policy application due to previous errors"));
(VOID) DeletePolicyInformation(
pIpsecPolicyState->pIpsecPolicyData
);
}
break;
case SPD_STATE_LOCAL_APPLY_FAIL:
// If apply failed, then still have loaded policy data so to reapply loaded data.
//
dwError = ApplyLoadedLocalPolicy(pIpsecPolicyState);
// If error rollback. Ignoring rollback errors, because nothing can be done.
//
if (dwError) {
TRACE(TRC_INFORMATION, ("Pastore rolling back policy application due to previous errors"));
(VOID) DeletePolicyInformation(
pIpsecPolicyState->pIpsecPolicyData
);
}
break;
case SPD_STATE_LOCAL_LOAD_FAIL:
dwError = PlumbLocalPolicy(pIpsecPolicyState);
break;
case SPD_STATE_DS_LOAD_FAIL:
case SPD_STATE_CACHE_LOAD_FAIL:
case SPD_STATE_CACHE_APPLY_FAIL:
case SPD_STATE_CACHE_LOAD_SUCCESS:
// if DS policy load failed so try to load *and* apply again.
// In case of CACHE policy load/apply failue, little point in retrying again,
// so directly try DS policy again.
//
dwError = PlumbDirectoryPolicy(pIpsecPolicyState);
break;
default:
// Any other state is unexpected during polling
// We should be in *APPLY_SUCCESS or *APPLY_FAIL or *LOAD_FAIL
// SPD_STATE_DS_LOAD_SUCCESS,
// SPD_STATE_LOCAL_LOAD_SUCCESS,
// SPD_STATE_PERSISTENT_LOAD_SUCCESS
// For the following errors we should have shutdown and not
// be here.
// SPD_STATE_PERSISTENT_LOAD_FAIL
// SPD_STATE_PERSISTENT_APPLY_FAIL
ASSERT(FALSE);
break;
}
//
// Set the new polling interval.
//
gCurrentPollingInterval = pIpsecPolicyState->CurrentPollingInterval;
TRACE(
TRC_INFORMATION,
("Set global polling interval to %d",
gCurrentPollingInterval)
);
if (InAcceptableState(pIpsecPolicyState->CurrentState)) {
gdwRetryCount = 0;
} else {
gdwRetryCount++;
}
return (dwError);
}
DWORD
ProcessDirectoryPolicyPollState(
PIPSEC_POLICY_STATE pIpsecPolicyState
)
{
DWORD dwError = 0;
DWORD dwIncarnationNumber = 0;
PIPSEC_POLICY_OBJECT pIpsecPolicyObject = NULL;
PIPSEC_POLICY_DATA pIpsecPolicyData = NULL;
DWORD dwStoreType = IPSEC_DIRECTORY_PROVIDER;
DWORD dwSlientErrorCode = 0;
if (pIpsecPolicyState->CurrentState != SPD_STATE_DS_APPLY_SUCCESS) {
TRACE(TRC_INFORMATION, (L"Pastore not checking whether directory policy has been modified because not in DS apply success."));
return ERROR_SUCCESS;
}
//
// The directory policy DN has to be the same, otherwise the
// IPSec extension in Winlogon would have already notified
// PA Store of the DS policy change.
//
TRACE(TRC_INFORMATION, (L"Pastore checking whether directory policy has been modified."));
dwError = GetDirectoryIncarnationNumber(
pIpsecPolicyState->pszDirectoryPolicyDN,
&dwIncarnationNumber
);
if (dwError) {
dwError = MigrateFromDSToCache(pIpsecPolicyState);
BAIL_ON_WIN32_ERROR(dwError);
return (ERROR_SUCCESS);
}
if (dwIncarnationNumber == pIpsecPolicyState->DSIncarnationNumber) {
//
// The policy has not changed at all.
//
AuditEvent(
SE_CATEGID_POLICY_CHANGE,
SE_AUDITID_IPSEC_POLICY_CHANGED,
PASTORE_POLLING_NO_CHANGES,
NULL,
TRUE,
TRUE
);
TRACE(TRC_INFORMATION, (L"Pastore did not detect any policy change."));
return (ERROR_SUCCESS);
}
//
// The incarnation number is different, so there's a need to
// update the policy.
//
TRACE(TRC_INFORMATION, (L"Pastore detected that policy has been modified. Performing policy update."));
dwError = LoadDirectoryPolicy(
pIpsecPolicyState->pszDirectoryPolicyDN,
&pIpsecPolicyObject
);
if (dwError) {
dwError = MigrateFromDSToCache(pIpsecPolicyState);
BAIL_ON_WIN32_ERROR(dwError);
return (ERROR_SUCCESS);
}
dwError = ProcessNFAs(
pIpsecPolicyObject,
dwStoreType,
&dwSlientErrorCode,
&pIpsecPolicyData
);
if (dwError) {
TRACE(
TRC_ERROR,
(L"Pastore failure when processing NFAs. Will migrate from directory to cache: %!winerr!",
dwError)
);
dwError = MigrateFromDSToCache(pIpsecPolicyState);
BAIL_ON_WIN32_ERROR(dwError);
if (pIpsecPolicyObject) {
FreeIpsecPolicyObject(pIpsecPolicyObject);
}
return (ERROR_SUCCESS);
}
dwError = UpdatePolicyInformation(
pIpsecPolicyState->pIpsecPolicyData,
pIpsecPolicyData,
IPSEC_SOURCE_DOMAIN
);
if (pIpsecPolicyState->pIpsecPolicyObject) {
FreeIpsecPolicyObject(pIpsecPolicyState->pIpsecPolicyObject);
}
if (pIpsecPolicyState->pIpsecPolicyData) {
FreeIpsecPolicyData(pIpsecPolicyState->pIpsecPolicyData);
}
//
// Now delete the old cache and write the new one in.
//
DeleteRegistryCache();
CacheDirectorytoRegistry(pIpsecPolicyObject);
pIpsecPolicyState->pIpsecPolicyObject = pIpsecPolicyObject;
pIpsecPolicyState->pIpsecPolicyData = pIpsecPolicyData;
pIpsecPolicyState->CurrentPollingInterval = pIpsecPolicyData->dwPollingInterval;
pIpsecPolicyState->DSIncarnationNumber = dwIncarnationNumber;
NotifyIpsecPolicyChange();
dwError = ERROR_SUCCESS;
if (dwSlientErrorCode) {
AuditIPSecPolicyErrorEvent(
SE_CATEGID_POLICY_CHANGE,
SE_AUDITID_IPSEC_POLICY_CHANGED,
PASTORE_FAILED_SOME_NFA_APPLICATION,
pIpsecPolicyData->pszIpsecName,
dwSlientErrorCode,
FALSE,
TRUE
);
TRACE(
TRC_WARNING,
("Pastore failed to process one or more NFAs. Please compare active policy in SPD with policy in storage: %!winerr!",
dwSlientErrorCode)
);
}
AuditEvent(
SE_CATEGID_POLICY_CHANGE,
SE_AUDITID_IPSEC_POLICY_CHANGED,
PASTORE_POLLING_APPLIED_CHANGES,
NULL,
TRUE,
TRUE
);
return (dwError);
error:
TRACE(
TRC_ERROR,
(L"Pastore failed when checking for policy change on poll: %!winerr!",
dwError)
);
if (pIpsecPolicyObject) {
FreeIpsecPolicyObject(pIpsecPolicyObject);
}
if (pIpsecPolicyData) {
FreeIpsecPolicyData(pIpsecPolicyData);
}
return (dwError);
}
DWORD
GetDirectoryIncarnationNumber(
LPWSTR pszIpsecPolicyDN,
DWORD * pdwIncarnationNumber
)
{
DWORD dwError = 0;
LPWSTR pszDefaultDirectory = NULL;
HLDAP hLdapBindHandle = NULL;
LPWSTR Attributes[] = {L"whenChanged", NULL};
LDAPMessage *res = NULL;
LDAPMessage *e = NULL;
WCHAR **strvalues = NULL;
DWORD dwCount = 0;
time_t t_WhenChanged = 0;
*pdwIncarnationNumber = 0;
//
// Open the directory store.
//
dwError = ComputeDefaultDirectory(
&pszDefaultDirectory
);
BAIL_ON_WIN32_ERROR(dwError);
dwError = OpenDirectoryServerHandle(
pszDefaultDirectory,
389,
&hLdapBindHandle
);
BAIL_ON_WIN32_ERROR(dwError);
dwError = LdapSearchST(
hLdapBindHandle,
pszIpsecPolicyDN,
LDAP_SCOPE_BASE,
L"(objectClass=*)",
Attributes,
0,
NULL,
&res
);
BAIL_ON_WIN32_ERROR(dwError);
dwError = LdapFirstEntry(
hLdapBindHandle,
res,
&e
);
BAIL_ON_WIN32_ERROR(dwError);
dwError = LdapGetValues(
hLdapBindHandle,
e,
L"whenChanged",
(WCHAR ***)&strvalues,
(int *)&dwCount
);
BAIL_ON_WIN32_ERROR(dwError);
dwError = GeneralizedTimeToTime(
LDAPOBJECT_STRING((PLDAPOBJECT)strvalues),
&t_WhenChanged
);
BAIL_ON_WIN32_ERROR(dwError);
*pdwIncarnationNumber = TIME_T_TO_DWORD(t_WhenChanged);
error:
#ifdef TRACE_ON
if (dwError) {
TRACE(TRC_ERROR, ("Pastore failed to get directory policy change date/time: %!winerr!", dwError));
}
#endif
if (pszDefaultDirectory) {
FreeSPDStr(pszDefaultDirectory);
}
if (hLdapBindHandle) {
CloseDirectoryServerHandle(hLdapBindHandle);
}
if (res) {
LdapMsgFree(res);
}
if (strvalues) {
LdapValueFree(strvalues);
}
return (dwError);
}
DWORD
MigrateFromDSToCache(
PIPSEC_POLICY_STATE pIpsecPolicyState
)
{
DWORD dwError = 0;
LPWSTR pszCachePolicyDN = NULL;
TRACE(TRC_INFORMATION, ("Migrating from directory to cache policy."));
dwError = GetCachePolicyDN(
&pszCachePolicyDN
);
BAIL_ON_WIN32_ERROR(dwError);
if (pIpsecPolicyState->pszDirectoryPolicyDN) {
FreeSPDStr(pIpsecPolicyState->pszDirectoryPolicyDN);
pIpsecPolicyState->pszDirectoryPolicyDN = NULL;
}
pIpsecPolicyState->pszCachePolicyDN = pszCachePolicyDN;
//
// Keep pIpsecPolicyState->pIpsecPolicyData.
// Keep pIpsecPolicyState->pIpsecPolicyObject.
// Change the incarnation numbers.
//
pIpsecPolicyState->RegIncarnationNumber = pIpsecPolicyState->DSIncarnationNumber;
pIpsecPolicyState->DSIncarnationNumber = 0;
SetSpdStateOnError(
IPSEC_SOURCE_CACHE,
SPD_POLICY_APPLY,
ERROR_SUCCESS,
&pIpsecPolicyState->CurrentState
);
//
// Keep pIpsecPolicyState->CurrentPollingInterval.
// Keep pIpsecPolicyState->DefaultPollingInterval.
//
gCurrentPollingInterval = pIpsecPolicyState->CurrentPollingInterval;
TRACE(
TRC_INFORMATION,
("Set global polling interval to %d",
gCurrentPollingInterval)
);
AuditEvent(
SE_CATEGID_POLICY_CHANGE,
SE_AUDITID_IPSEC_POLICY_CHANGED,
PASTORE_MIGRATE_DS_TO_CACHE,
NULL,
TRUE,
TRUE
);
TRACE(TRC_INFORMATION, (L"Pastore migrated from cache to directory policy."));
error:
return (dwError);
}
DWORD
ProcessCachePolicyPollState(
PIPSEC_POLICY_STATE pIpsecPolicyState
)
{
DWORD dwError = 0;
LPWSTR pszDirectoryPolicyDN = NULL;
DWORD dwIncarnationNumber = 0;
LPWSTR pszCachePolicyDN = NULL;
TRACE(TRC_INFORMATION, (L"Detecting if cache change time is different from directory change time."));
dwError = GetDirectoryPolicyDN(
&pszDirectoryPolicyDN
);
if (!dwError) {
dwError = GetDirectoryIncarnationNumber(
pszDirectoryPolicyDN,
&dwIncarnationNumber
);
if (!dwError) {
dwError = CopyPolicyDSToFQRegString(
pszDirectoryPolicyDN,
&pszCachePolicyDN
);
if (!dwError) {
if (!_wcsicmp(pIpsecPolicyState->pszCachePolicyDN, pszCachePolicyDN)) {
if (pIpsecPolicyState->RegIncarnationNumber == dwIncarnationNumber) {
dwError = MigrateFromCacheToDS(pIpsecPolicyState);
}
else {
dwError = UpdateFromCacheToDS(pIpsecPolicyState);
}
if (dwError) {
dwError = OnPolicyChanged(pIpsecPolicyState);
}
}
else {
dwError = OnPolicyChanged(pIpsecPolicyState);
}
}
}
}
if (pszDirectoryPolicyDN) {
FreeSPDStr(pszDirectoryPolicyDN);
}
if (pszCachePolicyDN) {
FreeSPDStr(pszCachePolicyDN);
}
return (ERROR_SUCCESS);
}
DWORD
MigrateFromCacheToDS(
PIPSEC_POLICY_STATE pIpsecPolicyState
)
{
DWORD dwError = 0;
LPWSTR pszDirectoryPolicyDN = NULL;
dwError = GetDirectoryPolicyDN(
&pszDirectoryPolicyDN
);
BAIL_ON_WIN32_ERROR(dwError);
if (pIpsecPolicyState->pszCachePolicyDN) {
FreeSPDStr(pIpsecPolicyState->pszCachePolicyDN);
pIpsecPolicyState->pszCachePolicyDN = NULL;
}
pIpsecPolicyState->pszDirectoryPolicyDN = pszDirectoryPolicyDN;
//
// Keep pIpsecPolicyState->pIpsecPolicyData.
// Keep pIpsecPolicyState->pIpsecPolicyObject.
// Change the incarnation numbers.
//
pIpsecPolicyState->DSIncarnationNumber = pIpsecPolicyState->RegIncarnationNumber;
pIpsecPolicyState->RegIncarnationNumber = 0;
SetSpdStateOnError(
IPSEC_SOURCE_DOMAIN,
SPD_POLICY_APPLY,
ERROR_SUCCESS,
&pIpsecPolicyState->CurrentState
);
//
// Keep pIpsecPolicyState->CurrentPollingInterval.
// Keep pIpsecPolicyState->DefaultPollingInterval.
//
gCurrentPollingInterval = pIpsecPolicyState->CurrentPollingInterval;
AuditEvent(
SE_CATEGID_POLICY_CHANGE,
SE_AUDITID_IPSEC_POLICY_CHANGED,
PASTORE_MIGRATE_CACHE_TO_DS,
NULL,
TRUE,
TRUE
);
error:
return (dwError);
}
DWORD
UpdateFromCacheToDS(
PIPSEC_POLICY_STATE pIpsecPolicyState
)
{
DWORD dwError = 0;
LPWSTR pszDirectoryPolicyDN = NULL;
PIPSEC_POLICY_OBJECT pIpsecPolicyObject = NULL;
PIPSEC_POLICY_DATA pIpsecPolicyData = NULL;
DWORD dwStoreType = IPSEC_DIRECTORY_PROVIDER;
DWORD dwSlientErrorCode = 0;
TRACE(TRC_INFORMATION, (L"Detect difference between plumbed cache, and directory policy. Updating plumbed policy."));
dwError = GetDirectoryPolicyDN(
&pszDirectoryPolicyDN
);
BAIL_ON_WIN32_ERROR(dwError);
dwError = LoadDirectoryPolicy(
pszDirectoryPolicyDN,
&pIpsecPolicyObject
);
BAIL_ON_WIN32_ERROR(dwError);
dwError = ProcessNFAs(
pIpsecPolicyObject,
dwStoreType,
&dwSlientErrorCode,
&pIpsecPolicyData
);
BAIL_ON_WIN32_ERROR(dwError);
dwError = UpdatePolicyInformation(
pIpsecPolicyState->pIpsecPolicyData,
pIpsecPolicyData,
IPSEC_SOURCE_DOMAIN
);
if (pIpsecPolicyState->pIpsecPolicyObject) {
FreeIpsecPolicyObject(pIpsecPolicyState->pIpsecPolicyObject);
}
if (pIpsecPolicyState->pIpsecPolicyData) {
FreeIpsecPolicyData(pIpsecPolicyState->pIpsecPolicyData);
}
if (pIpsecPolicyState->pszCachePolicyDN) {
FreeSPDStr(pIpsecPolicyState->pszCachePolicyDN);
}
//
// Now delete the old cache and write the new one in.
//
DeleteRegistryCache();
CacheDirectorytoRegistry(pIpsecPolicyObject);
pIpsecPolicyState->pIpsecPolicyObject = pIpsecPolicyObject;
pIpsecPolicyState->pIpsecPolicyData = pIpsecPolicyData;
pIpsecPolicyState->pszDirectoryPolicyDN = pszDirectoryPolicyDN;
//
// Set the state to DS-DOWNLOADED.
//
SetSpdStateOnError(
IPSEC_SOURCE_DOMAIN,
SPD_POLICY_APPLY,
ERROR_SUCCESS,
&pIpsecPolicyState->CurrentState
);
//
// Compute the new polling interval.
//
pIpsecPolicyState->CurrentPollingInterval = pIpsecPolicyData->dwPollingInterval;
pIpsecPolicyState->DSIncarnationNumber = pIpsecPolicyData->dwWhenChanged;
pIpsecPolicyState->RegIncarnationNumber = 0;
gCurrentPollingInterval = pIpsecPolicyState->CurrentPollingInterval;
NotifyIpsecPolicyChange();
dwError = ERROR_SUCCESS;
if (dwSlientErrorCode) {
AuditIPSecPolicyErrorEvent(
SE_CATEGID_POLICY_CHANGE,
SE_AUDITID_IPSEC_POLICY_CHANGED,
PASTORE_FAILED_SOME_NFA_APPLICATION,
pIpsecPolicyData->pszIpsecName,
dwSlientErrorCode,
FALSE,
TRUE
);
TRACE(
TRC_WARNING,
("Pastore failed to process one or more NFAs. Please compare active policy in SPD with policy in storage: %!winerr!",
dwSlientErrorCode)
);
}
AuditEvent(
SE_CATEGID_POLICY_CHANGE,
SE_AUDITID_IPSEC_POLICY_CHANGED,
PASTORE_UPDATE_CACHE_TO_DS,
NULL,
TRUE,
TRUE
);
return (dwError);
error:
if (pszDirectoryPolicyDN) {
FreeSPDStr(pszDirectoryPolicyDN);
}
if (pIpsecPolicyObject) {
FreeIpsecPolicyObject(pIpsecPolicyObject);
}
if (pIpsecPolicyData) {
FreeIpsecPolicyData(pIpsecPolicyData);
}
return (dwError);
}
DWORD
ProcessLocalPolicyPollState(
PIPSEC_POLICY_STATE pIpsecPolicyState
)
{
DWORD dwStatus = 0;
LPWSTR pszDirectoryPolicyDN = NULL;
DWORD dwDSIncarnationNumber = 0;
DWORD dwError = 0;
BOOL bChanged = FALSE;
DWORD dwIncarnationNumber = 0;
PIPSEC_POLICY_OBJECT pIpsecPolicyObject = NULL;
PIPSEC_POLICY_DATA pIpsecPolicyData = NULL;
DWORD dwStoreType = IPSEC_REGISTRY_PROVIDER;
DWORD dwSlientErrorCode = 0;
TRACE(TRC_INFORMATION, (L"Pastore checking whether local policy assignment has changed."));
dwStatus = GetDirectoryPolicyDN(
&pszDirectoryPolicyDN
);
if (!dwStatus) {
dwStatus = GetDirectoryIncarnationNumber(
pszDirectoryPolicyDN,
&dwDSIncarnationNumber
);
if (pszDirectoryPolicyDN) {
FreeSPDStr(pszDirectoryPolicyDN);
}
if (!dwStatus) {
dwStatus = OnPolicyChanged(pIpsecPolicyState);
return (dwStatus);
}
}
dwError = HasRegistryPolicyChanged(
pIpsecPolicyState->pszRegistryPolicyDN,
&bChanged
);
BAIL_ON_WIN32_ERROR(dwError);
if (bChanged) {
dwError = OnPolicyChanged(pIpsecPolicyState);
return (dwError);
}
if (pIpsecPolicyState->CurrentState == SPD_STATE_INITIAL) {
return (ERROR_SUCCESS);
}
dwError = GetRegistryIncarnationNumber(
pIpsecPolicyState->pszRegistryPolicyDN,
&dwIncarnationNumber
);
BAIL_ON_WIN32_ERROR(dwError);
if (dwIncarnationNumber == pIpsecPolicyState->RegIncarnationNumber) {
//
// The policy has not changed at all.
//
AuditEvent(
SE_CATEGID_POLICY_CHANGE,
SE_AUDITID_IPSEC_POLICY_CHANGED,
PASTORE_POLLING_NO_CHANGES,
NULL,
TRUE,
TRUE
);
TRACE(TRC_INFORMATION, (L"Pastore did not detect any policy change."));
return (ERROR_SUCCESS);
}
TRACE(TRC_INFORMATION, (L"Pastore detected that policy has been modified. Performing policy update."));
dwError = LoadRegistryPolicy(
pIpsecPolicyState->pszRegistryPolicyDN,
&pIpsecPolicyObject,
IPSEC_STORE_LOCAL
);
BAIL_ON_WIN32_ERROR(dwError);
dwError = ProcessNFAs(
pIpsecPolicyObject,
dwStoreType,
&dwSlientErrorCode,
&pIpsecPolicyData
);
BAIL_ON_WIN32_ERROR(dwError);
dwError = UpdatePolicyInformation(
pIpsecPolicyState->pIpsecPolicyData,
pIpsecPolicyData,
IPSEC_SOURCE_LOCAL
);
if (pIpsecPolicyState->pIpsecPolicyObject) {
FreeIpsecPolicyObject(pIpsecPolicyState->pIpsecPolicyObject);
}
if (pIpsecPolicyState->pIpsecPolicyData) {
FreeIpsecPolicyData(pIpsecPolicyState->pIpsecPolicyData);
}
pIpsecPolicyState->pIpsecPolicyObject = pIpsecPolicyObject;
pIpsecPolicyState->pIpsecPolicyData = pIpsecPolicyData;
pIpsecPolicyState->CurrentPollingInterval = pIpsecPolicyData->dwPollingInterval;
pIpsecPolicyState->RegIncarnationNumber = dwIncarnationNumber;
NotifyIpsecPolicyChange();
dwError = ERROR_SUCCESS;
if (dwSlientErrorCode) {
AuditIPSecPolicyErrorEvent(
SE_CATEGID_POLICY_CHANGE,
SE_AUDITID_IPSEC_POLICY_CHANGED,
PASTORE_FAILED_SOME_NFA_APPLICATION,
pIpsecPolicyData->pszIpsecName,
dwSlientErrorCode,
FALSE,
TRUE
);
TRACE(
TRC_WARNING,
("Pastore failed to process one or more NFAs. Please compare active policy in SPD with policy in storage: %!winerr!",
dwSlientErrorCode )
);
}
AuditEvent(
SE_CATEGID_POLICY_CHANGE,
SE_AUDITID_IPSEC_POLICY_CHANGED,
PASTORE_POLLING_APPLIED_CHANGES,
NULL,
TRUE,
TRUE
);
return (dwError);
error:
TRACE(
TRC_ERROR,
(L"Pastore failed when checking for policy change on poll: %!winerr!",
dwError)
);
if (pIpsecPolicyObject) {
FreeIpsecPolicyObject(pIpsecPolicyObject);
}
if (pIpsecPolicyData) {
FreeIpsecPolicyData(pIpsecPolicyData);
}
return (dwError);
}
DWORD
HasRegistryPolicyChanged(
LPWSTR pszCurrentPolicyDN,
PBOOL pbChanged
)
{
DWORD dwError = 0;
HKEY hRegKey = NULL;
LPWSTR pszIpsecPolicyName = NULL;
DWORD dwSize = 0;
BOOL bChanged = FALSE;
dwError = RegOpenKeyExW(
HKEY_LOCAL_MACHINE,
gpszIpsecLocalPolicyKey,
0,
KEY_ALL_ACCESS,
&hRegKey
);
BAIL_ON_WIN32_ERROR(dwError);
dwError = RegstoreQueryValue(
hRegKey,
L"ActivePolicy",
REG_SZ,
(LPBYTE *)&pszIpsecPolicyName,
&dwSize
);
//
// Must not bail from here, as there can be no
// active local policy.
//
if (pszIpsecPolicyName && *pszIpsecPolicyName) {
if (!pszCurrentPolicyDN || !*pszCurrentPolicyDN) {
bChanged = TRUE;
}
else {
if (!_wcsicmp(pszIpsecPolicyName, pszCurrentPolicyDN)) {
bChanged = FALSE;
}
else {
bChanged = TRUE;
}
}
}
else {
if (!pszCurrentPolicyDN || !*pszCurrentPolicyDN) {
bChanged = FALSE;
}
else {
bChanged = TRUE;
}
}
*pbChanged = bChanged;
dwError = ERROR_SUCCESS;
cleanup:
if (hRegKey) {
CloseHandle(hRegKey);
}
if (pszIpsecPolicyName) {
FreeSPDStr(pszIpsecPolicyName);
}
return (dwError);
error:
TRACE(TRC_ERROR, ("Pastore failed when trying to detect if local policy assigment has changed: %!winerr!", dwError));
*pbChanged = FALSE;
goto cleanup;
}
DWORD
GetRegistryIncarnationNumber(
LPWSTR pszIpsecPolicyDN,
DWORD * pdwIncarnationNumber
)
{
DWORD dwError = 0;
HKEY hRegKey = NULL;
DWORD dwType = REG_DWORD;
DWORD dwWhenChanged = 0;
DWORD dwSize = sizeof(DWORD);
*pdwIncarnationNumber = 0;
dwError = RegOpenKeyExW(
HKEY_LOCAL_MACHINE,
pszIpsecPolicyDN,
0,
KEY_ALL_ACCESS,
&hRegKey
);
BAIL_ON_WIN32_ERROR(dwError);
dwError = RegQueryValueExW(
hRegKey,
L"whenChanged",
NULL,
&dwType,
(LPBYTE)&dwWhenChanged,
&dwSize
);
BAIL_ON_WIN32_ERROR(dwError);
*pdwIncarnationNumber = dwWhenChanged;
error:
#ifdef TRACE_ON
if (dwError) {
TRACE(TRC_ERROR, ("Pastore failed to get registry change date/time: %!winerr!", dwError));
}
#endif
if (hRegKey) {
CloseHandle(hRegKey);
}
return(dwError);
}
DWORD
UpdatePolicyInformation(
PIPSEC_POLICY_DATA pOldIpsecPolicyData,
PIPSEC_POLICY_DATA pNewIpsecPolicyData,
IN DWORD dwSource
)
{
DWORD dwError = 0;
PIPSEC_ISAKMP_DATA pOldIpsecISAKMPData = NULL;
PIPSEC_NFA_DATA * ppOldIpsecNFAData = NULL;
DWORD dwNumOldNFACount = 0;
PIPSEC_ISAKMP_DATA pNewIpsecISAKMPData = NULL;
PIPSEC_NFA_DATA * ppNewIpsecNFAData = NULL;
DWORD dwNumNewNFACount = 0;
pOldIpsecISAKMPData = pOldIpsecPolicyData->pIpsecISAKMPData;
ppOldIpsecNFAData = pOldIpsecPolicyData->ppIpsecNFAData;
dwNumOldNFACount = pOldIpsecPolicyData->dwNumNFACount;
pNewIpsecISAKMPData = pNewIpsecPolicyData->pIpsecISAKMPData;
ppNewIpsecNFAData = pNewIpsecPolicyData->ppIpsecNFAData;
dwNumNewNFACount = pNewIpsecPolicyData->dwNumNFACount;
TRACE(
TRC_INFORMATION,
(L"Pastore performing policy update")
);
dwError = PADeleteObseleteISAKMPData(
&pOldIpsecISAKMPData,
1,
ppOldIpsecNFAData,
dwNumOldNFACount,
&pNewIpsecISAKMPData,
1
);
dwError = PAUpdateISAKMPData(
&pNewIpsecISAKMPData,
1,
ppOldIpsecNFAData,
dwNumOldNFACount,
&pOldIpsecISAKMPData,
1,
dwSource
);
dwError = PADeleteObseleteNFAData(
pNewIpsecISAKMPData,
ppOldIpsecNFAData,
dwNumOldNFACount,
ppNewIpsecNFAData,
dwNumNewNFACount
);
dwError = PAUpdateNFAData(
pNewIpsecISAKMPData,
ppNewIpsecNFAData,
dwNumNewNFACount,
ppOldIpsecNFAData,
dwNumOldNFACount,
dwSource
);
return (dwError);
}
DWORD
LoadDefaultISAKMPInformation(
LPWSTR pszDefaultISAKMPDN
)
{
DWORD dwError = 0;
gbLoadedISAKMPDefaults = TRUE;
return (dwError);
}
VOID
UnLoadDefaultISAKMPInformation(
LPWSTR pszDefaultISAKMPDN
)
{
return;
}
BOOL
IsDirectoryPolicySpecified(
)
{
DWORD dwError = ERROR_SUCCESS;
LPWSTR pszDirectoryPolicyDN = NULL;
dwError = GetDirectoryPolicyDN(
&pszDirectoryPolicyDN
);
if (pszDirectoryPolicyDN) {
FreeSPDStr(pszDirectoryPolicyDN);
}
if (dwError) {
return FALSE;
} else {
return TRUE;
}
}
BOOL
IsLocalPolicySpecified(
)
{
DWORD dwError = ERROR_SUCCESS;
LPWSTR pszRegistryPolicyDN = NULL;
dwError = GetRegistryPolicyDN(
&pszRegistryPolicyDN,
IPSEC_STORE_LOCAL
);
if (pszRegistryPolicyDN) {
FreeSPDStr(pszRegistryPolicyDN);
}
if (dwError) {
return FALSE;
} else {
return TRUE;
}
}
BOOL
IsPersistentPolicySpecified(
)
{
DWORD dwError = ERROR_SUCCESS;
LPWSTR pszRegistryPolicyDN = NULL;
dwError = GetRegistryPolicyDN(
&pszRegistryPolicyDN,
IPSEC_STORE_PERSISTENT
);
if (pszRegistryPolicyDN) {
FreeSPDStr(pszRegistryPolicyDN);
}
if (dwError) {
return FALSE;
} else {
return TRUE;
}
}