Leaked source code of windows server 2003
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.

1588 lines
47 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. //
  5. // Copyright (C) Microsoft Corporation, 1995 - 1996
  6. //
  7. // File: tcertpro.cpp
  8. //
  9. // Contents: Cert Protection Tests
  10. //
  11. // See Usage() for a list of test options.
  12. //
  13. //
  14. // Functions: main
  15. //
  16. // History: 30-Nov-97 philh created
  17. //--------------------------------------------------------------------------
  18. #include <windows.h>
  19. #include <assert.h>
  20. #include "wincrypt.h"
  21. #include "certtest.h"
  22. #include "unicode.h"
  23. #include "certprot.h"
  24. #include <stdlib.h>
  25. #include <stdio.h>
  26. #include <string.h>
  27. #include <memory.h>
  28. #include <time.h>
  29. static void PrintLastError(LPCSTR pszMsg, LONG lErr)
  30. {
  31. printf(" %s failed => 0x%x (%d) \n", pszMsg, lErr, lErr);
  32. }
  33. static void PrintLastError(LPCSTR pszMsg)
  34. {
  35. DWORD dwErr = GetLastError();
  36. printf(" %s failed => 0x%x (%d) \n", pszMsg, dwErr, dwErr);
  37. }
  38. static
  39. BOOL
  40. SetPrivilege(
  41. HANDLE hToken, // token handle
  42. LPCSTR Privilege, // Privilege to enable/disable
  43. BOOL bEnablePrivilege // to enable or disable privilege
  44. )
  45. {
  46. TOKEN_PRIVILEGES tp;
  47. LUID luid;
  48. TOKEN_PRIVILEGES tpPrevious;
  49. DWORD cbPrevious=sizeof(TOKEN_PRIVILEGES);
  50. if(!LookupPrivilegeValueA( NULL, Privilege, &luid )) return FALSE;
  51. //
  52. // first pass. get current privilege setting
  53. //
  54. tp.PrivilegeCount = 1;
  55. tp.Privileges[0].Luid = luid;
  56. tp.Privileges[0].Attributes = 0;
  57. AdjustTokenPrivileges(
  58. hToken,
  59. FALSE,
  60. &tp,
  61. sizeof(TOKEN_PRIVILEGES),
  62. &tpPrevious,
  63. &cbPrevious
  64. );
  65. if (GetLastError() != ERROR_SUCCESS) return FALSE;
  66. //
  67. // second pass. set privilege based on previous setting
  68. //
  69. tpPrevious.PrivilegeCount = 1;
  70. tpPrevious.Privileges[0].Luid = luid;
  71. if(bEnablePrivilege) {
  72. tpPrevious.Privileges[0].Attributes |= (SE_PRIVILEGE_ENABLED);
  73. }
  74. else {
  75. tpPrevious.Privileges[0].Attributes ^= (SE_PRIVILEGE_ENABLED &
  76. tpPrevious.Privileges[0].Attributes);
  77. }
  78. AdjustTokenPrivileges(
  79. hToken,
  80. FALSE,
  81. &tpPrevious,
  82. cbPrevious,
  83. NULL,
  84. NULL
  85. );
  86. if (GetLastError() != ERROR_SUCCESS) return FALSE;
  87. return TRUE;
  88. }
  89. static
  90. BOOL
  91. SetCurrentPrivilege(
  92. LPCSTR Privilege, // Privilege to enable/disable
  93. BOOL bEnablePrivilege // to enable or disable privilege
  94. )
  95. {
  96. BOOL bSuccess=FALSE; // assume failure
  97. HANDLE hToken;
  98. if(OpenProcessToken(
  99. GetCurrentProcess(),
  100. TOKEN_QUERY | TOKEN_ADJUST_PRIVILEGES,
  101. &hToken
  102. ))
  103. {
  104. if(SetPrivilege(hToken, Privilege, bEnablePrivilege)) bSuccess=TRUE;
  105. CloseHandle(hToken);
  106. }
  107. return bSuccess;
  108. }
  109. static void Usage(void)
  110. {
  111. printf("Usage: tcertpro [options] <TestName> <RegPath>\n");
  112. printf("Options are:\n");
  113. printf(" -h - This message\n");
  114. // printf(" -r - Recurse subkeys\n");
  115. printf(" -lCU - CurrentUser (default)\n");
  116. printf(" -lLM - LocalMachine\n");
  117. printf("TestNames (case insensitive):\n");
  118. printf(" GetKey - Get Registry Key Security Information\n");
  119. printf(" SetKey - Set Registry Key Security Information\n");
  120. printf(" PurgeLMRoots - Purge LocalMachine Roots From CurrentUser\n");
  121. printf(" DeleteUnknownRoots - Delete Unknown Roots From Protected List\n");
  122. printf(" CheckProtectedRoots - Check ProtectedRoots ACLs\n");
  123. printf(" ServiceUI - Cert protect service UI\n");
  124. printf(" ServiceTokenInfo - Get Cert protect service token info\n");
  125. printf(" ServiceInvalid - Invalid Cert protect function\n");
  126. printf("\n");
  127. }
  128. #if 0
  129. #define OWNER_SECURITY_INFORMATION (0X00000001L)
  130. #define GROUP_SECURITY_INFORMATION (0X00000002L)
  131. #define DACL_SECURITY_INFORMATION (0X00000004L)
  132. #define SACL_SECURITY_INFORMATION (0X00000008L)
  133. #endif
  134. static PSECURITY_DESCRIPTOR AllocAndGetSecurityDescriptor(
  135. IN HKEY hKey,
  136. SECURITY_INFORMATION SecInf
  137. )
  138. {
  139. LONG err;
  140. PSECURITY_DESCRIPTOR psd = NULL;
  141. DWORD cbsd = 0;
  142. err = RegGetKeySecurity(
  143. hKey,
  144. SecInf,
  145. NULL, // psd
  146. &cbsd
  147. );
  148. if (!(ERROR_SUCCESS == err || ERROR_INSUFFICIENT_BUFFER == err)) {
  149. PrintLastError("RegGetKeySecurity", err);
  150. return NULL;
  151. }
  152. if (0 == cbsd)
  153. return NULL;
  154. if (NULL == (psd = (PSECURITY_DESCRIPTOR) TestAlloc(cbsd)))
  155. return NULL;
  156. if (ERROR_SUCCESS != (err = RegGetKeySecurity(
  157. hKey,
  158. SecInf,
  159. psd,
  160. &cbsd
  161. ))) {
  162. PrintLastError("RegGetKeySecurity", err);
  163. TestFree(psd);
  164. }
  165. return psd;
  166. }
  167. #if 0
  168. #define SE_OWNER_DEFAULTED (0x0001)
  169. #define SE_GROUP_DEFAULTED (0x0002)
  170. #define SE_DACL_PRESENT (0x0004)
  171. #define SE_DACL_DEFAULTED (0x0008)
  172. #define SE_SACL_PRESENT (0x0010)
  173. #define SE_SACL_DEFAULTED (0x0020)
  174. #define SE_DACL_AUTO_INHERIT_REQ (0x0100)
  175. #define SE_SACL_AUTO_INHERIT_REQ (0x0200)
  176. #define SE_DACL_AUTO_INHERITED (0x0400)
  177. #define SE_SACL_AUTO_INHERITED (0x0800)
  178. #define SE_DACL_PROTECTED (0x1000)
  179. #define SE_SACL_PROTECTED (0x2000)
  180. #define SE_SELF_RELATIVE (0x8000)
  181. #endif
  182. //
  183. // Where:
  184. //
  185. // SE_OWNER_DEFAULTED - This boolean flag, when set, indicates that the
  186. // SID pointed to by the Owner field was provided by a
  187. // defaulting mechanism rather than explicitly provided by the
  188. // original provider of the security descriptor. This may
  189. // affect the treatment of the SID with respect to inheritence
  190. // of an owner.
  191. //
  192. // SE_GROUP_DEFAULTED - This boolean flag, when set, indicates that the
  193. // SID in the Group field was provided by a defaulting mechanism
  194. // rather than explicitly provided by the original provider of
  195. // the security descriptor. This may affect the treatment of
  196. // the SID with respect to inheritence of a primary group.
  197. //
  198. // SE_DACL_PRESENT - This boolean flag, when set, indicates that the
  199. // security descriptor contains a discretionary ACL. If this
  200. // flag is set and the Dacl field of the SECURITY_DESCRIPTOR is
  201. // null, then a null ACL is explicitly being specified.
  202. //
  203. // SE_DACL_DEFAULTED - This boolean flag, when set, indicates that the
  204. // ACL pointed to by the Dacl field was provided by a defaulting
  205. // mechanism rather than explicitly provided by the original
  206. // provider of the security descriptor. This may affect the
  207. // treatment of the ACL with respect to inheritence of an ACL.
  208. // This flag is ignored if the DaclPresent flag is not set.
  209. //
  210. // SE_SACL_PRESENT - This boolean flag, when set, indicates that the
  211. // security descriptor contains a system ACL pointed to by the
  212. // Sacl field. If this flag is set and the Sacl field of the
  213. // SECURITY_DESCRIPTOR is null, then an empty (but present)
  214. // ACL is being specified.
  215. //
  216. // SE_SACL_DEFAULTED - This boolean flag, when set, indicates that the
  217. // ACL pointed to by the Sacl field was provided by a defaulting
  218. // mechanism rather than explicitly provided by the original
  219. // provider of the security descriptor. This may affect the
  220. // treatment of the ACL with respect to inheritence of an ACL.
  221. // This flag is ignored if the SaclPresent flag is not set.
  222. //
  223. // SE_SELF_RELATIVE - This boolean flag, when set, indicates that the
  224. // security descriptor is in self-relative form. In this form,
  225. // all fields of the security descriptor are contiguous in memory
  226. // and all pointer fields are expressed as offsets from the
  227. // beginning of the security descriptor. This form is useful
  228. // for treating security descriptors as opaque data structures
  229. // for transmission in communication protocol or for storage on
  230. // secondary media.
  231. //
  232. #if 0
  233. typedef enum _SID_NAME_USE {
  234. SidTypeUser = 1,
  235. SidTypeGroup,
  236. SidTypeDomain,
  237. SidTypeAlias,
  238. SidTypeWellKnownGroup,
  239. SidTypeDeletedAccount,
  240. SidTypeInvalid,
  241. SidTypeUnknown
  242. } SID_NAME_USE, *PSID_NAME_USE;
  243. #endif
  244. static void DisplayControl(
  245. PSECURITY_DESCRIPTOR psd
  246. )
  247. {
  248. SECURITY_DESCRIPTOR_CONTROL sdc;
  249. DWORD dwRevision;
  250. if (!GetSecurityDescriptorControl(psd, &sdc, &dwRevision))
  251. PrintLastError("GetSecurityDescriptorControl");
  252. else {
  253. printf(" Control: 0x%x", sdc);
  254. if (sdc & SE_OWNER_DEFAULTED)
  255. printf(" OWNER_DEFAULTED");
  256. if (sdc & SE_GROUP_DEFAULTED)
  257. printf(" GROUP_DEFAULTED");
  258. if (sdc & SE_DACL_PRESENT)
  259. printf(" DACL_PRESENT");
  260. if (sdc & SE_DACL_DEFAULTED)
  261. printf(" DACL_DEFAULTED");
  262. if (sdc & SE_SACL_PRESENT)
  263. printf(" SACL_PRESENT");
  264. if (sdc & SE_SACL_DEFAULTED)
  265. printf(" SACL_DEFAULTED");
  266. if (sdc & SE_DACL_AUTO_INHERIT_REQ)
  267. printf(" DACL_AUTO_INHERIT_REQ");
  268. if (sdc & SE_SACL_AUTO_INHERIT_REQ)
  269. printf(" SACL_AUTO_INHERIT_REQ");
  270. if (sdc & SE_DACL_AUTO_INHERITED)
  271. printf(" DACL_AUTO_INHERITED");
  272. if (sdc & SE_SACL_AUTO_INHERITED)
  273. printf(" SACL_AUTO_INHERITED");
  274. if (sdc & SE_DACL_PROTECTED)
  275. printf(" DACL_PROTECTED");
  276. if (sdc & SE_SACL_PROTECTED)
  277. printf(" SACL_PROTECTED");
  278. if (sdc & SE_SELF_RELATIVE)
  279. printf(" SELF_RELATIVE");
  280. printf("\n");
  281. printf(" Revision: %d\n", dwRevision);
  282. }
  283. }
  284. static void DisplaySid(
  285. PSID pSid
  286. )
  287. {
  288. PSID_IDENTIFIER_AUTHORITY psia;
  289. DWORD dwSubAuthorities;
  290. DWORD dwCounter;
  291. char szAccount[_MAX_PATH];
  292. DWORD cchAccount;
  293. char szDomain[_MAX_PATH];
  294. DWORD cchDomain;
  295. SID_NAME_USE snu;
  296. if (!IsValidSid(pSid)) {
  297. printf("Invalid SID\n");
  298. return;
  299. }
  300. // obtain SidIdentifierAuthority
  301. psia = GetSidIdentifierAuthority(pSid);
  302. // obtain sidsubauthority count
  303. dwSubAuthorities = *GetSidSubAuthorityCount(pSid);
  304. //
  305. // prepare S-SID_REVISION-
  306. //
  307. printf("S-%lu-", SID_REVISION);
  308. //
  309. // prepare SidIdentifierAuthority
  310. //
  311. if ( (psia->Value[0] != 0) || (psia->Value[1] != 0) ) {
  312. printf("0x%02hx%02hx%02hx%02hx%02hx%02hx",
  313. (USHORT)psia->Value[0],
  314. (USHORT)psia->Value[1],
  315. (USHORT)psia->Value[2],
  316. (USHORT)psia->Value[3],
  317. (USHORT)psia->Value[4],
  318. (USHORT)psia->Value[5]);
  319. } else {
  320. printf("%lu",
  321. (ULONG)(psia->Value[5] ) +
  322. (ULONG)(psia->Value[4] << 8) +
  323. (ULONG)(psia->Value[3] << 16) +
  324. (ULONG)(psia->Value[2] << 24) );
  325. }
  326. //
  327. // loop through SidSubAuthorities
  328. //
  329. for (dwCounter = 0 ; dwCounter < dwSubAuthorities ; dwCounter++) {
  330. printf("-%lu", *GetSidSubAuthority(pSid, dwCounter) );
  331. }
  332. cchAccount = sizeof(szAccount) - 1;
  333. memset(szAccount, 0, sizeof(szAccount));
  334. cchDomain = sizeof(szDomain) - 1;
  335. memset(szDomain, 0, sizeof(szDomain));
  336. snu = (SID_NAME_USE) 0;
  337. if (LookupAccountSidA(
  338. NULL, // lpSystemName
  339. pSid,
  340. szAccount,
  341. &cchAccount,
  342. szDomain,
  343. &cchDomain,
  344. &snu
  345. ))
  346. printf(" Account: %s Domain: %s SNU: %d", szAccount, szDomain, snu);
  347. printf("\n");
  348. }
  349. static void DisplayOwnerSecurityInfo(
  350. IN PSECURITY_DESCRIPTOR psd
  351. )
  352. {
  353. PSID pSid = NULL;
  354. BOOL fOwnerDefaulted;
  355. if (!GetSecurityDescriptorOwner(psd, &pSid, &fOwnerDefaulted)) {
  356. PrintLastError("GetSecurityDescriptorOwner");
  357. return;
  358. }
  359. if (NULL == pSid)
  360. printf(" NO OWNER\n");
  361. else {
  362. printf(" Owner: ");
  363. DisplaySid(pSid);
  364. if (fOwnerDefaulted)
  365. printf(" Owner Defaulted\n");
  366. }
  367. }
  368. static void DisplayGroupSecurityInfo(
  369. IN PSECURITY_DESCRIPTOR psd
  370. )
  371. {
  372. PSID pSid = NULL;
  373. BOOL fGroupDefaulted;
  374. if (!GetSecurityDescriptorGroup(psd, &pSid, &fGroupDefaulted)) {
  375. PrintLastError("GetSecurityDescriptorGroup");
  376. return;
  377. }
  378. if (NULL == pSid)
  379. printf(" NO Group\n");
  380. else {
  381. printf(" Group: ");
  382. DisplaySid(pSid);
  383. if (fGroupDefaulted)
  384. printf(" Group Defaulted\n");
  385. }
  386. }
  387. static LPCSTR GetAceTypeString(
  388. IN BYTE AceType
  389. )
  390. {
  391. switch (AceType) {
  392. case ACCESS_ALLOWED_ACE_TYPE:
  393. return "ACCESS_ALLOWED";
  394. break;
  395. case ACCESS_DENIED_ACE_TYPE:
  396. return "ACCESS_DENIED_ACE_TYPE";
  397. break;
  398. case SYSTEM_AUDIT_ACE_TYPE:
  399. return "SYSTEM_AUDIT_ACE_TYPE";
  400. break;
  401. case SYSTEM_ALARM_ACE_TYPE:
  402. return "SYSTEM_ALARM_ACE_TYPE";
  403. break;
  404. case ACCESS_ALLOWED_COMPOUND_ACE_TYPE:
  405. return "ACCESS_ALLOWED_COMPOUND_ACE_TYPE";
  406. break;
  407. case ACCESS_ALLOWED_OBJECT_ACE_TYPE:
  408. return "ACCESS_ALLOWED_OBJECT_ACE_TYPE";
  409. break;
  410. case ACCESS_DENIED_OBJECT_ACE_TYPE:
  411. return "ACCESS_DENIED_OBJECT_ACE_TYPE";
  412. break;
  413. case SYSTEM_AUDIT_OBJECT_ACE_TYPE:
  414. return "SYSTEM_AUDIT_OBJECT_ACE_TYPE";
  415. break;
  416. case SYSTEM_ALARM_OBJECT_ACE_TYPE:
  417. return "SYSTEM_ALARM_OBJECT_ACE_TYPE";
  418. break;
  419. default:
  420. return "???";
  421. }
  422. }
  423. static void DisplayAceFlags(
  424. IN BYTE AceFlags
  425. )
  426. {
  427. if (AceFlags & OBJECT_INHERIT_ACE)
  428. printf(" OBJECT_INHERIT");
  429. if (AceFlags & CONTAINER_INHERIT_ACE)
  430. printf(" CONTAINER_INHERIT");
  431. if (AceFlags & NO_PROPAGATE_INHERIT_ACE)
  432. printf(" NO_PROPAGATE_INHERIT");
  433. if (AceFlags & INHERIT_ONLY_ACE)
  434. printf(" INHERIT_ONLY");
  435. if (AceFlags & INHERITED_ACE)
  436. printf(" INHERITED");
  437. if (AceFlags & SUCCESSFUL_ACCESS_ACE_FLAG)
  438. printf(" SUCCESSFUL_ACCESS");
  439. if (AceFlags & FAILED_ACCESS_ACE_FLAG)
  440. printf(" FAILED_ACCESS");
  441. }
  442. static void DisplayAccessMask(
  443. IN ACCESS_MASK Mask
  444. )
  445. {
  446. if (Mask & SYNCHRONIZE)
  447. printf(" SYNCHRONIZE");
  448. if (Mask & ACCESS_SYSTEM_SECURITY)
  449. printf(" ACCESS_SYSTEM_SECURITY");
  450. if (Mask & MAXIMUM_ALLOWED)
  451. printf(" MAXIMUM_ALLOWED");
  452. if (Mask & GENERIC_READ)
  453. printf(" GENERIC_READ");
  454. if (Mask & GENERIC_WRITE)
  455. printf(" GENERIC_WRITE");
  456. if (Mask & GENERIC_EXECUTE)
  457. printf(" GENERIC_EXECUTE");
  458. if (Mask & GENERIC_ALL)
  459. printf(" GENERIC_ALL");
  460. if (KEY_ALL_ACCESS == (Mask & KEY_ALL_ACCESS)) {
  461. printf(" KEY_ALL_ACCESS");
  462. return;
  463. }
  464. if (KEY_READ == (Mask & KEY_READ))
  465. printf(" KEY_READ");
  466. if (KEY_WRITE == (Mask & KEY_WRITE))
  467. printf(" KEY_WRITE");
  468. if (KEY_EXECUTE == (Mask & KEY_EXECUTE))
  469. printf(" KEY_EXECUTE");
  470. if (Mask & DELETE)
  471. printf(" DELETE");
  472. if (Mask & READ_CONTROL)
  473. printf(" READ_CONTROL");
  474. if (Mask & WRITE_DAC)
  475. printf(" WRITE_DAC");
  476. if (Mask & WRITE_OWNER)
  477. printf(" WRITE_OWNER");
  478. if (Mask & KEY_QUERY_VALUE)
  479. printf(" KEY_QUERY_VALUE");
  480. if (Mask & KEY_SET_VALUE)
  481. printf(" KEY_SET_VALUE");
  482. if (Mask & KEY_CREATE_SUB_KEY)
  483. printf(" KEY_CREATE_SUB_KEY");
  484. if (Mask & KEY_ENUMERATE_SUB_KEYS)
  485. printf(" KEY_ENUMERATE_SUB_KEYS");
  486. if (Mask & KEY_NOTIFY)
  487. printf(" KEY_NOTIFY");
  488. if (Mask & KEY_CREATE_LINK)
  489. printf(" KEY_CREATE_LINK");
  490. }
  491. static void DisplayAcl(
  492. IN BOOL fDaclPresent,
  493. IN PACL pAcl,
  494. IN BOOL fDaclDefaulted
  495. )
  496. {
  497. DWORD dwAceIndex;
  498. if (!fDaclPresent) {
  499. printf(" NO ACL\n");
  500. return;
  501. }
  502. if (NULL == pAcl) {
  503. printf(" NULL ACL\n");
  504. return;
  505. }
  506. printf(" AclRevision: %d", pAcl->AclRevision);
  507. if (fDaclDefaulted)
  508. printf(" Defaulted ACL");
  509. printf("\n");
  510. for (dwAceIndex = 0; dwAceIndex < pAcl->AceCount; dwAceIndex++) {
  511. PACE_HEADER pAceHdr;
  512. PACCESS_ALLOWED_ACE pAce;
  513. if (!GetAce(pAcl, dwAceIndex, (void **) &pAceHdr)) {
  514. PrintLastError("GetAce");
  515. return;
  516. }
  517. printf(" Ace[%d]\n", dwAceIndex);
  518. printf(" Type: 0x%x %s\n", pAceHdr->AceType,
  519. GetAceTypeString(pAceHdr->AceType));
  520. printf(" Flags: 0x%x ", pAceHdr->AceFlags);
  521. DisplayAceFlags(pAceHdr->AceFlags);
  522. printf("\n");
  523. switch (pAceHdr->AceType) {
  524. case ACCESS_ALLOWED_ACE_TYPE:
  525. case ACCESS_DENIED_ACE_TYPE:
  526. case SYSTEM_AUDIT_ACE_TYPE:
  527. case SYSTEM_ALARM_ACE_TYPE:
  528. pAce = (PACCESS_ALLOWED_ACE) pAceHdr;
  529. printf(" Mask: 0x%x", pAce->Mask);
  530. DisplayAccessMask(pAce->Mask);
  531. printf("\n");
  532. printf(" SID: ");
  533. DisplaySid((PSID) &pAce->SidStart);
  534. break;
  535. default:
  536. break;
  537. }
  538. }
  539. }
  540. static void DisplayDaclSecurityInfo(
  541. IN PSECURITY_DESCRIPTOR psd
  542. )
  543. {
  544. BOOL fDaclPresent;
  545. PACL pAcl;
  546. BOOL fDaclDefaulted;
  547. DWORD dwAceIndex;
  548. printf(" --- DACLs ---\n");
  549. if (!GetSecurityDescriptorDacl(psd, &fDaclPresent, &pAcl,
  550. &fDaclDefaulted)) {
  551. PrintLastError("GetSecurityDescriptorDacl");
  552. return;
  553. }
  554. DisplayAcl(fDaclPresent, pAcl, fDaclDefaulted);
  555. }
  556. static void DisplaySaclSecurityInfo(
  557. IN PSECURITY_DESCRIPTOR psd
  558. )
  559. {
  560. BOOL fSaclPresent;
  561. PACL pAcl;
  562. BOOL fSaclDefaulted;
  563. DWORD dwAceIndex;
  564. printf(" --- SACLs ---\n");
  565. if (!GetSecurityDescriptorSacl(psd, &fSaclPresent, &pAcl,
  566. &fSaclDefaulted)) {
  567. PrintLastError("GetSecurityDescriptorSacl");
  568. return;
  569. }
  570. DisplayAcl(fSaclPresent, pAcl, fSaclDefaulted);
  571. }
  572. static void DisplayRegQueryInfo(
  573. IN HKEY hKey
  574. )
  575. {
  576. FILETIME ftLastWriteTime;
  577. LONG err;
  578. memset(&ftLastWriteTime, 0, sizeof(ftLastWriteTime));
  579. if (ERROR_SUCCESS == (err = RegQueryInfoKeyA(
  580. hKey,
  581. NULL, // lpszClass
  582. NULL, // lpcchClass
  583. NULL, // lpdwReserved
  584. NULL, // lpcSubKeys
  585. NULL, // lpcchMaxSubKey
  586. NULL, // lpcchMaxClass
  587. NULL, // lpcValues
  588. NULL, // lpcchMaxValuesName
  589. NULL, // lpcbMaxValueData
  590. NULL, // lpcbSecurityDescriptor
  591. &ftLastWriteTime
  592. ))) {
  593. printf("LastWriteTime:: %s\n", FileTimeText(&ftLastWriteTime));
  594. }
  595. }
  596. static void DisplayRegSecurityInfo(
  597. IN HKEY hKey,
  598. IN LPCSTR pszKeyBase,
  599. IN LPCSTR pszRegPath,
  600. SECURITY_INFORMATION SecInf,
  601. IN BOOL fRecurse
  602. )
  603. {
  604. PSECURITY_DESCRIPTOR psd = NULL;
  605. printf("%s\\%s\n", pszKeyBase, pszRegPath);
  606. if (NULL == (psd = AllocAndGetSecurityDescriptor(
  607. hKey, SecInf)))
  608. return;
  609. DisplayRegQueryInfo(hKey);
  610. DisplayControl(psd);
  611. DisplayOwnerSecurityInfo(psd);
  612. DisplayGroupSecurityInfo(psd);
  613. DisplayDaclSecurityInfo(psd);
  614. if (SecInf & SACL_SECURITY_INFORMATION)
  615. DisplaySaclSecurityInfo(psd);
  616. TestFree(psd);
  617. if (fRecurse) {
  618. }
  619. }
  620. static void * AllocAndGetTokenInfo(
  621. IN HANDLE hToken,
  622. IN TOKEN_INFORMATION_CLASS tic
  623. )
  624. {
  625. void *pvInfo = NULL;
  626. DWORD cbInfo = 0;
  627. DWORD cbInfo2;
  628. if (!GetTokenInformation(
  629. hToken,
  630. tic,
  631. pvInfo,
  632. 0, // cbInfo
  633. &cbInfo
  634. )) {
  635. if (ERROR_INSUFFICIENT_BUFFER != GetLastError()) {
  636. PrintLastError("GetTokenInformation");
  637. return NULL;
  638. }
  639. }
  640. if (0 == cbInfo) {
  641. printf("No Information\n");
  642. return NULL;
  643. }
  644. if (NULL == (pvInfo = TestAlloc(cbInfo)))
  645. return NULL;
  646. cbInfo2 = cbInfo;
  647. if (!GetTokenInformation(
  648. hToken,
  649. tic,
  650. pvInfo,
  651. cbInfo,
  652. &cbInfo2
  653. )) {
  654. PrintLastError("GetTokenInformation");
  655. TestFree(pvInfo);
  656. return NULL;
  657. }
  658. return pvInfo;
  659. }
  660. static void GetProcessTokenInfo()
  661. {
  662. HANDLE hToken = NULL;
  663. void *pvInfo = NULL;
  664. printf("Get Process Token Information\n\n");
  665. if (!OpenProcessToken(
  666. GetCurrentProcess(),
  667. TOKEN_QUERY,
  668. &hToken
  669. )) {
  670. PrintLastError("OpenProcessToken");
  671. goto ErrorReturn;
  672. }
  673. printf("TokenUser: ");
  674. if (pvInfo = AllocAndGetTokenInfo(hToken, TokenUser)) {
  675. PTOKEN_USER pTokenUser = (PTOKEN_USER) pvInfo;
  676. if (pTokenUser->User.Attributes)
  677. printf("Attributes(0x%x) ", pTokenUser->User.Attributes);
  678. DisplaySid(pTokenUser->User.Sid);
  679. TestFree(pvInfo);
  680. pvInfo = NULL;
  681. }
  682. printf("TokenOwner: ");
  683. if (pvInfo = AllocAndGetTokenInfo(hToken, TokenOwner)) {
  684. PTOKEN_OWNER pTokenOwner = (PTOKEN_OWNER) pvInfo;
  685. DisplaySid(pTokenOwner->Owner);
  686. TestFree(pvInfo);
  687. pvInfo = NULL;
  688. }
  689. printf("TokenPrimaryGroup: ");
  690. if (pvInfo = AllocAndGetTokenInfo(hToken, TokenPrimaryGroup)) {
  691. PTOKEN_PRIMARY_GROUP pTokenPrimaryGroup = (PTOKEN_PRIMARY_GROUP) pvInfo;
  692. DisplaySid(pTokenPrimaryGroup->PrimaryGroup);
  693. TestFree(pvInfo);
  694. pvInfo = NULL;
  695. }
  696. printf("TokenGroups\n");
  697. if (pvInfo = AllocAndGetTokenInfo(hToken, TokenGroups)) {
  698. PTOKEN_GROUPS pTokenGroups = (PTOKEN_GROUPS) pvInfo;
  699. DWORD GroupCount = pTokenGroups->GroupCount;
  700. if (0 == GroupCount)
  701. printf(" No Groups\n");
  702. else {
  703. DWORD i;
  704. for (i = 0; i < GroupCount; i++) {
  705. printf(" Group[%d]: ", i);
  706. if (pTokenGroups->Groups[i].Attributes)
  707. printf("Attributes(0x%x) ",
  708. pTokenGroups->Groups[i].Attributes);
  709. DisplaySid(pTokenGroups->Groups[i].Sid);
  710. }
  711. }
  712. TestFree(pvInfo);
  713. pvInfo = NULL;
  714. }
  715. printf("TokenPrivileges\n");
  716. if (pvInfo = AllocAndGetTokenInfo(hToken, TokenPrivileges)) {
  717. PTOKEN_PRIVILEGES pTokenPrivileges = (PTOKEN_PRIVILEGES) pvInfo;
  718. DWORD PrivilegeCount = pTokenPrivileges->PrivilegeCount;
  719. if (0 == PrivilegeCount)
  720. printf(" No Privileges\n");
  721. else {
  722. DWORD i;
  723. for (i = 0; i < PrivilegeCount; i++) {
  724. char szName[_MAX_PATH];
  725. DWORD cchName;
  726. printf(" Privilege[%d]: ", i);
  727. if (pTokenPrivileges->Privileges[i].Attributes)
  728. printf("Attributes(0x%x) ",
  729. pTokenPrivileges->Privileges[i].Attributes);
  730. cchName = sizeof(szName);
  731. if (LookupPrivilegeName(
  732. NULL, // pszSystemName
  733. &pTokenPrivileges->Privileges[i].Luid,
  734. szName,
  735. &cchName
  736. ))
  737. printf("%s\n", szName);
  738. else
  739. PrintLastError("LookupPrivlegeName");
  740. }
  741. }
  742. TestFree(pvInfo);
  743. pvInfo = NULL;
  744. }
  745. printf("TokenDefaultDacl\n");
  746. if (pvInfo = AllocAndGetTokenInfo(hToken, TokenDefaultDacl)) {
  747. PTOKEN_DEFAULT_DACL pTokenDacl = (PTOKEN_DEFAULT_DACL) pvInfo;
  748. DisplayAcl(TRUE, pTokenDacl->DefaultDacl, FALSE);
  749. TestFree(pvInfo);
  750. pvInfo = NULL;
  751. }
  752. ErrorReturn:
  753. if (hToken)
  754. CloseHandle(hToken);
  755. TestFree(pvInfo);
  756. }
  757. static void SetOwner(
  758. IN HKEY hKeyBase,
  759. IN LPCSTR pszRegPath
  760. )
  761. {
  762. LONG err;
  763. HKEY hKey = NULL;
  764. HANDLE hToken = NULL;
  765. void *pvInfo = NULL;
  766. SECURITY_DESCRIPTOR sd;
  767. PSID pSid; // not allocated
  768. printf("SetOwner\n");
  769. if (!SetCurrentPrivilege(SE_TAKE_OWNERSHIP_NAME, TRUE))
  770. PrintLastError("SetCurrentPrivilege(SE_TAKE_OWNERSHIP_NAME)");
  771. if (ERROR_SUCCESS != (err = RegOpenKeyExA(
  772. hKeyBase,
  773. pszRegPath,
  774. 0, // dwReserved
  775. WRITE_OWNER,
  776. &hKey))) {
  777. if (ERROR_FILE_NOT_FOUND == err) {
  778. DWORD dwDisposition;
  779. if (ERROR_SUCCESS == (err = RegCreateKeyExA(
  780. hKeyBase,
  781. pszRegPath,
  782. 0, // dwReserved
  783. NULL, // lpClass
  784. REG_OPTION_NON_VOLATILE,
  785. WRITE_OWNER,
  786. NULL, // lpSecurityAttributes
  787. &hKey,
  788. &dwDisposition)))
  789. printf("Created Subkey\n");
  790. }
  791. }
  792. if (ERROR_SUCCESS != err) {
  793. PrintLastError("RegOpenKeyExA(WRITE_OWNER)", err);
  794. hKey = NULL;
  795. goto ErrorReturn;
  796. }
  797. if (!InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION)) {
  798. PrintLastError("InitializeSecurityDescriptor");
  799. goto ErrorReturn;
  800. }
  801. if (!OpenProcessToken(
  802. GetCurrentProcess(),
  803. TOKEN_QUERY,
  804. &hToken
  805. )) {
  806. PrintLastError("OpenProcessToken");
  807. goto ErrorReturn;
  808. }
  809. if (NULL == (pvInfo = AllocAndGetTokenInfo(hToken, TokenUser)))
  810. goto ErrorReturn;
  811. else {
  812. PTOKEN_USER pTokenUser = (PTOKEN_USER) pvInfo;
  813. pSid = pTokenUser->User.Sid;
  814. }
  815. if (!SetSecurityDescriptorOwner(&sd, pSid, FALSE)) {
  816. PrintLastError("SetSecurityDescriptorOwner");
  817. goto ErrorReturn;
  818. }
  819. if (ERROR_SUCCESS != (err = RegSetKeySecurity(
  820. hKey,
  821. OWNER_SECURITY_INFORMATION,
  822. &sd
  823. ))) {
  824. PrintLastError("RegSetKeySecurity(OWNER)", err);
  825. goto ErrorReturn;
  826. }
  827. ErrorReturn:
  828. if (hKey)
  829. RegCloseKey(hKey);
  830. if (hToken)
  831. CloseHandle(hToken);
  832. TestFree(pvInfo);
  833. }
  834. static void SetGroupDaclSacl(
  835. IN HKEY hKeyBase,
  836. IN LPCSTR pszRegPath
  837. )
  838. {
  839. LONG err;
  840. HKEY hKey = NULL;
  841. HANDLE hToken = NULL;
  842. void *pvGroupInfo = NULL;
  843. void *pvUserInfo = NULL;
  844. SECURITY_DESCRIPTOR sd;
  845. SID_IDENTIFIER_AUTHORITY siaNtAuthority = SECURITY_NT_AUTHORITY;
  846. SID_IDENTIFIER_AUTHORITY siaWorldSidAuthority =
  847. SECURITY_WORLD_SID_AUTHORITY;
  848. PSID psidLocalSystem = NULL;
  849. PSID psidAdministrators = NULL;
  850. PSID psidEveryone = NULL;
  851. PSID psidUser; // Not allocated
  852. PACL pDacl = NULL;
  853. PACCESS_ALLOWED_ACE pAce;
  854. DWORD dwAclSize;
  855. DWORD i;
  856. SECURITY_INFORMATION SecInf = DACL_SECURITY_INFORMATION |
  857. GROUP_SECURITY_INFORMATION;
  858. REGSAM samDesired = WRITE_OWNER | WRITE_DAC;
  859. printf("SetGroupDaclSacl\n");
  860. if (!InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION)) {
  861. PrintLastError("InitializeSecurityDescriptor");
  862. goto ErrorReturn;
  863. }
  864. if (!SetCurrentPrivilege(SE_SECURITY_NAME, TRUE))
  865. PrintLastError("SetCurrentPrivilege(SE_SECURITY_NAME)");
  866. else {
  867. SecInf |= SACL_SECURITY_INFORMATION;
  868. samDesired |= ACCESS_SYSTEM_SECURITY;
  869. if (!SetSecurityDescriptorSacl(&sd, FALSE, NULL, FALSE)) {
  870. PrintLastError("SetSecurityDescriptorSacl");
  871. goto ErrorReturn;
  872. }
  873. }
  874. if (ERROR_SUCCESS != (err = RegOpenKeyExA(
  875. hKeyBase,
  876. pszRegPath,
  877. 0, // dwReserved
  878. samDesired,
  879. &hKey))) {
  880. PrintLastError("RegOpenKeyExA(WRITE_OWNER | WRITE_DAC)", err);
  881. hKey = NULL;
  882. goto ErrorReturn;
  883. }
  884. if (!OpenProcessToken(
  885. GetCurrentProcess(),
  886. TOKEN_QUERY,
  887. &hToken
  888. )) {
  889. PrintLastError("OpenProcessToken");
  890. goto ErrorReturn;
  891. }
  892. if (NULL == (pvGroupInfo = AllocAndGetTokenInfo(hToken, TokenPrimaryGroup)))
  893. goto ErrorReturn;
  894. else {
  895. PTOKEN_PRIMARY_GROUP pTokenPrimaryGroup =
  896. (PTOKEN_PRIMARY_GROUP) pvGroupInfo;
  897. PSID pSid = pTokenPrimaryGroup->PrimaryGroup;
  898. if (!SetSecurityDescriptorGroup(&sd, pSid, FALSE)) {
  899. PrintLastError("SetSecurityDescriptorGroup");
  900. goto ErrorReturn;
  901. }
  902. }
  903. if (NULL == (pvUserInfo = AllocAndGetTokenInfo(hToken, TokenUser)))
  904. goto ErrorReturn;
  905. else {
  906. PTOKEN_USER pTokenUser = (PTOKEN_USER) pvUserInfo;
  907. psidUser = pTokenUser->User.Sid;
  908. }
  909. //
  910. // prepare the SIDS for LocalSystem, Administrators and Everyone
  911. //
  912. if (!AllocateAndInitializeSid(
  913. &siaNtAuthority,
  914. 1,
  915. SECURITY_LOCAL_SYSTEM_RID,
  916. 0, 0, 0, 0, 0, 0, 0,
  917. &psidLocalSystem
  918. )) {
  919. PrintLastError("AllocateAndInitializeSid(LocalSystem)");
  920. goto ErrorReturn;
  921. }
  922. if (!AllocateAndInitializeSid(
  923. &siaNtAuthority,
  924. 2,
  925. SECURITY_BUILTIN_DOMAIN_RID,
  926. DOMAIN_ALIAS_RID_ADMINS,
  927. 0, 0, 0, 0, 0, 0,
  928. &psidAdministrators
  929. )) {
  930. PrintLastError("AllocateAndInitializeSid(Administrators)");
  931. goto ErrorReturn;
  932. }
  933. if (!AllocateAndInitializeSid(
  934. &siaWorldSidAuthority,
  935. 1,
  936. SECURITY_WORLD_RID,
  937. 0, 0, 0, 0, 0, 0, 0,
  938. &psidEveryone
  939. )) {
  940. PrintLastError("AllocateAndInitializeSid(Everyone)");
  941. goto ErrorReturn;
  942. }
  943. //
  944. // compute size of new acl
  945. //
  946. dwAclSize = sizeof(ACL) +
  947. 4 * ( sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD) ) +
  948. GetLengthSid(psidLocalSystem) +
  949. GetLengthSid(psidAdministrators) +
  950. GetLengthSid(psidEveryone) +
  951. GetLengthSid(psidUser)
  952. ;
  953. //
  954. // allocate storage for Acl
  955. //
  956. if (NULL == (pDacl = (PACL) TestAlloc(dwAclSize)))
  957. goto ErrorReturn;
  958. if (!InitializeAcl(pDacl, dwAclSize, ACL_REVISION)) {
  959. PrintLastError("InitializeAcl");
  960. goto ErrorReturn;
  961. }
  962. if (!AddAccessAllowedAce(
  963. pDacl,
  964. ACL_REVISION,
  965. KEY_ALL_ACCESS,
  966. psidLocalSystem
  967. )) {
  968. PrintLastError("AddAccessAllowedAce(LocalSystem)");
  969. goto ErrorReturn;
  970. }
  971. if (!AddAccessAllowedAce(
  972. pDacl,
  973. ACL_REVISION,
  974. KEY_ALL_ACCESS,
  975. psidAdministrators
  976. )) {
  977. PrintLastError("AddAccessAllowedAce(Administrators)");
  978. goto ErrorReturn;
  979. }
  980. if (!AddAccessAllowedAce(
  981. pDacl,
  982. ACL_REVISION,
  983. KEY_READ,
  984. psidEveryone
  985. )) {
  986. PrintLastError("AddAccessAllowedAce(Everyone)");
  987. goto ErrorReturn;
  988. }
  989. if (!AddAccessAllowedAce(
  990. pDacl,
  991. ACL_REVISION,
  992. KEY_ALL_ACCESS,
  993. psidUser
  994. )) {
  995. PrintLastError("AddAccessAllowedAce(User)");
  996. goto ErrorReturn;
  997. }
  998. //
  999. // make containers inherit.
  1000. //
  1001. for (i = 0; i < 4; i++) {
  1002. if(!GetAce(pDacl, i, (void **) &pAce)) {
  1003. PrintLastError("GetAce");
  1004. goto ErrorReturn;
  1005. }
  1006. pAce->Header.AceFlags = CONTAINER_INHERIT_ACE;
  1007. }
  1008. if (!SetSecurityDescriptorDacl(&sd, TRUE, pDacl, FALSE)) {
  1009. PrintLastError("SetSecurityDescriptorDacl");
  1010. goto ErrorReturn;
  1011. }
  1012. if (ERROR_SUCCESS != (err = RegSetKeySecurity(
  1013. hKey,
  1014. SecInf,
  1015. &sd
  1016. ))) {
  1017. PrintLastError("RegSetKeySecurity(Group, DACL, SACL)", err);
  1018. goto ErrorReturn;
  1019. }
  1020. ErrorReturn:
  1021. if (hKey)
  1022. RegCloseKey(hKey);
  1023. if (hToken)
  1024. CloseHandle(hToken);
  1025. TestFree(pvGroupInfo);
  1026. TestFree(pvUserInfo);
  1027. if (psidLocalSystem)
  1028. FreeSid(psidLocalSystem);
  1029. if (psidAdministrators)
  1030. FreeSid(psidAdministrators);
  1031. if (psidEveryone)
  1032. FreeSid(psidEveryone);
  1033. TestFree(pDacl);
  1034. }
  1035. #define PROT_ROOT_SUBKEY_NAME L"ProtectedRoots"
  1036. #define SYSTEM_STORE_REGPATH L"Software\\Microsoft\\SystemCertificates"
  1037. #define PROT_ROOT_REGPATH \
  1038. SYSTEM_STORE_REGPATH L"\\Root\\" PROT_ROOT_SUBKEY_NAME
  1039. #define PSID_PROT_OWNER psidAdministrators
  1040. #define PSID_PROT_SYSTEM psidLocalSystem
  1041. #define PSID_PROT_EVERYONE psidEveryone
  1042. //+-------------------------------------------------------------------------
  1043. // ACL definitions used to set security on the "ProtectedRoots" SubKey.
  1044. //--------------------------------------------------------------------------
  1045. #define PROT_SYSTEM_ACE_MASK KEY_ALL_ACCESS
  1046. #define PROT_EVERYONE_ACE_MASK KEY_READ
  1047. #define PROT_ACE_FLAGS CONTAINER_INHERIT_ACE
  1048. #define PROT_ACE_COUNT 2
  1049. #define PROT_SYSTEM_ACE_INDEX 0
  1050. #define PROT_EVERYONE_ACE_INDEX 1
  1051. static void CheckProtectedRoots()
  1052. {
  1053. LONG lErr;
  1054. HKEY hKeyProtRoot = NULL;
  1055. PSECURITY_DESCRIPTOR psd = NULL;
  1056. PSID psidOwner; // not allocated
  1057. BOOL fOwnerDefaulted;
  1058. BOOL fDaclPresent;
  1059. PACL pAcl; // not allocated
  1060. BOOL fDaclDefaulted;
  1061. DWORD dwAceIndex;
  1062. PACCESS_ALLOWED_ACE rgpAce[PROT_ACE_COUNT];
  1063. PSID psidLocalSystem = NULL;
  1064. PSID psidAdministrators = NULL;
  1065. PSID psidEveryone = NULL;
  1066. SID_IDENTIFIER_AUTHORITY siaNtAuthority = SECURITY_NT_AUTHORITY;
  1067. SID_IDENTIFIER_AUTHORITY siaWorldSidAuthority =
  1068. SECURITY_WORLD_SID_AUTHORITY;
  1069. if (ERROR_SUCCESS != (lErr = RegOpenKeyExU(
  1070. HKEY_CURRENT_USER,
  1071. PROT_ROOT_REGPATH,
  1072. 0, // dwReserved
  1073. KEY_READ,
  1074. &hKeyProtRoot))) {
  1075. PrintLastError("OpenProtectedRootKey", lErr);
  1076. goto ErrorReturn;
  1077. }
  1078. if (NULL == (psd = AllocAndGetSecurityDescriptor(
  1079. hKeyProtRoot,
  1080. OWNER_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION
  1081. )))
  1082. goto ErrorReturn;
  1083. //
  1084. // prepare the SIDS for LocalSystem, Administrators and Everyone
  1085. //
  1086. if (!AllocateAndInitializeSid(
  1087. &siaNtAuthority,
  1088. 1,
  1089. SECURITY_LOCAL_SYSTEM_RID,
  1090. 0, 0, 0, 0, 0, 0, 0,
  1091. &psidLocalSystem
  1092. )) {
  1093. PrintLastError("AllocateAndInitializeSid(LocalSystem)");
  1094. goto ErrorReturn;
  1095. }
  1096. if (!AllocateAndInitializeSid(
  1097. &siaNtAuthority,
  1098. 2,
  1099. SECURITY_BUILTIN_DOMAIN_RID,
  1100. DOMAIN_ALIAS_RID_ADMINS,
  1101. 0, 0, 0, 0, 0, 0,
  1102. &psidAdministrators
  1103. )) {
  1104. PrintLastError("AllocateAndInitializeSid(Administrators)");
  1105. goto ErrorReturn;
  1106. }
  1107. if (!AllocateAndInitializeSid(
  1108. &siaWorldSidAuthority,
  1109. 1,
  1110. SECURITY_WORLD_RID,
  1111. 0, 0, 0, 0, 0, 0, 0,
  1112. &psidEveryone
  1113. )) {
  1114. PrintLastError("AllocateAndInitializeSid(Everyone)");
  1115. goto ErrorReturn;
  1116. }
  1117. // Verify owner
  1118. if (!GetSecurityDescriptorOwner(psd, &psidOwner, &fOwnerDefaulted)) {
  1119. PrintLastError("GetSecurityDescriptorOwner");
  1120. goto ErrorReturn;
  1121. }
  1122. if (NULL == psidOwner || !EqualSid(psidOwner, PSID_PROT_OWNER)) {
  1123. printf("failed => invalid Owner\n");
  1124. goto ErrorReturn;
  1125. }
  1126. // Verify DACL
  1127. if (!GetSecurityDescriptorDacl(psd, &fDaclPresent, &pAcl,
  1128. &fDaclDefaulted)) {
  1129. PrintLastError("GetSecurityDescriptorDacl");
  1130. goto ErrorReturn;
  1131. }
  1132. if (!fDaclPresent || NULL == pAcl) {
  1133. printf("failed => missing Dacl\n");
  1134. goto ErrorReturn;
  1135. }
  1136. if (PROT_ACE_COUNT != pAcl->AceCount) {
  1137. printf("failed => invalid AceCount\n");
  1138. goto ErrorReturn;
  1139. }
  1140. for (dwAceIndex = 0; dwAceIndex < PROT_ACE_COUNT; dwAceIndex++) {
  1141. PACCESS_ALLOWED_ACE pAce;
  1142. if (!GetAce(pAcl, dwAceIndex, (void **) &pAce)) {
  1143. printf("failed => invalid Acl\n");
  1144. goto ErrorReturn;
  1145. }
  1146. rgpAce[dwAceIndex] = pAce;
  1147. if (ACCESS_ALLOWED_ACE_TYPE != pAce->Header.AceType ||
  1148. PROT_ACE_FLAGS != pAce->Header.AceFlags) {
  1149. printf("failed => invalid Acl\n");
  1150. goto ErrorReturn;
  1151. }
  1152. }
  1153. if (PROT_SYSTEM_ACE_MASK != rgpAce[PROT_SYSTEM_ACE_INDEX]->Mask ||
  1154. !EqualSid(PSID_PROT_SYSTEM,
  1155. (PSID) &rgpAce[PROT_SYSTEM_ACE_INDEX]->SidStart) ||
  1156. PROT_EVERYONE_ACE_MASK != rgpAce[PROT_EVERYONE_ACE_INDEX]->Mask ||
  1157. !EqualSid(PSID_PROT_EVERYONE,
  1158. (PSID) &rgpAce[PROT_EVERYONE_ACE_INDEX]->SidStart)) {
  1159. printf("failed => invalid Acl\n");
  1160. goto ErrorReturn;
  1161. }
  1162. printf("Success => ProtectedRoots has correct ACLs\n");
  1163. CommonReturn:
  1164. if (psidLocalSystem)
  1165. FreeSid(psidLocalSystem);
  1166. if (psidAdministrators)
  1167. FreeSid(psidAdministrators);
  1168. if (psidEveryone)
  1169. FreeSid(psidEveryone);
  1170. TestFree(psd);
  1171. if (hKeyProtRoot)
  1172. RegCloseKey(hKeyProtRoot);
  1173. return;
  1174. ErrorReturn:
  1175. printf("Failed => ProtectedRoots has the following BAD ACLs\n");
  1176. if (hKeyProtRoot)
  1177. DisplayRegQueryInfo(hKeyProtRoot);
  1178. if (psd) {
  1179. DisplayControl(psd);
  1180. DisplayOwnerSecurityInfo(psd);
  1181. DisplayGroupSecurityInfo(psd);
  1182. DisplayDaclSecurityInfo(psd);
  1183. }
  1184. goto CommonReturn;
  1185. }
  1186. int _cdecl main(int argc, char * argv[])
  1187. {
  1188. int status;
  1189. #define TEST_NAME_INDEX 0
  1190. #define PATH_NAME_INDEX 1
  1191. #define MAX_NAME_CNT 2
  1192. DWORD dwNameCnt = 0;
  1193. LPCSTR rgpszName[MAX_NAME_CNT];
  1194. LPCSTR pszTestName; // not allocated
  1195. LPCSTR pszRegPath; // not allocated
  1196. HKEY hKeyBase = HKEY_CURRENT_USER;
  1197. LPCSTR pszKeyBase = "HKEY_CURRENT_USER";
  1198. BOOL fRecurse = FALSE;
  1199. HKEY hKey = NULL;
  1200. while (--argc>0) {
  1201. if (**++argv == '-')
  1202. {
  1203. switch(argv[0][1])
  1204. {
  1205. case 'l':
  1206. if (argv[0][2]) {
  1207. if (0 == _stricmp(argv[0]+2, "CU")) {
  1208. hKeyBase = HKEY_CURRENT_USER;
  1209. pszKeyBase = "HKEY_CURRENT_USER";
  1210. } else if (0 == _stricmp(argv[0]+2, "LM")) {
  1211. hKeyBase = HKEY_LOCAL_MACHINE;
  1212. pszKeyBase = "HKEY_LOCAL_MACHINE";
  1213. } else {
  1214. printf("Need to specify -lCU or -lLM\n");
  1215. goto BadUsage;
  1216. }
  1217. } else {
  1218. printf("Need to specify -lCU or -lLM\n");
  1219. goto BadUsage;
  1220. }
  1221. break;
  1222. case 'r':
  1223. fRecurse = TRUE;
  1224. break;
  1225. case 'h':
  1226. default:
  1227. goto BadUsage;
  1228. }
  1229. } else {
  1230. if (MAX_NAME_CNT <= dwNameCnt) {
  1231. printf("Too many names starting with:: %s\n", argv[0]);
  1232. goto BadUsage;
  1233. }
  1234. rgpszName[dwNameCnt++] = argv[0];
  1235. }
  1236. }
  1237. printf("command line: %s\n", GetCommandLine());
  1238. if (0 == dwNameCnt) {
  1239. printf("Missing <TestName>\n");
  1240. goto BadUsage;
  1241. } else
  1242. pszTestName = rgpszName[TEST_NAME_INDEX];
  1243. if (0 == _stricmp("PurgeLMRoots", pszTestName)) {
  1244. printf("Purge LocalMachine Duplicate Roots from CurrentUser\n");
  1245. if (!I_CertProtectFunction(
  1246. CERT_PROT_PURGE_LM_ROOTS_FUNC_ID,
  1247. 0, // dwFlags
  1248. NULL, // pwszIn
  1249. NULL, // pbIn
  1250. 0, // cbIn
  1251. NULL, // ppbOut
  1252. NULL // pcbOut
  1253. ))
  1254. PrintLastError(
  1255. "I_CertProtectFunction(CERT_PROT_PURGE_LM_ROOTS_FUNC_ID)");
  1256. goto SuccessReturn;
  1257. } else if (0 == _stricmp("DeleteUnknownRoots", pszTestName)) {
  1258. printf("Delete unknown CurrentUser roots from Protected List\n");
  1259. if (!I_CertProtectFunction(
  1260. CERT_PROT_DELETE_UNKNOWN_ROOTS_FUNC_ID,
  1261. 0, // dwFlags
  1262. NULL, // pwszIn
  1263. NULL, // pbIn
  1264. 0, // cbIn
  1265. NULL, // ppbOut
  1266. NULL // pcbOut
  1267. ))
  1268. PrintLastError(
  1269. "I_CertProtectFunction(CERT_PROT_DELETE_UNKNOWN_ROOTS_FUNC_ID)");
  1270. goto SuccessReturn;
  1271. } else if (0 == _stricmp("CheckProtectedRoots", pszTestName)) {
  1272. printf("Check ProtectedRoots ACLs\n");
  1273. CheckProtectedRoots();
  1274. goto SuccessReturn;
  1275. } else if (0 == _stricmp("ServiceUI", pszTestName)) {
  1276. BYTE *pbOut = NULL;
  1277. DWORD cbOut = 0;
  1278. printf("Certificate Protect Service UI\n");
  1279. if (!I_CertProtectFunction(
  1280. 1000,
  1281. 0, // dwFlags
  1282. L"Root test", // pwszIn
  1283. NULL, // pbIn
  1284. 0, // cbIn
  1285. &pbOut,
  1286. &cbOut
  1287. ))
  1288. PrintLastError("I_CertProtectFunction(UI)");
  1289. else if (pbOut) {
  1290. PrintBytes("DataOut", pbOut, cbOut);
  1291. CryptMemFree(pbOut);
  1292. }
  1293. goto SuccessReturn;
  1294. } else if (0 == _stricmp("ServiceTokenInfo", pszTestName)) {
  1295. BYTE *pbOut = NULL;
  1296. DWORD cbOut = 0;
  1297. printf("Certificate Protect Service's Token Info\n");
  1298. if (!I_CertProtectFunction(
  1299. 1001,
  1300. 0, // dwFlags
  1301. NULL, // pwszIn
  1302. NULL, // pbIn
  1303. 0, // cbIn
  1304. &pbOut,
  1305. &cbOut
  1306. ))
  1307. PrintLastError("I_CertProtectFunction(GetTokenInfo)");
  1308. else if (pbOut) {
  1309. if (cbOut)
  1310. puts((LPCSTR) pbOut);
  1311. CryptMemFree(pbOut);
  1312. }
  1313. goto SuccessReturn;
  1314. } else if (0 == _stricmp("ServiceInvalid", pszTestName)) {
  1315. printf("Calling Invalid Certificate Protect Function\n");
  1316. if (!I_CertProtectFunction(
  1317. 1002,
  1318. 0, // dwFlags
  1319. NULL, // pwszIn
  1320. NULL, // pbIn
  1321. 0, // cbIn
  1322. NULL, // ppbOut
  1323. NULL // pcbOut
  1324. ))
  1325. PrintLastError("I_CertProtectFunction(1002)");
  1326. goto SuccessReturn;
  1327. } else if (1 == dwNameCnt) {
  1328. printf("Missing <RegPath>\n");
  1329. goto BadUsage;
  1330. } else
  1331. pszRegPath = rgpszName[PATH_NAME_INDEX];
  1332. printf("\n");
  1333. if (0 == _stricmp("GetKey", pszTestName)) {
  1334. LONG err;
  1335. REGSAM samDesired = READ_CONTROL | ACCESS_SYSTEM_SECURITY;
  1336. SECURITY_INFORMATION SecInf = OWNER_SECURITY_INFORMATION |
  1337. GROUP_SECURITY_INFORMATION |
  1338. DACL_SECURITY_INFORMATION |
  1339. SACL_SECURITY_INFORMATION;
  1340. if (!SetCurrentPrivilege(SE_SECURITY_NAME, TRUE)) {
  1341. PrintLastError("SetCurrentPrivilege(SE_SECURITY_NAME)");
  1342. samDesired = READ_CONTROL;
  1343. SecInf &= ~SACL_SECURITY_INFORMATION;
  1344. }
  1345. if (!SetCurrentPrivilege(SE_TAKE_OWNERSHIP_NAME, TRUE))
  1346. PrintLastError("SetCurrentPrivilege(SE_TAKE_OWNERSHIP_NAME)");
  1347. GetProcessTokenInfo();
  1348. printf("\n\nGet Registry Key Security Information\n\n");
  1349. if (ERROR_SUCCESS != (err = RegOpenKeyExA(
  1350. hKeyBase,
  1351. pszRegPath,
  1352. 0, // dwReserved
  1353. KEY_READ | samDesired,
  1354. &hKey))) {
  1355. if (ERROR_ACCESS_DENIED == err) {
  1356. if (ERROR_SUCCESS == (err = RegOpenKeyExA(
  1357. hKeyBase,
  1358. pszRegPath,
  1359. 0, // dwReserved
  1360. samDesired,
  1361. &hKey))) {
  1362. printf("No Read Access\n");
  1363. fRecurse = FALSE;
  1364. }
  1365. }
  1366. }
  1367. if (ERROR_SUCCESS != err) {
  1368. printf("RegOpenKeyExA(%s\\%s) failed => 0x%x (%d)\n",
  1369. pszKeyBase, pszRegPath, err, err);
  1370. hKey = NULL;
  1371. } else
  1372. DisplayRegSecurityInfo(
  1373. hKey,
  1374. pszKeyBase,
  1375. pszRegPath,
  1376. SecInf,
  1377. fRecurse
  1378. );
  1379. } else if (0 == _stricmp("SetKey", pszTestName)) {
  1380. printf("Set Registry Key Security Information\n\n");
  1381. SetOwner(hKeyBase, pszRegPath);
  1382. SetGroupDaclSacl(hKeyBase, pszRegPath);
  1383. } else {
  1384. printf("Invalid TestName: %s\n", pszTestName);
  1385. goto BadUsage;
  1386. }
  1387. SuccessReturn:
  1388. status = 0;
  1389. CommonReturn:
  1390. if (hKey)
  1391. RegCloseKey(hKey);
  1392. return status;
  1393. BadUsage:
  1394. Usage();
  1395. status = -1;
  1396. goto CommonReturn;
  1397. }