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.

1703 lines
51 KiB

  1. #include "stdafx.h"
  2. #include <conio.h>
  3. #include "dcomperm.h"
  4. #define _WIN32_DCOM
  5. #include <objbase.h>
  6. #define MY_DCOM_PERSIST_FLAG _T("PREEXIST")
  7. int IsValidDaclInSD(PSECURITY_DESCRIPTOR pSD)
  8. {
  9. int iReturn = TRUE;
  10. BOOL present = 0;
  11. BOOL defaultDACL = 0;
  12. PACL dacl = NULL;
  13. // Check if the SD is valid
  14. if (!IsValidSecurityDescriptor(pSD))
  15. {
  16. iisDebugOut((LOG_TYPE_ERROR, _T("IsValidDaclInSD:IsValidSecurityDescriptor FAILED")));
  17. iReturn = FALSE;
  18. }
  19. else
  20. {
  21. // Check if the dacl we got is valid...
  22. if (!GetSecurityDescriptorDacl (pSD, &present, &dacl, &defaultDACL))
  23. {
  24. iisDebugOut((LOG_TYPE_ERROR, _T("IsValidDaclInSD:GetSecurityDescriptorDacl FAILED")));
  25. iReturn = FALSE;
  26. }
  27. else
  28. {
  29. if (present)
  30. {
  31. // check if our sd is valid after call
  32. if (!IsValidSecurityDescriptor(pSD))
  33. {
  34. iisDebugOut((LOG_TYPE_ERROR, _T("IsValidDaclInSD:IsValidSecurityDescriptor FAILED")));
  35. iReturn = FALSE;
  36. }
  37. else
  38. {
  39. iisDebugOut((LOG_TYPE_TRACE_WIN32_API, _T("IsValidDaclInSD:SD has valid dacl")));
  40. }
  41. }
  42. }
  43. }
  44. return iReturn;
  45. }
  46. DWORD
  47. CopyACL (
  48. PACL OldACL,
  49. PACL NewACL
  50. )
  51. {
  52. ACL_SIZE_INFORMATION aclSizeInfo;
  53. LPVOID ace;
  54. ACE_HEADER *aceHeader;
  55. ULONG i;
  56. DWORD returnValue = ERROR_SUCCESS;
  57. if (0 == IsValidAcl(OldACL))
  58. {
  59. iisDebugOut((LOG_TYPE_ERROR, _T("CopyACL:IsValidAcl.FAILED.ACL is bad.")));
  60. returnValue = ERROR_INVALID_ACL;
  61. return returnValue;
  62. }
  63. if (0 == GetAclInformation (OldACL, (LPVOID) &aclSizeInfo, (DWORD) sizeof (aclSizeInfo), AclSizeInformation))
  64. {
  65. returnValue = GetLastError();
  66. iisDebugOut((LOG_TYPE_ERROR, _T("CopyACL:GetAclInformation.FAILED.Return=0x%x."), returnValue));
  67. return returnValue;
  68. }
  69. //
  70. // Copy all of the ACEs to the new ACL
  71. //
  72. for (i = 0; i < aclSizeInfo.AceCount; i++)
  73. {
  74. //
  75. // Get the ACE and header info
  76. //
  77. if (!GetAce (OldACL, i, &ace))
  78. {
  79. returnValue = GetLastError();
  80. iisDebugOut((LOG_TYPE_ERROR, _T("CopyACL:GetAce.FAILED.Return=0x%x."), returnValue));
  81. return returnValue;
  82. }
  83. aceHeader = (ACE_HEADER *) ace;
  84. //
  85. // Add the ACE to the new list
  86. //
  87. if (!AddAce (NewACL, ACL_REVISION, 0xffffffff, ace, aceHeader->AceSize))
  88. {
  89. returnValue = GetLastError();
  90. iisDebugOut((LOG_TYPE_ERROR, _T("CopyACL:AddAce.FAILED.Return=0x%x."), returnValue));
  91. return returnValue;
  92. }
  93. }
  94. return returnValue;
  95. }
  96. DWORD
  97. AddAccessDeniedACEToACL (
  98. PACL *Acl,
  99. DWORD PermissionMask,
  100. LPTSTR Principal
  101. )
  102. {
  103. ACL_SIZE_INFORMATION aclSizeInfo;
  104. int aclSize;
  105. DWORD returnValue = ERROR_SUCCESS;
  106. PSID principalSID = NULL;
  107. PACL newACL = NULL;
  108. PACL oldACL = NULL;
  109. BOOL bWellKnownSID = FALSE;
  110. oldACL = *Acl;
  111. returnValue = GetPrincipalSID (Principal, &principalSID, &bWellKnownSID);
  112. if (returnValue != ERROR_SUCCESS)
  113. return returnValue;
  114. if (0 == IsValidAcl(oldACL))
  115. {
  116. iisDebugOut((LOG_TYPE_ERROR, _T("AddAccessDeniedACEToACL:IsValidAcl.FAILED.ACL is bad.")));
  117. returnValue = ERROR_INVALID_ACL;
  118. return returnValue;
  119. }
  120. if (0 == GetAclInformation (oldACL, (LPVOID) &aclSizeInfo, (DWORD) sizeof (ACL_SIZE_INFORMATION), AclSizeInformation))
  121. {
  122. returnValue = GetLastError();
  123. goto cleanup;
  124. }
  125. aclSize = aclSizeInfo.AclBytesInUse +
  126. sizeof (ACL) + sizeof (ACCESS_DENIED_ACE) +
  127. GetLengthSid (principalSID) - sizeof (DWORD);
  128. newACL = (PACL) new BYTE [aclSize];
  129. if (!InitializeAcl (newACL, aclSize, ACL_REVISION))
  130. {
  131. returnValue = GetLastError();
  132. goto cleanup;
  133. }
  134. if (!AddAccessDeniedAce (newACL, ACL_REVISION, PermissionMask, principalSID))
  135. {
  136. returnValue = GetLastError();
  137. goto cleanup;
  138. }
  139. returnValue = CopyACL (oldACL, newACL);
  140. if (returnValue != ERROR_SUCCESS)
  141. {
  142. goto cleanup;
  143. }
  144. // cleanup old memory whose pointer we're replacing
  145. // okay to leak in setup... (need to comment out or else av's)
  146. //if (*Acl) {delete(*Acl);}
  147. *Acl = newACL;
  148. newACL = NULL;
  149. cleanup:
  150. if (principalSID) {
  151. if (bWellKnownSID)
  152. FreeSid (principalSID);
  153. else
  154. free (principalSID);
  155. }
  156. if (newACL)
  157. {
  158. delete [] newACL;
  159. newACL = NULL;
  160. }
  161. return returnValue;
  162. }
  163. DWORD
  164. AddAccessAllowedACEToACL (
  165. PACL *Acl,
  166. DWORD PermissionMask,
  167. LPTSTR Principal
  168. )
  169. {
  170. ACL_SIZE_INFORMATION aclSizeInfo;
  171. int aclSize;
  172. DWORD returnValue = ERROR_SUCCESS;
  173. PSID principalSID = NULL;
  174. PACL oldACL = NULL;
  175. PACL newACL = NULL;
  176. BOOL bWellKnownSID = FALSE;
  177. oldACL = *Acl;
  178. // check if the acl we got passed in is valid!
  179. if (0 == IsValidAcl(oldACL))
  180. {
  181. returnValue = ERROR_INVALID_ACL;
  182. iisDebugOut((LOG_TYPE_ERROR, _T("AddAccessAllowedACEToACL:IsValidAcl.FAILED.ACL we got passed in is bad1.")));
  183. goto cleanup;
  184. }
  185. returnValue = GetPrincipalSID (Principal, &principalSID, &bWellKnownSID);
  186. if (returnValue != ERROR_SUCCESS)
  187. {
  188. iisDebugOut((LOG_TYPE_ERROR, _T("GetPrincipalSID.FAILED.Return=0x%x."), returnValue));
  189. return returnValue;
  190. }
  191. if (0 == GetAclInformation (oldACL, (LPVOID) &aclSizeInfo, (DWORD) sizeof (ACL_SIZE_INFORMATION), AclSizeInformation))
  192. {
  193. returnValue = GetLastError();
  194. iisDebugOut((LOG_TYPE_ERROR, _T("GetAclInformation.FAILED.Return=0x%x."), returnValue));
  195. goto cleanup;
  196. }
  197. aclSize = aclSizeInfo.AclBytesInUse +
  198. sizeof (ACL) + sizeof (ACCESS_ALLOWED_ACE) +
  199. GetLengthSid (principalSID) - sizeof (DWORD);
  200. newACL = (PACL) new BYTE [aclSize];
  201. if (!InitializeAcl (newACL, aclSize, ACL_REVISION))
  202. {
  203. returnValue = GetLastError();
  204. iisDebugOut((LOG_TYPE_ERROR, _T("InitializeAcl.FAILED.Return=0x%x."), returnValue));
  205. goto cleanup;
  206. }
  207. returnValue = CopyACL (oldACL, newACL);
  208. if (returnValue != ERROR_SUCCESS)
  209. {
  210. iisDebugOut((LOG_TYPE_ERROR, _T("CopyACL.FAILED.Return=0x%x."), returnValue));
  211. goto cleanup;
  212. }
  213. //if (!AddAccessAllowedAce (newACL, ACL_REVISION2, PermissionMask, principalSID))
  214. if (!AddAccessAllowedAce (newACL, ACL_REVISION, PermissionMask, principalSID))
  215. {
  216. returnValue = GetLastError();
  217. iisDebugOut((LOG_TYPE_ERROR, _T("AddAccessAllowedAce.FAILED.Return=0x%x."), returnValue));
  218. goto cleanup;
  219. }
  220. // check if the acl is valid!
  221. /*
  222. if (0 == IsValidAcl(newACL))
  223. {
  224. returnValue = ERROR_INVALID_ACL;
  225. iisDebugOut((LOG_TYPE_ERROR, _T("AddAccessAllowedACEToACL:IsValidAcl.FAILED.ACL we are pasing out is bad.")));
  226. goto cleanup;
  227. }
  228. */
  229. // cleanup old memory whose pointer we're replacing
  230. // okay to leak in setup... (need to comment out or else av's)
  231. //if (*Acl) {delete(*Acl);}
  232. *Acl = newACL;
  233. newACL = NULL;
  234. cleanup:
  235. if (principalSID) {
  236. if (bWellKnownSID)
  237. FreeSid (principalSID);
  238. else
  239. free (principalSID);
  240. }
  241. if (newACL)
  242. {
  243. delete [] newACL;
  244. newACL = NULL;
  245. }
  246. return returnValue;
  247. }
  248. DWORD
  249. RemovePrincipalFromACL (
  250. PACL Acl,
  251. LPTSTR Principal,
  252. BOOL *pbUserExistsToBeDeleted
  253. )
  254. {
  255. ACL_SIZE_INFORMATION aclSizeInfo;
  256. ULONG i;
  257. LPVOID ace;
  258. ACCESS_ALLOWED_ACE *accessAllowedAce;
  259. ACCESS_DENIED_ACE *accessDeniedAce;
  260. SYSTEM_AUDIT_ACE *systemAuditAce;
  261. PSID principalSID = NULL;
  262. DWORD returnValue = ERROR_SUCCESS;
  263. ACE_HEADER *aceHeader;
  264. BOOL bWellKnownSID = FALSE;
  265. *pbUserExistsToBeDeleted = FALSE;
  266. returnValue = GetPrincipalSID (Principal, &principalSID, &bWellKnownSID);
  267. if (returnValue != ERROR_SUCCESS)
  268. return returnValue;
  269. // check if the acl we got passed in is valid!
  270. if (0 == IsValidAcl(Acl))
  271. {
  272. iisDebugOut((LOG_TYPE_ERROR, _T("RemovePrincipalFromACL:IsValidAcl.FAILED.ACL is bad.")));
  273. returnValue = ERROR_INVALID_ACL;
  274. return returnValue;
  275. }
  276. if (0 == GetAclInformation (Acl, (LPVOID) &aclSizeInfo, (DWORD) sizeof (ACL_SIZE_INFORMATION), AclSizeInformation))
  277. {
  278. returnValue = GetLastError();
  279. return returnValue;
  280. }
  281. for (i = 0; i < aclSizeInfo.AceCount; i++)
  282. {
  283. if (!GetAce (Acl, i, &ace))
  284. {
  285. returnValue = GetLastError();
  286. break;
  287. }
  288. aceHeader = (ACE_HEADER *) ace;
  289. if (aceHeader->AceType == ACCESS_ALLOWED_ACE_TYPE)
  290. {
  291. accessAllowedAce = (ACCESS_ALLOWED_ACE *) ace;
  292. if (EqualSid (principalSID, (PSID) &accessAllowedAce->SidStart))
  293. {
  294. DeleteAce (Acl, i);
  295. *pbUserExistsToBeDeleted = TRUE;
  296. break;
  297. }
  298. } else
  299. if (aceHeader->AceType == ACCESS_DENIED_ACE_TYPE)
  300. {
  301. accessDeniedAce = (ACCESS_DENIED_ACE *) ace;
  302. if (EqualSid (principalSID, (PSID) &accessDeniedAce->SidStart))
  303. {
  304. DeleteAce (Acl, i);
  305. *pbUserExistsToBeDeleted = TRUE;
  306. break;
  307. }
  308. } else
  309. if (aceHeader->AceType == SYSTEM_AUDIT_ACE_TYPE)
  310. {
  311. systemAuditAce = (SYSTEM_AUDIT_ACE *) ace;
  312. if (EqualSid (principalSID, (PSID) &systemAuditAce->SidStart))
  313. {
  314. DeleteAce (Acl, i);
  315. *pbUserExistsToBeDeleted = TRUE;
  316. break;
  317. }
  318. }
  319. }
  320. if (principalSID) {
  321. if (bWellKnownSID)
  322. FreeSid (principalSID);
  323. else
  324. free (principalSID);
  325. }
  326. return returnValue;
  327. }
  328. DWORD
  329. GetCurrentUserSID (
  330. PSID *Sid
  331. )
  332. {
  333. DWORD dwReturn = ERROR_SUCCESS;
  334. TOKEN_USER *tokenUser = NULL;
  335. HANDLE tokenHandle = NULL;
  336. DWORD tokenSize;
  337. DWORD sidLength;
  338. if (OpenProcessToken (GetCurrentProcess(), TOKEN_QUERY, &tokenHandle))
  339. {
  340. GetTokenInformation (tokenHandle, TokenUser, tokenUser, 0, &tokenSize);
  341. tokenUser = (TOKEN_USER *) malloc (tokenSize);
  342. if (!tokenUser)
  343. {
  344. SetLastError(ERROR_NOT_ENOUGH_MEMORY);
  345. return GetLastError();
  346. }
  347. if (GetTokenInformation (tokenHandle, TokenUser, tokenUser, tokenSize, &tokenSize))
  348. {
  349. sidLength = GetLengthSid (tokenUser->User.Sid);
  350. *Sid = (PSID) malloc (sidLength);
  351. if (*Sid)
  352. {
  353. memcpy (*Sid, tokenUser->User.Sid, sidLength);
  354. }
  355. CloseHandle (tokenHandle);
  356. } else
  357. dwReturn = GetLastError();
  358. if (tokenUser)
  359. free(tokenUser);
  360. } else
  361. dwReturn = GetLastError();
  362. return dwReturn;
  363. }
  364. DWORD
  365. GetPrincipalSID (
  366. LPTSTR Principal,
  367. PSID *Sid,
  368. BOOL *pbWellKnownSID
  369. )
  370. {
  371. iisDebugOut((LOG_TYPE_TRACE_WIN32_API, _T("GetPrincipalSID():Principal=%s\n"), Principal));
  372. DWORD returnValue=ERROR_SUCCESS;
  373. CString csPrincipal = Principal;
  374. SID_IDENTIFIER_AUTHORITY SidIdentifierNTAuthority = SECURITY_NT_AUTHORITY;
  375. SID_IDENTIFIER_AUTHORITY SidIdentifierWORLDAuthority = SECURITY_WORLD_SID_AUTHORITY;
  376. PSID_IDENTIFIER_AUTHORITY pSidIdentifierAuthority;
  377. BYTE Count;
  378. DWORD dwRID[8];
  379. *pbWellKnownSID = TRUE;
  380. memset(&(dwRID[0]), 0, 8 * sizeof(DWORD));
  381. csPrincipal.MakeLower();
  382. if ( csPrincipal.Find(_T("administrators")) != -1 ) {
  383. // Administrators group
  384. pSidIdentifierAuthority = &SidIdentifierNTAuthority;
  385. Count = 2;
  386. dwRID[0] = SECURITY_BUILTIN_DOMAIN_RID;
  387. dwRID[1] = DOMAIN_ALIAS_RID_ADMINS;
  388. } else if (csPrincipal.Find(_T("system")) != -1) {
  389. // SYSTEM
  390. pSidIdentifierAuthority = &SidIdentifierNTAuthority;
  391. Count = 1;
  392. dwRID[0] = SECURITY_LOCAL_SYSTEM_RID;
  393. } else if (csPrincipal.Find(_T("networkservice")) != -1) {
  394. // SYSTEM
  395. pSidIdentifierAuthority = &SidIdentifierNTAuthority;
  396. Count = 1;
  397. dwRID[0] = SECURITY_NETWORK_SERVICE_RID;
  398. } else if (csPrincipal.Find(_T("service")) != -1) {
  399. // SYSTEM
  400. pSidIdentifierAuthority = &SidIdentifierNTAuthority;
  401. Count = 1;
  402. dwRID[0] = SECURITY_LOCAL_SERVICE_RID;
  403. } else if (csPrincipal.Find(_T("interactive")) != -1) {
  404. // INTERACTIVE
  405. pSidIdentifierAuthority = &SidIdentifierNTAuthority;
  406. Count = 1;
  407. dwRID[0] = SECURITY_INTERACTIVE_RID;
  408. } else if (csPrincipal.Find(_T("everyone")) != -1) {
  409. // Everyone
  410. pSidIdentifierAuthority = &SidIdentifierWORLDAuthority;
  411. Count = 1;
  412. dwRID[0] = SECURITY_WORLD_RID;
  413. } else {
  414. *pbWellKnownSID = FALSE;
  415. }
  416. if (*pbWellKnownSID) {
  417. if ( !AllocateAndInitializeSid(pSidIdentifierAuthority,
  418. (BYTE)Count,
  419. dwRID[0],
  420. dwRID[1],
  421. dwRID[2],
  422. dwRID[3],
  423. dwRID[4],
  424. dwRID[5],
  425. dwRID[6],
  426. dwRID[7],
  427. Sid) ) {
  428. returnValue = GetLastError();
  429. }
  430. } else {
  431. // get regular account sid
  432. DWORD sidSize;
  433. TCHAR refDomain [256];
  434. DWORD refDomainSize;
  435. SID_NAME_USE snu;
  436. sidSize = 0;
  437. refDomainSize = 255;
  438. LookupAccountName (NULL,
  439. Principal,
  440. *Sid,
  441. &sidSize,
  442. refDomain,
  443. &refDomainSize,
  444. &snu);
  445. returnValue = GetLastError();
  446. if (returnValue == ERROR_INSUFFICIENT_BUFFER) {
  447. *Sid = (PSID) malloc (sidSize);
  448. if (!*Sid)
  449. {
  450. SetLastError(ERROR_NOT_ENOUGH_MEMORY);
  451. return GetLastError();
  452. }
  453. refDomainSize = 255;
  454. if (!LookupAccountName (NULL,
  455. Principal,
  456. *Sid,
  457. &sidSize,
  458. refDomain,
  459. &refDomainSize,
  460. &snu))
  461. {
  462. returnValue = GetLastError();
  463. } else {
  464. returnValue = ERROR_SUCCESS;
  465. }
  466. }
  467. }
  468. iisDebugOut((LOG_TYPE_TRACE_WIN32_API, _T("GetPrincipalSID():Ret=0x%x."), returnValue));
  469. return returnValue;
  470. }
  471. DWORD
  472. CreateNewSD (
  473. SECURITY_DESCRIPTOR **SD
  474. )
  475. {
  476. PACL dacl = NULL;
  477. DWORD sidLength;
  478. PSID sid;
  479. PSID groupSID;
  480. PSID ownerSID;
  481. DWORD returnValue;
  482. *SD = NULL;
  483. iisDebugOut((LOG_TYPE_TRACE_WIN32_API, _T("CreateNewSD()")));
  484. returnValue = GetCurrentUserSID (&sid);
  485. if (returnValue != ERROR_SUCCESS) {
  486. if (sid)
  487. free(sid);
  488. iisDebugOut((LOG_TYPE_ERROR, _T("CreateNewSD.FAILED1.Return=0x%x."), returnValue));
  489. return returnValue;
  490. }
  491. sidLength = GetLengthSid (sid);
  492. *SD = (SECURITY_DESCRIPTOR *) malloc (
  493. (sizeof (ACL)+sizeof (ACCESS_ALLOWED_ACE)+sidLength) +
  494. (2 * sidLength) +
  495. sizeof (SECURITY_DESCRIPTOR));
  496. if (!*SD)
  497. {
  498. SetLastError(ERROR_NOT_ENOUGH_MEMORY);
  499. returnValue = GetLastError();
  500. iisDebugOut((LOG_TYPE_ERROR, _T("CreateNewSD.FAILED2.Return=0x%x."), returnValue));
  501. return returnValue;
  502. }
  503. groupSID = (SID *) (*SD + 1);
  504. ownerSID = (SID *) (((BYTE *) groupSID) + sidLength);
  505. dacl = (ACL *) (((BYTE *) ownerSID) + sidLength);
  506. if (!InitializeSecurityDescriptor (*SD, SECURITY_DESCRIPTOR_REVISION))
  507. {
  508. free (*SD);
  509. free (sid);
  510. returnValue = GetLastError();
  511. iisDebugOut((LOG_TYPE_ERROR, _T("CreateNewSD.FAILED3.Return=0x%x."), returnValue));
  512. return returnValue;
  513. }
  514. if (!InitializeAcl (dacl,
  515. sizeof (ACL)+sizeof (ACCESS_ALLOWED_ACE)+sidLength,
  516. ACL_REVISION2))
  517. {
  518. free (*SD);
  519. free (sid);
  520. returnValue = GetLastError();
  521. iisDebugOut((LOG_TYPE_ERROR, _T("CreateNewSD.FAILED4.Return=0x%x."), returnValue));
  522. return returnValue;
  523. }
  524. if (!AddAccessAllowedAce (dacl,
  525. ACL_REVISION2,
  526. COM_RIGHTS_EXECUTE,
  527. sid))
  528. {
  529. free (*SD);
  530. free (sid);
  531. returnValue = GetLastError();
  532. iisDebugOut((LOG_TYPE_ERROR, _T("CreateNewSD.FAILED5.Return=0x%x."), returnValue));
  533. return returnValue;
  534. }
  535. if (!SetSecurityDescriptorDacl (*SD, TRUE, dacl, FALSE))
  536. {
  537. free (*SD);
  538. free (sid);
  539. returnValue = GetLastError();
  540. iisDebugOut((LOG_TYPE_ERROR, _T("CreateNewSD.FAILED6.Return=0x%x."), returnValue));
  541. return returnValue;
  542. }
  543. memcpy (groupSID, sid, sidLength);
  544. if (!SetSecurityDescriptorGroup (*SD, groupSID, FALSE))
  545. {
  546. free (*SD);
  547. free (sid);
  548. returnValue = GetLastError();
  549. iisDebugOut((LOG_TYPE_ERROR, _T("CreateNewSD.FAILED7.Return=0x%x."), returnValue));
  550. return returnValue;
  551. }
  552. memcpy (ownerSID, sid, sidLength);
  553. if (!SetSecurityDescriptorOwner (*SD, ownerSID, FALSE))
  554. {
  555. free (*SD);
  556. free (sid);
  557. returnValue = GetLastError();
  558. iisDebugOut((LOG_TYPE_ERROR, _T("CreateNewSD.FAILED8.Return=0x%x."), returnValue));
  559. return returnValue;
  560. }
  561. // check if everything went ok
  562. if (!IsValidSecurityDescriptor(*SD))
  563. {
  564. free (*SD);
  565. free (sid);
  566. returnValue = ERROR_INVALID_SECURITY_DESCR;
  567. iisDebugOut((LOG_TYPE_ERROR, _T("CreateNewSD.IsValidDaclInSD.FAILED.Return=0x%x."), returnValue));
  568. return returnValue;
  569. }
  570. if (sid)
  571. free(sid);
  572. return ERROR_SUCCESS;
  573. }
  574. DWORD
  575. MakeSDAbsolute (
  576. PSECURITY_DESCRIPTOR OldSD,
  577. PSECURITY_DESCRIPTOR *NewSD
  578. )
  579. {
  580. PSECURITY_DESCRIPTOR sd = NULL;
  581. DWORD descriptorSize;
  582. DWORD daclSize;
  583. DWORD saclSize;
  584. DWORD ownerSIDSize;
  585. DWORD groupSIDSize;
  586. PACL dacl = NULL;
  587. PACL sacl = NULL;
  588. PSID ownerSID = NULL;
  589. PSID groupSID = NULL;
  590. BOOL present;
  591. BOOL systemDefault;
  592. //
  593. // Get SACL
  594. //
  595. if (!GetSecurityDescriptorSacl (OldSD, &present, &sacl, &systemDefault))
  596. return GetLastError();
  597. if (sacl && present)
  598. {
  599. saclSize = sacl->AclSize;
  600. } else saclSize = 0;
  601. //
  602. // Get DACL
  603. //
  604. if (!GetSecurityDescriptorDacl (OldSD, &present, &dacl, &systemDefault))
  605. return GetLastError();
  606. if (dacl && present)
  607. {
  608. daclSize = dacl->AclSize;
  609. } else daclSize = 0;
  610. //
  611. // Get Owner
  612. //
  613. if (!GetSecurityDescriptorOwner (OldSD, &ownerSID, &systemDefault))
  614. return GetLastError();
  615. ownerSIDSize = GetLengthSid (ownerSID);
  616. //
  617. // Get Group
  618. //
  619. if (!GetSecurityDescriptorGroup (OldSD, &groupSID, &systemDefault))
  620. return GetLastError();
  621. groupSIDSize = GetLengthSid (groupSID);
  622. //
  623. // Do the conversion
  624. //
  625. descriptorSize = 0;
  626. MakeAbsoluteSD (OldSD, sd, &descriptorSize, dacl, &daclSize, sacl,
  627. &saclSize, ownerSID, &ownerSIDSize, groupSID,
  628. &groupSIDSize);
  629. sd = (PSECURITY_DESCRIPTOR) new BYTE [SECURITY_DESCRIPTOR_MIN_LENGTH];
  630. if (!sd)
  631. {
  632. SetLastError(ERROR_NOT_ENOUGH_MEMORY);
  633. return GetLastError();
  634. }
  635. if (!InitializeSecurityDescriptor (sd, SECURITY_DESCRIPTOR_REVISION))
  636. return GetLastError();
  637. if (!MakeAbsoluteSD (OldSD, sd, &descriptorSize, dacl, &daclSize, sacl,
  638. &saclSize, ownerSID, &ownerSIDSize, groupSID,
  639. &groupSIDSize))
  640. return GetLastError();
  641. *NewSD = sd;
  642. return ERROR_SUCCESS;
  643. }
  644. DWORD
  645. SetNamedValueSD (
  646. HKEY RootKey,
  647. LPTSTR KeyName,
  648. LPTSTR ValueName,
  649. SECURITY_DESCRIPTOR *SD
  650. )
  651. {
  652. DWORD returnValue;
  653. DWORD disposition;
  654. HKEY registryKey;
  655. //
  656. // Create new key or open existing key
  657. //
  658. returnValue = RegCreateKeyEx (RootKey, KeyName, 0, _T(""), 0, KEY_ALL_ACCESS, NULL, &registryKey, &disposition);
  659. if (returnValue != ERROR_SUCCESS)
  660. return returnValue;
  661. //
  662. // Write the security descriptor
  663. //
  664. returnValue = RegSetValueEx (registryKey, ValueName, 0, REG_BINARY, (LPBYTE) SD, GetSecurityDescriptorLength (SD));
  665. if (returnValue != ERROR_SUCCESS)
  666. return returnValue;
  667. RegCloseKey (registryKey);
  668. return ERROR_SUCCESS;
  669. }
  670. DWORD
  671. GetNamedValueSD (
  672. HKEY RootKey,
  673. LPTSTR KeyName,
  674. LPTSTR ValueName,
  675. SECURITY_DESCRIPTOR **SD,
  676. BOOL *NewSD,
  677. BOOL bCreateNewIfNotExist
  678. )
  679. {
  680. DWORD returnValue = E_FAIL;
  681. HKEY registryKey;
  682. DWORD valueType = 0;
  683. DWORD valueSize = 0;
  684. *NewSD = FALSE;
  685. //
  686. // Get the security descriptor from the named value. If it doesn't
  687. // exist, create a fresh one.
  688. //
  689. returnValue = RegOpenKeyEx (RootKey, KeyName, 0, KEY_ALL_ACCESS, &registryKey);
  690. if (returnValue != ERROR_SUCCESS)
  691. {
  692. if (returnValue == ERROR_FILE_NOT_FOUND)
  693. {
  694. // okay it doesn't exist
  695. // shall we create a new one???
  696. if (TRUE == bCreateNewIfNotExist)
  697. {
  698. *SD = NULL;
  699. returnValue = CreateNewSD (SD);
  700. if (returnValue != ERROR_SUCCESS)
  701. {
  702. if (*SD){free(*SD);*SD=NULL;}
  703. goto GetNamedValueSD_Exit;
  704. }
  705. *NewSD = TRUE;
  706. returnValue = ERROR_SUCCESS;
  707. //iisDebugOut((LOG_TYPE_TRACE_WIN32_API, _T("GetNamedValueSD:key not exist.New SD created")));
  708. goto GetNamedValueSD_Exit;
  709. }
  710. else
  711. {
  712. return ERROR_FILE_NOT_FOUND;
  713. }
  714. }
  715. else
  716. {
  717. goto GetNamedValueSD_Exit;
  718. }
  719. }
  720. returnValue = RegQueryValueEx (registryKey, ValueName, NULL, &valueType, NULL, &valueSize);
  721. if (returnValue && returnValue != ERROR_INSUFFICIENT_BUFFER)
  722. {
  723. if (returnValue == ERROR_FILE_NOT_FOUND)
  724. {
  725. // okay it doesn't exist
  726. // shall we create a new one???
  727. if (TRUE == bCreateNewIfNotExist)
  728. {
  729. *SD = NULL;
  730. returnValue = CreateNewSD (SD);
  731. if (returnValue != ERROR_SUCCESS)
  732. {
  733. if (*SD){free(*SD);*SD=NULL;}
  734. goto GetNamedValueSD_Exit;
  735. }
  736. //iisDebugOut((LOG_TYPE_TRACE_WIN32_API, _T("GetNamedValueSD:key exist, but value not found.New SD created")));
  737. *NewSD = TRUE;
  738. }
  739. else
  740. {
  741. return ERROR_FILE_NOT_FOUND;
  742. }
  743. }
  744. else
  745. {
  746. goto GetNamedValueSD_Exit;
  747. }
  748. }
  749. else
  750. {
  751. *SD = (SECURITY_DESCRIPTOR *) malloc (valueSize);
  752. if (!*SD)
  753. {
  754. SetLastError(ERROR_NOT_ENOUGH_MEMORY);
  755. returnValue = ERROR_NOT_ENOUGH_MEMORY;
  756. goto GetNamedValueSD_Exit;
  757. }
  758. // get the SD from the registry
  759. returnValue = RegQueryValueEx (registryKey, ValueName, NULL, &valueType, (LPBYTE) *SD, &valueSize);
  760. if (returnValue != ERROR_SUCCESS)
  761. {
  762. if (*SD){free(*SD);*SD=NULL;}
  763. *SD = NULL;
  764. returnValue = CreateNewSD (SD);
  765. if (returnValue != ERROR_SUCCESS)
  766. {
  767. if (*SD){free(*SD);*SD=NULL;}
  768. goto GetNamedValueSD_Exit;
  769. }
  770. //iisDebugOut((LOG_TYPE_TRACE_WIN32_API, _T("GetNamedValueSD:key exist,no mem.New SD created")));
  771. *NewSD = TRUE;
  772. }
  773. else
  774. {
  775. // otherwise, we successfully got the SD from an existing key!
  776. // let's test if the one we got is valid.
  777. // if it's not then log the error and create a new one.
  778. iisDebugOut((LOG_TYPE_TRACE_WIN32_API, _T("GetNamedValueSD:key exist using SD from reg")));
  779. // check if our sd we got or created is valid
  780. if (!IsValidDaclInSD(*SD))
  781. {
  782. returnValue = ERROR_INVALID_SECURITY_DESCR;
  783. iisDebugOut((LOG_TYPE_ERROR, _T("Security Descriptor at [%s\\%s] is not valid.creating a new one temporarily to work around problem"),KeyName,ValueName));
  784. // try to just create a new one!
  785. if (*SD){free(*SD);*SD=NULL;}
  786. *SD = NULL;
  787. returnValue = CreateNewSD (SD);
  788. if (returnValue != ERROR_SUCCESS)
  789. {
  790. if (*SD){free(*SD);*SD=NULL;}
  791. goto GetNamedValueSD_Exit;
  792. }
  793. *NewSD = TRUE;
  794. }
  795. }
  796. }
  797. RegCloseKey (registryKey);
  798. returnValue = ERROR_SUCCESS;
  799. GetNamedValueSD_Exit:
  800. return returnValue;
  801. }
  802. DWORD
  803. AddPrincipalToNamedValueSD (
  804. HKEY RootKey,
  805. LPTSTR KeyName,
  806. LPTSTR ValueName,
  807. LPTSTR Principal,
  808. BOOL Permit
  809. )
  810. {
  811. DWORD returnValue = ERROR_SUCCESS;
  812. SECURITY_DESCRIPTOR *sd = NULL;
  813. SECURITY_DESCRIPTOR *sdSelfRelative = NULL;
  814. SECURITY_DESCRIPTOR *sdAbsolute = NULL;
  815. DWORD secDescSize;
  816. BOOL present;
  817. BOOL defaultDACL;
  818. PACL dacl = NULL;
  819. BOOL newSD = FALSE;
  820. BOOL fFreeAbsolute = TRUE;
  821. BOOL fCreateNewSDIfOneInRegNotThere = TRUE;
  822. //
  823. // Get security descriptor from registry or create a new one
  824. //
  825. returnValue = GetNamedValueSD (RootKey, KeyName, ValueName, &sd, &newSD, fCreateNewSDIfOneInRegNotThere);
  826. if (returnValue != ERROR_SUCCESS)
  827. {
  828. iisDebugOut((LOG_TYPE_ERROR, _T("GetNamedValueSD.FAILED.Return=0x%x."), returnValue));
  829. return returnValue;
  830. }
  831. if (!GetSecurityDescriptorDacl (sd, &present, &dacl, &defaultDACL)) {
  832. returnValue = GetLastError();
  833. iisDebugOut((LOG_TYPE_ERROR, _T("GetSecurityDescriptorDacl.FAILED.Return=0x%x."), returnValue));
  834. goto Cleanup;
  835. }
  836. if (newSD)
  837. {
  838. returnValue = AddAccessAllowedACEToACL (&dacl, COM_RIGHTS_EXECUTE, _T("SYSTEM"));
  839. if (returnValue != ERROR_SUCCESS)
  840. {
  841. iisDebugOut((LOG_TYPE_ERROR, _T("AddAccessAllowedACEToACL(SYSTEM).FAILED.Return=0x%x."), returnValue));
  842. }
  843. returnValue = AddAccessAllowedACEToACL (&dacl, COM_RIGHTS_EXECUTE, _T("INTERACTIVE"));
  844. if (returnValue != ERROR_SUCCESS)
  845. {
  846. iisDebugOut((LOG_TYPE_ERROR, _T("AddAccessAllowedACEToACL(INTERACTIVE).FAILED.Return=0x%x."), returnValue));
  847. }
  848. }
  849. //
  850. // Add the Principal that the caller wants added
  851. //
  852. if (Permit)
  853. {
  854. returnValue = AddAccessAllowedACEToACL (&dacl, COM_RIGHTS_EXECUTE, Principal);
  855. if (returnValue != ERROR_SUCCESS)
  856. {
  857. iisDebugOut((LOG_TYPE_ERROR, _T("AddAccessAllowedACEToACL(%s).FAILED.Return=0x%x."), Principal,returnValue));
  858. }
  859. }
  860. else
  861. {
  862. returnValue = AddAccessDeniedACEToACL (&dacl, GENERIC_ALL, Principal);
  863. }
  864. if (returnValue != ERROR_SUCCESS)
  865. {
  866. goto Cleanup;
  867. }
  868. //
  869. // Make the security descriptor absolute if it isn't new
  870. //
  871. if (!newSD) {
  872. MakeSDAbsolute ((PSECURITY_DESCRIPTOR) sd, (PSECURITY_DESCRIPTOR *) &sdAbsolute);
  873. fFreeAbsolute = TRUE;
  874. } else {
  875. sdAbsolute = sd;
  876. fFreeAbsolute = FALSE;
  877. }
  878. //
  879. // Set the discretionary ACL on the security descriptor
  880. //
  881. if (!SetSecurityDescriptorDacl (sdAbsolute, TRUE, dacl, FALSE)) {
  882. returnValue = GetLastError();
  883. iisDebugOut((LOG_TYPE_ERROR, _T("SetSecurityDescriptorDacl.FAILED.Return=0x%x."), returnValue));
  884. goto Cleanup;
  885. }
  886. //
  887. // Make the security descriptor self-relative so that we can
  888. // store it in the registry
  889. //
  890. secDescSize = 0;
  891. MakeSelfRelativeSD (sdAbsolute, sdSelfRelative, &secDescSize);
  892. sdSelfRelative = (SECURITY_DESCRIPTOR *) malloc (secDescSize);
  893. if (!sdSelfRelative)
  894. {
  895. SetLastError(ERROR_NOT_ENOUGH_MEMORY);
  896. returnValue = GetLastError();
  897. iisDebugOut((LOG_TYPE_ERROR, _T("MakeSelfRelativeSD.FAILED.Return=0x%x."), returnValue));
  898. goto Cleanup;
  899. }
  900. if (!MakeSelfRelativeSD (sdAbsolute, sdSelfRelative, &secDescSize)) {
  901. returnValue = GetLastError();
  902. iisDebugOut((LOG_TYPE_ERROR, _T("MakeSelfRelativeSD.FAILED.Return=0x%x."), returnValue));
  903. goto Cleanup;
  904. }
  905. //
  906. // Store the security descriptor in the registry
  907. //
  908. returnValue = SetNamedValueSD (RootKey, KeyName, ValueName, sdSelfRelative);
  909. if (ERROR_SUCCESS != returnValue)
  910. {
  911. iisDebugOut((LOG_TYPE_ERROR, _T("SetNamedValueSD.FAILED.Return=0x%x."), returnValue));
  912. }
  913. Cleanup:
  914. if (sd)
  915. free (sd);
  916. if (sdSelfRelative)
  917. free (sdSelfRelative);
  918. if (fFreeAbsolute && sdAbsolute)
  919. free (sdAbsolute);
  920. //iisDebugOut((LOG_TYPE_TRACE_WIN32_API, _T("AddPrincipalToNamedValueSD:%s.end\n"), Principal));
  921. return returnValue;
  922. }
  923. DWORD
  924. RemovePrincipalFromNamedValueSD (
  925. HKEY RootKey,
  926. LPTSTR KeyName,
  927. LPTSTR ValueName,
  928. LPTSTR Principal,
  929. BOOL * pbUserExistsToBeDeleted
  930. )
  931. {
  932. DWORD returnValue = ERROR_SUCCESS;
  933. SECURITY_DESCRIPTOR *sd = NULL;
  934. SECURITY_DESCRIPTOR *sdSelfRelative = NULL;
  935. SECURITY_DESCRIPTOR *sdAbsolute = NULL;
  936. DWORD secDescSize;
  937. BOOL present;
  938. BOOL defaultDACL;
  939. PACL dacl = NULL;
  940. BOOL newSD = FALSE;
  941. BOOL fFreeAbsolute = TRUE;
  942. BOOL fCreateNewSDIfOneInRegNotThere = FALSE;
  943. *pbUserExistsToBeDeleted = FALSE;
  944. //
  945. returnValue = GetNamedValueSD (RootKey, KeyName, ValueName, &sd, &newSD, fCreateNewSDIfOneInRegNotThere);
  946. if (returnValue == ERROR_FILE_NOT_FOUND)
  947. {
  948. // this means that there is no SD in registry, so
  949. // there is nothing to remove from it, just exit with successs!
  950. returnValue = ERROR_SUCCESS;
  951. goto Cleanup;
  952. }
  953. //
  954. // Get security descriptor from registry or create a new one
  955. //
  956. if (returnValue != ERROR_SUCCESS)
  957. {
  958. return returnValue;
  959. }
  960. if (!GetSecurityDescriptorDacl (sd, &present, &dacl, &defaultDACL)) {
  961. returnValue = GetLastError();
  962. goto Cleanup;
  963. }
  964. // check if the acl we got passed in is valid!
  965. if (present && dacl)
  966. {
  967. if (0 == IsValidAcl(dacl))
  968. {
  969. returnValue = ERROR_INVALID_ACL;
  970. goto Cleanup;
  971. }
  972. }
  973. //
  974. // If the security descriptor is new, add the required Principals to it
  975. //
  976. if (newSD)
  977. {
  978. // but if this is a removal, then don't add system and interactive!
  979. // AddAccessAllowedACEToACL (&dacl, COM_RIGHTS_EXECUTE, _T("SYSTEM"));
  980. // AddAccessAllowedACEToACL (&dacl, COM_RIGHTS_EXECUTE, _T("INTERACTIVE"));
  981. }
  982. //
  983. // Remove the Principal that the caller wants removed
  984. //
  985. returnValue = RemovePrincipalFromACL (dacl, Principal,pbUserExistsToBeDeleted);
  986. if (returnValue != ERROR_SUCCESS)
  987. goto Cleanup;
  988. //
  989. // Make the security descriptor absolute if it isn't new
  990. //
  991. if (!newSD) {
  992. MakeSDAbsolute ((PSECURITY_DESCRIPTOR) sd, (PSECURITY_DESCRIPTOR *) &sdAbsolute);
  993. fFreeAbsolute = TRUE;
  994. } else {
  995. sdAbsolute = sd;
  996. fFreeAbsolute = FALSE;
  997. }
  998. //
  999. // Set the discretionary ACL on the security descriptor
  1000. //
  1001. if (!SetSecurityDescriptorDacl (sdAbsolute, TRUE, dacl, FALSE)) {
  1002. returnValue = GetLastError();
  1003. goto Cleanup;
  1004. }
  1005. //
  1006. // Make the security descriptor self-relative so that we can
  1007. // store it in the registry
  1008. //
  1009. secDescSize = 0;
  1010. MakeSelfRelativeSD (sdAbsolute, sdSelfRelative, &secDescSize);
  1011. sdSelfRelative = (SECURITY_DESCRIPTOR *) malloc (secDescSize);
  1012. if (!sdSelfRelative)
  1013. {
  1014. SetLastError(ERROR_NOT_ENOUGH_MEMORY);
  1015. returnValue = GetLastError();
  1016. goto Cleanup;
  1017. }
  1018. if (!MakeSelfRelativeSD (sdAbsolute, sdSelfRelative, &secDescSize)) {
  1019. returnValue = GetLastError();
  1020. goto Cleanup;
  1021. }
  1022. //
  1023. // Store the security descriptor in the registry
  1024. //
  1025. SetNamedValueSD (RootKey, KeyName, ValueName, sdSelfRelative);
  1026. Cleanup:
  1027. if (sd)
  1028. free (sd);
  1029. if (sdSelfRelative)
  1030. free (sdSelfRelative);
  1031. if (fFreeAbsolute && sdAbsolute)
  1032. free (sdAbsolute);
  1033. return returnValue;
  1034. }
  1035. DWORD
  1036. ChangeAppIDAccessACL (
  1037. LPTSTR AppID,
  1038. LPTSTR Principal,
  1039. BOOL SetPrincipal,
  1040. BOOL Permit,
  1041. BOOL bDumbCall
  1042. )
  1043. {
  1044. BOOL bUserExistsToBeDeleted = FALSE;
  1045. iisDebugOut((LOG_TYPE_TRACE_WIN32_API, _T("ChangeAppIDAccessACL():APPID=%s,Principal=%s. \n"), AppID, Principal));
  1046. TCHAR keyName [256];
  1047. DWORD err;
  1048. CString csKey;
  1049. CString csData;
  1050. if (AppID [0] == _T('{'))
  1051. _stprintf (keyName, _T("APPID\\%s"), AppID);
  1052. else
  1053. _stprintf (keyName, _T("APPID\\{%s}"), AppID);
  1054. csKey = keyName;
  1055. csKey += _T(":A:");
  1056. csKey += Principal;
  1057. if (SetPrincipal)
  1058. {
  1059. err = RemovePrincipalFromNamedValueSD (HKEY_CLASSES_ROOT, keyName, _T("AccessPermission"), Principal,&bUserExistsToBeDeleted);
  1060. if (TRUE == bUserExistsToBeDeleted)
  1061. {
  1062. // this means that in fact the user was already in there!
  1063. // so we now have to add it back in!
  1064. // we just want to make sure we know that it was already in there
  1065. // so when we do an uninstall -- we don't delete the value if it was already in there!
  1066. if (FALSE == bDumbCall)
  1067. {
  1068. // Do not set this on an upgrade!
  1069. if (g_pTheApp->m_eInstallMode != IM_UPGRADE)
  1070. {
  1071. g_pTheApp->UnInstallList_Add(csKey,MY_DCOM_PERSIST_FLAG);
  1072. }
  1073. }
  1074. }
  1075. err = AddPrincipalToNamedValueSD (HKEY_CLASSES_ROOT, keyName, _T("AccessPermission"), Principal, Permit);
  1076. if (FAILED(err))
  1077. {
  1078. iisDebugOut((LOG_TYPE_ERROR, _T("AddPrincipalToNamedValueSD():Principal=%s.End.FAILED.Return=0x%x."), Principal, err));
  1079. }
  1080. }
  1081. else
  1082. {
  1083. if (TRUE == bDumbCall)
  1084. {
  1085. csData = g_pTheApp->UnInstallList_QueryKey(csKey);
  1086. if (_tcsicmp(csData, MY_DCOM_PERSIST_FLAG) == 0)
  1087. {
  1088. // don't remove it!! it was already there before we even added it!
  1089. err = ERROR_SUCCESS;
  1090. }
  1091. else
  1092. {
  1093. err = RemovePrincipalFromNamedValueSD (HKEY_CLASSES_ROOT, keyName, _T("AccessPermission"), Principal,&bUserExistsToBeDeleted);
  1094. }
  1095. g_pTheApp->UnInstallList_DelKey(csKey);
  1096. }
  1097. else
  1098. {
  1099. err = RemovePrincipalFromNamedValueSD (HKEY_CLASSES_ROOT, keyName, _T("AccessPermission"), Principal,&bUserExistsToBeDeleted);
  1100. }
  1101. }
  1102. iisDebugOut((LOG_TYPE_TRACE_WIN32_API, _T("ChangeAppIDAccessACL():APPID=%s,Principal=%s. End. Return=0x%x\n"), AppID, Principal, err));
  1103. return err;
  1104. }
  1105. DWORD
  1106. ChangeAppIDLaunchACL (
  1107. LPTSTR AppID,
  1108. LPTSTR Principal,
  1109. BOOL SetPrincipal,
  1110. BOOL Permit,
  1111. BOOL bDumbCall
  1112. )
  1113. {
  1114. BOOL bUserExistsToBeDeleted = FALSE;
  1115. iisDebugOut((LOG_TYPE_TRACE_WIN32_API, _T("ChangeAppIDLaunchACL():APPID=%s,Principal=%s. Start."), AppID, Principal));
  1116. TCHAR keyName [256];
  1117. DWORD err;
  1118. CString csKey;
  1119. CString csData;
  1120. if (AppID [0] == _T('{'))
  1121. _stprintf (keyName, _T("APPID\\%s"), AppID);
  1122. else
  1123. _stprintf (keyName, _T("APPID\\{%s}"), AppID);
  1124. csKey = keyName;
  1125. csKey += _T(":L:");
  1126. csKey += Principal;
  1127. if (SetPrincipal)
  1128. {
  1129. err = RemovePrincipalFromNamedValueSD (HKEY_CLASSES_ROOT, keyName, _T("LaunchPermission"), Principal,&bUserExistsToBeDeleted);
  1130. if (TRUE == bUserExistsToBeDeleted)
  1131. {
  1132. // this means that in fact the user was already in there!
  1133. // so we now have to add it back in!
  1134. // we just want to make sure we know that it was already in there
  1135. // so when we do an uninstall -- we don't delete the value if it was already in there!
  1136. if (FALSE == bDumbCall)
  1137. {
  1138. // Do not set this on an upgrade!
  1139. if (g_pTheApp->m_eInstallMode != IM_UPGRADE)
  1140. {
  1141. g_pTheApp->UnInstallList_Add(csKey,MY_DCOM_PERSIST_FLAG);
  1142. }
  1143. }
  1144. }
  1145. err = AddPrincipalToNamedValueSD (HKEY_CLASSES_ROOT, keyName, _T("LaunchPermission"), Principal, Permit);
  1146. if (FAILED(err))
  1147. {
  1148. iisDebugOut((LOG_TYPE_ERROR, _T("AddPrincipalToNamedValueSD():Principal=%s.End.FAILED.Return=0x%x."), Principal, err));
  1149. }
  1150. }
  1151. else
  1152. {
  1153. if (TRUE == bDumbCall)
  1154. {
  1155. err = RemovePrincipalFromNamedValueSD (HKEY_CLASSES_ROOT, keyName, _T("LaunchPermission"), Principal,&bUserExistsToBeDeleted);
  1156. }
  1157. else
  1158. {
  1159. csData = g_pTheApp->UnInstallList_QueryKey(csKey);
  1160. if (_tcsicmp(csData, MY_DCOM_PERSIST_FLAG) == 0)
  1161. {
  1162. // don't remove it!! it was already there before we even added it!
  1163. err = ERROR_SUCCESS;
  1164. }
  1165. else
  1166. {
  1167. err = RemovePrincipalFromNamedValueSD (HKEY_CLASSES_ROOT, keyName, _T("LaunchPermission"), Principal,&bUserExistsToBeDeleted);
  1168. }
  1169. g_pTheApp->UnInstallList_DelKey(csKey);
  1170. }
  1171. }
  1172. iisDebugOut((LOG_TYPE_TRACE_WIN32_API, _T("ChangeAppIDLaunchACL():APPID=%s,Principal=%s.End. Return=0x%x"), AppID, Principal, err));
  1173. return err;
  1174. }
  1175. DWORD
  1176. ChangeDCOMAccessACL (
  1177. LPTSTR Principal,
  1178. BOOL SetPrincipal,
  1179. BOOL Permit,
  1180. BOOL bDumbCall
  1181. )
  1182. {
  1183. BOOL bUserExistsToBeDeleted = FALSE;
  1184. iisDebugOut((LOG_TYPE_TRACE_WIN32_API, _T("ChangeDCOMAccessACL():Principal=%s. Start.\n"), Principal));
  1185. TCHAR keyName [256] = _T("Software\\Microsoft\\OLE");
  1186. DWORD err;
  1187. CString csKey;
  1188. CString csData;
  1189. csKey = _T("DCOM_DA:");
  1190. csKey += Principal;
  1191. if (SetPrincipal)
  1192. {
  1193. err = RemovePrincipalFromNamedValueSD (HKEY_LOCAL_MACHINE, keyName, _T("DefaultAccessPermission"), Principal,&bUserExistsToBeDeleted);
  1194. if (TRUE == bUserExistsToBeDeleted)
  1195. {
  1196. // this means that in fact the user was already in there!
  1197. // so we now have to add it back in!
  1198. // we just want to make sure we know that it was already in there
  1199. // so when we do an uninstall -- we don't delete the value if it was already in there!
  1200. if (FALSE == bDumbCall)
  1201. {
  1202. // Do not set this on an upgrade!
  1203. if (g_pTheApp->m_eInstallMode != IM_UPGRADE)
  1204. {
  1205. g_pTheApp->UnInstallList_Add(csKey,MY_DCOM_PERSIST_FLAG);
  1206. }
  1207. }
  1208. }
  1209. err = AddPrincipalToNamedValueSD (HKEY_LOCAL_MACHINE, keyName, _T("DefaultAccessPermission"), Principal, Permit);
  1210. if (FAILED(err))
  1211. {
  1212. iisDebugOut((LOG_TYPE_ERROR, _T("ChangeDCOMAccessACL():Principal=%s.End.FAILED.Return=0x%x."), Principal, err));
  1213. }
  1214. }
  1215. else
  1216. {
  1217. // Should we remove this principle from there?
  1218. // we should only do it if we actually had added them.
  1219. // the problem is that before iis5.1 we didn't have this information
  1220. // so when we go look in the registry to find "DCOM_DA:iusr_computername", we won't find it
  1221. // because iis5.1 setup hasn't been run yet.
  1222. // if "DCOM_DA:IUSR_COMPUTERNAME" exists and it is = MY_DCOM_PERSIST_FLAG
  1223. // then do not allow the entry to be deleted!
  1224. // that's because iis5.1 when trying to add the entry -- found that it was already there!
  1225. if (TRUE == bDumbCall)
  1226. {
  1227. err = RemovePrincipalFromNamedValueSD (HKEY_LOCAL_MACHINE, keyName, _T("DefaultAccessPermission"), Principal,&bUserExistsToBeDeleted);
  1228. }
  1229. else
  1230. {
  1231. csData = g_pTheApp->UnInstallList_QueryKey(csKey);
  1232. if (_tcsicmp(csData, MY_DCOM_PERSIST_FLAG) == 0)
  1233. {
  1234. // don't remove it!! it was already there before we even added it!
  1235. err = ERROR_SUCCESS;
  1236. }
  1237. else
  1238. {
  1239. err = RemovePrincipalFromNamedValueSD (HKEY_LOCAL_MACHINE, keyName, _T("DefaultAccessPermission"), Principal,&bUserExistsToBeDeleted);
  1240. }
  1241. g_pTheApp->UnInstallList_DelKey(csKey);
  1242. }
  1243. }
  1244. iisDebugOut((LOG_TYPE_TRACE, _T("ChangeDCOMAccessACL():End.Return=0x%x"), err));
  1245. return err;
  1246. }
  1247. DWORD
  1248. ChangeDCOMLaunchACL (
  1249. LPTSTR Principal,
  1250. BOOL SetPrincipal,
  1251. BOOL Permit,
  1252. BOOL bDumbCall
  1253. )
  1254. {
  1255. BOOL bUserExistsToBeDeleted = FALSE;
  1256. iisDebugOut((LOG_TYPE_TRACE_WIN32_API, _T("ChangeDCOMLaunchACL():Principal=%s. Start.\n"), Principal));
  1257. TCHAR keyName [256] = _T("Software\\Microsoft\\OLE");
  1258. DWORD err;
  1259. CString csKey;
  1260. CString csData;
  1261. csKey = _T("DCOM_DL:");
  1262. csKey += Principal;
  1263. if (SetPrincipal)
  1264. {
  1265. err = RemovePrincipalFromNamedValueSD (HKEY_LOCAL_MACHINE, keyName, _T("DefaultLaunchPermission"), Principal,&bUserExistsToBeDeleted);
  1266. if (TRUE == bUserExistsToBeDeleted)
  1267. {
  1268. // this means that in fact the user was already in there!
  1269. // so we now have to add it back in!
  1270. // we just want to make sure we know that it was already in there
  1271. // so when we do an uninstall -- we don't delete the value if it was already in there!
  1272. if (FALSE == bDumbCall)
  1273. {
  1274. // Do not set this on an upgrade!
  1275. if (g_pTheApp->m_eInstallMode != IM_UPGRADE)
  1276. {
  1277. g_pTheApp->UnInstallList_Add(csKey,MY_DCOM_PERSIST_FLAG);
  1278. }
  1279. }
  1280. }
  1281. err = AddPrincipalToNamedValueSD (HKEY_LOCAL_MACHINE, keyName, _T("DefaultLaunchPermission"), Principal, Permit);
  1282. if (FAILED(err))
  1283. {
  1284. iisDebugOut((LOG_TYPE_ERROR, _T("ChangeDCOMLaunchACL():Principal=%s.End.FAILED.Return=0x%x"), Principal, err));
  1285. }
  1286. }
  1287. else
  1288. {
  1289. // Should we remove this principle from there?
  1290. // we should only do it if we actually had added them.
  1291. // the problem is that before iis5.1 we didn't have this information
  1292. // so when we go look in the registry to find "DCOM_DL:iusr_computername", we won't find it
  1293. // because iis5.1 setup hasn't been run yet.
  1294. // if "DCOM_DL:IUSR_COMPUTERNAME" exists and it is = MY_DCOM_PERSIST_FLAG
  1295. // then do not allow the entry to be deleted!
  1296. // that's because iis5.1 when trying to add the entry -- found that it was already there!
  1297. if (TRUE == bDumbCall)
  1298. {
  1299. err = RemovePrincipalFromNamedValueSD (HKEY_LOCAL_MACHINE, keyName, _T("DefaultLaunchPermission"), Principal,&bUserExistsToBeDeleted);
  1300. }
  1301. else
  1302. {
  1303. csData = g_pTheApp->UnInstallList_QueryKey(csKey);
  1304. if (_tcsicmp(csData, MY_DCOM_PERSIST_FLAG) == 0)
  1305. {
  1306. // don't remove it!! it was already there before we even added it!
  1307. err = ERROR_SUCCESS;
  1308. }
  1309. else
  1310. {
  1311. err = RemovePrincipalFromNamedValueSD (HKEY_LOCAL_MACHINE, keyName, _T("DefaultLaunchPermission"), Principal,&bUserExistsToBeDeleted);
  1312. }
  1313. g_pTheApp->UnInstallList_DelKey(csKey);
  1314. }
  1315. }
  1316. iisDebugOut((LOG_TYPE_TRACE, _T("ChangeDCOMLaunchACL():End.\n"), err));
  1317. return err;
  1318. }
  1319. BOOL
  1320. MakeAbsoluteCopyFromRelative(
  1321. PSECURITY_DESCRIPTOR psdOriginal,
  1322. PSECURITY_DESCRIPTOR* ppsdNew
  1323. )
  1324. {
  1325. // we have to find out whether the original is already self-relative
  1326. SECURITY_DESCRIPTOR_CONTROL sdc = 0;
  1327. PSECURITY_DESCRIPTOR psdAbsoluteCopy = NULL;
  1328. DWORD dwRevision = 0;
  1329. DWORD cb = 0;
  1330. PACL Dacl = NULL, Sacl = NULL;
  1331. BOOL bDefaulted;
  1332. PSID Owner = NULL, Group = NULL;
  1333. DWORD dwDaclSize = 0;
  1334. BOOL bDaclPresent = FALSE;
  1335. DWORD dwSaclSize = 0;
  1336. BOOL bSaclPresent = FALSE;
  1337. DWORD dwOwnerSize = 0;
  1338. DWORD dwPrimaryGroupSize = 0;
  1339. if( !IsValidSecurityDescriptor( psdOriginal ) ) {
  1340. return FALSE;
  1341. }
  1342. if( !GetSecurityDescriptorControl( psdOriginal, &sdc, &dwRevision ) ) {
  1343. DWORD err = GetLastError();
  1344. goto cleanup;
  1345. }
  1346. if( sdc & SE_SELF_RELATIVE ) {
  1347. // the original is in self-relative format, build an absolute copy
  1348. // get the dacl
  1349. if( !GetSecurityDescriptorDacl(
  1350. psdOriginal, // address of security descriptor
  1351. &bDaclPresent, // address of flag for presence of disc. ACL
  1352. &Dacl, // address of pointer to ACL
  1353. &bDefaulted // address of flag for default disc. ACL
  1354. )
  1355. ) {
  1356. goto cleanup;
  1357. }
  1358. // get the sacl
  1359. if( !GetSecurityDescriptorSacl(
  1360. psdOriginal, // address of security descriptor
  1361. &bSaclPresent, // address of flag for presence of disc. ACL
  1362. &Sacl, // address of pointer to ACL
  1363. &bDefaulted // address of flag for default disc. ACL
  1364. )
  1365. ) {
  1366. goto cleanup;
  1367. }
  1368. // get the owner
  1369. if( !GetSecurityDescriptorOwner(
  1370. psdOriginal, // address of security descriptor
  1371. &Owner, // address of pointer to owner security
  1372. // identifier (SID)
  1373. &bDefaulted // address of flag for default
  1374. )
  1375. ) {
  1376. goto cleanup;
  1377. }
  1378. // get the group
  1379. if( !GetSecurityDescriptorGroup(
  1380. psdOriginal, // address of security descriptor
  1381. &Group, // address of pointer to owner security
  1382. // identifier (SID)
  1383. &bDefaulted // address of flag for default
  1384. )
  1385. ) {
  1386. goto cleanup;
  1387. }
  1388. // get required buffer size
  1389. cb = 0;
  1390. MakeAbsoluteSD(
  1391. psdOriginal, // address of self-relative SD
  1392. psdAbsoluteCopy, // address of absolute SD
  1393. &cb, // address of size of absolute SD
  1394. NULL, // address of discretionary ACL
  1395. &dwDaclSize, // address of size of discretionary ACL
  1396. NULL, // address of system ACL
  1397. &dwSaclSize, // address of size of system ACL
  1398. NULL, // address of owner SID
  1399. &dwOwnerSize, // address of size of owner SID
  1400. NULL, // address of primary-group SID
  1401. &dwPrimaryGroupSize // address of size of group SID
  1402. );
  1403. // alloc the memory
  1404. psdAbsoluteCopy = (PSECURITY_DESCRIPTOR) malloc( cb );
  1405. Dacl = (PACL) malloc( dwDaclSize );
  1406. Sacl = (PACL) malloc( dwSaclSize );
  1407. Owner = (PSID) malloc( dwOwnerSize );
  1408. Group = (PSID) malloc( dwPrimaryGroupSize );
  1409. if(NULL == psdAbsoluteCopy ||
  1410. NULL == Dacl ||
  1411. NULL == Sacl ||
  1412. NULL == Owner ||
  1413. NULL == Group
  1414. ) {
  1415. goto cleanup;
  1416. }
  1417. // make the copy
  1418. if( !MakeAbsoluteSD(
  1419. psdOriginal, // address of self-relative SD
  1420. psdAbsoluteCopy, // address of absolute SD
  1421. &cb, // address of size of absolute SD
  1422. Dacl, // address of discretionary ACL
  1423. &dwDaclSize, // address of size of discretionary ACL
  1424. Sacl, // address of system ACL
  1425. &dwSaclSize, // address of size of system ACL
  1426. Owner, // address of owner SID
  1427. &dwOwnerSize, // address of size of owner SID
  1428. Group, // address of primary-group SID
  1429. &dwPrimaryGroupSize // address of size of group SID
  1430. )
  1431. ) {
  1432. goto cleanup;
  1433. }
  1434. } else {
  1435. // the original is in absolute format, fail
  1436. goto cleanup;
  1437. }
  1438. *ppsdNew = psdAbsoluteCopy;
  1439. // paranoia check
  1440. if( !IsValidSecurityDescriptor( *ppsdNew ) ) {
  1441. goto cleanup;
  1442. }
  1443. if( !IsValidSecurityDescriptor( psdOriginal ) ) {
  1444. goto cleanup;
  1445. }
  1446. return(TRUE);
  1447. cleanup:
  1448. if( Dacl != NULL && bDaclPresent == TRUE ) {
  1449. free((PVOID) Dacl );
  1450. Dacl = NULL;
  1451. }
  1452. if( Sacl != NULL && bSaclPresent == TRUE ) {
  1453. free((PVOID) Sacl );
  1454. Sacl = NULL;
  1455. }
  1456. if( Owner != NULL ) {
  1457. free((PVOID) Owner );
  1458. Owner = NULL;
  1459. }
  1460. if( Group != NULL ) {
  1461. free((PVOID) Group );
  1462. Group = NULL;
  1463. }
  1464. if( psdAbsoluteCopy != NULL ) {
  1465. free((PVOID) psdAbsoluteCopy );
  1466. psdAbsoluteCopy = NULL;
  1467. }
  1468. return (FALSE);
  1469. }