|
|
#include "precomp.h"
VOID InitializePolicyStateBlock( PWIRELESS_POLICY_STATE pWirelessPolicyState ) { memset(pWirelessPolicyState, 0, sizeof(WIRELESS_POLICY_STATE)); pWirelessPolicyState->DefaultPollingInterval = gDefaultPollingInterval; }
DWORD StartStatePollingManager( PWIRELESS_POLICY_STATE pWirelessPolicyState ) { DWORD dwError = 0;
dwError = PlumbDirectoryPolicy( pWirelessPolicyState ); if (dwError) {
dwError = PlumbCachePolicy( pWirelessPolicyState ); BAIL_ON_WIN32_ERROR(dwError); }
//
// The new polling interval has been set by either the
// registry code or the DS code.
//
gCurrentPollingInterval = pWirelessPolicyState->CurrentPollingInterval;
return (dwError);
error:
//
// On error, set the state to INITIAL.
//
pWirelessPolicyState->dwCurrentState = POLL_STATE_INITIAL; _WirelessDbg(TRC_STATE, "Policy State :: Initial State ");
gCurrentPollingInterval = pWirelessPolicyState->DefaultPollingInterval;
return (dwError); }
DWORD PlumbDirectoryPolicy( PWIRELESS_POLICY_STATE pWirelessPolicyState ) { DWORD dwError = 0; LPWSTR pszDirectoryPolicyDN = NULL; PWIRELESS_POLICY_OBJECT pWirelessPolicyObject = NULL; PWIRELESS_POLICY_DATA pWirelessPolicyData = NULL; DWORD dwStoreType = WIRELESS_DIRECTORY_PROVIDER; DWORD dwSlientErrorCode = 0; BOOL bIsActivePolicy = FALSE; LPVOID lpMsgBuf; DWORD len = 0; DWORD i = 0;
_WirelessDbg(TRC_NOTIF, "DBASE: Wireless Policy - Checking for Current Policy on DC "); dwError = GetDirectoryPolicyDN( &pszDirectoryPolicyDN ); BAIL_ON_WIN32_ERROR(dwError); bIsActivePolicy = TRUE;
dwError = LoadDirectoryPolicy( pszDirectoryPolicyDN, &pWirelessPolicyObject ); BAIL_ON_WIN32_ERROR(dwError); // Taroon:: For some reason, the dwChanged Field is written by ProcessNFA Routine.
// Ideally it should be written here first. May be, the when changed field is decided
// based on if the NFA policy too has changed etc etc.
// Unmarshalling of IPSEC happens in ProcessNFA. We get rid of that and call it right here.
__try { dwError = UnmarshallWirelessPolicyObject( pWirelessPolicyObject, dwStoreType, &pWirelessPolicyData ); } __except(EXCEPTION_EXECUTE_HANDLER) { dwError = ERROR_INVALID_DATA; _WirelessDbg(TRC_ERR, "Got Invalid Data "); } BAIL_ON_WIN32_ERROR(dwError);
dwError = AddPolicyInformation( pWirelessPolicyData ); if (pWirelessPolicyState->pWirelessPolicyObject) { FreeWirelessPolicyObject(pWirelessPolicyState->pWirelessPolicyObject); } if (pWirelessPolicyState->pWirelessPolicyData) { FreeWirelessPolicyData(pWirelessPolicyState->pWirelessPolicyData); } if (pWirelessPolicyState->pszDirectoryPolicyDN) { FreeSPDStr(pWirelessPolicyState->pszDirectoryPolicyDN); }
//
// Delete the old cache and write the new one in.
//
DeleteRegistryCache();
CacheDirectorytoRegistry(pWirelessPolicyObject);
pWirelessPolicyState->pWirelessPolicyObject = pWirelessPolicyObject;
pWirelessPolicyState->pWirelessPolicyData = pWirelessPolicyData;
pWirelessPolicyState->pszDirectoryPolicyDN = pszDirectoryPolicyDN;
//
// Set the state to DS_DOWNLOADED.
//
pWirelessPolicyState->dwCurrentState = POLL_STATE_DS_DOWNLOADED; _WirelessDbg(TRC_STATE, "Policy State is DS Downloaded ");
//
// Compute the new polling interval.
//
pWirelessPolicyState->CurrentPollingInterval = pWirelessPolicyData->dwPollingInterval;
pWirelessPolicyState->DSIncarnationNumber = pWirelessPolicyData->dwWhenChanged;
pWirelessPolicyState->RegIncarnationNumber = 0;
gCurrentPollingInterval = pWirelessPolicyState->CurrentPollingInterval;
dwError = ERROR_SUCCESS; return (dwError);
error:
//
// Check pszDirectoryPolicyDN for non-NULL.
//
if (pszDirectoryPolicyDN) { FreeSPDStr(pszDirectoryPolicyDN); }
if (pWirelessPolicyObject) { FreeWirelessPolicyObject(pWirelessPolicyObject); }
if (pWirelessPolicyData) { FreeWirelessPolicyData(pWirelessPolicyData); }
return (dwError); }
// This Pre-requisite for this function is that Policy state is either CACHE or DS
DWORD CheckDeleteOldPolicy( DWORD *dwDelete ) { DWORD dwError = 0; HKEY hPolicyKey = NULL; DWORD dwSize = 0; DWORD dwSizeID = 0; DWORD dwSizeName = 0; DWORD dwToDelete = 1; PWIRELESS_POLICY_DATA pWirelessPolicyData = NULL; LPWSTR pszWirelessPolicyID = NULL; LPWSTR pszPolicyID = NULL; LPWSTR pszStringUuid = NULL; LPWSTR pszWirelessPolicyName = NULL; dwError = RegOpenKeyExW( HKEY_LOCAL_MACHINE, gpszWirelessDSPolicyKey, 0, KEY_ALL_ACCESS, &hPolicyKey );
BAIL_ON_WIN32_ERROR(dwError);
dwError = RegstoreQueryValue( hPolicyKey, L"WirelessID", REG_SZ, (LPBYTE *)&pszWirelessPolicyID, &dwSize );
BAIL_ON_WIN32_ERROR(dwError);
dwError = RegstoreQueryValue( hPolicyKey, L"DSWirelessPolicyName", REG_SZ, (LPBYTE *)&pszWirelessPolicyName, &dwSize );
BAIL_ON_WIN32_ERROR(dwError);
// account for the first {
pszPolicyID = pszWirelessPolicyID+ wcslen(L"{");
pWirelessPolicyData = gpWirelessPolicyState->pWirelessPolicyData;
dwError = UuidToString( &pWirelessPolicyData->PolicyIdentifier, &pszStringUuid ); BAIL_ON_WIN32_ERROR(dwError); dwSizeID = wcslen(pszStringUuid) * sizeof(WCHAR); dwSizeName = wcslen(pszWirelessPolicyName) * sizeof(WCHAR); if (!memcmp(pszPolicyID, pszStringUuid, dwSizeID) && (!memcmp(pszWirelessPolicyName, pWirelessPolicyData->pszWirelessName, dwSizeName))) { dwToDelete = 0; }
error:
*dwDelete = dwToDelete;
if (pszStringUuid) { RpcStringFree(&pszStringUuid); }
if (pszWirelessPolicyID) { FreePolMem(pszWirelessPolicyID); }
if (pszWirelessPolicyName) { FreePolMem(pszWirelessPolicyName); }
if (hPolicyKey) { CloseHandle(hPolicyKey); }
return (dwError); }
DWORD GetDirectoryPolicyDN( LPWSTR * ppszDirectoryPolicyDN ) { DWORD dwError = 0; HKEY hPolicyKey = NULL; LPWSTR pszWirelessPolicyName = NULL; DWORD dwSize = 0; LPWSTR pszPolicyDN = NULL; LPWSTR pszDirectoryPolicyDN = NULL;
*ppszDirectoryPolicyDN = NULL;
dwError = RegOpenKeyExW( HKEY_LOCAL_MACHINE, gpszWirelessDSPolicyKey, 0, KEY_ALL_ACCESS, &hPolicyKey ); BAIL_ON_WIN32_ERROR(dwError);
dwError = RegstoreQueryValue( hPolicyKey, L"DSWirelessPolicyPath", REG_SZ, (LPBYTE *)&pszWirelessPolicyName, &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 = pszWirelessPolicyName + wcslen(L"LDAP://");
pszDirectoryPolicyDN = AllocSPDStr(pszPolicyDN);
if (!pszDirectoryPolicyDN) { dwError = ERROR_OUTOFMEMORY; BAIL_ON_WIN32_ERROR(dwError); }
*ppszDirectoryPolicyDN = pszDirectoryPolicyDN;
error:
if (pszWirelessPolicyName) { FreeSPDStr(pszWirelessPolicyName); }
if (hPolicyKey) { CloseHandle(hPolicyKey); }
return (dwError); }
DWORD LoadDirectoryPolicy( LPWSTR pszDirectoryPolicyDN, PWIRELESS_POLICY_OBJECT * ppWirelessPolicyObject ) { DWORD dwError = 0; LPWSTR pszDefaultDirectory = NULL; HLDAP hLdapBindHandle = NULL; PWIRELESS_POLICY_OBJECT pWirelessPolicyObject = NULL;
dwError = ComputeDefaultDirectory( &pszDefaultDirectory ); BAIL_ON_WIN32_ERROR(dwError);
dwError = OpenDirectoryServerHandle( pszDefaultDirectory, 389, &hLdapBindHandle ); BAIL_ON_WIN32_ERROR(dwError);
dwError = ReadPolicyObjectFromDirectory( hLdapBindHandle, pszDirectoryPolicyDN, &pWirelessPolicyObject ); BAIL_ON_WIN32_ERROR(dwError);
*ppWirelessPolicyObject = pWirelessPolicyObject;
cleanup:
if (pszDefaultDirectory) { FreeSPDStr(pszDefaultDirectory); }
if (hLdapBindHandle) { CloseDirectoryServerHandle(hLdapBindHandle); }
return (dwError);
error:
*ppWirelessPolicyObject = NULL;
goto cleanup; }
DWORD PlumbCachePolicy( PWIRELESS_POLICY_STATE pWirelessPolicyState ) { DWORD dwError = 0; LPWSTR pszCachePolicyDN = NULL; PWIRELESS_POLICY_OBJECT pWirelessPolicyObject = NULL; PWIRELESS_POLICY_DATA pWirelessPolicyData = NULL; DWORD dwStoreType = WIRELESS_REGISTRY_PROVIDER; DWORD dwSlientErrorCode = 0; BOOL bIsActivePolicy = FALSE;
_WirelessDbg(TRC_NOTIF, "DBASE: Wireless Policy - Checking for Current Cached Policy ");
dwError = GetCachePolicyDN( &pszCachePolicyDN ); BAIL_ON_WIN32_ERROR(dwError); bIsActivePolicy = TRUE;
dwError = LoadCachePolicy( pszCachePolicyDN, &pWirelessPolicyObject ); BAIL_ON_WIN32_ERROR(dwError);
__try { dwError = UnmarshallWirelessPolicyObject( pWirelessPolicyObject, dwStoreType, &pWirelessPolicyData ); } __except(EXCEPTION_EXECUTE_HANDLER) { dwError = ERROR_INVALID_DATA; } BAIL_ON_WIN32_ERROR(dwError);
dwError = AddPolicyInformation( pWirelessPolicyData ); if (pWirelessPolicyState->pWirelessPolicyObject) { FreeWirelessPolicyObject(pWirelessPolicyState->pWirelessPolicyObject); }
if (pWirelessPolicyState->pWirelessPolicyData) { FreeWirelessPolicyData(pWirelessPolicyState->pWirelessPolicyData); }
if (pWirelessPolicyState->pszCachePolicyDN) { FreeSPDStr(pWirelessPolicyState->pszCachePolicyDN); }
pWirelessPolicyState->pWirelessPolicyObject = pWirelessPolicyObject;
pWirelessPolicyState->pWirelessPolicyData = pWirelessPolicyData;
pWirelessPolicyState->pszCachePolicyDN = pszCachePolicyDN;
//
// Set the state to CACHE_DOWNLOADED.
//
//
pWirelessPolicyState->dwCurrentState = POLL_STATE_CACHE_DOWNLOADED; _WirelessDbg(TRC_STATE, "Policy State :: Cache Downloaded ");
//
// Compute the new polling interval.
//
pWirelessPolicyState->CurrentPollingInterval = pWirelessPolicyData->dwPollingInterval;
pWirelessPolicyState->DSIncarnationNumber = 0;
pWirelessPolicyState->RegIncarnationNumber = pWirelessPolicyData->dwWhenChanged;
gCurrentPollingInterval = pWirelessPolicyState->CurrentPollingInterval;
dwError = ERROR_SUCCESS; return (dwError);
error:
//
// Check pszCachePolicyDN for non-NULL.
//
if (pszCachePolicyDN) { FreeSPDStr(pszCachePolicyDN); }
if (pWirelessPolicyObject) { FreeWirelessPolicyObject(pWirelessPolicyObject); }
if (pWirelessPolicyData) { FreeWirelessPolicyData(pWirelessPolicyData); }
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:
if (pszDirectoryPolicyDN) { FreeSPDStr(pszDirectoryPolicyDN); }
return (dwError); }
DWORD LoadCachePolicy( LPWSTR pszCachePolicyDN, PWIRELESS_POLICY_OBJECT * ppWirelessPolicyObject ) { DWORD dwError = 0; HKEY hRegistryKey = NULL; PWIRELESS_POLICY_OBJECT pWirelessPolicyObject = NULL;
dwError = OpenRegistryWIRELESSRootKey( NULL, gpszWirelessCachePolicyKey, &hRegistryKey ); BAIL_ON_WIN32_ERROR(dwError);
dwError = ReadPolicyObjectFromRegistry( hRegistryKey, pszCachePolicyDN, gpszWirelessCachePolicyKey, &pWirelessPolicyObject ); BAIL_ON_WIN32_ERROR(dwError);
*ppWirelessPolicyObject = pWirelessPolicyObject;
cleanup:
if (hRegistryKey) { CloseHandle(hRegistryKey); }
return (dwError);
error:
*ppWirelessPolicyObject = NULL;
goto cleanup; }
DWORD OnPolicyChanged( PWIRELESS_POLICY_STATE pWirelessPolicyState ) { DWORD dwError = 0; DWORD dwDelete = 1;
// If Initial Start - Start afresh
if (pWirelessPolicyState->dwCurrentState == POLL_STATE_INITIAL) { StartStatePollingManager(pWirelessPolicyState); return(dwError); }
//
// Check if the existing Policy Object has been changed.. Only in that case, delete the policy.
//
CheckDeleteOldPolicy(&dwDelete);
if (dwDelete) {
//
// Remove all the old policy that was plumbed.
//
dwError = DeletePolicyInformation( pWirelessPolicyState->pWirelessPolicyData ); ClearPolicyStateBlock( pWirelessPolicyState );
//
// Calling the Initializer again.
//
dwError = StartStatePollingManager( pWirelessPolicyState );
return (dwError);
}
// Policy Object is the same. Might be Modified Though. Call the On Policy Poll
_WirelessDbg(TRC_TRACK, "Policy Not New: Changing to Poll Function "); dwError = OnPolicyPoll(pWirelessPolicyState); return(dwError);
}
DWORD OnPolicyChangedEx( PWIRELESS_POLICY_STATE pWirelessPolicyState ) { DWORD dwError = 0;
// If Initial Start - Start afresh
if (pWirelessPolicyState->dwCurrentState == POLL_STATE_INITIAL) { StartStatePollingManager(pWirelessPolicyState); return(dwError); }
//
// Remove all the old policy that was plumbed.
//
_WirelessDbg(TRC_TRACK, "OnPolicyChangeEx called ");
dwError = DeletePolicyInformation( pWirelessPolicyState->pWirelessPolicyData ); ClearPolicyStateBlock( pWirelessPolicyState );
//
// Calling the Initializer again.
//
dwError = StartStatePollingManager( pWirelessPolicyState );
return (dwError);
}
DWORD DeletePolicyInformation( PWIRELESS_POLICY_DATA pWirelessPolicyData ) { DWORD dwError = 0;
if (!pWirelessPolicyData) { dwError = ERROR_SUCCESS; return (dwError); }
_WirelessDbg(TRC_NOTIF, "DBASE: Wireless Policy - Deleting Existing Policy for Zero Conf / 802.1x ");
_WirelessDbg(TRC_TRACK, "Deleting Policy Information"); _WirelessDbg(TRC_TRACK, "Deleted Policy is "); printPolicy(pWirelessPolicyData);
dwError = AddWZCPolicy(NULL); if (dwError) { _WirelessDbg(TRC_ERR, "Error in Deleting ZeroConfig Policy Error %d ", dwError); dwError = ERROR_SUCCESS; } else { _WirelessDbg(TRC_TRACK, "ZeroConf Policy Deletion Succesful "); }
dwError = AddEapolPolicy(NULL); if (dwError) { _WirelessDbg(TRC_ERR, "Error in Deleting EAPOL Policy with Error No. %d ", dwError); dwError = ERROR_SUCCESS; } else { _WirelessDbg(TRC_TRACK, "EAPOL Policy Deletion Succesful "); } return (dwError); }
VOID ClearPolicyStateBlock( PWIRELESS_POLICY_STATE pWirelessPolicyState ) { if (pWirelessPolicyState->pWirelessPolicyObject) { FreeWirelessPolicyObject( pWirelessPolicyState->pWirelessPolicyObject ); pWirelessPolicyState->pWirelessPolicyObject = NULL; }
if (pWirelessPolicyState->pWirelessPolicyData) { FreeWirelessPolicyData( pWirelessPolicyState->pWirelessPolicyData ); pWirelessPolicyState->pWirelessPolicyData = NULL; }
if (pWirelessPolicyState->pszDirectoryPolicyDN) { FreeSPDStr(pWirelessPolicyState->pszDirectoryPolicyDN); pWirelessPolicyState->pszDirectoryPolicyDN = NULL; }
pWirelessPolicyState->CurrentPollingInterval = gDefaultPollingInterval; pWirelessPolicyState->DefaultPollingInterval = gDefaultPollingInterval; pWirelessPolicyState->DSIncarnationNumber = 0; pWirelessPolicyState->RegIncarnationNumber = 0; pWirelessPolicyState->dwCurrentState = POLL_STATE_INITIAL; _WirelessDbg(TRC_STATE, "Policy State :: Initial State "); }
DWORD OnPolicyPoll( PWIRELESS_POLICY_STATE pWirelessPolicyState ) { DWORD dwError = 0;
_WirelessDbg(TRC_NOTIF, "DBASE: Wireless Policy - Polling for Policy Changes ");
switch (pWirelessPolicyState->dwCurrentState) {
case POLL_STATE_DS_DOWNLOADED: dwError = ProcessDirectoryPolicyPollState(pWirelessPolicyState); BAIL_ON_WIN32_ERROR(dwError); break;
case POLL_STATE_CACHE_DOWNLOADED: dwError = ProcessCachePolicyPollState(pWirelessPolicyState); BAIL_ON_WIN32_ERROR(dwError); break;
case POLL_STATE_INITIAL: dwError = OnPolicyChangedEx(pWirelessPolicyState); BAIL_ON_WIN32_ERROR(dwError); break;
}
//
// Set the new polling interval.
//
gCurrentPollingInterval = pWirelessPolicyState->CurrentPollingInterval;
return (dwError);
error:
//
// If in any of the three states other than the initial state,
// then there was an error in pulling down the incarnation number
// or the Wireless Policy from either the directory or the registry
// or there might not no longer be any Wireless policy assigned to
// this machine. So the polling state must reset back to the
// start state through a forced policy change. This is also
// necessary if the polling state is already in the initial state.
//
dwError = OnPolicyChangedEx( pWirelessPolicyState );
return (dwError); }
DWORD ProcessDirectoryPolicyPollState( PWIRELESS_POLICY_STATE pWirelessPolicyState ) { DWORD dwError = 0; DWORD dwIncarnationNumber = 0; PWIRELESS_POLICY_OBJECT pWirelessPolicyObject = NULL; PWIRELESS_POLICY_DATA pWirelessPolicyData = NULL; DWORD dwStoreType = WIRELESS_DIRECTORY_PROVIDER; DWORD dwSlientErrorCode = 0;
//
// The directory policy DN has to be the same, otherwise the
// Wireless extension in Winlogon would have already notified
// PA Store of the DS policy change.
//
dwError = GetDirectoryIncarnationNumber( pWirelessPolicyState->pszDirectoryPolicyDN, &dwIncarnationNumber ); if (dwError) { dwError = MigrateFromDSToCache(pWirelessPolicyState); BAIL_ON_WIN32_ERROR(dwError); return (ERROR_SUCCESS); }
if (dwIncarnationNumber == pWirelessPolicyState->DSIncarnationNumber) {
//
// The policy has not changed at all.
//
_WirelessDbg(TRC_NOTIF, "DBASE: Wireless Policy - Policy on DS has Not Changed "); return (ERROR_SUCCESS); }
//
// The incarnation number is different, so there's a need to
// update the policy.
//
dwError = LoadDirectoryPolicy( pWirelessPolicyState->pszDirectoryPolicyDN, &pWirelessPolicyObject ); if (dwError) { dwError = MigrateFromDSToCache(pWirelessPolicyState); BAIL_ON_WIN32_ERROR(dwError); return (ERROR_SUCCESS); }
__try { dwError = UnmarshallWirelessPolicyObject( pWirelessPolicyObject, dwStoreType, &pWirelessPolicyData ); } __except(EXCEPTION_EXECUTE_HANDLER) { dwError = ERROR_INVALID_DATA; }
if (dwError) { dwError = MigrateFromDSToCache(pWirelessPolicyState); BAIL_ON_WIN32_ERROR(dwError); if (pWirelessPolicyObject) { FreeWirelessPolicyObject(pWirelessPolicyObject); } return (ERROR_SUCCESS); }
dwError = UpdatePolicyInformation( pWirelessPolicyState->pWirelessPolicyData, pWirelessPolicyData );
if (pWirelessPolicyState->pWirelessPolicyObject) { FreeWirelessPolicyObject(pWirelessPolicyState->pWirelessPolicyObject); }
if (pWirelessPolicyState->pWirelessPolicyData) { FreeWirelessPolicyData(pWirelessPolicyState->pWirelessPolicyData); }
//
// Now delete the old cache and write the new one in.
//
DeleteRegistryCache();
CacheDirectorytoRegistry(pWirelessPolicyObject);
pWirelessPolicyState->pWirelessPolicyObject = pWirelessPolicyObject;
pWirelessPolicyState->pWirelessPolicyData = pWirelessPolicyData;
pWirelessPolicyState->CurrentPollingInterval = pWirelessPolicyData->dwPollingInterval;
pWirelessPolicyState->DSIncarnationNumber = dwIncarnationNumber;
//NotifyWirelessPolicyChange();
dwError = ERROR_SUCCESS; return (dwError);
error:
if (pWirelessPolicyObject) { FreeWirelessPolicyObject(pWirelessPolicyObject); }
if (pWirelessPolicyData) { FreeWirelessPolicyData(pWirelessPolicyData); }
return (dwError); }
DWORD GetDirectoryIncarnationNumber( LPWSTR pszWirelessPolicyDN, 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; DWORD dwWhenChanged = 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, pszWirelessPolicyDN, 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);
dwWhenChanged = _wtol(LDAPOBJECT_STRING((PLDAPOBJECT)strvalues));
*pdwIncarnationNumber = dwWhenChanged;
error:
if (pszDefaultDirectory) { FreeSPDStr(pszDefaultDirectory); }
if (hLdapBindHandle) { CloseDirectoryServerHandle(hLdapBindHandle); }
if (res) { LdapMsgFree(res); }
if (strvalues) { LdapValueFree(strvalues); }
return (dwError); }
DWORD MigrateFromDSToCache( PWIRELESS_POLICY_STATE pWirelessPolicyState ) { DWORD dwError = 0; LPWSTR pszCachePolicyDN = NULL;
dwError = GetCachePolicyDN( &pszCachePolicyDN ); BAIL_ON_WIN32_ERROR(dwError);
if (pWirelessPolicyState->pszDirectoryPolicyDN) { FreeSPDStr(pWirelessPolicyState->pszDirectoryPolicyDN); pWirelessPolicyState->pszDirectoryPolicyDN = NULL; }
pWirelessPolicyState->pszCachePolicyDN = pszCachePolicyDN;
//
// Keep pWirelessPolicyState->pWirelessPolicyData.
// Keep pWirelessPolicyState->pWirelessPolicyObject.
// Change the incarnation numbers.
//
pWirelessPolicyState->RegIncarnationNumber = pWirelessPolicyState->DSIncarnationNumber;
pWirelessPolicyState->DSIncarnationNumber = 0;
pWirelessPolicyState->dwCurrentState = POLL_STATE_CACHE_DOWNLOADED; _WirelessDbg(TRC_STATE, "Policy State :: Cache Downloaded "); _WirelessDbg(TRC_NOTIF, "DBASE: Wireless Policy - Error Syncing Policy with DC, Using Cached Policy "); //
// Keep pWirelessPolicyState->CurrentPollingInterval.
// Keep pWirelessPolicyState->DefaultPollingInterval.
//
gCurrentPollingInterval = pWirelessPolicyState->CurrentPollingInterval;
error:
return (dwError); }
DWORD ProcessCachePolicyPollState( PWIRELESS_POLICY_STATE pWirelessPolicyState ) { DWORD dwError = 0; LPWSTR pszDirectoryPolicyDN = NULL; DWORD dwIncarnationNumber = 0; LPWSTR pszCachePolicyDN = NULL;
dwError = GetDirectoryPolicyDN( &pszDirectoryPolicyDN );
if (!dwError) {
dwError = GetDirectoryIncarnationNumber( pszDirectoryPolicyDN, &dwIncarnationNumber );
if (!dwError) {
dwError = CopyPolicyDSToFQRegString( pszDirectoryPolicyDN, &pszCachePolicyDN );
if (!dwError) {
if (!_wcsicmp(pWirelessPolicyState->pszCachePolicyDN, pszCachePolicyDN)) {
if (pWirelessPolicyState->RegIncarnationNumber == dwIncarnationNumber) { dwError = MigrateFromCacheToDS(pWirelessPolicyState); } else { dwError = UpdateFromCacheToDS(pWirelessPolicyState); }
if (dwError) { dwError = OnPolicyChangedEx(pWirelessPolicyState); }
} else {
dwError = OnPolicyChangedEx(pWirelessPolicyState);
}
}
}
}
if (pszDirectoryPolicyDN) { FreeSPDStr(pszDirectoryPolicyDN); }
if (pszCachePolicyDN) { FreeSPDStr(pszCachePolicyDN); }
return (ERROR_SUCCESS); }
DWORD MigrateFromCacheToDS( PWIRELESS_POLICY_STATE pWirelessPolicyState ) { DWORD dwError = 0; LPWSTR pszDirectoryPolicyDN = NULL;
dwError = GetDirectoryPolicyDN( &pszDirectoryPolicyDN ); BAIL_ON_WIN32_ERROR(dwError);
if (pWirelessPolicyState->pszCachePolicyDN) { FreeSPDStr(pWirelessPolicyState->pszCachePolicyDN); pWirelessPolicyState->pszCachePolicyDN = NULL; }
pWirelessPolicyState->pszDirectoryPolicyDN = pszDirectoryPolicyDN;
//
// Keep pWirelessPolicyState->pWirelessPolicyData.
// Keep pWirelessPolicyState->pWirelessPolicyObject.
// Change the incarnation numbers.
//
pWirelessPolicyState->DSIncarnationNumber = pWirelessPolicyState->RegIncarnationNumber;
pWirelessPolicyState->RegIncarnationNumber = 0;
pWirelessPolicyState->dwCurrentState = POLL_STATE_DS_DOWNLOADED; _WirelessDbg(TRC_NOTIF, "DBASE: Wireless Policy - Policy in sync with DC "); _WirelessDbg(TRC_STATE, "Policy State :: DS Downloaded "); //
// Keep pWirelessPolicyState->CurrentPollingInterval.
// Keep pWirelessPolicyState->DefaultPollingInterval.
//
gCurrentPollingInterval = pWirelessPolicyState->CurrentPollingInterval;
error:
return (dwError); }
DWORD UpdateFromCacheToDS( PWIRELESS_POLICY_STATE pWirelessPolicyState ) { DWORD dwError = 0; LPWSTR pszDirectoryPolicyDN = NULL; PWIRELESS_POLICY_OBJECT pWirelessPolicyObject = NULL; PWIRELESS_POLICY_DATA pWirelessPolicyData = NULL; DWORD dwStoreType = WIRELESS_DIRECTORY_PROVIDER; DWORD dwSlientErrorCode = 0;
dwError = GetDirectoryPolicyDN( &pszDirectoryPolicyDN ); BAIL_ON_WIN32_ERROR(dwError);
dwError = LoadDirectoryPolicy( pszDirectoryPolicyDN, &pWirelessPolicyObject ); BAIL_ON_WIN32_ERROR(dwError);
__try { dwError = UnmarshallWirelessPolicyObject( pWirelessPolicyObject, dwStoreType, &pWirelessPolicyData ); } __except(EXCEPTION_EXECUTE_HANDLER) { dwError = ERROR_INVALID_DATA; } BAIL_ON_WIN32_ERROR(dwError);
_WirelessDbg(TRC_NOTIF, "DBASE: Wireless Policy - Policy in Sync with DC ");
dwError = UpdatePolicyInformation( pWirelessPolicyState->pWirelessPolicyData, pWirelessPolicyData );
if (pWirelessPolicyState->pWirelessPolicyObject) { FreeWirelessPolicyObject(pWirelessPolicyState->pWirelessPolicyObject); }
if (pWirelessPolicyState->pWirelessPolicyData) { FreeWirelessPolicyData(pWirelessPolicyState->pWirelessPolicyData); }
if (pWirelessPolicyState->pszCachePolicyDN) { FreeSPDStr(pWirelessPolicyState->pszCachePolicyDN); }
//
// Now delete the old cache and write the new one in.
//
DeleteRegistryCache();
CacheDirectorytoRegistry(pWirelessPolicyObject);
pWirelessPolicyState->pWirelessPolicyObject = pWirelessPolicyObject;
pWirelessPolicyState->pWirelessPolicyData = pWirelessPolicyData;
pWirelessPolicyState->pszDirectoryPolicyDN = pszDirectoryPolicyDN;
//
// Set the state to DS-DOWNLOADED.
//
pWirelessPolicyState->dwCurrentState = POLL_STATE_DS_DOWNLOADED; _WirelessDbg(TRC_STATE, "Policy State :: DS Downloaded "); _WirelessDbg(TRC_NOTIF, "DBASE: Wireless Policy Synced with DS "); //
// Compute the new polling interval.
//
pWirelessPolicyState->CurrentPollingInterval = pWirelessPolicyData->dwPollingInterval;
pWirelessPolicyState->DSIncarnationNumber = pWirelessPolicyData->dwWhenChanged;
pWirelessPolicyState->RegIncarnationNumber = 0;
gCurrentPollingInterval = pWirelessPolicyState->CurrentPollingInterval;
//NotifyWirelessPolicyChange();
dwError = ERROR_SUCCESS; return (dwError);
error:
if (pszDirectoryPolicyDN) { FreeSPDStr(pszDirectoryPolicyDN); }
if (pWirelessPolicyObject) { FreeWirelessPolicyObject(pWirelessPolicyObject); }
if (pWirelessPolicyData) { FreeWirelessPolicyData(pWirelessPolicyData); }
return (dwError); }
DWORD GetRegistryIncarnationNumber( LPWSTR pszWirelessPolicyDN, 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, pszWirelessPolicyDN, 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:
if (hRegKey) { CloseHandle(hRegKey); }
return(dwError); }
DWORD UpdatePolicyInformation( PWIRELESS_POLICY_DATA pOldWirelessPolicyData, PWIRELESS_POLICY_DATA pNewWirelessPolicyData ) { DWORD dwError = 0; _WirelessDbg(TRC_TRACK, "Updating Policy Information"); _WirelessDbg(TRC_TRACK, "Old Policy is "); printPolicy(pOldWirelessPolicyData); _WirelessDbg(TRC_TRACK, "New Policy is "); printPolicy(pNewWirelessPolicyData);
_WirelessDbg(TRC_NOTIF, "DBASE: Wireless Policy - Updating Policy for Zero Conf / 802.1x "); dwError = AddWZCPolicy(pNewWirelessPolicyData); if (dwError) { _WirelessDbg(TRC_ERR, "Error in Updating the Zero Conf Policy Error Code %d ", dwError); dwError = ERROR_SUCCESS; } else { _WirelessDbg(TRC_TRACK, "Policy Update for Zero Conf Successful "); }
dwError = AddEapolPolicy(pNewWirelessPolicyData); if (dwError) { _WirelessDbg(TRC_ERR, "Error in Applying EAPOL Policy Error Code %d ", dwError); dwError = ERROR_SUCCESS; } else { _WirelessDbg(TRC_TRACK, "Policy Update for EAPOL Successful "); } return (dwError); }
DWORD AddPolicyInformation( PWIRELESS_POLICY_DATA pWirelessPolicyData ) { DWORD dwError = 0;
_WirelessDbg(TRC_TRACK, "Adding Policy ");
_WirelessDbg(TRC_NOTIF, "DBASE: Wireless Policy - Adding Policy for Zero Conf / 802.1x "); // Find the diff here.
// Compare that Guids are same and the dwChanged are same..
// Then look for other differences
dwError = AddWZCPolicy(pWirelessPolicyData); if (dwError) { _WirelessDbg(TRC_ERR, "Error in ADDing Zero Conf the Policy Error Code %d ", dwError); dwError = ERROR_SUCCESS; } else { _WirelessDbg(TRC_TRACK, "ZeroConf Policy Addition Succesful "); }
dwError = AddEapolPolicy(pWirelessPolicyData); if (dwError) { _WirelessDbg(TRC_ERR, "Error in Adding EAPOL Policy Error Code %d ", dwError); dwError = ERROR_SUCCESS; } else { _WirelessDbg(TRC_TRACK, "EAPOL Policy Addition Succesful "); } return (dwError); }
DWORD AddWZCPolicy(PWIRELESS_POLICY_DATA pWirelessPolicyData) {
DWORD dwError = 0; DWORD i=0; DWORD dwNumPSSettings = 0; DWORD dwCtlFlags = 0;
PINTF_ENTRY pIntfEntry = NULL; PWZC_802_11_CONFIG_LIST pWZCConfigList = NULL; DWORD dwWZCConfigListSize = 0; PWZC_WLAN_CONFIG pWZCConfig = NULL; PWIRELESS_PS_DATA *ppWirelessPSData = NULL; DWORD dwInFlags = 0; DWORD dwOutFlags = 0; DWORD dwSSIDSize = 0; WCHAR pszTempSSID[33]; BYTE pszOutSSID[33];
_WirelessDbg(TRC_TRACK, "Adding Wireless Zero Config Informaiton "); printPolicy(pWirelessPolicyData);
pIntfEntry = (PINTF_ENTRY) AllocSPDMem(sizeof(INTF_ENTRY)); if (!pIntfEntry) { dwError = GetLastError(); }
if (!pWirelessPolicyData) {
dwInFlags |= INTF_ALL_FLAGS; dwInFlags |= INTF_PREFLIST; pIntfEntry->rdStSSIDList.dwDataLen = 0; pIntfEntry->rdStSSIDList.pData = NULL; dwError = LstSetInterface(dwInFlags, pIntfEntry, &dwOutFlags); return (dwError); }
if (pWirelessPolicyData->dwDisableZeroConf == 0) { dwCtlFlags |= INTFCTL_ENABLED; }
if (pWirelessPolicyData->dwConnectToNonPreferredNtwks) { dwCtlFlags |= INTFCTL_FALLBACK; }
switch (pWirelessPolicyData->dwNetworkToAccess) {
case WIRELESS_ACCESS_NETWORK_ANY :
dwCtlFlags |= INTFCTL_CM_MASK & Ndis802_11AutoUnknown; break;
case WIRELESS_ACCESS_NETWORK_AP :
dwCtlFlags |= INTFCTL_CM_MASK & Ndis802_11Infrastructure; break;
case WIRELESS_ACCESS_NETWORK_ADHOC:
dwCtlFlags |= INTFCTL_CM_MASK & Ndis802_11IBSS; break;
default: dwCtlFlags |= INTFCTL_CM_MASK & Ndis802_11AutoUnknown; break;
}
dwCtlFlags |= INTFCTL_POLICY; dwCtlFlags |= INTFCTL_VOLATILE;
dwNumPSSettings = pWirelessPolicyData->dwNumPreferredSettings; if (dwNumPSSettings != 0) { dwWZCConfigListSize = (dwNumPSSettings-1) * sizeof(WZC_WLAN_CONFIG) + sizeof(WZC_802_11_CONFIG_LIST); } else { dwWZCConfigListSize = sizeof(WZC_802_11_CONFIG_LIST); } pWZCConfigList = (PWZC_802_11_CONFIG_LIST) AllocSPDMem(dwWZCConfigListSize);
if (!pWZCConfigList) { dwError = GetLastError(); BAIL_ON_WIN32_ERROR(dwError); }
pWZCConfig = (PWZC_WLAN_CONFIG) &(pWZCConfigList->Config); ppWirelessPSData = pWirelessPolicyData->ppWirelessPSData; for (i = 0; i < dwNumPSSettings; ++i) {
// If the SSID is 32 bit in length, we need to null terminate it so that the following call succeeds.
// SSid cannont take more than 32 bytes.. it becomes an issue with 32 byte SSID ..as it cannot null
// terminate it. So copy to a temp variable and then copy 32 bytes.
wcsncpy(pszTempSSID, ppWirelessPSData[i]->pszWirelessSSID, 32); pszTempSSID[32] = L'\0';
dwSSIDSize = WideCharToMultiByte ( CP_ACP, 0, pszTempSSID, //ppWirelessPSData[i]->pszWirelessSSID,
-1, pszOutSSID, MAX_SSID_LEN +1 , NULL, NULL); if (dwSSIDSize == 0) { dwError = GetLastError(); } BAIL_ON_WIN32_ERROR(dwError);
memcpy(pWZCConfig[i].Ssid.Ssid, pszOutSSID, 32);
pWZCConfig[i].Ssid.SsidLength = dwSSIDSize -1;
if (ppWirelessPSData[i]->dwNetworkType == WIRELESS_NETWORK_TYPE_ADHOC) { pWZCConfig[i].InfrastructureMode = Ndis802_11IBSS; } else { pWZCConfig[i].InfrastructureMode = Ndis802_11Infrastructure; }
if (ppWirelessPSData[i]->dwNetworkAuthentication) { pWZCConfig[i].AuthenticationMode = Ndis802_11AuthModeShared;
} else { pWZCConfig[i].AuthenticationMode = Ndis802_11AuthModeOpen; }
if (ppWirelessPSData[i]->dwWepEnabled) { pWZCConfig[i].Privacy = 1; } else { pWZCConfig[i].Privacy = 0; }
pWZCConfig[i].dwCtlFlags = 0; if (ppWirelessPSData[i]->dwAutomaticKeyProvision) {
pWZCConfig[i].dwCtlFlags &= ~WZCCTL_WEPK_PRESENT; pWZCConfig[i].KeyLength = 0;
} else {
pWZCConfig[i].dwCtlFlags |= WZCCTL_WEPK_PRESENT; pWZCConfig[i].KeyLength = 5; } pWZCConfig[i].dwCtlFlags |= WZCCTL_VOLATILE; pWZCConfig[i].dwCtlFlags |= WZCCTL_POLICY;
pWZCConfig[i].Length = sizeof(WZC_WLAN_CONFIG); }
pWZCConfigList->NumberOfItems = dwNumPSSettings; pWZCConfigList->Index = dwNumPSSettings;
pIntfEntry->dwCtlFlags = dwCtlFlags; pIntfEntry->rdStSSIDList.dwDataLen = dwWZCConfigListSize; pIntfEntry->rdStSSIDList.pData = (LPBYTE) pWZCConfigList;
dwInFlags |= INTF_ALL_FLAGS; dwInFlags |= INTF_PREFLIST;
dwError = LstSetInterface(dwInFlags, pIntfEntry, &dwOutFlags); error:
if (pWZCConfigList) FreeSPDMem(pWZCConfigList);
if (pIntfEntry) FreeSPDMem(pIntfEntry);
return (dwError); }
DWORD AddEapolPolicy(PWIRELESS_POLICY_DATA pWirelessPolicyData) { DWORD dwError = 0; PEAPOL_POLICY_LIST pEapolPolicyList = NULL;
dwError = ConvertWirelessPolicyDataToEAPOLList( pWirelessPolicyData, &pEapolPolicyList ); BAIL_ON_WIN32_ERROR(dwError);
_WirelessDbg(TRC_TRACK, "Calling into EAPOL API "); dwError = ElPolicyChange(pEapolPolicyList);
_WirelessDbg(TRC_TRACK, "Call to EAPOL API returned with code %d ", dwError);
if (pEapolPolicyList) { FreeEAPOLList(pEapolPolicyList); }
error:
return(dwError); }
|