|
|
//*************************************************************
//
// Group Policy Support for planning mode
//
// Microsoft Confidential
// Copyright (c) Microsoft Corporation 1997-1998
// All rights reserved
//
//*************************************************************
#include "gphdr.h"
#include <strsafe.h>
DWORD GenerateRegistryPolicy( DWORD dwFlags, BOOL *pbAbort, WCHAR *pwszSite, PRSOP_TARGET pComputerTarget, PRSOP_TARGET pUserTarget );
BOOL GenerateGpoInfo( WCHAR *pwszDomain, WCHAR *pwszDomainDns, WCHAR *pwszAccount, WCHAR *pwszNewSOM, SAFEARRAY *psaSecGroups, DWORD dwFlags, BOOL bMachine, WCHAR *pwszSite, CGpoFilter *pGpoFilter, CLocator *pLocator, WCHAR *pwszMachAccount, WCHAR *pwszNewMachSOM, LPGPOINFO pGpoInfo, PNETAPI32_API pNetAPI32 );
BOOL GetCategory( WCHAR *pwszDomain, WCHAR *pwszAccount, WCHAR **ppwszDNName );
extern "C" DWORD ProcessMachAndUserGpoList( LPGPEXT lpExtMach, LPGPEXT lpExtUser, DWORD dwFlags, WCHAR *pwszSite, WCHAR *pwszMach, WCHAR *pwszNewComputerOU, SAFEARRAY *psaComputerSecurityGroups, LPGPOINFO pGpoInfoMach, WCHAR *pwszUser, WCHAR *pwszNewUserOU, SAFEARRAY *psaUserSecurityGroups, LPGPOINFO pGpoInfoUser );
BOOL ProcessRegistryFiles(PRSOP_TARGET pTarget, REGHASHTABLE *pHashTable); BOOL ProcessRegistryValue ( void* pUnused, LPTSTR lpKeyName, LPTSTR lpValueName, DWORD dwType, DWORD dwDataLength, LPBYTE lpData, WCHAR *pwszGPO, WCHAR *pwszSOM, REGHASHTABLE *pHashTable); BOOL ProcessAdmData( PRSOP_TARGET pTarget, BOOL bUser );
//*************************************************************
//
// GenerateRsopPolicy()
//
// Purpose: Generates planning mode Rsop policy for specified target
//
// Parameters: dwFlags - Processing flags
// bstrMachName - Target computer name
// bstrNewMachSOM - New machine domain or OU
// psaMachSecGroups - New machine security groups
// bstrUserName - Target user name
// psaUserSecGroups - New user security groups
// bstrSite - Site of target computer
// pwszNameSpace - Namespace to write Rsop data
// pvProgress - Progress indicator class
// pvGpoFilter - GPO filter class
//
// Return: True if successful, False otherwise
//
// Notes: If a new SOM is specified then that is used instead of
// the SOM the target belongs to. Similarly, if new
// security groups are specified then that is used instead of
// the security groups that the target belongs to. If
// target name is null and both new SOM and new security
// groups are non-null, then we simulate a dummy target; otherwise
// we skip generating planning mode info for the target.
//
//*************************************************************
BOOL GenerateRsopPolicy( DWORD dwFlags, BSTR bstrMachName, BSTR bstrNewMachSOM, SAFEARRAY *psaMachSecGroups, BSTR bstrUserName, BSTR bstrNewUserSOM, SAFEARRAY *psaUserSecGroups, BSTR bstrSite, WCHAR *pwszNameSpace, LPVOID pvProgress, LPVOID pvMachGpoFilter, LPVOID pvUserGpoFilter ) { LPGPOINFO pGpoInfoMach = NULL; LPGPOINFO pGpoInfoUser = NULL; PNETAPI32_API pNetAPI32 = NULL; PDSROLE_PRIMARY_DOMAIN_INFO_BASIC pDsInfo = NULL; BOOL bDC = FALSE; DWORD dwResult; LPWSTR pwszDomain = NULL; LPWSTR pwszMachDns = NULL; LPWSTR pwszDomainDns = NULL; DWORD dwSize = 0; BOOL bResult = FALSE; LPGPEXT lpExtMach = NULL; LPGPEXT lpExtUser = NULL; LPGPEXT lpExt,lpTemp = NULL; WCHAR *pwszMach = (WCHAR *) bstrMachName; WCHAR *pwszUser = (WCHAR *) bstrUserName; DWORD dwExtCount = 1; DWORD dwIncrPercent; CProgressIndicator* pProgress = (CProgressIndicator*) pvProgress; CGpoFilter *pMachGpoFilter = (CGpoFilter *) pvMachGpoFilter; CGpoFilter *pUserGpoFilter = (CGpoFilter *) pvUserGpoFilter; RSOPSESSIONDATA rsopSessionData; LPRSOPSESSIONDATA lprsopSessionData; BOOL bDummyMach = pwszMach == NULL && bstrNewMachSOM != NULL; BOOL bDummyUser = pwszUser == NULL && bstrNewUserSOM != NULL; DWORD dwUserGPCoreError = ERROR_SUCCESS; DWORD dwMachGPCoreError = ERROR_SUCCESS; CLocator locator; HRESULT hr = S_OK; XLastError xe;
//
// Allow debugging level to be changed dynamically
//
InitDebugSupport( FALSE );
if ( pwszUser == NULL && pwszMach == NULL && !bDummyUser && !bDummyMach ) { DebugMsg((DM_WARNING, TEXT("GenerateRsopPolicy: Both user and machine names cannot be NULL."))); xe = ERROR_INVALID_PARAMETER; return FALSE; }
pNetAPI32 = LoadNetAPI32();
if (!pNetAPI32) { xe = GetLastError(); DebugMsg((DM_WARNING, TEXT("GenerateRsopPolicy: Failed to load netapi32 with %d."), GetLastError())); // error logged in LoadNetAPI32
goto Exit; }
//
// Get the role of this computer
//
dwResult = pNetAPI32->pfnDsRoleGetPrimaryDomainInformation( NULL, DsRolePrimaryDomainInfoBasic, (PBYTE *)&pDsInfo );
if (dwResult != ERROR_SUCCESS) { xe = GetLastError(); DebugMsg((DM_WARNING, TEXT("GenerateRsopPolicy: DsRoleGetPrimaryDomainInformation failed with %d."), dwResult)); goto Exit; }
if ( pDsInfo->MachineRole == DsRole_RoleBackupDomainController || pDsInfo->MachineRole == DsRole_RolePrimaryDomainController ) { bDC = TRUE; }
if ( !bDC ) { xe = ERROR_ACCESS_DENIED; DebugMsg((DM_WARNING, TEXT("GeneratRsopPolicy: Rsop data can be generated on a DC only"))); goto Exit; }
pwszDomain = pDsInfo->DomainNameFlat;
//
// Get the machine name in dns format, so that ldap_bind can be done to this specific DC.
//
dwSize = 0; GetComputerNameEx( ComputerNameDnsFullyQualified, pwszMachDns, &dwSize );
if ( dwSize > 0 ) {
pwszMachDns = (WCHAR *) LocalAlloc (LPTR, dwSize * sizeof(WCHAR) ); if ( pwszMachDns == NULL ) { xe = GetLastError(); DebugMsg((DM_WARNING, TEXT("GenerateRsopPolicy: Failed to allocate memory"))); goto Exit; }
} else { xe = GetLastError(); DebugMsg((DM_WARNING, TEXT("GenerateRsopPolicy: GetComputerNameEx failed"))); goto Exit; }
bResult = GetComputerNameEx( ComputerNameDnsFullyQualified, pwszMachDns, &dwSize ); if ( !bResult ) { xe = GetLastError(); DebugMsg((DM_WARNING, TEXT("GenerateRsopPolicy: GetComputerNameEx failed"))); goto Exit; }
pwszDomainDns = pwszMachDns;
//
// 5% of the task is done
//
pProgress->IncrementBy( 5 );
//
// Setup computer target info, if any
//
bResult = FALSE;
if ( pwszMach || bDummyMach ) {
pGpoInfoMach = (LPGPOINFO) LocalAlloc (LPTR, sizeof(GPOINFO));
if (!pGpoInfoMach) { xe = GetLastError(); DebugMsg((DM_WARNING, TEXT("GenerateGpoInfo: Failed to alloc lpGPOInfo (%d)."), GetLastError())); CEvents ev(TRUE, EVENT_FAILED_ALLOCATION); ev.AddArgWin32Error(GetLastError()); ev.Report(); goto Exit; }
pGpoInfoMach->dwFlags = GP_PLANMODE | GP_MACHINE;
bResult = GetWbemServices( pGpoInfoMach, pwszNameSpace, TRUE, NULL, &(pGpoInfoMach->pWbemServices) ); if (!bResult) { xe = GetLastError(); DebugMsg((DM_WARNING, TEXT("GenerateRsopPolicy: Error when getting Wbemservices."))); goto Exit; }
//
// First set dirty to be true
//
bResult = LogExtSessionStatus(pGpoInfoMach->pWbemServices, NULL, TRUE); if (!bResult) { xe = GetLastError(); DebugMsg((DM_WARNING, TEXT("GenerateRsopPolicy: Error when logging user Session data."))); goto Exit; }
if ( ! GenerateGpoInfo( pwszDomain, pwszDomainDns, pwszMach, (WCHAR *) bstrNewMachSOM, psaMachSecGroups, dwFlags, TRUE, (WCHAR *) bstrSite, pMachGpoFilter, &locator, NULL, NULL, pGpoInfoMach, pNetAPI32 ) ) { xe = GetLastError(); DebugMsg((DM_WARNING, TEXT("GenerateRsopPolicy: GenerateGpoInfo failed with %d."), xe)); dwMachGPCoreError = (xe) ? xe : E_FAIL; } else { dwMachGPCoreError = ERROR_SUCCESS; }
}
//
// 10% of the task is done
//
pProgress->IncrementBy( 5 );
//
// Setup user target info, if any
//
if ( pwszUser || bDummyUser ) { pGpoInfoUser = (LPGPOINFO) LocalAlloc (LPTR, sizeof(GPOINFO));
if (!pGpoInfoUser) { xe = GetLastError(); DebugMsg((DM_WARNING, TEXT("GenerateGpoInfo: Failed to alloc lpGPOInfo (%d)."), GetLastError())); CEvents ev(TRUE, EVENT_FAILED_ALLOCATION); ev.AddArgWin32Error(GetLastError()); ev.Report(); goto Exit; }
pGpoInfoUser->dwFlags = GP_PLANMODE;
bResult = GetWbemServices( pGpoInfoUser, pwszNameSpace, TRUE, NULL, &(pGpoInfoUser->pWbemServices)); if (!bResult) { xe = GetLastError(); DebugMsg((DM_WARNING, TEXT("GenerateRsopPolicy: Error when getting Wbemservices."))); goto Exit; }
//
// First set dirty to be true
//
bResult = LogExtSessionStatus(pGpoInfoUser->pWbemServices, NULL, TRUE); if (!bResult) { xe = GetLastError(); DebugMsg((DM_WARNING, TEXT("GenerateRsopPolicy: Error when logging user Session data."))); goto Exit; }
if ( ! GenerateGpoInfo( pwszDomain, pwszDomainDns, pwszUser, (WCHAR *) bstrNewUserSOM, psaUserSecGroups, dwFlags, FALSE, (WCHAR *) bstrSite, pUserGpoFilter, &locator, pwszMach, (WCHAR *) bstrNewMachSOM, pGpoInfoUser, pNetAPI32 ) ) { xe = GetLastError(); DebugMsg((DM_WARNING, TEXT("GenerateRsopPolicy: GenerateGpoInfo failed with %d."), xe)); dwUserGPCoreError = (xe) ? xe : E_FAIL; } else { dwUserGPCoreError = ERROR_SUCCESS; } }
//
// Log Gpo info to WMI's database
//
lprsopSessionData = &rsopSessionData;
if ( pwszMach || bDummyMach ) {
XPtrLF<TOKEN_GROUPS> xGrps;
if ( pGpoInfoMach->pRsopToken != NULL ) { hr = RsopSidsFromToken(pGpoInfoMach->pRsopToken, &xGrps);
if (FAILED(hr)) { xe = HRESULT_CODE(hr); DebugMsg((DM_WARNING, TEXT("GenerateRsopPolicy: RsopSidsFromToken failed with error 0x%x."), hr)); goto Exit;
} }
//
// Fill up the rsop Session Data (Machine Specific)
//
//
// Add the relevant flags corresponding to the input parameters for machine
//
DebugMsg((DM_VERBOSE, TEXT("GenerateRsopPolicy: Marking the flags for machine with appropriate input parameters")));
lprsopSessionData->dwFlags = FLAG_PLANNING_MODE; lprsopSessionData->dwFlags |= (dwFlags & FLAG_ASSUME_COMP_WQLFILTER_TRUE);
lprsopSessionData->pwszTargetName = pwszMach; lprsopSessionData->pwszSOM = GetSomPath(bstrNewMachSOM ? bstrNewMachSOM : pGpoInfoMach->lpDNName); if ( pGpoInfoMach->pRsopToken != NULL ) { lprsopSessionData->pSecurityGroups = (PTOKEN_GROUPS)xGrps; lprsopSessionData->bLogSecurityGroup = TRUE; } else { lprsopSessionData->pSecurityGroups = 0; lprsopSessionData->bLogSecurityGroup = FALSE; } lprsopSessionData->pwszSite = (WCHAR *) bstrSite; lprsopSessionData->bMachine = TRUE; lprsopSessionData->bSlowLink = ( dwFlags & FLAG_ASSUME_SLOW_LINK ) ? TRUE: FALSE;
bResult = LogRsopData( pGpoInfoMach, lprsopSessionData ); if (!bResult) { xe = GetLastError(); DebugMsg((DM_WARNING, TEXT("GenerateRsopPolicy: Error when logging machine Rsop data."))); goto Exit; }
pGpoInfoMach->bRsopLogging = TRUE; }
if ( pwszUser || bDummyUser ) { XPtrLF<TOKEN_GROUPS> xGrps;
if ( pGpoInfoUser->pRsopToken != NULL ) { hr = RsopSidsFromToken(pGpoInfoUser->pRsopToken, &xGrps);
if (FAILED(hr)) { xe = HRESULT_CODE(hr); DebugMsg((DM_WARNING, TEXT("GenerateRsopPolicy: RsopSidsFromToken failed with error 0x%x."), hr)); goto Exit;
} }
//
// Fill up the rsop Session Data (User Specific)
//
lprsopSessionData->pwszTargetName = pwszUser; lprsopSessionData->pwszSOM = GetSomPath(bstrNewUserSOM ? bstrNewUserSOM : pGpoInfoUser->lpDNName); //
// Add the relevant flags corresponding to the input parameters for user
//
lprsopSessionData->dwFlags = FLAG_PLANNING_MODE; lprsopSessionData->dwFlags |= (dwFlags & FLAG_ASSUME_USER_WQLFILTER_TRUE); lprsopSessionData->dwFlags |= (dwFlags & FLAG_LOOPBACK_MERGE); lprsopSessionData->dwFlags |= (dwFlags & FLAG_LOOPBACK_REPLACE); DebugMsg((DM_VERBOSE, TEXT("GenerateRsopPolicy: Marking the flags for user with appropriate input parameters")));
if ( pGpoInfoUser->pRsopToken != NULL ) { lprsopSessionData->pSecurityGroups = (PTOKEN_GROUPS)xGrps; lprsopSessionData->bLogSecurityGroup = TRUE; } else { lprsopSessionData->pSecurityGroups = 0; lprsopSessionData->bLogSecurityGroup = FALSE; } lprsopSessionData->pwszSite = (WCHAR *) bstrSite; lprsopSessionData->bMachine = FALSE; lprsopSessionData->bSlowLink = ( dwFlags & FLAG_ASSUME_SLOW_LINK ) ? TRUE: FALSE;
bResult = LogRsopData( pGpoInfoUser, lprsopSessionData ); if (!bResult) { xe = GetLastError(); DebugMsg((DM_WARNING, TEXT("GenerateRsopPolicy: Error when logging user Rsop data."))); goto Exit; } pGpoInfoUser->bRsopLogging = TRUE; }
if ( ( dwUserGPCoreError != ERROR_SUCCESS) || ( dwMachGPCoreError != ERROR_SUCCESS) ){ DebugMsg((DM_WARNING, TEXT("GenerateRsopPolicy: Couldn't fetch the user/computer GPO list. Exitting provider."))); // note that at this point bResult can be true and we want to actually return that
// since this error will be part of the GP Core error...
goto Exit; }
//
// 15% of the task is done
//
pProgress->IncrementBy( 5 );
if ( dwFlags & FLAG_NO_CSE_INVOKE ) { bResult = TRUE; goto Exit; }
//
// By this time, pGPOInfoMach should be defined if
// we needed data for mach and pGPOInfoUser should be
// defined if we needed the data for user.
//
// Assumption: lpExt is the same for both user and Machine
//
if (pGpoInfoMach) lpExt = lpExtMach = pGpoInfoMach->lpExtensions;
if (pGpoInfoUser) lpExt = lpExtUser = pGpoInfoUser->lpExtensions;
//
// count the number of extensions
//
DmAssert(lpExt);
lpTemp = lpExt;
while ( lpExt ) { dwExtCount++; lpExt = lpExt->pNext; }
lpExt = lpTemp;
dwIncrPercent = ( pProgress->MaxProgress() - pProgress->CurrentProgress() ) / dwExtCount;
//
// Loop through registered extensions, asking them to generate planning mode info
//
while ( lpExt ) {
//
// Add check here for cancellation of policy generation
//
DebugMsg((DM_VERBOSE, TEXT("GenerateRsopPolicy: -----------------------"))); DebugMsg((DM_VERBOSE, TEXT("GenerateRsopPolicy: Processing extension %s"), lpExt->lpDisplayName));
if (lpExtMach) FilterGPOs( lpExtMach, pGpoInfoMach );
if (lpExtUser) FilterGPOs( lpExtUser, pGpoInfoUser );
__try {
dwResult = ProcessMachAndUserGpoList( lpExtMach, lpExtUser, dwFlags, (WCHAR *) bstrSite, pwszMach, (WCHAR *) bstrNewMachSOM, psaMachSecGroups, pGpoInfoMach, pwszUser, (WCHAR *) bstrNewUserSOM, psaUserSecGroups, pGpoInfoUser ); pProgress->IncrementBy( dwIncrPercent );
} __except( GPOExceptionFilter( GetExceptionInformation() ) ) {
RevertToSelf();
DebugMsg((DM_WARNING, TEXT("GenerateRsopPolicy: Extension %s ProcessGroupPolicy threw unhandled exception 0x%x."), lpExt->lpDisplayName, GetExceptionCode() ));
CEvents ev(TRUE, EVENT_CAUGHT_EXCEPTION); ev.AddArg(lpExt->lpDisplayName); ev.AddArgHex(GetExceptionCode()); ev.Report(); }
DebugMsg((DM_VERBOSE, TEXT("GenerateRsopPolicy: -----------------------")));
if (lpExtMach) lpExtMach = lpExtMach->pNext;
if (lpExtUser) lpExtUser = lpExtUser->pNext;
lpExt = lpExt->pNext; }
bResult = TRUE;
Exit:
//
// if all logging was successful
//
if ((pGpoInfoUser) && (pGpoInfoUser->bRsopLogging)) { bResult = UpdateExtSessionStatus(pGpoInfoUser->pWbemServices, NULL, (!bResult), dwUserGPCoreError ); }
if ((pGpoInfoMach) && (pGpoInfoMach->bRsopLogging)) { bResult = UpdateExtSessionStatus(pGpoInfoMach->pWbemServices, NULL, (!bResult), dwMachGPCoreError); }
UnloadGPExtensions( pGpoInfoMach ); UnloadGPExtensions( pGpoInfoUser ); // Frees lpExtensions field
if ( pDsInfo ) { pNetAPI32->pfnDsRoleFreeMemory (pDsInfo); }
LocalFree( pwszMachDns );
FreeGpoInfo( pGpoInfoUser ); FreeGpoInfo( pGpoInfoMach );
return bResult; }
//*************************************************************
//
// GenerateGpoInfo()
//
// Purpose: Allocates and fills in pGpoInfo for specified target
//
// Parameters: pwszDomain - Domain name
// pwszDomainDns - Dns name of machine for ldap binding
// pwszAccount - User or machine account name
// pwszNewSOM - New SOM of target
// psaSecGroups - New security groups of target
// dwFlags - Processing flags
// bMachine - Is this machine processing
// pwszSite - Site name
// pGpoFilter - Gpo filter
// pLocator - Wbem interface class
// pwszMachAccount - Machine account
// pwszNewMachSOM - Machine SOM (abv 2 are applicable only for loopback)
// ppGpoInfo - Gpo info returned here
// pNetApi32 - Delay loaded netap32.dll
//
// Return: True if successful, False otherwise
//
//*************************************************************
BOOL GenerateGpoInfo( WCHAR *pwszDomain, WCHAR *pwszDomainDns, WCHAR *pwszAccount, WCHAR *pwszNewSOM, SAFEARRAY *psaSecGroups, DWORD dwFlags, BOOL bMachine, WCHAR *pwszSite, CGpoFilter *pGpoFilter, CLocator *pLocator, WCHAR *pwszMachAccount, WCHAR *pwszNewMachSOM, LPGPOINFO pGpoInfo, PNETAPI32_API pNetAPI32 ) { HRESULT hr; BOOL bResult = FALSE; XPtrLF<WCHAR> xszXlatName; PSECUR32_API pSecur32; XLastError xe; DWORD dwError = ERROR_SUCCESS; XPtrLF<WCHAR> xwszTargetDomain; DWORD dwUserPolicyMode = 0; DWORD dwLocFlags;
if (!bMachine) { if (dwFlags & FLAG_LOOPBACK_MERGE ) { dwUserPolicyMode = 1; } else if (dwFlags & FLAG_LOOPBACK_REPLACE ) { dwUserPolicyMode = 2; } }
dwLocFlags = GP_PLANMODE | (dwFlags & FLAG_ASSUME_COMP_WQLFILTER_TRUE) | (dwFlags & FLAG_ASSUME_USER_WQLFILTER_TRUE);
//
// Load secur32.dll
//
pSecur32 = LoadSecur32();
if (!pSecur32) { xe = GetLastError(); DebugMsg((DM_WARNING, TEXT("GenerateGpoInfo: Failed to load Secur32."))); return NULL; }
if ( pwszAccount == NULL ) { if ( pwszNewSOM == NULL ) {
//
// When dummy user is specified then both SOM and security groups
// must be specified.
//
xe = GetLastError(); DebugMsg((DM_WARNING, TEXT("GenerateGpoInfo: Incorrect SOM or security specification for dummy target"), GetLastError())); goto Exit; } }
if ( bMachine ) dwFlags |= GP_MACHINE;
dwFlags |= GP_PLANMODE; // mark the processing as planning mode processing
pGpoInfo->dwFlags = dwFlags;
//
// caller can force slow link in planning mode
//
if ( dwFlags & FLAG_ASSUME_SLOW_LINK ) { pGpoInfo->dwFlags |= GP_SLOW_LINK; } else { pGpoInfo->dwFlags &= ~GP_SLOW_LINK; }
if ( pwszAccount ) { if ( !GetCategory( pwszDomain, pwszAccount, &pGpoInfo->lpDNName ) ) { xe = GetLastError(); DebugMsg((DM_WARNING, TEXT("GenerateGpoInfo - getCategory failed with error - %d"), GetLastError())); goto Exit; } }
//
// TranslateName to SamCompatible so that the rest of the functions work correctly
// for any of the various name formats
//
if ( pwszAccount ) { DWORD dwSize = MAX_PATH+1;
xszXlatName = (LPWSTR)LocalAlloc(LPTR, sizeof(WCHAR)*dwSize);
if (!xszXlatName) { xe = GetLastError(); DebugMsg((DM_WARNING, TEXT("GenerateGpoInfo - Couldn't allocate memory for Name..."))); goto Exit; }
if (!pSecur32->pfnTranslateName( pwszAccount, NameUnknown, NameSamCompatible, xszXlatName, &dwSize )) {
BOOL bOk = FALSE;
if (dwSize > (MAX_PATH+1)) {
xszXlatName = (LPWSTR)LocalAlloc(LPTR, sizeof(WCHAR)*dwSize);
if (!xszXlatName) { xe = GetLastError(); DebugMsg((DM_WARNING, TEXT("GenerateGpoInfo - Couldn't allocate memory for Name..."))); goto Exit; }
bOk = pSecur32->pfnTranslateName( pwszAccount, NameUnknown, NameSamCompatible, xszXlatName, &dwSize );
}
if (!bOk) { xe = GetLastError(); DebugMsg((DM_WARNING, TEXT("GenerateGpoInfo - TranslateName failed with error %d"), GetLastError())); goto Exit; } } DebugMsg((DM_VERBOSE, TEXT("GenerateGpoInfo: RsopCreateToken for Account Name <%s>"), (LPWSTR)xszXlatName)); }
hr = RsopCreateToken( xszXlatName, psaSecGroups, &pGpoInfo->pRsopToken ); if ( FAILED(hr) ) { xe = HRESULT_CODE(hr); DebugMsg((DM_WARNING, TEXT("GenerateGpoInfo: Failed to create Rsop token. Error - %d"), HRESULT_CODE(hr))); goto Exit; }
dwError = GetDomain(pwszNewSOM ? pwszNewSOM : pGpoInfo->lpDNName, &xwszTargetDomain);
if (dwError != ERROR_SUCCESS) { xe = dwError; DebugMsg((DM_WARNING, TEXT("GenerateGpoInfo: Failed to Get domain. Error - %d"), dwError)); 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("GenerateGpoInfo: Calling GetGPOInfo for normal policy mode")));
bResult = GetGPOInfo( dwLocFlags | ((pGpoInfo->dwFlags & GP_MACHINE) ? GPO_LIST_FLAG_MACHINE : 0), xwszTargetDomain, pwszNewSOM ? pwszNewSOM : pGpoInfo->lpDNName, NULL, &pGpoInfo->lpGPOList, &pGpoInfo->lpSOMList, &pGpoInfo->lpGpContainerList, pNetAPI32, FALSE, pGpoInfo->pRsopToken, pwszSite, pGpoFilter, pLocator ); if ( !bResult ) { xe = GetLastError(); DebugMsg((DM_WARNING, TEXT("GenerateGpoInfo: GetGPOInfo failed."))); CEvents ev( TRUE, EVENT_GPO_QUERY_FAILED ); ev.Report(); goto Exit; } } else if (dwUserPolicyMode == 2) { XPtrLF<TCHAR> xMachDNName; XPtrLF<TCHAR> xwszMachDomain;
DebugMsg((DM_VERBOSE, TEXT("ProcessGPOs: Calling GetGPOInfo for replacement user policy mode")));
if ( pwszMachAccount ) { if ( !GetCategory( pwszDomain, pwszMachAccount, &xMachDNName ) ) { xe = GetLastError(); DebugMsg((DM_WARNING, TEXT("GenerateGpoInfo - getCategory failed with error - %d"), GetLastError())); goto Exit; } }
dwError = GetDomain(pwszNewMachSOM ? pwszNewMachSOM : xMachDNName, &xwszMachDomain);
if (dwError != ERROR_SUCCESS) { xe = dwError; DebugMsg((DM_WARNING, TEXT("GenerateGpoInfo: Failed to Get domain. Error - %d"), dwError)); goto Exit; }
bResult = GetGPOInfo( dwLocFlags | 0, xwszMachDomain, pwszNewMachSOM ? pwszNewMachSOM : xMachDNName, NULL, &pGpoInfo->lpGPOList, &pGpoInfo->lpLoopbackSOMList, &pGpoInfo->lpLoopbackGpContainerList, pNetAPI32, FALSE, pGpoInfo->pRsopToken, pwszSite, pGpoFilter, pLocator ); if ( !bResult ) { xe = GetLastError(); DebugMsg((DM_WARNING, TEXT("GenerateGpoInfo: GetGPOInfo failed."))); CEvents ev( TRUE, EVENT_GPO_QUERY_FAILED ); ev.Report(); goto Exit; } } else { XPtrLF<TCHAR> xMachDNName; XPtrLF<TCHAR> xwszMachDomain; PGROUP_POLICY_OBJECT lpGPO = NULL; PGROUP_POLICY_OBJECT lpGPOTemp;
DebugMsg((DM_VERBOSE, TEXT("ProcessGPOs: Calling GetGPOInfo for merging user policy mode"))); bResult = GetGPOInfo( dwLocFlags | ((pGpoInfo->dwFlags & GP_MACHINE) ? GPO_LIST_FLAG_MACHINE : 0), xwszTargetDomain, pwszNewSOM ? pwszNewSOM : pGpoInfo->lpDNName, NULL, &pGpoInfo->lpGPOList, &pGpoInfo->lpSOMList, &pGpoInfo->lpGpContainerList, pNetAPI32, FALSE, pGpoInfo->pRsopToken, pwszSite, pGpoFilter, pLocator ); if ( !bResult ) { xe = GetLastError(); DebugMsg((DM_WARNING, TEXT("GenerateGpoInfo: GetGPOInfo failed."))); CEvents ev( TRUE, EVENT_GPO_QUERY_FAILED ); ev.Report(); goto Exit; }
if ( pwszMachAccount ) { if ( !GetCategory( pwszDomain, pwszMachAccount, &xMachDNName ) ) { xe = GetLastError(); DebugMsg((DM_WARNING, TEXT("GenerateGpoInfo - getCategory failed with error - %d"), GetLastError())); goto Exit; } }
dwError = GetDomain(pwszNewMachSOM ? pwszNewMachSOM : xMachDNName, &xwszMachDomain);
if (dwError != ERROR_SUCCESS) { xe = dwError; DebugMsg((DM_WARNING, TEXT("GenerateGpoInfo: Failed to Get domain. Error - %d"), dwError)); goto Exit; }
bResult = GetGPOInfo( 0 | dwLocFlags, xwszMachDomain, pwszNewMachSOM ? pwszNewMachSOM : xMachDNName, NULL, &lpGPO, &pGpoInfo->lpLoopbackSOMList, &pGpoInfo->lpLoopbackGpContainerList, pNetAPI32, FALSE, pGpoInfo->pRsopToken, pwszSite, pGpoFilter, pLocator ); if ( !bResult ) { xe = GetLastError(); DebugMsg((DM_WARNING, TEXT("GenerateGpoInfo: GetGPOInfo failed."))); CEvents ev( TRUE, EVENT_GPO_QUERY_FAILED ); ev.Report(); goto Exit; }
if (pGpoInfo->lpGPOList && lpGPO) {
DebugMsg((DM_VERBOSE, TEXT("GenerateGpoInfo: Both user and machine lists are defined. Merging them together.")));
//
// Need to merge the lists together
//
lpGPOTemp = pGpoInfo->lpGPOList;
while (lpGPOTemp->pNext) { lpGPOTemp = lpGPOTemp->pNext; }
lpGPOTemp->pNext = lpGPO;
} else if (!pGpoInfo->lpGPOList && lpGPO) {
DebugMsg((DM_VERBOSE, TEXT("GenerateGpoInfo: Only machine list is defined."))); pGpoInfo->lpGPOList = lpGPO;
} else {
DebugMsg((DM_VERBOSE, TEXT("GenerateGpoInfo: Only user list is defined."))); } }
if ( !ReadGPExtensions( pGpoInfo ) ) { xe = GetLastError(); DebugMsg((DM_WARNING, TEXT("GenerateGpoInfo: ReadGPExtensions failed."))); CEvents ev( TRUE, EVENT_READ_EXT_FAILED ); ev.Report(); goto Exit; }
if ( !CheckForSkippedExtensions( pGpoInfo, TRUE ) ) { xe = GetLastError(); DebugMsg((DM_WARNING, TEXT("GenerateGpoInfo: Checking extensions for skipping failed"))); goto Exit; }
bResult = SetupGPOFilter( pGpoInfo );
if ( !bResult ) { xe = GetLastError(); DebugMsg((DM_WARNING, TEXT("GenerateGpoInfo: SetupGPOFilter failed."))); CEvents ev(TRUE, EVENT_SETUP_GPOFILTER_FAILED); ev.Report(); goto Exit; }
Exit:
return bResult; }
//*************************************************************
//
// GetCategory()
//
// Purpose: Gets the fully qualified domain name
//
// Parameters: pwszDomain - Domain name
// pwszAccount - User or machine account name
// pwszDNName - Fully qualified domain name returned here
//
// Return: True if successful, False otherwise
//
//*************************************************************
BOOL GetCategory( WCHAR *pwszDomain, WCHAR *pwszAccount, WCHAR **ppwszDNName ) { PSECUR32_API pSecur32Api; BOOL bResult = FALSE; ULONG ulSize = 512; XLastError xe;
*ppwszDNName = NULL;
*ppwszDNName = (WCHAR *) LocalAlloc (LPTR, ulSize * sizeof(WCHAR) ); if ( *ppwszDNName == NULL ) { xe = GetLastError(); DebugMsg((DM_WARNING, TEXT("GetCategory: Memory allocation failed."))); goto Exit; }
pSecur32Api = LoadSecur32();
if (!pSecur32Api) { xe = GetLastError(); DebugMsg((DM_WARNING, TEXT("GetCategory: Failed to load secur32 api."))); goto Exit; }
bResult = pSecur32Api->pfnTranslateName( pwszAccount, NameUnknown, NameFullyQualifiedDN, *ppwszDNName, &ulSize );
if ( !bResult && ulSize > 0 ) {
LocalFree( *ppwszDNName ); *ppwszDNName = (WCHAR *) LocalAlloc (LPTR, ulSize * sizeof(WCHAR) ); if ( *ppwszDNName == NULL ) { xe = GetLastError(); DebugMsg((DM_WARNING, TEXT("GetCategory: Memory allocation failed."))); goto Exit; }
bResult = pSecur32Api->pfnTranslateName( pwszAccount, NameUnknown, NameFullyQualifiedDN, *ppwszDNName, &ulSize );
if (!bResult) { xe = GetLastError(); DebugMsg((DM_WARNING, TEXT("GetCategory: TranslateName failed with error %d."), GetLastError())); } } else { if (!bResult) { xe = GetLastError(); DebugMsg((DM_WARNING, TEXT("GetCategory: TranslateName failed with error %d."), GetLastError())); } }
Exit:
if ( !bResult ) { LocalFree( *ppwszDNName ); *ppwszDNName = NULL; }
return bResult; }
//*************************************************************
//
// ProcessMachAndUserGpoList()
//
// Purpose: Calls the various extensions to do the planning
// mode logging
//
// Parameters: lpExtMach - Machine extension struct
// lpExtUser - User extension struct
// dwFlags - Processing flags
// pwszSite - Site name
// pwszNewComputerSOM - New computer scope of management
// psaCompSecGroups - New computer security groups
// pGpoInfoMach - Machine Gpo info
// ... - Similarly for user account
//
// Return: True if successful, False otherwise
//
//*************************************************************
DWORD ProcessMachAndUserGpoList( LPGPEXT lpExtMach, LPGPEXT lpExtUser, DWORD dwFlags, WCHAR *pwszSite, WCHAR *pwszMach, WCHAR *pwszNewComputerSOM, SAFEARRAY *psaComputerSecurityGroups, LPGPOINFO pGpoInfoMach, WCHAR *pwszUser, WCHAR *pwszNewUserSOM, SAFEARRAY *psaUserSecurityGroups, LPGPOINFO pGpoInfoUser ) { BOOL bAbort = FALSE; DWORD dwResult;
RSOP_TARGET computerTarget, userTarget; PRSOP_TARGET pComputerTarget = NULL; PRSOP_TARGET pUserTarget = NULL; BOOL bPlanningSupported = TRUE; LPGPEXT lpExt;
lpExt = (lpExtMach != NULL) ? lpExtMach : lpExtUser;
if (!lpExt) { DebugMsg((DM_WARNING, TEXT("ProcessMachAndUserGpoList: Both user and computer exts are null, returning."))); return TRUE; }
bPlanningSupported = lpExt->bRegistryExt || (lpExt->lpRsopFunctionName ? TRUE : FALSE);
if ( lpExtMach && !lpExtMach->bSkipped && pGpoInfoMach->lpGPOList ) {
//
// Computer target is non-null
//
pComputerTarget = &computerTarget; pComputerTarget->pwszAccountName = pwszMach; pComputerTarget->pwszNewSOM = pwszNewComputerSOM; pComputerTarget->psaSecurityGroups = psaComputerSecurityGroups; pComputerTarget->pRsopToken = pGpoInfoMach->pRsopToken; pComputerTarget->pGPOList = pGpoInfoMach->lpGPOList; pComputerTarget->pWbemServices = pGpoInfoMach->pWbemServices;
if (pGpoInfoMach->bRsopLogging) { pGpoInfoMach->bRsopLogging = LogExtSessionStatus(pGpoInfoMach->pWbemServices, lpExtMach, bPlanningSupported); if (!pGpoInfoMach->bRsopLogging) { DebugMsg((DM_WARNING, TEXT("GenerateRsopPolicy: Error when logging user Session data."))); } } }
if ( lpExtUser && !lpExtUser->bSkipped && pGpoInfoUser->lpGPOList ) {
//
// User target is non-null
//
pUserTarget = &userTarget; pUserTarget->pwszAccountName = pwszUser; pUserTarget->pwszNewSOM = pwszNewUserSOM; pUserTarget->psaSecurityGroups = psaUserSecurityGroups; pUserTarget->pRsopToken = pGpoInfoUser->pRsopToken; pUserTarget->pGPOList = pGpoInfoUser->lpGPOList; pUserTarget->pWbemServices = pGpoInfoUser->pWbemServices;
if (pGpoInfoUser->bRsopLogging) { pGpoInfoUser->bRsopLogging = LogExtSessionStatus(pGpoInfoUser->pWbemServices, lpExtUser, bPlanningSupported); if (!pGpoInfoUser->bRsopLogging) { DebugMsg((DM_WARNING, TEXT("GenerateRsopPolicy: Error when logging user Session data."))); } } }
if ( pComputerTarget == NULL && pUserTarget == NULL ) { DebugMsg((DM_WARNING, TEXT("ProcessMachAndUserGpoList: Both user and computer targets are null, returning."))); return TRUE; }
if ( lpExt->bRegistryExt ) {
//
// Registry pseudo extension
//
dwResult = GenerateRegistryPolicy( dwFlags, &bAbort, pwszSite, pComputerTarget, pUserTarget );
} else {
if ( LoadGPExtension( lpExt, TRUE ) ) { dwResult = lpExt->pRsopEntryPoint( dwFlags, &bAbort, pwszSite, pComputerTarget, pUserTarget );
} else { dwResult = GetLastError(); } }
if ( lpExtUser && !lpExtUser->bSkipped && pGpoInfoUser->bRsopLogging) { if ( !bPlanningSupported ) UpdateExtSessionStatus(pGpoInfoUser->pWbemServices, lpExtUser->lpKeyName, TRUE, ERROR_SUCCESS); else if (dwResult != ERROR_SUCCESS) UpdateExtSessionStatus(pGpoInfoUser->pWbemServices, lpExtUser->lpKeyName, TRUE, dwResult); else UpdateExtSessionStatus(pGpoInfoUser->pWbemServices, lpExtUser->lpKeyName, FALSE, dwResult); }
if ( lpExtMach && !lpExtMach->bSkipped && pGpoInfoMach->bRsopLogging) { if ( !bPlanningSupported ) UpdateExtSessionStatus(pGpoInfoMach->pWbemServices, lpExtMach->lpKeyName, TRUE, ERROR_SUCCESS); else if (dwResult != ERROR_SUCCESS) UpdateExtSessionStatus(pGpoInfoMach->pWbemServices, lpExtMach->lpKeyName, TRUE, dwResult); else UpdateExtSessionStatus(pGpoInfoMach->pWbemServices, lpExtMach->lpKeyName, FALSE, dwResult); }
return dwResult; }
//*********************************************************************
// * Planning mode registry stuff
//*********************************************************************
//*************************************************************
//
// ProcessRegistryFiles()
//
// Purpose: Called from GenerateRegsitryPolicy to process registry data from
// the registry files associated with a policy target.
//
// Parameters:
// pTarget - Policy for which registry policy is to be processed.
// pHashTable - Hash table to keep registry policy information.
//
// Return: On success, TRUE. Otherwise, FALSE.
//
//*************************************************************
BOOL ProcessRegistryFiles(PRSOP_TARGET pTarget, REGHASHTABLE *pHashTable) { PGROUP_POLICY_OBJECT lpGPO; TCHAR szRegistry[MAX_PATH]; LPTSTR lpEnd; HRESULT hr; XLastError xe; //
// Check parameters
//
DmAssert(pHashTable);
if(!pHashTable) { DebugMsg((DM_WARNING, TEXT("ProcessRegistryFiles: Invalid parameter."))); return FALSE; }
//
// Spin through GPOs in the list.
//
lpGPO = pTarget->pGPOList;
while ( lpGPO ) {
//
// Build the path to Registry.pol
//
DmAssert( lstrlen(lpGPO->lpFileSysPath) + lstrlen(c_szRegistryPol) + 1 < MAX_PATH ); if(lstrlen(lpGPO->lpFileSysPath) + lstrlen(c_szRegistryPol) + 1 >= MAX_PATH) { DebugMsg((DM_WARNING, TEXT("ProcessRegistryFiles: Length of path to registry.pol exceeded MAX_PATH."))); return FALSE; }
hr = StringCchCopy (szRegistry, ARRAYSIZE(szRegistry), lpGPO->lpFileSysPath); if (FAILED(hr)) { xe = HRESULT_CODE(hr); return FALSE; }
lpEnd = CheckSlash (szRegistry); hr = StringCchCopy (lpEnd, ARRAYSIZE(szRegistry) - (lpEnd - szRegistry), c_szRegistryPol); if (FAILED(hr)) { xe = HRESULT_CODE(hr); return FALSE; }
//
// Process registry data for this particular file.
//
if (!ParseRegistryFile (NULL, szRegistry, (PFNREGFILECALLBACK)ProcessRegistryValue, NULL, lpGPO->lpDSPath, lpGPO->lpLink,pHashTable, TRUE)) { DebugMsg((DM_WARNING, TEXT("ProcessRegistryFiles: ProcessRegistryFile failed."))); return FALSE; }
lpGPO = lpGPO->pNext; }
return TRUE; }
//*************************************************************
//
// ProcessAdmData()
//
// Purpose: Called from GenerateRegistryPolicy in order to process Admin templates
// data associated with a registry policy target.
//
// Parameters: pTarget - Target for which data is to be processed
// bUser - Is this for user or machine policy ?
//
// Return: On success, TRUE. Otherwise, FALSE.
//
//*************************************************************
BOOL ProcessAdmData( PRSOP_TARGET pTarget, BOOL bUser ) { PGROUP_POLICY_OBJECT lpGPO;
WIN32_FIND_DATA findData; ADMFILEINFO *pAdmFileCache = 0; TCHAR szRegistry[MAX_PATH]; LPTSTR lpEnd;
HANDLE hFindFile; WIN32_FILE_ATTRIBUTE_DATA attrData; DWORD dwFilePathSize; DWORD dwSize;
WCHAR *pwszEnd; WCHAR *pwszFile;
HRESULT hr;
//
// Check parameters
//
if(pTarget == NULL ) { DebugMsg((DM_WARNING, TEXT("ProcessAdmData: Invalid paramter."))); return FALSE; }
lpGPO = pTarget->pGPOList;
while(lpGPO) {
//
// Log Adm data
//
dwFilePathSize = lstrlen( lpGPO->lpFileSysPath ); dwSize = dwFilePathSize + MAX_PATH;
pwszFile = (WCHAR *) LocalAlloc( LPTR, dwSize * sizeof(WCHAR) );
if ( pwszFile == 0 ) { DebugMsg((DM_WARNING, TEXT("ProcessAdmData: Failed to allocate memory."))); FreeAdmFileCache( pAdmFileCache ); return FALSE; }
hr = StringCchCopy( pwszFile, dwSize, lpGPO->lpFileSysPath ); ASSERT(SUCCEEDED(hr));
//
// Strip off trailing 'machine' or 'user'
//
pwszEnd = pwszFile + lstrlen( pwszFile );
if ( !bUser ) pwszEnd -= 7; // length of "machine"
else pwszEnd -= 4; // length of "user"
hr = StringCchCopy( pwszEnd, dwSize - (pwszEnd - pwszFile), L"Adm\\*.adm"); ASSERT(SUCCEEDED(hr));
//
// Remember end point so that the actual Adm filename can be
// easily concatenated.
//
pwszEnd = pwszEnd + lstrlen( L"Adm\\" );
//
// Enumerate all Adm files
//
hFindFile = FindFirstFile( pwszFile, &findData);
if ( hFindFile != INVALID_HANDLE_VALUE ) { do { if ( !(findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ) { DmAssert( dwFilePathSize + lstrlen(findData.cFileName) + lstrlen( L"\\Adm\\" ) < dwSize );
hr = StringCchCopy( pwszEnd, dwSize - (pwszEnd - pwszFile), findData.cFileName); ASSERT(SUCCEEDED(hr));
ZeroMemory (&attrData, sizeof(attrData));
if ( GetFileAttributesEx (pwszFile, GetFileExInfoStandard, &attrData ) != 0 ) {
if ( !AddAdmFile( pwszFile, lpGPO->lpDSPath, &attrData.ftLastWriteTime, NULL, &pAdmFileCache ) ) { DebugMsg((DM_WARNING, TEXT("ProcessAdmData: NewAdmData failed."))); }
} } // if findData & file_attr_dir
} while ( FindNextFile(hFindFile, &findData) );// do
FindClose(hFindFile);
} // if hfindfile
LocalFree( pwszFile );
lpGPO = lpGPO->pNext; }
if ( ! LogAdmRsopData( pAdmFileCache, pTarget->pWbemServices ) ) { DebugMsg((DM_WARNING, TEXT("ProcessAdmData: Error when logging Adm Rsop data. Continuing."))); }
FreeAdmFileCache( pAdmFileCache );
return TRUE; }
//*************************************************************
//
// GenerateRegistryPolicy()
//
// Purpose: Implementation of Planning mode regsitry pseudo-extension
//
// Parameters: dwFlags - Flags
// pbAbort - Abort processing
// pwszSite - Site of target
// pComputerTarget - Computer target specification
// pUserTarget - User target specification
//
// Return: On success, S_OK. Otherwise, E_FAIL.
//
//*************************************************************
DWORD GenerateRegistryPolicy( DWORD dwFlags, BOOL *pbAbort, WCHAR *pwszSite, PRSOP_TARGET pComputerTarget, PRSOP_TARGET pUserTarget ) { REGHASHTABLE *pHashTable = NULL; BOOL bUser;
if(pComputerTarget && pComputerTarget->pGPOList) {
//
// Setup computer hash table
//
pHashTable = AllocHashTable(); if ( pHashTable == NULL ) { DebugMsg((DM_WARNING, TEXT("GenerateRegistryPolicy: AllocHashTable failed."))); return E_FAIL; }
//
// Process computer GPO list
//
if(!ProcessRegistryFiles(pComputerTarget, pHashTable)) { DebugMsg((DM_WARNING, TEXT("GenerateRegistryPolicy: ProcessRegistryFiles failed."))); FreeHashTable( pHashTable ); return E_FAIL; }
//
// Log computer registry data to Cimom database
//
if ( ! LogRegistryRsopData( GP_MACHINE, pHashTable, pComputerTarget->pWbemServices ) ) { DebugMsg((DM_WARNING, TEXT("GenerateRegistryPolicy: LogRegistryRsopData failed."))); FreeHashTable( pHashTable ); return E_FAIL; } FreeHashTable( pHashTable ); pHashTable = NULL;
//
// Process ADM data
//
bUser = FALSE; if (pComputerTarget && !ProcessAdmData( pComputerTarget, bUser ) ) { DebugMsg((DM_WARNING, TEXT("GenerateRegistryPolicy: ProcessAdmData failed."))); return E_FAIL; }
}
//
// Process user GPO list
//
if(pUserTarget && pUserTarget->pGPOList) {
//
// Setup user hash table
//
pHashTable = AllocHashTable(); if ( pHashTable == NULL ) { DebugMsg((DM_WARNING, TEXT("GenerateRegistryPolicy: AllocHashTable failed."))); return E_FAIL; }
if(!ProcessRegistryFiles(pUserTarget, pHashTable)) { DebugMsg((DM_WARNING, TEXT("GenerateRegistryPolicy: ProcessRegistryFiles failed."))); FreeHashTable( pHashTable ); return E_FAIL; }
//
// Log user registry data to Cimom database
//
if ( ! LogRegistryRsopData( 0, pHashTable, pUserTarget->pWbemServices ) ) { DebugMsg((DM_WARNING, TEXT("GenerateRegistryPolicy: LogRegistryRsopData failed."))); FreeHashTable( pHashTable ); return E_FAIL; } FreeHashTable( pHashTable ); pHashTable = NULL;
//
// Process ADM data
//
bUser = TRUE; if (pUserTarget && !ProcessAdmData( pUserTarget, bUser ) ) { DebugMsg((DM_WARNING, TEXT("GenerateRegistryPolicy: ProcessAdmData failed."))); return E_FAIL; }
}
return S_OK; }
//*************************************************************
//
// CheckOUAccess()
//
// Purpose: Determines if the user / machine has read access to
// the OU.
//
// Parameters: pld - LDAP connection
// pLDAP - LDAP function table pointer
// pMessage - LDAP message
// pRsopToken - RSOP token of the user or machine
// pSD - Security descriptor returned here
// pcbSDLen - Length of security descriptor returned here
// pbAccessGranted - Receives the final yes / no status
//
// Return: TRUE if successful
// FALSE if an error occurs.
//
//*************************************************************
BOOL CheckOUAccess( PLDAP_API pLDAP, PLDAP pld, PLDAPMessage pMessage, PRSOPTOKEN pRsopToken, BOOL *pbAccessGranted ) { BOOL bResult = FALSE; TCHAR szSDProperty[] = TEXT("nTSecurityDescriptor"); PWSTR *ppwszValues;
*pbAccessGranted = FALSE;
//
// Get the security descriptor value
//
ppwszValues = pLDAP->pfnldap_get_values( pld, pMessage, szSDProperty );
if (!ppwszValues) { if (pld->ld_errno == LDAP_NO_SUCH_ATTRIBUTE) { DebugMsg((DM_VERBOSE, TEXT("CheckOUAccess: Object can not be accessed."))); bResult = TRUE; } else { DebugMsg((DM_WARNING, TEXT("CheckOUAccess: ldap_get_values failed with 0x%x"), pld->ld_errno)); } } else { PLDAP_BERVAL *pSize; //
// Get the length of the security descriptor
//
pSize = pLDAP->pfnldap_get_values_len(pld, pMessage, szSDProperty);
if (!pSize) { DebugMsg((DM_WARNING, TEXT("CheckOUAccess: ldap_get_values_len failed with 0x%x"), pld->ld_errno)); } else { //
// Allocate the memory for the security descriptor
//
PSECURITY_DESCRIPTOR pSD = (PSECURITY_DESCRIPTOR)LocalAlloc(LPTR, (*pSize)->bv_len);
if ( pSD == NULL ) { DebugMsg((DM_WARNING, TEXT("CheckOUAccess: Failed to allocate memory for SD with %d"), GetLastError())); } else { //
// OU {bf967aa8-0de6-11d0-a285-00aa003049e2}
//
GUID OrganizationalUnit = { 0xbf967aa5, 0x0de6, 0x11d0, 0xa2, 0x85, 0x00, 0xaa, 0x00, 0x30, 0x49, 0xe2 };
//
// gPOptions {f30e3bbf-9ff0-11d1-b603-0000f80367c1}
//
GUID gPOptionsGuid = { 0xf30e3bbf, 0x9ff0, 0x11d1, 0xb6, 0x03, 0x00, 0x00, 0xf8, 0x03, 0x67, 0xc1 };
//
// gPLink {f30e3bbe-9ff0-11d1-b603-0000f80367c1}
//
GUID gPLinkGuid = { 0xf30e3bbe, 0x9ff0, 0x11d1, 0xb6, 0x03, 0x00, 0x00, 0xf8, 0x03, 0x67, 0xc1 };
OBJECT_TYPE_LIST ObjType[] = { { ACCESS_OBJECT_GUID, 0, &OrganizationalUnit }, { ACCESS_PROPERTY_SET_GUID, 0, &gPLinkGuid }, { ACCESS_PROPERTY_SET_GUID, 0, &gPOptionsGuid } }; HRESULT hr; PRIVILEGE_SET PrivSet; DWORD PrivSetLength = sizeof(PRIVILEGE_SET); DWORD dwGrantedAccess; BOOL bAccessStatus = TRUE; GENERIC_MAPPING DS_GENERIC_MAPPING = { DS_GENERIC_READ, DS_GENERIC_WRITE, DS_GENERIC_EXECUTE, DS_GENERIC_ALL };
//
// Copy the security descriptor
//
CopyMemory( pSD, (PBYTE)(*pSize)->bv_val, (*pSize)->bv_len);
//
// Now we use RsopAccessCheckByType to determine if the user / machine
// should have this GPO applied to them
//
hr = RsopAccessCheckByType(pSD, 0, pRsopToken, ACTRL_DS_READ_PROP, ObjType, ARRAYSIZE(ObjType), &DS_GENERIC_MAPPING, &PrivSet, &PrivSetLength, &dwGrantedAccess, &bAccessStatus ); if ( FAILED( hr ) ) { DebugMsg((DM_WARNING, TEXT("CheckOUAccess: RsopAccessCheckByType failed with %d"), GetLastError())); } else { *pbAccessGranted = bAccessStatus; bResult = TRUE; }
LocalFree( pSD ); }
pLDAP->pfnldap_value_free_len(pSize); }
pLDAP->pfnldap_value_free(ppwszValues); }
return bResult; }
|