Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1162 lines
30 KiB

  1. #include "stdafx.h"
  2. #include "dcomperm.h"
  3. #include <strsafe.h>
  4. //
  5. // Check whether we are running as administrator on the machine
  6. // or not
  7. //
  8. BOOL RunningAsAdministrator(void)
  9. {
  10. BOOL fReturn = FALSE;
  11. PSID psidAdmin;
  12. DWORD err;
  13. SID_IDENTIFIER_AUTHORITY SystemSidAuthority= SECURITY_NT_AUTHORITY;
  14. if ( AllocateAndInitializeSid ( &SystemSidAuthority, 2,
  15. SECURITY_BUILTIN_DOMAIN_RID,
  16. DOMAIN_ALIAS_RID_ADMINS,
  17. 0, 0, 0, 0, 0, 0, &psidAdmin) )
  18. {
  19. if (!CheckTokenMembership( NULL, psidAdmin, &fReturn ))
  20. {
  21. err = GetLastError();
  22. }
  23. FreeSid ( psidAdmin);
  24. }
  25. return ( fReturn );
  26. }
  27. DWORD
  28. CopyACL (
  29. PACL OldACL,
  30. PACL NewACL
  31. )
  32. {
  33. ACL_SIZE_INFORMATION aclSizeInfo;
  34. LPVOID ace;
  35. ACE_HEADER *aceHeader;
  36. ULONG i;
  37. DWORD returnValue = ERROR_SUCCESS;
  38. if (0 == IsValidAcl(OldACL))
  39. {
  40. returnValue = ERROR_INVALID_ACL;
  41. return returnValue;
  42. }
  43. if (0 == GetAclInformation (OldACL, (LPVOID) &aclSizeInfo, (DWORD) sizeof (aclSizeInfo), AclSizeInformation))
  44. {
  45. returnValue = GetLastError();
  46. return returnValue;
  47. }
  48. //
  49. // Copy all of the ACEs to the new ACL
  50. //
  51. for (i = 0; i < aclSizeInfo.AceCount; i++)
  52. {
  53. //
  54. // Get the ACE and header info
  55. //
  56. if (!GetAce (OldACL, i, &ace))
  57. {
  58. returnValue = GetLastError();
  59. return returnValue;
  60. }
  61. aceHeader = (ACE_HEADER *) ace;
  62. //
  63. // Add the ACE to the new list
  64. //
  65. if (!AddAce (NewACL, ACL_REVISION, 0xffffffff, ace, aceHeader->AceSize))
  66. {
  67. returnValue = GetLastError();
  68. return returnValue;
  69. }
  70. }
  71. return returnValue;
  72. }
  73. DWORD
  74. GetPrincipalSID (
  75. LPCTSTR Principal,
  76. PSID *Sid,
  77. BOOL *pbWellKnownSID
  78. )
  79. {
  80. DWORD returnValue=ERROR_SUCCESS;
  81. SID_IDENTIFIER_AUTHORITY SidIdentifierNTAuthority = SECURITY_NT_AUTHORITY;
  82. SID_IDENTIFIER_AUTHORITY SidIdentifierWORLDAuthority = SECURITY_WORLD_SID_AUTHORITY;
  83. PSID_IDENTIFIER_AUTHORITY pSidIdentifierAuthority;
  84. BYTE Count;
  85. DWORD dwRID[8];
  86. TCHAR pszPrincipal[MAX_PATH];
  87. *pbWellKnownSID = TRUE;
  88. memset(&(dwRID[0]), 0, 8 * sizeof(DWORD));
  89. StringCbCopy(pszPrincipal,sizeof(pszPrincipal),Principal);
  90. _wcslwr(pszPrincipal);
  91. if ( wcsstr(pszPrincipal, TEXT("administrators")) != NULL ) {
  92. // Administrators group
  93. pSidIdentifierAuthority = &SidIdentifierNTAuthority;
  94. Count = 2;
  95. dwRID[0] = SECURITY_BUILTIN_DOMAIN_RID;
  96. dwRID[1] = DOMAIN_ALIAS_RID_ADMINS;
  97. } else if ( wcsstr(pszPrincipal, TEXT("system")) != NULL) {
  98. // SYSTEM
  99. pSidIdentifierAuthority = &SidIdentifierNTAuthority;
  100. Count = 1;
  101. dwRID[0] = SECURITY_LOCAL_SYSTEM_RID;
  102. } else if ( wcsstr(pszPrincipal, TEXT("interactive")) != NULL) {
  103. // INTERACTIVE
  104. pSidIdentifierAuthority = &SidIdentifierNTAuthority;
  105. Count = 1;
  106. dwRID[0] = SECURITY_INTERACTIVE_RID;
  107. } else if ( wcsstr(pszPrincipal, TEXT("everyone")) != NULL) {
  108. // Everyone
  109. pSidIdentifierAuthority = &SidIdentifierWORLDAuthority;
  110. Count = 1;
  111. dwRID[0] = SECURITY_WORLD_RID;
  112. } else {
  113. *pbWellKnownSID = FALSE;
  114. }
  115. if (*pbWellKnownSID) {
  116. if ( !AllocateAndInitializeSid(pSidIdentifierAuthority,
  117. (BYTE)Count,
  118. dwRID[0],
  119. dwRID[1],
  120. dwRID[2],
  121. dwRID[3],
  122. dwRID[4],
  123. dwRID[5],
  124. dwRID[6],
  125. dwRID[7],
  126. Sid) ) {
  127. returnValue = GetLastError();
  128. }
  129. } else {
  130. // get regular account sid
  131. DWORD sidSize;
  132. TCHAR refDomain [256];
  133. DWORD refDomainSize;
  134. SID_NAME_USE snu;
  135. sidSize = 0;
  136. refDomainSize = 255;
  137. LookupAccountName (NULL,
  138. pszPrincipal,
  139. *Sid,
  140. &sidSize,
  141. refDomain,
  142. &refDomainSize,
  143. &snu);
  144. returnValue = GetLastError();
  145. if (returnValue == ERROR_INSUFFICIENT_BUFFER) {
  146. *Sid = (PSID) malloc (sidSize);
  147. if (!*Sid)
  148. {
  149. SetLastError(ERROR_NOT_ENOUGH_MEMORY);
  150. return GetLastError();
  151. }
  152. refDomainSize = 255;
  153. if (!LookupAccountName (NULL,
  154. pszPrincipal,
  155. *Sid,
  156. &sidSize,
  157. refDomain,
  158. &refDomainSize,
  159. &snu))
  160. {
  161. returnValue = GetLastError();
  162. } else {
  163. returnValue = ERROR_SUCCESS;
  164. }
  165. }
  166. }
  167. return returnValue;
  168. }
  169. DWORD
  170. AddAccessDeniedACEToACL (
  171. PACL *Acl,
  172. DWORD PermissionMask,
  173. LPTSTR Principal
  174. )
  175. {
  176. ACL_SIZE_INFORMATION aclSizeInfo;
  177. int aclSize;
  178. DWORD returnValue = ERROR_SUCCESS;
  179. PSID principalSID = NULL;
  180. PACL oldACL, newACL;
  181. BOOL bWellKnownSID = FALSE;
  182. oldACL = *Acl;
  183. returnValue = GetPrincipalSID (Principal, &principalSID, &bWellKnownSID);
  184. if (returnValue != ERROR_SUCCESS)
  185. return returnValue;
  186. GetAclInformation (oldACL,
  187. (LPVOID) &aclSizeInfo,
  188. (DWORD) sizeof (ACL_SIZE_INFORMATION),
  189. AclSizeInformation);
  190. aclSize = aclSizeInfo.AclBytesInUse +
  191. sizeof (ACL) + sizeof (ACCESS_DENIED_ACE) +
  192. GetLengthSid (principalSID) - sizeof (DWORD);
  193. newACL = (PACL) new BYTE [aclSize];
  194. if (!InitializeAcl (newACL, aclSize, ACL_REVISION))
  195. {
  196. returnValue = GetLastError();
  197. goto cleanup;
  198. }
  199. if (!AddAccessDeniedAce (newACL, ACL_REVISION2, PermissionMask, principalSID))
  200. {
  201. returnValue = GetLastError();
  202. goto cleanup;
  203. }
  204. returnValue = CopyACL (oldACL, newACL);
  205. if (returnValue != ERROR_SUCCESS)
  206. {
  207. goto cleanup;
  208. }
  209. *Acl = newACL;
  210. newACL = NULL;
  211. cleanup:
  212. // BugFix: 57654 Whistler
  213. // Prefix bug leaking memory in error condition.
  214. // By setting the newACL to NULL above if we have
  215. // relinquished the memory to *Acl, we avoid releasing
  216. // memory we have passed back to the caller.
  217. // EBK 5/5/2000
  218. if (newACL)
  219. {
  220. delete[] newACL;
  221. newACL = NULL;
  222. }
  223. if (principalSID) {
  224. if (bWellKnownSID)
  225. FreeSid (principalSID);
  226. else
  227. free (principalSID);
  228. }
  229. return returnValue;
  230. }
  231. DWORD
  232. AddAccessAllowedACEToACL (
  233. PACL *Acl,
  234. DWORD PermissionMask,
  235. LPTSTR Principal
  236. )
  237. {
  238. ACL_SIZE_INFORMATION aclSizeInfo;
  239. int aclSize;
  240. DWORD returnValue = ERROR_SUCCESS;
  241. PSID principalSID = NULL;
  242. PACL oldACL = NULL;
  243. PACL newACL = NULL;
  244. BOOL bWellKnownSID = FALSE;
  245. oldACL = *Acl;
  246. // check if the acl we got passed in is valid!
  247. if (0 == IsValidAcl(oldACL))
  248. {
  249. returnValue = ERROR_INVALID_ACL;
  250. goto cleanup;
  251. }
  252. returnValue = GetPrincipalSID (Principal, &principalSID, &bWellKnownSID);
  253. if (returnValue != ERROR_SUCCESS)
  254. {
  255. return returnValue;
  256. }
  257. if (0 == GetAclInformation (oldACL, (LPVOID) &aclSizeInfo, (DWORD) sizeof (ACL_SIZE_INFORMATION), AclSizeInformation))
  258. {
  259. returnValue = GetLastError();
  260. goto cleanup;
  261. }
  262. aclSize = aclSizeInfo.AclBytesInUse +
  263. sizeof (ACL) + sizeof (ACCESS_ALLOWED_ACE) +
  264. GetLengthSid (principalSID) - sizeof (DWORD);
  265. newACL = (PACL) new BYTE [aclSize];
  266. if (!InitializeAcl (newACL, aclSize, ACL_REVISION))
  267. {
  268. returnValue = GetLastError();
  269. goto cleanup;
  270. }
  271. returnValue = CopyACL (oldACL, newACL);
  272. if (returnValue != ERROR_SUCCESS)
  273. {
  274. goto cleanup;
  275. }
  276. //if (!AddAccessAllowedAce (newACL, ACL_REVISION2, PermissionMask, principalSID))
  277. if (!AddAccessAllowedAce (newACL, ACL_REVISION, PermissionMask, principalSID))
  278. {
  279. returnValue = GetLastError();
  280. goto cleanup;
  281. }
  282. // check if the acl is valid!
  283. /*
  284. if (0 == IsValidAcl(newACL))
  285. {
  286. returnValue = ERROR_INVALID_ACL;
  287. goto cleanup;
  288. }
  289. */
  290. // cleanup old memory whose pointer we're replacing
  291. // okay to leak in setup... (need to comment out or else av's)
  292. //if (*Acl) {delete(*Acl);}
  293. *Acl = newACL;
  294. newACL = NULL;
  295. cleanup:
  296. if (principalSID) {
  297. if (bWellKnownSID)
  298. FreeSid (principalSID);
  299. else
  300. free (principalSID);
  301. }
  302. if (newACL)
  303. {
  304. delete [] newACL;
  305. newACL = NULL;
  306. }
  307. return returnValue;
  308. }
  309. DWORD
  310. RemovePrincipalFromACL (
  311. PACL Acl,
  312. LPTSTR Principal
  313. )
  314. {
  315. ACL_SIZE_INFORMATION aclSizeInfo;
  316. ULONG i;
  317. LPVOID ace;
  318. ACCESS_ALLOWED_ACE *accessAllowedAce;
  319. ACCESS_DENIED_ACE *accessDeniedAce;
  320. SYSTEM_AUDIT_ACE *systemAuditAce;
  321. PSID principalSID = NULL;
  322. DWORD returnValue = ERROR_SUCCESS;
  323. ACE_HEADER *aceHeader;
  324. BOOL bWellKnownSID = FALSE;
  325. returnValue = GetPrincipalSID (Principal, &principalSID, &bWellKnownSID);
  326. if (returnValue != ERROR_SUCCESS)
  327. return returnValue;
  328. GetAclInformation (Acl,
  329. (LPVOID) &aclSizeInfo,
  330. (DWORD) sizeof (ACL_SIZE_INFORMATION),
  331. AclSizeInformation);
  332. for (i = 0; i < aclSizeInfo.AceCount; i++)
  333. {
  334. if (!GetAce (Acl, i, &ace))
  335. {
  336. returnValue = GetLastError();
  337. break;
  338. }
  339. aceHeader = (ACE_HEADER *) ace;
  340. if (aceHeader->AceType == ACCESS_ALLOWED_ACE_TYPE)
  341. {
  342. accessAllowedAce = (ACCESS_ALLOWED_ACE *) ace;
  343. if (EqualSid (principalSID, (PSID) &accessAllowedAce->SidStart))
  344. {
  345. DeleteAce (Acl, i);
  346. break;
  347. }
  348. } else
  349. if (aceHeader->AceType == ACCESS_DENIED_ACE_TYPE)
  350. {
  351. accessDeniedAce = (ACCESS_DENIED_ACE *) ace;
  352. if (EqualSid (principalSID, (PSID) &accessDeniedAce->SidStart))
  353. {
  354. DeleteAce (Acl, i);
  355. break;
  356. }
  357. } else
  358. if (aceHeader->AceType == SYSTEM_AUDIT_ACE_TYPE)
  359. {
  360. systemAuditAce = (SYSTEM_AUDIT_ACE *) ace;
  361. if (EqualSid (principalSID, (PSID) &systemAuditAce->SidStart))
  362. {
  363. DeleteAce (Acl, i);
  364. break;
  365. }
  366. }
  367. }
  368. if (principalSID) {
  369. if (bWellKnownSID)
  370. FreeSid (principalSID);
  371. else
  372. free (principalSID);
  373. }
  374. return returnValue;
  375. }
  376. DWORD
  377. GetCurrentUserSID (
  378. PSID *Sid
  379. )
  380. {
  381. DWORD dwReturn = ERROR_SUCCESS;
  382. TOKEN_USER *tokenUser = NULL;
  383. HANDLE tokenHandle = NULL;
  384. DWORD tokenSize;
  385. DWORD sidLength;
  386. if (OpenProcessToken (GetCurrentProcess(), TOKEN_QUERY, &tokenHandle))
  387. {
  388. GetTokenInformation (tokenHandle, TokenUser, tokenUser, 0, &tokenSize);
  389. tokenUser = (TOKEN_USER *) malloc (tokenSize);
  390. if (!tokenUser)
  391. {
  392. SetLastError(ERROR_NOT_ENOUGH_MEMORY);
  393. return GetLastError();
  394. }
  395. if (GetTokenInformation (tokenHandle, TokenUser, tokenUser, tokenSize, &tokenSize))
  396. {
  397. sidLength = GetLengthSid (tokenUser->User.Sid);
  398. *Sid = (PSID) malloc (sidLength);
  399. if (*Sid)
  400. {
  401. memcpy (*Sid, tokenUser->User.Sid, sidLength);
  402. }
  403. CloseHandle (tokenHandle);
  404. } else
  405. dwReturn = GetLastError();
  406. if (tokenUser)
  407. free(tokenUser);
  408. } else
  409. dwReturn = GetLastError();
  410. return dwReturn;
  411. }
  412. DWORD
  413. CreateNewSD (
  414. SECURITY_DESCRIPTOR **SD
  415. )
  416. {
  417. PACL dacl = NULL;
  418. DWORD sidLength;
  419. PSID sid = NULL;
  420. PSID groupSID = NULL;
  421. PSID ownerSID = NULL;
  422. DWORD returnValue = 0;
  423. *SD = NULL;
  424. returnValue = GetCurrentUserSID (&sid);
  425. if (returnValue != ERROR_SUCCESS) {
  426. if (sid)
  427. free(sid);
  428. return returnValue;
  429. }
  430. if (!sid)
  431. {
  432. return E_FAIL;
  433. }
  434. sidLength = GetLengthSid (sid);
  435. *SD = (SECURITY_DESCRIPTOR *) malloc (
  436. (sizeof (ACL)+sizeof (ACCESS_ALLOWED_ACE)+sidLength) +
  437. (2 * sidLength) +
  438. sizeof (SECURITY_DESCRIPTOR));
  439. if (!*SD)
  440. {
  441. SetLastError(ERROR_NOT_ENOUGH_MEMORY);
  442. returnValue = GetLastError();
  443. return returnValue;
  444. }
  445. groupSID = (SID *) (*SD + 1);
  446. ownerSID = (SID *) (((BYTE *) groupSID) + sidLength);
  447. dacl = (ACL *) (((BYTE *) ownerSID) + sidLength);
  448. if (!InitializeSecurityDescriptor (*SD, SECURITY_DESCRIPTOR_REVISION))
  449. {
  450. free (*SD);
  451. free (sid);
  452. returnValue = GetLastError();
  453. return returnValue;
  454. }
  455. if (!InitializeAcl (dacl,
  456. sizeof (ACL)+sizeof (ACCESS_ALLOWED_ACE)+sidLength,
  457. ACL_REVISION2))
  458. {
  459. free (*SD);
  460. free (sid);
  461. returnValue = GetLastError();
  462. return returnValue;
  463. }
  464. if (!AddAccessAllowedAce (dacl,
  465. ACL_REVISION2,
  466. COM_RIGHTS_EXECUTE,
  467. sid))
  468. {
  469. free (*SD);
  470. free (sid);
  471. returnValue = GetLastError();
  472. return returnValue;
  473. }
  474. if (!SetSecurityDescriptorDacl (*SD, TRUE, dacl, FALSE))
  475. {
  476. free (*SD);
  477. free (sid);
  478. returnValue = GetLastError();
  479. return returnValue;
  480. }
  481. memcpy (groupSID, sid, sidLength);
  482. if (!SetSecurityDescriptorGroup (*SD, groupSID, FALSE))
  483. {
  484. free (*SD);
  485. free (sid);
  486. returnValue = GetLastError();
  487. return returnValue;
  488. }
  489. memcpy (ownerSID, sid, sidLength);
  490. if (!SetSecurityDescriptorOwner (*SD, ownerSID, FALSE))
  491. {
  492. free (*SD);
  493. free (sid);
  494. returnValue = GetLastError();
  495. return returnValue;
  496. }
  497. // check if everything went ok
  498. if (!IsValidSecurityDescriptor(*SD))
  499. {
  500. free (*SD);
  501. free (sid);
  502. returnValue = ERROR_INVALID_SECURITY_DESCR;
  503. return returnValue;
  504. }
  505. if (sid)
  506. free(sid);
  507. return ERROR_SUCCESS;
  508. }
  509. DWORD
  510. MakeSDAbsolute (
  511. PSECURITY_DESCRIPTOR OldSD,
  512. PSECURITY_DESCRIPTOR *NewSD
  513. )
  514. {
  515. PSECURITY_DESCRIPTOR sd = NULL;
  516. DWORD descriptorSize;
  517. DWORD daclSize;
  518. DWORD saclSize;
  519. DWORD ownerSIDSize;
  520. DWORD groupSIDSize;
  521. PACL dacl = NULL;
  522. PACL sacl = NULL;
  523. PSID ownerSID = NULL;
  524. PSID groupSID = NULL;
  525. BOOL present;
  526. BOOL systemDefault;
  527. //
  528. // Get SACL
  529. //
  530. if (!GetSecurityDescriptorSacl (OldSD, &present, &sacl, &systemDefault))
  531. return GetLastError();
  532. if (sacl && present)
  533. {
  534. saclSize = sacl->AclSize;
  535. } else saclSize = 0;
  536. //
  537. // Get DACL
  538. //
  539. if (!GetSecurityDescriptorDacl (OldSD, &present, &dacl, &systemDefault))
  540. return GetLastError();
  541. if (dacl && present)
  542. {
  543. daclSize = dacl->AclSize;
  544. } else daclSize = 0;
  545. //
  546. // Get Owner
  547. //
  548. if (!GetSecurityDescriptorOwner (OldSD, &ownerSID, &systemDefault))
  549. return GetLastError();
  550. ownerSIDSize = GetLengthSid (ownerSID);
  551. //
  552. // Get Group
  553. //
  554. if (!GetSecurityDescriptorGroup (OldSD, &groupSID, &systemDefault))
  555. return GetLastError();
  556. groupSIDSize = GetLengthSid (groupSID);
  557. //
  558. // Do the conversion
  559. //
  560. descriptorSize = 0;
  561. MakeAbsoluteSD (OldSD, sd, &descriptorSize, dacl, &daclSize, sacl,
  562. &saclSize, ownerSID, &ownerSIDSize, groupSID,
  563. &groupSIDSize);
  564. sd = (PSECURITY_DESCRIPTOR) new BYTE [SECURITY_DESCRIPTOR_MIN_LENGTH];
  565. if (!sd)
  566. {
  567. SetLastError(ERROR_NOT_ENOUGH_MEMORY);
  568. return GetLastError();
  569. }
  570. if (!InitializeSecurityDescriptor (sd, SECURITY_DESCRIPTOR_REVISION))
  571. return GetLastError();
  572. if (!MakeAbsoluteSD (OldSD, sd, &descriptorSize, dacl, &daclSize, sacl,
  573. &saclSize, ownerSID, &ownerSIDSize, groupSID,
  574. &groupSIDSize))
  575. return GetLastError();
  576. *NewSD = sd;
  577. return ERROR_SUCCESS;
  578. }
  579. DWORD
  580. SetNamedValueSD (
  581. HKEY RootKey,
  582. LPTSTR KeyName,
  583. LPTSTR ValueName,
  584. SECURITY_DESCRIPTOR *SD
  585. )
  586. {
  587. DWORD returnValue;
  588. DWORD disposition;
  589. HKEY registryKey;
  590. //
  591. // Create new key or open existing key
  592. //
  593. returnValue = RegCreateKeyEx (RootKey, KeyName, 0, _T(""), 0, KEY_ALL_ACCESS, NULL, &registryKey, &disposition);
  594. if (returnValue != ERROR_SUCCESS)
  595. return returnValue;
  596. //
  597. // Write the security descriptor
  598. //
  599. returnValue = RegSetValueEx (registryKey, ValueName, 0, REG_BINARY, (LPBYTE) SD, GetSecurityDescriptorLength (SD));
  600. if (returnValue != ERROR_SUCCESS)
  601. return returnValue;
  602. RegCloseKey (registryKey);
  603. return ERROR_SUCCESS;
  604. }
  605. DWORD
  606. GetNamedValueSD (
  607. HKEY RootKey,
  608. LPTSTR KeyName,
  609. LPTSTR ValueName,
  610. SECURITY_DESCRIPTOR **SD,
  611. BOOL *NewSD
  612. )
  613. {
  614. DWORD returnValue;
  615. HKEY registryKey;
  616. DWORD valueType;
  617. DWORD valueSize = 0;
  618. *NewSD = FALSE;
  619. //
  620. // Get the security descriptor from the named value. If it doesn't
  621. // exist, create a fresh one.
  622. //
  623. returnValue = RegOpenKeyEx (RootKey, KeyName, 0, KEY_ALL_ACCESS, &registryKey);
  624. if (returnValue != ERROR_SUCCESS)
  625. {
  626. if (returnValue == ERROR_FILE_NOT_FOUND)
  627. {
  628. *SD = NULL;
  629. returnValue = CreateNewSD (SD);
  630. if (returnValue != ERROR_SUCCESS) {
  631. if (*SD)
  632. free(*SD);
  633. return returnValue;
  634. }
  635. *NewSD = TRUE;
  636. return ERROR_SUCCESS;
  637. } else
  638. return returnValue;
  639. }
  640. returnValue = RegQueryValueEx (registryKey, ValueName, NULL, &valueType, NULL, &valueSize);
  641. if (returnValue && returnValue != ERROR_INSUFFICIENT_BUFFER)
  642. {
  643. *SD = NULL;
  644. returnValue = CreateNewSD (SD);
  645. if (returnValue != ERROR_SUCCESS) {
  646. if (*SD)
  647. free(*SD);
  648. return returnValue;
  649. }
  650. *NewSD = TRUE;
  651. } else
  652. {
  653. *SD = (SECURITY_DESCRIPTOR *) malloc (valueSize);
  654. if (!*SD)
  655. {
  656. SetLastError(ERROR_NOT_ENOUGH_MEMORY);
  657. return GetLastError();
  658. }
  659. returnValue = RegQueryValueEx (registryKey,
  660. ValueName,
  661. NULL,
  662. &valueType,
  663. (LPBYTE) *SD,
  664. &valueSize);
  665. if (returnValue)
  666. {
  667. if (*SD)
  668. free (*SD);
  669. *SD = NULL;
  670. returnValue = CreateNewSD (SD);
  671. if (returnValue != ERROR_SUCCESS) {
  672. if (*SD){
  673. free(*SD);
  674. }
  675. if( NULL != registryKey ) {
  676. RegCloseKey(registryKey);
  677. }
  678. return returnValue;
  679. }
  680. *NewSD = TRUE;
  681. }
  682. }
  683. if( NULL != registryKey ) {
  684. RegCloseKey(registryKey);
  685. }
  686. return ERROR_SUCCESS;
  687. }
  688. DWORD
  689. AddPrincipalToNamedValueSD (
  690. HKEY RootKey,
  691. LPTSTR KeyName,
  692. LPTSTR ValueName,
  693. LPTSTR Principal,
  694. BOOL Permit
  695. )
  696. {
  697. DWORD returnValue = ERROR_SUCCESS;
  698. SECURITY_DESCRIPTOR *sd = NULL;
  699. SECURITY_DESCRIPTOR *sdSelfRelative = NULL;
  700. SECURITY_DESCRIPTOR *sdAbsolute = NULL;
  701. DWORD secDescSize;
  702. BOOL present;
  703. BOOL defaultDACL;
  704. PACL dacl;
  705. BOOL newSD = FALSE;
  706. BOOL fFreeAbsolute = TRUE;
  707. returnValue = GetNamedValueSD (RootKey, KeyName, ValueName, &sd, &newSD);
  708. //
  709. // Get security descriptor from registry or create a new one
  710. //
  711. if (returnValue != ERROR_SUCCESS)
  712. return returnValue;
  713. if (!GetSecurityDescriptorDacl (sd, &present, &dacl, &defaultDACL)) {
  714. returnValue = GetLastError();
  715. goto Cleanup;
  716. }
  717. if (newSD)
  718. {
  719. AddAccessAllowedACEToACL (&dacl, COM_RIGHTS_EXECUTE, TEXT("SYSTEM"));
  720. AddAccessAllowedACEToACL (&dacl, COM_RIGHTS_EXECUTE, TEXT("INTERACTIVE"));
  721. }
  722. //
  723. // Add the Principal that the caller wants added
  724. //
  725. if (Permit)
  726. returnValue = AddAccessAllowedACEToACL (&dacl, COM_RIGHTS_EXECUTE, Principal);
  727. else
  728. returnValue = AddAccessDeniedACEToACL (&dacl, GENERIC_ALL, Principal);
  729. if (returnValue != ERROR_SUCCESS)
  730. goto Cleanup;
  731. //
  732. // Make the security descriptor absolute if it isn't new
  733. //
  734. if (!newSD) {
  735. MakeSDAbsolute ((PSECURITY_DESCRIPTOR) sd, (PSECURITY_DESCRIPTOR *) &sdAbsolute);
  736. fFreeAbsolute = TRUE;
  737. } else {
  738. sdAbsolute = sd;
  739. fFreeAbsolute = FALSE;
  740. }
  741. //
  742. // Set the discretionary ACL on the security descriptor
  743. //
  744. if (!SetSecurityDescriptorDacl (sdAbsolute, TRUE, dacl, FALSE)) {
  745. returnValue = GetLastError();
  746. goto Cleanup;
  747. }
  748. //
  749. // Make the security descriptor self-relative so that we can
  750. // store it in the registry
  751. //
  752. secDescSize = 0;
  753. MakeSelfRelativeSD (sdAbsolute, sdSelfRelative, &secDescSize);
  754. sdSelfRelative = (SECURITY_DESCRIPTOR *) malloc (secDescSize);
  755. if (!sdSelfRelative)
  756. {
  757. SetLastError(ERROR_NOT_ENOUGH_MEMORY);
  758. returnValue = GetLastError();
  759. goto Cleanup;
  760. }
  761. if (!MakeSelfRelativeSD (sdAbsolute, sdSelfRelative, &secDescSize)) {
  762. returnValue = GetLastError();
  763. goto Cleanup;
  764. }
  765. //
  766. // Store the security descriptor in the registry
  767. //
  768. SetNamedValueSD (RootKey, KeyName, ValueName, sdSelfRelative);
  769. Cleanup:
  770. if (sd)
  771. free (sd);
  772. if (sdSelfRelative)
  773. free (sdSelfRelative);
  774. if (fFreeAbsolute && sdAbsolute)
  775. free (sdAbsolute);
  776. return returnValue;
  777. }
  778. DWORD
  779. RemovePrincipalFromNamedValueSD (
  780. HKEY RootKey,
  781. LPTSTR KeyName,
  782. LPTSTR ValueName,
  783. LPTSTR Principal
  784. )
  785. {
  786. DWORD returnValue = ERROR_SUCCESS;
  787. SECURITY_DESCRIPTOR *sd = NULL;
  788. SECURITY_DESCRIPTOR *sdSelfRelative = NULL;
  789. SECURITY_DESCRIPTOR *sdAbsolute = NULL;
  790. DWORD secDescSize;
  791. BOOL present;
  792. BOOL defaultDACL;
  793. PACL dacl = NULL;
  794. BOOL newSD = FALSE;
  795. BOOL fFreeAbsolute = TRUE;
  796. returnValue = GetNamedValueSD (RootKey, KeyName, ValueName, &sd, &newSD);
  797. //
  798. // Get security descriptor from registry or create a new one
  799. //
  800. if (returnValue != ERROR_SUCCESS)
  801. return returnValue;
  802. if (!GetSecurityDescriptorDacl (sd, &present, &dacl, &defaultDACL)) {
  803. returnValue = GetLastError();
  804. goto Cleanup;
  805. }
  806. //
  807. // If the security descriptor is new, add the required Principals to it
  808. //
  809. if (newSD)
  810. {
  811. AddAccessAllowedACEToACL (&dacl, COM_RIGHTS_EXECUTE, TEXT("SYSTEM"));
  812. AddAccessAllowedACEToACL (&dacl, COM_RIGHTS_EXECUTE, TEXT("INTERACTIVE"));
  813. }
  814. //
  815. // Remove the Principal that the caller wants removed
  816. //
  817. returnValue = RemovePrincipalFromACL (dacl, Principal);
  818. if (returnValue != ERROR_SUCCESS)
  819. goto Cleanup;
  820. //
  821. // Make the security descriptor absolute if it isn't new
  822. //
  823. if (!newSD) {
  824. MakeSDAbsolute ((PSECURITY_DESCRIPTOR) sd, (PSECURITY_DESCRIPTOR *) &sdAbsolute);
  825. fFreeAbsolute = TRUE;
  826. } else {
  827. sdAbsolute = sd;
  828. fFreeAbsolute = FALSE;
  829. }
  830. //
  831. // Set the discretionary ACL on the security descriptor
  832. //
  833. if (!SetSecurityDescriptorDacl (sdAbsolute, TRUE, dacl, FALSE)) {
  834. returnValue = GetLastError();
  835. goto Cleanup;
  836. }
  837. //
  838. // Make the security descriptor self-relative so that we can
  839. // store it in the registry
  840. //
  841. secDescSize = 0;
  842. MakeSelfRelativeSD (sdAbsolute, sdSelfRelative, &secDescSize);
  843. sdSelfRelative = (SECURITY_DESCRIPTOR *) malloc (secDescSize);
  844. if (!sdSelfRelative)
  845. {
  846. SetLastError(ERROR_NOT_ENOUGH_MEMORY);
  847. returnValue = GetLastError();
  848. goto Cleanup;
  849. }
  850. if (!MakeSelfRelativeSD (sdAbsolute, sdSelfRelative, &secDescSize)) {
  851. returnValue = GetLastError();
  852. goto Cleanup;
  853. }
  854. //
  855. // Store the security descriptor in the registry
  856. //
  857. SetNamedValueSD (RootKey, KeyName, ValueName, sdSelfRelative);
  858. Cleanup:
  859. if (sd)
  860. free (sd);
  861. if (sdSelfRelative)
  862. free (sdSelfRelative);
  863. if (fFreeAbsolute && sdAbsolute)
  864. free (sdAbsolute);
  865. return returnValue;
  866. }
  867. DWORD
  868. ChangeAppIDAccessACL (
  869. LPTSTR AppID,
  870. LPTSTR Principal,
  871. BOOL SetPrincipal,
  872. BOOL Permit
  873. )
  874. {
  875. TCHAR keyName [256];
  876. DWORD err;
  877. StringCbCopy(keyName,sizeof(keyName),TEXT("APPID\\"));
  878. StringCbCat(keyName,sizeof(keyName),AppID);
  879. if (SetPrincipal)
  880. {
  881. err = RemovePrincipalFromNamedValueSD (HKEY_CLASSES_ROOT,
  882. keyName,
  883. TEXT("AccessPermission"),
  884. Principal);
  885. err = AddPrincipalToNamedValueSD (HKEY_CLASSES_ROOT,
  886. keyName,
  887. TEXT("AccessPermission"),
  888. Principal,
  889. Permit);
  890. }
  891. else
  892. {
  893. err = RemovePrincipalFromNamedValueSD (HKEY_CLASSES_ROOT,
  894. keyName,
  895. TEXT("AccessPermission"),
  896. Principal);
  897. }
  898. return err;
  899. }
  900. DWORD
  901. ChangeAppIDLaunchACL (
  902. LPTSTR AppID,
  903. LPTSTR Principal,
  904. BOOL SetPrincipal,
  905. BOOL Permit
  906. )
  907. {
  908. TCHAR keyName [256];
  909. DWORD err;
  910. StringCbCopy(keyName,sizeof(keyName),TEXT("APPID\\"));
  911. StringCbCat(keyName,sizeof(keyName),AppID);
  912. if (SetPrincipal)
  913. {
  914. err = RemovePrincipalFromNamedValueSD (HKEY_CLASSES_ROOT,
  915. keyName,
  916. TEXT("LaunchPermission"),
  917. Principal);
  918. err = AddPrincipalToNamedValueSD (HKEY_CLASSES_ROOT,
  919. keyName,
  920. TEXT("LaunchPermission"),
  921. Principal,
  922. Permit);
  923. }
  924. else
  925. {
  926. err = RemovePrincipalFromNamedValueSD (HKEY_CLASSES_ROOT,
  927. keyName,
  928. TEXT("LaunchPermission"),
  929. Principal);
  930. }
  931. return err;
  932. }
  933. DWORD
  934. ChangeAppIDAuthenticationLevel(
  935. LPTSTR AppID,
  936. DWORD dwAuthenticationLevel
  937. )
  938. {
  939. // Simply set the registry setting for Authentication Level
  940. DWORD dwRetVal = ERROR_SUCCESS;
  941. TCHAR keyName[256];
  942. if( NULL == AppID )
  943. {
  944. return( ERROR_INVALID_PARAMETER );
  945. }
  946. if( AppID[0] == '{' )
  947. {
  948. StringCbPrintf(keyName,sizeof(keyName),_T("APPID\\%s"),AppID);
  949. }
  950. else
  951. {
  952. StringCbPrintf(keyName,sizeof(keyName),_T("APPID\\(%s)"),AppID);
  953. }
  954. // Now set the registry
  955. HKEY hKey = NULL;
  956. dwRetVal = RegOpenKeyEx( HKEY_CLASSES_ROOT, keyName, 0, KEY_WRITE, &hKey );
  957. if( ERROR_SUCCESS == dwRetVal )
  958. {
  959. dwRetVal = RegSetValueEx( hKey, _T("AuthenticationLevel"), 0, REG_DWORD, (BYTE *) &dwAuthenticationLevel, sizeof( DWORD ) );
  960. }
  961. if( NULL != hKey )
  962. {
  963. RegCloseKey( hKey );
  964. hKey = NULL;
  965. }
  966. return( dwRetVal );
  967. }