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.

964 lines
24 KiB

  1. #include "windows.h"
  2. #include <stdio.h>
  3. #include <tchar.h>
  4. #include <string.h>
  5. #include <conio.h>
  6. #include "dcomperm.h"
  7. #define _WIN32_DCOM
  8. #include <objbase.h>
  9. DWORD
  10. CopyACL (
  11. PACL OldACL,
  12. PACL NewACL
  13. )
  14. {
  15. ACL_SIZE_INFORMATION aclSizeInfo;
  16. LPVOID ace;
  17. ACE_HEADER *aceHeader;
  18. ULONG i;
  19. GetAclInformation (OldACL, (LPVOID) &aclSizeInfo, (DWORD) sizeof (aclSizeInfo), AclSizeInformation);
  20. //
  21. // Copy all of the ACEs to the new ACL
  22. //
  23. for (i = 0; i < aclSizeInfo.AceCount; i++)
  24. {
  25. //
  26. // Get the ACE and header info
  27. //
  28. if (!GetAce (OldACL, i, &ace))
  29. return GetLastError();
  30. aceHeader = (ACE_HEADER *) ace;
  31. //
  32. // Add the ACE to the new list
  33. //
  34. if (!AddAce (NewACL, ACL_REVISION, 0xffffffff, ace, aceHeader->AceSize))
  35. return GetLastError();
  36. }
  37. return ERROR_SUCCESS;
  38. }
  39. DWORD
  40. AddAccessDeniedACEToACL (
  41. PACL *Acl,
  42. DWORD PermissionMask,
  43. LPTSTR Principal
  44. )
  45. {
  46. ACL_SIZE_INFORMATION aclSizeInfo;
  47. int aclSize;
  48. DWORD returnValue = ERROR_SUCCESS;
  49. PSID principalSID = NULL;
  50. PACL oldACL, newACL;
  51. BOOL bWellKnownSID = FALSE;
  52. oldACL = *Acl;
  53. returnValue = GetPrincipalSID (Principal, &principalSID, &bWellKnownSID);
  54. if (returnValue != ERROR_SUCCESS)
  55. return returnValue;
  56. GetAclInformation (oldACL, (LPVOID) &aclSizeInfo, (DWORD) sizeof (ACL_SIZE_INFORMATION), AclSizeInformation);
  57. aclSize = aclSizeInfo.AclBytesInUse +
  58. sizeof (ACL) + sizeof (ACCESS_DENIED_ACE) +
  59. GetLengthSid (principalSID) - sizeof (DWORD);
  60. newACL = (PACL) new BYTE [aclSize];
  61. if (!InitializeAcl (newACL, aclSize, ACL_REVISION))
  62. {
  63. returnValue = GetLastError();
  64. goto cleanup;
  65. }
  66. if (!AddAccessDeniedAce (newACL, ACL_REVISION2, PermissionMask, principalSID))
  67. {
  68. returnValue = GetLastError();
  69. goto cleanup;
  70. }
  71. returnValue = CopyACL (oldACL, newACL);
  72. if (returnValue != ERROR_SUCCESS)
  73. {
  74. goto cleanup;
  75. }
  76. *Acl = newACL;
  77. cleanup:
  78. if (principalSID) {
  79. if (bWellKnownSID)
  80. FreeSid (principalSID);
  81. else
  82. free (principalSID);
  83. }
  84. return returnValue;
  85. }
  86. DWORD
  87. AddAccessAllowedACEToACL (
  88. PACL *Acl,
  89. DWORD PermissionMask,
  90. LPTSTR Principal
  91. )
  92. {
  93. ACL_SIZE_INFORMATION aclSizeInfo;
  94. int aclSize;
  95. DWORD returnValue = ERROR_SUCCESS;
  96. PSID principalSID = NULL;
  97. PACL oldACL, newACL;
  98. BOOL bWellKnownSID = FALSE;
  99. oldACL = *Acl;
  100. returnValue = GetPrincipalSID (Principal, &principalSID, &bWellKnownSID);
  101. if (returnValue != ERROR_SUCCESS)
  102. return returnValue;
  103. GetAclInformation (oldACL, (LPVOID) &aclSizeInfo, (DWORD) sizeof (ACL_SIZE_INFORMATION), AclSizeInformation);
  104. aclSize = aclSizeInfo.AclBytesInUse +
  105. sizeof (ACL) + sizeof (ACCESS_ALLOWED_ACE) +
  106. GetLengthSid (principalSID) - sizeof (DWORD);
  107. newACL = (PACL) new BYTE [aclSize];
  108. if (!InitializeAcl (newACL, aclSize, ACL_REVISION))
  109. {
  110. returnValue = GetLastError();
  111. goto cleanup;
  112. }
  113. returnValue = CopyACL (oldACL, newACL);
  114. if (returnValue != ERROR_SUCCESS)
  115. {
  116. goto cleanup;
  117. }
  118. if (!AddAccessAllowedAce (newACL, ACL_REVISION2, PermissionMask, principalSID))
  119. {
  120. returnValue = GetLastError();
  121. goto cleanup;
  122. }
  123. *Acl = newACL;
  124. cleanup:
  125. if (principalSID) {
  126. if (bWellKnownSID)
  127. FreeSid (principalSID);
  128. else
  129. free (principalSID);
  130. }
  131. return returnValue;
  132. }
  133. DWORD
  134. RemovePrincipalFromACL (
  135. PACL Acl,
  136. LPTSTR Principal
  137. )
  138. {
  139. ACL_SIZE_INFORMATION aclSizeInfo;
  140. ULONG i;
  141. LPVOID ace;
  142. ACCESS_ALLOWED_ACE *accessAllowedAce;
  143. ACCESS_DENIED_ACE *accessDeniedAce;
  144. SYSTEM_AUDIT_ACE *systemAuditAce;
  145. PSID principalSID = NULL;
  146. DWORD returnValue = ERROR_SUCCESS;
  147. ACE_HEADER *aceHeader;
  148. BOOL bWellKnownSID = FALSE;
  149. returnValue = GetPrincipalSID (Principal, &principalSID, &bWellKnownSID);
  150. if (returnValue != ERROR_SUCCESS)
  151. return returnValue;
  152. GetAclInformation (Acl, (LPVOID) &aclSizeInfo, (DWORD) sizeof (ACL_SIZE_INFORMATION), AclSizeInformation);
  153. for (i = 0; i < aclSizeInfo.AceCount; i++)
  154. {
  155. if (!GetAce (Acl, i, &ace))
  156. {
  157. returnValue = GetLastError();
  158. break;
  159. }
  160. aceHeader = (ACE_HEADER *) ace;
  161. if (aceHeader->AceType == ACCESS_ALLOWED_ACE_TYPE)
  162. {
  163. accessAllowedAce = (ACCESS_ALLOWED_ACE *) ace;
  164. if (EqualSid (principalSID, (PSID) &accessAllowedAce->SidStart))
  165. {
  166. DeleteAce (Acl, i);
  167. break;
  168. }
  169. } else
  170. if (aceHeader->AceType == ACCESS_DENIED_ACE_TYPE)
  171. {
  172. accessDeniedAce = (ACCESS_DENIED_ACE *) ace;
  173. if (EqualSid (principalSID, (PSID) &accessDeniedAce->SidStart))
  174. {
  175. DeleteAce (Acl, i);
  176. break;
  177. }
  178. } else
  179. if (aceHeader->AceType == SYSTEM_AUDIT_ACE_TYPE)
  180. {
  181. systemAuditAce = (SYSTEM_AUDIT_ACE *) ace;
  182. if (EqualSid (principalSID, (PSID) &systemAuditAce->SidStart))
  183. {
  184. DeleteAce (Acl, i);
  185. break;
  186. }
  187. }
  188. }
  189. if (principalSID) {
  190. if (bWellKnownSID)
  191. FreeSid (principalSID);
  192. else
  193. free (principalSID);
  194. }
  195. return returnValue;
  196. }
  197. DWORD
  198. GetCurrentUserSID (
  199. PSID *Sid
  200. )
  201. {
  202. DWORD dwReturn = ERROR_SUCCESS;
  203. TOKEN_USER *tokenUser = NULL;
  204. HANDLE tokenHandle = NULL;
  205. DWORD tokenSize;
  206. DWORD sidLength;
  207. if (OpenProcessToken (GetCurrentProcess(), TOKEN_QUERY, &tokenHandle))
  208. {
  209. GetTokenInformation (tokenHandle, TokenUser, tokenUser, 0, &tokenSize);
  210. tokenUser = (TOKEN_USER *) malloc (tokenSize);
  211. if (GetTokenInformation (tokenHandle, TokenUser, tokenUser, tokenSize, &tokenSize))
  212. {
  213. sidLength = GetLengthSid (tokenUser->User.Sid);
  214. *Sid = (PSID) malloc (sidLength);
  215. memcpy (*Sid, tokenUser->User.Sid, sidLength);
  216. CloseHandle (tokenHandle);
  217. } else
  218. dwReturn = GetLastError();
  219. if (tokenUser)
  220. free(tokenUser);
  221. } else
  222. dwReturn = GetLastError();
  223. return dwReturn;
  224. }
  225. DWORD
  226. GetPrincipalSID (
  227. LPTSTR Principal,
  228. PSID *Sid,
  229. BOOL *pbWellKnownSID
  230. )
  231. {
  232. SID_IDENTIFIER_AUTHORITY SidIdentifierNTAuthority = SECURITY_NT_AUTHORITY;
  233. SID_IDENTIFIER_AUTHORITY SidIdentifierWORLDAuthority = SECURITY_WORLD_SID_AUTHORITY;
  234. PSID_IDENTIFIER_AUTHORITY pSidIdentifierAuthority;
  235. BYTE Count;
  236. DWORD dwRID[8];
  237. *pbWellKnownSID = TRUE;
  238. memset(&(dwRID[0]), 0, 8 * sizeof(DWORD));
  239. //_strlwr( Principal);
  240. if ( !strcmp( Principal,"administrators") ) {
  241. // Administrators group
  242. pSidIdentifierAuthority = &SidIdentifierNTAuthority;
  243. Count = 2;
  244. dwRID[0] = SECURITY_BUILTIN_DOMAIN_RID;
  245. dwRID[1] = DOMAIN_ALIAS_RID_ADMINS;
  246. } else if ( !strcmp( Principal, "system") ) {
  247. // SYSTEM
  248. pSidIdentifierAuthority = &SidIdentifierNTAuthority;
  249. Count = 1;
  250. dwRID[0] = SECURITY_LOCAL_SYSTEM_RID;
  251. } else if ( !strcmp( Principal,"interactive") ) {
  252. // INTERACTIVE
  253. pSidIdentifierAuthority = &SidIdentifierNTAuthority;
  254. Count = 1;
  255. dwRID[0] = SECURITY_INTERACTIVE_RID;
  256. } else if ( !strcmp( Principal,"everyone") ) {
  257. // Everyone
  258. pSidIdentifierAuthority = &SidIdentifierWORLDAuthority;
  259. Count = 1;
  260. dwRID[0] = SECURITY_WORLD_RID;
  261. } else {
  262. *pbWellKnownSID = FALSE;
  263. }
  264. if (*pbWellKnownSID) {
  265. if ( !AllocateAndInitializeSid(pSidIdentifierAuthority,
  266. (BYTE)Count,
  267. dwRID[0],
  268. dwRID[1],
  269. dwRID[2],
  270. dwRID[3],
  271. dwRID[4],
  272. dwRID[5],
  273. dwRID[6],
  274. dwRID[7],
  275. Sid) )
  276. return GetLastError();
  277. } else {
  278. // get regular account sid
  279. DWORD sidSize;
  280. TCHAR refDomain [256];
  281. DWORD refDomainSize;
  282. DWORD returnValue;
  283. SID_NAME_USE snu;
  284. sidSize = 0;
  285. refDomainSize = 255;
  286. LookupAccountName (NULL,
  287. Principal,
  288. *Sid,
  289. &sidSize,
  290. refDomain,
  291. &refDomainSize,
  292. &snu);
  293. returnValue = GetLastError();
  294. if (returnValue != ERROR_INSUFFICIENT_BUFFER)
  295. return returnValue;
  296. *Sid = (PSID) malloc (sidSize);
  297. refDomainSize = 255;
  298. if (!LookupAccountName (NULL,
  299. Principal,
  300. *Sid,
  301. &sidSize,
  302. refDomain,
  303. &refDomainSize,
  304. &snu))
  305. {
  306. return GetLastError();
  307. }
  308. }
  309. return ERROR_SUCCESS;
  310. }
  311. DWORD
  312. CreateNewSD (
  313. SECURITY_DESCRIPTOR **SD
  314. )
  315. {
  316. PACL dacl;
  317. DWORD sidLength;
  318. PSID sid;
  319. PSID groupSID;
  320. PSID ownerSID;
  321. DWORD returnValue;
  322. *SD = NULL;
  323. returnValue = GetCurrentUserSID (&sid);
  324. if (returnValue != ERROR_SUCCESS) {
  325. if (sid)
  326. free(sid);
  327. return returnValue;
  328. }
  329. sidLength = GetLengthSid (sid);
  330. *SD = (SECURITY_DESCRIPTOR *) malloc (
  331. (sizeof (ACL)+sizeof (ACCESS_ALLOWED_ACE)+sidLength) +
  332. (2 * sidLength) +
  333. sizeof (SECURITY_DESCRIPTOR));
  334. groupSID = (SID *) (*SD + 1);
  335. ownerSID = (SID *) (((BYTE *) groupSID) + sidLength);
  336. dacl = (ACL *) (((BYTE *) ownerSID) + sidLength);
  337. if (!InitializeSecurityDescriptor (*SD, SECURITY_DESCRIPTOR_REVISION))
  338. {
  339. free (*SD);
  340. free (sid);
  341. return GetLastError();
  342. }
  343. if (!InitializeAcl (dacl,
  344. sizeof (ACL)+sizeof (ACCESS_ALLOWED_ACE)+sidLength,
  345. ACL_REVISION2))
  346. {
  347. free (*SD);
  348. free (sid);
  349. return GetLastError();
  350. }
  351. if (!AddAccessAllowedAce (dacl,
  352. ACL_REVISION2,
  353. COM_RIGHTS_EXECUTE,
  354. sid))
  355. {
  356. free (*SD);
  357. free (sid);
  358. return GetLastError();
  359. }
  360. if (!SetSecurityDescriptorDacl (*SD, TRUE, dacl, FALSE))
  361. {
  362. free (*SD);
  363. free (sid);
  364. return GetLastError();
  365. }
  366. memcpy (groupSID, sid, sidLength);
  367. if (!SetSecurityDescriptorGroup (*SD, groupSID, FALSE))
  368. {
  369. free (*SD);
  370. free (sid);
  371. return GetLastError();
  372. }
  373. memcpy (ownerSID, sid, sidLength);
  374. if (!SetSecurityDescriptorOwner (*SD, ownerSID, FALSE))
  375. {
  376. free (*SD);
  377. free (sid);
  378. return GetLastError();
  379. }
  380. if (sid)
  381. free(sid);
  382. return ERROR_SUCCESS;
  383. }
  384. DWORD
  385. MakeSDAbsolute (
  386. PSECURITY_DESCRIPTOR OldSD,
  387. PSECURITY_DESCRIPTOR *NewSD
  388. )
  389. {
  390. PSECURITY_DESCRIPTOR sd = NULL;
  391. DWORD descriptorSize;
  392. DWORD daclSize;
  393. DWORD saclSize;
  394. DWORD ownerSIDSize;
  395. DWORD groupSIDSize;
  396. PACL dacl = NULL;
  397. PACL sacl = NULL;
  398. PSID ownerSID = NULL;
  399. PSID groupSID = NULL;
  400. BOOL present;
  401. BOOL systemDefault;
  402. //
  403. // Get SACL
  404. //
  405. if (!GetSecurityDescriptorSacl (OldSD, &present, &sacl, &systemDefault))
  406. return GetLastError();
  407. if (sacl && present)
  408. {
  409. saclSize = sacl->AclSize;
  410. } else saclSize = 0;
  411. //
  412. // Get DACL
  413. //
  414. if (!GetSecurityDescriptorDacl (OldSD, &present, &dacl, &systemDefault))
  415. return GetLastError();
  416. if (dacl && present)
  417. {
  418. daclSize = dacl->AclSize;
  419. } else daclSize = 0;
  420. //
  421. // Get Owner
  422. //
  423. if (!GetSecurityDescriptorOwner (OldSD, &ownerSID, &systemDefault))
  424. return GetLastError();
  425. ownerSIDSize = GetLengthSid (ownerSID);
  426. //
  427. // Get Group
  428. //
  429. if (!GetSecurityDescriptorGroup (OldSD, &groupSID, &systemDefault))
  430. return GetLastError();
  431. groupSIDSize = GetLengthSid (groupSID);
  432. //
  433. // Do the conversion
  434. //
  435. descriptorSize = 0;
  436. MakeAbsoluteSD (OldSD, sd, &descriptorSize, dacl, &daclSize, sacl,
  437. &saclSize, ownerSID, &ownerSIDSize, groupSID,
  438. &groupSIDSize);
  439. sd = (PSECURITY_DESCRIPTOR) new BYTE [SECURITY_DESCRIPTOR_MIN_LENGTH];
  440. if (!InitializeSecurityDescriptor (sd, SECURITY_DESCRIPTOR_REVISION))
  441. return GetLastError();
  442. if (!MakeAbsoluteSD (OldSD, sd, &descriptorSize, dacl, &daclSize, sacl,
  443. &saclSize, ownerSID, &ownerSIDSize, groupSID,
  444. &groupSIDSize))
  445. return GetLastError();
  446. *NewSD = sd;
  447. return ERROR_SUCCESS;
  448. }
  449. DWORD
  450. SetNamedValueSD (
  451. HKEY RootKey,
  452. LPTSTR KeyName,
  453. LPTSTR ValueName,
  454. SECURITY_DESCRIPTOR *SD
  455. )
  456. {
  457. DWORD returnValue;
  458. DWORD disposition;
  459. HKEY registryKey;
  460. //
  461. // Create new key or open existing key
  462. //
  463. returnValue = RegCreateKeyEx (RootKey, KeyName, 0, _T(""), 0, KEY_ALL_ACCESS, NULL, &registryKey, &disposition);
  464. if (returnValue != ERROR_SUCCESS)
  465. return returnValue;
  466. //
  467. // Write the security descriptor
  468. //
  469. returnValue = RegSetValueEx (registryKey, ValueName, 0, REG_BINARY, (LPBYTE) SD, GetSecurityDescriptorLength (SD));
  470. if (returnValue != ERROR_SUCCESS)
  471. return returnValue;
  472. RegCloseKey (registryKey);
  473. return ERROR_SUCCESS;
  474. }
  475. DWORD
  476. GetNamedValueSD (
  477. HKEY RootKey,
  478. LPTSTR KeyName,
  479. LPTSTR ValueName,
  480. SECURITY_DESCRIPTOR **SD,
  481. BOOL *NewSD
  482. )
  483. {
  484. DWORD returnValue;
  485. HKEY registryKey;
  486. DWORD valueType;
  487. DWORD valueSize;
  488. *NewSD = FALSE;
  489. //
  490. // Get the security descriptor from the named value. If it doesn't
  491. // exist, create a fresh one.
  492. //
  493. returnValue = RegOpenKeyEx (RootKey, KeyName, 0, KEY_ALL_ACCESS, &registryKey);
  494. if (returnValue != ERROR_SUCCESS)
  495. {
  496. if (returnValue == ERROR_FILE_NOT_FOUND)
  497. {
  498. *SD = NULL;
  499. returnValue = CreateNewSD (SD);
  500. if (returnValue != ERROR_SUCCESS) {
  501. if (*SD)
  502. free(*SD);
  503. return returnValue;
  504. }
  505. *NewSD = TRUE;
  506. return ERROR_SUCCESS;
  507. } else
  508. return returnValue;
  509. }
  510. returnValue = RegQueryValueEx (registryKey, ValueName, NULL, &valueType, NULL, &valueSize);
  511. if (returnValue && returnValue != ERROR_INSUFFICIENT_BUFFER)
  512. {
  513. *SD = NULL;
  514. returnValue = CreateNewSD (SD);
  515. if (returnValue != ERROR_SUCCESS) {
  516. if (*SD)
  517. free(*SD);
  518. return returnValue;
  519. }
  520. *NewSD = TRUE;
  521. } else
  522. {
  523. *SD = (SECURITY_DESCRIPTOR *) malloc (valueSize);
  524. returnValue = RegQueryValueEx (registryKey, ValueName, NULL, &valueType, (LPBYTE) *SD, &valueSize);
  525. if (returnValue)
  526. {
  527. if (*SD)
  528. free (*SD);
  529. *SD = NULL;
  530. returnValue = CreateNewSD (SD);
  531. if (returnValue != ERROR_SUCCESS) {
  532. if (*SD)
  533. free(*SD);
  534. return returnValue;
  535. }
  536. *NewSD = TRUE;
  537. }
  538. }
  539. RegCloseKey (registryKey);
  540. return ERROR_SUCCESS;
  541. }
  542. DWORD
  543. AddPrincipalToNamedValueSD (
  544. HKEY RootKey,
  545. LPTSTR KeyName,
  546. LPTSTR ValueName,
  547. LPTSTR Principal,
  548. BOOL Permit
  549. )
  550. {
  551. DWORD returnValue = ERROR_SUCCESS;
  552. SECURITY_DESCRIPTOR *sd = NULL;
  553. SECURITY_DESCRIPTOR *sdSelfRelative = NULL;
  554. SECURITY_DESCRIPTOR *sdAbsolute = NULL;
  555. DWORD secDescSize;
  556. BOOL present;
  557. BOOL defaultDACL;
  558. PACL dacl;
  559. BOOL newSD = FALSE;
  560. BOOL fFreeAbsolute = TRUE;
  561. returnValue = GetNamedValueSD (RootKey, KeyName, ValueName, &sd, &newSD);
  562. //
  563. // Get security descriptor from registry or create a new one
  564. //
  565. if (returnValue != ERROR_SUCCESS)
  566. return returnValue;
  567. if (!GetSecurityDescriptorDacl (sd, &present, &dacl, &defaultDACL)) {
  568. returnValue = GetLastError();
  569. goto Cleanup;
  570. }
  571. if (newSD)
  572. {
  573. AddAccessAllowedACEToACL (&dacl, COM_RIGHTS_EXECUTE, _T("system"));
  574. #if 0
  575. AddAccessAllowedACEToACL (&dacl, COM_RIGHTS_EXECUTE, _T("INTERACTIVE"));
  576. #endif
  577. }
  578. //
  579. // Add the Principal that the caller wants added
  580. //
  581. if (Permit)
  582. returnValue = AddAccessAllowedACEToACL (&dacl, COM_RIGHTS_EXECUTE, Principal);
  583. else
  584. returnValue = AddAccessDeniedACEToACL (&dacl, GENERIC_ALL, Principal);
  585. if (returnValue != ERROR_SUCCESS)
  586. goto Cleanup;
  587. //
  588. // Make the security descriptor absolute if it isn't new
  589. //
  590. if (!newSD) {
  591. MakeSDAbsolute ((PSECURITY_DESCRIPTOR) sd, (PSECURITY_DESCRIPTOR *) &sdAbsolute);
  592. fFreeAbsolute = TRUE;
  593. } else {
  594. sdAbsolute = sd;
  595. fFreeAbsolute = FALSE;
  596. }
  597. //
  598. // Set the discretionary ACL on the security descriptor
  599. //
  600. if (!SetSecurityDescriptorDacl (sdAbsolute, TRUE, dacl, FALSE)) {
  601. returnValue = GetLastError();
  602. goto Cleanup;
  603. }
  604. //
  605. // Make the security descriptor self-relative so that we can
  606. // store it in the registry
  607. //
  608. secDescSize = 0;
  609. MakeSelfRelativeSD (sdAbsolute, sdSelfRelative, &secDescSize);
  610. sdSelfRelative = (SECURITY_DESCRIPTOR *) malloc (secDescSize);
  611. if (!MakeSelfRelativeSD (sdAbsolute, sdSelfRelative, &secDescSize)) {
  612. returnValue = GetLastError();
  613. goto Cleanup;
  614. }
  615. //
  616. // Store the security descriptor in the registry
  617. //
  618. SetNamedValueSD (RootKey, KeyName, ValueName, sdSelfRelative);
  619. Cleanup:
  620. if (sd)
  621. free (sd);
  622. if (sdSelfRelative)
  623. free (sdSelfRelative);
  624. if (fFreeAbsolute && sdAbsolute)
  625. free (sdAbsolute);
  626. return returnValue;
  627. }
  628. DWORD
  629. RemovePrincipalFromNamedValueSD (
  630. HKEY RootKey,
  631. LPTSTR KeyName,
  632. LPTSTR ValueName,
  633. LPTSTR Principal
  634. )
  635. {
  636. DWORD returnValue = ERROR_SUCCESS;
  637. SECURITY_DESCRIPTOR *sd = NULL;
  638. SECURITY_DESCRIPTOR *sdSelfRelative = NULL;
  639. SECURITY_DESCRIPTOR *sdAbsolute = NULL;
  640. DWORD secDescSize;
  641. BOOL present;
  642. BOOL defaultDACL;
  643. PACL dacl = NULL;
  644. BOOL newSD = FALSE;
  645. BOOL fFreeAbsolute = TRUE;
  646. returnValue = GetNamedValueSD (RootKey, KeyName, ValueName, &sd, &newSD);
  647. //
  648. // Get security descriptor from registry or create a new one
  649. //
  650. if (returnValue != ERROR_SUCCESS)
  651. return returnValue;
  652. if (!GetSecurityDescriptorDacl (sd, &present, &dacl, &defaultDACL)) {
  653. returnValue = GetLastError();
  654. goto Cleanup;
  655. }
  656. //
  657. // If the security descriptor is new, add the required Principals to it
  658. //
  659. if (newSD)
  660. {
  661. AddAccessAllowedACEToACL (&dacl, COM_RIGHTS_EXECUTE, _T("system"));
  662. #if 0
  663. AddAccessAllowedACEToACL (&dacl, COM_RIGHTS_EXECUTE, _T("INTERACTIVE"));
  664. #endif
  665. }
  666. //
  667. // Remove the Principal that the caller wants removed
  668. //
  669. returnValue = RemovePrincipalFromACL (dacl, Principal);
  670. if (returnValue != ERROR_SUCCESS)
  671. goto Cleanup;
  672. //
  673. // Make the security descriptor absolute if it isn't new
  674. //
  675. if (!newSD) {
  676. MakeSDAbsolute ((PSECURITY_DESCRIPTOR) sd, (PSECURITY_DESCRIPTOR *) &sdAbsolute);
  677. fFreeAbsolute = TRUE;
  678. } else {
  679. sdAbsolute = sd;
  680. fFreeAbsolute = FALSE;
  681. }
  682. //
  683. // Set the discretionary ACL on the security descriptor
  684. //
  685. if (!SetSecurityDescriptorDacl (sdAbsolute, TRUE, dacl, FALSE)) {
  686. returnValue = GetLastError();
  687. goto Cleanup;
  688. }
  689. //
  690. // Make the security descriptor self-relative so that we can
  691. // store it in the registry
  692. //
  693. secDescSize = 0;
  694. MakeSelfRelativeSD (sdAbsolute, sdSelfRelative, &secDescSize);
  695. sdSelfRelative = (SECURITY_DESCRIPTOR *) malloc (secDescSize);
  696. if (!MakeSelfRelativeSD (sdAbsolute, sdSelfRelative, &secDescSize)) {
  697. returnValue = GetLastError();
  698. goto Cleanup;
  699. }
  700. //
  701. // Store the security descriptor in the registry
  702. //
  703. SetNamedValueSD (RootKey, KeyName, ValueName, sdSelfRelative);
  704. Cleanup:
  705. if (sd)
  706. free (sd);
  707. if (sdSelfRelative)
  708. free (sdSelfRelative);
  709. if (fFreeAbsolute && sdAbsolute)
  710. free (sdAbsolute);
  711. return returnValue;
  712. }
  713. DWORD
  714. ChangeAppIDAccessACL (
  715. LPTSTR AppID,
  716. LPTSTR Principal,
  717. BOOL SetPrincipal,
  718. BOOL Permit
  719. )
  720. {
  721. TCHAR keyName [256];
  722. DWORD err;
  723. if (AppID [0] == _T('{'))
  724. _stprintf (keyName, _T("APPID\\%s"), AppID);
  725. else
  726. _stprintf (keyName, _T("APPID\\{%s}"), AppID);
  727. if (SetPrincipal)
  728. {
  729. err = RemovePrincipalFromNamedValueSD (HKEY_CLASSES_ROOT, keyName, _T("AccessPermission"), Principal);
  730. err = AddPrincipalToNamedValueSD (HKEY_CLASSES_ROOT, keyName, _T("AccessPermission"), Principal, Permit);
  731. } else
  732. err = RemovePrincipalFromNamedValueSD (HKEY_CLASSES_ROOT, keyName, _T("AccessPermission"), Principal);
  733. return err;
  734. }
  735. DWORD
  736. ChangeAppIDLaunchACL (
  737. LPTSTR AppID,
  738. LPTSTR Principal,
  739. BOOL SetPrincipal,
  740. BOOL Permit
  741. )
  742. {
  743. TCHAR keyName [256];
  744. DWORD err;
  745. if (AppID [0] == _T('{'))
  746. _stprintf (keyName, _T("APPID\\%s"), AppID);
  747. else
  748. _stprintf (keyName, _T("APPID\\{%s}"), AppID);
  749. if (SetPrincipal)
  750. {
  751. err = RemovePrincipalFromNamedValueSD (HKEY_CLASSES_ROOT, keyName, _T("LaunchPermission"), Principal);
  752. err = AddPrincipalToNamedValueSD (HKEY_CLASSES_ROOT, keyName, _T("LaunchPermission"), Principal, Permit);
  753. } else
  754. err = RemovePrincipalFromNamedValueSD (HKEY_CLASSES_ROOT, keyName, _T("LaunchPermission"), Principal);
  755. return err;
  756. }
  757. DWORD
  758. ChangeDCOMAccessACL (
  759. LPTSTR Principal,
  760. BOOL SetPrincipal,
  761. BOOL Permit
  762. )
  763. {
  764. TCHAR keyName [256] = _T("Software\\Microsoft\\OLE");
  765. DWORD err;
  766. if (SetPrincipal)
  767. {
  768. err = RemovePrincipalFromNamedValueSD (HKEY_LOCAL_MACHINE, keyName, _T("DefaultAccessPermission"), Principal);
  769. err = AddPrincipalToNamedValueSD (HKEY_LOCAL_MACHINE, keyName, _T("DefaultAccessPermission"), Principal, Permit);
  770. } else
  771. err = RemovePrincipalFromNamedValueSD (HKEY_LOCAL_MACHINE, keyName, _T("DefaultAccessPermission"), Principal);
  772. return err;
  773. }
  774. DWORD
  775. ChangeDCOMLaunchACL (
  776. LPTSTR Principal,
  777. BOOL SetPrincipal,
  778. BOOL Permit
  779. )
  780. {
  781. TCHAR keyName [256] = _T("Software\\Microsoft\\OLE");
  782. DWORD err;
  783. if (SetPrincipal)
  784. {
  785. err = RemovePrincipalFromNamedValueSD (HKEY_LOCAL_MACHINE, keyName, _T("DefaultLaunchPermission"), Principal);
  786. err = AddPrincipalToNamedValueSD (HKEY_LOCAL_MACHINE, keyName, _T("DefaultLaunchPermission"), Principal, Permit);
  787. } else
  788. err = RemovePrincipalFromNamedValueSD (HKEY_LOCAL_MACHINE, keyName, _T("DefaultLaunchPermission"), Principal);
  789. return err;
  790. }