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.

857 lines
21 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1992 - 1995
  5. //
  6. // File: regdcom.cxx
  7. //
  8. // Contents: Utility functions used to manipulated the DCOM registry
  9. // settings.
  10. //
  11. // This code was stolen from the DCOMPERM sample code written
  12. // by Michael Nelson.
  13. //
  14. // The only function that should be called outside this file is
  15. // ChangeAppIDACL. All others are utility functions used by it.
  16. //
  17. //----------------------------------------------------------------------------
  18. #include "headers.hxx"
  19. #include "ntsecapi.h"
  20. DWORD
  21. GetCurrentUserSID (
  22. PSID *Sid
  23. )
  24. {
  25. TOKEN_USER *tokenUser = NULL;
  26. HANDLE tokenHandle;
  27. DWORD tokenSize;
  28. DWORD sidLength;
  29. if (OpenProcessToken (GetCurrentProcess(), TOKEN_QUERY, &tokenHandle))
  30. {
  31. GetTokenInformation (tokenHandle,
  32. TokenUser,
  33. tokenUser,
  34. 0,
  35. &tokenSize);
  36. tokenUser = (TOKEN_USER *) MemAlloc (tokenSize);
  37. if (GetTokenInformation (tokenHandle,
  38. TokenUser,
  39. tokenUser,
  40. tokenSize,
  41. &tokenSize))
  42. {
  43. sidLength = GetLengthSid (tokenUser->User.Sid);
  44. *Sid = (PSID) MemAlloc (sidLength);
  45. memcpy (*Sid, tokenUser->User.Sid, sidLength);
  46. CloseHandle (tokenHandle);
  47. } else
  48. {
  49. MemFree (tokenUser);
  50. return GetLastError();
  51. }
  52. } else
  53. {
  54. MemFree (tokenUser);
  55. return GetLastError();
  56. }
  57. MemFree (tokenUser);
  58. return ERROR_SUCCESS;
  59. }
  60. DWORD
  61. GetPrincipalSID (
  62. LPTSTR Principal,
  63. PSID *Sid
  64. )
  65. {
  66. DWORD sidSize;
  67. TCHAR refDomain [256];
  68. DWORD refDomainSize;
  69. DWORD returnValue;
  70. SID_NAME_USE snu;
  71. sidSize = 0;
  72. refDomainSize = 255;
  73. LookupAccountName (NULL,
  74. Principal,
  75. *Sid,
  76. &sidSize,
  77. refDomain,
  78. &refDomainSize,
  79. &snu);
  80. returnValue = GetLastError();
  81. if (returnValue != ERROR_INSUFFICIENT_BUFFER)
  82. return returnValue;
  83. *Sid = (PSID) MemAlloc (sidSize);
  84. refDomainSize = 255;
  85. if (!LookupAccountName (NULL,
  86. Principal,
  87. *Sid,
  88. &sidSize,
  89. refDomain,
  90. &refDomainSize,
  91. &snu))
  92. {
  93. return GetLastError();
  94. }
  95. return ERROR_SUCCESS;
  96. }
  97. DWORD
  98. CreateNewSD (
  99. SECURITY_DESCRIPTOR **SD
  100. )
  101. {
  102. PACL dacl;
  103. DWORD sidLength;
  104. PSID sid;
  105. PSID groupSID;
  106. PSID ownerSID;
  107. DWORD returnValue;
  108. *SD = NULL;
  109. returnValue = GetCurrentUserSID (&sid);
  110. if (returnValue != ERROR_SUCCESS)
  111. return returnValue;
  112. sidLength = GetLengthSid (sid);
  113. *SD = (SECURITY_DESCRIPTOR *) MemAlloc (
  114. (sizeof (ACL)+sizeof (ACCESS_ALLOWED_ACE)+sidLength) +
  115. (2 * sidLength) +
  116. sizeof (SECURITY_DESCRIPTOR));
  117. groupSID = (SID *) (*SD + 1);
  118. ownerSID = (SID *) (((BYTE *) groupSID) + sidLength);
  119. dacl = (ACL *) (((BYTE *) ownerSID) + sidLength);
  120. if (!InitializeSecurityDescriptor (*SD, SECURITY_DESCRIPTOR_REVISION))
  121. {
  122. MemFree (*SD);
  123. MemFree (sid);
  124. return GetLastError();
  125. }
  126. if (!InitializeAcl (dacl,
  127. sizeof (ACL)+sizeof (ACCESS_ALLOWED_ACE)+sidLength,
  128. ACL_REVISION2))
  129. {
  130. MemFree (*SD);
  131. MemFree (sid);
  132. return GetLastError();
  133. }
  134. if (!AddAccessAllowedAce (dacl,
  135. ACL_REVISION2,
  136. COM_RIGHTS_EXECUTE,
  137. sid))
  138. {
  139. MemFree (*SD);
  140. MemFree (sid);
  141. return GetLastError();
  142. }
  143. if (!SetSecurityDescriptorDacl (*SD, TRUE, dacl, FALSE))
  144. {
  145. MemFree (*SD);
  146. MemFree (sid);
  147. return GetLastError();
  148. }
  149. memcpy (groupSID, sid, sidLength);
  150. if (!SetSecurityDescriptorGroup (*SD, groupSID, FALSE))
  151. {
  152. MemFree (*SD);
  153. MemFree (sid);
  154. return GetLastError();
  155. }
  156. memcpy (ownerSID, sid, sidLength);
  157. if (!SetSecurityDescriptorOwner (*SD, ownerSID, FALSE))
  158. {
  159. MemFree (*SD);
  160. MemFree (sid);
  161. return GetLastError();
  162. }
  163. MemFree(sid);
  164. return ERROR_SUCCESS;
  165. }
  166. DWORD
  167. MakeSDAbsolute (
  168. PSECURITY_DESCRIPTOR OldSD,
  169. PSECURITY_DESCRIPTOR *NewSD
  170. )
  171. {
  172. PSECURITY_DESCRIPTOR sd = NULL;
  173. DWORD descriptorSize;
  174. DWORD daclSize;
  175. DWORD saclSize;
  176. DWORD ownerSIDSize;
  177. DWORD groupSIDSize;
  178. PACL dacl;
  179. PACL sacl;
  180. PSID ownerSID;
  181. PSID groupSID;
  182. BOOL present;
  183. BOOL systemDefault;
  184. //
  185. // Get SACL
  186. //
  187. if (!GetSecurityDescriptorSacl (OldSD, &present, &sacl, &systemDefault))
  188. return GetLastError();
  189. if (sacl && present)
  190. {
  191. saclSize = sacl->AclSize;
  192. } else saclSize = 0;
  193. //
  194. // Get DACL
  195. //
  196. if (!GetSecurityDescriptorDacl (OldSD, &present, &dacl, &systemDefault))
  197. return GetLastError();
  198. if (dacl && present)
  199. {
  200. daclSize = dacl->AclSize;
  201. } else daclSize = 0;
  202. //
  203. // Get Owner
  204. //
  205. if (!GetSecurityDescriptorOwner (OldSD, &ownerSID, &systemDefault))
  206. return GetLastError();
  207. ownerSIDSize = GetLengthSid (ownerSID);
  208. //
  209. // Get Group
  210. //
  211. if (!GetSecurityDescriptorGroup (OldSD, &groupSID, &systemDefault))
  212. return GetLastError();
  213. groupSIDSize = GetLengthSid (groupSID);
  214. //
  215. // Do the conversion
  216. //
  217. descriptorSize = 0;
  218. MakeAbsoluteSD (OldSD, sd, &descriptorSize, dacl, &daclSize, sacl,
  219. &saclSize, ownerSID, &ownerSIDSize, groupSID,
  220. &groupSIDSize);
  221. sd = (PSECURITY_DESCRIPTOR) new BYTE [SECURITY_DESCRIPTOR_MIN_LENGTH];
  222. if (!InitializeSecurityDescriptor (sd, SECURITY_DESCRIPTOR_REVISION))
  223. return GetLastError();
  224. if (!MakeAbsoluteSD (OldSD, sd, &descriptorSize, dacl, &daclSize, sacl,
  225. &saclSize, ownerSID, &ownerSIDSize, groupSID,
  226. &groupSIDSize))
  227. return GetLastError();
  228. *NewSD = sd;
  229. return ERROR_SUCCESS;
  230. }
  231. DWORD
  232. SetNamedValueSD (
  233. HKEY RootKey,
  234. LPTSTR KeyName,
  235. LPTSTR ValueName,
  236. SECURITY_DESCRIPTOR *SD
  237. )
  238. {
  239. DWORD returnValue;
  240. DWORD disposition;
  241. HKEY registryKey;
  242. //
  243. // Create new key or open existing key
  244. //
  245. returnValue = RegCreateKeyEx (RootKey, KeyName, 0, TEXT(""), 0, KEY_ALL_ACCESS, NULL, &registryKey, &disposition);
  246. if (returnValue != ERROR_SUCCESS)
  247. return returnValue;
  248. //
  249. // Write the security descriptor
  250. //
  251. returnValue = RegSetValueEx (registryKey, ValueName, 0, REG_BINARY, (LPBYTE) SD, GetSecurityDescriptorLength (SD));
  252. if (returnValue != ERROR_SUCCESS)
  253. return returnValue;
  254. RegCloseKey (registryKey);
  255. return ERROR_SUCCESS;
  256. }
  257. DWORD
  258. GetNamedValueSD (
  259. HKEY RootKey,
  260. LPTSTR KeyName,
  261. LPTSTR ValueName,
  262. SECURITY_DESCRIPTOR **SD,
  263. BOOL *NewSD
  264. )
  265. {
  266. DWORD returnValue;
  267. HKEY registryKey;
  268. DWORD valueType;
  269. DWORD valueSize;
  270. *NewSD = FALSE;
  271. //
  272. // Get the security descriptor from the named value. If it doesn't
  273. // exist, create a fresh one.
  274. //
  275. returnValue = RegOpenKeyEx (RootKey, KeyName, 0, KEY_ALL_ACCESS, &registryKey);
  276. if (returnValue != ERROR_SUCCESS)
  277. {
  278. if (returnValue == ERROR_FILE_NOT_FOUND)
  279. {
  280. *SD = NULL;
  281. returnValue = CreateNewSD (SD);
  282. if (returnValue != ERROR_SUCCESS)
  283. return returnValue;
  284. *NewSD = TRUE;
  285. return ERROR_SUCCESS;
  286. } else
  287. return returnValue;
  288. }
  289. returnValue = RegQueryValueEx (registryKey, ValueName, NULL, &valueType, NULL, &valueSize);
  290. if (returnValue && returnValue != ERROR_INSUFFICIENT_BUFFER)
  291. {
  292. *SD = NULL;
  293. returnValue = CreateNewSD (SD);
  294. if (returnValue != ERROR_SUCCESS)
  295. return returnValue;
  296. *NewSD = TRUE;
  297. } else
  298. {
  299. *SD = (SECURITY_DESCRIPTOR *) MemAlloc (valueSize);
  300. returnValue = RegQueryValueEx (registryKey, ValueName, NULL, &valueType, (LPBYTE) *SD, &valueSize);
  301. if (returnValue)
  302. {
  303. MemFree (*SD);
  304. *SD = NULL;
  305. returnValue = CreateNewSD (SD);
  306. if (returnValue != ERROR_SUCCESS)
  307. return returnValue;
  308. *NewSD = TRUE;
  309. }
  310. }
  311. RegCloseKey (registryKey);
  312. return ERROR_SUCCESS;
  313. }
  314. DWORD
  315. CopyACL (
  316. PACL OldACL,
  317. PACL NewACL
  318. )
  319. {
  320. ACL_SIZE_INFORMATION aclSizeInfo;
  321. LPVOID ace;
  322. ACE_HEADER *aceHeader;
  323. ULONG i;
  324. GetAclInformation (OldACL, (LPVOID) &aclSizeInfo, (DWORD) sizeof (aclSizeInfo), AclSizeInformation);
  325. //
  326. // Copy all of the ACEs to the new ACL
  327. //
  328. for (i = 0; i < aclSizeInfo.AceCount; i++)
  329. {
  330. //
  331. // Get the ACE and header info
  332. //
  333. if (!GetAce (OldACL, i, &ace))
  334. return GetLastError();
  335. aceHeader = (ACE_HEADER *) ace;
  336. //
  337. // Add the ACE to the new list
  338. //
  339. if (!AddAce (NewACL, ACL_REVISION, 0xffffffff, ace, aceHeader->AceSize))
  340. return GetLastError();
  341. }
  342. return ERROR_SUCCESS;
  343. }
  344. DWORD
  345. AddAccessDeniedACEToACL (
  346. PACL *Acl,
  347. BOOL *pfNewAcl,
  348. DWORD PermissionMask,
  349. LPTSTR Principal
  350. )
  351. {
  352. ACL_SIZE_INFORMATION aclSizeInfo;
  353. int aclSize;
  354. DWORD returnValue;
  355. PSID principalSID;
  356. PACL oldACL, newACL;
  357. oldACL = *Acl;
  358. returnValue = GetPrincipalSID (Principal, &principalSID);
  359. if (returnValue != ERROR_SUCCESS)
  360. return returnValue;
  361. GetAclInformation (oldACL, (LPVOID) &aclSizeInfo, (DWORD) sizeof (ACL_SIZE_INFORMATION), AclSizeInformation);
  362. aclSize = aclSizeInfo.AclBytesInUse +
  363. sizeof (ACL) + sizeof (ACCESS_DENIED_ACE) +
  364. GetLengthSid (principalSID) - sizeof (DWORD);
  365. newACL = (PACL) new BYTE [aclSize];
  366. if (!InitializeAcl (newACL, aclSize, ACL_REVISION))
  367. {
  368. MemFree (principalSID);
  369. return GetLastError();
  370. }
  371. if (!AddAccessDeniedAce (newACL, ACL_REVISION2, PermissionMask, principalSID))
  372. {
  373. MemFree (principalSID);
  374. return GetLastError();
  375. }
  376. returnValue = CopyACL (oldACL, newACL);
  377. if (returnValue != ERROR_SUCCESS)
  378. {
  379. MemFree (principalSID);
  380. return returnValue;
  381. }
  382. *Acl = newACL;
  383. if (*pfNewAcl)
  384. delete [] oldACL;
  385. *pfNewAcl = TRUE;
  386. MemFree (principalSID);
  387. return ERROR_SUCCESS;
  388. }
  389. DWORD
  390. AddAccessAllowedACEToACL (
  391. PACL *Acl,
  392. BOOL *pfNewAcl,
  393. DWORD PermissionMask,
  394. LPTSTR Principal
  395. )
  396. {
  397. ACL_SIZE_INFORMATION aclSizeInfo;
  398. int aclSize;
  399. DWORD returnValue;
  400. PSID principalSID = NULL;
  401. PACL oldACL, newACL;
  402. oldACL = *Acl;
  403. returnValue = GetPrincipalSID (Principal, &principalSID);
  404. if (returnValue != ERROR_SUCCESS)
  405. goto Cleanup;
  406. GetAclInformation (oldACL, (LPVOID) &aclSizeInfo, (DWORD) sizeof (ACL_SIZE_INFORMATION), AclSizeInformation);
  407. aclSize = aclSizeInfo.AclBytesInUse +
  408. sizeof (ACL) + sizeof (ACCESS_ALLOWED_ACE) +
  409. GetLengthSid (principalSID) - sizeof (DWORD);
  410. newACL = (PACL) new BYTE [aclSize];
  411. if (!InitializeAcl (newACL, aclSize, ACL_REVISION))
  412. goto Cleanup;
  413. returnValue = CopyACL (oldACL, newACL);
  414. if (returnValue != ERROR_SUCCESS)
  415. goto Cleanup;
  416. if (!AddAccessAllowedAce (newACL, ACL_REVISION2, PermissionMask, principalSID))
  417. goto Cleanup;
  418. *Acl = newACL;
  419. if (*pfNewAcl)
  420. delete [] oldACL;
  421. *pfNewAcl = TRUE;
  422. Cleanup:
  423. MemFree (principalSID);
  424. return returnValue;
  425. }
  426. DWORD
  427. RemovePrincipalFromACL (
  428. PACL Acl,
  429. LPTSTR Principal
  430. )
  431. {
  432. ACL_SIZE_INFORMATION aclSizeInfo;
  433. ULONG i;
  434. LPVOID ace;
  435. ACCESS_ALLOWED_ACE *accessAllowedAce;
  436. ACCESS_DENIED_ACE *accessDeniedAce;
  437. SYSTEM_AUDIT_ACE *systemAuditAce;
  438. PSID principalSID;
  439. DWORD returnValue;
  440. ACE_HEADER *aceHeader;
  441. returnValue = GetPrincipalSID (Principal, &principalSID);
  442. if (returnValue != ERROR_SUCCESS)
  443. return returnValue;
  444. GetAclInformation (Acl, (LPVOID) &aclSizeInfo, (DWORD) sizeof (ACL_SIZE_INFORMATION), AclSizeInformation);
  445. for (i = 0; i < aclSizeInfo.AceCount; i++)
  446. {
  447. if (!GetAce (Acl, i, &ace))
  448. {
  449. MemFree (principalSID);
  450. return GetLastError();
  451. }
  452. aceHeader = (ACE_HEADER *) ace;
  453. if (aceHeader->AceType == ACCESS_ALLOWED_ACE_TYPE)
  454. {
  455. accessAllowedAce = (ACCESS_ALLOWED_ACE *) ace;
  456. if (EqualSid (principalSID, (PSID) &accessAllowedAce->SidStart))
  457. {
  458. DeleteAce (Acl, i);
  459. MemFree (principalSID);
  460. return ERROR_SUCCESS;
  461. }
  462. } else
  463. if (aceHeader->AceType == ACCESS_DENIED_ACE_TYPE)
  464. {
  465. accessDeniedAce = (ACCESS_DENIED_ACE *) ace;
  466. if (EqualSid (principalSID, (PSID) &accessDeniedAce->SidStart))
  467. {
  468. DeleteAce (Acl, i);
  469. MemFree (principalSID);
  470. return ERROR_SUCCESS;
  471. }
  472. } else
  473. if (aceHeader->AceType == SYSTEM_AUDIT_ACE_TYPE)
  474. {
  475. systemAuditAce = (SYSTEM_AUDIT_ACE *) ace;
  476. if (EqualSid (principalSID, (PSID) &systemAuditAce->SidStart))
  477. {
  478. DeleteAce (Acl, i);
  479. MemFree (principalSID);
  480. return ERROR_SUCCESS;
  481. }
  482. }
  483. }
  484. MemFree (principalSID);
  485. return ERROR_SUCCESS;
  486. }
  487. DWORD
  488. AddPrincipalToNamedValueSD (
  489. HKEY RootKey,
  490. LPTSTR KeyName,
  491. LPTSTR ValueName,
  492. LPTSTR Principal,
  493. BOOL Permit
  494. )
  495. {
  496. DWORD returnValue;
  497. SECURITY_DESCRIPTOR *sd;
  498. SECURITY_DESCRIPTOR *sdSelfRelative = NULL;
  499. SECURITY_DESCRIPTOR *sdAbsolute;
  500. DWORD secDescSize;
  501. BOOL present;
  502. BOOL defaultDACL;
  503. PACL dacl;
  504. BOOL newACL = FALSE;
  505. BOOL newSD = FALSE;
  506. returnValue = GetNamedValueSD (RootKey, KeyName, ValueName, &sd, &newSD);
  507. //
  508. // Get security descriptor from registry or create a new one
  509. //
  510. if (returnValue != ERROR_SUCCESS)
  511. return returnValue;
  512. if (!GetSecurityDescriptorDacl (sd, &present, &dacl, &defaultDACL))
  513. return GetLastError();
  514. if (newSD)
  515. {
  516. AddAccessAllowedACEToACL (&dacl, &newACL, COM_RIGHTS_EXECUTE, TEXT("SYSTEM"));
  517. AddAccessAllowedACEToACL (&dacl, &newACL, COM_RIGHTS_EXECUTE, TEXT("INTERACTIVE"));
  518. }
  519. //
  520. // Add the Principal that the caller wants added
  521. //
  522. if (Permit)
  523. {
  524. returnValue = AddAccessAllowedACEToACL (&dacl, &newACL, COM_RIGHTS_EXECUTE, Principal);
  525. }
  526. else
  527. returnValue = AddAccessDeniedACEToACL (&dacl, &newACL, GENERIC_ALL, Principal);
  528. if (returnValue != ERROR_SUCCESS)
  529. {
  530. MemFree (sd);
  531. return returnValue;
  532. }
  533. //
  534. // Make the security descriptor absolute if it isn't new
  535. //
  536. if (!newSD)
  537. MakeSDAbsolute ((PSECURITY_DESCRIPTOR) sd, (PSECURITY_DESCRIPTOR *) &sdAbsolute);
  538. else
  539. sdAbsolute = sd;
  540. //
  541. // Set the discretionary ACL on the security descriptor
  542. //
  543. if (!SetSecurityDescriptorDacl (sdAbsolute, TRUE, dacl, FALSE))
  544. return GetLastError();
  545. //
  546. // Make the security descriptor self-relative so that we can
  547. // store it in the registry
  548. //
  549. secDescSize = 0;
  550. MakeSelfRelativeSD (sdAbsolute, sdSelfRelative, &secDescSize);
  551. sdSelfRelative = (SECURITY_DESCRIPTOR *) MemAlloc (secDescSize);
  552. if (!MakeSelfRelativeSD (sdAbsolute, sdSelfRelative, &secDescSize))
  553. return GetLastError();
  554. //
  555. // Store the security descriptor in the registry
  556. //
  557. SetNamedValueSD (RootKey, KeyName, ValueName, sdSelfRelative);
  558. MemFree (sd);
  559. MemFree (sdSelfRelative);
  560. if (newACL)
  561. delete [] dacl;
  562. if (!newSD)
  563. MemFree (sdAbsolute);
  564. return ERROR_SUCCESS;
  565. }
  566. DWORD
  567. RemovePrincipalFromNamedValueSD (
  568. HKEY RootKey,
  569. LPTSTR KeyName,
  570. LPTSTR ValueName,
  571. LPTSTR Principal
  572. )
  573. {
  574. DWORD returnValue;
  575. SECURITY_DESCRIPTOR *sd;
  576. SECURITY_DESCRIPTOR *sdSelfRelative = NULL;
  577. SECURITY_DESCRIPTOR *sdAbsolute;
  578. DWORD secDescSize;
  579. BOOL present;
  580. BOOL defaultDACL;
  581. PACL dacl;
  582. BOOL newACL = FALSE;
  583. BOOL newSD = FALSE;
  584. returnValue = GetNamedValueSD (RootKey, KeyName, ValueName, &sd, &newSD);
  585. //
  586. // Get security descriptor from registry or create a new one
  587. //
  588. if (returnValue != ERROR_SUCCESS)
  589. return returnValue;
  590. if (!GetSecurityDescriptorDacl (sd, &present, &dacl, &defaultDACL))
  591. return GetLastError();
  592. //
  593. // If the security descriptor is new, add the required Principals to it
  594. //
  595. if (newSD)
  596. {
  597. AddAccessAllowedACEToACL (&dacl, &newACL, COM_RIGHTS_EXECUTE, TEXT("SYSTEM"));
  598. AddAccessAllowedACEToACL (&dacl, &newACL, COM_RIGHTS_EXECUTE, TEXT("INTERACTIVE"));
  599. }
  600. //
  601. // Remove the Principal that the caller wants removed
  602. //
  603. returnValue = RemovePrincipalFromACL (dacl, Principal);
  604. if (returnValue != ERROR_SUCCESS)
  605. {
  606. MemFree (sd);
  607. return returnValue;
  608. }
  609. //
  610. // Make the security descriptor absolute if it isn't new
  611. //
  612. if (!newSD)
  613. MakeSDAbsolute ((PSECURITY_DESCRIPTOR) sd, (PSECURITY_DESCRIPTOR *) &sdAbsolute);
  614. else
  615. sdAbsolute = sd;
  616. //
  617. // Set the discretionary ACL on the security descriptor
  618. //
  619. if (!SetSecurityDescriptorDacl (sdAbsolute, TRUE, dacl, FALSE))
  620. return GetLastError();
  621. //
  622. // Make the security descriptor self-relative so that we can
  623. // store it in the registry
  624. //
  625. secDescSize = 0;
  626. MakeSelfRelativeSD (sdAbsolute, sdSelfRelative, &secDescSize);
  627. sdSelfRelative = (SECURITY_DESCRIPTOR *) MemAlloc (secDescSize);
  628. if (!MakeSelfRelativeSD (sdAbsolute, sdSelfRelative, &secDescSize))
  629. return GetLastError();
  630. //
  631. // Store the security descriptor in the registry
  632. //
  633. SetNamedValueSD (RootKey, KeyName, ValueName, sdSelfRelative);
  634. MemFree (sd);
  635. MemFree (sdSelfRelative);
  636. if (newACL)
  637. delete [] dacl;
  638. if (!newSD)
  639. MemFree (sdAbsolute);
  640. return ERROR_SUCCESS;
  641. }
  642. //+---------------------------------------------------------------------------
  643. //
  644. // Function: ChangeAppIDACL
  645. //
  646. // Synopsis: Given an AppID and a username ("EVERYONE",
  647. // "REDMOND\johndoe") add or remove them from the DCOM Access
  648. // or launch permissions for that app.
  649. //
  650. // Arguments: [AppID] -- GUID of application to set permissions for.
  651. // [Principal] -- Name of user
  652. // [fAccess] -- If TRUE, set the access permissions. If
  653. // FALSE, set the launch permissions.
  654. // [SetPrincipal] -- If TRUE, add the user, otherwise remove
  655. // [Permit] -- If TRUE, give them access, otherwise deny
  656. // them access (ignored if [SetPrincipal] is
  657. // false.
  658. //
  659. // Returns: HRESULT
  660. //
  661. //----------------------------------------------------------------------------
  662. HRESULT
  663. ChangeAppIDACL (
  664. REFGUID AppID,
  665. LPTSTR Principal,
  666. BOOL fAccess,
  667. BOOL SetPrincipal,
  668. BOOL Permit)
  669. {
  670. TCHAR keyName [256];
  671. DWORD dwRet;
  672. LPTSTR pstrValue;
  673. OLECHAR strClsid[40];
  674. StringFromGUID2(AppID, strClsid, 40);
  675. wsprintf (keyName, TEXT("APPID\\%s"), strClsid);
  676. if (fAccess)
  677. pstrValue = TEXT("AccessPermission");
  678. else
  679. pstrValue = TEXT("LaunchPermission");
  680. if (SetPrincipal)
  681. {
  682. RemovePrincipalFromNamedValueSD (HKEY_CLASSES_ROOT, keyName, pstrValue, Principal);
  683. dwRet = AddPrincipalToNamedValueSD (HKEY_CLASSES_ROOT, keyName, pstrValue, Principal, Permit);
  684. }
  685. else
  686. {
  687. dwRet = RemovePrincipalFromNamedValueSD (HKEY_CLASSES_ROOT, keyName, pstrValue, Principal);
  688. }
  689. return HRESULT_FROM_WIN32(dwRet);
  690. }