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
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;
|
|
}
|
|
}
|