/*++ Copyright (c) 2000 Microsoft Corporation Module Name: precedence.cpp Abstract: This file contains the main routine to calculate precedences. This is called during planning/diagnosis. Author: Vishnu Patankar (VishnuP) 7-April-2000 Environment: User Mode - Win32 Revision History: --*/ /////////////////////////////////////////////////////////////////////////////// // // // Includes // // // /////////////////////////////////////////////////////////////////////////////// #include "precedence.h" #include "logger.h" #include "infp.h" #include "headers.h" #include "align.h" #include "..\sceutil.h" #include #include "scerpc.h" extern BOOL gbAsyncWinlogonThread; extern HRESULT gHrSynchRsopStatus; extern HRESULT gHrAsynchRsopStatus; extern BOOL gbThisIsDC; extern BOOL gbDCQueried; extern PWSTR gpwszDCDomainName; extern HINSTANCE MyModuleHandle; WCHAR gpwszPlanOrDiagLogFile[MAX_PATH]; /////////////////////////////////////////////////////////////////////////////// // // // Private defines // // // /////////////////////////////////////////////////////////////////////////////// #define SCEP_VALID_NAME(pName) (pName[0] == L'\0' ? NULL : pName) // // prime nos are good for hashing // #define PRIVILEGE_TABLE_SIZE 7 #define GROUP_TABLE_SIZE 7 #define REGISTRY_SECURITY_TABLE_SIZE 43 #define FILE_SECURITY_TABLE_SIZE 43 #define REGISTRY_VALUE_TABLE_SIZE 43 #define SERVICES_TABLE_SIZE 5 // // macro to gracefully handle errors // #define SCEP_RSOP_CONTINUE_OR_BREAK if (rc != NO_ERROR ) {\ rcSave = rc;\ if (rc == ERROR_NOT_ENOUGH_MEMORY)\ break;\ } // // macro to gracefully handle errors // #define SCEP_RSOP_CONTINUE_OR_GOTO if (rc != NO_ERROR ) {\ rcSave = rc;\ if (rc == ERROR_NOT_ENOUGH_MEMORY)\ goto Done;\ } const UINT NumSchemaClasses = sizeof ScepRsopSchemaClassNames/ sizeof(PWSTR); const UINT NumSettings = sizeof PrecedenceLookup/ sizeof(SCE_KEY_LOOKUP_PRECEDENCE); DWORD SceLogSettingsPrecedenceGPOs( IN IWbemServices *pWbemServices, IN BOOL bPlanningMode, IN PWSTR *ppwszLogFile ) /////////////////////////////////////////////////////////////////////////////// // precedence algorithm /// // foreach GPO (parse all gpt*.* into SceProfileInfoBuffer) /// // foreach setting in a GPO (log the values and precedences if present)/// /////////////////////////////////////////////////////////////////////////////// { PSCE_PROFILE_INFO pSceProfileInfoBuffer = NULL; PWSTR pwszGPOName = NULL; PWSTR pwszSOMID = NULL; DWORD rc = ERROR_SUCCESS; DWORD rcSave = ERROR_SUCCESS; BOOL bKerberosBlob = FALSE; PWSTR Windir = NULL; PWSTR TemplatePath = NULL; SCEP_HASH_TABLE PrivilegeHashTable(PRIVILEGE_TABLE_SIZE); SCEP_HASH_TABLE GroupHashTable(GROUP_TABLE_SIZE); SCEP_HASH_TABLE RegistrySecurityHashTable(REGISTRY_SECURITY_TABLE_SIZE); SCEP_HASH_TABLE FileSecurityHashTable(FILE_SECURITY_TABLE_SIZE); SCEP_HASH_TABLE RegistryValueHashTable(REGISTRY_VALUE_TABLE_SIZE); SCEP_HASH_TABLE ServicesHashTable(SERVICES_TABLE_SIZE); SafeAllocaAllocate( Windir, (MAX_PATH + 1) * sizeof(WCHAR) ); SafeAllocaAllocate( TemplatePath, (MAX_PATH + 50 + 1) * sizeof(WCHAR) ); if (NULL == Windir || NULL == TemplatePath) { goto ExitHandler; } // // get the path to the templates // GetSystemWindowsDirectory(Windir, MAX_PATH); Windir[MAX_PATH-1] = L'\0'; if (bPlanningMode) { swprintf(TemplatePath, L"%s"PLANNING_GPT_DIR L"gpt*.*", Windir); } else { swprintf(TemplatePath, L"%s"DIAGNOSIS_GPT_DIR L"gpt*.*", Windir); } gpwszPlanOrDiagLogFile[MAX_PATH-1] = L'\0'; // // old planning.log/diagnosis.log removed (*ppwszLogFile != NULL if verbose) // if (*ppwszLogFile) { if (bPlanningMode) { wcscpy(gpwszPlanOrDiagLogFile, *ppwszLogFile); } else { wcscpy(gpwszPlanOrDiagLogFile, Windir); wcscat(gpwszPlanOrDiagLogFile, DIAGNOSIS_LOG_FILE); } WCHAR szTmpName[MAX_PATH]; wcscpy(szTmpName, gpwszPlanOrDiagLogFile); UINT Len = wcslen(szTmpName); szTmpName[Len-3] = L'o'; szTmpName[Len-2] = L'l'; szTmpName[Len-1] = L'd'; CopyFile( gpwszPlanOrDiagLogFile, szTmpName, FALSE ); DeleteFile(gpwszPlanOrDiagLogFile); } else { gpwszPlanOrDiagLogFile[0] = L'\0'; } // // clear the database log - if something fails continue // for (UINT schemaClassNum = 0; schemaClassNum < NumSchemaClasses ; schemaClassNum++ ) { rc = ScepWbemErrorToDosError(DeleteInstances( ScepRsopSchemaClassNames[schemaClassNum], pWbemServices )); if (rc != NO_ERROR) rcSave = rc; } ScepLogEventAndReport(MyModuleHandle, gpwszPlanOrDiagLogFile, 0, 0, IDS_CLEAR_RSOP_DB, rcSave, NULL ); // // need to process the files from gpt9999* -> gpt0000* (opposite of jetdb merge) // use LIFO linked stack of gpt* filenames // intptr_t hFile; struct _wfinddata_t FileInfo; HINF hInf; hFile = _wfindfirst(TemplatePath, &FileInfo); PSCE_NAME_STATUS_LIST pGptNameList = NULL; if ( hFile != -1 ) { do { if (ERROR_NOT_ENOUGH_MEMORY == (rc = ScepAddToNameStatusList( &pGptNameList, FileInfo.name, wcslen(FileInfo.name), 0))) { _findclose(hFile); if (pGptNameList) ScepFreeNameStatusList(pGptNameList); rcSave = ERROR_NOT_ENOUGH_MEMORY; goto ExitHandler; } } while ( _wfindnext(hFile, &FileInfo) == 0 ); _findclose(hFile); } // // first get all the GPOs, and some other info needed for logging // this is the outermost loop (per gpt*.* template) // PSCE_NAME_STATUS_LIST pCurrFileName = pGptNameList; while (pCurrFileName) { DWORD dwAuditLogRetentionPeriod[] = {SCE_NO_VALUE, SCE_NO_VALUE, SCE_NO_VALUE}; DWORD dwLockoutBadCount = SCE_NO_VALUE; if (bPlanningMode) { swprintf(TemplatePath, L"%s"PLANNING_GPT_DIR L"%s", Windir, pCurrFileName->Name); } else { swprintf(TemplatePath, L"%s"DIAGNOSIS_GPT_DIR L"%s", Windir, pCurrFileName->Name); } // // open template file // rc = SceInfpOpenProfile( TemplatePath, &hInf ); DWORD dSize = 0; INFCONTEXT InfLine; // // get GPO name - default to "NoName" if unable to get it // if (rc == ERROR_SUCCESS) { if ( SetupFindFirstLine(hInf,L"Version",L"DSPath",&InfLine) ) { if (SetupGetStringField(&InfLine,1,NULL,0,&dSize) && dSize > 0) { pwszGPOName = (PWSTR)ScepAlloc( 0, (dSize+1)*sizeof(WCHAR)); if (!pwszGPOName) { rc = SCESTATUS_NOT_ENOUGH_RESOURCE; SceInfpCloseProfile(hInf); goto NextGPO; } pwszGPOName[dSize] = L'\0'; SetupGetStringField(&InfLine,1,pwszGPOName,dSize, NULL); } else rc = GetLastError(); } else rc = GetLastError(); if (rc != ERROR_SUCCESS) { // // log this error and continue this GPO by initializing pwszGPOName to "NoGPOName" // if (pwszGPOName) ScepFree(pwszGPOName); rcSave = rc; pwszGPOName = (PWSTR)ScepAlloc( 0, (9+1)*sizeof(WCHAR)); if (!pwszGPOName) { rc = SCESTATUS_NOT_ENOUGH_RESOURCE; rcSave = rc; SceInfpCloseProfile(hInf); goto NextGPO; } wcscpy(pwszGPOName, L"NoGPOName"); ScepLogEventAndReport(MyModuleHandle, gpwszPlanOrDiagLogFile, 0, 0, IDS_ERROR_OPEN_CACHED_GPO, rc, TemplatePath ); } } else { rcSave = rc; ScepLogEventAndReport(MyModuleHandle, gpwszPlanOrDiagLogFile, 0, 0, IDS_ERROR_OPEN_CACHED_GPO, rc, TemplatePath ); // // will continue with next GPO // goto NextGPO; } // // get SOMID - default to "NoSOMID" if unable to get it // if ( SetupFindFirstLine(hInf,L"Version",L"SOMID",&InfLine) ) { if (SetupGetStringField(&InfLine,1,NULL,0,&dSize) && dSize > 0) { pwszSOMID = (PWSTR)ScepAlloc( 0, (dSize+1)*sizeof(WCHAR)); pwszSOMID[dSize] = L'\0'; SetupGetStringField(&InfLine,1,pwszSOMID,dSize, NULL); } else rc = GetLastError(); } else rc = GetLastError(); if (rc != ERROR_SUCCESS) { // // log this error and continue this GPO by initializing pwszGPOName to "NoGPOName" // if (pwszSOMID) ScepFree(pwszSOMID); rcSave = rc; pwszSOMID = (PWSTR)ScepAlloc( 0, (7 + 1)*sizeof(WCHAR)); if (!pwszSOMID) { rc = SCESTATUS_NOT_ENOUGH_RESOURCE; rcSave = rc; SceInfpCloseProfile(hInf); goto NextGPO; } wcscpy(pwszSOMID, L"NoSOMID"); ScepLogEventAndReport(MyModuleHandle, gpwszPlanOrDiagLogFile, 0, 0, IDS_ERROR_OPEN_CACHED_GPO, rc, TemplatePath ); } rc = SceInfpGetSecurityProfileInfo( hInf, AREA_ALL, &pSceProfileInfoBuffer, NULL ); if (rc != ERROR_SUCCESS) { rcSave = rc; SceInfpCloseProfile(hInf); ScepLogEventAndReport(MyModuleHandle, gpwszPlanOrDiagLogFile, 0, 0, IDS_ERROR_OPEN_CACHED_GPO, rc, TemplatePath ); // // will continue with next GPO // goto NextGPO; } SceInfpCloseProfile(hInf); ScepLogEventAndReport(MyModuleHandle, gpwszPlanOrDiagLogFile, 0, 0, IDS_INFO_RSOP_LOG, rc, pwszGPOName ); // // now the info buffer is successfully populated - need to // iterate over all settings for this GPO // // // to efficiently access fields(settings) in the info buffer, we use a lookup table of // precomputed offsets // // // a matrix holds precedence info for fields whose locations are well known in memory // and hash-tables hold precedence info for fields whose locations are dynamic // // // try except around each log attempt - intention is to continue with next setting if // logging for current setting fails // guarded code does not explicitly throw any exceptions - error codes are set instead // so, if we get an exception it is thrown by the system in which case we ignore and continue // // // this is the second loop (setting per gpt*.* template) // bKerberosBlob = FALSE; for (UINT settingNo = 0; settingNo < NumSettings; settingNo++) { CHAR settingType = PrecedenceLookup[settingNo].KeyLookup.BufferType; PWSTR pSettingName = PrecedenceLookup[settingNo].KeyLookup.KeyString; UINT settingOffset = PrecedenceLookup[settingNo].KeyLookup.Offset; DWORD *pSettingPrecedence = &PrecedenceLookup[settingNo].Precedence; BOOL bSystemAccessPolicy = PrecedenceLookup[settingNo].bSystemAccessPolicy; BOOL bLogErrorOutsideSwitch = TRUE; // // depending on the schema class being processed, we instantiate logger objects // // on BDCs, skip system access policies if (gMachineRole == DsRole_RoleBackupDomainController && bSystemAccessPolicy == TRUE) { continue; } switch (settingType) { case RSOP_SecuritySettingNumeric: try { { RSOP_SecuritySettingNumericLogger Log(pWbemServices, pwszGPOName, pwszSOMID); // // special case kerberos since it is dynamically allocated // if (_wcsicmp(pSettingName, L"pKerberosInfo") == 0) bKerberosBlob = TRUE; if (bKerberosBlob == FALSE && (bPlanningMode || !(gbDCQueried == TRUE && gbThisIsDC == TRUE) || ((gbDCQueried == TRUE && gbThisIsDC == TRUE) && wcsstr(pCurrFileName->Name, L".dom")))) { DWORD dwValue = SCEP_TYPECAST(DWORD, pSceProfileInfoBuffer, settingOffset); if (dwValue != SCE_NO_VALUE) { // // LockoutBadCount controls two other lockout settings - so remember // if (_wcsicmp(pSettingName, L"LockoutBadCount") == 0) dwLockoutBadCount = dwValue; // // skip if dwLockoutBadCount == 0 // if (_wcsicmp(pSettingName, L"ResetLockoutCount") == 0 && (dwLockoutBadCount == 0 || dwLockoutBadCount == SCE_NO_VALUE)) continue; if (_wcsicmp(pSettingName, L"LockoutDuration") == 0 && (dwLockoutBadCount == 0 || dwLockoutBadCount == SCE_NO_VALUE)) continue; rc = ScepWbemErrorToDosError(Log.Log( pSettingName, dwValue, ++(*pSettingPrecedence) )); if (rc == NO_ERROR) ScepLogEventAndReport(MyModuleHandle, gpwszPlanOrDiagLogFile, 0, 0, IDS_INFO_RSOP_LOG, rc, pSettingName ); if (rc != NO_ERROR) break; } } else if (bKerberosBlob == TRUE && (bPlanningMode || ((gbDCQueried == TRUE && gbThisIsDC == TRUE) && wcsstr(pCurrFileName->Name, L".dom")))) { // // kerberos only if DC from *.dom. If planning mode don't care type of m/c // PSCE_KERBEROS_TICKET_INFO pKerberosInfo = SCEP_TYPECAST(PSCE_KERBEROS_TICKET_INFO, pSceProfileInfoBuffer, settingOffset); bLogErrorOutsideSwitch = FALSE; if (pKerberosInfo) { // // kerberos numeric // for (UINT NumericSubSetting = 1; NumericSubSetting < NUM_KERBEROS_SUB_SETTINGS; NumericSubSetting++ ) { pSettingName = PrecedenceLookup[settingNo + NumericSubSetting].KeyLookup.KeyString; settingOffset = PrecedenceLookup[settingNo + NumericSubSetting].KeyLookup.Offset; pSettingPrecedence = &PrecedenceLookup[settingNo + NumericSubSetting].Precedence; DWORD dwValue = SCEP_TYPECAST(DWORD, pKerberosInfo, settingOffset); if (dwValue != SCE_NO_VALUE) { rc = ScepWbemErrorToDosError(Log.Log( pSettingName, dwValue, ++(*pSettingPrecedence) )); ScepLogEventAndReport(MyModuleHandle, gpwszPlanOrDiagLogFile, 0, 0, IDS_INFO_RSOP_LOG, rc, pSettingName ); SCEP_RSOP_CONTINUE_OR_BREAK } } // //kerberos boolean (moved here to incompatible case: statement - to avoid a goto) // pSettingName = PrecedenceLookup[settingNo + NUM_KERBEROS_SUB_SETTINGS].KeyLookup.KeyString; settingOffset = PrecedenceLookup[settingNo + NUM_KERBEROS_SUB_SETTINGS].KeyLookup.Offset; pSettingPrecedence = &PrecedenceLookup[settingNo + NUM_KERBEROS_SUB_SETTINGS].Precedence; DWORD dwValue = SCEP_TYPECAST(DWORD, pKerberosInfo, settingOffset); RSOP_SecuritySettingBooleanLogger LogBool(pWbemServices, pwszGPOName, pwszSOMID); if (rc != ERROR_NOT_ENOUGH_MEMORY && dwValue != SCE_NO_VALUE) { rc = ScepWbemErrorToDosError(LogBool.Log( pSettingName, dwValue, ++(*pSettingPrecedence) )); ScepLogEventAndReport(MyModuleHandle, gpwszPlanOrDiagLogFile, 0, 0, IDS_INFO_RSOP_LOG, rc, pSettingName ); if (rc != NO_ERROR ) { rcSave = rc; } } } } // // just processed NUM_KERBEROS_SUB_SETTINGS // if (bKerberosBlob) settingNo += NUM_KERBEROS_SUB_SETTINGS; } } catch (...) { // // system error continue with next setting // rc = EVENT_E_INTERNALEXCEPTION; bLogErrorOutsideSwitch = TRUE; } break; case RSOP_SecuritySettingBoolean: try { { RSOP_SecuritySettingBooleanLogger Log(pWbemServices, pwszGPOName, pwszSOMID); DWORD dwValue = SCEP_TYPECAST(DWORD, pSceProfileInfoBuffer, settingOffset); BOOL bDomainUniformSetting = (0 == _wcsicmp(pSettingName, L"ClearTextPassword") || 0 == _wcsicmp(pSettingName, L"RequireLogonToChangePassword") || 0 == _wcsicmp(pSettingName, L"ForceLogoffWhenHourExpire") || 0 == _wcsicmp(pSettingName, L"EnableAdminAccount") || 0 == _wcsicmp(pSettingName, L"EnableGuestAccount") || 0 == _wcsicmp(pSettingName, L"PasswordComplexity")); if (bDomainUniformSetting && !(bPlanningMode || !(gbDCQueried == TRUE && gbThisIsDC == TRUE) || ((gbDCQueried == TRUE && gbThisIsDC == TRUE) && wcsstr(pCurrFileName->Name, L".dom")))) { // // if it is a domain uniform policy and not coming from a domain policy on a DC, do not log. // continue; } if (dwValue != SCE_NO_VALUE) { rc = ScepWbemErrorToDosError(Log.Log( pSettingName, dwValue, ++(*pSettingPrecedence) )); if (rc == NO_ERROR) ScepLogEventAndReport(MyModuleHandle, gpwszPlanOrDiagLogFile, 0, 0, IDS_INFO_RSOP_LOG, rc, pSettingName ); if (rc != NO_ERROR) break; } } } catch (...) { // // system error continue with next setting // rc = EVENT_E_INTERNALEXCEPTION; } break; case RSOP_SecuritySettingString: try { { RSOP_SecuritySettingStringLogger Log(pWbemServices, pwszGPOName, pwszSOMID); PWSTR pszValue = SCEP_TYPECAST(PWSTR, pSceProfileInfoBuffer, settingOffset); if (pszValue != NULL) { rc = ScepWbemErrorToDosError(Log.Log( pSettingName, pszValue, ++(*pSettingPrecedence) )); if (rc == NO_ERROR) ScepLogEventAndReport(MyModuleHandle, gpwszPlanOrDiagLogFile, 0, 0, IDS_INFO_RSOP_LOG, rc, pSettingName ); if (rc != NO_ERROR) break; } } } catch (...) { // system error continue with next setting rc = EVENT_E_INTERNALEXCEPTION; } break; case RSOP_AuditPolicy: { RSOP_AuditPolicyLogger Log(pWbemServices, pwszGPOName, pwszSOMID); DWORD dwValue = SCEP_TYPECAST(DWORD, pSceProfileInfoBuffer, settingOffset); if (dwValue != SCE_NO_VALUE) { rc = ScepWbemErrorToDosError(Log.Log( pSettingName, dwValue, ++(*pSettingPrecedence) )); if (rc == NO_ERROR) ScepLogEventAndReport(MyModuleHandle, gpwszPlanOrDiagLogFile, 0, 0, IDS_INFO_RSOP_LOG, rc, pSettingName ); if (rc != NO_ERROR) break; } } break; case RSOP_SecurityEventLogSettingNumeric: try { { RSOP_SecurityEventLogSettingNumericLogger Log(pWbemServices, pwszGPOName, pwszSOMID); bLogErrorOutsideSwitch = FALSE; for (UINT LogType = 0; LogType < NUM_EVENTLOG_TYPES ; LogType ++) { settingOffset = PrecedenceLookup[settingNo + LogType].KeyLookup.Offset; pSettingPrecedence = &PrecedenceLookup[settingNo + LogType].Precedence; DWORD dwValue = SCEP_TYPECAST(DWORD, pSceProfileInfoBuffer, settingOffset); // // calculate dwValue depdending on dwAuditLogRetentionPeriod[] // if (_wcsicmp(pSettingName, L"RetentionDays") == 0) { switch (dwAuditLogRetentionPeriod[LogType]) { case 2: // manually dwValue = MAXULONG; break; case 1: // number of days * seconds/day //if (dwValue != SCE_NO_VALUE) //dwValue = dwValue * 24 * 3600; //leave it in days break; case 0: // as needed dwValue = 0; break; // default should not happen default: dwValue = SCE_NO_VALUE; } } if (dwValue != SCE_NO_VALUE) { WCHAR pwszLogType[10]; _itow((int)LogType, pwszLogType, 10); // // AuditLogRetentionPeriod controls RetentionDays - so remember // also it is never logged since it is an artifact of the template spec // if (_wcsicmp(pSettingName, L"AuditLogRetentionPeriod") == 0) { dwAuditLogRetentionPeriod[LogType] = dwValue; ScepLogEventAndReport(MyModuleHandle, gpwszPlanOrDiagLogFile, 0, 0, IDS_INFO_RSOP_LOG, LogType, pSettingName ); continue; } rc = ScepWbemErrorToDosError(Log.Log( pSettingName, pwszLogType, dwValue, ++(*pSettingPrecedence) )); ScepLogEventAndReport(MyModuleHandle, gpwszPlanOrDiagLogFile, 0, 0, IDS_INFO_RSOP_LOG, LogType, pSettingName ); SCEP_RSOP_CONTINUE_OR_BREAK } } // // just processed NUM_EVENTLOG_TYPES - system, application, security, for this setting // settingNo += NUM_EVENTLOG_TYPES - 1; } } catch (...) { // // system error continue with next setting // rc = EVENT_E_INTERNALEXCEPTION; bLogErrorOutsideSwitch = TRUE; } break; case RSOP_SecurityEventLogSettingBoolean: try { { RSOP_SecurityEventLogSettingBooleanLogger Log(pWbemServices, pwszGPOName, pwszSOMID); bLogErrorOutsideSwitch = FALSE; for (UINT LogType = 0; LogType < NUM_EVENTLOG_TYPES ; LogType ++) { settingOffset = PrecedenceLookup[settingNo + LogType].KeyLookup.Offset; pSettingPrecedence = &PrecedenceLookup[settingNo + LogType].Precedence; DWORD dwValue = SCEP_TYPECAST(DWORD, pSceProfileInfoBuffer, settingOffset); if (dwValue != SCE_NO_VALUE) { WCHAR pwszLogType[10]; _itow((int)LogType, pwszLogType, 10); rc = ScepWbemErrorToDosError(Log.Log( pSettingName, pwszLogType, dwValue, ++(*pSettingPrecedence) )); ScepLogEventAndReport(MyModuleHandle, gpwszPlanOrDiagLogFile, 0, 0, IDS_INFO_RSOP_LOG, rc, pSettingName ); SCEP_RSOP_CONTINUE_OR_BREAK } } // // processed NUM_EVENTLOG_TYPES - system, application, security, for this setting // settingNo += NUM_EVENTLOG_TYPES - 1; } } catch (...) { // // system error continue with next setting // rc = EVENT_E_INTERNALEXCEPTION; bLogErrorOutsideSwitch = TRUE; } break; case RSOP_RegistryValue: try { { RSOP_RegistryValueLogger Log(pWbemServices, pwszGPOName, pwszSOMID); DWORD dwRegCount = SCEP_TYPECAST(DWORD, pSceProfileInfoBuffer, settingOffset); PSCE_REGISTRY_VALUE_INFO aRegValues = NULL; // // 64-bit alignment fix (alternatively, have an entry for aRegValues in the offset table) // #ifdef _WIN64 // CHAR *pAlign; aRegValues = pSceProfileInfoBuffer->aRegValues; // pAlign = (CHAR *)pSceProfileInfoBuffer + settingOffset + sizeof(DWORD); // aRegValues = (PSCE_REGISTRY_VALUE_INFO)ROUND_UP_POINTER(pAlign,ALIGN_LPVOID); #else aRegValues = SCEP_TYPECAST(PSCE_REGISTRY_VALUE_INFO, pSceProfileInfoBuffer, settingOffset + sizeof(DWORD)); #endif bLogErrorOutsideSwitch = FALSE; if ( aRegValues == NULL ) continue; for (UINT regNo = 0; regNo < dwRegCount; regNo++ ) { if ((aRegValues)[regNo].FullValueName) { pSettingPrecedence = NULL; if (NO_ERROR != (rc = RegistryValueHashTable.LookupAdd( (aRegValues)[regNo].FullValueName, &pSettingPrecedence))) { rcSave = rc; ScepLogEventAndReport(MyModuleHandle, gpwszPlanOrDiagLogFile, 0, 0, IDS_ERROR_RSOP_LOG, rc, (aRegValues)[regNo].FullValueName ); // // if hash table fails for any reason, cannot // trust it for processing of other elements // break; } rc = ScepWbemErrorToDosError(Log.Log( (aRegValues)[regNo].FullValueName, (aRegValues)[regNo].ValueType, (aRegValues)[regNo].Value, ++(*pSettingPrecedence) )); ScepLogEventAndReport(MyModuleHandle, gpwszPlanOrDiagLogFile, 0, 0, IDS_INFO_RSOP_LOG, rc, (aRegValues)[regNo].FullValueName ); SCEP_RSOP_CONTINUE_OR_BREAK } } } } catch (...) { // // system error continue with next setting // rc = EVENT_E_INTERNALEXCEPTION; bLogErrorOutsideSwitch = TRUE; } break; case RSOP_UserPrivilegeRight: try { { RSOP_UserPrivilegeRightLogger Log(pWbemServices, pwszGPOName, pwszSOMID); PSCE_PRIVILEGE_ASSIGNMENT pInfPrivilegeAssignedTo = SCEP_TYPECAST(PSCE_PRIVILEGE_ASSIGNMENT, pSceProfileInfoBuffer, settingOffset); bLogErrorOutsideSwitch = FALSE; while (pInfPrivilegeAssignedTo) { if (pInfPrivilegeAssignedTo->Name) { pSettingPrecedence = NULL; if (NO_ERROR != (rc = PrivilegeHashTable.LookupAdd( pInfPrivilegeAssignedTo->Name, &pSettingPrecedence))) { rcSave = rc; ScepLogEventAndReport(MyModuleHandle, gpwszPlanOrDiagLogFile, 0, 0, IDS_ERROR_RSOP_LOG, rc, pInfPrivilegeAssignedTo->Name ); // // if hash table fails for any reason, cannot // trust it for processing of other elements // break; } rc = ScepWbemErrorToDosError(Log.Log( pInfPrivilegeAssignedTo->Name, pInfPrivilegeAssignedTo->AssignedTo, ++(*pSettingPrecedence) )); ScepLogEventAndReport(MyModuleHandle, gpwszPlanOrDiagLogFile, 0, 0, IDS_INFO_RSOP_LOG, rc, pInfPrivilegeAssignedTo->Name ); SCEP_RSOP_CONTINUE_OR_BREAK } pInfPrivilegeAssignedTo = pInfPrivilegeAssignedTo->Next; } } } catch (...) { // // system error continue with next setting // rc = EVENT_E_INTERNALEXCEPTION; bLogErrorOutsideSwitch = TRUE; } break; case RSOP_RestrictedGroup: try { { RSOP_RestrictedGroupLogger Log(pWbemServices, pwszGPOName, pwszSOMID); PSCE_GROUP_MEMBERSHIP pGroupMembership = SCEP_TYPECAST(PSCE_GROUP_MEMBERSHIP, pSceProfileInfoBuffer, settingOffset); bLogErrorOutsideSwitch = FALSE; PWSTR pCanonicalGroupName = NULL; while (pGroupMembership) { if (pGroupMembership->GroupName) { rc = ScepCanonicalizeGroupName(pGroupMembership->GroupName, &pCanonicalGroupName ); SCEP_RSOP_CONTINUE_OR_BREAK pSettingPrecedence = NULL; if (NO_ERROR != (rc = GroupHashTable.LookupAdd( pCanonicalGroupName, &pSettingPrecedence))) { rcSave = rc; ScepLogEventAndReport(MyModuleHandle, gpwszPlanOrDiagLogFile, 0, 0, IDS_ERROR_RSOP_LOG, rc, pCanonicalGroupName ); // // if hash table fails for any reason, cannot // trust it for processing of other elements // if (pCanonicalGroupName) ScepFree(pCanonicalGroupName); pCanonicalGroupName = NULL; break; } rc = ScepWbemErrorToDosError(Log.Log( pCanonicalGroupName, pGroupMembership->pMembers, ++(*pSettingPrecedence) )); ScepLogEventAndReport(MyModuleHandle, gpwszPlanOrDiagLogFile, 0, 0, IDS_INFO_RSOP_LOG, rc, pCanonicalGroupName ); if (pCanonicalGroupName) ScepFree(pCanonicalGroupName); pCanonicalGroupName = NULL; SCEP_RSOP_CONTINUE_OR_BREAK } pGroupMembership = pGroupMembership->Next; } } } catch (...) { // // system error continue with next setting // rc = EVENT_E_INTERNALEXCEPTION; bLogErrorOutsideSwitch = TRUE; } break; case RSOP_SystemService: try { { RSOP_SystemServiceLogger Log(pWbemServices, pwszGPOName, pwszSOMID); PSCE_SERVICES pServices = SCEP_TYPECAST(PSCE_SERVICES, pSceProfileInfoBuffer, settingOffset); bLogErrorOutsideSwitch = FALSE; while (pServices) { if (pServices->ServiceName) { pSettingPrecedence = NULL; if (NO_ERROR != (rc = ServicesHashTable.LookupAdd( pServices->ServiceName, &pSettingPrecedence))) { rcSave = rc; ScepLogEventAndReport(MyModuleHandle, gpwszPlanOrDiagLogFile, 0, 0, IDS_ERROR_RSOP_LOG, rc, pServices->ServiceName ); // // if hash table fails for any reason, cannot // trust it for processing of other elements // break; } rc = ScepWbemErrorToDosError(Log.Log( pServices->ServiceName, pServices->Startup, pServices->General.pSecurityDescriptor, pServices->SeInfo, ++(*pSettingPrecedence) )); ScepLogEventAndReport(MyModuleHandle, gpwszPlanOrDiagLogFile, 0, 0, IDS_INFO_RSOP_LOG, rc, pServices->ServiceName ); SCEP_RSOP_CONTINUE_OR_BREAK } pServices = pServices->Next; } } } catch (...) { // // system error continue with next setting // rc = EVENT_E_INTERNALEXCEPTION; bLogErrorOutsideSwitch = TRUE; } break; case RSOP_File: try { { RSOP_FileLogger Log(pWbemServices, pwszGPOName, pwszSOMID); SCE_OBJECTS pObjects = SCEP_TYPECAST(SCE_OBJECTS, pSceProfileInfoBuffer, settingOffset); BOOL bPathIsTranslated = FALSE; bLogErrorOutsideSwitch = FALSE; if (pObjects.pAllNodes) { PSCE_OBJECT_SECURITY *pObjectArray = pObjects.pAllNodes->pObjectArray; for (DWORD rCount = 0; rCount < pObjects.pAllNodes->Count; rCount++) { if (pObjectArray[rCount] && pObjectArray[rCount]->Name) { pSettingPrecedence = NULL; // // if diagnosis mode, translate env-vars and store // bPathIsTranslated = FALSE; PWSTR pwszTranslatedPath = NULL; if (!bPlanningMode && (wcschr(pObjectArray[rCount]->Name, L'%') != NULL )) { bPathIsTranslated = TRUE; rc = ScepClientTranslateFileDirName( pObjectArray[rCount]->Name, &pwszTranslatedPath); if ( rc == ERROR_PATH_NOT_FOUND ) rc = SCESTATUS_INVALID_DATA; else if ( rc != NO_ERROR ) rc = ScepDosErrorToSceStatus(rc); SCEP_RSOP_CONTINUE_OR_BREAK } else { pwszTranslatedPath = pObjectArray[rCount]->Name; } if (NO_ERROR != (rc = FileSecurityHashTable.LookupAdd( pwszTranslatedPath, &pSettingPrecedence))) { rcSave = rc; ScepLogEventAndReport(MyModuleHandle, gpwszPlanOrDiagLogFile, 0, 0, IDS_ERROR_RSOP_LOG, rc, pwszTranslatedPath ); // // if hash table fails for any reason, cannot // trust it for processing of other elements // if (bPathIsTranslated && pwszTranslatedPath) LocalFree(pwszTranslatedPath); break; } rc = ScepWbemErrorToDosError(Log.Log( pwszTranslatedPath, (bPathIsTranslated ? pObjectArray[rCount]->Name : NULL), pObjectArray[rCount]->Status, pObjectArray[rCount]->pSecurityDescriptor, pObjectArray[rCount]->SeInfo, ++(*pSettingPrecedence) )); ScepLogEventAndReport(MyModuleHandle, gpwszPlanOrDiagLogFile, 0, 0, IDS_INFO_RSOP_LOG, rc, pwszTranslatedPath ); if (bPathIsTranslated && pwszTranslatedPath) LocalFree(pwszTranslatedPath); SCEP_RSOP_CONTINUE_OR_BREAK } } } } } catch (...) { // // system error continue with next setting // rc = EVENT_E_INTERNALEXCEPTION; bLogErrorOutsideSwitch = TRUE; } break; case RSOP_RegistryKey: try { { RSOP_RegistryKeyLogger Log(pWbemServices, pwszGPOName, pwszSOMID); SCE_OBJECTS pObjects = SCEP_TYPECAST(SCE_OBJECTS, pSceProfileInfoBuffer, settingOffset); bLogErrorOutsideSwitch = FALSE; if (pObjects.pAllNodes) { PSCE_OBJECT_SECURITY *pObjectArray = pObjects.pAllNodes->pObjectArray; for (DWORD rCount = 0; rCount < pObjects.pAllNodes->Count; rCount++) { if (pObjectArray[rCount] && pObjectArray[rCount]->Name) { pSettingPrecedence = NULL; if (NO_ERROR != (rc = RegistrySecurityHashTable.LookupAdd( pObjectArray[rCount]->Name, &pSettingPrecedence))) { rcSave = rc; ScepLogEventAndReport(MyModuleHandle, gpwszPlanOrDiagLogFile, 0, 0, IDS_ERROR_RSOP_LOG, rc, pObjectArray[rCount]->Name ); // // if hash table fails for any reason, cannot // trust it for processing of other elements // break; } rc = ScepWbemErrorToDosError(Log.Log( pObjectArray[rCount]->Name, pObjectArray[rCount]->Status, pObjectArray[rCount]->pSecurityDescriptor, pObjectArray[rCount]->SeInfo, ++(*pSettingPrecedence) )); ScepLogEventAndReport(MyModuleHandle, gpwszPlanOrDiagLogFile, 0, 0, IDS_INFO_RSOP_LOG, rc, pObjectArray[rCount]->Name ); SCEP_RSOP_CONTINUE_OR_BREAK } } } } } catch (...) { // // system error continue with next setting // rc = EVENT_E_INTERNALEXCEPTION; bLogErrorOutsideSwitch = TRUE; } break; default: // // should not happen // rc = ERROR_INVALID_PARAMETER; } if (bLogErrorOutsideSwitch && rc != NO_ERROR ) { // // log error and continue // rcSave = rc; ScepLogEventAndReport(MyModuleHandle, gpwszPlanOrDiagLogFile, 0, 0, IDS_ERROR_RSOP_LOG, rc, pSettingName ); } bLogErrorOutsideSwitch = TRUE; // // this is the only case in which we quit logging completely // if (rc == ERROR_NOT_ENOUGH_MEMORY) break; } NextGPO: if (pSceProfileInfoBuffer) SceFreeProfileMemory(pSceProfileInfoBuffer); pSceProfileInfoBuffer = NULL; if (pwszGPOName) ScepFree(pwszGPOName); pwszGPOName = NULL; if (pwszSOMID) ScepFree(pwszSOMID); pwszSOMID = NULL; if (rc == ERROR_NOT_ENOUGH_MEMORY) break; // this is the only case in which we quit logging completely pCurrFileName = pCurrFileName->Next; } if (pGptNameList) ScepFreeNameStatusList(pGptNameList); // // only log the final status to both event log and logfile // (all other statuses are logged to logfile only) // if (rcSave == ERROR_SUCCESS) ScepLogEventAndReport(MyModuleHandle, gpwszPlanOrDiagLogFile, 0, 0, IDS_SUCCESS_RSOP_LOG, rcSave, L"" ); else ScepLogEventAndReport(MyModuleHandle, gpwszPlanOrDiagLogFile, 0, 0, IDS_ERROR_RSOP_LOG, rcSave, L"" ); ExitHandler: if ( Windir ) SafeAllocaFree( Windir ); if ( TemplatePath ) SafeAllocaFree( TemplatePath ); return rcSave; } SCEPR_STATUS SceClientCallbackRsopLog( IN AREAPR cbArea, IN DWORD ncbErrorStatus, IN wchar_t *pSettingInfo OPTIONAL, IN DWORD dwPrivLow OPTIONAL, IN DWORD dwPrivHigh OPTIONAL ) ///////////////////////////////////////////////////////////////////////////////////////////////////// // This function is called by the server via RPC when settings defined in the jet // // db are applied (along with a status of application, and optional detailed information) // // // // The areas were decided based on the granularity of configuration in scesrv. cbArea can have // // more than one area encoded in it, again due to the resolution granularity of error in scesrv. // // Hence this is a massive "if" routine // // // // configuration from jet db corresponds to precedence = "1" simulated configuration in the // // rsop database which was logged by the client. For each area, we try to log the status of // // configuration by querying the database for these precedence = "1" settings and updating the // // status fields per such instance found. We should find all called back settings in WMI db except // // for local-policy // // // // if any error, update golbal Synch/Asynch statuses with the accumulated status // ///////////////////////////////////////////////////////////////////////////////////////////////////// { DWORD rc = ERROR_SUCCESS; DWORD rcSave = ERROR_SUCCESS; // // instantiate a logger that logs status from callback (has overloaded log methods) // try { SCEP_DIAGNOSIS_LOGGER Log(tg_pWbemServices, NULL, NULL); // // password policy // if (cbArea & SCE_RSOP_PASSWORD_INFO) { try { rc = ScepWbemErrorToDosError(Log.Log(L"RSOP_SecuritySettingNumeric", L"KeyName", L"MinimumPasswordAge", ncbErrorStatus, FALSE )); ScepLogEventAndReport(MyModuleHandle, gpwszPlanOrDiagLogFile, 0, 0, IDS_ERROR_RSOP_DIAG_LOG, rc, L"MinimumPasswordAge" ); SCEP_RSOP_CONTINUE_OR_GOTO rc = ScepWbemErrorToDosError(Log.Log(L"RSOP_SecuritySettingNumeric", L"KeyName", L"MaximumPasswordAge", ncbErrorStatus, FALSE )); ScepLogEventAndReport(MyModuleHandle, gpwszPlanOrDiagLogFile, 0, 0, IDS_ERROR_RSOP_DIAG_LOG, rc, L"MaximumPasswordAge" ); SCEP_RSOP_CONTINUE_OR_GOTO rc = ScepWbemErrorToDosError(Log.Log(L"RSOP_SecuritySettingNumeric", L"KeyName", L"MinimumPasswordLength", ncbErrorStatus, FALSE )); ScepLogEventAndReport(MyModuleHandle, gpwszPlanOrDiagLogFile, 0, 0, IDS_ERROR_RSOP_DIAG_LOG, rc, L"MinimumPasswordLength" ); SCEP_RSOP_CONTINUE_OR_GOTO rc = ScepWbemErrorToDosError(Log.Log(L"RSOP_SecuritySettingNumeric", L"KeyName", L"PasswordHistorySize", ncbErrorStatus, FALSE )); ScepLogEventAndReport(MyModuleHandle, gpwszPlanOrDiagLogFile, 0, 0, IDS_ERROR_RSOP_DIAG_LOG, rc, L"PasswordHistorySize" ); SCEP_RSOP_CONTINUE_OR_GOTO rc = ScepWbemErrorToDosError(Log.Log(L"RSOP_SecuritySettingBoolean", L"KeyName", L"ClearTextPassword", ncbErrorStatus, FALSE )); ScepLogEventAndReport(MyModuleHandle, gpwszPlanOrDiagLogFile, 0, 0, IDS_ERROR_RSOP_DIAG_LOG, rc, L"ClearTextPassword" ); SCEP_RSOP_CONTINUE_OR_GOTO rc = ScepWbemErrorToDosError(Log.Log(L"RSOP_SecuritySettingBoolean", L"KeyName", L"PasswordComplexity", ncbErrorStatus, FALSE )); ScepLogEventAndReport(MyModuleHandle, gpwszPlanOrDiagLogFile, 0, 0, IDS_ERROR_RSOP_DIAG_LOG, rc, L"PasswordComplexity" ); SCEP_RSOP_CONTINUE_OR_GOTO rc = ScepWbemErrorToDosError(Log.Log(L"RSOP_SecuritySettingBoolean", L"KeyName", L"RequireLogonToChangePassword", ncbErrorStatus, FALSE )); ScepLogEventAndReport(MyModuleHandle, gpwszPlanOrDiagLogFile, 0, 0, IDS_ERROR_RSOP_DIAG_LOG, rc, L"RequireLogonToChangePassword" ); SCEP_RSOP_CONTINUE_OR_GOTO } catch (...) { // // system error continue with next setting // rcSave = EVENT_E_INTERNALEXCEPTION; } } // // account lockout policy // if (cbArea & SCE_RSOP_LOCKOUT_INFO) { try { rc = ScepWbemErrorToDosError(Log.Log(L"RSOP_SecuritySettingNumeric", L"KeyName", L"LockoutBadCount", ncbErrorStatus, FALSE )); ScepLogEventAndReport(MyModuleHandle, gpwszPlanOrDiagLogFile, 0, 0, IDS_ERROR_RSOP_DIAG_LOG, rc, L"LockoutBadCount" ); SCEP_RSOP_CONTINUE_OR_GOTO rc = ScepWbemErrorToDosError(Log.Log(L"RSOP_SecuritySettingNumeric", L"KeyName", L"ResetLockoutCount", ncbErrorStatus, FALSE )); ScepLogEventAndReport(MyModuleHandle, gpwszPlanOrDiagLogFile, 0, 0, IDS_ERROR_RSOP_DIAG_LOG, rc, L"ResetLockoutCount" ); SCEP_RSOP_CONTINUE_OR_GOTO rc = ScepWbemErrorToDosError(Log.Log(L"RSOP_SecuritySettingNumeric", L"KeyName", L"LockoutDuration", ncbErrorStatus, FALSE )); ScepLogEventAndReport(MyModuleHandle, gpwszPlanOrDiagLogFile, 0, 0, IDS_ERROR_RSOP_DIAG_LOG, rc, L"LockoutDuration" ); SCEP_RSOP_CONTINUE_OR_GOTO } catch (...) { // // system error continue with next setting // rcSave = EVENT_E_INTERNALEXCEPTION; } } // // forcelogoff setting // if (cbArea & SCE_RSOP_LOGOFF_INFO) { try { rc = ScepWbemErrorToDosError(Log.Log(L"RSOP_SecuritySettingBoolean", L"KeyName", L"ForceLogoffWhenHourExpire", ncbErrorStatus, FALSE )); ScepLogEventAndReport(MyModuleHandle, gpwszPlanOrDiagLogFile, 0, 0, IDS_ERROR_RSOP_DIAG_LOG, rc, L"ForceLogoffWhenHourExpire" ); SCEP_RSOP_CONTINUE_OR_GOTO } catch (...) { // // system error continue with next setting // rcSave = EVENT_E_INTERNALEXCEPTION; } } // // LSA policy setting // if (cbArea & SCE_RSOP_LSA_POLICY_INFO) { try { rc = ScepWbemErrorToDosError(Log.Log(L"RSOP_SecuritySettingBoolean", L"KeyName", L"LSAAnonymousNameLookup", ncbErrorStatus, FALSE )); ScepLogEventAndReport(MyModuleHandle, gpwszPlanOrDiagLogFile, 0, 0, IDS_ERROR_RSOP_DIAG_LOG, rc, L"LSAAnonymousNameLookup" ); SCEP_RSOP_CONTINUE_OR_GOTO } catch (...) { // // system error continue with next setting // rcSave = EVENT_E_INTERNALEXCEPTION; } } // // disable admin account // if (cbArea & SCE_RSOP_DISABLE_ADMIN_INFO) { try { rc = ScepWbemErrorToDosError(Log.Log(L"RSOP_SecuritySettingBoolean", L"KeyName", L"EnableAdminAccount", ncbErrorStatus, FALSE )); ScepLogEventAndReport(MyModuleHandle, gpwszPlanOrDiagLogFile, 0, 0, IDS_ERROR_RSOP_DIAG_LOG, rc, L"EnableAdminAccount" ); SCEP_RSOP_CONTINUE_OR_GOTO } catch (...) { // // system error continue with next setting // rcSave = EVENT_E_INTERNALEXCEPTION; } } // // disable guest account // if (cbArea & SCE_RSOP_DISABLE_GUEST_INFO) { try { rc = ScepWbemErrorToDosError(Log.Log(L"RSOP_SecuritySettingBoolean", L"KeyName", L"EnableGuestAccount", ncbErrorStatus, FALSE )); ScepLogEventAndReport(MyModuleHandle, gpwszPlanOrDiagLogFile, 0, 0, IDS_ERROR_RSOP_DIAG_LOG, rc, L"EnableGuestAccount" ); SCEP_RSOP_CONTINUE_OR_GOTO } catch (...) { // // system error continue with next setting // rcSave = EVENT_E_INTERNALEXCEPTION; } } // // administratorname setting // if (cbArea & SCE_RSOP_ADMIN_INFO) { try { rc = ScepWbemErrorToDosError(Log.Log(L"RSOP_SecuritySettingString", L"KeyName", L"NewAdministratorName", ncbErrorStatus, FALSE )); ScepLogEventAndReport(MyModuleHandle, gpwszPlanOrDiagLogFile, 0, 0, IDS_ERROR_RSOP_DIAG_LOG, rc, L"NewAdministratorName" ); SCEP_RSOP_CONTINUE_OR_GOTO } catch (...) { // // system error continue with next setting // rcSave = EVENT_E_INTERNALEXCEPTION; } } // // guestname setting // if (cbArea & SCE_RSOP_GUEST_INFO) { try { rc = ScepWbemErrorToDosError(Log.Log(L"RSOP_SecuritySettingString", L"KeyName", L"NewGuestName", ncbErrorStatus, FALSE )); ScepLogEventAndReport(MyModuleHandle, gpwszPlanOrDiagLogFile, 0, 0, IDS_ERROR_RSOP_DIAG_LOG, rc, L"NewGuestName" ); SCEP_RSOP_CONTINUE_OR_GOTO } catch (...) { // // system error continue with next setting // rcSave = EVENT_E_INTERNALEXCEPTION; } } // // user groups settings // if (cbArea & SCE_RSOP_GROUP_INFO) { try { PWSTR pCanonicalGroupName = NULL; PWSTR pwszCanonicalDoubleSlashName = NULL; rc = ScepCanonicalizeGroupName(pSettingInfo, &pCanonicalGroupName ); SCEP_RSOP_CONTINUE_OR_GOTO rc = ScepConvertSingleSlashToDoubleSlashPath( pCanonicalGroupName, &pwszCanonicalDoubleSlashName ); if (rc == ERROR_NOT_ENOUGH_MEMORY && pCanonicalGroupName) { ScepFree(pCanonicalGroupName); pCanonicalGroupName = NULL; } SCEP_RSOP_CONTINUE_OR_GOTO rc = ScepWbemErrorToDosError(Log.Log(L"RSOP_RestrictedGroup", L"GroupName", pwszCanonicalDoubleSlashName, ncbErrorStatus, FALSE )); ScepLogEventAndReport(MyModuleHandle, gpwszPlanOrDiagLogFile, 0, 0, IDS_ERROR_RSOP_DIAG_LOG, rc, pCanonicalGroupName ); if (pCanonicalGroupName) ScepFree(pCanonicalGroupName); if (pwszCanonicalDoubleSlashName) LocalFree(pwszCanonicalDoubleSlashName); SCEP_RSOP_CONTINUE_OR_GOTO } catch (...) { // // system error continue with next setting // rcSave = EVENT_E_INTERNALEXCEPTION; } } // // user privileges settings // if (cbArea & SCE_RSOP_PRIVILEGE_INFO) { try { // // loop through all privileges to see which are set for this account and log status // only if existing status is already != some error // for ( UINT i=0; i 0 ) { szVar = (PWSTR)ScepAlloc(0, (cSize+1)*sizeof(WCHAR)); if ( szVar ) { cSize = GetEnvironmentVariable(TmpBuf, szVar, cSize); if ( cSize > 0 ) { // // get info in szVar // bContinue = FALSE; newFileSize = ((DWORD)(pStart-oldFileName))+cSize+wcslen(pTemp+1)+1; *newFileName = (PWSTR)ScepAlloc(0, newFileSize*sizeof(TCHAR)); if (*newFileName ) { if ( pStart != oldFileName ) wcsncpy(*newFileName, oldFileName, (size_t)(pStart-oldFileName)); swprintf((PWSTR)(*newFileName+(pStart-oldFileName)), L"%s%s", szVar, pTemp+1); } else rc = ERROR_NOT_ENOUGH_MEMORY; } ScepFree(szVar); } else rc = ERROR_NOT_ENOUGH_MEMORY; } ScepFree(TmpBuf); } else rc = ERROR_NOT_ENOUGH_MEMORY; if ( NO_ERROR != rc || !bContinue ) { // // if errored, or do not continue // return(rc); } // // not found in process environment, // continue to search for DSDIT/DSLOG/SYSVOL in registry // if ( (gbDCQueried == TRUE && gbThisIsDC == TRUE) ) { // // search for DSDIT // rc = ScepExpandEnvironmentVariable(oldFileName, L"%DSDIT%", SCE_FLAG_DSDIT_DIR, newFileName); if ( rc != ERROR_FILE_NOT_FOUND ) { return rc; } // // search for DSLOG // rc = ScepExpandEnvironmentVariable(oldFileName, L"%DSLOG%", SCE_FLAG_DSLOG_DIR, newFileName); if ( rc != ERROR_FILE_NOT_FOUND ) { return rc; } // // search for SYSVOL // rc = ScepExpandEnvironmentVariable(oldFileName, L"%SYSVOL%", SCE_FLAG_SYSVOL_DIR, newFileName); if ( rc != ERROR_FILE_NOT_FOUND ) { return rc; } } } } // // Otherwise, just copy the old name to a new buffer and return ERROR_PATH_NOT_FOUND // *newFileName = (PWSTR)ScepAlloc(0, (wcslen(oldFileName)+1)*sizeof(TCHAR)); if (*newFileName != NULL) { wcscpy(*newFileName, _wcsupr(oldFileName) ); rc = ERROR_PATH_NOT_FOUND; } else rc = ERROR_NOT_ENOUGH_MEMORY; return(rc); } VOID ScepLogEventAndReport( IN HINSTANCE hInstance, IN LPTSTR LogFileName, IN DWORD LogLevel, IN DWORD dwEventID, IN UINT idMsg, IN DWORD rc, IN PWSTR pwszMsg ) ///////////////////////////////////////////////////////////////////////////////////////////////////// // Wrapper to log efficiently // ///////////////////////////////////////////////////////////////////////////////////////////////////// { if (SCEP_VALID_NAME(LogFileName)) { LogEventAndReport(hInstance, LogFileName, LogLevel, dwEventID, idMsg, rc, pwszMsg ); } } DWORD ScepCanonicalizeGroupName( IN PWSTR pwszGroupName, OUT PWSTR *ppwszCanonicalGroupName ) ////////////////////////////////////////////////////////////////////////////////// // memory allocated here should be freed outside // // if SID format, returns SID itself // // else if "BuiltinDomain\Administrator" convert to "Administrator" // // else if (it is DC) and "g" convert to "DomainName\g" // ////////////////////////////////////////////////////////////////////////////////// { DWORD rc = NO_ERROR; if (pwszGroupName == NULL || ppwszCanonicalGroupName == NULL) return ERROR_INVALID_PARAMETER; PWSTR pwszAfterSlash = NULL; if (pwszAfterSlash = wcsstr(pwszGroupName, L"\\")) ++ pwszAfterSlash; else pwszAfterSlash = pwszGroupName; if ( pwszGroupName[0] == L'*' ) { // // if sid, just copy as is // *ppwszCanonicalGroupName = (PWSTR)ScepAlloc(LMEM_ZEROINIT, (wcslen(pwszGroupName) + 1) * sizeof (WCHAR) ); if (*ppwszCanonicalGroupName == NULL) rc = ERROR_NOT_ENOUGH_MEMORY; else wcscpy(*ppwszCanonicalGroupName, pwszGroupName); } else if (ScepRsopLookupBuiltinNameTable(pwszAfterSlash)) { // // example - if "BuiltinDomainName\Administrator", we need "Administrator" // *ppwszCanonicalGroupName = (PWSTR)ScepAlloc(LMEM_ZEROINIT, (wcslen(pwszAfterSlash) + 1) * sizeof (WCHAR) ); if (*ppwszCanonicalGroupName == NULL) rc = ERROR_NOT_ENOUGH_MEMORY; else wcscpy(*ppwszCanonicalGroupName, pwszAfterSlash); } else if (gbDCQueried == TRUE && gbThisIsDC == TRUE) { // // example - if "g", we need "DomainName\g" // if (NULL == wcsstr(pwszGroupName, L"\\")){ // // if domain name is not available, we continue since callback will have the same problem, so OK // if (gpwszDCDomainName){ *ppwszCanonicalGroupName = (PWSTR)ScepAlloc(LMEM_ZEROINIT, (wcslen(gpwszDCDomainName) + wcslen(pwszGroupName) + 2) * sizeof (WCHAR) ); if (*ppwszCanonicalGroupName == NULL) rc = ERROR_NOT_ENOUGH_MEMORY; else { wcscpy(*ppwszCanonicalGroupName, gpwszDCDomainName); wcscat(*ppwszCanonicalGroupName, L"\\"); wcscat(*ppwszCanonicalGroupName, pwszGroupName); } } } else { // // already in "DomainName\g" format - simply copy // *ppwszCanonicalGroupName = (PWSTR)ScepAlloc(LMEM_ZEROINIT, (wcslen(pwszGroupName) + 1) * sizeof (WCHAR) ); if (*ppwszCanonicalGroupName == NULL) rc = ERROR_NOT_ENOUGH_MEMORY; else wcscpy(*ppwszCanonicalGroupName, pwszGroupName); } } else { // // simply copy - workstation or none of the above matched // *ppwszCanonicalGroupName = (PWSTR)ScepAlloc(LMEM_ZEROINIT, (wcslen(pwszGroupName) + 1) * sizeof (WCHAR) ); if (*ppwszCanonicalGroupName == NULL) rc = ERROR_NOT_ENOUGH_MEMORY; else wcscpy(*ppwszCanonicalGroupName, pwszGroupName); } return rc; } BOOL ScepRsopLookupBuiltinNameTable( IN PWSTR pwszGroupName ) ////////////////////////////////////////////////////////////////////////////////// // returns TRUE if group is found in builtin groups, else returns FALSE // ////////////////////////////////////////////////////////////////////////////////// { return ScepLookupWellKnownName( pwszGroupName, NULL, // no Lsa handle available, ScepLookupWellKnownName will open one NULL); // don't need the SID, just want to know if it's a known principal }