Code/Resource
Windows Develop
Linux-Unix program
Internet-Socket-Network
Web Server
Browser Client
Ftp Server
Ftp Client
Browser Plugins
Proxy Server
Email Server
Email Client
WEB Mail
Firewall-Security
Telnet Server
Telnet Client
ICQ-IM-Chat
Search Engine
Sniffer Package capture
Remote Control
xml-soap-webservice
P2P
WEB(ASP,PHP,...)
TCP/IP Stack
SNMP
Grid Computing
SilverLight
DNS
Cluster Service
Network Security
Communication-Mobile
Game Program
Editor
Multimedia program
Graph program
Compiler program
Compress-Decompress algrithms
Crypt_Decrypt algrithms
Mathimatics-Numerical algorithms
MultiLanguage
Disk/Storage
Java Develop
assembly language
Applications
Other systems
Database system
Embeded-SCM Develop
FlashMX/Flex
source in ebook
Delphi VCL
OS Develop
MiddleWare
MPI
MacOS develop
LabView
ELanguage
Software/Tools
E-Books
Artical/Document
gpt.c
Package: win2ksrc.rar [view]
Upload User: caisha3
Upload Date: 2013-09-21
Package Size: 208739k
Code Size: 326k
Category:
Windows Develop
Development Platform:
Visual C++
- //*************************************************************
- //
- // Group Policy Support
- //
- // Microsoft Confidential
- // Copyright (c) Microsoft Corporation 1997-1998
- // All rights reserved
- //
- //*************************************************************
- #include "uenv.h"
- #define GPO_LPARAM_FLAG_DELETE 0x00000001
- //
- // Structures
- //
- typedef struct _GPEXT {
- LPTSTR lpDisplayName; // Display name
- LPTSTR lpKeyName; // Extension name
- LPTSTR lpDllName; // Dll name
- LPSTR lpFunctionName; // Entry point name
- HANDLE hInstance; // Handle to dll
- PFNPROCESSGROUPPOLICY pEntryPoint; // Entry point for ProcessGPO
- DWORD dwNoMachPolicy; // Mach policy setting
- DWORD dwNoUserPolicy; // User policy setting
- DWORD dwNoSlowLink; // Slow link setting
- DWORD dwNoBackgroundPolicy; // Background policy setting
- DWORD dwNoGPOChanges; // GPO changes setting
- DWORD dwUserLocalSetting; // Per user per machine setting
- DWORD dwRequireRegistry; // RequireSuccReg setting
- DWORD dwEnableAsynch; // Enable asynchronous processing setting
- DWORD dwLinkTransition; // Link speed transition setting
- DWORD dwMaxChangesInterval; // Max interval (mins) for which NoGpoChanges is adhered to
- BOOL bRegistryExt; // Is this the psuedo reg extension ?
- BOOL bSkipped; // Should processing be skipped for this extension ?
- BOOL bHistoryProcessing; // Is processing needed to clean up cached Gpos ?
- DWORD dwSlowLinkPrev; // Slow link when policy applied previously ?
- GUID guid; // Guid of extension
- struct _GPEXT *pNext; // Singly linked list pointer
- } GPEXT, *LPGPEXT;
- typedef struct _EXTLIST {
- GUID guid; // Extension guid
- struct _EXTLIST *pNext; // Singly linked list pointer
- } EXTLIST, *LPEXTLIST;
- typedef struct _EXTFILTERLIST {
- PGROUP_POLICY_OBJECT lpGPO; // GPO
- LPEXTLIST lpExtList; // List of extension guids that apply to lpGPO
- struct _EXTFILTERLIST *pNext; // Singly linked list pointer
- } EXTFILTERLIST, *LPEXTFILTERLIST;
- typedef struct _GPOINFO {
- DWORD dwFlags;
- INT iMachineRole;
- HANDLE hToken;
- HANDLE hEvent;
- HKEY hKeyRoot;
- BOOL bXferToExtList; // Has the ownership been transferred from lpGPOList to lpExtFilterList ?
- LPEXTFILTERLIST lpExtFilterList; // List of extensions to be filtered, cardinality is same as GetGPOList's list
- PGROUP_POLICY_OBJECT lpGPOList; // Filtered GPO List, can vary from one extension to next
- LPTSTR lpwszSidUser; // Sid of user in string form
- HANDLE hTriggerEvent;
- HANDLE hNotifyEvent;
- HANDLE hCritSection;
- LPGPEXT lpExtensions;
- BOOL bMemChanged; // Has security group membership has changed ?
- BOOL bUserLocalMemChanged; // Has membership changed on per user local basis ?
- BOOL bSidChanged; // Has the Sid changed since the last policy run?
- PFNSTATUSMESSAGECALLBACK pStatusCallback;
- } GPOINFO, *LPGPOINFO;
- typedef struct _GPINFOHANDLE
- {
- LPGPOINFO pGPOInfo;
- } GPINFOHANDLE, *LPGPINFOHANDLE;
- typedef struct _DNENTRY {
- LPTSTR pwszDN; // Distinguished name
- union {
- PGROUP_POLICY_OBJECT pDeferredGPO; // GPO corresponding to this DN
- struct _DNENTRY * pDeferredOU; // OU correspdonding to this DN
- };
- PLDAPMessage pOUMsg; // Message for evaluating deferred OU
- GPO_LINK gpoLink; // Type of GPO
- struct _DNENTRY * pNext; // Singly linked list pointer
- } DNENTRY;
- typedef struct _LDAPQUERY {
- LPTSTR pwszDomain; // Domain of subtree search
- LPTSTR pwszFilter; // Ldap filter for search
- DWORD cbAllocLen; // Allocated size of pwszFilter in bytes
- DWORD cbLen; // Size of pwszFilter currently used in bytes
- PLDAP pLdapHandle; // Ldap bind handle
- BOOL bOwnLdapHandle; // Does this struct own pLdapHandle ?
- PLDAPMessage pMessage; // Ldap message handle
- DNENTRY * pDnEntry; // Distinguished name entry
- struct _LDAPQUERY * pNext; // Singly linked list pointer
- } LDAPQUERY;
- //
- // Verison number for the registry file format
- //
- #define REGISTRY_FILE_VERSION 1
- //
- // File signature
- //
- #define REGFILE_SIGNATURE 0x67655250
- //
- // Default refresh rate (minutes)
- //
- // Client machines will refresh every 90 minutes
- // Domain controllers will refresh every 5 minutes
- //
- #define GP_DEFAULT_REFRESH_RATE 90
- #define GP_DEFAULT_REFRESH_RATE_DC 5
- //
- // Default refresh rate max offset
- //
- // To prevent many clients from querying policy at the exact same
- // time, a random amount is added to the refresh rate. In the
- // default case, a number between 0 and 30 will be added to
- // 180 to determine when the next background refresh will occur
- //
- #define GP_DEFAULT_REFRESH_RATE_OFFSET 30
- #define GP_DEFAULT_REFRESH_RATE_OFFSET_DC 0
- //
- // Max keyname size
- //
- #define MAX_KEYNAME_SIZE 2048
- #define MAX_VALUENAME_SIZE 512
- //
- // Max time to wait for the network to start (in ms)
- //
- #define MAX_WAIT_TIME 120000
- //
- // Extension registry path
- //
- #define GP_EXTENSIONS TEXT("Software\Microsoft\Windows NT\CurrentVersion\Winlogon\GPExtensions")
- //
- // Path for extension preference policies
- //
- #define GP_EXTENSIONS_POLICIES TEXT("Software\Policies\Microsoft\Windows\Group Policy\%s")
- //
- // Group Policy Object option flags
- //
- // Note, this was taken from sdkincgpedit.h
- //
- #define GPO_OPTION_DISABLE_USER 0x00000001 // The user portion of this GPO is disabled
- #define GPO_OPTION_DISABLE_MACHINE 0x00000002 // The machine portion of this GPO is disabled
- //
- // Generic access mappings
- //
- const
- ACCESS_MASK
- GENERIC_READ_MAPPING = ((STANDARD_RIGHTS_READ) |
- (ACTRL_DS_LIST) |
- (ACTRL_DS_READ_PROP) |
- (ACTRL_DS_LIST_OBJECT));
- const
- ACCESS_MASK
- GENERIC_EXECUTE_MAPPING = ((STANDARD_RIGHTS_EXECUTE) |
- (ACTRL_DS_LIST));
- const
- ACCESS_MASK
- GENERIC_WRITE_MAPPING = ((STANDARD_RIGHTS_WRITE) |
- (ACTRL_DS_SELF) |
- (ACTRL_DS_WRITE_PROP));
- const
- ACCESS_MASK
- GENERIC_ALL_MAPPING = ((STANDARD_RIGHTS_REQUIRED) |
- (ACTRL_DS_CREATE_CHILD) |
- (ACTRL_DS_DELETE_CHILD) |
- (ACTRL_DS_DELETE_TREE) |
- (ACTRL_DS_READ_PROP) |
- (ACTRL_DS_WRITE_PROP) |
- (ACTRL_DS_LIST) |
- (ACTRL_DS_LIST_OBJECT) |
- (ACTRL_DS_CONTROL_ACCESS) |
- (ACTRL_DS_SELF));
- //
- // DS Object class types
- //
- TCHAR szDSClassAny[] = TEXT("(objectClass=*)");
- TCHAR szDSClassGPO[] = TEXT("groupPolicyContainer");
- TCHAR szDSClassSite[] = TEXT("site");
- TCHAR szDSClassDomain[] = TEXT("domainDNS");
- TCHAR szDSClassOU[] = TEXT("organizationalUnit");
- TCHAR szObjectClass[] = TEXT("objectClass");
- //
- // Extension name properties
- //
- #define GPO_MACHEXTENSION_NAMES L"gPCMachineExtensionNames"
- #define GPO_USEREXTENSION_NAMES L"gPCUserExtensionNames"
- #define GPO_FUNCTIONALITY_VERSION L"gPCFunctionalityVersion"
- TCHAR wszKerberos[] = TEXT("Kerberos");
- #define POLICY_GUID_PATH TEXT("Software\Microsoft\Windows NT\CurrentVersion\PolicyGuid")
- //
- // Global flags for Gpo shutdown processing. These are accessed outside
- // the lock because its value is either 0 or 1. Even if there is a race,
- // all it means is that shutdown will start one iteration later.
- //
- BOOL g_bStopMachGPOProcessing = FALSE;
- BOOL g_bStopUserGPOProcessing = FALSE;
- //
- // Critical section for handling concurrent, asynchronous completion
- //
- CRITICAL_SECTION g_GPOCS;
- //
- // Global pointers for maintaining asynchronous completion context
- //
- LPGPINFOHANDLE g_pMachGPInfo = 0;
- LPGPINFOHANDLE g_pUserGPInfo = 0;
- //
- // Status UI critical section, callback, and proto-types
- //
- CRITICAL_SECTION g_StatusCallbackCS;
- PFNSTATUSMESSAGECALLBACK g_pStatusMessageCallback = NULL;
- DWORD UserPolicyCallback (BOOL bVerbose, LPWSTR lpMessage);
- DWORD MachinePolicyCallback (BOOL bVerbose, LPWSTR lpMessage);
- //
- // Function proto-types
- //
- DWORD WINAPI GPOThread (LPGPOINFO lpGPOInfo);
- BOOL ProcessGPOs (LPGPOINFO lpGPOInfo);
- DWORD WINAPI PolicyChangedThread (BOOL bMachine);
- BOOL ResetPolicies (LPGPOINFO lpGPOInfo, LPTSTR lpArchive);
- BOOL SetupGPOFilter (LPGPOINFO lpGPOInfo );
- void FilterGPOs( LPGPEXT lpExt, LPGPOINFO lpGPOInfo );
- void FreeLists( LPGPOINFO lpGPOInfo );
- void FreeExtList(LPEXTLIST pExtList );
- BOOL CheckGPOs (LPGPEXT lpExt, LPGPOINFO lpGPOInfo, DWORD dwTime, BOOL *pbProcessGPOs,
- BOOL *pbNoChanges, PGROUP_POLICY_OBJECT *ppDeletedGPOList);
- BOOL CheckForChangedSid( LPGPOINFO lpGPOInfo );
- BOOL CheckForSkippedExtensions( LPGPOINFO lpGPOInfo );
- BOOL ReadGPExtensions( LPGPOINFO lpGPOInfo );
- BOOL LoadGPExtension (LPGPEXT lpExt);
- BOOL UnloadGPExtensions (LPGPOINFO lpGPOInfo);
- BOOL WriteStatus( TCHAR *lpExtName, LPGPOINFO lpGPOInfo, LPTSTR lpwszSidUser, DWORD dwStatus, DWORD dwTime, DWORD dwSlowLink );
- BOOL ReadStatus( TCHAR *lpExtName, LPGPOINFO lpGPOInfo, LPTSTR lpwszSidUser, DWORD *pdwStatus, DWORD *pdwTime, DWORD *pdwSlowlink );
- DWORD ProcessGPOList (LPGPEXT lpExt, LPGPOINFO lpGPOInfo, PGROUP_POLICY_OBJECT pDeletedGPOList,
- PGROUP_POLICY_OBJECT pChangedGPOList, BOOL bNoChanges,
- ASYNCCOMPLETIONHANDLE pAsyncHandle );
- BOOL ProcessGPORegistryPolicy (LPGPOINFO lpGPOInfo, PGROUP_POLICY_OBJECT pChangedGPOList);
- BOOL SaveGPOList (TCHAR *pszExtName, LPGPOINFO lpGPOInfo,
- HKEY hKeyRootMach, LPTSTR lpwszSidUser, BOOL bShadow, PGROUP_POLICY_OBJECT lpGPOList);
- BOOL AddGPO (PGROUP_POLICY_OBJECT * lpGPOList, DWORD dwOptions, DWORD dwVersion,
- LPTSTR lpDSPath, LPTSTR lpFileSysPath, LPTSTR lpDisplayName,
- LPTSTR lpGPOName, LPTSTR lpExtensions, GPO_LINK GPOLink, LPTSTR lpLink, LPARAM lParam, BOOL bFront,
- BOOL bBlock, BOOL bVerbose);
- BOOL RefreshDisplay (LPGPOINFO lpGPOInfo);
- DWORD IsSlowLink (HKEY hKeyRoot, LPTSTR lpDCAddress, BOOL *bSlow);
- BOOL GetGPOInfo (DWORD dwFlags, LPTSTR lpHostName, LPTSTR lpDNName,
- LPCTSTR lpComputerName, PGROUP_POLICY_OBJECT *lpGPOList,
- PNETAPI32_API pNetAPI32, BOOL bMachineTokenOk);
- void WINAPI ShutdownGPOProcessing( BOOL bMachine );
- void DebugPrintGPOList( LPGPOINFO lpGPOInfo );
- typedef BOOL (*PFNREGFILECALLBACK)(LPGPOINFO lpGPOInfo, LPTSTR lpKeyName,
- LPTSTR lpValueName, DWORD dwType,
- DWORD dwDataLength, LPBYTE lpData);
- BOOL ParseRegistryFile (LPGPOINFO lpGPOInfo, LPTSTR lpRegistry,
- PFNREGFILECALLBACK pfnRegFileCallback,
- HANDLE hArchive);
- BOOL ExtensionHasPerUserLocalSetting( LPTSTR pszExtension, HKEY hKeyRoot );
- void CheckGroupMembership( LPGPOINFO lpGPOInfo, HANDLE hToken, BOOL *pbMemChanged, BOOL *pbUserLocalMemChanged );
- BOOL ReadMembershipList( LPGPOINFO lpGPOInfo, LPTSTR lpwszSidUser, PTOKEN_GROUPS pGroups );
- void SaveMembershipList( LPGPOINFO lpGPOInfo, LPTSTR lpwszSidUser, PTOKEN_GROUPS pGroups );
- BOOL GroupInList( LPTSTR lpSid, PTOKEN_GROUPS pGroups );
- DWORD GetCurTime();
- DWORD GetDomainControllerInfo( PNETAPI32_API pNetAPI32, LPTSTR szDomainName,
- ULONG ulFlags, HKEY hKeyRoot, PDOMAIN_CONTROLLER_INFO* ppInfo,
- BOOL* pfSlow );
- PLDAP GetMachineDomainDS( PNETAPI32_API pNetApi32, PLDAP_API pLdapApi );
- HANDLE GetMachineToken();
- NTSTATUS CallDFS(LPWSTR lpDomainName, LPWSTR lpDCName);
- //*************************************************************
- //
- // ApplyGroupPolicy()
- //
- // Purpose: Processes group policy
- //
- // Parameters: dwFlags - Processing flags
- // hToken - Token (user or machine)
- // hEvent - Termination event for background thread
- // hKeyRoot - Root registry key (HKCU or HKLM)
- // pStatusCallback - Callback function for display status messages
- //
- // Return: Thread handle if successful
- // NULL if an error occurs
- //
- //*************************************************************
- HANDLE WINAPI ApplyGroupPolicy (DWORD dwFlags, HANDLE hToken, HANDLE hEvent,
- HKEY hKeyRoot, PFNSTATUSMESSAGECALLBACK pStatusCallback)
- {
- HANDLE hThread = NULL;
- DWORD dwThreadID;
- LPGPOINFO lpGPOInfo = NULL;
- SECURITY_DESCRIPTOR sd;
- SECURITY_ATTRIBUTES sa;
- //
- // Verbose output
- //
- DebugMsg((DM_VERBOSE, TEXT("ApplyGroupPolicy: Entering. Flags = %x"), dwFlags));
- //
- // Save the status UI callback function
- //
- EnterCriticalSection (&g_StatusCallbackCS);
- g_pStatusMessageCallback = pStatusCallback;
- LeaveCriticalSection (&g_StatusCallbackCS);
- //
- // Allocate a GPOInfo structure to work with.
- //
- lpGPOInfo = (LPGPOINFO) LocalAlloc (LPTR, sizeof(GPOINFO));
- if (!lpGPOInfo) {
- DebugMsg((DM_WARNING, TEXT("ApplyGroupPolicy: Failed to alloc lpGPOInfo (%d)."),
- GetLastError()));
- LogEvent (TRUE, IDS_FAILED_ALLOCATION, GetLastError());
- goto Exit;
- }
- lpGPOInfo->dwFlags = dwFlags;
- lpGPOInfo->hToken = hToken;
- lpGPOInfo->hEvent = hEvent;
- lpGPOInfo->hKeyRoot = hKeyRoot;
- if (dwFlags & GP_MACHINE) {
- lpGPOInfo->pStatusCallback = MachinePolicyCallback;
- } else {
- lpGPOInfo->pStatusCallback = UserPolicyCallback;
- }
- //
- // Create an event so other processes can trigger policy
- // to be applied immediately
- //
- InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION);
- SetSecurityDescriptorDacl (
- &sd,
- TRUE, // Dacl present
- NULL, // NULL Dacl
- FALSE // Not defaulted
- );
- sa.lpSecurityDescriptor = &sd;
- sa.bInheritHandle = FALSE;
- sa.nLength = sizeof(sa);
- lpGPOInfo->hTriggerEvent = CreateEvent (&sa, FALSE, FALSE,
- (dwFlags & GP_MACHINE) ?
- MACHINE_POLICY_REFRESH_EVENT : USER_POLICY_REFRESH_EVENT);
- //
- // Create the notification event
- //
- lpGPOInfo->hNotifyEvent = CreateEvent (&sa, TRUE, FALSE,
- (dwFlags & GP_MACHINE) ?
- MACHINE_POLICY_APPLIED_EVENT : USER_POLICY_APPLIED_EVENT);
- //
- // Initilialize shutdown gpo processing support
- //
- if ( dwFlags & GP_MACHINE )
- g_bStopMachGPOProcessing = FALSE;
- else
- g_bStopUserGPOProcessing = FALSE;
- //
- // Process the GPOs
- //
- ProcessGPOs(lpGPOInfo);
- //
- // If requested, create a background thread to keep updating
- // the profile from the gpos
- //
- if (lpGPOInfo->dwFlags & GP_BACKGROUND_REFRESH) {
- //
- // Create a thread which sleeps and processes GPOs
- //
- hThread = CreateThread (NULL, 0, (LPTHREAD_START_ROUTINE) GPOThread,
- (LPVOID) lpGPOInfo, CREATE_SUSPENDED, &dwThreadID);
- if (!hThread) {
- DebugMsg((DM_WARNING, TEXT("ApplyGroupPolicy: Failed to create background thread (%d)."),
- GetLastError()));
- goto Exit;
- }
- SetThreadPriority (hThread, THREAD_PRIORITY_IDLE);
- lpGPOInfo->pStatusCallback = NULL;
- ResumeThread (hThread);
- //
- // Reset the status UI callback function
- //
- EnterCriticalSection (&g_StatusCallbackCS);
- g_pStatusMessageCallback = NULL;
- LeaveCriticalSection (&g_StatusCallbackCS);
- DebugMsg((DM_VERBOSE, TEXT("ApplyGroupPolicy: Leaving successfully.")));
- return hThread;
- }
- DebugMsg((DM_VERBOSE, TEXT("ApplyGroupPolicy: Background refresh not requested. Leaving successfully.")));
- hThread = (HANDLE) 1;
- Exit:
- EnterCriticalSection( &g_GPOCS );
- if ( dwFlags & GP_MACHINE ) {
- if ( g_pMachGPInfo )
- LocalFree( g_pMachGPInfo );
- g_pMachGPInfo = 0;
- } else {
- if ( g_pUserGPInfo )
- LocalFree( g_pUserGPInfo );
- g_pUserGPInfo = 0;
- }
- LeaveCriticalSection( &g_GPOCS );
- if (lpGPOInfo) {
- if (lpGPOInfo->hTriggerEvent) {
- CloseHandle (lpGPOInfo->hTriggerEvent);
- }
- if (lpGPOInfo->hNotifyEvent) {
- CloseHandle (lpGPOInfo->hNotifyEvent);
- }
- if (lpGPOInfo->lpwszSidUser)
- DeleteSidString( lpGPOInfo->lpwszSidUser );
- LocalFree (lpGPOInfo);
- }
- //
- // Reset the status UI callback function
- //
- EnterCriticalSection (&g_StatusCallbackCS);
- g_pStatusMessageCallback = NULL;
- LeaveCriticalSection (&g_StatusCallbackCS);
- return hThread;
- }
- //*************************************************************
- //
- // GPOThread()
- //
- // Purpose: Background thread for GPO processing.
- //
- // Parameters: lpGPOInfo - GPO info
- //
- // Return: 0
- //
- //*************************************************************
- DWORD WINAPI GPOThread (LPGPOINFO lpGPOInfo)
- {
- HINSTANCE hInst;
- HKEY hKey;
- HANDLE hHandles[3] = {NULL, NULL, NULL};
- DWORD dwType, dwSize, dwResult;
- DWORD dwTimeout, dwOffset;
- BOOL bSetBkGndFlag;
- TCHAR szEventName[60];
- LARGE_INTEGER DueTime;
- hInst = LoadLibrary (TEXT("userenv.dll"));
- hHandles[0] = lpGPOInfo->hEvent;
- hHandles[1] = lpGPOInfo->hTriggerEvent;
- while (TRUE) {
- //
- // Initialize
- //
- if (lpGPOInfo->dwFlags & GP_MACHINE) {
- if (lpGPOInfo->iMachineRole == 3) {
- dwTimeout = GP_DEFAULT_REFRESH_RATE_DC;
- dwOffset = GP_DEFAULT_REFRESH_RATE_OFFSET_DC;
- } else {
- dwTimeout = GP_DEFAULT_REFRESH_RATE;
- dwOffset = GP_DEFAULT_REFRESH_RATE_OFFSET;
- }
- } else {
- dwTimeout = GP_DEFAULT_REFRESH_RATE;
- dwOffset = GP_DEFAULT_REFRESH_RATE_OFFSET;
- }
- //
- // Query for the refresh timer value and max offset
- //
- if (RegOpenKeyEx (lpGPOInfo->hKeyRoot,
- SYSTEM_POLICIES_KEY,
- 0, KEY_READ, &hKey) == ERROR_SUCCESS) {
- if ((lpGPOInfo->iMachineRole == 3) && (lpGPOInfo->dwFlags & GP_MACHINE)) {
- dwSize = sizeof(dwTimeout);
- RegQueryValueEx (hKey,
- TEXT("GroupPolicyRefreshTimeDC"),
- NULL,
- &dwType,
- (LPBYTE) &dwTimeout,
- &dwSize);
- dwSize = sizeof(dwOffset);
- RegQueryValueEx (hKey,
- TEXT("GroupPolicyRefreshTimeOffsetDC"),
- NULL,
- &dwType,
- (LPBYTE) &dwOffset,
- &dwSize);
- } else {
- dwSize = sizeof(dwTimeout);
- RegQueryValueEx (hKey,
- TEXT("GroupPolicyRefreshTime"),
- NULL,
- &dwType,
- (LPBYTE) &dwTimeout,
- &dwSize);
- dwSize = sizeof(dwOffset);
- RegQueryValueEx (hKey,
- TEXT("GroupPolicyRefreshTimeOffset"),
- NULL,
- &dwType,
- (LPBYTE) &dwOffset,
- &dwSize);
- }
- RegCloseKey (hKey);
- }
- //
- // Limit the timeout to once every 64800 minutes (45 days)
- //
- if (dwTimeout >= 64800) {
- dwTimeout = 64800;
- }
- //
- // Convert seconds to milliseconds
- //
- dwTimeout = dwTimeout * 60 * 1000;
- //
- // Limit the offset to 1440 minutes (24 hours)
- //
- if (dwOffset >= 1440) {
- dwOffset = 1440;
- }
- //
- // Special case 0 milliseconds to be 7 seconds
- //
- if (dwTimeout == 0) {
- dwTimeout = 7000;
- } else {
- //
- // If there is an offset, pick a random number
- // from 0 to dwOffset and then add it to the timeout
- //
- if (dwOffset) {
- dwOffset = GetTickCount() % dwOffset;
- dwOffset = dwOffset * 60 * 1000;
- dwTimeout += dwOffset;
- }
- }
- //
- // Setup the timer
- //
- if (dwTimeout >= 60000) {
- DebugMsg((DM_VERBOSE, TEXT("GPOThread: Next refresh will happen in %d minutes"),
- ((dwTimeout / 1000) / 60)));
- } else {
- DebugMsg((DM_VERBOSE, TEXT("GPOThread: Next refresh will happen in %d seconds"),
- (dwTimeout / 1000)));
- }
- wsprintf (szEventName, TEXT("userenv: refresh timer for %d:%d"),
- GetCurrentProcessId(), GetCurrentThreadId());
- hHandles[2] = CreateWaitableTimer (NULL, TRUE, szEventName);
- if (hHandles[2] == NULL) {
- DebugMsg((DM_WARNING, TEXT("GPOThread: CreateWaitableTimer failed with error %d"),
- GetLastError()));
- LogEvent (TRUE, IDS_FAILED_TIMER, TEXT("CreateWaitableTimer"), GetLastError());
- break;
- }
- DueTime.QuadPart = UInt32x32To64(10000, dwTimeout);
- DueTime.QuadPart *= -1;
- if (!SetWaitableTimer (hHandles[2], &DueTime, 0, NULL, 0, FALSE)) {
- DebugMsg((DM_WARNING, TEXT("GPOThread: Failed to set timer with error %d"),
- GetLastError()));
- LogEvent (TRUE, IDS_FAILED_TIMER, TEXT("SetWaitableTimer"), GetLastError());
- break;
- }
- dwResult = WaitForMultipleObjects (3, hHandles, FALSE, INFINITE);
- if ( (dwResult - WAIT_OBJECT_0) == 0 )
- {
- //
- // for machine policy thread, this is a shutdown.
- // for user policy thread, this is a logoff.
- //
- break;
- }
- else if ( dwResult == WAIT_FAILED )
- {
- LogEvent (TRUE, IDS_FAILED_TIMER, TEXT("WaitForMultipleObjects"), GetLastError());
- break;
- }
- //
- // Check if we should set the background flag. We offer this
- // option for the test team's automation tests. They need to
- // simulate logon / boot policy without actually logging on or
- // booting the machine.
- //
- bSetBkGndFlag = TRUE;
- if (RegOpenKeyEx (HKEY_LOCAL_MACHINE,
- WINLOGON_KEY,
- 0, KEY_READ, &hKey) == ERROR_SUCCESS) {
- dwSize = sizeof(bSetBkGndFlag);
- RegQueryValueEx (hKey,
- TEXT("SetGroupPolicyBackgroundFlag"),
- NULL,
- &dwType,
- (LPBYTE) &bSetBkGndFlag,
- &dwSize);
- RegCloseKey (hKey);
- }
- lpGPOInfo->dwFlags &= ~GP_REGPOLICY_CPANEL;
- lpGPOInfo->dwFlags &= ~GP_SLOW_LINK;
- lpGPOInfo->dwFlags &= ~GP_VERBOSE;
- lpGPOInfo->dwFlags &= ~GP_BACKGROUND_THREAD;
- //
- // Set the background thread flag so components known
- // when they are being called from the background thread
- // vs the main thread.
- //
- if (bSetBkGndFlag) {
- lpGPOInfo->dwFlags |= GP_BACKGROUND_THREAD;
- }
- ProcessGPOs(lpGPOInfo);
- CloseHandle (hHandles[2]);
- hHandles[2] = NULL;
- }
- //
- // Cleanup
- //
- if (hHandles[2]) {
- CloseHandle (hHandles[2]);
- }
- if (lpGPOInfo->hTriggerEvent) {
- CloseHandle (lpGPOInfo->hTriggerEvent);
- }
- if (lpGPOInfo->hNotifyEvent) {
- CloseHandle (lpGPOInfo->hNotifyEvent);
- }
- EnterCriticalSection( &g_GPOCS );
- if ( lpGPOInfo->dwFlags & GP_MACHINE ) {
- if ( g_pMachGPInfo )
- LocalFree( g_pMachGPInfo );
- g_pMachGPInfo = 0;
- } else {
- if ( g_pUserGPInfo )
- LocalFree( g_pUserGPInfo );
- g_pUserGPInfo = 0;
- }
- LeaveCriticalSection( &g_GPOCS );
- if (lpGPOInfo->lpwszSidUser)
- DeleteSidString( lpGPOInfo->lpwszSidUser );
- LocalFree (lpGPOInfo);
- FreeLibraryAndExitThread (hInst, 0);
- return 0;
- }
- //*************************************************************
- //
- // GPOExceptionFilter()
- //
- // Purpose: Exception filter when procssing GPO extensions
- //
- // Parameters: pExceptionPtrs - Pointer to exception pointer
- //
- // Returns: EXCEPTION_EXECUTE_HANDLER
- //
- //*************************************************************
- LONG GPOExceptionFilter( PEXCEPTION_POINTERS pExceptionPtrs )
- {
- PEXCEPTION_RECORD pExr = pExceptionPtrs->ExceptionRecord;
- PCONTEXT pCxr = pExceptionPtrs->ContextRecord;
- DebugMsg(( DM_WARNING, L"GPOExceptionFilter: Caught exception 0x%x, exr = 0x%x, cxr = 0x%xn",
- pExr->ExceptionCode, pExr, pCxr ));
- DmAssert( ! L"Caught unhandled exception when processing group policy extension" );
- return EXCEPTION_EXECUTE_HANDLER;
- }
- //*************************************************************
- //
- // ProcessGPOs()
- //
- // Purpose: Processes GPOs
- //
- // Parameters: lpGPOInfo - GPO information
- //
- // Return: TRUE if successful
- // FALSE if an error occurs
- //
- //*************************************************************
- BOOL ProcessGPOs (LPGPOINFO lpGPOInfo)
- {
- BOOL bRetVal = FALSE;
- DWORD dwThreadID;
- HANDLE hThread;
- DWORD dwType, dwSize, dwResult;
- HKEY hKey;
- BOOL bResult;
- PDOMAIN_CONTROLLER_INFO pDCI = NULL;
- LPTSTR lpDomain = NULL;
- LPTSTR lpName = NULL;
- LPTSTR lpDomainDN = NULL;
- LPTSTR lpComputerName;
- PGROUP_POLICY_OBJECT lpGPO = NULL;
- PGROUP_POLICY_OBJECT lpGPOTemp;
- BOOL bAllSkipped;
- LPGPEXT lpExt;
- LPGPINFOHANDLE pGPHandle = NULL;
- ASYNCCOMPLETIONHANDLE pAsyncHandle = 0;
- HANDLE hOldToken;
- UINT uExtensionCount = 0;
- PNETAPI32_API pNetAPI32;
- DWORD dwUserPolicyMode = 0;
- DWORD dwCurrentTime = 0;
- INT iRole;
- BOOL bSlow;
- //
- // Allow debugging level to be changed dynamically between
- // policy refreshes.
- //
- InitDebugSupport( FALSE );
- //
- // Debug spew
- //
- if (lpGPOInfo->dwFlags & GP_MACHINE) {
- DebugMsg(( DM_VERBOSE, TEXT("ProcessGPOs:")));
- DebugMsg(( DM_VERBOSE, TEXT("ProcessGPOs:")));
- DebugMsg(( DM_VERBOSE, TEXT("ProcessGPOs: Starting computer Group Policy processing...")));
- DebugMsg(( DM_VERBOSE, TEXT("ProcessGPOs:")));
- DebugMsg(( DM_VERBOSE, TEXT("ProcessGPOs:")));
- } else {
- DebugMsg(( DM_VERBOSE, TEXT("ProcessGPOs:")));
- DebugMsg(( DM_VERBOSE, TEXT("ProcessGPOs:")));
- DebugMsg(( DM_VERBOSE, TEXT("ProcessGPOs: Starting user Group Policy processing...")));
- DebugMsg(( DM_VERBOSE, TEXT("ProcessGPOs:")));
- DebugMsg(( DM_VERBOSE, TEXT("ProcessGPOs:")));
- }
- //
- // Check if we should be verbose to the event log
- //
- if (CheckForVerbosePolicy()) {
- lpGPOInfo->dwFlags |= GP_VERBOSE;
- DebugMsg((DM_VERBOSE, TEXT("ProcessGPOs: Verbose output to eventlog requested.")));
- }
- if (lpGPOInfo->dwFlags & GP_VERBOSE) {
- if (lpGPOInfo->dwFlags & GP_MACHINE) {
- LogEvent (FALSE, IDS_START_MACHINE_POLICY);
- } else {
- LogEvent (FALSE, IDS_START_USER_POLICY);
- }
- }
- //
- // Claim the critical section
- //
- lpGPOInfo->hCritSection = EnterCriticalPolicySection((lpGPOInfo->dwFlags & GP_MACHINE));
- if (!lpGPOInfo->hCritSection) {
- DebugMsg((DM_WARNING, TEXT("ProcessGPOs: Failed to claim the policy critical section with %d."),
- GetLastError()));
- LogEvent (TRUE, IDS_FAILED_CRITICAL_SECTION, GetLastError());
- goto Exit;
- }
- //
- // Set the security on the Group Policy registry key
- //
- if (!MakeRegKeySecure((lpGPOInfo->dwFlags & GP_MACHINE) ? NULL : lpGPOInfo->hToken,
- lpGPOInfo->hKeyRoot,
- TEXT("Software\Microsoft\Windows\CurrentVersion\Group Policy"))) {
- DebugMsg((DM_WARNING, TEXT("ProcessGPOs: Failed to secure reg key.")));
- }
- //
- // Load netapi32
- //
- pNetAPI32 = LoadNetAPI32();
- if (!pNetAPI32) {
- DebugMsg((DM_WARNING, TEXT("ProcessGPOs: Failed to load netapi32 with %d."),
- GetLastError()));
- LogEvent (TRUE, IDS_FAILED_NETAPI32, GetLastError());
- goto Exit;
- }
- //
- // Get the role of this computer
- //
- if (!GetMachineRole (&iRole)) {
- DebugMsg((DM_WARNING, TEXT("ProcessGPOs: Failed to get the role of the computer.")));
- LogEvent (TRUE, IDS_FAILED_ROLE);
- goto Exit;
- }
- lpGPOInfo->iMachineRole = iRole;
- DebugMsg((DM_VERBOSE, TEXT("ProcessGPOs: Machine role is %d."), iRole));
- if (lpGPOInfo->dwFlags & GP_VERBOSE) {
- switch (iRole) {
- case 0:
- LogEvent (FALSE, IDS_ROLE_STANDALONE);
- break;
- case 1:
- LogEvent (FALSE, IDS_ROLE_DOWNLEVEL_DOMAIN);
- break;
- default:
- LogEvent (FALSE, IDS_ROLE_DS_DOMAIN);
- break;
- }
- }
- //
- // If we are going to apply policy from the DS, query for the user's
- // DN name, domain name, etc
- //
- if (lpGPOInfo->dwFlags & GP_APPLY_DS_POLICY) {
- //
- // Query for the user's domain name
- //
- if (!ImpersonateUser(lpGPOInfo->hToken, &hOldToken)) {
- DebugMsg((DM_WARNING, TEXT("ProcessGPOs: Failed to impersonate user")));
- goto Exit;
- }
- lpDomain = MyGetDomainName ();
- RevertToUser(&hOldToken);
- if (!lpDomain) {
- dwResult = GetLastError();
- DebugMsg((DM_WARNING, TEXT("ProcessGPOs: MyGetDomainName failed with %d."),
- dwResult));
- goto Exit;
- }
- //
- // Query for the DS server name
- //
- dwResult = GetDomainControllerInfo( pNetAPI32,
- lpDomain,
- DS_DIRECTORY_SERVICE_REQUIRED | DS_IS_FLAT_NAME
- | DS_RETURN_DNS_NAME |
- ((lpGPOInfo->dwFlags & GP_BACKGROUND_THREAD) ? DS_BACKGROUND_ONLY : 0),
- lpGPOInfo->hKeyRoot,
- &pDCI,
- &bSlow );
- if (dwResult != ERROR_SUCCESS) {
- if ((dwResult == ERROR_BAD_NETPATH) ||
- (dwResult == ERROR_NETWORK_UNREACHABLE) ||
- (dwResult == ERROR_NO_SUCH_DOMAIN)) {
- //
- // couldn't find DC. Nothing more we can do, abort
- //
- DebugMsg((DM_VERBOSE, TEXT("ProcessGPOs: The DC for domain %s is not available"),
- lpDomain));
- } else {
- DebugMsg((DM_WARNING, TEXT("ProcessGPOs: DSGetDCName failed with %d."),
- dwResult));
- LogEvent (TRUE, IDS_FAILED_DSNAME, dwResult);
- }
- goto Exit;
- } else {
- //
- // success, slow link?
- //
- if (bSlow) {
- lpGPOInfo->dwFlags |= GP_SLOW_LINK;
- if (lpGPOInfo->dwFlags & GP_VERBOSE) {
- LogEvent (FALSE, IDS_SLOWLINK);
- }
- DebugMsg((DM_VERBOSE, TEXT("ProcessGPOs: A slow link was detected.")));
- }
- }
- //
- // Get the user's DN name
- //
- if (!ImpersonateUser(lpGPOInfo->hToken, &hOldToken)) {
- DebugMsg((DM_WARNING, TEXT("ProcessGPOs: Failed to impersonate user")));
- goto Exit;
- }
- lpName = MyGetUserName (NameFullyQualifiedDN);
- RevertToUser(&hOldToken);
- if (!lpName) {
- dwResult = GetLastError();
- DebugMsg((DM_WARNING, TEXT("ProcessGPOs: MyGetUserName failed with %d."),
- dwResult));
- LogEvent (TRUE, IDS_FAILED_USERNAME, dwResult);
- goto Exit;
- }
- lpDomainDN = pDCI->DomainName;
- if (lpGPOInfo->dwFlags & GP_VERBOSE) {
- LogEvent (FALSE, IDS_USERNAME, lpName);
- LogEvent (FALSE, IDS_DOMAINNAME, lpDomain);
- LogEvent (FALSE, IDS_DCNAME, pDCI->DomainControllerName);
- }
- DebugMsg((DM_VERBOSE, TEXT("ProcessGPOs: User name is: %s, Domain name is: %s"),
- lpName, lpDomain));
- DebugMsg((DM_VERBOSE, TEXT("ProcessGPOs: Domain controller is: %s Domain DN is %s"),
- pDCI->DomainControllerName, lpDomainDN));
- if (!(lpGPOInfo->dwFlags & GP_MACHINE)) {
- CallDFS(pDCI->DomainName, pDCI->DomainControllerName);
- }
- //
- // Save the DC name in the registry for future reference
- //
- if (RegOpenKeyEx (lpGPOInfo->hKeyRoot,
- TEXT("Software\Microsoft\Windows\CurrentVersion\Group Policy\History"),
- 0, KEY_WRITE, &hKey) == ERROR_SUCCESS) {
- dwSize = (lstrlen(pDCI->DomainControllerName) + 1) * sizeof(TCHAR);
- RegSetValueEx (hKey, TEXT("DCName"), 0, REG_SZ,
- (LPBYTE) pDCI->DomainControllerName, dwSize);
- RegCloseKey (hKey);
- }
- }
- //
- // Read the group policy extensions from the registry
- //
- if ( !ReadGPExtensions( lpGPOInfo ) ) {
- DebugMsg((DM_WARNING, TEXT("ProcessGPOs: ReadGPExtensions failed.")));
- LogEvent (TRUE, IDS_READ_EXT_FAILED );
- goto Exit;
- }
- //
- // Get the user policy mode if appropriate
- //
- if (!(lpGPOInfo->dwFlags & GP_MACHINE)) {
- if (RegOpenKeyEx (HKEY_LOCAL_MACHINE,
- SYSTEM_POLICIES_KEY,
- 0, KEY_READ, &hKey) == ERROR_SUCCESS) {
- dwSize = sizeof(dwUserPolicyMode);
- RegQueryValueEx (hKey,
- TEXT("UserPolicyMode"),
- NULL,
- &dwType,
- (LPBYTE) &dwUserPolicyMode,
- &dwSize);
- RegCloseKey (hKey);
- }
- if (dwUserPolicyMode > 0) {
- if (!(lpGPOInfo->dwFlags & GP_APPLY_DS_POLICY)) {
- DebugMsg((DM_WARNING, TEXT("ProcessGPOs: Loopback is not allowed for downlevel or local user accounts. Loopback will be disabled.")));
- LogEvent (FALSE, IDS_LOOPBACK_DISABLED1);
- dwUserPolicyMode = 0;
- }
- if (dwUserPolicyMode > 0) {
- if (lpGPOInfo->iMachineRole < 2) {
- DebugMsg((DM_WARNING, TEXT("ProcessGPOs: Loopback is not allowed on machines joined to a downlevel domain or running standalone. Loopback will be disabled.")));
- LogEvent (TRUE, IDS_LOOPBACK_DISABLED2);
- dwUserPolicyMode = 0;
- }
- }
- }
- }
- //
- // Check if user's sid has changed
- //
- if ( !CheckForChangedSid( lpGPOInfo ) ) {
- DebugMsg((DM_WARNING, TEXT("ProcessGPOs: Check for changed sid failed")));
- goto Exit;
- }
- if (!ImpersonateUser(lpGPOInfo->hToken, &hOldToken)) {
- DebugMsg((DM_WARNING, TEXT("ProcessGPOs: Failed to impersonate user")));
- LogEvent (TRUE, IDS_FAILED_IMPERSONATE, GetLastError() );
- goto Exit;
- }
- //
- // Check if any extensions can be skipped. If there is ever a case where
- // all extensions can be skipped, then exit successfully right after this check.
- // Currently RegistryExtension is always run unless there are no GPO changes,
- // but the GPO changes check is done much later.
- //
- if ( !CheckForSkippedExtensions( lpGPOInfo ) ) {
- DebugMsg((DM_WARNING, TEXT("ProcessGPOs: Checking extensions for skipping failed")));
- //
- // LogEvent() is called by CheckForSkippedExtensions()
- //
- goto Exit;
- }
- //
- // Query for the GPO list based upon the mode
- //
- // 0 is normal
- // 1 is merge. Merge user list + machine list
- // 2 is replace. use machine list instead of user list
- //
- if (dwUserPolicyMode == 0) {
- DebugMsg((DM_VERBOSE, TEXT("ProcessGPOs: Calling GetGPOInfo for normal policy mode")));
- bResult = GetGPOInfo ((lpGPOInfo->dwFlags & GP_MACHINE) ? GPO_LIST_FLAG_MACHINE : 0,
- lpDomainDN, lpName, NULL, &lpGPOInfo->lpGPOList, pNetAPI32, TRUE);
- if (!bResult) {
- DebugMsg((DM_WARNING, TEXT("ProcessGPOs: GetGPOInfo failed.")));
- LogEvent (TRUE, IDS_GPO_QUERY_FAILED);
- }
- } else if (dwUserPolicyMode == 2) {
- DebugMsg((DM_VERBOSE, TEXT("ProcessGPOs: Calling GetGPOInfo for replacement user policy mode")));
- lpComputerName = MyGetComputerName (NameFullyQualifiedDN);
- if (lpComputerName) {
- PDOMAIN_CONTROLLER_INFO pDCInfo;
- DebugMsg((DM_VERBOSE, TEXT("ProcessGPOs: Using computer name %s for query."), lpComputerName));
- dwResult = pNetAPI32->pfnDsGetDcName( 0,
- 0,
- 0,
- 0,
- DS_DIRECTORY_SERVICE_REQUIRED |
- ((lpGPOInfo->dwFlags & GP_BACKGROUND_THREAD) ? DS_BACKGROUND_ONLY : 0),
- &pDCInfo);
- if ( dwResult == 0 )
- {
- bResult = GetGPOInfo (0, pDCInfo->DomainName, lpComputerName, NULL,
- &lpGPOInfo->lpGPOList, pNetAPI32, FALSE);
- if (!bResult) {
- DebugMsg((DM_WARNING, TEXT("ProcessGPOs: GetGPOInfo failed.")));
- LogEvent (TRUE, IDS_GPO_QUERY_FAILED);
- }
- pNetAPI32->pfnNetApiBufferFree( pDCInfo );
- }
- else
- {
- DebugMsg((DM_WARNING, TEXT("ProcessGPOs: Failed to get the computer domain name with %d"),
- GetLastError()));
- LogEvent (TRUE, IDS_NO_MACHINE_DOMAIN, lpComputerName, GetLastError() );
- bResult = FALSE;
- }
- LocalFree (lpComputerName);
- } else {
- DebugMsg((DM_WARNING, TEXT("ProcessGPOs: Failed to get the computer name with %d"),
- GetLastError()));
- LogEvent (TRUE, IDS_FAILED_MACHINENAME, GetLastError());
- bResult = FALSE;
- }
- } else {
- DebugMsg((DM_VERBOSE, TEXT("ProcessGPOs: Calling GetGPOInfo for merging user policy mode")));
- lpComputerName = MyGetComputerName (NameFullyQualifiedDN);
- if (lpComputerName) {
- lpGPOInfo->lpGPOList = NULL;
- bResult = GetGPOInfo (0, lpDomainDN, lpName, NULL,
- &lpGPOInfo->lpGPOList, pNetAPI32, FALSE);
- if (bResult) {
- PDOMAIN_CONTROLLER_INFO pDCInfo;
- DebugMsg((DM_VERBOSE, TEXT("ProcessGPOs: Using computer name %s for query."), lpComputerName));
- lpGPO = NULL;
- dwResult = pNetAPI32->pfnDsGetDcName( 0,
- 0,
- 0,
- 0,
- DS_DIRECTORY_SERVICE_REQUIRED |
- ((lpGPOInfo->dwFlags & GP_BACKGROUND_THREAD) ? DS_BACKGROUND_ONLY : 0),
- &pDCInfo);
- if ( dwResult == 0 )
- {
- bResult = GetGPOInfo (0, pDCInfo->DomainName, lpComputerName, NULL,
- &lpGPO, pNetAPI32, FALSE);
- if (bResult) {
- if (lpGPOInfo->lpGPOList && lpGPO) {
- DebugMsg((DM_VERBOSE, TEXT("ProcessGPOs: Both user and machine lists are defined. Merging them together.")));
- //
- // Need to merge the lists together
- //
- lpGPOTemp = lpGPOInfo->lpGPOList;
- while (lpGPOTemp->pNext) {
- lpGPOTemp = lpGPOTemp->pNext;
- }
- lpGPOTemp->pNext = lpGPO;
- } else if (!lpGPOInfo->lpGPOList && lpGPO) {
- DebugMsg((DM_VERBOSE, TEXT("ProcessGPOs: Only machine list is defined.")));
- lpGPOInfo->lpGPOList = lpGPO;
- } else {
- DebugMsg((DM_VERBOSE, TEXT("ProcessGPOs: Only user list is defined.")));
- }
- } else {
- DebugMsg((DM_WARNING, TEXT("ProcessGPOs: GetGPOInfo failed for computer name.")));
- LogEvent (TRUE, IDS_GPO_QUERY_FAILED);
- }
- pNetAPI32->pfnNetApiBufferFree( pDCInfo );
- }
- else
- {
- DebugMsg((DM_WARNING, TEXT("ProcessGPOs: Failed to get the computer domain name with %d"),
- GetLastError()));
- LogEvent (TRUE, IDS_NO_MACHINE_DOMAIN, lpComputerName, GetLastError());
- bResult = FALSE;
- }
- } else {
- DebugMsg((DM_WARNING, TEXT("ProcessGPOs: GetGPOInfo failed for user name.")));
- LogEvent (TRUE, IDS_GPO_QUERY_FAILED);
- }
- LocalFree (lpComputerName);
- } else {
- DebugMsg((DM_WARNING, TEXT("ProcessGPOs: Failed to get the computer name with %d"),
- GetLastError()));
- LogEvent (TRUE, IDS_FAILED_MACHINENAME, GetLastError());
- bResult = FALSE;
- }
- }
- if (!RevertToUser(&hOldToken)) {
- DebugMsg((DM_WARNING, TEXT("ProcessGPOs: Failed to revert to self")));
- }
- if (!bResult) {
- goto Exit;
- }
- bResult = SetupGPOFilter( lpGPOInfo );
- if (!bResult) {
- DebugMsg((DM_WARNING, TEXT("ProcessGPOs: SetupGPOFilter failed.")));
- LogEvent (TRUE, IDS_SETUP_GPOFILTER_FAILED);
- goto Exit;
- }
- //
- // Need to check if the security group membership has changed the first time around
- //
- if ( !(lpGPOInfo->dwFlags & GP_BACKGROUND_THREAD) ) {
- if ((lpGPOInfo->dwFlags & GP_MACHINE) && (lpGPOInfo->dwFlags & GP_APPLY_DS_POLICY)) {
- HANDLE hLocToken=NULL;
- //
- // if it is machine policy processing, get the machine token so that we can check
- // security group membership using the right token. This causes GetMachineToken to be called twice
- // but moving it to the beginning requires too much change.
- //
- hLocToken = GetMachineToken();
- if (hLocToken) {
- CheckGroupMembership( lpGPOInfo, hLocToken, &lpGPOInfo->bMemChanged, &lpGPOInfo->bUserLocalMemChanged);
- CloseHandle(hLocToken);
- }
- else {
- DebugMsg((DM_WARNING, TEXT("ProcessGPOs: Failed to get the machine token with %d"), GetLastError()));
- goto Exit;
- }
- }
- else {
- //
- // In the user case just use the token passed in
- //
- CheckGroupMembership( lpGPOInfo, lpGPOInfo->hToken, &lpGPOInfo->bMemChanged, &lpGPOInfo->bUserLocalMemChanged);
- }
- }
- DebugPrintGPOList( lpGPOInfo );
- //================================================================
- //
- // Now walk through the list of extensions
- //
- //================================================================
- EnterCriticalSection( &g_GPOCS );
- pGPHandle = (LPGPINFOHANDLE) LocalAlloc( LPTR, sizeof(GPINFOHANDLE) );
- //
- // Continue even if pGPHandle is 0, because all it means is that async completions (if any)
- // will fail. Remove old asynch completion context.
- //
- if ( pGPHandle )
- pGPHandle->pGPOInfo = lpGPOInfo;
- if ( lpGPOInfo->dwFlags & GP_MACHINE ) {
- if ( g_pMachGPInfo )
- LocalFree( g_pMachGPInfo );
- g_pMachGPInfo = pGPHandle;
- } else {
- if ( g_pUserGPInfo )
- LocalFree( g_pUserGPInfo );
- g_pUserGPInfo = pGPHandle;
- }
- LeaveCriticalSection( &g_GPOCS );
- pAsyncHandle = (ASYNCCOMPLETIONHANDLE) pGPHandle;
- dwCurrentTime = GetCurTime();
- lpExt = lpGPOInfo->lpExtensions;
- //
- // Before going in, get the thread token and reset the thread token in case
- // one of the extensions hit an exception.
- //
- if (!OpenThreadToken (GetCurrentThread(), TOKEN_IMPERSONATE | TOKEN_READ,
- TRUE, &hOldToken)) {
- DebugMsg((DM_VERBOSE, TEXT("ProcessGPOs: OpenThreadToken failed with error %d, assuming thread is not impersonating"), GetLastError()));
- hOldToken = NULL;
- }
- while ( lpExt ) {
- BOOL bProcessGPOs, bNoChanges, bUsePerUserLocalSetting;
- PGROUP_POLICY_OBJECT pDeletedGPOList;
- DWORD dwRet;
- //
- // Check for early shutdown or user logoff
- //
- if ( (lpGPOInfo->dwFlags & GP_MACHINE) && g_bStopMachGPOProcessing
- || !(lpGPOInfo->dwFlags & GP_MACHINE) && g_bStopUserGPOProcessing ) {
- DebugMsg((DM_VERBOSE, TEXT("ProcessGPOs: Aborting GPO processing due to machine shutdown or logoff")));
- LogEvent (TRUE, IDS_GPO_PROC_STOPPED);
- break;
- }
- DebugMsg((DM_VERBOSE, TEXT("ProcessGPOs: -----------------------")));
- DebugMsg((DM_VERBOSE, TEXT("ProcessGPOs: Processing extension %s"),
- lpExt->lpDisplayName));
- if ( lpExt->bSkipped ) {
- DebugMsg((DM_VERBOSE, TEXT("ProcessGPOs: Extension %s skipped with flags 0x%x."),
- lpExt->lpDisplayName, lpGPOInfo->dwFlags));
- if (lpGPOInfo->dwFlags & GP_VERBOSE)
- LogEvent (FALSE, IDS_EXT_SKIPPED, lpExt->lpDisplayName, lpGPOInfo->dwFlags);
- lpExt = lpExt->pNext;
- continue;
- }
- //
- // Reset lpGPOInfo->lpGPOList based on extension filter list. If the extension
- // is being called to do delete processing on the history then the current GpoList
- // is null.
- //
- if ( lpExt->bHistoryProcessing ) {
- DebugMsg((DM_VERBOSE, TEXT("ProcessGPOs: Extension %s is being called to do delete processing on cached history."),
- lpExt->lpDisplayName));
- lpGPOInfo->lpGPOList = NULL;
- }
- else
- FilterGPOs( lpExt, lpGPOInfo );
- DebugPrintGPOList( lpGPOInfo );
- if ( !CheckGPOs( lpExt, lpGPOInfo, dwCurrentTime,
- &bProcessGPOs, &bNoChanges, &pDeletedGPOList ) ) {
- DebugMsg((DM_WARNING, TEXT("ProcessGPOs: CheckGPOs failed.")));
- lpExt = lpExt->pNext;
- continue;
- }
- if ( bProcessGPOs ) {
- if ( pDeletedGPOList == NULL && lpGPOInfo->lpGPOList == NULL ) {
- DebugMsg((DM_VERBOSE, TEXT("ProcessGPOs: Extension %s skipped because both deleted and changed GPO lists are empty."),
- lpExt->lpDisplayName ));
- if (lpGPOInfo->dwFlags & GP_VERBOSE)
- LogEvent (FALSE, IDS_EXT_HAS_EMPTY_LISTS, lpExt->lpDisplayName);
- lpExt = lpExt->pNext;
- continue;
- }
- if ( lpExt->dwEnableAsynch ) {
- //
- // Save now to shadow area to avoid race between thread that returns from
- // ProcessGPOList and the thread that does ProcessGroupPolicyCompleted and
- // reads from shadow area.
- //
- SaveGPOList( lpExt->lpKeyName, lpGPOInfo,
- HKEY_LOCAL_MACHINE,
- bUsePerUserLocalSetting ? lpGPOInfo->lpwszSidUser : NULL,
- TRUE, lpGPOInfo->lpGPOList );
- }
- dwRet = E_FAIL;
- __try {
- dwRet = ProcessGPOList( lpExt, lpGPOInfo, pDeletedGPOList,
- lpGPOInfo->lpGPOList, bNoChanges, pAsyncHandle );
- }
- __except( GPOExceptionFilter( GetExceptionInformation() ) ) {
- SetThreadToken(NULL, hOldToken);
- DebugMsg((DM_WARNING, TEXT("ProcessGPOs: Extension %s ProcessGroupPolicy threw unhandled exception 0x%x."),
- lpExt->lpDisplayName, GetExceptionCode() ));
- LogEvent (TRUE, IDS_CAUGHT_EXCEPTION, lpExt->lpDisplayName, GetExceptionCode());
- }
- FreeGPOList( pDeletedGPOList );
- pDeletedGPOList = NULL;
- bUsePerUserLocalSetting = lpExt->dwUserLocalSetting && !(lpGPOInfo->dwFlags & GP_MACHINE);
- if ( dwRet == ERROR_SUCCESS || dwRet == ERROR_OVERRIDE_NOCHANGES ) {
- //
- // ERROR_OVERRIDE_NOCHANGES means that extension processed the list and so the cached list
- // must be updated, but the extension will be called the next time even if there are
- // no changes.
- //
- SaveGPOList( lpExt->lpKeyName, lpGPOInfo,
- HKEY_LOCAL_MACHINE,
- bUsePerUserLocalSetting ? lpGPOInfo->lpwszSidUser : NULL,
- FALSE, lpGPOInfo->lpGPOList );
- uExtensionCount++;
- } else if ( dwRet == E_PENDING ) {
- DebugMsg((DM_VERBOSE, TEXT("ProcessGPOs: Extension %s ProcessGroupPolicy returned e_pending."),
- lpExt->lpDisplayName));
- } else {
- DebugMsg((DM_WARNING, TEXT("ProcessGPOs: Extension %s ProcessGroupPolicy failed, status 0x%x."),
- lpExt->lpDisplayName, dwRet));
- if (lpGPOInfo->dwFlags & GP_VERBOSE) {
- LogEvent (FALSE, IDS_CHANGES_FAILED, lpExt->lpDisplayName, dwRet);
- }
- }
- WriteStatus( lpExt->lpKeyName, lpGPOInfo,
- bUsePerUserLocalSetting ? lpGPOInfo->lpwszSidUser : NULL,
- dwRet, dwCurrentTime,
- (lpGPOInfo->dwFlags & GP_SLOW_LINK) != 0 );
- }
- //
- // Process next extension
- //
- DebugMsg((DM_VERBOSE, TEXT("ProcessGPOs: -----------------------")));
- lpExt = lpExt->pNext;
- }
- if (hOldToken)
- CloseHandle(hOldToken);
- //================================================================
- //
- // Success
- //
- //================================================================
- //
- // Set the return value
- //
- bRetVal = TRUE;
- Exit:
- //
- // Unload the Group Policy Extensions
- //
- UnloadGPExtensions (lpGPOInfo);
- FreeLists( lpGPOInfo );
- lpGPOInfo->lpGPOList = NULL;
- lpGPOInfo->lpExtFilterList = NULL;
- //
- // Token groups can change only at logon time, so reset to false
- //
- lpGPOInfo->bMemChanged = FALSE;
- lpGPOInfo->bUserLocalMemChanged = FALSE;
- //
- // We migrate the policy data from old sid only at logon time.
- // reset it to false.
- //
- lpGPOInfo->bSidChanged = FALSE;
- if (pDCI) {
- pNetAPI32->pfnNetApiBufferFree(pDCI);
- }
- if (lpName) {
- LocalFree (lpName);
- }
- if (lpDomain) {
- LocalFree (lpDomain);
- }
- //
- // Release the critical section
- //
- if (lpGPOInfo->hCritSection) {
- LeaveCriticalPolicySection (lpGPOInfo->hCritSection);
- lpGPOInfo->hCritSection = NULL;
- }
- //
- // Announce that policies have changed
- //
- if (bRetVal) {
- if (uExtensionCount) {
- //
- // First, update User with new colors, bitmaps, etc.
- //
- if (lpGPOInfo->dwFlags & GP_REGPOLICY_CPANEL) {
- //
- // Something has changed in the control panel section
- // Start control.exe with the /policy switch so the
- // display is refreshed.
- //
- RefreshDisplay (lpGPOInfo);
- }
- //
- // Notify anyone waiting on an event handle
- //
- if (lpGPOInfo->hNotifyEvent) {
- PulseEvent (lpGPOInfo->hNotifyEvent);
- }
- //
- // Create a thread to broadcase the WM_SETTINGCHANGE message
- //
- hThread = CreateThread (NULL, 0, (LPTHREAD_START_ROUTINE) PolicyChangedThread,
- (LPVOID) ((lpGPOInfo->dwFlags & GP_MACHINE) ? 1 : 0),
- CREATE_SUSPENDED, &dwThreadID);
- if (hThread) {
- SetThreadPriority (hThread, THREAD_PRIORITY_IDLE);
- ResumeThread (hThread);
- CloseHandle (hThread);
- } else {
- DebugMsg((DM_WARNING, TEXT("ProcessGPOs: Failed to create background thread (%d)."),
- GetLastError()));
- PolicyChangedThread (((lpGPOInfo->dwFlags & GP_MACHINE) ? 1 : 0));
- }
- }
- }
- if (lpGPOInfo->dwFlags & GP_VERBOSE) {
- if (lpGPOInfo->dwFlags & GP_MACHINE) {
- LogEvent (FALSE, IDS_MACHINE_POLICY_APPLIED);
- } else {
- LogEvent (FALSE, IDS_USER_POLICY_APPLIED);
- }
- }
- if (lpGPOInfo->dwFlags & GP_MACHINE) {
- DebugMsg((DM_VERBOSE, TEXT("ProcessGPOs: Computer Group Policy has been applied.")));
- } else {
- DebugMsg((DM_VERBOSE, TEXT("ProcessGPOs: User Group Policy has been applied.")));
- }
- DebugMsg((DM_VERBOSE, TEXT("ProcessGPOs: Leaving with %d."), bRetVal));
- return bRetVal;
- }
- //*************************************************************
- //
- // PolicyChangedThread()
- //
- // Purpose: Sends the WM_SETTINGCHANGE message announcing
- // that policy has changed. This is done on a
- // separate thread because this could take many
- // seconds to succeed if an application is hung
- //
- // Parameters: BOOL bMachine - machine or user policy has been applied
- //
- //
- // Return: 0
- //
- //*************************************************************
- DWORD WINAPI PolicyChangedThread (BOOL bMachine)
- {
- HINSTANCE hInst;
- NTSTATUS Status;
- BOOLEAN WasEnabled;
- DWORD dwBSM;
- hInst = LoadLibrary (TEXT("userenv.dll"));
- DebugMsg((DM_VERBOSE, TEXT("PolicyChangedThread: Entering with %d."), bMachine));
- //
- // Broadcase the WM_SETTINGCHANGE message
- //
- Status = RtlAdjustPrivilege(SE_TCB_PRIVILEGE, TRUE, FALSE, &WasEnabled);
- if (NT_SUCCESS(Status)) {
- dwBSM = BSM_ALLDESKTOPS | BSM_APPLICATIONS;
- BroadcastSystemMessage (BSF_IGNORECURRENTTASK | BSF_FORCEIFHUNG,
- &dwBSM,
- WM_SETTINGCHANGE,
- bMachine, (LPARAM) TEXT("Policy"));
- RtlAdjustPrivilege(SE_TCB_PRIVILEGE, WasEnabled, FALSE, &WasEnabled);
- }
- DebugMsg((DM_VERBOSE, TEXT("PolicyChangedThread: Leaving")));
- FreeLibraryAndExitThread (hInst, 0);
- return 0;
- }
- //*************************************************************
- //
- // DeleteRegistryValue()
- //
- // Purpose: Callback from ParseRegistryFile that deletes
- // registry policies
- //
- // Parameters: lpGPOInfo - GPO Information
- // lpKeyName - Key name
- // lpValueName - Value name
- // dwType - Registry data type
- // lpData - Registry data
- //
- // Return: TRUE if successful
- // FALSE if an error occurs
- //
- //*************************************************************
- BOOL DeleteRegistryValue (LPGPOINFO lpGPOInfo, LPTSTR lpKeyName,
- LPTSTR lpValueName, DWORD dwType,
- DWORD dwDataLength, LPBYTE lpData)
- {
- DWORD dwDisp;
- HKEY hSubKey;
- LONG lResult;
- INT iStrLen;
- TCHAR szPolicies1[] = TEXT("Software\Policies");
- TCHAR szPolicies2[] = TEXT("Software\Microsoft\Windows\CurrentVersion\Policies");
- //
- // Check if there is a keyname
- //
- if (!lpKeyName || !(*lpKeyName)) {
- return TRUE;
- }
- //
- // Check if the key is in one of the policies keys
- //
- iStrLen = lstrlen(szPolicies1);
- if (CompareString (LOCALE_USER_DEFAULT, NORM_IGNORECASE, szPolicies1,
- iStrLen, lpKeyName, iStrLen) != CSTR_EQUAL) {
- iStrLen = lstrlen(szPolicies2);
- if (CompareString (LOCALE_USER_DEFAULT, NORM_IGNORECASE, szPolicies2,
- iStrLen, lpKeyName, iStrLen) != CSTR_EQUAL) {
- return TRUE;
- }
- }
- //
- // Check if the value name starts with **
- //
- if (lpValueName && (lstrlen(lpValueName) > 1)) {
- if ( (*lpValueName == TEXT('*')) && (*(lpValueName+1) == TEXT('*')) ) {
- return TRUE;
- }
- }
- //
- // We found a value that needs to be deleted
- //
- if (RegCleanUpValue (lpGPOInfo->hKeyRoot, lpKeyName, lpValueName)) {
- DebugMsg((DM_VERBOSE, TEXT("DeleteRegistryValue: Deleted %s\%s"),
- lpKeyName, lpValueName));
- } else {
- DebugMsg((DM_WARNING, TEXT("DeleteRegistryValue: Failed to delete %s\%s"),
- lpKeyName, lpValueName));
- }
- return TRUE;
- }
- //*************************************************************
- //
- // ResetPolicies()
- //
- // Purpose: Resets the Policies and old Policies key to their
- // original state.
- //
- // Parameters: lpGPOInfo - GPT information
- // lpArchive - Name of archive file
- //
- //
- // Return: TRUE if successful
- // FALSE if an error occurs
- //
- //*************************************************************
- BOOL ResetPolicies (LPGPOINFO lpGPOInfo, LPTSTR lpArchive)
- {
- HKEY hKey;
- LONG lResult;
- DWORD dwDisp, dwValue = 0x95;
- DebugMsg((DM_VERBOSE, TEXT("ResetPolicies: Entering.")));
- //
- // Parse the archive file and delete any policies
- //
- if (!ParseRegistryFile (lpGPOInfo, lpArchive,
- DeleteRegistryValue, NULL)) {
- DebugMsg((DM_WARNING, TEXT("ResetPolicies: Leaving")));
- return FALSE;
- }
- //
- // Recreate the new policies key
- //
- lResult = RegCreateKeyEx (lpGPOInfo->hKeyRoot,
- TEXT("Software\Policies"),
- 0, NULL, REG_OPTION_NON_VOLATILE,
- KEY_WRITE, NULL, &hKey, &dwDisp);
- if (lResult == ERROR_SUCCESS) {
- //
- // Re-apply security
- //
- RegCloseKey (hKey);
- if (!MakeRegKeySecure((lpGPOInfo->dwFlags & GP_MACHINE) ? NULL : lpGPOInfo->hToken,
- lpGPOInfo->hKeyRoot,
- TEXT("Software\Policies"))) {
- DebugMsg((DM_WARNING, TEXT("ResetPolicies: Failed to secure reg key.")));
- }
- } else {
- DebugMsg((DM_WARNING, TEXT("ResetPolicies: Failed to create reg key with %d."), lResult));
- }
- //
- // Recreate the old policies key
- //
- lResult = RegCreateKeyEx (lpGPOInfo->hKeyRoot,
- TEXT("Software\Microsoft\Windows\CurrentVersion\Policies"),
- 0, NULL, REG_OPTION_NON_VOLATILE,
- KEY_WRITE, NULL, &hKey, &dwDisp);
- if (lResult == ERROR_SUCCESS) {
- //
- // Re-apply security
- //
- RegCloseKey (hKey);
- if (!MakeRegKeySecure((lpGPOInfo->dwFlags & GP_MACHINE) ? NULL : lpGPOInfo->hToken,
- lpGPOInfo->hKeyRoot,
- TEXT("Software\Microsoft\Windows\CurrentVersion\Policies"))) {
- DebugMsg((DM_WARNING, TEXT("ResetPolicies: Failed to secure reg key.")));
- }
- } else {
- DebugMsg((DM_WARNING, TEXT("ResetPolicies: Failed to create reg key with %d."), lResult));
- }
- //
- // If this is user policy, reset the NoDriveTypeAutoRun default value
- //
- if (!(lpGPOInfo->dwFlags & GP_MACHINE)) {
- if (RegCreateKeyEx (lpGPOInfo->hKeyRoot,
- TEXT("Software\Microsoft\Windows\CurrentVersion\Policies\Explorer"),
- 0, NULL, REG_OPTION_NON_VOLATILE,
- KEY_WRITE, NULL, &hKey, &dwDisp) == ERROR_SUCCESS) {
- RegSetValueEx (hKey, TEXT("NoDriveTypeAutoRun"), 0,
- REG_DWORD, (LPBYTE) &dwValue, sizeof(dwValue));
- RegCloseKey (hKey);
- }
- }
- DebugMsg((DM_VERBOSE, TEXT("ResetPolicies: Leaving.")));
- return TRUE;
- }
- //*************************************************************
- //
- // SetupGPOFilter()
- //
- // Purpose: Setup up GPO Filter info
- //
- // Parameters: lpGPOInfo - GPO info
- //
- // Return: TRUE if successful
- // FALSE if an error occurs
- //
- //*************************************************************
- BOOL SetupGPOFilter( LPGPOINFO lpGPOInfo )
- {
- //
- // Format is [{ext guid1}{snapin guid1}..{snapin guidn}][{ext guid2}...]...
- // Both extension and snapin guids are in ascending order.
- //
- // Note: If the format is corrupt then take the conservative
- // position and assume that it means that all
- // extensions need to be applied to the GPO.
- //
- LPEXTFILTERLIST pExtFilterListTail = 0;
- PGROUP_POLICY_OBJECT lpGPO = 0;
- LPEXTFILTERLIST pExtFilterElem = NULL;
- lpGPOInfo->bXferToExtList = FALSE;
- lpGPO = lpGPOInfo->lpGPOList;
- while ( lpGPO ) {
- TCHAR *pchCur = lpGPO->lpExtensions;
- LPEXTLIST pExtListHead = 0;
- LPEXTLIST pExtListTail = 0;
- if ( pchCur ) {
- while ( *pchCur ) {
- GUID guidExt;
- LPEXTLIST pExtElem;
- if ( *pchCur == TEXT('[') )
- pchCur++;
- else {
- DebugMsg((DM_WARNING, TEXT("SetupGPOFilter: Corrupt extension name format.")));
- FreeExtList( pExtListHead );
- pExtListHead = 0;
- break;
- }
- if ( ValidateGuid( pchCur ) )
- StringToGuid( pchCur, &guidExt );
- else {
- DebugMsg((DM_WARNING, TEXT("SetupGPOFilter: Corrupt extension name format.")));
- FreeExtList( pExtListHead );
- pExtListHead = 0;
- break;
- }
- pExtElem = LocalAlloc( LPTR, sizeof(EXTLIST) );
- if ( pExtElem == 0 ) {
- DebugMsg((DM_WARNING, TEXT("SetupGPOFilter: Unable to allocate memory.")));
- FreeExtList( pExtListHead );
- return FALSE;
- }
- pExtElem->guid = guidExt;
- pExtElem->pNext = 0;
- if ( pExtListTail )
- pExtListTail->pNext = pExtElem;
- else
- pExtListHead = pExtElem;
- pExtListTail = pExtElem;
- while ( *pchCur && *pchCur != TEXT('[') )
- pchCur++;
- } // while *pchcur
- } // if pchcur
- //
- // Append to lpExtFilterList
- //
- pExtFilterElem = LocalAlloc( LPTR, sizeof(EXTFILTERLIST) );
- if ( pExtFilterElem == NULL ) {
- DebugMsg((DM_WARNING, TEXT("SetupGPOFilter: Unable to allocate memory.")));
- FreeExtList( pExtListHead );
- return FALSE;
- }
- pExtFilterElem->lpExtList = pExtListHead;
- pExtFilterElem->lpGPO = lpGPO;
- pExtFilterElem->pNext = NULL;
- if ( pExtFilterListTail == 0 )
- lpGPOInfo->lpExtFilterList = pExtFilterElem;
- else
- pExtFilterListTail->pNext = pExtFilterElem;
- pExtFilterListTail = pExtFilterElem;
- //
- // Advance to next GPO
- //
- lpGPO = lpGPO->pNext;
- } // while lpgpo
- //
- // Transfer ownership from lpGPOList to lpExtFilterList
- //
- lpGPOInfo->bXferToExtList = TRUE;
- return TRUE;
- }
- //*************************************************************
- //
- // FilterGPOs()
- //
- // Purpose: Filter GPOs not relevant to this extension
- //
- // Parameters: lpExt - Extension
- // lpGPOInfo - GPO info
- //
- //*************************************************************
- void FilterGPOs( LPGPEXT lpExt, LPGPOINFO lpGPOInfo )
- {
- //
- // lpGPOInfo->lpGPOList will have the filtered list of GPOs
- //
- PGROUP_POLICY_OBJECT pGPOTail = 0;
- LPEXTFILTERLIST pExtFilterList = lpGPOInfo->lpExtFilterList;
- lpGPOInfo->lpGPOList = 0;
- while ( pExtFilterList ) {
- BOOL bFound = FALSE;
- LPEXTLIST pExtList = pExtFilterList->lpExtList;
- if ( pExtList == NULL ) {
- //
- // A null pExtlist means no extensions apply to this GPO
- //
- bFound = FALSE;
- } else {
- while (pExtList) {
- INT iComp = CompareGuid( &lpExt->guid, &pExtList->guid );
- if ( iComp == 0 ) {
- bFound = TRUE;
- break;
- } else if ( iComp < 0 ) {
- //
- // Guids in pExtList are in ascending order, so we are done
- //
- break;
- } else
- pExtList = pExtList->pNext;
- } // while pextlist
- } // else
- if ( bFound ) {
- //
- // Append pExtFilterList->lpGPO to the filtered GPO list
- //
- pExtFilterList->lpGPO->pNext = 0;
- pExtFilterList->lpGPO->pPrev = pGPOTail;
- if ( pGPOTail == 0 )
- lpGPOInfo->lpGPOList = pExtFilterList->lpGPO;
- else
- pGPOTail->pNext = pExtFilterList->lpGPO;
- pGPOTail = pExtFilterList->lpGPO;
- } // bFound
- pExtFilterList = pExtFilterList->pNext;
- } // while pextfilterlist
- }
- //*************************************************************
- //
- // GetDeletedGPOList()
- //
- // Purpose: Get the list of deleted GPOs
- //
- // Parameters: lpGPOList - List of old GPOs
- // ppDeletedGPOList - Deleted list returned here
- //
- //
- // Return: TRUE if successful
- // FALSE if an error occurs
- //
- //*************************************************************
- BOOL GetDeletedGPOList (PGROUP_POLICY_OBJECT lpGPOList,
- PGROUP_POLICY_OBJECT *ppDeletedGPOList)
- {
- *ppDeletedGPOList = NULL;
- //
- // It's possible that lpGPOList could be NULL. This is ok.
- //
- if (!lpGPOList) {
- DebugMsg((DM_VERBOSE, TEXT("GetDeletedList: No old GPOs. Leaving.")));
- return TRUE;
- }
- //
- // We need to do any delete operations in reverse order
- // of the way there were applied.
- //
- while ( lpGPOList ) {
- PGROUP_POLICY_OBJECT pCurGPO = lpGPOList;
- lpGPOList = lpGPOList->pNext;
- if ( pCurGPO->lParam & GPO_LPARAM_FLAG_DELETE ) {
- //
- // Prepend to deleted list
- //
- pCurGPO->pNext = *ppDeletedGPOList;
- pCurGPO->pPrev = NULL;
- if ( *ppDeletedGPOList )
- (*ppDeletedGPOList)->pPrev = pCurGPO;
- *ppDeletedGPOList = pCurGPO;
- } else
- LocalFree( pCurGPO );
- }
- DebugMsg((DM_VERBOSE, TEXT("GetDeletedGPOList: Finished.")));
- return TRUE;
- }
- //*************************************************************
- //
- // ReadGPOList()
- //
- // Purpose: Reads the list of Group Policy Objects from
- // the registry
- //
- // Parameters: pszExtName - GP extension
- // hKeyRoot - Registry handle
- // hKeyRootMach - Registry handle to hklm
- // lpwszSidUser - Sid of user, if non-null then it means
- // per user local setting
- // bShadow - Read from shadow or from history list
- // lpGPOList - pointer to the array of GPOs
- //
- //
- // Return: TRUE if successful
- // FALSE if an error occurs
- //
- //*************************************************************
- BOOL ReadGPOList ( TCHAR * pszExtName, HKEY hKeyRoot,
- HKEY hKeyRootMach, LPTSTR lpwszSidUser, BOOL bShadow,
- PGROUP_POLICY_OBJECT * lpGPOList)
- {
- INT iIndex = 0;
- LONG lResult;
- HKEY hKey, hSubKey = NULL;
- BOOL bResult = FALSE;
- TCHAR szSubKey[10];
- DWORD dwOptions, dwVersion;
- GPO_LINK GPOLink;
- LPARAM lParam;
- TCHAR szGPOName[50];
- LPTSTR lpDSPath = NULL, lpFileSysPath = NULL, lpDisplayName = NULL, lpExtensions = NULL, lpLink = NULL;
- DWORD dwDisp, dwSize, dwType, dwTemp, dwMaxSize;
- PGROUP_POLICY_OBJECT lpGPO, lpGPOTemp;
- TCHAR szKey[400];
- //
- // Set default
- //
- *lpGPOList = NULL;
- //
- // Open the key that holds the GPO list
- //
- if ( lpwszSidUser == 0 ) {
- wsprintf (szKey,
- bShadow ? GP_SHADOW_KEY
- : GP_HISTORY_KEY,
- pszExtName );
- } else {
- wsprintf (szKey,
- bShadow ? GP_SHADOW_SID_KEY
- : GP_HISTORY_SID_KEY,
- lpwszSidUser, pszExtName );
- }
- lResult = RegOpenKeyEx ( lpwszSidUser ? hKeyRootMach : hKeyRoot,
- szKey,
- 0, KEY_READ, &hKey);
- if (lResult != ERROR_SUCCESS) {
- if (lResult == ERROR_FILE_NOT_FOUND) {
- return TRUE;
- } else {
- DebugMsg((DM_WARNING, TEXT("ReadGPOList: Failed to open reg key with %d."), lResult));
- return FALSE;
- }
- }
- while (TRUE) {
- //
- // Enumerate through the subkeys. The keys are named by index number
- // eg: 0, 1, 2, 3, etc...
- //
- IntToString (iIndex, szSubKey);
- lResult = RegOpenKeyEx (hKey, szSubKey, 0, KEY_READ, &hSubKey);
- if (lResult != ERROR_SUCCESS) {
- if (lResult == ERROR_FILE_NOT_FOUND) {
- bResult = TRUE;
- goto Exit;
- } else {
- DebugMsg((DM_WARNING, TEXT("ReadGPOList: Failed to open reg key <%s> with %d."), szSubKey, lResult));
- goto Exit;
- }
- }
- //
- // Read the size of the largest value in this key
- //
- lResult = RegQueryInfoKey (hSubKey, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
- &dwMaxSize, NULL, NULL);
- if (lResult != ERROR_SUCCESS) {
- DebugMsg((DM_WARNING, TEXT("ReadGPOList: Failed to query max size with %d."), lResult));
- goto Exit;
- }
- //
- // Allocate buffers based upon the value above
- //
- lpDSPath = LocalAlloc (LPTR, dwMaxSize);
- if (!lpDSPath) {
- DebugMsg((DM_WARNING, TEXT("ReadGPOList: Failed to allocate memory with %d."), GetLastError()));
- goto Exit;
- }
- lpFileSysPath = LocalAlloc (LPTR, dwMaxSize);
- if (!lpFileSysPath) {
- DebugMsg((DM_WARNING, TEXT("ReadGPOList: Failed to allocate memory with %d."), GetLastError()));
- goto Exit;
- }
- lpDisplayName = LocalAlloc (LPTR, dwMaxSize);
- if (!lpDisplayName) {
- DebugMsg((DM_WARNING, TEXT("ReadGPOList: Failed to allocate memory with %d."), GetLastError()));
- goto Exit;
- }
- lpExtensions = LocalAlloc (LPTR, dwMaxSize);
- if (!lpExtensions) {
- DebugMsg((DM_WARNING, TEXT("ReadGPOList: Failed to allocate memory with %d."), GetLastError()));
- goto Exit;
- }
- lpLink = LocalAlloc (LPTR, dwMaxSize);
- if (!lpLink) {
- DebugMsg((DM_WARNING, TEXT("ReadGPOList: Failed to allocate memory with %d."), GetLastError()));
- goto Exit;
- }
- //
- // Read in the GPO
- //
- dwOptions = 0;
- dwSize = sizeof(dwOptions);
- lResult = RegQueryValueEx (hSubKey, TEXT("Options"), NULL, &dwType,
- (LPBYTE) &dwOptions, &dwSize);
- if (lResult != ERROR_SUCCESS) {
- DebugMsg((DM_WARNING, TEXT("ReadGPOList: Failed to query options reg value with %d."), lResult));
- }
- dwVersion = 0;
- dwSize = sizeof(dwVersion);
- lResult = RegQueryValueEx (hSubKey, TEXT("Version"), NULL, &dwType,
- (LPBYTE) &dwVersion, &dwSize);
- if (lResult != ERROR_SUCCESS) {
- DebugMsg((DM_WARNING, TEXT("ReadGPOList: Failed to query Version reg value with %d."), lResult));
- }
- dwSize = dwMaxSize;
- lResult = RegQueryValueEx (hSubKey, TEXT("DSPath"), NULL, &dwType,
- (LPBYTE) lpDSPath, &dwSize);
- if (lResult != ERROR_SUCCESS) {
- if (lResult != ERROR_FILE_NOT_FOUND) {
- DebugMsg((DM_WARNING, TEXT("ReadGPOList: Failed to query DS reg value with %d."), lResult));
- goto Exit;
- }
- LocalFree (lpDSPath);
- lpDSPath = NULL;
- }
- dwSize = dwMaxSize;
- lResult = RegQueryValueEx (hSubKey, TEXT("FileSysPath"), NULL, &dwType,
- (LPBYTE) lpFileSysPath, &dwSize);
- if (lResult != ERROR_SUCCESS) {
- DebugMsg((DM_WARNING, TEXT("ReadGPOList: Failed to query file sys path reg value with %d."), lResult));
- goto Exit;
- }
- dwSize = dwMaxSize;
- lResult = RegQueryValueEx (hSubKey, TEXT("DisplayName"), NULL, &dwType,
- (LPBYTE) lpDisplayName, &dwSize);
- if (lResult != ERROR_SUCCESS) {
- DebugMsg((DM_WARNING, TEXT("ReadGPOList: Failed to query display name reg value with %d."), lResult));
- goto Exit;
- }
- dwSize = dwMaxSize;
- lResult = RegQueryValueEx (hSubKey, TEXT("Extensions"), NULL, &dwType,
- (LPBYTE) lpExtensions, &dwSize);
- if (lResult != ERROR_SUCCESS) {
- DebugMsg((DM_WARNING, TEXT("ReadGPOList: Failed to query extension names reg value with %d."), lResult));
- LocalFree(lpExtensions);
- lpExtensions = NULL;
- }
- dwSize = dwMaxSize;
- lResult = RegQueryValueEx (hSubKey, TEXT("Link"), NULL, &dwType,
- (LPBYTE) lpLink, &dwSize);
- if (lResult != ERROR_SUCCESS) {
- if (lResult != ERROR_FILE_NOT_FOUND) {
- DebugMsg((DM_WARNING, TEXT("ReadGPOList: Failed to query DS Object reg value with %d."), lResult));
- }
- LocalFree(lpLink);
- lpLink = NULL;
- }
- dwSize = sizeof(szGPOName);
- lResult = RegQueryValueEx (hSubKey, TEXT("GPOName"), NULL, &dwType,
- (LPBYTE) szGPOName, &dwSize);
- if (lResult != ERROR_SUCCESS) {
- DebugMsg((DM_WARNING, TEXT("ReadGPOList: Failed to query GPO name reg value with %d."), lResult));
- goto Exit;
- }
- GPOLink = GPLinkUnknown;
- dwSize = sizeof(GPOLink);
- lResult = RegQueryValueEx (hSubKey, TEXT("GPOLink"), NULL, &dwType,
- (LPBYTE) &GPOLink, &dwSize);
- if (lResult != ERROR_SUCCESS) {
- DebugMsg((DM_WARNING, TEXT("ReadGPOList: Failed to query reserved reg value with %d."), lResult));
- }
- lParam = 0;
- dwSize = sizeof(lParam);
- lResult = RegQueryValueEx (hSubKey, TEXT("lParam"), NULL, &dwType,
- (LPBYTE) &lParam, &dwSize);
- if (lResult != ERROR_SUCCESS) {
- DebugMsg((DM_WARNING, TEXT("ReadGPOList: Failed to query lParam reg value with %d."), lResult));
- }
- //
- // Add the GPO to the list
- //
- if (!AddGPO (lpGPOList, dwOptions, dwVersion, lpDSPath, lpFileSysPath,
- lpDisplayName, szGPOName, lpExtensions, GPOLink, lpLink, lParam,
- FALSE, FALSE, FALSE)) {
- DebugMsg((DM_WARNING, TEXT("ReadGPOList: Failed to add GPO to list.")));
- goto Exit;
- }
- //
- // Free the buffers allocated above
- //
- if (lpDSPath) {
- LocalFree (lpDSPath);
- lpDSPath = NULL;
- }
- LocalFree (lpFileSysPath);
- lpFileSysPath = NULL;
- LocalFree (lpDisplayName);
- lpDisplayName = NULL;
- if (lpExtensions) {
- LocalFree(lpExtensions);
- lpExtensions = NULL;
- }
- if (lpLink) {
- LocalFree(lpLink);
- lpLink = NULL;
- }
- //
- // Close the subkey handle
- //
- RegCloseKey (hSubKey);
- hSubKey = NULL;
- iIndex++;
- }
- Exit:
- if (lpDSPath) {
- LocalFree (lpDSPath);
- }
- if (lpFileSysPath) {
- LocalFree (lpFileSysPath);
- }
- if (lpDisplayName) {
- LocalFree (lpDisplayName);
- }
- if (lpExtensions) {
- LocalFree(lpExtensions);
- }
- if (lpLink) {
- LocalFree(lpLink);
- }
- if (hSubKey) {
- RegCloseKey (hSubKey);
- }
- RegCloseKey (hKey);
- if (!bResult) {
- //
- // Free any entries in the list
- //
- lpGPO = *lpGPOList;
- while (lpGPO) {
- lpGPOTemp = lpGPO->pNext;
- LocalFree (lpGPO);
- lpGPO = lpGPOTemp;
- }
- *lpGPOList = NULL;
- }
- return bResult;
- }
- //*************************************************************
- //
- // SaveGPOList()
- //
- // Purpose: Saves the list of Group Policy Objects in
- // the registry
- //
- // Parameters: pszExtName - GP extension
- // lpGPOInfo - Group policy info
- // hKeyRootMach - Registry handle to hklm
- // lpwszSidUser - Sid of user, if non-null then it means
- // per user local setting
- // bShadow - Save to shadow or to history list
- // lpGPOList - Array of GPOs
- //
- //
- // Return: TRUE if successful
- // FALSE if an error occurs
- //
- //*************************************************************
- BOOL SaveGPOList (TCHAR *pszExtName, LPGPOINFO lpGPOInfo,
- HKEY hKeyRootMach, LPTSTR lpwszSidUser, BOOL bShadow,
- PGROUP_POLICY_OBJECT lpGPOList)
- {
- INT iIndex = 0;
- LONG lResult;
- HKEY hKey = NULL;
- BOOL bResult = FALSE;
- TCHAR szSubKey[400];
- DWORD dwDisp, dwSize;
- //
- // Start off with an empty key
- //
- if ( lpwszSidUser == 0 ) {
- wsprintf (szSubKey,
- bShadow ? GP_SHADOW_KEY
- : GP_HISTORY_KEY,
- pszExtName);
- } else {
- wsprintf (szSubKey,
- bShadow ? GP_SHADOW_SID_KEY
- : GP_HISTORY_SID_KEY,
- lpwszSidUser, pszExtName);
- }
- if (!RegDelnode (lpwszSidUser ? hKeyRootMach : lpGPOInfo->hKeyRoot,
- szSubKey)) {
- DebugMsg((DM_VERBOSE, TEXT("SaveGPOList: RegDelnode failed.")));
- }
- //
- // Check if we have any GPOs to store. It's ok for this to be NULL.
- //
- if (!lpGPOList) {
- return TRUE;
- }
- //
- // Set the proper security on the registry key
- //
- if ( !MakeRegKeySecure( (lpGPOInfo->dwFlags & GP_MACHINE) ? NULL : lpGPOInfo->hToken,
- lpwszSidUser ? hKeyRootMach : lpGPOInfo->hKeyRoot,
- szSubKey ) ) {
- DebugMsg((DM_WARNING, TEXT("SaveGpoList: Failed to secure reg key.")));
- }
- //
- // Loop through the GPOs saving them in the registry
- //
- while (lpGPOList) {
- if ( lpwszSidUser == 0 ) {
- wsprintf (szSubKey,
- bShadow ? TEXT("Software\Microsoft\Windows\CurrentVersion\Group Policy\Shadow\%ws\%d")
- : TEXT("Software\Microsoft\Windows\CurrentVersion\Group Policy\History\%ws\%d"),
- pszExtName,
- iIndex);
- } else {
- wsprintf (szSubKey,
- bShadow ? TEXT("Software\Microsoft\Windows\CurrentVersion\Group Policy\%ws\Shadow\%ws\%d")
- : TEXT("Software\Microsoft\Windows\CurrentVersion\Group Policy\%ws\History\%ws\%d"),
- lpwszSidUser, pszExtName, iIndex);
- }
- lResult = RegCreateKeyEx (lpwszSidUser ? hKeyRootMach : lpGPOInfo->hKeyRoot,
- szSubKey, 0, NULL,
- REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hKey, &dwDisp);
- if (lResult != ERROR_SUCCESS) {
- DebugMsg((DM_WARNING, TEXT("SaveGPOList: Failed to create reg key with %d."), lResult));
- goto Exit;
- }
- //
- // Save the GPO
- //
- dwSize = sizeof(lpGPOList->dwOptions);
- lResult = RegSetValueEx (hKey, TEXT("Options"), 0, REG_DWORD,
- (LPBYTE) &lpGPOList->dwOptions, dwSize);
- if (lResult != ERROR_SUCCESS) {
- DebugMsg((DM_WARNING, TEXT("SaveGPOList: Failed to set options reg value with %d."), lResult));
- goto Exit;
- }
- dwSize = sizeof(lpGPOList->dwVersion);
- lResult = RegSetValueEx (hKey, TEXT("Version"), 0, REG_DWORD,
- (LPBYTE) &lpGPOList->dwVersion, dwSize);
- if (lResult != ERROR_SUCCESS) {
- DebugMsg((DM_WARNING, TEXT("SaveGPOList: Failed to set Version reg value with %d."), lResult));
- goto Exit;
- }
- if (lpGPOList->lpDSPath) {
- dwSize = (lstrlen (lpGPOList->lpDSPath) + 1) * sizeof(TCHAR);
- lResult = RegSetValueEx (hKey, TEXT("DSPath"), 0, REG_SZ,
- (LPBYTE) lpGPOList->lpDSPath, dwSize);
- if (lResult != ERROR_SUCCESS) {
- DebugMsg((DM_WARNING, TEXT("SaveGPOList: Failed to set DS reg value with %d."), lResult));
- goto Exit;
- }
- }
- dwSize = (lstrlen (lpGPOList->lpFileSysPath) + 1) * sizeof(TCHAR);
- lResult = RegSetValueEx (hKey, TEXT("FileSysPath"), 0, REG_SZ,
- (LPBYTE) lpGPOList->lpFileSysPath, dwSize);
- if (lResult != ERROR_SUCCESS) {
- DebugMsg((DM_WARNING, TEXT("SaveGPOList: Failed to set file sys path reg value with %d."), lResult));
- goto Exit;
- }
- dwSize = (lstrlen (lpGPOList->lpDisplayName) + 1) * sizeof(TCHAR);
- lResult = RegSetValueEx (hKey, TEXT("DisplayName"), 0, REG_SZ,
- (LPBYTE) lpGPOList->lpDisplayName, dwSize);
- if (lResult != ERROR_SUCCESS) {
- DebugMsg((DM_WARNING, TEXT("SaveGPOList: Failed to set display name reg value with %d."), lResult));
- goto Exit;
- }
- if (lpGPOList->lpExtensions) {
- dwSize = (lstrlen (lpGPOList->lpExtensions) + 1) * sizeof(TCHAR);
- lResult = RegSetValueEx (hKey, TEXT("Extensions"), 0, REG_SZ,
- (LPBYTE) lpGPOList->lpExtensions, dwSize);
- if (lResult != ERROR_SUCCESS) {
- DebugMsg((DM_WARNING, TEXT("SaveGPOList: Failed to set extension names reg value with %d."), lResult));
- goto Exit;
- }
- }
- if (lpGPOList->lpLink) {
- dwSize = (lstrlen (lpGPOList->lpLink) + 1) * sizeof(TCHAR);
- lResult = RegSetValueEx (hKey, TEXT("Link"), 0, REG_SZ,
- (LPBYTE) lpGPOList->lpLink, dwSize);
- if (lResult != ERROR_SUCCESS) {
- DebugMsg((DM_WARNING, TEXT("SaveGPOList: Failed to set DSObject reg value with %d."), lResult));
- goto Exit;
- }
- }
- dwSize = (lstrlen (lpGPOList->szGPOName) + 1) * sizeof(TCHAR);
- lResult = RegSetValueEx (hKey, TEXT("GPOName"), 0, REG_SZ,
- (LPBYTE) lpGPOList->szGPOName, dwSize);
- if (lResult != ERROR_SUCCESS) {
- DebugMsg((DM_WARNING, TEXT("SaveGPOList: Failed to set GPO name reg value with %d."), lResult));
- goto Exit;
- }
- dwSize = sizeof(lpGPOList->GPOLink);
- lResult = RegSetValueEx (hKey, TEXT("GPOLink"), 0, REG_DWORD,
- (LPBYTE) &lpGPOList->GPOLink, dwSize);
- if (lResult != ERROR_SUCCESS) {
- DebugMsg((DM_WARNING, TEXT("SaveGPOList: Failed to set GPOLink reg value with %d."), lResult));
- goto Exit;
- }
- dwSize = sizeof(lpGPOList->lParam);
- lResult = RegSetValueEx (hKey, TEXT("lParam"), 0, REG_DWORD,
- (LPBYTE) &lpGPOList->lParam, dwSize);
- if (lResult != ERROR_SUCCESS) {
- DebugMsg((DM_WARNING, TEXT("SaveGPOList: Failed to set lParam reg value with %d."), lResult));
- goto Exit;
- }
- //
- // Close the handle
- //
- RegCloseKey (hKey);
- hKey = NULL;
- //
- // Prep for the next loop
- //
- iIndex++;
- lpGPOList = lpGPOList->pNext;
- }
- //
- // Success
- //
- bResult = TRUE;
- Exit:
- if (hKey) {
- RegCloseKey (hKey);
- }
- return bResult;
- }
- //*************************************************************
- //
- // WriteStatus()
- //
- // Purpose: Saves status in the registry
- //
- // Parameters: lpGPOInfo - GPO info
- // lpExtName - GP extension name
- // dwStatus - Status to write
- // dwTime - Policy time to write
- // dwSlowLink - Link speed to write
- //
- //
- // Return: TRUE if successful
- // FALSE if an error occurs
- //
- //*************************************************************
- BOOL WriteStatus( TCHAR *lpExtName, LPGPOINFO lpGPOInfo, LPTSTR lpwszSidUser, DWORD dwStatus, DWORD dwTime,
- DWORD dwSlowLink )
- {
- HKEY hKey = NULL;
- DWORD dwDisp, dwSize;
- LONG lResult;
- BOOL bResult = FALSE;
- TCHAR szKey[400];
- if ( lpwszSidUser == 0 ) {
- wsprintf (szKey,
- GP_EXTENSIONS_KEY,
- lpExtName);
- } else {
- wsprintf (szKey,
- GP_EXTENSIONS_SID_KEY,
- lpwszSidUser, lpExtName);
- }
- lResult = RegCreateKeyEx (lpwszSidUser ? HKEY_LOCAL_MACHINE : lpGPOInfo->hKeyRoot,
- szKey, 0, NULL,
- REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hKey, &dwDisp);
- if (lResult != ERROR_SUCCESS) {
- DebugMsg((DM_WARNING, TEXT("WriteStatus: Failed to create reg key with %d."), lResult));
- goto Exit;
- }
- dwSize = sizeof(dwStatus);
- lResult = RegSetValueEx (hKey, TEXT("Status"), 0, REG_DWORD,
- (LPBYTE) &dwStatus, dwSize);
- if (lResult != ERROR_SUCCESS) {
- DebugMsg((DM_WARNING, TEXT("WriteStatus: Failed to set status reg value with %d."), lResult));
- goto Exit;
- }
- dwSize = sizeof(dwTime);
- lResult = RegSetValueEx (hKey, TEXT("LastPolicyTime"), 0, REG_DWORD,
- (LPBYTE) &dwTime, dwSize);
- if (lResult != ERROR_SUCCESS) {
- DebugMsg((DM_WARNING, TEXT("WriteStatus: Failed to set time reg value with %d."), lResult));
- goto Exit;
- }
- dwSize = sizeof(dwSlowLink);
- lResult = RegSetValueEx (hKey, TEXT("PrevSlowLink"), 0, REG_DWORD,
- (LPBYTE) &dwSlowLink, dwSize);
- if (lResult != ERROR_SUCCESS) {
- DebugMsg((DM_WARNING, TEXT("WriteStatus: Failed to set slowlink reg value with %d."), lResult));
- goto Exit;
- }
- bResult = TRUE;
- Exit:
- if ( hKey != NULL )
- RegCloseKey( hKey );
- return bResult;
- }
- //*************************************************************
- //
- // ReadStatus()
- //
- // Purpose: Reads status from the registry
- //
- // Parameters: lpKeyName - Extension name
- // lpGPOInfo - GPO info
- // lpwszSidUser - Sid of user, if non-null then it means
- // per user local setting
- // pdwStatus - Status returned here
- // pdwTime - Last policy time returned here
- // pdwSlowLink - Previous link speed returned here
- //
- //
- // Return: TRUE if successful
- // FALSE if an error occurs
- //
- //*************************************************************
- BOOL ReadStatus( TCHAR *lpKeyName, LPGPOINFO lpGPOInfo, LPTSTR lpwszSidUser, DWORD *pdwStatus, DWORD *pdwTime,
- DWORD *pdwSlowLink )
- {
- HKEY hKey = NULL;
- DWORD dwType, dwSize;
- LONG lResult;
- BOOL bResult = FALSE;
- TCHAR szKey[400];
- if ( lpwszSidUser == 0 ) {
- wsprintf (szKey,
- GP_EXTENSIONS_KEY,
- lpKeyName);
- } else {
- wsprintf (szKey,
- GP_EXTENSIONS_SID_KEY,
- lpwszSidUser, lpKeyName);
- }
- lResult = RegOpenKeyEx (lpwszSidUser ? HKEY_LOCAL_MACHINE : lpGPOInfo->hKeyRoot,
- szKey,
- 0, KEY_READ, &hKey);
- if (lResult != ERROR_SUCCESS) {
- if (lResult != ERROR_FILE_NOT_FOUND) {
- DebugMsg((DM_VERBOSE, TEXT("ReadStatus: Failed to open reg key with %d."), lResult));
- }
- goto Exit;
- }
- dwSize = sizeof(DWORD);
- lResult = RegQueryValueEx( hKey, TEXT("Status"), NULL,
- &dwType, (LPBYTE) pdwStatus,
- &dwSize );
- if (lResult != ERROR_SUCCESS) {
- if (lResult != ERROR_FILE_NOT_FOUND) {
- DebugMsg((DM_VERBOSE, TEXT("ReadStatus: Failed to read status reg value with %d."), lResult));
- }
- goto Exit;
- }
- dwSize = sizeof(DWORD);
- lResult = RegQueryValueEx( hKey, TEXT("LastPolicyTime"), NULL,
- &dwType, (LPBYTE) pdwTime,
- &dwSize );
- if (lResult != ERROR_SUCCESS) {
- DebugMsg((DM_VERBOSE, TEXT("ReadStatus: Failed to read time reg value with %d."), lResult));
- goto Exit;
- }
- dwSize = sizeof(DWORD);
- lResult = RegQueryValueEx( hKey, TEXT("PrevSlowLink"), NULL,
- &dwType, (LPBYTE) pdwSlowLink,
- &dwSize );
- if (lResult != ERROR_SUCCESS) {
- DebugMsg((DM_VERBOSE, TEXT("ReadStatus: Failed to read slowlink reg value with %d."), lResult));
- goto Exit;
- }
- bResult = TRUE;
- Exit:
- if ( hKey != NULL )
- RegCloseKey( hKey );
- return bResult;
- }
- //*************************************************************
- //
- // GetCurTime()
- //
- // Purpose: Returns current time in minutes, or 0 if there
- // is a failure
- //
- //*************************************************************
- DWORD GetCurTime()
- {
- DWORD dwCurTime = 0;
- LARGE_INTEGER liCurTime;
- if ( NT_SUCCESS( NtQuerySystemTime( &liCurTime) ) ) {
- if ( RtlTimeToSecondsSince1980 ( &liCurTime, &dwCurTime) ) {
- dwCurTime /= 60; // seconds to minutes
- }
- }
- return dwCurTime;
- }
- //*************************************************************
- //
- // CheckForGPOsToRemove()
- //
- // Purpose: Compares the GPOs in list1 with list 2 to determine
- // if any GPOs need to be removed.
- //
- // Parameters: lpGPOList1 - GPO link list 1
- // lpGPOList2 - GPO link list 2
- //
- // Return: TRUE if one or more GPOs need to be removed
- // FALSE if not
- //
- //*************************************************************
- BOOL CheckForGPOsToRemove (PGROUP_POLICY_OBJECT lpGPOList1, PGROUP_POLICY_OBJECT lpGPOList2)
- {
- PGROUP_POLICY_OBJECT lpGPOSrc, lpGPODest;
- BOOL bFound;
- BOOL bResult = FALSE;
- //
- // First check to see if they are both NULL
- //
- if (!lpGPOList1 && !lpGPOList2) {
- return FALSE;
- }
- //
- // Go through every GPO in list 1, and see if it is still in list 2
- //
- lpGPOSrc = lpGPOList1;
- while (lpGPOSrc) {
- lpGPODest = lpGPOList2;
- bFound = FALSE;
- while (lpGPODest) {
- if (!lstrcmpi (lpGPOSrc->szGPOName, lpGPODest->szGPOName)) {
- bFound = TRUE;
- break;
- }
- lpGPODest = lpGPODest->pNext;
- }
- if (!bFound) {
- DebugMsg((DM_VERBOSE, TEXT("CheckForGPOsToRemove: GPO <%s> needs to be removed"), lpGPOSrc->lpDisplayName));
- lpGPOSrc->lParam |= GPO_LPARAM_FLAG_DELETE;
- bResult = TRUE;
- }
- lpGPOSrc = lpGPOSrc->pNext;
- }
- return bResult;
- }
- //*************************************************************
- //
- // CompareGPOLists()
- //
- // Purpose: Compares one list of GPOs to another
- //
- // Parameters: lpGPOList1 - GPO link list 1
- // lpGPOList2 - GPO link list 2
- //
- // Return: TRUE if the lists are the same
- // FALSE if not
- //
- //*************************************************************
- BOOL CompareGPOLists (PGROUP_POLICY_OBJECT lpGPOList1, PGROUP_POLICY_OBJECT lpGPOList2)
- {
- //
- // Check if one list is empty
- //
- if ((lpGPOList1 && !lpGPOList2) || (!lpGPOList1 && lpGPOList2)) {
- DebugMsg((DM_VERBOSE, TEXT("CompareGPOLists: One list is empty")));
- return FALSE;
- }
- //
- // Loop through the GPOs
- //
- while (lpGPOList1 && lpGPOList2) {
- //
- // Compare GPO names
- //
- if (lstrcmpi (lpGPOList1->szGPOName, lpGPOList2->szGPOName) != 0) {
- DebugMsg((DM_VERBOSE, TEXT("CompareGPOLists: Different entries found.")));
- return FALSE;
- }
- //
- // Compare the version numbers
- //
- if (lpGPOList1->dwVersion != lpGPOList2->dwVersion) {
- DebugMsg((DM_VERBOSE, TEXT("CompareGPOLists: Different version numbers found")));
- return FALSE;
- }
- //
- // Move to the next node
- //
- lpGPOList1 = lpGPOList1->pNext;
- lpGPOList2 = lpGPOList2->pNext;
- //
- // Check if one list has more entries than the other
- //
- if ((lpGPOList1 && !lpGPOList2) || (!lpGPOList1 && lpGPOList2)) {
- DebugMsg((DM_VERBOSE, TEXT("CompareGPOLists: One list has more entries than the other")));
- return FALSE;
- }
- }
- DebugMsg((DM_VERBOSE, TEXT("CompareGPOLists: The lists are the same.")));
- return TRUE;
- }
- //*************************************************************
- //
- // HistoryPresent()
- //
- // Purpose: Checks if the current extension has any cached
- // GPOs
- //
- // Parameters: lpGPOInfo - GPOInfo
- // lpExt - Extension
- //
- //
- // Return: TRUE if cached GPOs present
- // FALSE otherwise
- //
- //*************************************************************
- BOOL HistoryPresent( LPGPOINFO lpGPOInfo, LPGPEXT lpExt )
- {
- TCHAR szKey[400];
- LONG lResult;
- HKEY hKey;
- //
- // Check if history is cached on per user per machine basis
- //
- BOOL bUsePerUserLocalSetting = lpExt->dwUserLocalSetting && !(lpGPOInfo->dwFlags & GP_MACHINE);
- DmAssert( !bUsePerUserLocalSetting || lpGPOInfo->lpwszSidUser != 0 );
- if ( bUsePerUserLocalSetting ) {
- wsprintf( szKey, GP_HISTORY_SID_KEY,
- lpGPOInfo->lpwszSidUser, lpExt->lpKeyName );
- } else {
- wsprintf( szKey, GP_HISTORY_KEY,
- lpExt->lpKeyName );
- }
- lResult = RegOpenKeyEx ( bUsePerUserLocalSetting ? HKEY_LOCAL_MACHINE : lpGPOInfo->hKeyRoot,
- szKey,
- 0, KEY_READ, &hKey);
- if (lResult == ERROR_SUCCESS) {
- RegCloseKey( hKey );
- return TRUE;
- } else
- return FALSE;
- }
- //*************************************************************
- //
- // MigrateMembershipData()
- //
- // Purpose: Moves group membership data from old sid to new
- // sid.
- //
- // Parameters: lpwszSidUserNew - New sid
- // lpwszSidUserOld - Old sid
- //
- // Return: TRUE if success
- // FALSE otherwise
- //
- //*************************************************************
- BOOL MigrateMembershipData( LPTSTR lpwszSidUserNew, LPTSTR lpwszSidUserOld )
- {
- DWORD dwCount = 0;
- DWORD dwSize, dwType, dwMaxSize, dwDisp;
- DWORD i= 0;
- LONG lResult;
- HKEY hKeyRead = NULL, hKeyWrite = NULL;
- BOOL bResult = TRUE;
- LPTSTR lpSid = NULL;
- TCHAR szKeyRead[250];
- TCHAR szKeyWrite[250];
- TCHAR szGroup[30];
- wsprintf( szKeyRead, GP_MEMBERSHIP_KEY, lpwszSidUserOld );
- lResult = RegOpenKeyEx( HKEY_LOCAL_MACHINE, szKeyRead, 0, KEY_READ, &hKeyRead);
- if (lResult != ERROR_SUCCESS)
- return TRUE;
- wsprintf( szKeyWrite, GP_MEMBERSHIP_KEY, lpwszSidUserNew );
- if ( !RegDelnode( HKEY_LOCAL_MACHINE, szKeyWrite ) ) {
- DebugMsg((DM_VERBOSE, TEXT("MigrateMembershipData: RegDelnode failed.")));
- bResult = FALSE;
- goto Exit;
- }
- lResult = RegCreateKeyEx( HKEY_LOCAL_MACHINE, szKeyWrite, 0, NULL,
- REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hKeyWrite, &dwDisp);
- if (lResult != ERROR_SUCCESS) {
- DebugMsg((DM_WARNING, TEXT("MigrateMembershipData: Failed to create key with %d."), lResult));
- bResult = FALSE;
- goto Exit;
- }
- dwSize = sizeof(dwCount);
- lResult = RegQueryValueEx (hKeyRead, TEXT("Count"), NULL, &dwType,
- (LPBYTE) &dwCount, &dwSize);
- if ( lResult != ERROR_SUCCESS ) {
- DebugMsg((DM_VERBOSE, TEXT("MigrateMembershipData: Failed to read membership count")));
- goto Exit;
- }
- lResult = RegQueryInfoKey (hKeyRead, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
- &dwMaxSize, NULL, NULL);
- if (lResult != ERROR_SUCCESS) {
- DebugMsg((DM_WARNING, TEXT("MigrateMembershipData: Failed to query max size with %d."), lResult));
- goto Exit;
- }
- //
- // Allocate buffer based upon the largest value
- //
- lpSid = LocalAlloc (LPTR, dwMaxSize);
- if (!lpSid) {
- DebugMsg((DM_WARNING, TEXT("MigrateMembershipData: Failed to allocate memory with %d."), lResult));
- bResult = FALSE;
- goto Exit;
- }
- for ( i=0; i<dwCount; i++ ) {
- wsprintf( szGroup, TEXT("Group%d"), i );
- dwSize = dwMaxSize;
- lResult = RegQueryValueEx (hKeyRead, szGroup, NULL, &dwType, (LPBYTE) lpSid, &dwSize);
- if (lResult != ERROR_SUCCESS) {
- DebugMsg((DM_WARNING, TEXT("MigrateMembershipData: Failed to read value %ws"), szGroup ));
- goto Exit;
- }
- dwSize = (lstrlen(lpSid) + 1) * sizeof(TCHAR);
- lResult = RegSetValueEx (hKeyWrite, szGroup, 0, REG_SZ, (LPBYTE) lpSid, dwSize);
- if (lResult != ERROR_SUCCESS) {
- bResult = FALSE;
- DebugMsg((DM_WARNING, TEXT("MigrateMembershipData: Failed to write value %ws"), szGroup ));
- goto Exit;
- }
- }
- dwSize = sizeof(dwCount);
- lResult = RegSetValueEx (hKeyWrite, TEXT("Count"), 0, REG_DWORD, (LPBYTE) &dwCount, dwSize);
- if (lResult != ERROR_SUCCESS) {
- bResult = FALSE;
- DebugMsg((DM_WARNING, TEXT("MigrateMembershipData: Failed to write count value") ));
- goto Exit;
- }
- Exit:
- if ( lpSid )
- LocalFree( lpSid );
- if ( hKeyRead )
- RegCloseKey (hKeyRead);
- if ( hKeyWrite )
- RegCloseKey (hKeyWrite);
- return bResult;
- }
- //*************************************************************
- //
- // MigrateGPOData()
- //
- // Purpose: Moves cached GPOs from old sid to new
- // sid.
- //
- // Parameters: lpGPOInfo - GPOInfo
- // lpwszSidUserNew - New sid
- // lpwszSidUserOld - Old sid
- //
- // Return: TRUE if success
- // FALSE otherwise
- //
- //*************************************************************
- BOOL MigrateGPOData( LPGPOINFO lpGPOInfo, LPTSTR lpwszSidUserNew, LPTSTR lpwszSidUserOld )
- {
- TCHAR szKey[250];
- LONG lResult;
- HKEY hKey = NULL;
- DWORD dwIndex = 0;
- TCHAR szExtension[50];
- DWORD dwSize = 50;
- FILETIME ftWrite;
- PGROUP_POLICY_OBJECT pGPOList, lpGPO, lpGPOTemp;
- BOOL bResult;
- wsprintf( szKey, GP_HISTORY_SID_ROOT_KEY, lpwszSidUserOld );
- lResult = RegOpenKeyEx (HKEY_LOCAL_MACHINE, szKey, 0, KEY_READ, &hKey);
- if ( lResult != ERROR_SUCCESS )
- return TRUE;
- while (RegEnumKeyEx (hKey, dwIndex, szExtension, &dwSize,
- NULL, NULL, NULL, &ftWrite) == ERROR_SUCCESS ) {
- if ( ReadGPOList( szExtension, NULL, HKEY_LOCAL_MACHINE,
- lpwszSidUserOld, FALSE, &pGPOList) ) {
- bResult = SaveGPOList( szExtension, lpGPOInfo, HKEY_LOCAL_MACHINE,
- lpwszSidUserNew, FALSE, pGPOList );
- lpGPO = pGPOList;
- while (lpGPO) {
- lpGPOTemp = lpGPO->pNext;
- LocalFree (lpGPO);
- lpGPO = lpGPOTemp;
- }
- if ( !bResult ) {
- DebugMsg((DM_WARNING, TEXT("MigrateGPOData: Failed to save GPO list") ));
- RegCloseKey( hKey );
- return FALSE;
- }
- }
- dwSize = ARRAYSIZE(szExtension);
- dwIndex++;
- }
- RegCloseKey( hKey );
- return TRUE;
- }
- //*************************************************************
- //
- // MigrateStatusData()
- //
- // Purpose: Moves extension status data from old sid to new
- // sid.
- //
- // Parameters: lpGPOInfo - GPOInfo
- // lpwszSidUserNew - New sid
- // lpwszSidUserOld - Old sid
- //
- // Return: TRUE if success
- // FALSE otherwise
- //
- //*************************************************************
- BOOL MigrateStatusData( LPGPOINFO lpGPOInfo, LPTSTR lpwszSidUserNew, LPTSTR lpwszSidUserOld )
- {
- TCHAR szKey[250];
- LONG lResult;
- HKEY hKey = NULL;
- DWORD dwIndex = 0;
- TCHAR szExtension[50];
- DWORD dwSize = 50;
- FILETIME ftWrite;
- BOOL bTemp;
- DWORD dwStatus, dwTime, dwSlowLink;
- wsprintf( szKey, GP_EXTENSIONS_SID_ROOT_KEY, lpwszSidUserOld );
- lResult = RegOpenKeyEx (HKEY_LOCAL_MACHINE, szKey, 0, KEY_READ, &hKey);
- if ( lResult != ERROR_SUCCESS )
- return TRUE;
- while (RegEnumKeyEx (hKey, dwIndex, szExtension, &dwSize,
- NULL, NULL, NULL, &ftWrite) == ERROR_SUCCESS ) {
- if ( ReadStatus( szExtension, lpGPOInfo, lpwszSidUserOld, &dwStatus, &dwTime, &dwSlowLink ) ) {
- bTemp = WriteStatus( szExtension, lpGPOInfo, lpwszSidUserNew, dwStatus, dwTime, dwSlowLink );
- if ( !bTemp ) {
- DebugMsg((DM_WARNING, TEXT("MigrateStatusData: Failed to save status") ));
- RegCloseKey( hKey );
- return FALSE;
- }
- }
- dwSize = ARRAYSIZE(szExtension);
- dwIndex++;
- }
- RegCloseKey( hKey );
- return TRUE;
- }
- //*************************************************************
- //
- // CheckForChangedSid()
- //
- // Purpose: Checks if the user's sid has changed and if so,
- // moves history data from old sid to new sid.
- //
- // Parameters: lpGPOInfo - GPOInfo
- //
- // Return: TRUE if success
- // FALSE otherwise
- //