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.

970 lines
24 KiB

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