//+--------------------------------------------------------------------------- // // Microsoft Windows // Copyright (C) Microsoft Corporation 1996-2001. // // File: wmihooks.cpp // // Contents: implementation of CWMIRsop // //---------------------------------------------------------------------------- #include #include #include "util.h" WCHAR const QUERY_LANG[] = L"WQL"; WCHAR const WMI_CLASS[] = L"__CLASS"; WCHAR const RSOP_NAME_SPACE[] = L"root\\rsop\\computer"; WCHAR const RSOP_PREC_ONE_QUERY[] = L"select * from RSOP_SecuritySettings where precedence=1"; WCHAR const RSOP_ALL_QUERY[] = L"select * from RSOP_SecuritySettings"; WCHAR const RSOP_STATUS[] = L"Status"; WCHAR const RSOP_ERROR[] = L"ErrorCode"; WCHAR const RSOP_PRECEDENCE[] = L"precedence"; WCHAR const RSOP_GPOID[] = L"GPOID"; WCHAR const RSOP_KEYNAME[] = L"KeyName"; WCHAR const RSOP_SETTING[] = L"Setting"; WCHAR const RSOP_USERRIGHT[] = L"UserRight"; WCHAR const RSOP_ACCOUNTLIST[] = L"AccountList"; WCHAR const RSOP_EVENTLOG_TYPE[] = L"Type"; //String Constants for RSOP_classNames WCHAR const RSOP_SEC_NUM[] = TEXT("RSOP_SecuritySettingNumeric"); WCHAR const RSOP_SEC_BOOL[] = TEXT("RSOP_SecuritySettingBoolean"); WCHAR const RSOP_SCE_STRING[] = TEXT("RSOP_SecuritySettingString"); WCHAR const RSOP_AUDIT[] = TEXT("RSOP_AuditPolicy"); WCHAR const RSOP_EVENT_NUM[] = TEXT("RSOP_SecurityEventLogSettingNumeric"); WCHAR const RSOP_EVENT_BOOL[] = TEXT("RSOP_SecurityEventLogSettingBoolean"); WCHAR const RSOP_REG_VAL[] = TEXT("RSOP_RegistryValue"); WCHAR const RSOP_USER_RIGHT[] = TEXT("RSOP_UserPrivilegeRight"); WCHAR const RSOP_RGROUPS[] = TEXT("RSOP_RestrictedGroup"); WCHAR const RSOP_SERVICE[] = TEXT("RSOP_SystemService"); WCHAR const RSOP_FILE[] = TEXT("RSOP_File"); WCHAR const RSOP_REG[] = TEXT("RSOP_RegistryKey"); //KeyNames WCHAR const MIN_PASS_AGE[] = TEXT("MinimumPasswordAge"); WCHAR const MAX_PASS_AGE[] = TEXT("MaximumPasswordAge"); WCHAR const MIN_PASS_LEN[] = TEXT("MinimumPasswordLength"); WCHAR const PASS_HIS_SIZE[] = TEXT("PasswordHistorySize"); WCHAR const REQUIRE_LOGON_TO_CHANGE_PASS[] = TEXT("RequireLogonToChangePassword"); WCHAR const LOCKOUT_COUNT[] = TEXT("LockoutBadCount"); WCHAR const RESET_LOCKOUT_COUNT[] = TEXT("ResetLockoutCount"); WCHAR const LOCKOUT_DURATION[] = TEXT("LockoutDuration"); WCHAR const MAX_TICKET_AGE[] = TEXT("MaxTicketAge"); WCHAR const MAX_RENEW_AGE[] = TEXT("MaxRenewAge"); WCHAR const MAX_SERVICE_AGE[] = TEXT("MaxServiceAge"); WCHAR const MAX_CLOCK_SKEW[] = TEXT("MaxClockSkew"); WCHAR const VALIDATE_CLIENT[] = TEXT("TicketValidateClient"); WCHAR const PASS_COMPLEX[] = TEXT("PasswordComplexity"); WCHAR const FORCE_LOGOFF[] = TEXT("ForceLogOffWhenHourExpire"); WCHAR const ENABLE_ADMIN[] = TEXT("EnableAdminAccount"); WCHAR const ENABLE_GUEST[] = TEXT("EnableGuestAccount"); WCHAR const LSA_ANON_LOOKUP[] = TEXT("LSAAnonymousNameLookup"); WCHAR const CLEAR_TEXT_PASS[] = TEXT("ClearTextPassword"); WCHAR const AUDIT_SYSTEM_EVENTS[] = TEXT("AuditSystemEvents"); WCHAR const AUDIT_LOGON_EVENTS[] = TEXT("AuditLogonEvents"); WCHAR const AUDIT_OBJECT_ACCESS[] = TEXT("AuditObjectAccess"); WCHAR const AUDIT_PRIVILEGE_USE[] = TEXT("AuditPrivilegeUse"); WCHAR const AUDIT_POLICY_CHANGE[] = TEXT("AuditPolicyChange"); WCHAR const AUDIT_ACCOUNT_MANAGE[] = TEXT("AuditAccountManage"); WCHAR const AUDIT_PROCESS_TRAKING[] = TEXT("AuditProcessTracking"); WCHAR const AUDIT_DS_ACCESS[] = TEXT("AuditDSAccess"); WCHAR const AUDIT_ACCOUNT_LOGON[] = TEXT("AuditAccountLogon"); WCHAR const MAX_LOG_SIZE[] = TEXT("MaximumLogSize"); WCHAR const AUDIT_LOG_RETENTION_PERIOD[] = TEXT ("AuditLogRetentionPeriod"); WCHAR const RETENTION_DAYS[] = TEXT ("RetentionDays"); WCHAR const RESTRICT_GUEST_ACCESS[] = TEXT ("RestrictGuestAccess"); WCHAR const NEW_GUEST_NAME[] = TEXT ("NewGuestName"); WCHAR const NEW_ADMINISTRATOR_NAME[] = TEXT ("NewAdministratorName"); VOID FreeRI(PRSOP_INFO ptr) { if(ptr) { if(ptr->pszGPOID) LocalFree(ptr->pszGPOID); LocalFree(ptr); } } VOID InitWMI_SEC_PROFILE_INFO(PWMI_SCE_PROFILE_INFO pProfileInfo) { memset(pProfileInfo,0,sizeof(SCE_PROFILE_INFO)); pProfileInfo->MinimumPasswordAge = SCE_NO_VALUE; pProfileInfo->MaximumPasswordAge = SCE_NO_VALUE; pProfileInfo->MinimumPasswordLength = SCE_NO_VALUE; pProfileInfo->PasswordComplexity = SCE_NO_VALUE; pProfileInfo->PasswordHistorySize = SCE_NO_VALUE; pProfileInfo->LockoutBadCount = SCE_NO_VALUE; pProfileInfo->ResetLockoutCount = SCE_NO_VALUE; pProfileInfo->LockoutDuration = SCE_NO_VALUE; pProfileInfo->RequireLogonToChangePassword = SCE_NO_VALUE; pProfileInfo->ForceLogoffWhenHourExpire = SCE_NO_VALUE; pProfileInfo->NewAdministratorName = 0; pProfileInfo->NewGuestName = 0; pProfileInfo->EnableAdminAccount = SCE_NO_VALUE; pProfileInfo->EnableGuestAccount = SCE_NO_VALUE; pProfileInfo->LSAAnonymousNameLookup = SCE_NO_VALUE; pProfileInfo->ClearTextPassword = SCE_NO_VALUE; pProfileInfo->AuditDSAccess = SCE_NO_VALUE; pProfileInfo->AuditAccountLogon = SCE_NO_VALUE; pProfileInfo->MaximumLogSize[0] = SCE_NO_VALUE; pProfileInfo->MaximumLogSize[1] = SCE_NO_VALUE; pProfileInfo->MaximumLogSize[2] = SCE_NO_VALUE; pProfileInfo->AuditLogRetentionPeriod[0] = SCE_NO_VALUE; pProfileInfo->AuditLogRetentionPeriod[1] = SCE_NO_VALUE; pProfileInfo->AuditLogRetentionPeriod[2] = SCE_NO_VALUE; pProfileInfo->RetentionDays[0] = SCE_NO_VALUE; pProfileInfo->RetentionDays[1] = SCE_NO_VALUE; pProfileInfo->RetentionDays[2] = SCE_NO_VALUE; pProfileInfo->RestrictGuestAccess[0] = SCE_NO_VALUE; pProfileInfo->RestrictGuestAccess[1] = SCE_NO_VALUE; pProfileInfo->RestrictGuestAccess[2] = SCE_NO_VALUE; pProfileInfo->AuditSystemEvents = SCE_NO_VALUE; pProfileInfo->AuditLogonEvents = SCE_NO_VALUE; pProfileInfo->AuditObjectAccess = SCE_NO_VALUE; pProfileInfo->AuditPrivilegeUse = SCE_NO_VALUE; pProfileInfo->AuditPolicyChange = SCE_NO_VALUE; pProfileInfo->AuditAccountManage = SCE_NO_VALUE; pProfileInfo->AuditProcessTracking = SCE_NO_VALUE; pProfileInfo->pInfo=NULL; pProfileInfo->pRIMinimumPasswordAge=NULL; pProfileInfo->pRIMaximumPasswordAge=NULL; pProfileInfo->pRIMinimumPasswordLength=NULL; pProfileInfo->pRIPasswordComplexity=NULL; pProfileInfo->pRIPasswordHistorySize=NULL; pProfileInfo->pRILockoutBadCount=NULL; pProfileInfo->pRIResetLockoutCount=NULL; pProfileInfo->pRILockoutDuration=NULL; pProfileInfo->pRIRequireLogonToChangePassword=NULL; pProfileInfo->pRIForceLogoffWhenHourExpire=NULL; pProfileInfo->pRIEnableAdminAccount=NULL; pProfileInfo->pRIEnableGuestAccount=NULL; pProfileInfo->pRILSAAnonymousNameLookup=NULL; pProfileInfo->pRINewAdministratorName=NULL; pProfileInfo->pRINewGuestName=NULL; pProfileInfo->pRIClearTextPassword=NULL; pProfileInfo->pRIMaxTicketAge=NULL; pProfileInfo->pRIMaxRenewAge=NULL; pProfileInfo->pRIMaxServiceAge=NULL; pProfileInfo->pRIMaxClockSkew=NULL; pProfileInfo->pRITicketValidateClient=NULL; pProfileInfo->pRIAuditSystemEvents=NULL; pProfileInfo->pRIAuditLogonEvents=NULL; pProfileInfo->pRIAuditObjectAccess=NULL; pProfileInfo->pRIAuditPrivilegeUse=NULL; pProfileInfo->pRIAuditPolicyChange=NULL; pProfileInfo->pRIAuditAccountManage=NULL; pProfileInfo->pRIAuditProcessTracking=NULL; pProfileInfo->pRIAuditDSAccess=NULL; pProfileInfo->pRIAuditAccountLogon=NULL; pProfileInfo->pRIMaximumLogSize[0]=NULL; pProfileInfo->pRIMaximumLogSize[1]=NULL; pProfileInfo->pRIMaximumLogSize[2]=NULL; pProfileInfo->pRIAuditLogRetentionPeriod[0]=NULL; pProfileInfo->pRIAuditLogRetentionPeriod[1]=NULL; pProfileInfo->pRIAuditLogRetentionPeriod[2]=NULL; pProfileInfo->pRIRetentionDays[0]=NULL; pProfileInfo->pRIRetentionDays[1]=NULL; pProfileInfo->pRIRetentionDays[2]=NULL; pProfileInfo->pRIRestrictGuestAccess[0]=NULL; pProfileInfo->pRIRestrictGuestAccess[1]=NULL; pProfileInfo->pRIRestrictGuestAccess[2]=NULL; } VOID FreeList(list * li) { for(list::iterator i = li->begin(); i != li->end(); ++i ) { FreeRI(*i); } li->erase(li->begin(),li->end()); } VOID FreeVector(vector * li) { for(vector::iterator i = li->begin(); i != li->end(); ++i ) { FreeRI(*i); } li->erase(li->begin(),li->end()); } VOID FreeWMI_SCE_PROFILE_INFO(PWMI_SCE_PROFILE_INFO pProfileInfo) { if (!pProfileInfo) { return; } //TODO //Use the code to Free SCE_PROFILE_INFO FreeRI(pProfileInfo->pInfo); FreeRI(pProfileInfo->pRIMinimumPasswordAge); FreeRI(pProfileInfo->pRIMaximumPasswordAge); FreeRI(pProfileInfo->pRIMinimumPasswordLength); FreeRI(pProfileInfo->pRIPasswordComplexity); FreeRI(pProfileInfo->pRIPasswordHistorySize); FreeRI(pProfileInfo->pRILockoutBadCount); FreeRI(pProfileInfo->pRIResetLockoutCount); FreeRI(pProfileInfo->pRILockoutDuration); FreeRI(pProfileInfo->pRIRequireLogonToChangePassword); FreeRI(pProfileInfo->pRIForceLogoffWhenHourExpire); FreeRI(pProfileInfo->pRIEnableAdminAccount); FreeRI(pProfileInfo->pRIEnableGuestAccount); FreeRI(pProfileInfo->pRILSAAnonymousNameLookup); FreeRI(pProfileInfo->pRINewAdministratorName); FreeRI(pProfileInfo->pRINewGuestName); FreeRI(pProfileInfo->pRIClearTextPassword); FreeRI(pProfileInfo->pRIMaxTicketAge); FreeRI(pProfileInfo->pRIMaxRenewAge); FreeRI(pProfileInfo->pRIMaxServiceAge); FreeRI(pProfileInfo->pRIMaxClockSkew); FreeRI(pProfileInfo->pRITicketValidateClient); FreeRI(pProfileInfo->pRIAuditSystemEvents); FreeRI(pProfileInfo->pRIAuditLogonEvents); FreeRI(pProfileInfo->pRIAuditObjectAccess); FreeRI(pProfileInfo->pRIAuditPrivilegeUse); FreeRI(pProfileInfo->pRIAuditPolicyChange); FreeRI(pProfileInfo->pRIAuditAccountManage); FreeRI(pProfileInfo->pRIAuditProcessTracking); FreeRI(pProfileInfo->pRIAuditDSAccess); FreeRI(pProfileInfo->pRIAuditAccountLogon); FreeRI(pProfileInfo->pRIMaximumLogSize[0]); FreeRI(pProfileInfo->pRIMaximumLogSize[1]); FreeRI(pProfileInfo->pRIMaximumLogSize[2]); FreeRI(pProfileInfo->pRIAuditLogRetentionPeriod[0]); FreeRI(pProfileInfo->pRIAuditLogRetentionPeriod[1]); FreeRI(pProfileInfo->pRIAuditLogRetentionPeriod[2]); FreeRI(pProfileInfo->pRIRetentionDays[0]); FreeRI(pProfileInfo->pRIRetentionDays[1]); FreeRI(pProfileInfo->pRIRetentionDays[2]); FreeRI(pProfileInfo->pRIRestrictGuestAccess[0]); FreeRI(pProfileInfo->pRIRestrictGuestAccess[1]); FreeRI(pProfileInfo->pRIRestrictGuestAccess[2]); FreeList(&(pProfileInfo->listRIInfPrivilegeAssignedTo)); FreeList(&(pProfileInfo->listRIGroupMemebership)); FreeList(&(pProfileInfo->listRIServices)); FreeVector(&(pProfileInfo->vecRIFiles)); FreeVector(&(pProfileInfo->vecRIReg)); SceFreeProfileMemory(pProfileInfo); } CWMIRsop::~CWMIRsop() { if (m_vecAllRSOPCache) { for(vector::iterator i = m_vecAllRSOPCache->begin(); i != m_vecAllRSOPCache->end(); ++i ) { PWMI_SCE_PROFILE_INFO pProfileInfo = *i; FreeWMI_SCE_PROFILE_INFO(pProfileInfo); } } delete m_vecAllRSOPCache; m_vecAllRSOPCache = NULL; // be extra carefull because the old code is not to delete it at all. if (m_pSvc) { m_pSvc->Release(); } } HRESULT CWMIRsop::Initialize() { HRESULT hr = S_OK; IWbemLocator *pLoc = NULL; //Already initialized if(m_pSvc) return hr; if (!m_pRSOPInformation) { return E_FAIL; } hr = CoCreateInstance(CLSID_WbemLocator, 0, CLSCTX_INPROC_SERVER, IID_IWbemLocator, (LPVOID *) &pLoc); if (FAILED(hr)) { return hr; } const int cchMaxLength = 512; WCHAR szNameSpace[cchMaxLength];//LPOLESTR pszNameSpace = (LPOLESTR) LocalAlloc (LPTR, cchMaxLength * sizeof (WCHAR)); hr = m_pRSOPInformation->GetNamespace ( GPO_SECTION_MACHINE, szNameSpace, cchMaxLength); szNameSpace[cchMaxLength - 1] = L'\0'; if (SUCCEEDED(hr)) { BSTR bstrNameSpace = SysAllocString (szNameSpace); if (bstrNameSpace) { hr = pLoc->ConnectServer(bstrNameSpace, NULL, NULL, 0, NULL, 0, 0, &m_pSvc ); SysFreeString(bstrNameSpace); } else hr = E_OUTOFMEMORY; } if (SUCCEEDED(hr)) { // Set the proxy so that impersonation of the client occurs. hr = CoSetProxyBlanket(m_pSvc, RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE, NULL, RPC_C_AUTHN_LEVEL_CALL, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE); } pLoc->Release(); return hr; // Program successfully completed. } HRESULT CWMIRsop::EnumeratePrecedenceOne(IEnumWbemClassObject **ppEnum) { HRESULT hr = m_pSvc->ExecQuery(_bstr_t(QUERY_LANG), _bstr_t(RSOP_PREC_ONE_QUERY), WBEM_FLAG_FORWARD_ONLY, NULL, ppEnum); return hr; } HRESULT CWMIRsop::EnumerateAll(IEnumWbemClassObject **ppEnum) { HRESULT hr = m_pSvc->ExecQuery(_bstr_t(QUERY_LANG), _bstr_t(RSOP_ALL_QUERY), WBEM_FLAG_FORWARD_ONLY, NULL, ppEnum); return hr; } HRESULT CWMIRsop::GetNextInstance(IEnumWbemClassObject *pEnum, IWbemClassObject** rsopInstance) { HRESULT hr = WBEM_S_FALSE; ULONG returnedNum = 0; if(pEnum) { hr = pEnum->Next(WBEM_INFINITE, 1, rsopInstance, &returnedNum); if( FAILED(hr) ) return hr; if (returnedNum == 0) hr = WBEM_S_FALSE; } return hr; } HRESULT CWMIRsop::GetClass(IWbemClassObject* rsopInstance, LPWSTR *ppClass) { PTSTR pszClassName; VARIANT value; HRESULT hr = rsopInstance->Get(_bstr_t(WMI_CLASS), 0, &value, NULL, NULL); if(FAILED(hr) || value.vt != VT_BSTR || value.bstrVal == NULL) return hr; pszClassName = (PTSTR) V_BSTR(&value); ULONG uLen = wcslen(pszClassName); *ppClass = (LPWSTR)LocalAlloc(LPTR, (uLen + 1) * sizeof(WCHAR)); if( *ppClass == NULL ) { VariantClear(&value); return E_OUTOFMEMORY; } wcscpy(*ppClass,pszClassName); VariantClear(&value); return hr; } HRESULT CWMIRsop::GetRSOPInfo(IWbemClassObject *rsopInstance, PRSOP_INFO pInfo) { HRESULT hr = S_OK; PTSTR pszGPOID = 0; UINT status = 0; UINT precedence = 0; VARIANT value; //Get Status hr = rsopInstance->Get(_bstr_t(RSOP_STATUS), 0, &value, NULL, NULL); if(FAILED(hr)) return hr; pInfo->status = (ULONG) V_UINT(&value); VariantClear(&value); //Get Error hr = rsopInstance->Get(_bstr_t(RSOP_ERROR), 0, &value, NULL, NULL); if(FAILED(hr)) return hr; pInfo->error = (ULONG) V_UINT(&value); VariantClear(&value); //Get Precedence hr = rsopInstance->Get(_bstr_t(RSOP_PRECEDENCE), 0, &value, NULL, NULL); if(FAILED(hr)) return hr; pInfo->precedence = (ULONG) V_UINT(&value); VariantClear(&value); //Get GPOID hr = rsopInstance->Get(_bstr_t(RSOP_GPOID), 0, &value, NULL, NULL); if(FAILED(hr) || value.vt != VT_BSTR || (value.vt == VT_BSTR && value.bstrVal == NULL) ) return hr; pszGPOID = (PTSTR) V_BSTR(&value); ULONG uLen = wcslen(pszGPOID); pInfo->pszGPOID = (LPWSTR)LocalAlloc(LPTR, (uLen + 1) * sizeof(WCHAR)); if( pInfo->pszGPOID == NULL ) { VariantClear(&value); return E_OUTOFMEMORY; } wcscpy(pInfo->pszGPOID, pszGPOID); VariantClear(&value); return hr; } HRESULT CWMIRsop::GetPrecedenceOneRSOPInfo(PWMI_SCE_PROFILE_INFO *ppProfileInfo) { HRESULT hr = S_OK; IWbemClassObject *rsopInstance = NULL; IEnumWbemClassObject *pEnumObject = NULL; PWMI_SCE_PROFILE_INFO pTempProfileInfo = NULL; PRSOP_INFO pInfo = NULL; hr = Initialize(); if( FAILED(hr) ) goto exit_gracefully; hr = EnumeratePrecedenceOne(&pEnumObject); if( FAILED(hr) ) goto exit_gracefully; pTempProfileInfo = new WMI_SCE_PROFILE_INFO; if( !pTempProfileInfo ) { hr = E_OUTOFMEMORY; goto exit_gracefully; } InitWMI_SEC_PROFILE_INFO(pTempProfileInfo); //Get each instance while( ((hr = GetNextInstance(pEnumObject, &rsopInstance)) != WBEM_S_FALSE) && !FAILED(hr) ) { pInfo = (PRSOP_INFO)LocalAlloc(LPTR, sizeof(RSOP_INFO)); if(pInfo == NULL) { hr = E_OUTOFMEMORY; goto exit_gracefully; } //Get RSOP_INFO hr = GetRSOPInfo(rsopInstance, pInfo); if( FAILED(hr) ) goto exit_gracefully; hr = AddInstance(rsopInstance, pInfo, pTempProfileInfo); if( FAILED(hr) ) goto exit_gracefully; rsopInstance->Release(); rsopInstance = NULL; pInfo = NULL; } exit_gracefully: if(FAILED(hr)) { if (rsopInstance) rsopInstance->Release(); // if while loop somehow terminate to here, rsopInstance is never released there if(pEnumObject) pEnumObject->Release(); FreeRI(pInfo); //Free pTempProfileInfo FreeWMI_SCE_PROFILE_INFO(pTempProfileInfo); pTempProfileInfo = NULL; } *ppProfileInfo = pTempProfileInfo; return hr; } PWMI_SCE_PROFILE_INFO SearchProfileInList(vector *vecInfo, PRSOP_INFO pInfo) { for(vector::iterator i = vecInfo->begin(); i != vecInfo->end(); ++i ) { PWMI_SCE_PROFILE_INFO pProfileInfo = *i; if(_wcsicmp(pProfileInfo->pInfo->pszGPOID,pInfo->pszGPOID) == 0 ) return pProfileInfo; } return NULL; } //Function Object Used for sorting vector struct less_mag : public binary_function { bool operator()(PWMI_SCE_PROFILE_INFO x, PWMI_SCE_PROFILE_INFO y) { return x->pInfo->precedence < y->pInfo->precedence; } }; HRESULT CWMIRsop::GetAllRSOPInfo(vector *vecInfo) { HRESULT hr = S_OK; IWbemClassObject *rsopInstance = NULL; IEnumWbemClassObject *pEnumObject = NULL; PRSOP_INFO pInfo = NULL; PWMI_SCE_PROFILE_INFO pProfileInfo = NULL; if (NULL == vecInfo) { return E_INVALIDARG; } // // If we've alrady cached the info from WMI then just return it // don't try and get it again // if (m_vecAllRSOPCache) { for(vector::iterator i = m_vecAllRSOPCache->begin(); i != m_vecAllRSOPCache->end(); ++i ) { vecInfo->push_back(*i); } return S_OK; } hr = Initialize(); if( FAILED(hr) ) goto exit_gracefully; hr = EnumerateAll(&pEnumObject); if( FAILED(hr) ) goto exit_gracefully; //Get each instance while( ((hr = GetNextInstance(pEnumObject, &rsopInstance)) != WBEM_S_FALSE) && !FAILED(hr) ) { pInfo = (PRSOP_INFO)LocalAlloc(LPTR, sizeof(RSOP_INFO)); if(pInfo == NULL) { hr = E_OUTOFMEMORY; goto exit_gracefully; } //Get RSOP_INFO hr = GetRSOPInfo(rsopInstance, pInfo); if( FAILED(hr) ) goto exit_gracefully; pProfileInfo = SearchProfileInList(vecInfo,pInfo); if(!pProfileInfo) { pProfileInfo = new WMI_SCE_PROFILE_INFO; if(!pProfileInfo) { hr = E_OUTOFMEMORY; goto exit_gracefully; } InitWMI_SEC_PROFILE_INFO(pProfileInfo); pProfileInfo->pInfo = (PRSOP_INFO)LocalAlloc(LPTR,sizeof(RSOP_INFO)); if(!pProfileInfo->pInfo) { hr = E_OUTOFMEMORY; goto exit_gracefully; } pProfileInfo->pInfo->pszGPOID = (LPWSTR)LocalAlloc(LPTR, (wcslen(pInfo->pszGPOID)+1)*sizeof(WCHAR)); if(!pProfileInfo->pInfo->pszGPOID) { hr = E_OUTOFMEMORY; goto exit_gracefully; } wcscpy(pProfileInfo->pInfo->pszGPOID,pInfo->pszGPOID); vecInfo->push_back(pProfileInfo); } if( pProfileInfo->pInfo->precedence < pInfo->precedence ) pProfileInfo->pInfo->precedence = pInfo->precedence; hr = AddInstance(rsopInstance, pInfo, pProfileInfo); if(FAILED(hr)) goto exit_gracefully; rsopInstance->Release(); rsopInstance = NULL; pInfo = NULL; } sort(vecInfo->begin(),vecInfo->end(),less_mag()); m_vecAllRSOPCache = new vector; if (m_vecAllRSOPCache) { for(vector::iterator i = vecInfo->begin(); i != vecInfo->end(); ++i ) { m_vecAllRSOPCache->push_back(*i); } } exit_gracefully: if(FAILED(hr)) { FreeRI(pInfo); //Free the vector for(vector::iterator i = vecInfo->begin(); i != vecInfo->end(); ++i ) { PWMI_SCE_PROFILE_INFO pProfileInfo = *i; FreeWMI_SCE_PROFILE_INFO(pProfileInfo); } } if(pEnumObject) pEnumObject->Release(); if(rsopInstance) rsopInstance->Release(); return hr; } HRESULT CWMIRsop::AddNumericSetting(IWbemClassObject *rsopInstance, PRSOP_INFO pInfo, PWMI_SCE_PROFILE_INFO pProfileInfo) { HRESULT hr = S_OK; VARIANT bKeyName; PTSTR keyName; VARIANT bSettingValue; DWORD settingValue; _TRACE (1, L"Entering CWMIRsop::AddNumericSetting\n"); hr = rsopInstance->Get((BSTR)RSOP_KEYNAME, 0, &bKeyName, NULL, NULL); if( FAILED(hr) || bKeyName.vt != VT_BSTR || bKeyName.bstrVal == NULL) goto exit_gracefully; hr = rsopInstance->Get((BSTR)RSOP_SETTING, 0, &bSettingValue, NULL, NULL); if( FAILED(hr) ) goto exit_gracefully; keyName = V_BSTR(&bKeyName); settingValue = V_UINT(&bSettingValue); if(!_wcsicmp(keyName, MIN_PASS_AGE)) { pProfileInfo->MinimumPasswordAge = settingValue; pProfileInfo->pRIMinimumPasswordAge = pInfo; } else if(!_wcsicmp(keyName, MAX_PASS_AGE)) { pProfileInfo->MaximumPasswordAge = settingValue; pProfileInfo->pRIMaximumPasswordAge = pInfo; } else if(!_wcsicmp(keyName, MIN_PASS_LEN)) { pProfileInfo->MinimumPasswordLength = settingValue; pProfileInfo->pRIMinimumPasswordLength = pInfo; } else if(!_wcsicmp(keyName, PASS_HIS_SIZE)) { pProfileInfo->PasswordHistorySize = settingValue; pProfileInfo->pRIPasswordHistorySize = pInfo; } else if(!_wcsicmp(keyName, LOCKOUT_COUNT)) { pProfileInfo->LockoutBadCount = settingValue; pProfileInfo->pRILockoutBadCount = pInfo; } else if(!_wcsicmp(keyName, RESET_LOCKOUT_COUNT)) { pProfileInfo->ResetLockoutCount = settingValue; pProfileInfo->pRIResetLockoutCount = pInfo; } else if(!_wcsicmp(keyName, LOCKOUT_DURATION)) { pProfileInfo->LockoutDuration = settingValue; pProfileInfo->pRILockoutDuration = pInfo; } else if(!_wcsicmp(keyName, MAX_TICKET_AGE)) { if(!pProfileInfo->pKerberosInfo) { pProfileInfo->pKerberosInfo = (PSCE_KERBEROS_TICKET_INFO) LocalAlloc(LPTR, sizeof(SCE_KERBEROS_TICKET_INFO)); if(pProfileInfo->pKerberosInfo == NULL) { hr = E_OUTOFMEMORY; goto exit_gracefully; } } pProfileInfo->pKerberosInfo->MaxTicketAge = settingValue; pProfileInfo->pRIMaxTicketAge = pInfo; } else if(!_wcsicmp(keyName, MAX_RENEW_AGE)) { if(!pProfileInfo->pKerberosInfo) { pProfileInfo->pKerberosInfo = (PSCE_KERBEROS_TICKET_INFO) LocalAlloc(LPTR, sizeof(SCE_KERBEROS_TICKET_INFO)); if(pProfileInfo->pKerberosInfo == NULL) { hr = E_OUTOFMEMORY; goto exit_gracefully; } } pProfileInfo->pKerberosInfo->MaxRenewAge = settingValue; pProfileInfo->pRIMaxRenewAge = pInfo; } else if(!_wcsicmp(keyName, MAX_SERVICE_AGE)) { if(!pProfileInfo->pKerberosInfo) { pProfileInfo->pKerberosInfo = (PSCE_KERBEROS_TICKET_INFO) LocalAlloc(LPTR, sizeof(SCE_KERBEROS_TICKET_INFO)); if(pProfileInfo->pKerberosInfo == NULL) { hr = E_OUTOFMEMORY; goto exit_gracefully; } } pProfileInfo->pKerberosInfo->MaxServiceAge = settingValue; pProfileInfo->pRIMaxServiceAge = pInfo; } else if(!_wcsicmp(keyName, MAX_CLOCK_SKEW)) { if(!pProfileInfo->pKerberosInfo) { pProfileInfo->pKerberosInfo = (PSCE_KERBEROS_TICKET_INFO) LocalAlloc(LPTR, sizeof(SCE_KERBEROS_TICKET_INFO)); if(pProfileInfo->pKerberosInfo == NULL) { hr = E_OUTOFMEMORY; goto exit_gracefully; } } pProfileInfo->pKerberosInfo->MaxClockSkew = settingValue; pProfileInfo->pRIMaxClockSkew = pInfo; } else { _ASSERT (FALSE); // key name not accounted for } exit_gracefully: VariantClear(&bKeyName); VariantClear(&bSettingValue); _TRACE (-1,L"Leaving CWMIRsop::AddNumericSetting\n"); return hr; } HRESULT CWMIRsop::AddEventLogNumericSetting(IWbemClassObject *rsopInstance, PRSOP_INFO pInfo, PWMI_SCE_PROFILE_INFO pProfileInfo) { VARIANT bKeyName; VARIANT bSettingValue; VARIANT bType; _TRACE (1, L"Entering CWMIRsop::AddEventLogNumericSetting\n"); HRESULT hr = rsopInstance->Get((BSTR)RSOP_KEYNAME, 0, &bKeyName, NULL, NULL); if( FAILED(hr) || bKeyName.vt != VT_BSTR || bKeyName.bstrVal == NULL) goto exit_gracefully; hr = rsopInstance->Get((BSTR)RSOP_SETTING, 0, &bSettingValue, NULL, NULL); if( FAILED(hr) ) goto exit_gracefully; hr = rsopInstance->Get((BSTR)RSOP_EVENTLOG_TYPE, 0, &bType, NULL, NULL); if( FAILED(hr) ) goto exit_gracefully; PTSTR keyName = V_BSTR(&bKeyName); DWORD settingValue = V_UINT(&bSettingValue); PTSTR typeValue = V_BSTR(&bType); unsigned long ulType = wcstoul (typeValue, L'\0', 10); ASSERT (ulType <= 2); if ( ulType <= 2 ) { if ( !_wcsicmp(keyName, MAX_LOG_SIZE) ) { pProfileInfo->MaximumLogSize[ulType] = settingValue; pProfileInfo->pRIMaximumLogSize[ulType] = pInfo; } else if ( !_wcsicmp(keyName, AUDIT_LOG_RETENTION_PERIOD) ) { pProfileInfo->AuditLogRetentionPeriod[ulType] = settingValue; pProfileInfo->pRIAuditLogRetentionPeriod[ulType] = pInfo; } else if ( !_wcsicmp(keyName, RETENTION_DAYS) ) { pProfileInfo->RetentionDays[ulType] = settingValue; pProfileInfo->pRIRetentionDays[ulType] = pInfo; } else { _ASSERT (FALSE); // key name not accounted for } } else hr = E_FAIL; exit_gracefully: VariantClear (&bKeyName); VariantClear (&bSettingValue); VariantClear (&bType); _TRACE (-1,L"Leaving CWMIRsop::AddEventLogNumericSetting\n"); return hr; } HRESULT CWMIRsop::AddEventLogBooleanSetting(IWbemClassObject *rsopInstance, PRSOP_INFO pInfo, PWMI_SCE_PROFILE_INFO pProfileInfo) { HRESULT hr = S_OK; VARIANT bKeyName; PTSTR keyName = 0; VARIANT bSettingValue; DWORD settingValue; BOOL boolVal = FALSE; VARIANT bType; PTSTR typeValue = 0; _TRACE (1, L"Entering CWMIRsop::AddEventLogBooleanSetting\n"); hr = rsopInstance->Get((BSTR)RSOP_KEYNAME, 0, &bKeyName, NULL, NULL); if( FAILED(hr) || bKeyName.vt != VT_BSTR || bKeyName.bstrVal == NULL) goto exit_gracefully; hr = rsopInstance->Get((BSTR)RSOP_SETTING, 0, &bSettingValue, NULL, NULL); if( FAILED(hr) ) goto exit_gracefully; hr = rsopInstance->Get((BSTR)RSOP_EVENTLOG_TYPE, 0, &bType, NULL, NULL); if( FAILED(hr) ) goto exit_gracefully; keyName = V_BSTR(&bKeyName); boolVal = V_BOOL(&bSettingValue); settingValue = (boolVal)? 1:0; typeValue = V_BSTR(&bType); unsigned long ulType = wcstoul (typeValue, L'\0', 10); ASSERT (ulType <= 2); if ( ulType <= 2 ) { if ( !_wcsicmp(keyName, RESTRICT_GUEST_ACCESS) ) { pProfileInfo->RestrictGuestAccess[ulType] = settingValue; pProfileInfo->pRIRestrictGuestAccess[ulType] = pInfo; } else { _ASSERT (FALSE); // key name not accounted for } } else hr = E_FAIL; exit_gracefully: VariantClear (&bKeyName); VariantClear (&bSettingValue); VariantClear (&bType); _TRACE (-1,L"Leaving CWMIRsop::AddEventLogBooleanSetting\n"); return hr; } HRESULT CWMIRsop::AddBooleanSetting(IWbemClassObject *rsopInstance, PRSOP_INFO pInfo, PWMI_SCE_PROFILE_INFO pProfileInfo) { VARIANT bKeyName; PTSTR keyName; VARIANT bSettingValue; BOOL boolVal; DWORD settingValue; HRESULT hr = S_OK; _TRACE (1, L"Entering CWMIRsop::AddBooleanSetting\n"); hr = rsopInstance->Get((BSTR)RSOP_KEYNAME, 0, &bKeyName, NULL, NULL); if(FAILED(hr) || bKeyName.vt != VT_BSTR || bKeyName.bstrVal == NULL) goto exit_gracefully; hr = rsopInstance->Get((BSTR)RSOP_SETTING, 0, &bSettingValue, NULL, NULL); if(FAILED(hr)) goto exit_gracefully; keyName = (PTSTR) V_BSTR(&bKeyName); boolVal = V_BOOL(&bSettingValue); settingValue = (boolVal)? 1:0; if(!_wcsicmp(keyName, PASS_COMPLEX)) { pProfileInfo->PasswordComplexity = settingValue; pProfileInfo->pRIPasswordComplexity = pInfo; } else if(!_wcsicmp(keyName, FORCE_LOGOFF)) { pProfileInfo->ForceLogoffWhenHourExpire = settingValue; pProfileInfo->pRIForceLogoffWhenHourExpire = pInfo; } else if(!_wcsicmp(keyName, ENABLE_ADMIN)) { pProfileInfo->EnableAdminAccount = settingValue; pProfileInfo->pRIEnableAdminAccount = pInfo; } else if(!_wcsicmp(keyName, ENABLE_GUEST)) { pProfileInfo->EnableGuestAccount = settingValue; pProfileInfo->pRIEnableGuestAccount = pInfo; } else if(!_wcsicmp(keyName, LSA_ANON_LOOKUP)) { pProfileInfo->LSAAnonymousNameLookup = settingValue; pProfileInfo->pRILSAAnonymousNameLookup = pInfo; } else if(!_wcsicmp(keyName, CLEAR_TEXT_PASS)) { pProfileInfo->ClearTextPassword = settingValue; pProfileInfo->pRIClearTextPassword = pInfo; } else if (!_wcsicmp(keyName, REQUIRE_LOGON_TO_CHANGE_PASS)) { pProfileInfo->RequireLogonToChangePassword = settingValue; pProfileInfo->pRIRequireLogonToChangePassword = pInfo; } else if(!_wcsicmp(keyName, VALIDATE_CLIENT)) { if(!pProfileInfo->pKerberosInfo) { pProfileInfo->pKerberosInfo = (PSCE_KERBEROS_TICKET_INFO) LocalAlloc(LPTR, sizeof(SCE_KERBEROS_TICKET_INFO)); if(pProfileInfo->pKerberosInfo == NULL) { hr = E_OUTOFMEMORY; goto exit_gracefully; } } pProfileInfo->pKerberosInfo->TicketValidateClient = settingValue; pProfileInfo->pRITicketValidateClient = pInfo; } else { _ASSERT (FALSE); // key name not accounted for } exit_gracefully: VariantClear(&bKeyName); VariantClear(&bSettingValue); _TRACE (-1,L"Leaving CWMIRsop::AddBooleanSetting\n"); return hr; } HRESULT CWMIRsop::AddAuditSetting(IWbemClassObject *rsopInstance, PRSOP_INFO pInfo, PWMI_SCE_PROFILE_INFO pProfileInfo) { VARIANT bCategoryName; PTSTR categoryName; VARIANT vSuccessVal; VARIANT vFailVal; BOOL successVal; BOOL failVal; DWORD settingVal = 0; HRESULT hr = S_OK; _TRACE (1, L"Entering CWMIRsop::AddAuditSetting\n"); hr = rsopInstance->Get(_bstr_t(TEXT("Category")), 0, &bCategoryName, NULL, NULL ); if(FAILED(hr) || bCategoryName.vt != VT_BSTR || bCategoryName.bstrVal == NULL) goto exit_gracefully; hr = rsopInstance->Get(_bstr_t(TEXT("Success")), 0, &vSuccessVal, NULL, NULL ); if(FAILED(hr)) goto exit_gracefully; hr = rsopInstance->Get(_bstr_t(TEXT("Failure")), 0, &vFailVal, NULL, NULL ); if(FAILED(hr)) goto exit_gracefully; categoryName = (PTSTR) V_BSTR(&bCategoryName); successVal = V_BOOL(&vSuccessVal); failVal = V_BOOL(&vFailVal); if (successVal) settingVal |= 1; if (failVal) settingVal |= 2; if(!_wcsicmp(categoryName, AUDIT_SYSTEM_EVENTS)) { pProfileInfo->AuditSystemEvents = settingVal; pProfileInfo->pRIAuditSystemEvents = pInfo; } else if(!_wcsicmp(categoryName, AUDIT_LOGON_EVENTS)) { pProfileInfo->AuditLogonEvents = settingVal; pProfileInfo->pRIAuditLogonEvents = pInfo; } else if(!_wcsicmp(categoryName, AUDIT_OBJECT_ACCESS)) { pProfileInfo->AuditObjectAccess = settingVal; pProfileInfo->pRIAuditObjectAccess = pInfo; } else if (!_wcsicmp(categoryName, AUDIT_PRIVILEGE_USE)) { pProfileInfo->AuditPrivilegeUse = settingVal; pProfileInfo->pRIAuditPrivilegeUse = pInfo; } else if(!_wcsicmp(categoryName, AUDIT_POLICY_CHANGE)) { pProfileInfo->AuditPolicyChange = settingVal; pProfileInfo->pRIAuditPolicyChange = pInfo; } else if(!_wcsicmp(categoryName, AUDIT_ACCOUNT_MANAGE)) { pProfileInfo->AuditAccountManage = settingVal; pProfileInfo->pRIAuditAccountManage = pInfo; } else if(!_wcsicmp(categoryName, AUDIT_PROCESS_TRAKING)) { pProfileInfo->AuditProcessTracking = settingVal; pProfileInfo->pRIAuditProcessTracking = pInfo; } else if(!_wcsicmp(categoryName, AUDIT_DS_ACCESS)) { pProfileInfo->AuditDSAccess = settingVal; pProfileInfo->pRIAuditDSAccess = pInfo; } else if(!_wcsicmp(categoryName, AUDIT_ACCOUNT_LOGON)) { pProfileInfo->AuditAccountLogon = settingVal; pProfileInfo->pRIAuditAccountLogon = pInfo; } else { _ASSERT (FALSE); // key name not accounted for } exit_gracefully: VariantClear(&bCategoryName); VariantClear(&vSuccessVal); VariantClear(&vFailVal); _TRACE (-1,L"Leaving CWMIRsop::AddAuditSetting\n"); return hr; } HRESULT CWMIRsop::AddUserRightSetting( IWbemClassObject *rsopInstance, PRSOP_INFO pInfo, PWMI_SCE_PROFILE_INFO pProfileInfo) { VARIANT bUserRight; PTSTR userRight = NULL; VARIANT vAccountList; HRESULT hr = S_OK; _TRACE (1, L"Entering CWMIRsop::AddUserRightSetting\n"); hr = rsopInstance->Get(_bstr_t(RSOP_USERRIGHT), 0, &bUserRight, NULL, NULL); if( FAILED(hr) || bUserRight.vt != VT_BSTR || bUserRight.bstrVal == NULL ) goto exit_gracefully; hr = rsopInstance->Get(_bstr_t(RSOP_ACCOUNTLIST), 0, &vAccountList, NULL, NULL); if( FAILED(hr) ) goto exit_gracefully; DWORD len; len = wcslen((PTSTR) V_BSTR(&bUserRight)); userRight = (PTSTR) LocalAlloc(LPTR, (len+1) * sizeof(WCHAR) ); if(!userRight) { hr = E_OUTOFMEMORY; goto exit_gracefully; } wcscpy(userRight, (PTSTR) V_BSTR(&bUserRight)); PSCE_PRIVILEGE_ASSIGNMENT head; head = pProfileInfo->OtherInfo.scp.u.pInfPrivilegeAssignedTo; if (!head) { head = (pProfileInfo->OtherInfo.scp.u.pInfPrivilegeAssignedTo = (PSCE_PRIVILEGE_ASSIGNMENT) LocalAlloc(LPTR, sizeof(SCE_PRIVILEGE_ASSIGNMENT))); if(!head) { hr = E_OUTOFMEMORY; goto exit_gracefully; } } else { PSCE_PRIVILEGE_ASSIGNMENT current; current = (PSCE_PRIVILEGE_ASSIGNMENT) LocalAlloc(LPTR, sizeof(SCE_PRIVILEGE_ASSIGNMENT)); if(!current) { hr = E_OUTOFMEMORY; goto exit_gracefully; } current->Next = head; head = current; pProfileInfo->OtherInfo.scp.u.pInfPrivilegeAssignedTo = head; } head->Name = userRight; userRight = NULL; if(V_VT(&vAccountList) != VT_NULL) { SAFEARRAY* ptempArray; ptempArray = NULL; BSTR tempString; long lowerBoundray=0, upperBoundray=0, loopCount=0; ptempArray = V_ARRAY(&vAccountList); if ( FAILED(SafeArrayGetLBound(ptempArray, 1, &lowerBoundray)) ) lowerBoundray = 0; if ( FAILED(SafeArrayGetUBound(ptempArray, 1, &upperBoundray)) ) upperBoundray = 0; PSCE_NAME_LIST nameHead = head->AssignedTo; for (loopCount = lowerBoundray; loopCount <= upperBoundray; loopCount++) { hr = SafeArrayGetElement(ptempArray, &loopCount, &tempString); if ( FAILED(hr) ) goto exit_gracefully; if(!nameHead) { nameHead = (head->AssignedTo = (PSCE_NAME_LIST) LocalAlloc(LPTR, sizeof(SCE_NAME_LIST))); if(!nameHead) { hr = E_OUTOFMEMORY; goto exit_gracefully; } } else { PSCE_NAME_LIST currentName = (PSCE_NAME_LIST) LocalAlloc(LPTR, sizeof(SCE_NAME_LIST)); if(!currentName) { hr = E_OUTOFMEMORY; goto exit_gracefully; } currentName->Next = nameHead; nameHead = currentName; head->AssignedTo = nameHead; } DWORD nameLen = wcslen((PTSTR) tempString); nameHead->Name = (PTSTR) LocalAlloc(LPTR, (nameLen+1) *sizeof(WCHAR) ); if(!nameHead->Name) { hr = E_OUTOFMEMORY; goto exit_gracefully; } wcscpy(nameHead->Name, (PTSTR) tempString); } } //Set other info pProfileInfo->listRIInfPrivilegeAssignedTo.push_front(pInfo); exit_gracefully: if(FAILED(hr) && (userRight != NULL)) { LocalFree(userRight); } VariantClear(&bUserRight); VariantClear(&vAccountList); _TRACE (-1,L"Leaving CWMIRsop::AddUserRightSetting\n"); return hr; } HRESULT CWMIRsop::AddRegValSetting(IWbemClassObject *rsopInstance, PRSOP_INFO pInfo, PWMI_SCE_PROFILE_INFO pProfileInfo) { VARIANT bKeyName; PTSTR keyName; VARIANT vSettingValue; VARIANT vType; PTSTR settingValue; DWORD type; HRESULT hr = S_OK; _TRACE (1, L"Entering CWMIRsop::AddRegValSetting\n"); hr = rsopInstance->Get(_bstr_t(TEXT("Path")), 0, &bKeyName, NULL, NULL); if(FAILED(hr) || bKeyName.vt != VT_BSTR || bKeyName.bstrVal == NULL ) goto exit_gracefully; hr = rsopInstance->Get(_bstr_t(TEXT("Data")), 0, &vSettingValue, NULL, NULL); if(FAILED(hr) || vSettingValue.vt != VT_BSTR || vSettingValue.bstrVal == NULL ) goto exit_gracefully; hr = rsopInstance->Get(_bstr_t(TEXT("Type")), 0, &vType, NULL, NULL); if(FAILED(hr)) goto exit_gracefully; DWORD len; len = wcslen((PTSTR) V_BSTR(&bKeyName)); keyName = (PTSTR) LocalAlloc(LPTR, (len+1) *sizeof(WCHAR)); if(!keyName) { hr = E_OUTOFMEMORY; goto exit_gracefully; } wcscpy(keyName,(PTSTR) V_BSTR(&bKeyName)); len = wcslen((PTSTR) V_BSTR(&vSettingValue)); settingValue = (PTSTR) LocalAlloc(LPTR, (len+1) *sizeof(WCHAR)); if(!settingValue) { hr = E_OUTOFMEMORY; goto exit_gracefully; } wcscpy(settingValue,(PTSTR) V_BSTR(&vSettingValue)); type = (DWORD) V_I4(&vType); DWORD arrayIndex; if ((arrayIndex = pProfileInfo->RegValueCount) == 0) { pProfileInfo->aRegValues = (PSCE_REGISTRY_VALUE_INFO) LocalAlloc(LPTR, sizeof(SCE_REGISTRY_VALUE_INFO)* m_cRegValueSize); if(!pProfileInfo->aRegValues) { hr = E_OUTOFMEMORY; goto exit_gracefully; } } //double the array preserving the content if( arrayIndex >= m_cRegValueSize ) { PSCE_REGISTRY_VALUE_INFO temp = (PSCE_REGISTRY_VALUE_INFO) LocalAlloc(LPTR, sizeof(SCE_REGISTRY_VALUE_INFO)* m_cRegValueSize * 2); if(!temp) { hr = E_OUTOFMEMORY; goto exit_gracefully; } memcpy(temp,pProfileInfo->aRegValues,sizeof(SCE_REGISTRY_VALUE_INFO)*arrayIndex); LocalFree(pProfileInfo->aRegValues); pProfileInfo->aRegValues = temp; m_cRegValueSize *= 2; } pProfileInfo->aRegValues[arrayIndex].FullValueName = keyName; pProfileInfo->aRegValues[arrayIndex].Value = settingValue; pProfileInfo->aRegValues[arrayIndex].ValueType = type; pProfileInfo->RegValueCount += 1; //Store RSOP_INFO pProfileInfo->vecRIRegValues.push_back(pInfo); exit_gracefully: VariantClear(&bKeyName); VariantClear(&vSettingValue); VariantClear(&vType); _TRACE (-1,L"Leaving CWMIRsop::AddRegValSetting\n"); return hr; } HRESULT CWMIRsop::AddRestrictedGroupSetting(IWbemClassObject *rsopInstance, PRSOP_INFO pInfo, PWMI_SCE_PROFILE_INFO pProfileInfo) { VARIANT bRGroup; PTSTR RGroup; VARIANT vMembers; HRESULT hr = S_OK; _TRACE (1, L"Entering CWMIRsop::AddRestrictedGroupSetting\n"); hr = rsopInstance->Get(_bstr_t(TEXT("GroupName")), 0, &bRGroup, NULL, NULL ); if(FAILED(hr) || bRGroup.vt != VT_BSTR || bRGroup.bstrVal == NULL ) goto exit_gracefully; hr = rsopInstance->Get(_bstr_t(TEXT("Members")), 0, &vMembers, NULL, NULL ); if(FAILED(hr)) goto exit_gracefully; DWORD len; len = wcslen((PTSTR) V_BSTR(&bRGroup)); RGroup = (PTSTR) LocalAlloc(LPTR, (len+1) * sizeof(WCHAR)); if(!RGroup) { hr = E_OUTOFMEMORY; goto exit_gracefully; } wcscpy(RGroup, (PTSTR) V_BSTR(&bRGroup)); PSCE_GROUP_MEMBERSHIP head; head = pProfileInfo->pGroupMembership; if (!head) { head = (pProfileInfo->pGroupMembership = (PSCE_GROUP_MEMBERSHIP) LocalAlloc(LPTR, sizeof(SCE_GROUP_MEMBERSHIP))); if(!head) { hr = E_OUTOFMEMORY; goto exit_gracefully; } } else { PSCE_GROUP_MEMBERSHIP current = (PSCE_GROUP_MEMBERSHIP) LocalAlloc(LPTR, sizeof(SCE_GROUP_MEMBERSHIP)); if(!current) { hr = E_OUTOFMEMORY; goto exit_gracefully; } current->Next = head; head = current; pProfileInfo->pGroupMembership = head; } head->GroupName = RGroup; if(V_VT(&vMembers) != VT_NULL) { SAFEARRAY* ptempArray = NULL; BSTR tempString; long lowerBoundray=0, upperBoundray=0, loopCount=0; ptempArray = V_ARRAY(&vMembers); if ( FAILED(SafeArrayGetLBound(ptempArray, 1, &lowerBoundray)) ) lowerBoundray = 0; if ( FAILED(SafeArrayGetUBound(ptempArray, 1, &upperBoundray)) ) upperBoundray = 0; PSCE_NAME_LIST nameHead = head->pMembers; for (loopCount = lowerBoundray; loopCount <= upperBoundray; loopCount++){ hr = SafeArrayGetElement(ptempArray, &loopCount, &tempString); if ( FAILED(hr) ) goto exit_gracefully; if(!nameHead) { nameHead = (head->pMembers = (PSCE_NAME_LIST) LocalAlloc(LPTR, sizeof(SCE_NAME_LIST))); if(!nameHead) { hr = E_OUTOFMEMORY; goto exit_gracefully; } } else { PSCE_NAME_LIST currentName = (PSCE_NAME_LIST) LocalAlloc(LPTR, sizeof(SCE_NAME_LIST)); if(!currentName) { hr = E_OUTOFMEMORY; goto exit_gracefully; } currentName->Next = nameHead; nameHead = currentName; head->pMembers = nameHead; } DWORD nameLen = wcslen((PTSTR) tempString); nameHead->Name = (PTSTR) LocalAlloc(LPTR, (nameLen+1) *sizeof(WCHAR) ); if ( !(nameHead->Name) ) { hr = E_OUTOFMEMORY; goto exit_gracefully; } wcscpy(nameHead->Name, (PTSTR) tempString); } } //Add RSOP info pProfileInfo->listRIGroupMemebership.push_front(pInfo); exit_gracefully: VariantClear(&bRGroup); VariantClear(&vMembers); _TRACE (-1,L"Leaving CWMIRsop::AddRestrictedGroupSetting\n"); return hr; } HRESULT CWMIRsop::AddServiceSetting(IWbemClassObject *rsopInstance, PRSOP_INFO pInfo, PWMI_SCE_PROFILE_INFO pProfileInfo) { VARIANT bServiceName; PTSTR serviceName; VARIANT vSDDL; VARIANT vStartup; PSECURITY_DESCRIPTOR SDDL = NULL; DWORD startup; HRESULT hr = S_OK; _TRACE (1, L"Entering CWMIRsop::AddServiceSetting\n"); hr = rsopInstance->Get(_bstr_t(TEXT("Service")), 0, &bServiceName, NULL, NULL); if(FAILED(hr) || bServiceName.vt != VT_BSTR || bServiceName.bstrVal == NULL ) goto exit_gracefully; hr = rsopInstance->Get(_bstr_t(TEXT("SDDLString")), 0, &vSDDL, NULL, NULL); if(FAILED(hr)) goto exit_gracefully; hr = rsopInstance->Get((BSTR)(TEXT("StartupMode")), 0, &vStartup, NULL, NULL); if(FAILED(hr)) goto exit_gracefully; DWORD len; len = wcslen((PTSTR) V_BSTR(&bServiceName)); serviceName = (PTSTR) LocalAlloc(LPTR, (len+1) *sizeof(WCHAR)); if(!serviceName) { hr = E_OUTOFMEMORY; goto exit_gracefully; } wcscpy(serviceName,(PTSTR) V_BSTR(&bServiceName)); ULONG sdLen; sdLen = 0; if( !ConvertStringSecurityDescriptorToSecurityDescriptor( (PTSTR) V_BSTR(&vSDDL), SDDL_REVISION_1, &SDDL, &sdLen ) ) { hr = HRESULT_FROM_WIN32(GetLastError()); goto exit_gracefully; } startup = (DWORD) V_I4(&vStartup); PSCE_SERVICES head; head = pProfileInfo->pServices; if (!head) { head = (pProfileInfo->pServices = (PSCE_SERVICES) LocalAlloc(LPTR, sizeof(SCE_SERVICES))); if(!head) { hr = E_OUTOFMEMORY; goto exit_gracefully; } } else { PSCE_SERVICES current = (PSCE_SERVICES) LocalAlloc(LPTR, sizeof(SCE_SERVICES)); if(!current) { hr = E_OUTOFMEMORY; goto exit_gracefully; } current->Next = head; head = current; pProfileInfo->pServices = head; } head->ServiceName = serviceName; head->General.pSecurityDescriptor = SDDL; head->Startup = (BYTE) startup; //no data loss value is <= 4 //Add RSOP info pProfileInfo->listRIServices.push_front(pInfo); exit_gracefully: VariantClear(&bServiceName); VariantClear(&vSDDL); VariantClear(&vStartup); _TRACE (-1,L"Leaving CWMIRsop::AddServiceSetting\n"); return hr; } HRESULT CWMIRsop::AddFileSetting(IWbemClassObject *rsopInstance, PRSOP_INFO pInfo, PWMI_SCE_PROFILE_INFO pProfileInfo) { VARIANT bFileName; PTSTR fileName = NULL; VARIANT vSDDL; VARIANT vMode; PSECURITY_DESCRIPTOR SDDL = NULL; DWORD mode = 0; _TRACE (1, L"Entering CWMIRsop::AddFileSetting\n"); HRESULT hr = S_OK; hr = rsopInstance->Get((BSTR)(TEXT("Path")), 0, &bFileName, NULL, NULL ); if(FAILED(hr) || bFileName.vt != VT_BSTR || bFileName.bstrVal == NULL ) goto exit_gracefully; hr = rsopInstance->Get((BSTR)(TEXT("Mode")), 0, &vMode, NULL, NULL ); if(FAILED(hr)) goto exit_gracefully; hr = rsopInstance->Get((BSTR)(TEXT("SDDLString")), 0, &vSDDL, NULL, NULL ); if(FAILED(hr)) goto exit_gracefully; DWORD len; len = wcslen((PTSTR) V_BSTR(&bFileName)); fileName = (PTSTR) LocalAlloc(LPTR, len * sizeof(TCHAR) + 2); if(!fileName) { hr = E_OUTOFMEMORY; goto exit_gracefully; } wcscpy(fileName, (PTSTR) V_BSTR(&bFileName)); mode = (DWORD) V_I4(&vMode); if (mode != 1) { ULONG sdLen = 0; if( !ConvertStringSecurityDescriptorToSecurityDescriptor( (PTSTR) V_BSTR(&vSDDL), SDDL_REVISION_1, &SDDL, &sdLen )) { hr = HRESULT_FROM_WIN32(GetLastError()); goto exit_gracefully; } } PSCE_OBJECT_ARRAY head; head = pProfileInfo->pFiles.pAllNodes; if(!head) { head = (pProfileInfo->pFiles.pAllNodes = (PSCE_OBJECT_ARRAY) LocalAlloc(LPTR, sizeof(SCE_OBJECT_ARRAY))); if(!head) { hr = E_OUTOFMEMORY; goto exit_gracefully; } head->pObjectArray = (PSCE_OBJECT_SECURITY*) LocalAlloc(LPTR, sizeof(PSCE_OBJECT_SECURITY)*m_cFileSize); if(!head->pObjectArray) { hr = E_OUTOFMEMORY; goto exit_gracefully; } } else if(head->Count >= m_cFileSize) { PSCE_OBJECT_SECURITY* temp = (PSCE_OBJECT_SECURITY*) LocalAlloc(LPTR, sizeof(PSCE_OBJECT_SECURITY)*m_cFileSize*2); if(!temp) { hr = E_OUTOFMEMORY; goto exit_gracefully; } memcpy(temp,head->pObjectArray,head->Count *sizeof(PSCE_OBJECT_SECURITY)); LocalFree(head->pObjectArray); head->pObjectArray = temp; m_cFileSize *=2; } DWORD index; index = head->Count; head->pObjectArray[index] = (PSCE_OBJECT_SECURITY) LocalAlloc(LPTR, sizeof(SCE_OBJECT_SECURITY)); if(!head->pObjectArray[index]) { hr = E_OUTOFMEMORY; goto exit_gracefully; } head->pObjectArray[index]->Name = fileName; head->pObjectArray[index]->pSecurityDescriptor = SDDL; head->pObjectArray[index]->Status = (BYTE) mode; head->Count++; //SET RSOP INFO pProfileInfo->vecRIFiles.push_back(pInfo); exit_gracefully: VariantClear(&bFileName); VariantClear(&vMode); if(mode != 1){ VariantClear(&vSDDL); } _TRACE (-1,L"Leaving CWMIRsop::AddFileSetting\n"); return hr; } HRESULT CWMIRsop::AddRegSetting(IWbemClassObject *rsopInstance, PRSOP_INFO pInfo, PWMI_SCE_PROFILE_INFO pProfileInfo) { PTSTR gpoID = NULL; VARIANT bFileName; PTSTR fileName = NULL; VARIANT vSDDL; VARIANT vMode; PSECURITY_DESCRIPTOR SDDL = NULL; DWORD mode = 0; static DWORD multiplier = 1; HRESULT hr = S_OK; _TRACE (1, L"Entering CWMIRsop::AddRegSetting\n"); hr = rsopInstance->Get((BSTR)(TEXT("Path")), 0, &bFileName, NULL, NULL ); if(FAILED(hr) || bFileName.vt != VT_BSTR || bFileName.bstrVal == NULL ) goto exit_gracefully; hr = rsopInstance->Get((BSTR)(TEXT("Mode")), 0, &vMode, NULL, NULL ); if(FAILED(hr)) goto exit_gracefully; hr = rsopInstance->Get((BSTR)(TEXT("SDDLString")), 0, &vSDDL, NULL, NULL ); if(FAILED(hr)) goto exit_gracefully; DWORD len; len = wcslen((PTSTR) V_BSTR(&bFileName)); fileName = (PTSTR) LocalAlloc(LPTR, len * sizeof(TCHAR) + 2); if(!fileName) { hr = E_OUTOFMEMORY; goto exit_gracefully; } wcscpy(fileName, (PTSTR) V_BSTR(&bFileName)); mode = (DWORD) V_I4(&vMode); if (mode != 1) { ULONG sdLen = 0; if( !ConvertStringSecurityDescriptorToSecurityDescriptor( (PTSTR) V_BSTR(&vSDDL), SDDL_REVISION_1, &SDDL, &sdLen )) { hr = HRESULT_FROM_WIN32(GetLastError()); goto exit_gracefully; } } PSCE_OBJECT_ARRAY head; head = pProfileInfo->pRegistryKeys.pAllNodes; if(!head){ head = (pProfileInfo->pRegistryKeys.pAllNodes = (PSCE_OBJECT_ARRAY) LocalAlloc(LPTR, sizeof(SCE_OBJECT_ARRAY))); if(!head) { hr = E_OUTOFMEMORY; goto exit_gracefully; } head->pObjectArray = (PSCE_OBJECT_SECURITY*) LocalAlloc(LPTR, sizeof(PSCE_OBJECT_SECURITY)*m_cRegArrayCount); if(!head->pObjectArray) { hr = E_OUTOFMEMORY; goto exit_gracefully; } } else if(head->Count >= m_cRegArrayCount){ PSCE_OBJECT_SECURITY* temp = head->pObjectArray; head->pObjectArray = (PSCE_OBJECT_SECURITY*) LocalAlloc(LPTR, sizeof(PSCE_OBJECT_SECURITY)*m_cRegArrayCount*2); if(!head->pObjectArray) { hr = E_OUTOFMEMORY; goto exit_gracefully; } memcpy(head->pObjectArray,temp,head->Count *sizeof(PSCE_OBJECT_SECURITY)); LocalFree(temp); m_cRegArrayCount *= 2; } // // Can't initialize at declaration since this is skipped by gotos // DWORD index; index = head->Count; head->pObjectArray[index] = (PSCE_OBJECT_SECURITY) LocalAlloc(LPTR, sizeof(SCE_OBJECT_SECURITY)); if (head->pObjectArray[index]) { head->pObjectArray[index]->Name = fileName; head->pObjectArray[index]->pSecurityDescriptor = SDDL; head->pObjectArray[index]->Status = (BYTE) mode; head->Count++; } //add rsop info pProfileInfo->vecRIReg.push_back(pInfo); exit_gracefully: VariantClear(&bFileName); VariantClear(&vMode); if(mode != 1){ VariantClear(&vSDDL); } _TRACE (-1, L"Leaving CWMIRsop::AddRegSetting\n"); return hr; } HRESULT CWMIRsop::AddStringSetting (IWbemClassObject *rsopInstance, PRSOP_INFO pInfo, PWMI_SCE_PROFILE_INFO pProfileInfo) { HRESULT hr = S_OK; VARIANT bKeyName; PWSTR keyName = 0; VARIANT bSettingValue; PWSTR settingValue = 0; _TRACE (1, L"Entering CWMIRsop::AddStringSetting\n"); hr = rsopInstance->Get((BSTR)RSOP_KEYNAME, 0, &bKeyName, NULL, NULL); if( FAILED(hr) || bKeyName.vt != VT_BSTR || bKeyName.bstrVal == NULL) goto exit_gracefully; hr = rsopInstance->Get((BSTR)RSOP_SETTING, 0, &bSettingValue, NULL, NULL); if( FAILED(hr) || bSettingValue.vt != VT_BSTR || bSettingValue.bstrVal == NULL) goto exit_gracefully; keyName = V_BSTR(&bKeyName); settingValue = V_BSTR(&bSettingValue); if (!_wcsicmp(keyName, NEW_GUEST_NAME)) { if ( 0 != pProfileInfo->NewGuestName ) { LocalFree (pProfileInfo->NewGuestName); pProfileInfo->NewGuestName = 0; } size_t len = wcslen (settingValue); pProfileInfo->NewGuestName = (PWSTR) LocalAlloc (LPTR, (len + 1) * sizeof (TCHAR)); if ( pProfileInfo->NewGuestName ) { wcscpy (pProfileInfo->NewGuestName, settingValue); } else hr = E_OUTOFMEMORY; pProfileInfo->pRINewGuestName = pInfo; } else if (!_wcsicmp(keyName, NEW_ADMINISTRATOR_NAME)) { if ( 0 != pProfileInfo->NewAdministratorName ) { LocalFree (pProfileInfo->NewAdministratorName); pProfileInfo->NewAdministratorName = 0; } size_t len = wcslen (settingValue); pProfileInfo->NewAdministratorName = (PWSTR) LocalAlloc (LPTR, (len + 1) * sizeof (TCHAR)); if ( pProfileInfo->NewAdministratorName ) { wcscpy (pProfileInfo->NewAdministratorName, settingValue); } else hr = E_OUTOFMEMORY; pProfileInfo->pRINewAdministratorName = pInfo; } else { _ASSERT (FALSE); // key name not accounted for } exit_gracefully: VariantClear(&bKeyName); VariantClear(&bSettingValue); _TRACE (-1,L"Leaving CWMIRsop::AddStringSetting\n"); return hr; } HRESULT CWMIRsop::AddInstance(IWbemClassObject *rsopInstance, PRSOP_INFO pInfo, PWMI_SCE_PROFILE_INFO pProfileInfo) { HRESULT hr = S_OK; LPWSTR className = NULL; _TRACE (1, L"Entering CWMIRsop::AddInstance\n"); //Get RSOP_Class Name hr = GetClass(rsopInstance, &className); if( FAILED(hr) ) goto exit_gracefully; if(!_wcsicmp(className, RSOP_SEC_NUM)) { hr = AddNumericSetting(rsopInstance, pInfo, pProfileInfo); } else if(!_wcsicmp(className, RSOP_SEC_BOOL)) { hr = AddBooleanSetting(rsopInstance, pInfo, pProfileInfo); } else if(!_wcsicmp(className, RSOP_SCE_STRING)) { hr = AddStringSetting(rsopInstance,pInfo,pProfileInfo); } else if(!_wcsicmp(className, RSOP_AUDIT)) { hr = AddAuditSetting(rsopInstance,pInfo,pProfileInfo); } else if(!_wcsicmp(className, RSOP_EVENT_NUM)) { hr = AddEventLogNumericSetting (rsopInstance, pInfo, pProfileInfo); } else if(!_wcsicmp(className, RSOP_EVENT_BOOL)) { hr = AddEventLogBooleanSetting(rsopInstance,pInfo,pProfileInfo); } else if(!_wcsicmp(className, RSOP_REG_VAL)) { hr = AddRegValSetting(rsopInstance,pInfo,pProfileInfo); } else if(!_wcsicmp(className, RSOP_USER_RIGHT)) { hr = AddUserRightSetting(rsopInstance,pInfo,pProfileInfo); } else if(!_wcsicmp(className, RSOP_RGROUPS)) { hr = AddRestrictedGroupSetting(rsopInstance,pInfo,pProfileInfo); } else if(!_wcsicmp(className, RSOP_SERVICE)) { hr = AddServiceSetting(rsopInstance,pInfo,pProfileInfo); } else if(!_wcsicmp(className, RSOP_FILE)) { hr = AddFileSetting(rsopInstance,pInfo,pProfileInfo); } else if(!_wcsicmp(className, RSOP_REG)) { hr = AddRegSetting(rsopInstance,pInfo,pProfileInfo); } else { _ASSERT (FALSE); // class not accounted for } exit_gracefully: _TRACE (-1,L"Exiting CWMIRsop::AddInstance\n"); LocalFree(className); return hr; } HRESULT CWMIRsop::GetGPOFriendlyName (PWSTR lpGPOID, PWSTR *pGPOName) { BSTR pQuery = NULL, pName = NULL; LPTSTR lpQuery = NULL; IEnumWbemClassObject * pEnum = NULL; IWbemClassObject *pObjects[2]; HRESULT hr; ULONG ulRet; VARIANT varGPOName; // // Set the default // *pGPOName = NULL; // // Build the query // lpQuery = (LPTSTR) LocalAlloc (LPTR, ((lstrlen(lpGPOID) + 50) * sizeof(TCHAR))); if (!lpQuery) { _TRACE (0, L"CWMIRsop::GetGPOFriendlyName: Failed to allocate memory for unicode query"); hr = HRESULT_FROM_WIN32(ERROR_OUTOFMEMORY); goto Exit; } wsprintf (lpQuery, TEXT("SELECT name, id FROM RSOP_GPO where id=\"%s\""), lpGPOID); pQuery = SysAllocString (lpQuery); if (!pQuery) { _TRACE (0, L"CWMIRsop::GetGPOFriendlyName: Failed to allocate memory for query"); hr = HRESULT_FROM_WIN32(ERROR_OUTOFMEMORY); goto Exit; } // // Allocate BSTRs for the property names we want to retreive // pName = SysAllocString (TEXT("name")); if (!pName) { _TRACE (0, L"CWMIRsop::GetGPOFriendlyName: Failed to allocate memory for name"); hr = HRESULT_FROM_WIN32(ERROR_OUTOFMEMORY); goto Exit; } // // Execute the query // hr = m_pSvc->ExecQuery (_bstr_t(QUERY_LANG), pQuery, WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY, NULL, &pEnum); if (FAILED(hr)) { _TRACE (0, L"CWMIRsop::GetGPOFriendlyName: Failed to query for %s with 0x%x\n", pQuery, hr); goto Exit; } // // Loop through the results // hr = pEnum->Next(WBEM_INFINITE, 1, pObjects, &ulRet); if (FAILED(hr)) { _TRACE (0, L"CWMIRsop::GetGPOFriendlyName: Failed to get first item in query results for %s with 0x%x\n", pQuery, hr); goto Exit; } // // Check for the "data not available case" // if (ulRet == 0) { hr = S_OK; goto Exit; } // // Get the name // VariantInit(&varGPOName); hr = pObjects[0]->Get (pName, 0, &varGPOName, NULL, NULL); if (FAILED(hr)) { _TRACE (0, L"CWMIRsop::GetGPOFriendlyName: Failed to get gponame in query results for %s with 0x%x\n", pQuery, hr); goto Exit; } // // Save the name // *pGPOName = (LPTSTR) LocalAlloc (LPTR, (lstrlen(varGPOName.bstrVal) + 1) * sizeof(TCHAR)); if (!(*pGPOName)) { _TRACE (0, L"CWMIRsop::GetGPOFriendlyName: Failed to allocate memory for GPO Name"); hr = HRESULT_FROM_WIN32(ERROR_OUTOFMEMORY); goto Exit; } lstrcpy (*pGPOName, varGPOName.bstrVal); hr = S_OK; Exit: VariantClear (&varGPOName); if (pEnum) { pEnum->Release(); } if (pQuery) { SysFreeString (pQuery); } if (lpQuery) { LocalFree (lpQuery); } if (pName) { SysFreeString (pName); } return hr; }