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.

980 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 (tokenUser == NULL) {
  212. dwReturn = E_OUTOFMEMORY;
  213. }
  214. else if (GetTokenInformation (tokenHandle, TokenUser, tokenUser, tokenSize, &tokenSize))
  215. {
  216. sidLength = GetLengthSid (tokenUser->User.Sid);
  217. *Sid = (PSID) malloc (sidLength);
  218. if (*Sid == NULL) {
  219. dwReturn = E_OUTOFMEMORY;
  220. }
  221. else {
  222. memcpy (*Sid, tokenUser->User.Sid, sidLength);
  223. CloseHandle (tokenHandle);
  224. }
  225. }
  226. else {
  227. dwReturn = GetLastError();
  228. }
  229. if (tokenUser)
  230. free(tokenUser);
  231. } else
  232. dwReturn = GetLastError();
  233. return dwReturn;
  234. }
  235. DWORD
  236. GetPrincipalSID (
  237. LPTSTR Principal,
  238. PSID *Sid,
  239. BOOL *pbWellKnownSID
  240. )
  241. {
  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. //_strlwr( Principal);
  250. if ( !_tcscmp( Principal,TEXT("administrators")) ) {
  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 ( !_tcscmp( Principal, TEXT("system")) ) {
  257. // SYSTEM
  258. pSidIdentifierAuthority = &SidIdentifierNTAuthority;
  259. Count = 1;
  260. dwRID[0] = SECURITY_LOCAL_SYSTEM_RID;
  261. } else if ( !_tcscmp( Principal,TEXT("interactive")) ) {
  262. // INTERACTIVE
  263. pSidIdentifierAuthority = &SidIdentifierNTAuthority;
  264. Count = 1;
  265. dwRID[0] = SECURITY_INTERACTIVE_RID;
  266. } else if ( !_tcscmp( Principal,TEXT("everyone")) ) {
  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;
  330. PSID ownerSID;
  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. if (*SD == NULL)
  345. return E_OUTOFMEMORY;
  346. groupSID = (SID *) (*SD + 1);
  347. ownerSID = (SID *) (((BYTE *) groupSID) + sidLength);
  348. dacl = (ACL *) (((BYTE *) ownerSID) + sidLength);
  349. if (!InitializeSecurityDescriptor (*SD, SECURITY_DESCRIPTOR_REVISION))
  350. {
  351. free (*SD);
  352. free (sid);
  353. return GetLastError();
  354. }
  355. if (!InitializeAcl (dacl,
  356. sizeof (ACL)+sizeof (ACCESS_ALLOWED_ACE)+sidLength,
  357. ACL_REVISION2))
  358. {
  359. free (*SD);
  360. free (sid);
  361. return GetLastError();
  362. }
  363. if (!AddAccessAllowedAce (dacl,
  364. ACL_REVISION2,
  365. COM_RIGHTS_EXECUTE,
  366. sid))
  367. {
  368. free (*SD);
  369. free (sid);
  370. return GetLastError();
  371. }
  372. if (!SetSecurityDescriptorDacl (*SD, TRUE, dacl, FALSE))
  373. {
  374. free (*SD);
  375. free (sid);
  376. return GetLastError();
  377. }
  378. memcpy (groupSID, sid, sidLength);
  379. if (!SetSecurityDescriptorGroup (*SD, groupSID, FALSE))
  380. {
  381. free (*SD);
  382. free (sid);
  383. return GetLastError();
  384. }
  385. memcpy (ownerSID, sid, sidLength);
  386. if (!SetSecurityDescriptorOwner (*SD, ownerSID, FALSE))
  387. {
  388. free (*SD);
  389. free (sid);
  390. return GetLastError();
  391. }
  392. if (sid)
  393. free(sid);
  394. return ERROR_SUCCESS;
  395. }
  396. DWORD
  397. MakeSDAbsolute (
  398. PSECURITY_DESCRIPTOR OldSD,
  399. PSECURITY_DESCRIPTOR *NewSD
  400. )
  401. {
  402. PSECURITY_DESCRIPTOR sd = NULL;
  403. DWORD descriptorSize;
  404. DWORD daclSize;
  405. DWORD saclSize;
  406. DWORD ownerSIDSize;
  407. DWORD groupSIDSize;
  408. PACL dacl = NULL;
  409. PACL sacl = NULL;
  410. PSID ownerSID = NULL;
  411. PSID groupSID = NULL;
  412. BOOL present;
  413. BOOL systemDefault;
  414. //
  415. // Get SACL
  416. //
  417. if (!GetSecurityDescriptorSacl (OldSD, &present, &sacl, &systemDefault))
  418. return GetLastError();
  419. if (sacl && present)
  420. {
  421. saclSize = sacl->AclSize;
  422. } else saclSize = 0;
  423. //
  424. // Get DACL
  425. //
  426. if (!GetSecurityDescriptorDacl (OldSD, &present, &dacl, &systemDefault))
  427. return GetLastError();
  428. if (dacl && present)
  429. {
  430. daclSize = dacl->AclSize;
  431. } else daclSize = 0;
  432. //
  433. // Get Owner
  434. //
  435. if (!GetSecurityDescriptorOwner (OldSD, &ownerSID, &systemDefault))
  436. return GetLastError();
  437. ownerSIDSize = GetLengthSid (ownerSID);
  438. //
  439. // Get Group
  440. //
  441. if (!GetSecurityDescriptorGroup (OldSD, &groupSID, &systemDefault))
  442. return GetLastError();
  443. groupSIDSize = GetLengthSid (groupSID);
  444. //
  445. // Do the conversion
  446. //
  447. descriptorSize = 0;
  448. MakeAbsoluteSD (OldSD, sd, &descriptorSize, dacl, &daclSize, sacl,
  449. &saclSize, ownerSID, &ownerSIDSize, groupSID,
  450. &groupSIDSize);
  451. sd = (PSECURITY_DESCRIPTOR) new BYTE [SECURITY_DESCRIPTOR_MIN_LENGTH];
  452. if (sd == NULL)
  453. return E_OUTOFMEMORY;
  454. if (!InitializeSecurityDescriptor (sd, SECURITY_DESCRIPTOR_REVISION))
  455. return GetLastError();
  456. if (!MakeAbsoluteSD (OldSD, sd, &descriptorSize, dacl, &daclSize, sacl,
  457. &saclSize, ownerSID, &ownerSIDSize, groupSID,
  458. &groupSIDSize))
  459. return GetLastError();
  460. *NewSD = sd;
  461. return ERROR_SUCCESS;
  462. }
  463. DWORD
  464. SetNamedValueSD (
  465. HKEY RootKey,
  466. LPTSTR KeyName,
  467. LPTSTR ValueName,
  468. SECURITY_DESCRIPTOR *SD
  469. )
  470. {
  471. DWORD returnValue;
  472. DWORD disposition;
  473. HKEY registryKey;
  474. //
  475. // Create new key or open existing key
  476. //
  477. returnValue = RegCreateKeyEx (RootKey, KeyName, 0, _T(""), 0, KEY_ALL_ACCESS, NULL, &registryKey, &disposition);
  478. if (returnValue != ERROR_SUCCESS)
  479. return returnValue;
  480. //
  481. // Write the security descriptor
  482. //
  483. returnValue = RegSetValueEx (registryKey, ValueName, 0, REG_BINARY, (LPBYTE) SD, GetSecurityDescriptorLength (SD));
  484. if (returnValue != ERROR_SUCCESS)
  485. return returnValue;
  486. RegCloseKey (registryKey);
  487. return ERROR_SUCCESS;
  488. }
  489. DWORD
  490. GetNamedValueSD (
  491. HKEY RootKey,
  492. LPTSTR KeyName,
  493. LPTSTR ValueName,
  494. SECURITY_DESCRIPTOR **SD,
  495. BOOL *NewSD
  496. )
  497. {
  498. DWORD returnValue;
  499. HKEY registryKey;
  500. DWORD valueType;
  501. DWORD valueSize = 0;
  502. *NewSD = FALSE;
  503. //
  504. // Get the security descriptor from the named value. If it doesn't
  505. // exist, create a fresh one.
  506. //
  507. returnValue = RegOpenKeyEx (RootKey, KeyName, 0, KEY_ALL_ACCESS, &registryKey);
  508. if (returnValue != ERROR_SUCCESS)
  509. {
  510. if (returnValue == ERROR_FILE_NOT_FOUND)
  511. {
  512. *SD = NULL;
  513. returnValue = CreateNewSD (SD);
  514. if (returnValue != ERROR_SUCCESS) {
  515. if (*SD)
  516. free(*SD);
  517. return returnValue;
  518. }
  519. *NewSD = TRUE;
  520. return ERROR_SUCCESS;
  521. } else
  522. return returnValue;
  523. }
  524. returnValue = RegQueryValueEx (registryKey, ValueName, NULL, &valueType, NULL, &valueSize);
  525. if (returnValue && returnValue != ERROR_INSUFFICIENT_BUFFER)
  526. {
  527. *SD = NULL;
  528. returnValue = CreateNewSD (SD);
  529. if (returnValue != ERROR_SUCCESS) {
  530. if (*SD)
  531. free(*SD);
  532. return returnValue;
  533. }
  534. *NewSD = TRUE;
  535. } else
  536. {
  537. *SD = (SECURITY_DESCRIPTOR *) malloc (valueSize);
  538. if (*SD != NULL)
  539. returnValue = RegQueryValueEx (registryKey, ValueName, NULL, &valueType, (LPBYTE) *SD, &valueSize);
  540. if ((*SD == NULL) || returnValue)
  541. {
  542. if (*SD)
  543. free (*SD);
  544. *SD = NULL;
  545. returnValue = CreateNewSD (SD);
  546. if (returnValue != ERROR_SUCCESS) {
  547. if (*SD)
  548. free(*SD);
  549. return returnValue;
  550. }
  551. *NewSD = TRUE;
  552. }
  553. }
  554. RegCloseKey (registryKey);
  555. return ERROR_SUCCESS;
  556. }
  557. DWORD
  558. AddPrincipalToNamedValueSD (
  559. HKEY RootKey,
  560. LPTSTR KeyName,
  561. LPTSTR ValueName,
  562. LPTSTR Principal,
  563. BOOL Permit
  564. )
  565. {
  566. DWORD returnValue = ERROR_SUCCESS;
  567. SECURITY_DESCRIPTOR *sd = NULL;
  568. SECURITY_DESCRIPTOR *sdSelfRelative = NULL;
  569. SECURITY_DESCRIPTOR *sdAbsolute = NULL;
  570. DWORD secDescSize;
  571. BOOL present;
  572. BOOL defaultDACL;
  573. PACL dacl;
  574. BOOL newSD = FALSE;
  575. BOOL fFreeAbsolute = TRUE;
  576. returnValue = GetNamedValueSD (RootKey, KeyName, ValueName, &sd, &newSD);
  577. //
  578. // Get security descriptor from registry or create a new one
  579. //
  580. if (returnValue != ERROR_SUCCESS)
  581. return returnValue;
  582. if (!GetSecurityDescriptorDacl (sd, &present, &dacl, &defaultDACL)) {
  583. returnValue = GetLastError();
  584. goto Cleanup;
  585. }
  586. if (newSD)
  587. {
  588. AddAccessAllowedACEToACL (&dacl, COM_RIGHTS_EXECUTE, _T("system"));
  589. #if 0
  590. AddAccessAllowedACEToACL (&dacl, COM_RIGHTS_EXECUTE, _T("INTERACTIVE"));
  591. #endif
  592. }
  593. //
  594. // Add the Principal that the caller wants added
  595. //
  596. if (Permit)
  597. returnValue = AddAccessAllowedACEToACL (&dacl, COM_RIGHTS_EXECUTE, Principal);
  598. else
  599. returnValue = AddAccessDeniedACEToACL (&dacl, GENERIC_ALL, Principal);
  600. if (returnValue != ERROR_SUCCESS)
  601. goto Cleanup;
  602. //
  603. // Make the security descriptor absolute if it isn't new
  604. //
  605. if (!newSD) {
  606. MakeSDAbsolute ((PSECURITY_DESCRIPTOR) sd, (PSECURITY_DESCRIPTOR *) &sdAbsolute);
  607. fFreeAbsolute = TRUE;
  608. } else {
  609. sdAbsolute = sd;
  610. fFreeAbsolute = FALSE;
  611. }
  612. //
  613. // Set the discretionary ACL on the security descriptor
  614. //
  615. if (!SetSecurityDescriptorDacl (sdAbsolute, TRUE, dacl, FALSE)) {
  616. returnValue = GetLastError();
  617. goto Cleanup;
  618. }
  619. //
  620. // Make the security descriptor self-relative so that we can
  621. // store it in the registry
  622. //
  623. secDescSize = 0;
  624. MakeSelfRelativeSD (sdAbsolute, sdSelfRelative, &secDescSize);
  625. sdSelfRelative = (SECURITY_DESCRIPTOR *) malloc (secDescSize);
  626. if (!MakeSelfRelativeSD (sdAbsolute, sdSelfRelative, &secDescSize)) {
  627. returnValue = GetLastError();
  628. goto Cleanup;
  629. }
  630. //
  631. // Store the security descriptor in the registry
  632. //
  633. SetNamedValueSD (RootKey, KeyName, ValueName, sdSelfRelative);
  634. Cleanup:
  635. if (sd)
  636. free (sd);
  637. if (sdSelfRelative)
  638. free (sdSelfRelative);
  639. if (fFreeAbsolute && sdAbsolute)
  640. free (sdAbsolute);
  641. return returnValue;
  642. }
  643. DWORD
  644. RemovePrincipalFromNamedValueSD (
  645. HKEY RootKey,
  646. LPTSTR KeyName,
  647. LPTSTR ValueName,
  648. LPTSTR Principal
  649. )
  650. {
  651. DWORD returnValue = ERROR_SUCCESS;
  652. SECURITY_DESCRIPTOR *sd = NULL;
  653. SECURITY_DESCRIPTOR *sdSelfRelative = NULL;
  654. SECURITY_DESCRIPTOR *sdAbsolute = NULL;
  655. DWORD secDescSize;
  656. BOOL present;
  657. BOOL defaultDACL;
  658. PACL dacl = NULL;
  659. BOOL newSD = FALSE;
  660. BOOL fFreeAbsolute = TRUE;
  661. returnValue = GetNamedValueSD (RootKey, KeyName, ValueName, &sd, &newSD);
  662. //
  663. // Get security descriptor from registry or create a new one
  664. //
  665. if (returnValue != ERROR_SUCCESS)
  666. return returnValue;
  667. if (!GetSecurityDescriptorDacl (sd, &present, &dacl, &defaultDACL)) {
  668. returnValue = GetLastError();
  669. goto Cleanup;
  670. }
  671. //
  672. // If the security descriptor is new, add the required Principals to it
  673. //
  674. if (newSD)
  675. {
  676. AddAccessAllowedACEToACL (&dacl, COM_RIGHTS_EXECUTE, _T("system"));
  677. #if 0
  678. AddAccessAllowedACEToACL (&dacl, COM_RIGHTS_EXECUTE, _T("INTERACTIVE"));
  679. #endif
  680. }
  681. //
  682. // Remove the Principal that the caller wants removed
  683. //
  684. returnValue = RemovePrincipalFromACL (dacl, Principal);
  685. if (returnValue != ERROR_SUCCESS)
  686. goto Cleanup;
  687. //
  688. // Make the security descriptor absolute if it isn't new
  689. //
  690. if (!newSD) {
  691. MakeSDAbsolute ((PSECURITY_DESCRIPTOR) sd, (PSECURITY_DESCRIPTOR *) &sdAbsolute);
  692. fFreeAbsolute = TRUE;
  693. } else {
  694. sdAbsolute = sd;
  695. fFreeAbsolute = FALSE;
  696. }
  697. //
  698. // Set the discretionary ACL on the security descriptor
  699. //
  700. if (!SetSecurityDescriptorDacl (sdAbsolute, TRUE, dacl, FALSE)) {
  701. returnValue = GetLastError();
  702. goto Cleanup;
  703. }
  704. //
  705. // Make the security descriptor self-relative so that we can
  706. // store it in the registry
  707. //
  708. secDescSize = 0;
  709. MakeSelfRelativeSD (sdAbsolute, sdSelfRelative, &secDescSize);
  710. sdSelfRelative = (SECURITY_DESCRIPTOR *) malloc (secDescSize);
  711. if (!MakeSelfRelativeSD (sdAbsolute, sdSelfRelative, &secDescSize)) {
  712. returnValue = GetLastError();
  713. goto Cleanup;
  714. }
  715. //
  716. // Store the security descriptor in the registry
  717. //
  718. SetNamedValueSD (RootKey, KeyName, ValueName, sdSelfRelative);
  719. Cleanup:
  720. if (sd)
  721. free (sd);
  722. if (sdSelfRelative)
  723. free (sdSelfRelative);
  724. if (fFreeAbsolute && sdAbsolute)
  725. free (sdAbsolute);
  726. return returnValue;
  727. }
  728. DWORD
  729. ChangeAppIDAccessACL (
  730. LPTSTR AppID,
  731. LPTSTR Principal,
  732. BOOL SetPrincipal,
  733. BOOL Permit
  734. )
  735. {
  736. TCHAR keyName [256];
  737. DWORD err;
  738. if (AppID [0] == _T('{'))
  739. _stprintf (keyName, _T("APPID\\%s"), AppID);
  740. else
  741. _stprintf (keyName, _T("APPID\\{%s}"), AppID);
  742. if (SetPrincipal)
  743. {
  744. err = RemovePrincipalFromNamedValueSD (HKEY_CLASSES_ROOT, keyName, _T("AccessPermission"), Principal);
  745. err = AddPrincipalToNamedValueSD (HKEY_CLASSES_ROOT, keyName, _T("AccessPermission"), Principal, Permit);
  746. } else
  747. err = RemovePrincipalFromNamedValueSD (HKEY_CLASSES_ROOT, keyName, _T("AccessPermission"), Principal);
  748. return err;
  749. }
  750. DWORD
  751. ChangeAppIDLaunchACL (
  752. LPTSTR AppID,
  753. LPTSTR Principal,
  754. BOOL SetPrincipal,
  755. BOOL Permit
  756. )
  757. {
  758. TCHAR keyName [256];
  759. DWORD err;
  760. if (AppID [0] == _T('{'))
  761. _stprintf (keyName, _T("APPID\\%s"), AppID);
  762. else
  763. _stprintf (keyName, _T("APPID\\{%s}"), AppID);
  764. if (SetPrincipal)
  765. {
  766. err = RemovePrincipalFromNamedValueSD (HKEY_CLASSES_ROOT, keyName, _T("LaunchPermission"), Principal);
  767. err = AddPrincipalToNamedValueSD (HKEY_CLASSES_ROOT, keyName, _T("LaunchPermission"), Principal, Permit);
  768. } else
  769. err = RemovePrincipalFromNamedValueSD (HKEY_CLASSES_ROOT, keyName, _T("LaunchPermission"), Principal);
  770. return err;
  771. }
  772. DWORD
  773. ChangeDCOMAccessACL (
  774. LPTSTR Principal,
  775. BOOL SetPrincipal,
  776. BOOL Permit
  777. )
  778. {
  779. TCHAR keyName [256] = _T("Software\\Microsoft\\OLE");
  780. DWORD err;
  781. if (SetPrincipal)
  782. {
  783. err = RemovePrincipalFromNamedValueSD (HKEY_LOCAL_MACHINE, keyName, _T("DefaultAccessPermission"), Principal);
  784. err = AddPrincipalToNamedValueSD (HKEY_LOCAL_MACHINE, keyName, _T("DefaultAccessPermission"), Principal, Permit);
  785. } else
  786. err = RemovePrincipalFromNamedValueSD (HKEY_LOCAL_MACHINE, keyName, _T("DefaultAccessPermission"), Principal);
  787. return err;
  788. }
  789. DWORD
  790. ChangeDCOMLaunchACL (
  791. LPTSTR Principal,
  792. BOOL SetPrincipal,
  793. BOOL Permit
  794. )
  795. {
  796. TCHAR keyName [256] = _T("Software\\Microsoft\\OLE");
  797. DWORD err;
  798. if (SetPrincipal)
  799. {
  800. err = RemovePrincipalFromNamedValueSD (HKEY_LOCAL_MACHINE, keyName, _T("DefaultLaunchPermission"), Principal);
  801. err = AddPrincipalToNamedValueSD (HKEY_LOCAL_MACHINE, keyName, _T("DefaultLaunchPermission"), Principal, Permit);
  802. } else
  803. err = RemovePrincipalFromNamedValueSD (HKEY_LOCAL_MACHINE, keyName, _T("DefaultLaunchPermission"), Principal);
  804. return err;
  805. }