Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

3298 lines
124 KiB

  1. /*++
  2. Copyright (c) 2000 Microsoft Corporation
  3. Module Name:
  4. precedence.cpp
  5. Abstract:
  6. This file contains the main routine to calculate precedences.
  7. This is called during planning/diagnosis.
  8. Author:
  9. Vishnu Patankar (VishnuP) 7-April-2000
  10. Environment:
  11. User Mode - Win32
  12. Revision History:
  13. --*/
  14. ///////////////////////////////////////////////////////////////////////////////
  15. // //
  16. // Includes //
  17. // //
  18. ///////////////////////////////////////////////////////////////////////////////
  19. #include "precedence.h"
  20. #include "logger.h"
  21. #include "infp.h"
  22. #include "headers.h"
  23. #include "align.h"
  24. #include "..\sceutil.h"
  25. #include <io.h>
  26. #include "scerpc.h"
  27. extern BOOL gbAsyncWinlogonThread;
  28. extern HRESULT gHrSynchRsopStatus;
  29. extern HRESULT gHrAsynchRsopStatus;
  30. extern BOOL gbThisIsDC;
  31. extern BOOL gbDCQueried;
  32. extern PWSTR gpwszDCDomainName;
  33. extern HINSTANCE MyModuleHandle;
  34. WCHAR gpwszPlanOrDiagLogFile[MAX_PATH];
  35. ///////////////////////////////////////////////////////////////////////////////
  36. // //
  37. // Private defines //
  38. // //
  39. ///////////////////////////////////////////////////////////////////////////////
  40. #define SCEP_VALID_NAME(pName) (pName[0] == L'\0' ? NULL : pName)
  41. //
  42. // prime nos are good for hashing
  43. //
  44. #define PRIVILEGE_TABLE_SIZE 7
  45. #define GROUP_TABLE_SIZE 7
  46. #define REGISTRY_SECURITY_TABLE_SIZE 43
  47. #define FILE_SECURITY_TABLE_SIZE 43
  48. #define REGISTRY_VALUE_TABLE_SIZE 43
  49. #define SERVICES_TABLE_SIZE 5
  50. //
  51. // macro to gracefully handle errors
  52. //
  53. #define SCEP_RSOP_CONTINUE_OR_BREAK if (rc != NO_ERROR ) {\
  54. rcSave = rc;\
  55. if (rc == ERROR_NOT_ENOUGH_MEMORY)\
  56. break;\
  57. }
  58. //
  59. // macro to gracefully handle errors
  60. //
  61. #define SCEP_RSOP_CONTINUE_OR_GOTO if (rc != NO_ERROR ) {\
  62. rcSave = rc;\
  63. if (rc == ERROR_NOT_ENOUGH_MEMORY)\
  64. goto Done;\
  65. }
  66. const UINT NumSchemaClasses = sizeof ScepRsopSchemaClassNames/ sizeof(PWSTR);
  67. const UINT NumSettings = sizeof PrecedenceLookup/ sizeof(SCE_KEY_LOOKUP_PRECEDENCE);
  68. DWORD SceLogSettingsPrecedenceGPOs(
  69. IN IWbemServices *pWbemServices,
  70. IN BOOL bPlanningMode,
  71. IN PWSTR *ppwszLogFile
  72. )
  73. ///////////////////////////////////////////////////////////////////////////////
  74. // precedence algorithm ///
  75. // foreach GPO (parse all gpt*.* into SceProfileInfoBuffer) ///
  76. // foreach setting in a GPO (log the values and precedences if present)///
  77. ///////////////////////////////////////////////////////////////////////////////
  78. {
  79. PSCE_PROFILE_INFO pSceProfileInfoBuffer = NULL;
  80. PWSTR pwszGPOName = NULL;
  81. PWSTR pwszSOMID = NULL;
  82. DWORD rc = ERROR_SUCCESS;
  83. DWORD rcSave = ERROR_SUCCESS;
  84. BOOL bKerberosBlob = FALSE;
  85. TCHAR Windir[MAX_PATH], TemplatePath[MAX_PATH+50];
  86. SCEP_HASH_TABLE PrivilegeHashTable(PRIVILEGE_TABLE_SIZE);
  87. SCEP_HASH_TABLE GroupHashTable(GROUP_TABLE_SIZE);
  88. SCEP_HASH_TABLE RegistrySecurityHashTable(REGISTRY_SECURITY_TABLE_SIZE);
  89. SCEP_HASH_TABLE FileSecurityHashTable(FILE_SECURITY_TABLE_SIZE);
  90. SCEP_HASH_TABLE RegistryValueHashTable(REGISTRY_VALUE_TABLE_SIZE);
  91. SCEP_HASH_TABLE ServicesHashTable(SERVICES_TABLE_SIZE);
  92. //
  93. // get the path to the templates
  94. //
  95. GetSystemWindowsDirectory(Windir, MAX_PATH);
  96. Windir[MAX_PATH-1] = L'\0';
  97. if (bPlanningMode) {
  98. swprintf(TemplatePath,
  99. L"%s"PLANNING_GPT_DIR L"gpt*.*",
  100. Windir);
  101. } else {
  102. swprintf(TemplatePath,
  103. L"%s"DIAGNOSIS_GPT_DIR L"gpt*.*",
  104. Windir);
  105. }
  106. gpwszPlanOrDiagLogFile[MAX_PATH-1] = L'\0';
  107. //
  108. // old planning.log/diagnosis.log removed (*ppwszLogFile != NULL if verbose)
  109. //
  110. if (*ppwszLogFile) {
  111. if (bPlanningMode) {
  112. wcscpy(gpwszPlanOrDiagLogFile, *ppwszLogFile);
  113. } else {
  114. wcscpy(gpwszPlanOrDiagLogFile, Windir);
  115. wcscat(gpwszPlanOrDiagLogFile, DIAGNOSIS_LOG_FILE);
  116. }
  117. WCHAR szTmpName[MAX_PATH];
  118. wcscpy(szTmpName, gpwszPlanOrDiagLogFile);
  119. UINT Len = wcslen(szTmpName);
  120. szTmpName[Len-3] = L'o';
  121. szTmpName[Len-2] = L'l';
  122. szTmpName[Len-1] = L'd';
  123. CopyFile( gpwszPlanOrDiagLogFile, szTmpName, FALSE );
  124. DeleteFile(gpwszPlanOrDiagLogFile);
  125. } else {
  126. gpwszPlanOrDiagLogFile[0] = L'\0';
  127. }
  128. //
  129. // clear the database log - if something fails continue
  130. //
  131. for (UINT schemaClassNum = 0; schemaClassNum < NumSchemaClasses ; schemaClassNum++ ) {
  132. rc = ScepWbemErrorToDosError(DeleteInstances(
  133. ScepRsopSchemaClassNames[schemaClassNum],
  134. pWbemServices
  135. ));
  136. if (rc != NO_ERROR)
  137. rcSave = rc;
  138. }
  139. ScepLogEventAndReport(MyModuleHandle,
  140. gpwszPlanOrDiagLogFile,
  141. 0,
  142. 0,
  143. IDS_CLEAR_RSOP_DB,
  144. rcSave,
  145. NULL
  146. );
  147. //
  148. // need to process the files from gpt9999* -> gpt0000* (opposite of jetdb merge)
  149. // use LIFO linked stack of gpt* filenames
  150. //
  151. intptr_t hFile;
  152. struct _wfinddata_t FileInfo;
  153. HINF hInf;
  154. hFile = _wfindfirst(TemplatePath, &FileInfo);
  155. PSCE_NAME_STATUS_LIST pGptNameList = NULL;
  156. if ( hFile != -1 ) {
  157. do {
  158. if (ERROR_NOT_ENOUGH_MEMORY == (rc = ScepAddToNameStatusList(
  159. &pGptNameList,
  160. FileInfo.name,
  161. wcslen(FileInfo.name),
  162. 0))) {
  163. _findclose(hFile);
  164. if (pGptNameList)
  165. ScepFreeNameStatusList(pGptNameList);
  166. return ERROR_NOT_ENOUGH_MEMORY;
  167. }
  168. } while ( _wfindnext(hFile, &FileInfo) == 0 );
  169. _findclose(hFile);
  170. }
  171. //
  172. // first get all the GPOs, and some other info needed for logging
  173. // this is the outermost loop (per gpt*.* template)
  174. //
  175. PSCE_NAME_STATUS_LIST pCurrFileName = pGptNameList;
  176. while (pCurrFileName) {
  177. DWORD dwAuditLogRetentionPeriod[] = {SCE_NO_VALUE, SCE_NO_VALUE, SCE_NO_VALUE};
  178. DWORD dwLockoutBadCount = SCE_NO_VALUE;
  179. if (bPlanningMode) {
  180. swprintf(TemplatePath,
  181. L"%s"PLANNING_GPT_DIR L"%s",
  182. Windir, pCurrFileName->Name);
  183. } else {
  184. swprintf(TemplatePath,
  185. L"%s"DIAGNOSIS_GPT_DIR L"%s",
  186. Windir, pCurrFileName->Name);
  187. }
  188. //
  189. // open template file
  190. //
  191. rc = SceInfpOpenProfile(
  192. TemplatePath,
  193. &hInf
  194. );
  195. DWORD dSize = 0;
  196. INFCONTEXT InfLine;
  197. //
  198. // get GPO name - default to "NoName" if unable to get it
  199. //
  200. if (rc == ERROR_SUCCESS) {
  201. if ( SetupFindFirstLine(hInf,L"Version",L"DSPath",&InfLine) ) {
  202. if (SetupGetStringField(&InfLine,1,NULL,0,&dSize) && dSize > 0) {
  203. pwszGPOName = (PWSTR)ScepAlloc( 0, (dSize+1)*sizeof(WCHAR));
  204. if (!pwszGPOName) {
  205. rc = SCESTATUS_NOT_ENOUGH_RESOURCE;
  206. SceInfpCloseProfile(hInf);
  207. goto NextGPO;
  208. }
  209. pwszGPOName[dSize] = L'\0';
  210. SetupGetStringField(&InfLine,1,pwszGPOName,dSize, NULL);
  211. }
  212. else
  213. rc = GetLastError();
  214. }
  215. else
  216. rc = GetLastError();
  217. if (rc != ERROR_SUCCESS) {
  218. //
  219. // log this error and continue this GPO by initializing pwszGPOName to "NoGPOName"
  220. //
  221. if (pwszGPOName)
  222. ScepFree(pwszGPOName);
  223. rcSave = rc;
  224. pwszGPOName = (PWSTR)ScepAlloc( 0, (9+1)*sizeof(WCHAR));
  225. if (!pwszGPOName) {
  226. rc = SCESTATUS_NOT_ENOUGH_RESOURCE;
  227. rcSave = rc;
  228. SceInfpCloseProfile(hInf);
  229. goto NextGPO;
  230. }
  231. wcscpy(pwszGPOName, L"NoGPOName");
  232. ScepLogEventAndReport(MyModuleHandle,
  233. gpwszPlanOrDiagLogFile,
  234. 0,
  235. 0,
  236. IDS_ERROR_OPEN_CACHED_GPO,
  237. rc,
  238. TemplatePath
  239. );
  240. }
  241. } else {
  242. rcSave = rc;
  243. ScepLogEventAndReport(MyModuleHandle,
  244. gpwszPlanOrDiagLogFile,
  245. 0,
  246. 0,
  247. IDS_ERROR_OPEN_CACHED_GPO,
  248. rc,
  249. TemplatePath
  250. );
  251. //
  252. // will continue with next GPO
  253. //
  254. goto NextGPO;
  255. }
  256. //
  257. // get SOMID - default to "NoSOMID" if unable to get it
  258. //
  259. if ( SetupFindFirstLine(hInf,L"Version",L"SOMID",&InfLine) ) {
  260. if (SetupGetStringField(&InfLine,1,NULL,0,&dSize) && dSize > 0) {
  261. pwszSOMID = (PWSTR)ScepAlloc( 0, (dSize+1)*sizeof(WCHAR));
  262. pwszSOMID[dSize] = L'\0';
  263. SetupGetStringField(&InfLine,1,pwszSOMID,dSize, NULL);
  264. } else
  265. rc = GetLastError();
  266. } else
  267. rc = GetLastError();
  268. if (rc != ERROR_SUCCESS) {
  269. //
  270. // log this error and continue this GPO by initializing pwszGPOName to "NoGPOName"
  271. //
  272. if (pwszSOMID)
  273. ScepFree(pwszSOMID);
  274. rcSave = rc;
  275. pwszSOMID = (PWSTR)ScepAlloc( 0, (7 + 1)*sizeof(WCHAR));
  276. if (!pwszSOMID) {
  277. rc = SCESTATUS_NOT_ENOUGH_RESOURCE;
  278. rcSave = rc;
  279. SceInfpCloseProfile(hInf);
  280. goto NextGPO;
  281. }
  282. wcscpy(pwszSOMID, L"NoSOMID");
  283. ScepLogEventAndReport(MyModuleHandle,
  284. gpwszPlanOrDiagLogFile,
  285. 0,
  286. 0,
  287. IDS_ERROR_OPEN_CACHED_GPO,
  288. rc,
  289. TemplatePath
  290. );
  291. }
  292. rc = SceInfpGetSecurityProfileInfo(
  293. hInf,
  294. AREA_ALL,
  295. &pSceProfileInfoBuffer,
  296. NULL
  297. );
  298. if (rc != ERROR_SUCCESS) {
  299. rcSave = rc;
  300. SceInfpCloseProfile(hInf);
  301. ScepLogEventAndReport(MyModuleHandle,
  302. gpwszPlanOrDiagLogFile,
  303. 0,
  304. 0,
  305. IDS_ERROR_OPEN_CACHED_GPO,
  306. rc,
  307. TemplatePath
  308. );
  309. //
  310. // will continue with next GPO
  311. //
  312. goto NextGPO;
  313. }
  314. SceInfpCloseProfile(hInf);
  315. ScepLogEventAndReport(MyModuleHandle,
  316. gpwszPlanOrDiagLogFile,
  317. 0,
  318. 0,
  319. IDS_INFO_RSOP_LOG,
  320. rc,
  321. pwszGPOName
  322. );
  323. //
  324. // now the info buffer is successfully populated - need to
  325. // iterate over all settings for this GPO
  326. //
  327. //
  328. // to efficiently access fields(settings) in the info buffer, we use a lookup table of
  329. // precomputed offsets
  330. //
  331. //
  332. // a matrix holds precedence info for fields whose locations are well known in memory
  333. // and hash-tables hold precedence info for fields whose locations are dynamic
  334. //
  335. //
  336. // try except around each log attempt - intention is to continue with next setting if
  337. // logging for current setting fails
  338. // guarded code does not explicitly throw any exceptions - error codes are set instead
  339. // so, if we get an exception it is thrown by the system in which case we ignore and continue
  340. //
  341. //
  342. // this is the second loop (setting per gpt*.* template)
  343. //
  344. bKerberosBlob = FALSE;
  345. for (UINT settingNo = 0; settingNo < NumSettings; settingNo++) {
  346. CHAR settingType = PrecedenceLookup[settingNo].KeyLookup.BufferType;
  347. PWSTR pSettingName = PrecedenceLookup[settingNo].KeyLookup.KeyString;
  348. UINT settingOffset = PrecedenceLookup[settingNo].KeyLookup.Offset;
  349. DWORD *pSettingPrecedence = &PrecedenceLookup[settingNo].Precedence;
  350. BOOL bLogErrorOutsideSwitch = TRUE;
  351. //
  352. // depending on the schema class being processed, we instantiate logger objects
  353. //
  354. switch (settingType) {
  355. case RSOP_SecuritySettingNumeric:
  356. try {
  357. {
  358. RSOP_SecuritySettingNumericLogger Log(pWbemServices, pwszGPOName, pwszSOMID);
  359. //
  360. // special case kerberos since it is dynamically allocated
  361. //
  362. if (_wcsicmp(pSettingName, L"pKerberosInfo") == 0)
  363. bKerberosBlob = TRUE;
  364. if (bKerberosBlob == FALSE &&
  365. (bPlanningMode ||
  366. !(gbDCQueried == TRUE && gbThisIsDC == TRUE) ||
  367. ((gbDCQueried == TRUE && gbThisIsDC == TRUE) && wcsstr(pCurrFileName->Name, L".dom")))) {
  368. DWORD dwValue = SCEP_TYPECAST(DWORD, pSceProfileInfoBuffer, settingOffset);
  369. if (dwValue != SCE_NO_VALUE) {
  370. //
  371. // LockoutBadCount controls two other lockout settings - so remember
  372. //
  373. if (_wcsicmp(pSettingName, L"LockoutBadCount") == 0)
  374. dwLockoutBadCount = dwValue;
  375. //
  376. // skip if dwLockoutBadCount == 0
  377. //
  378. if (_wcsicmp(pSettingName, L"ResetLockoutCount") == 0 &&
  379. (dwLockoutBadCount == 0 || dwLockoutBadCount == SCE_NO_VALUE))
  380. continue;
  381. if (_wcsicmp(pSettingName, L"LockoutDuration") == 0 &&
  382. (dwLockoutBadCount == 0 || dwLockoutBadCount == SCE_NO_VALUE))
  383. continue;
  384. rc = ScepWbemErrorToDosError(Log.Log(
  385. pSettingName,
  386. dwValue,
  387. ++(*pSettingPrecedence)
  388. ));
  389. if (rc == NO_ERROR)
  390. ScepLogEventAndReport(MyModuleHandle,
  391. gpwszPlanOrDiagLogFile,
  392. 0,
  393. 0,
  394. IDS_INFO_RSOP_LOG,
  395. rc,
  396. pSettingName
  397. );
  398. if (rc != NO_ERROR)
  399. break;
  400. }
  401. } else if (bKerberosBlob == TRUE &&
  402. (bPlanningMode ||
  403. ((gbDCQueried == TRUE && gbThisIsDC == TRUE) && wcsstr(pCurrFileName->Name, L".dom")))) {
  404. //
  405. // kerberos only if DC from *.dom. If planning mode don't care type of m/c
  406. //
  407. PSCE_KERBEROS_TICKET_INFO pKerberosInfo =
  408. SCEP_TYPECAST(PSCE_KERBEROS_TICKET_INFO, pSceProfileInfoBuffer, settingOffset);
  409. bLogErrorOutsideSwitch = FALSE;
  410. if (pKerberosInfo) {
  411. //
  412. // kerberos numeric
  413. //
  414. for (UINT NumericSubSetting = 1; NumericSubSetting < NUM_KERBEROS_SUB_SETTINGS; NumericSubSetting++ ) {
  415. pSettingName = PrecedenceLookup[settingNo + NumericSubSetting].KeyLookup.KeyString;
  416. settingOffset = PrecedenceLookup[settingNo + NumericSubSetting].KeyLookup.Offset;
  417. pSettingPrecedence = &PrecedenceLookup[settingNo + NumericSubSetting].Precedence;
  418. DWORD dwValue = SCEP_TYPECAST(DWORD, pKerberosInfo, settingOffset);
  419. if (dwValue != SCE_NO_VALUE) {
  420. rc = ScepWbemErrorToDosError(Log.Log(
  421. pSettingName,
  422. dwValue,
  423. ++(*pSettingPrecedence)
  424. ));
  425. ScepLogEventAndReport(MyModuleHandle,
  426. gpwszPlanOrDiagLogFile,
  427. 0,
  428. 0,
  429. IDS_INFO_RSOP_LOG,
  430. rc,
  431. pSettingName
  432. );
  433. SCEP_RSOP_CONTINUE_OR_BREAK
  434. }
  435. }
  436. //
  437. //kerberos boolean (moved here to incompatible case: statement - to avoid a goto)
  438. //
  439. pSettingName = PrecedenceLookup[settingNo + NUM_KERBEROS_SUB_SETTINGS].KeyLookup.KeyString;
  440. settingOffset = PrecedenceLookup[settingNo + NUM_KERBEROS_SUB_SETTINGS].KeyLookup.Offset;
  441. pSettingPrecedence = &PrecedenceLookup[settingNo + NUM_KERBEROS_SUB_SETTINGS].Precedence;
  442. DWORD dwValue = SCEP_TYPECAST(DWORD, pKerberosInfo, settingOffset);
  443. RSOP_SecuritySettingBooleanLogger Log(pWbemServices, pwszGPOName, pwszSOMID);
  444. if (rc != ERROR_NOT_ENOUGH_MEMORY &&
  445. dwValue != SCE_NO_VALUE) {
  446. rc = ScepWbemErrorToDosError(Log.Log(
  447. pSettingName,
  448. dwValue,
  449. ++(*pSettingPrecedence)
  450. ));
  451. ScepLogEventAndReport(MyModuleHandle,
  452. gpwszPlanOrDiagLogFile,
  453. 0,
  454. 0,
  455. IDS_INFO_RSOP_LOG,
  456. rc,
  457. pSettingName
  458. );
  459. if (rc != NO_ERROR ) {
  460. rcSave = rc;
  461. }
  462. }
  463. }
  464. }
  465. //
  466. // just processed NUM_KERBEROS_SUB_SETTINGS
  467. //
  468. if (bKerberosBlob)
  469. settingNo += NUM_KERBEROS_SUB_SETTINGS;
  470. }
  471. } catch (...) {
  472. //
  473. // system error continue with next setting
  474. //
  475. rc = EVENT_E_INTERNALEXCEPTION;
  476. bLogErrorOutsideSwitch = TRUE;
  477. }
  478. break;
  479. case RSOP_SecuritySettingBoolean:
  480. try {
  481. {
  482. RSOP_SecuritySettingBooleanLogger Log(pWbemServices, pwszGPOName, pwszSOMID);
  483. DWORD dwValue = SCEP_TYPECAST(DWORD, pSceProfileInfoBuffer, settingOffset);
  484. if (dwValue != SCE_NO_VALUE) {
  485. rc = ScepWbemErrorToDosError(Log.Log(
  486. pSettingName,
  487. dwValue,
  488. ++(*pSettingPrecedence)
  489. ));
  490. if (rc == NO_ERROR)
  491. ScepLogEventAndReport(MyModuleHandle,
  492. gpwszPlanOrDiagLogFile,
  493. 0,
  494. 0,
  495. IDS_INFO_RSOP_LOG,
  496. rc,
  497. pSettingName
  498. );
  499. if (rc != NO_ERROR)
  500. break;
  501. }
  502. }
  503. } catch (...) {
  504. //
  505. // system error continue with next setting
  506. //
  507. rc = EVENT_E_INTERNALEXCEPTION;
  508. }
  509. break;
  510. case RSOP_SecuritySettingString:
  511. try {
  512. {
  513. RSOP_SecuritySettingStringLogger Log(pWbemServices, pwszGPOName, pwszSOMID);
  514. PWSTR pszValue = SCEP_TYPECAST(PWSTR, pSceProfileInfoBuffer, settingOffset);
  515. if (pszValue != NULL) {
  516. rc = ScepWbemErrorToDosError(Log.Log(
  517. pSettingName,
  518. pszValue,
  519. ++(*pSettingPrecedence)
  520. ));
  521. if (rc == NO_ERROR)
  522. ScepLogEventAndReport(MyModuleHandle,
  523. gpwszPlanOrDiagLogFile,
  524. 0,
  525. 0,
  526. IDS_INFO_RSOP_LOG,
  527. rc,
  528. pSettingName
  529. );
  530. if (rc != NO_ERROR)
  531. break;
  532. }
  533. }
  534. } catch (...) {
  535. // system error continue with next setting
  536. rc = EVENT_E_INTERNALEXCEPTION;
  537. }
  538. break;
  539. case RSOP_AuditPolicy:
  540. {
  541. RSOP_AuditPolicyLogger Log(pWbemServices, pwszGPOName, pwszSOMID);
  542. DWORD dwValue = SCEP_TYPECAST(DWORD, pSceProfileInfoBuffer, settingOffset);
  543. if (dwValue != SCE_NO_VALUE) {
  544. rc = ScepWbemErrorToDosError(Log.Log(
  545. pSettingName,
  546. dwValue,
  547. ++(*pSettingPrecedence)
  548. ));
  549. if (rc == NO_ERROR)
  550. ScepLogEventAndReport(MyModuleHandle,
  551. gpwszPlanOrDiagLogFile,
  552. 0,
  553. 0,
  554. IDS_INFO_RSOP_LOG,
  555. rc,
  556. pSettingName
  557. );
  558. if (rc != NO_ERROR)
  559. break;
  560. }
  561. }
  562. break;
  563. case RSOP_SecurityEventLogSettingNumeric:
  564. try {
  565. {
  566. RSOP_SecurityEventLogSettingNumericLogger Log(pWbemServices, pwszGPOName, pwszSOMID);
  567. bLogErrorOutsideSwitch = FALSE;
  568. for (UINT LogType = 0; LogType < NUM_EVENTLOG_TYPES ; LogType ++) {
  569. settingOffset = PrecedenceLookup[settingNo + LogType].KeyLookup.Offset;
  570. pSettingPrecedence = &PrecedenceLookup[settingNo + LogType].Precedence;
  571. DWORD dwValue = SCEP_TYPECAST(DWORD, pSceProfileInfoBuffer, settingOffset);
  572. //
  573. // calculate dwValue depdending on dwAuditLogRetentionPeriod[]
  574. //
  575. if (_wcsicmp(pSettingName, L"RetentionDays") == 0) {
  576. switch (dwAuditLogRetentionPeriod[LogType]) {
  577. case 2: // manually
  578. dwValue = MAXULONG;
  579. break;
  580. case 1: // number of days * seconds/day
  581. //if (dwValue != SCE_NO_VALUE)
  582. //dwValue = dwValue * 24 * 3600;
  583. //leave it in days
  584. break;
  585. case 0: // as needed
  586. dwValue = 0;
  587. break;
  588. // default should not happen
  589. default:
  590. dwValue = SCE_NO_VALUE;
  591. }
  592. }
  593. if (dwValue != SCE_NO_VALUE) {
  594. WCHAR pwszLogType[10];
  595. _itow((int)LogType, pwszLogType, 10);
  596. //
  597. // AuditLogRetentionPeriod controls RetentionDays - so remember
  598. // also it is never logged since it is an artifact of the template spec
  599. //
  600. if (_wcsicmp(pSettingName, L"AuditLogRetentionPeriod") == 0) {
  601. dwAuditLogRetentionPeriod[LogType] = dwValue;
  602. ScepLogEventAndReport(MyModuleHandle,
  603. gpwszPlanOrDiagLogFile,
  604. 0,
  605. 0,
  606. IDS_INFO_RSOP_LOG,
  607. LogType,
  608. pSettingName
  609. );
  610. continue;
  611. }
  612. rc = ScepWbemErrorToDosError(Log.Log(
  613. pSettingName,
  614. pwszLogType,
  615. dwValue,
  616. ++(*pSettingPrecedence)
  617. ));
  618. ScepLogEventAndReport(MyModuleHandle,
  619. gpwszPlanOrDiagLogFile,
  620. 0,
  621. 0,
  622. IDS_INFO_RSOP_LOG,
  623. LogType,
  624. pSettingName
  625. );
  626. SCEP_RSOP_CONTINUE_OR_BREAK
  627. }
  628. }
  629. //
  630. // just processed NUM_EVENTLOG_TYPES - system, application, security, for this setting
  631. //
  632. settingNo += NUM_EVENTLOG_TYPES - 1;
  633. }
  634. } catch (...) {
  635. //
  636. // system error continue with next setting
  637. //
  638. rc = EVENT_E_INTERNALEXCEPTION;
  639. bLogErrorOutsideSwitch = TRUE;
  640. }
  641. break;
  642. case RSOP_SecurityEventLogSettingBoolean:
  643. try {
  644. {
  645. RSOP_SecurityEventLogSettingBooleanLogger Log(pWbemServices, pwszGPOName, pwszSOMID);
  646. bLogErrorOutsideSwitch = FALSE;
  647. for (UINT LogType = 0; LogType < NUM_EVENTLOG_TYPES ; LogType ++) {
  648. settingOffset = PrecedenceLookup[settingNo + LogType].KeyLookup.Offset;
  649. pSettingPrecedence = &PrecedenceLookup[settingNo + LogType].Precedence;
  650. DWORD dwValue = SCEP_TYPECAST(DWORD, pSceProfileInfoBuffer, settingOffset);
  651. if (dwValue != SCE_NO_VALUE) {
  652. WCHAR pwszLogType[10];
  653. _itow((int)LogType, pwszLogType, 10);
  654. rc = ScepWbemErrorToDosError(Log.Log(
  655. pSettingName,
  656. pwszLogType,
  657. dwValue,
  658. ++(*pSettingPrecedence)
  659. ));
  660. ScepLogEventAndReport(MyModuleHandle,
  661. gpwszPlanOrDiagLogFile,
  662. 0,
  663. 0,
  664. IDS_INFO_RSOP_LOG,
  665. rc,
  666. pSettingName
  667. );
  668. SCEP_RSOP_CONTINUE_OR_BREAK
  669. }
  670. }
  671. //
  672. // processed NUM_EVENTLOG_TYPES - system, application, security, for this setting
  673. //
  674. settingNo += NUM_EVENTLOG_TYPES - 1;
  675. }
  676. } catch (...) {
  677. //
  678. // system error continue with next setting
  679. //
  680. rc = EVENT_E_INTERNALEXCEPTION;
  681. bLogErrorOutsideSwitch = TRUE;
  682. }
  683. break;
  684. case RSOP_RegistryValue:
  685. try {
  686. {
  687. RSOP_RegistryValueLogger Log(pWbemServices, pwszGPOName, pwszSOMID);
  688. DWORD dwRegCount = SCEP_TYPECAST(DWORD, pSceProfileInfoBuffer, settingOffset);
  689. PSCE_REGISTRY_VALUE_INFO aRegValues = NULL;
  690. //
  691. // 64-bit alignment fix (alternatively, have an entry for aRegValues in the offset table)
  692. //
  693. #ifdef _WIN64
  694. // CHAR *pAlign;
  695. aRegValues = pSceProfileInfoBuffer->aRegValues;
  696. // pAlign = (CHAR *)pSceProfileInfoBuffer + settingOffset + sizeof(DWORD);
  697. // aRegValues = (PSCE_REGISTRY_VALUE_INFO)ROUND_UP_POINTER(pAlign,ALIGN_LPVOID);
  698. #else
  699. aRegValues =
  700. SCEP_TYPECAST(PSCE_REGISTRY_VALUE_INFO, pSceProfileInfoBuffer, settingOffset + sizeof(DWORD));
  701. #endif
  702. bLogErrorOutsideSwitch = FALSE;
  703. if ( aRegValues == NULL )
  704. continue;
  705. for (UINT regNo = 0; regNo < dwRegCount; regNo++ ) {
  706. if ((aRegValues)[regNo].FullValueName) {
  707. pSettingPrecedence = NULL;
  708. if (NO_ERROR != (rc = RegistryValueHashTable.LookupAdd(
  709. (aRegValues)[regNo].FullValueName,
  710. &pSettingPrecedence))) {
  711. rcSave = rc;
  712. ScepLogEventAndReport(MyModuleHandle,
  713. gpwszPlanOrDiagLogFile,
  714. 0,
  715. 0,
  716. IDS_ERROR_RSOP_LOG,
  717. rc,
  718. (aRegValues)[regNo].FullValueName
  719. );
  720. //
  721. // if hash table fails for any reason, cannot
  722. // trust it for processing of other elements
  723. //
  724. break;
  725. }
  726. rc = ScepWbemErrorToDosError(Log.Log(
  727. (aRegValues)[regNo].FullValueName,
  728. (aRegValues)[regNo].ValueType,
  729. (aRegValues)[regNo].Value,
  730. ++(*pSettingPrecedence)
  731. ));
  732. ScepLogEventAndReport(MyModuleHandle,
  733. gpwszPlanOrDiagLogFile,
  734. 0,
  735. 0,
  736. IDS_INFO_RSOP_LOG,
  737. rc,
  738. (aRegValues)[regNo].FullValueName
  739. );
  740. SCEP_RSOP_CONTINUE_OR_BREAK
  741. }
  742. }
  743. }
  744. } catch (...) {
  745. //
  746. // system error continue with next setting
  747. //
  748. rc = EVENT_E_INTERNALEXCEPTION;
  749. bLogErrorOutsideSwitch = TRUE;
  750. }
  751. break;
  752. case RSOP_UserPrivilegeRight:
  753. try {
  754. {
  755. RSOP_UserPrivilegeRightLogger Log(pWbemServices, pwszGPOName, pwszSOMID);
  756. PSCE_PRIVILEGE_ASSIGNMENT pInfPrivilegeAssignedTo =
  757. SCEP_TYPECAST(PSCE_PRIVILEGE_ASSIGNMENT, pSceProfileInfoBuffer, settingOffset);
  758. bLogErrorOutsideSwitch = FALSE;
  759. while (pInfPrivilegeAssignedTo) {
  760. if (pInfPrivilegeAssignedTo->Name) {
  761. pSettingPrecedence = NULL;
  762. if (NO_ERROR != (rc = PrivilegeHashTable.LookupAdd(
  763. pInfPrivilegeAssignedTo->Name,
  764. &pSettingPrecedence))) {
  765. rcSave = rc;
  766. ScepLogEventAndReport(MyModuleHandle,
  767. gpwszPlanOrDiagLogFile,
  768. 0,
  769. 0,
  770. IDS_ERROR_RSOP_LOG,
  771. rc,
  772. pInfPrivilegeAssignedTo->Name
  773. );
  774. //
  775. // if hash table fails for any reason, cannot
  776. // trust it for processing of other elements
  777. //
  778. break;
  779. }
  780. rc = ScepWbemErrorToDosError(Log.Log(
  781. pInfPrivilegeAssignedTo->Name,
  782. pInfPrivilegeAssignedTo->AssignedTo,
  783. ++(*pSettingPrecedence)
  784. ));
  785. ScepLogEventAndReport(MyModuleHandle,
  786. gpwszPlanOrDiagLogFile,
  787. 0,
  788. 0,
  789. IDS_INFO_RSOP_LOG,
  790. rc,
  791. pInfPrivilegeAssignedTo->Name
  792. );
  793. SCEP_RSOP_CONTINUE_OR_BREAK
  794. }
  795. pInfPrivilegeAssignedTo = pInfPrivilegeAssignedTo->Next;
  796. }
  797. }
  798. } catch (...) {
  799. //
  800. // system error continue with next setting
  801. //
  802. rc = EVENT_E_INTERNALEXCEPTION;
  803. bLogErrorOutsideSwitch = TRUE;
  804. }
  805. break;
  806. case RSOP_RestrictedGroup:
  807. try {
  808. {
  809. RSOP_RestrictedGroupLogger Log(pWbemServices, pwszGPOName, pwszSOMID);
  810. PSCE_GROUP_MEMBERSHIP pGroupMembership =
  811. SCEP_TYPECAST(PSCE_GROUP_MEMBERSHIP, pSceProfileInfoBuffer, settingOffset);
  812. bLogErrorOutsideSwitch = FALSE;
  813. PWSTR pCanonicalGroupName = NULL;
  814. while (pGroupMembership) {
  815. if (pGroupMembership->GroupName) {
  816. rc = ScepCanonicalizeGroupName(pGroupMembership->GroupName,
  817. &pCanonicalGroupName
  818. );
  819. SCEP_RSOP_CONTINUE_OR_BREAK
  820. pSettingPrecedence = NULL;
  821. if (NO_ERROR != (rc = GroupHashTable.LookupAdd(
  822. pCanonicalGroupName,
  823. &pSettingPrecedence))) {
  824. rcSave = rc;
  825. ScepLogEventAndReport(MyModuleHandle,
  826. gpwszPlanOrDiagLogFile,
  827. 0,
  828. 0,
  829. IDS_ERROR_RSOP_LOG,
  830. rc,
  831. pCanonicalGroupName
  832. );
  833. //
  834. // if hash table fails for any reason, cannot
  835. // trust it for processing of other elements
  836. //
  837. if (pCanonicalGroupName)
  838. ScepFree(pCanonicalGroupName);
  839. pCanonicalGroupName = NULL;
  840. break;
  841. }
  842. rc = ScepWbemErrorToDosError(Log.Log(
  843. pCanonicalGroupName,
  844. pGroupMembership->pMembers,
  845. ++(*pSettingPrecedence)
  846. ));
  847. ScepLogEventAndReport(MyModuleHandle,
  848. gpwszPlanOrDiagLogFile,
  849. 0,
  850. 0,
  851. IDS_INFO_RSOP_LOG,
  852. rc,
  853. pCanonicalGroupName
  854. );
  855. if (pCanonicalGroupName)
  856. ScepFree(pCanonicalGroupName);
  857. pCanonicalGroupName = NULL;
  858. SCEP_RSOP_CONTINUE_OR_BREAK
  859. }
  860. pGroupMembership = pGroupMembership->Next;
  861. }
  862. }
  863. } catch (...) {
  864. //
  865. // system error continue with next setting
  866. //
  867. rc = EVENT_E_INTERNALEXCEPTION;
  868. bLogErrorOutsideSwitch = TRUE;
  869. }
  870. break;
  871. case RSOP_SystemService:
  872. try {
  873. {
  874. RSOP_SystemServiceLogger Log(pWbemServices, pwszGPOName, pwszSOMID);
  875. PSCE_SERVICES pServices =
  876. SCEP_TYPECAST(PSCE_SERVICES, pSceProfileInfoBuffer, settingOffset);
  877. bLogErrorOutsideSwitch = FALSE;
  878. while (pServices) {
  879. if (pServices->ServiceName) {
  880. pSettingPrecedence = NULL;
  881. if (NO_ERROR != (rc = ServicesHashTable.LookupAdd(
  882. pServices->ServiceName,
  883. &pSettingPrecedence))) {
  884. rcSave = rc;
  885. ScepLogEventAndReport(MyModuleHandle,
  886. gpwszPlanOrDiagLogFile,
  887. 0,
  888. 0,
  889. IDS_ERROR_RSOP_LOG,
  890. rc,
  891. pServices->ServiceName
  892. );
  893. //
  894. // if hash table fails for any reason, cannot
  895. // trust it for processing of other elements
  896. //
  897. break;
  898. }
  899. rc = ScepWbemErrorToDosError(Log.Log(
  900. pServices->ServiceName,
  901. pServices->Startup,
  902. pServices->General.pSecurityDescriptor,
  903. pServices->SeInfo,
  904. ++(*pSettingPrecedence)
  905. ));
  906. ScepLogEventAndReport(MyModuleHandle,
  907. gpwszPlanOrDiagLogFile,
  908. 0,
  909. 0,
  910. IDS_INFO_RSOP_LOG,
  911. rc,
  912. pServices->ServiceName
  913. );
  914. SCEP_RSOP_CONTINUE_OR_BREAK
  915. }
  916. pServices = pServices->Next;
  917. }
  918. }
  919. } catch (...) {
  920. //
  921. // system error continue with next setting
  922. //
  923. rc = EVENT_E_INTERNALEXCEPTION;
  924. bLogErrorOutsideSwitch = TRUE;
  925. }
  926. break;
  927. case RSOP_File:
  928. try {
  929. {
  930. RSOP_FileLogger Log(pWbemServices, pwszGPOName, pwszSOMID);
  931. SCE_OBJECTS pObjects =
  932. SCEP_TYPECAST(SCE_OBJECTS, pSceProfileInfoBuffer, settingOffset);
  933. BOOL bPathIsTranslated = FALSE;
  934. bLogErrorOutsideSwitch = FALSE;
  935. if (pObjects.pAllNodes) {
  936. PSCE_OBJECT_SECURITY *pObjectArray = pObjects.pAllNodes->pObjectArray;
  937. for (DWORD rCount = 0; rCount < pObjects.pAllNodes->Count; rCount++) {
  938. if (pObjectArray[rCount] && pObjectArray[rCount]->Name) {
  939. pSettingPrecedence = NULL;
  940. //
  941. // if diagnosis mode, translate env-vars and store
  942. //
  943. bPathIsTranslated = FALSE;
  944. PWSTR pwszTranslatedPath = NULL;
  945. if (!bPlanningMode && (wcschr(pObjectArray[rCount]->Name, L'%') != NULL )) {
  946. bPathIsTranslated = TRUE;
  947. rc = ScepClientTranslateFileDirName( pObjectArray[rCount]->Name, &pwszTranslatedPath);
  948. if ( rc == ERROR_PATH_NOT_FOUND )
  949. rc = SCESTATUS_INVALID_DATA;
  950. else if ( rc != NO_ERROR )
  951. rc = ScepDosErrorToSceStatus(rc);
  952. SCEP_RSOP_CONTINUE_OR_BREAK
  953. } else {
  954. pwszTranslatedPath = pObjectArray[rCount]->Name;
  955. }
  956. if (NO_ERROR != (rc = FileSecurityHashTable.LookupAdd(
  957. pwszTranslatedPath,
  958. &pSettingPrecedence))) {
  959. rcSave = rc;
  960. ScepLogEventAndReport(MyModuleHandle,
  961. gpwszPlanOrDiagLogFile,
  962. 0,
  963. 0,
  964. IDS_ERROR_RSOP_LOG,
  965. rc,
  966. pwszTranslatedPath
  967. );
  968. //
  969. // if hash table fails for any reason, cannot
  970. // trust it for processing of other elements
  971. //
  972. if (bPathIsTranslated && pwszTranslatedPath)
  973. LocalFree(pwszTranslatedPath);
  974. break;
  975. }
  976. rc = ScepWbemErrorToDosError(Log.Log(
  977. pwszTranslatedPath,
  978. (bPathIsTranslated ? pObjectArray[rCount]->Name : NULL),
  979. pObjectArray[rCount]->Status,
  980. pObjectArray[rCount]->pSecurityDescriptor,
  981. pObjectArray[rCount]->SeInfo,
  982. ++(*pSettingPrecedence)
  983. ));
  984. ScepLogEventAndReport(MyModuleHandle,
  985. gpwszPlanOrDiagLogFile,
  986. 0,
  987. 0,
  988. IDS_INFO_RSOP_LOG,
  989. rc,
  990. pwszTranslatedPath
  991. );
  992. if (bPathIsTranslated && pwszTranslatedPath)
  993. LocalFree(pwszTranslatedPath);
  994. SCEP_RSOP_CONTINUE_OR_BREAK
  995. }
  996. }
  997. }
  998. }
  999. } catch (...) {
  1000. //
  1001. // system error continue with next setting
  1002. //
  1003. rc = EVENT_E_INTERNALEXCEPTION;
  1004. bLogErrorOutsideSwitch = TRUE;
  1005. }
  1006. break;
  1007. case RSOP_RegistryKey:
  1008. try {
  1009. {
  1010. RSOP_RegistryKeyLogger Log(pWbemServices, pwszGPOName, pwszSOMID);
  1011. SCE_OBJECTS pObjects =
  1012. SCEP_TYPECAST(SCE_OBJECTS, pSceProfileInfoBuffer, settingOffset);
  1013. bLogErrorOutsideSwitch = FALSE;
  1014. if (pObjects.pAllNodes) {
  1015. PSCE_OBJECT_SECURITY *pObjectArray = pObjects.pAllNodes->pObjectArray;
  1016. for (DWORD rCount = 0; rCount < pObjects.pAllNodes->Count; rCount++) {
  1017. if (pObjectArray[rCount] && pObjectArray[rCount]->Name) {
  1018. pSettingPrecedence = NULL;
  1019. if (NO_ERROR != (rc = RegistrySecurityHashTable.LookupAdd(
  1020. pObjectArray[rCount]->Name,
  1021. &pSettingPrecedence))) {
  1022. rcSave = rc;
  1023. ScepLogEventAndReport(MyModuleHandle,
  1024. gpwszPlanOrDiagLogFile,
  1025. 0,
  1026. 0,
  1027. IDS_ERROR_RSOP_LOG,
  1028. rc,
  1029. pObjectArray[rCount]->Name
  1030. );
  1031. //
  1032. // if hash table fails for any reason, cannot
  1033. // trust it for processing of other elements
  1034. //
  1035. break;
  1036. }
  1037. rc = ScepWbemErrorToDosError(Log.Log(
  1038. pObjectArray[rCount]->Name,
  1039. pObjectArray[rCount]->Status,
  1040. pObjectArray[rCount]->pSecurityDescriptor,
  1041. pObjectArray[rCount]->SeInfo,
  1042. ++(*pSettingPrecedence)
  1043. ));
  1044. ScepLogEventAndReport(MyModuleHandle,
  1045. gpwszPlanOrDiagLogFile,
  1046. 0,
  1047. 0,
  1048. IDS_INFO_RSOP_LOG,
  1049. rc,
  1050. pObjectArray[rCount]->Name
  1051. );
  1052. SCEP_RSOP_CONTINUE_OR_BREAK
  1053. }
  1054. }
  1055. }
  1056. }
  1057. } catch (...) {
  1058. //
  1059. // system error continue with next setting
  1060. //
  1061. rc = EVENT_E_INTERNALEXCEPTION;
  1062. bLogErrorOutsideSwitch = TRUE;
  1063. }
  1064. break;
  1065. default:
  1066. //
  1067. // should not happen
  1068. //
  1069. rc = ERROR_INVALID_PARAMETER;
  1070. }
  1071. if (bLogErrorOutsideSwitch && rc != NO_ERROR ) {
  1072. //
  1073. // log error and continue
  1074. //
  1075. rcSave = rc;
  1076. ScepLogEventAndReport(MyModuleHandle,
  1077. gpwszPlanOrDiagLogFile,
  1078. 0,
  1079. 0,
  1080. IDS_ERROR_RSOP_LOG,
  1081. rc,
  1082. pSettingName
  1083. );
  1084. }
  1085. bLogErrorOutsideSwitch = TRUE;
  1086. //
  1087. // this is the only case in which we quit logging completely
  1088. //
  1089. if (rc == ERROR_NOT_ENOUGH_MEMORY)
  1090. break;
  1091. }
  1092. NextGPO:
  1093. if (pSceProfileInfoBuffer)
  1094. SceFreeProfileMemory(pSceProfileInfoBuffer);
  1095. pSceProfileInfoBuffer = NULL;
  1096. if (pwszGPOName)
  1097. ScepFree(pwszGPOName);
  1098. pwszGPOName = NULL;
  1099. if (pwszSOMID)
  1100. ScepFree(pwszSOMID);
  1101. pwszSOMID = NULL;
  1102. if (rc == ERROR_NOT_ENOUGH_MEMORY)
  1103. break;
  1104. // this is the only case in which we quit logging completely
  1105. pCurrFileName = pCurrFileName->Next;
  1106. }
  1107. if (pGptNameList)
  1108. ScepFreeNameStatusList(pGptNameList);
  1109. //
  1110. // only log the final status to both event log and logfile
  1111. // (all other statuses are logged to logfile only)
  1112. //
  1113. if (rcSave == ERROR_SUCCESS)
  1114. ScepLogEventAndReport(MyModuleHandle,
  1115. gpwszPlanOrDiagLogFile,
  1116. 0,
  1117. 0,
  1118. IDS_SUCCESS_RSOP_LOG,
  1119. rcSave,
  1120. L""
  1121. );
  1122. else
  1123. ScepLogEventAndReport(MyModuleHandle,
  1124. gpwszPlanOrDiagLogFile,
  1125. 0,
  1126. 0,
  1127. IDS_ERROR_RSOP_LOG,
  1128. rcSave,
  1129. L""
  1130. );
  1131. return rcSave;
  1132. }
  1133. SCEPR_STATUS
  1134. SceClientCallbackRsopLog(
  1135. IN AREAPR cbArea,
  1136. IN DWORD ncbErrorStatus,
  1137. IN wchar_t *pSettingInfo OPTIONAL,
  1138. IN DWORD dwPrivLow OPTIONAL,
  1139. IN DWORD dwPrivHigh OPTIONAL
  1140. )
  1141. /////////////////////////////////////////////////////////////////////////////////////////////////////
  1142. // This function is called by the server via RPC when settings defined in the jet //
  1143. // db are applied (along with a status of application, and optional detailed information) //
  1144. // //
  1145. // The areas were decided based on the granularity of configuration in scesrv. cbArea can have //
  1146. // more than one area encoded in it, again due to the resolution granularity of error in scesrv. //
  1147. // Hence this is a massive "if" routine //
  1148. // //
  1149. // configuration from jet db corresponds to precedence = "1" simulated configuration in the //
  1150. // rsop database which was logged by the client. For each area, we try to log the status of //
  1151. // configuration by querying the database for these precedence = "1" settings and updating the //
  1152. // status fields per such instance found. We should find all called back settings in WMI db except //
  1153. // for local-policy //
  1154. // //
  1155. // if any error, update golbal Synch/Asynch statuses with the accumulated status //
  1156. /////////////////////////////////////////////////////////////////////////////////////////////////////
  1157. {
  1158. DWORD rc = ERROR_SUCCESS;
  1159. DWORD rcSave = ERROR_SUCCESS;
  1160. //
  1161. // instantiate a logger that logs status from callback (has overloaded log methods)
  1162. //
  1163. try {
  1164. SCEP_DIAGNOSIS_LOGGER Log(tg_pWbemServices, NULL, NULL);
  1165. //
  1166. // password policy
  1167. //
  1168. if (cbArea & SCE_RSOP_PASSWORD_INFO) {
  1169. try {
  1170. rc = ScepWbemErrorToDosError(Log.Log(L"RSOP_SecuritySettingNumeric",
  1171. L"KeyName",
  1172. L"MinimumPasswordAge",
  1173. ncbErrorStatus,
  1174. FALSE
  1175. ));
  1176. ScepLogEventAndReport(MyModuleHandle,
  1177. gpwszPlanOrDiagLogFile,
  1178. 0,
  1179. 0,
  1180. IDS_ERROR_RSOP_DIAG_LOG,
  1181. rc,
  1182. L"MinimumPasswordAge"
  1183. );
  1184. SCEP_RSOP_CONTINUE_OR_GOTO
  1185. rc = ScepWbemErrorToDosError(Log.Log(L"RSOP_SecuritySettingNumeric",
  1186. L"KeyName",
  1187. L"MaximumPasswordAge",
  1188. ncbErrorStatus,
  1189. FALSE
  1190. ));
  1191. ScepLogEventAndReport(MyModuleHandle,
  1192. gpwszPlanOrDiagLogFile,
  1193. 0,
  1194. 0,
  1195. IDS_ERROR_RSOP_DIAG_LOG,
  1196. rc,
  1197. L"MaximumPasswordAge"
  1198. );
  1199. SCEP_RSOP_CONTINUE_OR_GOTO
  1200. rc = ScepWbemErrorToDosError(Log.Log(L"RSOP_SecuritySettingNumeric",
  1201. L"KeyName",
  1202. L"MinimumPasswordLength",
  1203. ncbErrorStatus,
  1204. FALSE
  1205. ));
  1206. ScepLogEventAndReport(MyModuleHandle,
  1207. gpwszPlanOrDiagLogFile,
  1208. 0,
  1209. 0,
  1210. IDS_ERROR_RSOP_DIAG_LOG,
  1211. rc,
  1212. L"MinimumPasswordLength"
  1213. );
  1214. SCEP_RSOP_CONTINUE_OR_GOTO
  1215. rc = ScepWbemErrorToDosError(Log.Log(L"RSOP_SecuritySettingNumeric",
  1216. L"KeyName",
  1217. L"PasswordHistorySize",
  1218. ncbErrorStatus,
  1219. FALSE
  1220. ));
  1221. ScepLogEventAndReport(MyModuleHandle,
  1222. gpwszPlanOrDiagLogFile,
  1223. 0,
  1224. 0,
  1225. IDS_ERROR_RSOP_DIAG_LOG,
  1226. rc,
  1227. L"PasswordHistorySize"
  1228. );
  1229. SCEP_RSOP_CONTINUE_OR_GOTO
  1230. rc = ScepWbemErrorToDosError(Log.Log(L"RSOP_SecuritySettingBoolean",
  1231. L"KeyName",
  1232. L"ClearTextPassword",
  1233. ncbErrorStatus,
  1234. FALSE
  1235. ));
  1236. ScepLogEventAndReport(MyModuleHandle,
  1237. gpwszPlanOrDiagLogFile,
  1238. 0,
  1239. 0,
  1240. IDS_ERROR_RSOP_DIAG_LOG,
  1241. rc,
  1242. L"ClearTextPassword"
  1243. );
  1244. SCEP_RSOP_CONTINUE_OR_GOTO
  1245. rc = ScepWbemErrorToDosError(Log.Log(L"RSOP_SecuritySettingBoolean",
  1246. L"KeyName",
  1247. L"PasswordComplexity",
  1248. ncbErrorStatus,
  1249. FALSE
  1250. ));
  1251. ScepLogEventAndReport(MyModuleHandle,
  1252. gpwszPlanOrDiagLogFile,
  1253. 0,
  1254. 0,
  1255. IDS_ERROR_RSOP_DIAG_LOG,
  1256. rc,
  1257. L"PasswordComplexity"
  1258. );
  1259. SCEP_RSOP_CONTINUE_OR_GOTO
  1260. rc = ScepWbemErrorToDosError(Log.Log(L"RSOP_SecuritySettingBoolean",
  1261. L"KeyName",
  1262. L"RequireLogonToChangePassword",
  1263. ncbErrorStatus,
  1264. FALSE
  1265. ));
  1266. ScepLogEventAndReport(MyModuleHandle,
  1267. gpwszPlanOrDiagLogFile,
  1268. 0,
  1269. 0,
  1270. IDS_ERROR_RSOP_DIAG_LOG,
  1271. rc,
  1272. L"RequireLogonToChangePassword"
  1273. );
  1274. SCEP_RSOP_CONTINUE_OR_GOTO
  1275. } catch (...) {
  1276. //
  1277. // system error continue with next setting
  1278. //
  1279. rcSave = EVENT_E_INTERNALEXCEPTION;
  1280. }
  1281. }
  1282. //
  1283. // account lockout policy
  1284. //
  1285. if (cbArea & SCE_RSOP_LOCKOUT_INFO) {
  1286. try {
  1287. rc = ScepWbemErrorToDosError(Log.Log(L"RSOP_SecuritySettingNumeric",
  1288. L"KeyName",
  1289. L"LockoutBadCount",
  1290. ncbErrorStatus,
  1291. FALSE
  1292. ));
  1293. ScepLogEventAndReport(MyModuleHandle,
  1294. gpwszPlanOrDiagLogFile,
  1295. 0,
  1296. 0,
  1297. IDS_ERROR_RSOP_DIAG_LOG,
  1298. rc,
  1299. L"LockoutBadCount"
  1300. );
  1301. SCEP_RSOP_CONTINUE_OR_GOTO
  1302. rc = ScepWbemErrorToDosError(Log.Log(L"RSOP_SecuritySettingNumeric",
  1303. L"KeyName",
  1304. L"ResetLockoutCount",
  1305. ncbErrorStatus,
  1306. FALSE
  1307. ));
  1308. ScepLogEventAndReport(MyModuleHandle,
  1309. gpwszPlanOrDiagLogFile,
  1310. 0,
  1311. 0,
  1312. IDS_ERROR_RSOP_DIAG_LOG,
  1313. rc,
  1314. L"ResetLockoutCount"
  1315. );
  1316. SCEP_RSOP_CONTINUE_OR_GOTO
  1317. rc = ScepWbemErrorToDosError(Log.Log(L"RSOP_SecuritySettingNumeric",
  1318. L"KeyName",
  1319. L"LockoutDuration",
  1320. ncbErrorStatus,
  1321. FALSE
  1322. ));
  1323. ScepLogEventAndReport(MyModuleHandle,
  1324. gpwszPlanOrDiagLogFile,
  1325. 0,
  1326. 0,
  1327. IDS_ERROR_RSOP_DIAG_LOG,
  1328. rc,
  1329. L"LockoutDuration"
  1330. );
  1331. SCEP_RSOP_CONTINUE_OR_GOTO
  1332. } catch (...) {
  1333. //
  1334. // system error continue with next setting
  1335. //
  1336. rcSave = EVENT_E_INTERNALEXCEPTION;
  1337. }
  1338. }
  1339. //
  1340. // forcelogoff setting
  1341. //
  1342. if (cbArea & SCE_RSOP_LOGOFF_INFO) {
  1343. try {
  1344. rc = ScepWbemErrorToDosError(Log.Log(L"RSOP_SecuritySettingBoolean",
  1345. L"KeyName",
  1346. L"ForceLogoffWhenHourExpire",
  1347. ncbErrorStatus,
  1348. FALSE
  1349. ));
  1350. ScepLogEventAndReport(MyModuleHandle,
  1351. gpwszPlanOrDiagLogFile,
  1352. 0,
  1353. 0,
  1354. IDS_ERROR_RSOP_DIAG_LOG,
  1355. rc,
  1356. L"ForceLogoffWhenHourExpire"
  1357. );
  1358. SCEP_RSOP_CONTINUE_OR_GOTO
  1359. } catch (...) {
  1360. //
  1361. // system error continue with next setting
  1362. //
  1363. rcSave = EVENT_E_INTERNALEXCEPTION;
  1364. }
  1365. }
  1366. //
  1367. // LSA policy setting
  1368. //
  1369. if (cbArea & SCE_RSOP_LSA_POLICY_INFO) {
  1370. try {
  1371. rc = ScepWbemErrorToDosError(Log.Log(L"RSOP_SecuritySettingBoolean",
  1372. L"KeyName",
  1373. L"LSAAnonymousNameLookup",
  1374. ncbErrorStatus,
  1375. FALSE
  1376. ));
  1377. ScepLogEventAndReport(MyModuleHandle,
  1378. gpwszPlanOrDiagLogFile,
  1379. 0,
  1380. 0,
  1381. IDS_ERROR_RSOP_DIAG_LOG,
  1382. rc,
  1383. L"LSAAnonymousNameLookup"
  1384. );
  1385. SCEP_RSOP_CONTINUE_OR_GOTO
  1386. } catch (...) {
  1387. //
  1388. // system error continue with next setting
  1389. //
  1390. rcSave = EVENT_E_INTERNALEXCEPTION;
  1391. }
  1392. }
  1393. //
  1394. // disable admin account
  1395. //
  1396. if (cbArea & SCE_RSOP_DISABLE_ADMIN_INFO) {
  1397. try {
  1398. rc = ScepWbemErrorToDosError(Log.Log(L"RSOP_SecuritySettingBoolean",
  1399. L"KeyName",
  1400. L"EnableAdminAccount",
  1401. ncbErrorStatus,
  1402. FALSE
  1403. ));
  1404. ScepLogEventAndReport(MyModuleHandle,
  1405. gpwszPlanOrDiagLogFile,
  1406. 0,
  1407. 0,
  1408. IDS_ERROR_RSOP_DIAG_LOG,
  1409. rc,
  1410. L"EnableAdminAccount"
  1411. );
  1412. SCEP_RSOP_CONTINUE_OR_GOTO
  1413. } catch (...) {
  1414. //
  1415. // system error continue with next setting
  1416. //
  1417. rcSave = EVENT_E_INTERNALEXCEPTION;
  1418. }
  1419. }
  1420. //
  1421. // disable guest account
  1422. //
  1423. if (cbArea & SCE_RSOP_DISABLE_GUEST_INFO) {
  1424. try {
  1425. rc = ScepWbemErrorToDosError(Log.Log(L"RSOP_SecuritySettingBoolean",
  1426. L"KeyName",
  1427. L"EnableGuestAccount",
  1428. ncbErrorStatus,
  1429. FALSE
  1430. ));
  1431. ScepLogEventAndReport(MyModuleHandle,
  1432. gpwszPlanOrDiagLogFile,
  1433. 0,
  1434. 0,
  1435. IDS_ERROR_RSOP_DIAG_LOG,
  1436. rc,
  1437. L"EnableGuestAccount"
  1438. );
  1439. SCEP_RSOP_CONTINUE_OR_GOTO
  1440. } catch (...) {
  1441. //
  1442. // system error continue with next setting
  1443. //
  1444. rcSave = EVENT_E_INTERNALEXCEPTION;
  1445. }
  1446. }
  1447. //
  1448. // administratorname setting
  1449. //
  1450. if (cbArea & SCE_RSOP_ADMIN_INFO) {
  1451. try {
  1452. rc = ScepWbemErrorToDosError(Log.Log(L"RSOP_SecuritySettingString",
  1453. L"KeyName",
  1454. L"NewAdministratorName",
  1455. ncbErrorStatus,
  1456. FALSE
  1457. ));
  1458. ScepLogEventAndReport(MyModuleHandle,
  1459. gpwszPlanOrDiagLogFile,
  1460. 0,
  1461. 0,
  1462. IDS_ERROR_RSOP_DIAG_LOG,
  1463. rc,
  1464. L"NewAdministratorName"
  1465. );
  1466. SCEP_RSOP_CONTINUE_OR_GOTO
  1467. } catch (...) {
  1468. //
  1469. // system error continue with next setting
  1470. //
  1471. rcSave = EVENT_E_INTERNALEXCEPTION;
  1472. }
  1473. }
  1474. //
  1475. // guestname setting
  1476. //
  1477. if (cbArea & SCE_RSOP_GUEST_INFO) {
  1478. try {
  1479. rc = ScepWbemErrorToDosError(Log.Log(L"RSOP_SecuritySettingString",
  1480. L"KeyName",
  1481. L"NewGuestName",
  1482. ncbErrorStatus,
  1483. FALSE
  1484. ));
  1485. ScepLogEventAndReport(MyModuleHandle,
  1486. gpwszPlanOrDiagLogFile,
  1487. 0,
  1488. 0,
  1489. IDS_ERROR_RSOP_DIAG_LOG,
  1490. rc,
  1491. L"NewGuestName"
  1492. );
  1493. SCEP_RSOP_CONTINUE_OR_GOTO
  1494. } catch (...) {
  1495. //
  1496. // system error continue with next setting
  1497. //
  1498. rcSave = EVENT_E_INTERNALEXCEPTION;
  1499. }
  1500. }
  1501. //
  1502. // user groups settings
  1503. //
  1504. if (cbArea & SCE_RSOP_GROUP_INFO) {
  1505. try {
  1506. PWSTR pCanonicalGroupName = NULL;
  1507. PWSTR pwszCanonicalDoubleSlashName = NULL;
  1508. rc = ScepCanonicalizeGroupName(pSettingInfo,
  1509. &pCanonicalGroupName
  1510. );
  1511. SCEP_RSOP_CONTINUE_OR_GOTO
  1512. rc = ScepConvertSingleSlashToDoubleSlashPath(
  1513. pCanonicalGroupName,
  1514. &pwszCanonicalDoubleSlashName
  1515. );
  1516. if (rc == ERROR_NOT_ENOUGH_MEMORY && pCanonicalGroupName) {
  1517. ScepFree(pCanonicalGroupName);
  1518. pCanonicalGroupName = NULL;
  1519. }
  1520. SCEP_RSOP_CONTINUE_OR_GOTO
  1521. rc = ScepWbemErrorToDosError(Log.Log(L"RSOP_RestrictedGroup",
  1522. L"GroupName",
  1523. pwszCanonicalDoubleSlashName,
  1524. ncbErrorStatus,
  1525. FALSE
  1526. ));
  1527. ScepLogEventAndReport(MyModuleHandle,
  1528. gpwszPlanOrDiagLogFile,
  1529. 0,
  1530. 0,
  1531. IDS_ERROR_RSOP_DIAG_LOG,
  1532. rc,
  1533. pCanonicalGroupName
  1534. );
  1535. if (pCanonicalGroupName)
  1536. ScepFree(pCanonicalGroupName);
  1537. if (pwszCanonicalDoubleSlashName)
  1538. LocalFree(pwszCanonicalDoubleSlashName);
  1539. SCEP_RSOP_CONTINUE_OR_GOTO
  1540. } catch (...) {
  1541. //
  1542. // system error continue with next setting
  1543. //
  1544. rcSave = EVENT_E_INTERNALEXCEPTION;
  1545. }
  1546. }
  1547. //
  1548. // user privileges settings
  1549. //
  1550. if (cbArea & SCE_RSOP_PRIVILEGE_INFO) {
  1551. try {
  1552. //
  1553. // loop through all privileges to see which are set for this account and log status
  1554. // only if existing status is already != some error
  1555. //
  1556. for ( UINT i=0; i<cPrivCnt; i++) {
  1557. if ( i < 32 ) {
  1558. if (dwPrivLow & (1 << i )) {
  1559. rc = ScepWbemErrorToDosError(Log.Log(L"RSOP_UserPrivilegeRight",
  1560. L"UserRight",
  1561. SCE_Privileges[i].Name,
  1562. ncbErrorStatus,
  1563. TRUE));
  1564. ScepLogEventAndReport(MyModuleHandle,
  1565. gpwszPlanOrDiagLogFile,
  1566. 0,
  1567. 0,
  1568. IDS_ERROR_RSOP_DIAG_LOG,
  1569. rc,
  1570. SCE_Privileges[i].Name
  1571. );
  1572. SCEP_RSOP_CONTINUE_OR_GOTO
  1573. }
  1574. } else {
  1575. if (dwPrivHigh & (1 << (i-32 ))) {
  1576. rc = ScepWbemErrorToDosError(Log.Log(L"RSOP_UserPrivilegeRight",
  1577. L"UserRight",
  1578. SCE_Privileges[i].Name,
  1579. ncbErrorStatus,
  1580. TRUE));
  1581. ScepLogEventAndReport(MyModuleHandle,
  1582. gpwszPlanOrDiagLogFile,
  1583. 0,
  1584. 0,
  1585. IDS_ERROR_RSOP_DIAG_LOG,
  1586. rc,
  1587. SCE_Privileges[i].Name
  1588. );
  1589. SCEP_RSOP_CONTINUE_OR_GOTO
  1590. }
  1591. }
  1592. }
  1593. } catch (...) {
  1594. //
  1595. // system error continue with next setting
  1596. //
  1597. rcSave = EVENT_E_INTERNALEXCEPTION;
  1598. }
  1599. }
  1600. //
  1601. // file security settings
  1602. //
  1603. if (cbArea & SCE_RSOP_FILE_SECURITY_INFO) {
  1604. PWSTR pwszDoubleSlashPath = NULL;
  1605. try {
  1606. rc = ScepConvertSingleSlashToDoubleSlashPath(
  1607. pSettingInfo,
  1608. &pwszDoubleSlashPath
  1609. );
  1610. SCEP_RSOP_CONTINUE_OR_GOTO
  1611. //
  1612. // the file itself
  1613. //
  1614. if (!(cbArea & SCE_RSOP_FILE_SECURITY_INFO_CHILD)) {
  1615. rc = ScepWbemErrorToDosError(Log.Log(L"RSOP_File",
  1616. L"Path",
  1617. pwszDoubleSlashPath,
  1618. ncbErrorStatus,
  1619. FALSE
  1620. ));
  1621. ScepLogEventAndReport(MyModuleHandle,
  1622. gpwszPlanOrDiagLogFile,
  1623. 0,
  1624. 0,
  1625. IDS_ERROR_RSOP_DIAG_LOG,
  1626. rc,
  1627. pSettingInfo
  1628. );
  1629. } else {
  1630. //
  1631. // the file was error free, but some child failed
  1632. //
  1633. rc = ScepWbemErrorToDosError(Log.LogChild(L"RSOP_File",
  1634. L"Path",
  1635. pwszDoubleSlashPath,
  1636. ncbErrorStatus,
  1637. 4
  1638. ));
  1639. ScepLogEventAndReport(MyModuleHandle,
  1640. gpwszPlanOrDiagLogFile,
  1641. 0,
  1642. 0,
  1643. IDS_ERROR_RSOP_DIAG_LOG,
  1644. rc,
  1645. pSettingInfo
  1646. );
  1647. }
  1648. if (pwszDoubleSlashPath)
  1649. LocalFree(pwszDoubleSlashPath);
  1650. pwszDoubleSlashPath = NULL;
  1651. SCEP_RSOP_CONTINUE_OR_GOTO
  1652. } catch (...) {
  1653. if (pwszDoubleSlashPath)
  1654. LocalFree(pwszDoubleSlashPath);
  1655. //
  1656. // system error continue with next setting
  1657. //
  1658. rcSave = EVENT_E_INTERNALEXCEPTION;
  1659. }
  1660. }
  1661. //
  1662. // registry security settings
  1663. //
  1664. if (cbArea & SCE_RSOP_REGISTRY_SECURITY_INFO) {
  1665. PWSTR pwszDoubleSlashPath = NULL;
  1666. try {
  1667. rc = ScepConvertSingleSlashToDoubleSlashPath(
  1668. pSettingInfo,
  1669. &pwszDoubleSlashPath
  1670. );
  1671. SCEP_RSOP_CONTINUE_OR_GOTO
  1672. //
  1673. // the registry key itself
  1674. //
  1675. if (!(cbArea & SCE_RSOP_REGISTRY_SECURITY_INFO_CHILD)) {
  1676. #ifdef _WIN64
  1677. rc = ScepWbemErrorToDosError(Log.LogRegistryKey(L"RSOP_RegistryKey",
  1678. L"Path",
  1679. pwszDoubleSlashPath,
  1680. ncbErrorStatus,
  1681. FALSE
  1682. ));
  1683. ScepLogEventAndReport(MyModuleHandle,
  1684. gpwszPlanOrDiagLogFile,
  1685. 0,
  1686. 0,
  1687. IDS_ERROR_RSOP_DIAG_LOG64_32KEY,
  1688. rc,
  1689. pSettingInfo
  1690. );
  1691. #else
  1692. rc = ScepWbemErrorToDosError(Log.Log(L"RSOP_RegistryKey",
  1693. L"Path",
  1694. pwszDoubleSlashPath,
  1695. ncbErrorStatus,
  1696. FALSE
  1697. ));
  1698. ScepLogEventAndReport(MyModuleHandle,
  1699. gpwszPlanOrDiagLogFile,
  1700. 0,
  1701. 0,
  1702. IDS_ERROR_RSOP_DIAG_LOG,
  1703. rc,
  1704. pSettingInfo
  1705. );
  1706. #endif
  1707. } else {
  1708. //
  1709. // the registry-key was error free, but some child failed
  1710. //
  1711. #ifdef _WIN64
  1712. rc = ScepWbemErrorToDosError(Log.LogRegistryKey(L"RSOP_RegistryKey",
  1713. L"Path",
  1714. pwszDoubleSlashPath,
  1715. ncbErrorStatus,
  1716. TRUE
  1717. ));
  1718. ScepLogEventAndReport(MyModuleHandle,
  1719. gpwszPlanOrDiagLogFile,
  1720. 0,
  1721. 0,
  1722. IDS_ERROR_RSOP_DIAG_LOG64_32KEY,
  1723. rc,
  1724. pSettingInfo
  1725. );
  1726. #else
  1727. rc = ScepWbemErrorToDosError(Log.LogChild(L"RSOP_RegistryKey",
  1728. L"Path",
  1729. pwszDoubleSlashPath,
  1730. ncbErrorStatus,
  1731. 4
  1732. ));
  1733. ScepLogEventAndReport(MyModuleHandle,
  1734. gpwszPlanOrDiagLogFile,
  1735. 0,
  1736. 0,
  1737. IDS_ERROR_RSOP_DIAG_LOG,
  1738. rc,
  1739. pSettingInfo
  1740. );
  1741. #endif
  1742. }
  1743. if (pwszDoubleSlashPath)
  1744. LocalFree(pwszDoubleSlashPath);
  1745. pwszDoubleSlashPath = NULL;
  1746. SCEP_RSOP_CONTINUE_OR_GOTO
  1747. } catch (...) {
  1748. if (pwszDoubleSlashPath)
  1749. LocalFree(pwszDoubleSlashPath);
  1750. //
  1751. // system error continue with next setting
  1752. //
  1753. rcSave = EVENT_E_INTERNALEXCEPTION;
  1754. }
  1755. }
  1756. //
  1757. // auditlogmaxsize settings
  1758. //
  1759. if (cbArea & SCE_RSOP_AUDIT_LOG_MAXSIZE_INFO) {
  1760. try {
  1761. rc = ScepWbemErrorToDosError(Log.Log(L"RSOP_SecurityEventLogSettingNumeric",
  1762. L"KeyName",
  1763. L"MaximumLogSize",
  1764. L"Type",
  1765. pSettingInfo,
  1766. ncbErrorStatus
  1767. ));
  1768. ScepLogEventAndReport(MyModuleHandle,
  1769. gpwszPlanOrDiagLogFile,
  1770. 0,
  1771. 0,
  1772. IDS_ERROR_RSOP_DIAG_LOG,
  1773. rc,
  1774. L"MaximumLogSize"
  1775. );
  1776. SCEP_RSOP_CONTINUE_OR_GOTO
  1777. } catch (...) {
  1778. //
  1779. // system error continue with next setting
  1780. //
  1781. rcSave = EVENT_E_INTERNALEXCEPTION;
  1782. }
  1783. }
  1784. //
  1785. // auditlogretention settings
  1786. //
  1787. if (cbArea & SCE_RSOP_AUDIT_LOG_RETENTION_INFO) {
  1788. try {
  1789. rc = ScepWbemErrorToDosError(Log.Log(L"RSOP_SecurityEventLogSettingNumeric",
  1790. L"KeyName",
  1791. L"RetentionDays",
  1792. L"Type",
  1793. pSettingInfo,
  1794. ncbErrorStatus
  1795. ));
  1796. ScepLogEventAndReport(MyModuleHandle,
  1797. gpwszPlanOrDiagLogFile,
  1798. 0,
  1799. 0,
  1800. IDS_ERROR_RSOP_DIAG_LOG,
  1801. rc,
  1802. L"RetentionDays"
  1803. );
  1804. SCEP_RSOP_CONTINUE_OR_GOTO
  1805. } catch (...) {
  1806. //
  1807. // system error continue with next setting
  1808. //
  1809. rcSave = EVENT_E_INTERNALEXCEPTION;
  1810. }
  1811. }
  1812. //
  1813. // auditlogguest settings
  1814. //
  1815. if (cbArea & SCE_RSOP_AUDIT_LOG_GUEST_INFO) {
  1816. try {
  1817. rc = ScepWbemErrorToDosError(Log.Log(L"RSOP_SecurityEventLogSettingBolean",
  1818. L"KeyName",
  1819. L"RestrictGuestAccess",
  1820. L"Type",
  1821. pSettingInfo,
  1822. ncbErrorStatus
  1823. ));
  1824. ScepLogEventAndReport(MyModuleHandle,
  1825. gpwszPlanOrDiagLogFile,
  1826. 0,
  1827. 0,
  1828. IDS_ERROR_RSOP_DIAG_LOG,
  1829. rc,
  1830. L"RestrictGuestAccess"
  1831. );
  1832. SCEP_RSOP_CONTINUE_OR_GOTO
  1833. } catch (...) {
  1834. //
  1835. // system error continue with next setting
  1836. //
  1837. rcSave = EVENT_E_INTERNALEXCEPTION;
  1838. }
  1839. }
  1840. //
  1841. // auditevent settings
  1842. //
  1843. if (cbArea & SCE_RSOP_AUDIT_EVENT_INFO) {
  1844. try {
  1845. rc = ScepWbemErrorToDosError(Log.Log(L"RSOP_AuditPolicy",
  1846. L"Category",
  1847. L"AuditSystemEvents",
  1848. ncbErrorStatus,
  1849. FALSE
  1850. ));
  1851. ScepLogEventAndReport(MyModuleHandle,
  1852. gpwszPlanOrDiagLogFile,
  1853. 0,
  1854. 0,
  1855. IDS_ERROR_RSOP_DIAG_LOG,
  1856. rc,
  1857. L"AuditSystemEvents"
  1858. );
  1859. SCEP_RSOP_CONTINUE_OR_GOTO
  1860. rc = ScepWbemErrorToDosError(Log.Log(L"RSOP_AuditPolicy",
  1861. L"Category",
  1862. L"AuditLogonEvents",
  1863. ncbErrorStatus,
  1864. FALSE
  1865. ));
  1866. ScepLogEventAndReport(MyModuleHandle,
  1867. gpwszPlanOrDiagLogFile,
  1868. 0,
  1869. 0,
  1870. IDS_ERROR_RSOP_DIAG_LOG,
  1871. rc,
  1872. L"AuditLogonEvents"
  1873. );
  1874. SCEP_RSOP_CONTINUE_OR_GOTO
  1875. rc = ScepWbemErrorToDosError(Log.Log(L"RSOP_AuditPolicy",
  1876. L"Category",
  1877. L"AuditObjectAccess",
  1878. ncbErrorStatus,
  1879. FALSE
  1880. ));
  1881. ScepLogEventAndReport(MyModuleHandle,
  1882. gpwszPlanOrDiagLogFile,
  1883. 0,
  1884. 0,
  1885. IDS_ERROR_RSOP_DIAG_LOG,
  1886. rc,
  1887. L"AuditObjectAccess"
  1888. );
  1889. SCEP_RSOP_CONTINUE_OR_GOTO
  1890. rc = ScepWbemErrorToDosError(Log.Log(L"RSOP_AuditPolicy",
  1891. L"Category",
  1892. L"AuditPrivilegeUse",
  1893. ncbErrorStatus,
  1894. FALSE
  1895. ));
  1896. ScepLogEventAndReport(MyModuleHandle,
  1897. gpwszPlanOrDiagLogFile,
  1898. 0,
  1899. 0,
  1900. IDS_ERROR_RSOP_DIAG_LOG,
  1901. rc,
  1902. L"AuditPrivilegeUse"
  1903. );
  1904. SCEP_RSOP_CONTINUE_OR_GOTO
  1905. rc = ScepWbemErrorToDosError(Log.Log(L"RSOP_AuditPolicy",
  1906. L"Category",
  1907. L"AuditPolicyChange",
  1908. ncbErrorStatus,
  1909. FALSE
  1910. ));
  1911. ScepLogEventAndReport(MyModuleHandle,
  1912. gpwszPlanOrDiagLogFile,
  1913. 0,
  1914. 0,
  1915. IDS_ERROR_RSOP_DIAG_LOG,
  1916. rc,
  1917. L"AuditPolicyChange"
  1918. );
  1919. SCEP_RSOP_CONTINUE_OR_GOTO
  1920. rc = ScepWbemErrorToDosError(Log.Log(L"RSOP_AuditPolicy",
  1921. L"Category",
  1922. L"AuditAccountManage",
  1923. ncbErrorStatus,
  1924. FALSE
  1925. ));
  1926. ScepLogEventAndReport(MyModuleHandle,
  1927. gpwszPlanOrDiagLogFile,
  1928. 0,
  1929. 0,
  1930. IDS_ERROR_RSOP_DIAG_LOG,
  1931. rc,
  1932. L"AuditAccountManage"
  1933. );
  1934. SCEP_RSOP_CONTINUE_OR_GOTO
  1935. rc = ScepWbemErrorToDosError(Log.Log(L"RSOP_AuditPolicy",
  1936. L"Category",
  1937. L"AuditProcessTracking",
  1938. ncbErrorStatus,
  1939. FALSE
  1940. ));
  1941. ScepLogEventAndReport(MyModuleHandle,
  1942. gpwszPlanOrDiagLogFile,
  1943. 0,
  1944. 0,
  1945. IDS_ERROR_RSOP_DIAG_LOG,
  1946. rc,
  1947. L"AuditProcessTracking"
  1948. );
  1949. SCEP_RSOP_CONTINUE_OR_GOTO
  1950. rc = ScepWbemErrorToDosError(Log.Log(L"RSOP_AuditPolicy",
  1951. L"Category",
  1952. L"AuditDSAccess",
  1953. ncbErrorStatus,
  1954. FALSE
  1955. ));
  1956. ScepLogEventAndReport(MyModuleHandle,
  1957. gpwszPlanOrDiagLogFile,
  1958. 0,
  1959. 0,
  1960. IDS_ERROR_RSOP_DIAG_LOG,
  1961. rc,
  1962. L"AuditDSAccess"
  1963. );
  1964. SCEP_RSOP_CONTINUE_OR_GOTO
  1965. rc = ScepWbemErrorToDosError(Log.Log(L"RSOP_AuditPolicy",
  1966. L"Category",
  1967. L"AuditAccountLogon",
  1968. ncbErrorStatus,
  1969. FALSE
  1970. ));
  1971. ScepLogEventAndReport(MyModuleHandle,
  1972. gpwszPlanOrDiagLogFile,
  1973. 0,
  1974. 0,
  1975. IDS_ERROR_RSOP_DIAG_LOG,
  1976. rc,
  1977. L"AuditAccountLogon"
  1978. );
  1979. SCEP_RSOP_CONTINUE_OR_GOTO
  1980. } catch (...) {
  1981. //
  1982. // system error continue with next setting
  1983. //
  1984. rcSave = EVENT_E_INTERNALEXCEPTION;
  1985. }
  1986. }
  1987. //
  1988. // kerberos settings
  1989. //
  1990. if (cbArea & SCE_RSOP_KERBEROS_INFO) {
  1991. try {
  1992. rc = ScepWbemErrorToDosError(Log.Log(L"RSOP_SecuritySettingNumeric",
  1993. L"KeyName",
  1994. L"MaxTicketAge",
  1995. ncbErrorStatus,
  1996. FALSE
  1997. ));
  1998. ScepLogEventAndReport(MyModuleHandle,
  1999. gpwszPlanOrDiagLogFile,
  2000. 0,
  2001. 0,
  2002. IDS_ERROR_RSOP_DIAG_LOG,
  2003. rc,
  2004. L"MaxTicketAge"
  2005. );
  2006. SCEP_RSOP_CONTINUE_OR_GOTO
  2007. rc = ScepWbemErrorToDosError(Log.Log(L"RSOP_SecuritySettingNumeric",
  2008. L"KeyName",
  2009. L"MaxRenewAge",
  2010. ncbErrorStatus,
  2011. FALSE
  2012. ));
  2013. ScepLogEventAndReport(MyModuleHandle,
  2014. gpwszPlanOrDiagLogFile,
  2015. 0,
  2016. 0,
  2017. IDS_ERROR_RSOP_DIAG_LOG,
  2018. rc,
  2019. L"MaxRenewAge"
  2020. );
  2021. SCEP_RSOP_CONTINUE_OR_GOTO
  2022. rc = ScepWbemErrorToDosError(Log.Log(L"RSOP_SecuritySettingNumeric",
  2023. L"KeyName",
  2024. L"MaxServiceAge",
  2025. ncbErrorStatus,
  2026. FALSE
  2027. ));
  2028. ScepLogEventAndReport(MyModuleHandle,
  2029. gpwszPlanOrDiagLogFile,
  2030. 0,
  2031. 0,
  2032. IDS_ERROR_RSOP_DIAG_LOG,
  2033. rc,
  2034. L"MaxServiceAge"
  2035. );
  2036. SCEP_RSOP_CONTINUE_OR_GOTO
  2037. rc = ScepWbemErrorToDosError(Log.Log(L"RSOP_SecuritySettingNumeric",
  2038. L"KeyName",
  2039. L"MaxClockSkew",
  2040. ncbErrorStatus,
  2041. FALSE
  2042. ));
  2043. ScepLogEventAndReport(MyModuleHandle,
  2044. gpwszPlanOrDiagLogFile,
  2045. 0,
  2046. 0,
  2047. IDS_ERROR_RSOP_DIAG_LOG,
  2048. rc,
  2049. L"MaxClockSkew"
  2050. );
  2051. SCEP_RSOP_CONTINUE_OR_GOTO
  2052. rc = ScepWbemErrorToDosError(Log.Log(L"RSOP_SecuritySettingBoolean",
  2053. L"KeyName",
  2054. L"TicketValidateClient",
  2055. ncbErrorStatus,
  2056. FALSE
  2057. ));
  2058. ScepLogEventAndReport(MyModuleHandle,
  2059. gpwszPlanOrDiagLogFile,
  2060. 0,
  2061. 0,
  2062. IDS_ERROR_RSOP_DIAG_LOG,
  2063. rc,
  2064. L"TicketValidateClient"
  2065. );
  2066. SCEP_RSOP_CONTINUE_OR_GOTO
  2067. } catch (...) {
  2068. //
  2069. // system error continue with next setting
  2070. //
  2071. rcSave = EVENT_E_INTERNALEXCEPTION;
  2072. }
  2073. }
  2074. //
  2075. // registryvalue settings
  2076. //
  2077. if (cbArea & SCE_RSOP_REGISTRY_VALUE_INFO) {
  2078. PWSTR pwszDoubleSlashPath = NULL;
  2079. try {
  2080. //
  2081. // replace single slash with double slash for building valid WMI query
  2082. //
  2083. rc = ScepConvertSingleSlashToDoubleSlashPath(
  2084. pSettingInfo,
  2085. &pwszDoubleSlashPath
  2086. );
  2087. SCEP_RSOP_CONTINUE_OR_GOTO
  2088. rc = ScepWbemErrorToDosError(Log.Log(L"RSOP_RegistryValue",
  2089. L"Path",
  2090. pwszDoubleSlashPath,
  2091. ncbErrorStatus,
  2092. FALSE
  2093. ));
  2094. if (pwszDoubleSlashPath)
  2095. LocalFree(pwszDoubleSlashPath);
  2096. pwszDoubleSlashPath = NULL;
  2097. ScepLogEventAndReport(MyModuleHandle,
  2098. gpwszPlanOrDiagLogFile,
  2099. 0,
  2100. 0,
  2101. IDS_ERROR_RSOP_DIAG_LOG,
  2102. rc,
  2103. pSettingInfo
  2104. );
  2105. SCEP_RSOP_CONTINUE_OR_GOTO
  2106. } catch (...) {
  2107. if (pwszDoubleSlashPath)
  2108. LocalFree(pwszDoubleSlashPath);
  2109. //
  2110. // system error continue with next setting
  2111. //
  2112. rcSave = EVENT_E_INTERNALEXCEPTION;
  2113. }
  2114. }
  2115. //
  2116. // services settings
  2117. //
  2118. if (cbArea & SCE_RSOP_SERVICES_INFO) {
  2119. try {
  2120. rc = ScepWbemErrorToDosError(Log.Log(L"RSOP_SystemService",
  2121. L"Service",
  2122. pSettingInfo,
  2123. ncbErrorStatus,
  2124. FALSE
  2125. ));
  2126. ScepLogEventAndReport(MyModuleHandle,
  2127. gpwszPlanOrDiagLogFile,
  2128. 0,
  2129. 0,
  2130. IDS_ERROR_RSOP_DIAG_LOG,
  2131. rc,
  2132. pSettingInfo
  2133. );
  2134. SCEP_RSOP_CONTINUE_OR_GOTO
  2135. } catch (...) {
  2136. //
  2137. // system error continue with next setting
  2138. //
  2139. rcSave = EVENT_E_INTERNALEXCEPTION;
  2140. }
  2141. }
  2142. Done:
  2143. //
  2144. // if exception, haven't logged yet so log it
  2145. //
  2146. if (rcSave == EVENT_E_INTERNALEXCEPTION) {
  2147. ScepLogEventAndReport(MyModuleHandle,
  2148. gpwszPlanOrDiagLogFile,
  2149. 0,
  2150. 0,
  2151. IDS_ERROR_RSOP_DIAG_LOG,
  2152. rcSave,
  2153. L""
  2154. );
  2155. }
  2156. //
  2157. // merge-update the synch/asynch global status, ignore not found instances
  2158. //
  2159. //
  2160. // WBEM_E_NOT_FOUND maps to ERROR_NONE_MAPPED
  2161. // have to mask this due to an artifact of callback granularity
  2162. // however, diagnosis.log will have the errors for debugging
  2163. //
  2164. if (rcSave != ERROR_SUCCESS && rcSave != ERROR_NOT_FOUND ) {
  2165. if (!gbAsyncWinlogonThread && gHrSynchRsopStatus == S_OK)
  2166. gHrSynchRsopStatus = ScepDosErrorToWbemError(rcSave);
  2167. if (gbAsyncWinlogonThread && gHrAsynchRsopStatus == S_OK)
  2168. gHrAsynchRsopStatus = ScepDosErrorToWbemError(rcSave);
  2169. }
  2170. } catch (...) {
  2171. rcSave = EVENT_E_INTERNALEXCEPTION;
  2172. }
  2173. return rcSave;
  2174. }
  2175. DWORD
  2176. ScepConvertSingleSlashToDoubleSlashPath(
  2177. IN wchar_t *pSettingInfo,
  2178. OUT PWSTR *ppwszDoubleSlashPath
  2179. )
  2180. /////////////////////////////////////////////////////////////////////////////////////////////////////
  2181. // This function converts single slashes to double slashes to suit WMI queries //
  2182. // If success is returned, caller should free the OUT parameter //
  2183. /////////////////////////////////////////////////////////////////////////////////////////////////////
  2184. {
  2185. if (ppwszDoubleSlashPath == NULL)
  2186. return ERROR_NOT_ENOUGH_MEMORY;
  2187. UINT Len = wcslen(pSettingInfo) + 1;
  2188. PWSTR pwszSingleSlashPath=(PWSTR)LocalAlloc(LPTR, (Len)*sizeof(WCHAR));
  2189. if (pwszSingleSlashPath == NULL)
  2190. return ERROR_NOT_ENOUGH_MEMORY;
  2191. //
  2192. // max of 25 slashes per file/registry object
  2193. //
  2194. PWSTR pwszDoubleSlashPath=(PWSTR)LocalAlloc(LPTR, (Len + 50)*sizeof(WCHAR));
  2195. if (pwszDoubleSlashPath == NULL) {
  2196. LocalFree(pwszSingleSlashPath);
  2197. return ERROR_NOT_ENOUGH_MEMORY;
  2198. }
  2199. wcscpy(pwszSingleSlashPath, pSettingInfo);
  2200. UINT charNumDouble = 0;
  2201. UINT charNumSingle = 0;
  2202. while (pwszSingleSlashPath[charNumSingle] != L'\0') {
  2203. if (pwszSingleSlashPath[charNumSingle] == L'\\') {
  2204. pwszDoubleSlashPath[charNumDouble] = L'\\';
  2205. charNumDouble++;
  2206. pwszDoubleSlashPath[charNumDouble] = L'\\';
  2207. } else {
  2208. pwszDoubleSlashPath[charNumDouble] = pwszSingleSlashPath[charNumSingle];
  2209. }
  2210. charNumDouble++;
  2211. charNumSingle++;
  2212. }
  2213. if (pwszSingleSlashPath)
  2214. LocalFree(pwszSingleSlashPath);
  2215. *ppwszDoubleSlashPath = pwszDoubleSlashPath;
  2216. return ERROR_SUCCESS;
  2217. }
  2218. DWORD
  2219. ScepClientTranslateFileDirName(
  2220. IN PWSTR oldFileName,
  2221. OUT PWSTR *newFileName
  2222. )
  2223. /* ++
  2224. Routine Description:
  2225. This routine converts a generic file/directory name to a real used name
  2226. for the current system. The following generic file/directory names are handled:
  2227. %systemroot% - Windows NT root directory (e.g., c:\winnt)
  2228. %systemDirectory% - Windows NT system32 directory (e.g., c:\winnt\system32)
  2229. Arguments:
  2230. oldFileName - the file name to convert, which includes "%" to represent
  2231. some directory names
  2232. newFileName - the real file name, in which the "%" name is replaced with
  2233. the real directory name
  2234. Return values:
  2235. Win32 error code
  2236. -- */
  2237. {
  2238. //
  2239. // match for %systemroot%
  2240. //
  2241. PWSTR pTemp=NULL, pStart, TmpBuf, szVar;
  2242. DWORD rc=NO_ERROR;
  2243. DWORD newFileSize, cSize;
  2244. BOOL bContinue;
  2245. rc = ScepExpandEnvironmentVariable(oldFileName,
  2246. L"%SYSTEMROOT%",
  2247. SCE_FLAG_WINDOWS_DIR,
  2248. newFileName);
  2249. if ( rc != ERROR_FILE_NOT_FOUND ) {
  2250. return rc;
  2251. }
  2252. //
  2253. // match for %systemdirectory%
  2254. //
  2255. rc = ScepExpandEnvironmentVariable(oldFileName,
  2256. L"%SYSTEMDIRECTORY%",
  2257. SCE_FLAG_SYSTEM_DIR,
  2258. newFileName);
  2259. if ( rc != ERROR_FILE_NOT_FOUND ) {
  2260. return rc;
  2261. }
  2262. //
  2263. // match for systemdrive
  2264. //
  2265. rc = ScepExpandEnvironmentVariable(oldFileName,
  2266. L"%SYSTEMDRIVE%",
  2267. SCE_FLAG_WINDOWS_DIR,
  2268. newFileName);
  2269. if ( rc != ERROR_FILE_NOT_FOUND ) {
  2270. return rc;
  2271. }
  2272. //
  2273. // match for boot drive
  2274. //
  2275. rc = ScepExpandEnvironmentVariable(oldFileName,
  2276. L"%BOOTDRIVE%",
  2277. SCE_FLAG_BOOT_DRIVE,
  2278. newFileName);
  2279. if ( rc != ERROR_FILE_NOT_FOUND ) {
  2280. return rc;
  2281. }
  2282. rc = ERROR_SUCCESS;
  2283. //
  2284. // search for environment variable in the current process
  2285. //
  2286. pStart = wcschr(oldFileName, L'%');
  2287. if ( pStart ) {
  2288. pTemp = wcschr(pStart+1, L'%');
  2289. if ( pTemp ) {
  2290. bContinue = TRUE;
  2291. //
  2292. // find a environment variable to translate
  2293. //
  2294. TmpBuf = (PWSTR)ScepAlloc(0, ((UINT)(pTemp-pStart))*sizeof(WCHAR));
  2295. if ( TmpBuf ) {
  2296. wcsncpy(TmpBuf, pStart+1, (size_t)(pTemp-pStart-1));
  2297. TmpBuf[pTemp-pStart-1] = L'\0';
  2298. //
  2299. // try search in the client environment block
  2300. //
  2301. cSize = GetEnvironmentVariable( TmpBuf,
  2302. NULL,
  2303. 0 );
  2304. if ( cSize > 0 ) {
  2305. szVar = (PWSTR)ScepAlloc(0, (cSize+1)*sizeof(WCHAR));
  2306. if ( szVar ) {
  2307. cSize = GetEnvironmentVariable(TmpBuf,
  2308. szVar,
  2309. cSize);
  2310. if ( cSize > 0 ) {
  2311. //
  2312. // get info in szVar
  2313. //
  2314. bContinue = FALSE;
  2315. newFileSize = ((DWORD)(pStart-oldFileName))+cSize+wcslen(pTemp+1)+1;
  2316. *newFileName = (PWSTR)ScepAlloc(0, newFileSize*sizeof(TCHAR));
  2317. if (*newFileName ) {
  2318. if ( pStart != oldFileName )
  2319. wcsncpy(*newFileName, oldFileName, (size_t)(pStart-oldFileName));
  2320. swprintf((PWSTR)(*newFileName+(pStart-oldFileName)), L"%s%s", szVar, pTemp+1);
  2321. } else
  2322. rc = ERROR_NOT_ENOUGH_MEMORY;
  2323. }
  2324. ScepFree(szVar);
  2325. } else
  2326. rc = ERROR_NOT_ENOUGH_MEMORY;
  2327. }
  2328. ScepFree(TmpBuf);
  2329. } else
  2330. rc = ERROR_NOT_ENOUGH_MEMORY;
  2331. if ( NO_ERROR != rc || !bContinue ) {
  2332. //
  2333. // if errored, or do not continue
  2334. //
  2335. return(rc);
  2336. }
  2337. //
  2338. // not found in process environment,
  2339. // continue to search for DSDIT/DSLOG/SYSVOL in registry
  2340. //
  2341. if ( (gbDCQueried == TRUE && gbThisIsDC == TRUE) ) {
  2342. //
  2343. // search for DSDIT
  2344. //
  2345. rc = ScepExpandEnvironmentVariable(oldFileName,
  2346. L"%DSDIT%",
  2347. SCE_FLAG_DSDIT_DIR,
  2348. newFileName);
  2349. if ( rc != ERROR_FILE_NOT_FOUND ) {
  2350. return rc;
  2351. }
  2352. //
  2353. // search for DSLOG
  2354. //
  2355. rc = ScepExpandEnvironmentVariable(oldFileName,
  2356. L"%DSLOG%",
  2357. SCE_FLAG_DSLOG_DIR,
  2358. newFileName);
  2359. if ( rc != ERROR_FILE_NOT_FOUND ) {
  2360. return rc;
  2361. }
  2362. //
  2363. // search for SYSVOL
  2364. //
  2365. rc = ScepExpandEnvironmentVariable(oldFileName,
  2366. L"%SYSVOL%",
  2367. SCE_FLAG_SYSVOL_DIR,
  2368. newFileName);
  2369. if ( rc != ERROR_FILE_NOT_FOUND ) {
  2370. return rc;
  2371. }
  2372. }
  2373. }
  2374. }
  2375. //
  2376. // Otherwise, just copy the old name to a new buffer and return ERROR_PATH_NOT_FOUND
  2377. //
  2378. *newFileName = (PWSTR)ScepAlloc(0, (wcslen(oldFileName)+1)*sizeof(TCHAR));
  2379. if (*newFileName != NULL) {
  2380. wcscpy(*newFileName, _wcsupr(oldFileName) );
  2381. rc = ERROR_PATH_NOT_FOUND;
  2382. } else
  2383. rc = ERROR_NOT_ENOUGH_MEMORY;
  2384. return(rc);
  2385. }
  2386. VOID
  2387. ScepLogEventAndReport(
  2388. IN HINSTANCE hInstance,
  2389. IN LPTSTR LogFileName,
  2390. IN DWORD LogLevel,
  2391. IN DWORD dwEventID,
  2392. IN UINT idMsg,
  2393. IN DWORD rc,
  2394. IN PWSTR pwszMsg
  2395. )
  2396. /////////////////////////////////////////////////////////////////////////////////////////////////////
  2397. // Wrapper to log efficiently //
  2398. /////////////////////////////////////////////////////////////////////////////////////////////////////
  2399. {
  2400. if (SCEP_VALID_NAME(LogFileName)) {
  2401. LogEventAndReport(hInstance,
  2402. LogFileName,
  2403. LogLevel,
  2404. dwEventID,
  2405. idMsg,
  2406. rc,
  2407. pwszMsg
  2408. );
  2409. }
  2410. }
  2411. DWORD
  2412. ScepCanonicalizeGroupName(
  2413. IN PWSTR pwszGroupName,
  2414. OUT PWSTR *ppwszCanonicalGroupName
  2415. )
  2416. //////////////////////////////////////////////////////////////////////////////////
  2417. // memory allocated here should be freed outside //
  2418. // if SID format, returns SID itself //
  2419. // else if "BuiltinDomain\Administrator" convert to "Administrator" //
  2420. // else if (it is DC) and "g" convert to "DomainName\g" //
  2421. //////////////////////////////////////////////////////////////////////////////////
  2422. {
  2423. DWORD rc = NO_ERROR;
  2424. if (pwszGroupName == NULL || ppwszCanonicalGroupName == NULL)
  2425. return ERROR_INVALID_PARAMETER;
  2426. PWSTR pwszAfterSlash = NULL;
  2427. if (pwszAfterSlash = wcsstr(pwszGroupName, L"\\"))
  2428. ++ pwszAfterSlash;
  2429. else
  2430. pwszAfterSlash = pwszGroupName;
  2431. if ( pwszGroupName[0] == L'*' ) {
  2432. //
  2433. // if sid, just copy as is
  2434. //
  2435. *ppwszCanonicalGroupName = (PWSTR)ScepAlloc(LMEM_ZEROINIT,
  2436. (wcslen(pwszGroupName) + 1) * sizeof (WCHAR)
  2437. );
  2438. if (*ppwszCanonicalGroupName == NULL)
  2439. rc = ERROR_NOT_ENOUGH_MEMORY;
  2440. else
  2441. wcscpy(*ppwszCanonicalGroupName, pwszGroupName);
  2442. }
  2443. else if (ScepRsopLookupBuiltinNameTable(pwszAfterSlash)) {
  2444. //
  2445. // example - if "BuiltinDomainName\Administrator", we need "Administrator"
  2446. //
  2447. *ppwszCanonicalGroupName = (PWSTR)ScepAlloc(LMEM_ZEROINIT,
  2448. (wcslen(pwszAfterSlash) + 1) * sizeof (WCHAR)
  2449. );
  2450. if (*ppwszCanonicalGroupName == NULL)
  2451. rc = ERROR_NOT_ENOUGH_MEMORY;
  2452. else
  2453. wcscpy(*ppwszCanonicalGroupName, pwszAfterSlash);
  2454. }
  2455. else if (gbDCQueried == TRUE && gbThisIsDC == TRUE) {
  2456. //
  2457. // example - if "g", we need "DomainName\g"
  2458. //
  2459. if (NULL == wcsstr(pwszGroupName, L"\\")){
  2460. //
  2461. // if domain name is not available, we continue since callback will have the same problem, so OK
  2462. //
  2463. if (gpwszDCDomainName){
  2464. *ppwszCanonicalGroupName = (PWSTR)ScepAlloc(LMEM_ZEROINIT,
  2465. (wcslen(gpwszDCDomainName) + wcslen(pwszGroupName) + 2) * sizeof (WCHAR)
  2466. );
  2467. if (*ppwszCanonicalGroupName == NULL)
  2468. rc = ERROR_NOT_ENOUGH_MEMORY;
  2469. else {
  2470. wcscpy(*ppwszCanonicalGroupName, gpwszDCDomainName);
  2471. wcscat(*ppwszCanonicalGroupName, L"\\");
  2472. wcscat(*ppwszCanonicalGroupName, pwszGroupName);
  2473. }
  2474. }
  2475. }
  2476. else {
  2477. //
  2478. // already in "DomainName\g" format - simply copy
  2479. //
  2480. *ppwszCanonicalGroupName = (PWSTR)ScepAlloc(LMEM_ZEROINIT,
  2481. (wcslen(pwszGroupName) + 1) * sizeof (WCHAR)
  2482. );
  2483. if (*ppwszCanonicalGroupName == NULL)
  2484. rc = ERROR_NOT_ENOUGH_MEMORY;
  2485. else
  2486. wcscpy(*ppwszCanonicalGroupName, pwszGroupName);
  2487. }
  2488. }
  2489. else {
  2490. //
  2491. // simply copy - workstation or none of the above matched
  2492. //
  2493. *ppwszCanonicalGroupName = (PWSTR)ScepAlloc(LMEM_ZEROINIT,
  2494. (wcslen(pwszGroupName) + 1) * sizeof (WCHAR)
  2495. );
  2496. if (*ppwszCanonicalGroupName == NULL)
  2497. rc = ERROR_NOT_ENOUGH_MEMORY;
  2498. else
  2499. wcscpy(*ppwszCanonicalGroupName, pwszGroupName);
  2500. }
  2501. return rc;
  2502. }
  2503. BOOL
  2504. ScepRsopLookupBuiltinNameTable(
  2505. IN PWSTR pwszGroupName
  2506. )
  2507. //////////////////////////////////////////////////////////////////////////////////
  2508. // returns TRUE if group is found in builtin groups, else returns FALSE //
  2509. //////////////////////////////////////////////////////////////////////////////////
  2510. {
  2511. for (int i = 0; i < TABLE_SIZE; i++) {
  2512. if ( _wcsicmp(NameTable[i].Name, pwszGroupName) == 0 )
  2513. return TRUE;
  2514. }
  2515. return FALSE;
  2516. }