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.

1341 lines
32 KiB

  1. //******************************************************************************
  2. //
  3. // Microsoft Confidential. Copyright (c) Microsoft Corporation 1999. All rights reserved
  4. //
  5. // File: RsopSec.cpp
  6. //
  7. // Description: RSOP Namespace Security functions
  8. //
  9. // History: 8-26-99 leonardm Created
  10. //
  11. //******************************************************************************
  12. #include <windows.h>
  13. #include <objbase.h>
  14. #include <wbemcli.h>
  15. #include <accctrl.h>
  16. #include <aclapi.h>
  17. #include <lm.h>
  18. #include "RsopUtil.h"
  19. #include "RsopSec.h"
  20. #include "rsopdbg.h"
  21. #include "smartptr.h"
  22. //******************************************************************************
  23. //
  24. // Function:
  25. //
  26. // Description:
  27. //
  28. // Parameters:
  29. //
  30. // Return:
  31. //
  32. // History: 8-26-99 leonardm Created
  33. //
  34. //******************************************************************************
  35. STDMETHODIMP GetExplicitAccesses( long lSecurityLevel,
  36. EXPLICIT_ACCESS** ppExplicitAccess,
  37. DWORD* pdwCount,
  38. CWString* psTrustees)
  39. {
  40. WKSTA_INFO_100* pWkstaInfo = NULL;
  41. NET_API_STATUS status = NetWkstaGetInfo(NULL,100,(LPBYTE*)&pWkstaInfo);
  42. if(status != NERR_Success)
  43. {
  44. return E_FAIL;
  45. }
  46. CWString sCurrentDomain = pWkstaInfo->wki100_langroup;
  47. NetApiBufferFree(pWkstaInfo);
  48. if(!sCurrentDomain.ValidString() || sCurrentDomain == L"")
  49. {
  50. return E_FAIL;
  51. }
  52. static ACCESS_MODE AccessMode = GRANT_ACCESS;
  53. static DWORD Inheritance = SUB_CONTAINERS_ONLY_INHERIT;
  54. static DWORD AccessPermissions = WBEM_ENABLE |
  55. WBEM_METHOD_EXECUTE |
  56. WBEM_FULL_WRITE_REP |
  57. WBEM_PARTIAL_WRITE_REP |
  58. WBEM_WRITE_PROVIDER |
  59. WBEM_REMOTE_ACCESS |
  60. READ_CONTROL |
  61. WRITE_DAC;
  62. XPtrArray<EXPLICIT_ACCESS> xpExplicitAccess = NULL;
  63. if(lSecurityLevel == NAMESPACE_SECURITY_DIAGNOSTIC)
  64. {
  65. if(*pdwCount < 1)
  66. {
  67. *pdwCount = 1;
  68. return E_FAIL;
  69. }
  70. *pdwCount = 1;
  71. xpExplicitAccess = new EXPLICIT_ACCESS[*pdwCount];
  72. if(!xpExplicitAccess)
  73. {
  74. return E_OUTOFMEMORY;
  75. }
  76. psTrustees[0] = sCurrentDomain + L"\\Domain Users";
  77. if(!psTrustees[0].ValidString())
  78. {
  79. return E_OUTOFMEMORY;
  80. }
  81. BuildExplicitAccessWithName(&(xpExplicitAccess[0]),
  82. psTrustees[0],
  83. AccessPermissions,
  84. AccessMode,
  85. Inheritance);
  86. }
  87. else if(lSecurityLevel == NAMESPACE_SECURITY_PLANNING)
  88. {
  89. if(*pdwCount < 2)
  90. {
  91. *pdwCount = 2;
  92. return E_FAIL;
  93. }
  94. *pdwCount = 2;
  95. xpExplicitAccess = new EXPLICIT_ACCESS[*pdwCount];
  96. if(!xpExplicitAccess)
  97. {
  98. return E_OUTOFMEMORY;
  99. }
  100. psTrustees[0] = sCurrentDomain + L"\\RSOP Admins";
  101. if(!psTrustees[0].ValidString())
  102. {
  103. return E_OUTOFMEMORY;
  104. }
  105. BuildExplicitAccessWithName(&(xpExplicitAccess[0]),
  106. psTrustees[0],
  107. AccessPermissions,
  108. AccessMode,
  109. Inheritance);
  110. psTrustees[1] = sCurrentDomain + L"\\Domain Admins";
  111. if(!psTrustees[1].ValidString())
  112. {
  113. return E_OUTOFMEMORY;
  114. }
  115. BuildExplicitAccessWithName(&(xpExplicitAccess[1]),
  116. psTrustees[1],
  117. AccessPermissions,
  118. AccessMode,
  119. Inheritance);
  120. }
  121. else
  122. {
  123. return E_INVALIDARG;
  124. }
  125. *ppExplicitAccess = xpExplicitAccess.Acquire();
  126. return S_OK;
  127. }
  128. //******************************************************************************
  129. //
  130. // Function:
  131. //
  132. // Description:
  133. //
  134. // Parameters:
  135. //
  136. // Return:
  137. //
  138. // History: 8-26-99 leonardm Created
  139. //
  140. //******************************************************************************
  141. STDMETHODIMP ReplaceDaclOnSD(PSECURITY_DESCRIPTOR pSD, long lSecurityLevel)
  142. {
  143. HRESULT hr;
  144. XPtrArray<EXPLICIT_ACCESS> xpExplicitAccess = NULL;
  145. DWORD dwCount = 2;
  146. XPtrArray<CWString> xpTrustees = new CWString[dwCount];
  147. if(!xpTrustees)
  148. {
  149. return E_OUTOFMEMORY;
  150. }
  151. hr = GetExplicitAccesses(lSecurityLevel, &xpExplicitAccess, &dwCount, xpTrustees);
  152. if(FAILED(hr))
  153. {
  154. return hr;
  155. }
  156. //
  157. // Get the DACL of the Security descriptor
  158. //
  159. BOOL bDaclPresent;
  160. BOOL bDaclDefaulted;
  161. ACL* pAcl = NULL;
  162. BOOL bRes = GetSecurityDescriptorDacl(pSD, &bDaclPresent, &pAcl,&bDaclDefaulted);
  163. if(!bRes)
  164. {
  165. return E_FAIL;
  166. }
  167. if(bDaclPresent)
  168. {
  169. //
  170. // Get the count of existing ACEs
  171. //
  172. ACL_SIZE_INFORMATION info;
  173. bRes = GetAclInformation(pAcl, &info, sizeof(ACL_SIZE_INFORMATION), AclSizeInformation);
  174. if(!bRes)
  175. {
  176. return E_FAIL;
  177. }
  178. //
  179. // Remove existing ACEs from DACL
  180. //
  181. for(int aceIndex = info.AceCount - 1; aceIndex >= 0; aceIndex--)
  182. {
  183. bRes = DeleteAce(pAcl, aceIndex);
  184. if(!bRes)
  185. {
  186. return E_FAIL;
  187. }
  188. }
  189. LocalFree(pAcl);
  190. }
  191. pAcl = NULL;
  192. //
  193. // SetEntriesInAcl
  194. //
  195. DWORD dwRes = SetEntriesInAcl(dwCount, xpExplicitAccess, NULL, &pAcl);
  196. if(dwRes != ERROR_SUCCESS)
  197. {
  198. return E_FAIL;
  199. }
  200. //
  201. // SetSecurityDescriptorDacl
  202. //
  203. bRes = SetSecurityDescriptorDacl(pSD, bDaclPresent, pAcl, bDaclDefaulted);
  204. if(!bRes)
  205. {
  206. DWORD dwLastError = GetLastError();
  207. return E_FAIL;
  208. }
  209. return S_OK;
  210. }
  211. //******************************************************************************
  212. //
  213. // Function:
  214. //
  215. // Description:
  216. //
  217. // Parameters:
  218. //
  219. // Return:
  220. //
  221. // History: 8-26-99 leonardm Created
  222. //
  223. //******************************************************************************
  224. STDMETHODIMP RSoPMakeAbsoluteSD(SECURITY_DESCRIPTOR* pSelfRelativeSD, SECURITY_DESCRIPTOR** ppAbsoluteSD)
  225. {
  226. BOOL bRes = IsValidSecurityDescriptor(pSelfRelativeSD);
  227. if(!bRes)
  228. {
  229. return WBEM_E_INVALID_PARAMETER;
  230. }
  231. XPtrLF<SECURITY_DESCRIPTOR> xpAbsoluteSD;
  232. XPtrLF<ACL> xpDacl;
  233. XPtrLF<ACL> xpSacl;
  234. XPtrLF<SID> xpOwner;
  235. XPtrLF<SID> xpPrimaryGroup;
  236. DWORD dwAbsoluteSecurityDescriptorSize = 0;
  237. DWORD dwDaclSize = 0;
  238. DWORD dwSaclSize = 0;
  239. DWORD dwOwnerSize = 0;
  240. DWORD dwPrimaryGroupSize = 0;
  241. bRes = ::MakeAbsoluteSD(
  242. pSelfRelativeSD,
  243. xpAbsoluteSD,
  244. &dwAbsoluteSecurityDescriptorSize,
  245. xpDacl, // discretionary ACL
  246. &dwDaclSize, // size of discretionary ACL
  247. xpSacl, // system ACL
  248. &dwSaclSize, // size of system ACL
  249. xpOwner, // owner SID
  250. &dwOwnerSize, // size of owner SID
  251. xpPrimaryGroup, // primary-group SID
  252. &dwPrimaryGroupSize // size of group SID
  253. );
  254. DWORD dwLastError = GetLastError();
  255. if(dwLastError != ERROR_INSUFFICIENT_BUFFER)
  256. {
  257. return E_FAIL;
  258. }
  259. if(!dwAbsoluteSecurityDescriptorSize)
  260. {
  261. return E_FAIL;
  262. }
  263. xpAbsoluteSD = reinterpret_cast<SECURITY_DESCRIPTOR*>(LocalAlloc(LPTR, dwAbsoluteSecurityDescriptorSize));
  264. if(!xpAbsoluteSD)
  265. {
  266. return E_OUTOFMEMORY;
  267. }
  268. if(dwDaclSize)
  269. {
  270. xpDacl = reinterpret_cast<ACL*>(LocalAlloc(LPTR, dwDaclSize));
  271. if(!xpDacl)
  272. {
  273. return E_OUTOFMEMORY;
  274. }
  275. }
  276. if(dwSaclSize)
  277. {
  278. xpSacl = reinterpret_cast<ACL*>(LocalAlloc(LPTR, dwSaclSize));
  279. if(!xpSacl)
  280. {
  281. return E_OUTOFMEMORY;
  282. }
  283. }
  284. if(dwOwnerSize)
  285. {
  286. xpOwner = reinterpret_cast<SID*>(LocalAlloc(LPTR, dwOwnerSize));
  287. if(!xpOwner)
  288. {
  289. return E_OUTOFMEMORY;
  290. }
  291. }
  292. if(dwPrimaryGroupSize)
  293. {
  294. xpPrimaryGroup = reinterpret_cast<SID*>(LocalAlloc(LPTR, dwPrimaryGroupSize));
  295. if(!xpPrimaryGroup)
  296. {
  297. return E_OUTOFMEMORY;
  298. }
  299. }
  300. bRes = ::MakeAbsoluteSD(
  301. pSelfRelativeSD,
  302. xpAbsoluteSD,
  303. &dwAbsoluteSecurityDescriptorSize,
  304. xpDacl, // discretionary ACL
  305. &dwDaclSize, // size of discretionary ACL
  306. xpSacl, // system ACL
  307. &dwSaclSize, // size of system ACL
  308. xpOwner, // owner SID
  309. &dwOwnerSize, // size of owner SID
  310. xpPrimaryGroup, // primary-group SID
  311. &dwPrimaryGroupSize // size of group SID
  312. );
  313. if(!bRes)
  314. {
  315. return E_FAIL;
  316. }
  317. bRes = IsValidSecurityDescriptor(xpAbsoluteSD);
  318. if(!bRes)
  319. {
  320. return E_FAIL;
  321. }
  322. xpDacl.Acquire();
  323. xpSacl.Acquire();
  324. xpOwner.Acquire();
  325. xpPrimaryGroup.Acquire();
  326. *ppAbsoluteSD = xpAbsoluteSD.Acquire();
  327. return S_OK;
  328. }
  329. //******************************************************************************
  330. //
  331. // Function:
  332. //
  333. // Description:
  334. //
  335. // Parameters:
  336. //
  337. // Return:
  338. //
  339. // History: 8-26-99 leonardm Created
  340. //
  341. //******************************************************************************
  342. STDMETHODIMP FreeAbsoluteSD(SECURITY_DESCRIPTOR* pAbsoluteSD)
  343. {
  344. if(!pAbsoluteSD)
  345. {
  346. return E_POINTER;
  347. }
  348. BOOL bRes;
  349. BOOL bDaclPresent;
  350. BOOL bDaclDefaulted;
  351. XPtrLF<ACL> xpDacl;
  352. bRes = GetSecurityDescriptorDacl( pAbsoluteSD,
  353. &bDaclPresent,
  354. &xpDacl,
  355. &bDaclDefaulted);
  356. if(!bRes)
  357. {
  358. return E_FAIL;
  359. }
  360. BOOL bSaclPresent;
  361. BOOL bSaclDefaulted;
  362. XPtrLF<ACL> xpSacl;
  363. bRes = GetSecurityDescriptorSacl( pAbsoluteSD,
  364. &bSaclPresent,
  365. &xpSacl,
  366. &bSaclDefaulted);
  367. if(!bRes)
  368. {
  369. return E_FAIL;
  370. }
  371. BOOL bOwnerDefaulted;
  372. XPtrLF<SID>xpOwner;
  373. bRes = GetSecurityDescriptorOwner(pAbsoluteSD, reinterpret_cast<void**>(&xpOwner), &bOwnerDefaulted);
  374. if(!bRes)
  375. {
  376. return E_FAIL;
  377. }
  378. BOOL bGroupDefaulted;
  379. XPtrLF<SID>xpPrimaryGroup;
  380. bRes = GetSecurityDescriptorGroup(pAbsoluteSD, reinterpret_cast<void**>(&xpPrimaryGroup), &bGroupDefaulted);
  381. if(!bRes)
  382. {
  383. return E_FAIL;
  384. }
  385. return S_OK;
  386. }
  387. //******************************************************************************
  388. //
  389. // Function:
  390. //
  391. // Description:
  392. //
  393. // Parameters:
  394. //
  395. // Return:
  396. //
  397. // History: 8-26-99 leonardm Created
  398. //
  399. //******************************************************************************
  400. STDMETHODIMP GetNamespaceSD(IWbemServices* pWbemServices, SECURITY_DESCRIPTOR** ppSD)
  401. {
  402. if(!pWbemServices)
  403. {
  404. return E_POINTER;
  405. }
  406. HRESULT hr;
  407. XInterface<IWbemClassObject> xpOutParams;
  408. const BSTR bstrInstancePath = SysAllocString(L"__systemsecurity=@");
  409. if(!bstrInstancePath)
  410. {
  411. return E_OUTOFMEMORY;
  412. }
  413. const BSTR bstrMethodName = SysAllocString(L"GetSD");
  414. if(!bstrMethodName)
  415. {
  416. SysFreeString(bstrInstancePath);
  417. return E_OUTOFMEMORY;
  418. }
  419. hr = pWbemServices->ExecMethod( bstrInstancePath,
  420. bstrMethodName,
  421. 0,
  422. NULL,
  423. NULL,
  424. &xpOutParams,
  425. NULL);
  426. SysFreeString(bstrInstancePath);
  427. SysFreeString(bstrMethodName);
  428. if(FAILED(hr))
  429. {
  430. return hr;
  431. }
  432. VARIANT v;
  433. XVariant xv(&v);
  434. VariantInit(&v);
  435. hr = xpOutParams->Get(L"sd", 0, &v, NULL, NULL);
  436. if(FAILED(hr))
  437. {
  438. return hr;
  439. }
  440. if(v.vt != (VT_ARRAY | VT_UI1))
  441. {
  442. return E_FAIL;
  443. }
  444. long lLowerBound;
  445. hr = SafeArrayGetLBound(v.parray, 1, &lLowerBound);
  446. if(FAILED(hr))
  447. {
  448. return hr;
  449. }
  450. long lUpperBound;
  451. hr = SafeArrayGetUBound(v.parray, 1, &lUpperBound);
  452. if(FAILED(hr))
  453. {
  454. return hr;
  455. }
  456. DWORD dwSize = static_cast<DWORD>(lUpperBound - lLowerBound + 1);
  457. XPtrLF<SECURITY_DESCRIPTOR> xpSelfRelativeSD = static_cast<SECURITY_DESCRIPTOR*>(LocalAlloc(LPTR, dwSize));
  458. if(!xpSelfRelativeSD)
  459. {
  460. return E_OUTOFMEMORY;
  461. }
  462. BYTE* pSrc;
  463. hr = SafeArrayAccessData(v.parray, reinterpret_cast<void**>(&pSrc));
  464. if(FAILED(hr))
  465. {
  466. return hr;
  467. }
  468. CopyMemory(xpSelfRelativeSD, pSrc, dwSize);
  469. hr = SafeArrayUnaccessData(v.parray);
  470. if(FAILED(hr))
  471. {
  472. return hr;
  473. }
  474. *ppSD = xpSelfRelativeSD.Acquire();
  475. return S_OK;
  476. }
  477. //******************************************************************************
  478. //
  479. // Function:
  480. //
  481. // Description:
  482. //
  483. // Parameters:
  484. //
  485. // Return:
  486. //
  487. // History: 8/20/99 leonardm Created.
  488. //
  489. //******************************************************************************
  490. STDMETHODIMP SetNamespaceSD(SECURITY_DESCRIPTOR* pSD, IWbemServices* pWbemServices)
  491. {
  492. if(!pWbemServices)
  493. {
  494. return E_POINTER;
  495. }
  496. HRESULT hr;
  497. //
  498. // Get the class object
  499. //
  500. XInterface<IWbemClassObject> xpClass;
  501. BSTR bstrClassPath = SysAllocString(L"__systemsecurity");
  502. if(!bstrClassPath)
  503. {
  504. return E_OUTOFMEMORY;
  505. }
  506. hr = pWbemServices->GetObject(bstrClassPath, 0, NULL, &xpClass, NULL);
  507. SysFreeString(bstrClassPath);
  508. if(FAILED(hr))
  509. {
  510. return hr;
  511. }
  512. //
  513. // Get the input parameter class
  514. //
  515. XInterface<IWbemClassObject> xpMethod;
  516. hr = xpClass->GetMethod(L"SetSD", 0, &xpMethod, NULL);
  517. if(FAILED(hr))
  518. {
  519. return hr;
  520. }
  521. //
  522. // move the SD into a variant.
  523. //
  524. SAFEARRAYBOUND rgsabound[1];
  525. rgsabound[0].lLbound = 0;
  526. DWORD dwLength = GetSecurityDescriptorLength(pSD);
  527. rgsabound[0].cElements = dwLength;
  528. SAFEARRAY* psa = SafeArrayCreate(VT_UI1, 1, rgsabound);
  529. if(!psa)
  530. {
  531. return E_FAIL;
  532. }
  533. BYTE* pDest = NULL;
  534. hr = SafeArrayAccessData(psa, reinterpret_cast<void**>(&pDest));
  535. if(FAILED(hr))
  536. {
  537. return hr;
  538. }
  539. CopyMemory(pDest, pSD, dwLength);
  540. hr = SafeArrayUnaccessData(psa);
  541. if(FAILED(hr))
  542. {
  543. return hr;
  544. }
  545. VARIANT v;
  546. XVariant xv(&v);
  547. v.vt = VT_UI1|VT_ARRAY;
  548. v.parray = psa;
  549. //
  550. // put the property
  551. //
  552. XInterface<IWbemClassObject> xpInParam;
  553. hr = xpMethod->SpawnInstance(0, &xpInParam);
  554. if(FAILED(hr))
  555. {
  556. return hr;
  557. }
  558. hr = xpInParam->Put(L"sd" , 0, &v, 0);
  559. if(FAILED(hr))
  560. {
  561. return hr;
  562. }
  563. //
  564. // Execute the method
  565. //
  566. BSTR bstrInstancePath = SysAllocString(L"__systemsecurity=@");
  567. if(!bstrInstancePath)
  568. {
  569. return E_OUTOFMEMORY;
  570. }
  571. BSTR bstrMethodName = SysAllocString(L"SetSD");
  572. if(!bstrMethodName)
  573. {
  574. SysFreeString(bstrInstancePath);
  575. return E_OUTOFMEMORY;
  576. }
  577. hr = pWbemServices->ExecMethod( bstrInstancePath,
  578. bstrMethodName,
  579. 0,
  580. NULL,
  581. xpInParam,
  582. NULL,
  583. NULL);
  584. SysFreeString(bstrInstancePath);
  585. SysFreeString(bstrMethodName);
  586. return hr;
  587. }
  588. //******************************************************************************
  589. //
  590. // Function:
  591. //
  592. // Description:
  593. //
  594. // Parameters:
  595. //
  596. // Return:
  597. //
  598. // History: 8/20/99 leonardm Created.
  599. //
  600. //******************************************************************************
  601. HRESULT SetNamespaceSecurity(const WCHAR* pszNamespace,
  602. long lSecurityLevel,
  603. IWbemServices* pWbemServices)
  604. {
  605. HRESULT hr;
  606. if(!pszNamespace)
  607. {
  608. return E_POINTER;
  609. }
  610. CWString sNamespace = pszNamespace;
  611. if(!sNamespace.ValidString() || sNamespace == L"" || !pWbemServices)
  612. {
  613. return E_INVALIDARG;
  614. }
  615. XPtrLF<SECURITY_DESCRIPTOR> xpOrgSelfRelativeSD;
  616. hr = GetNamespaceSD(pWbemServices, &xpOrgSelfRelativeSD);
  617. if(FAILED(hr))
  618. {
  619. return hr;
  620. }
  621. SECURITY_DESCRIPTOR* pAbsoluteSD = NULL;
  622. hr = RSoPMakeAbsoluteSD(xpOrgSelfRelativeSD, &pAbsoluteSD);
  623. if(FAILED(hr))
  624. {
  625. return hr;
  626. }
  627. hr = ReplaceDaclOnSD(pAbsoluteSD, lSecurityLevel);
  628. if(FAILED(hr))
  629. {
  630. FreeAbsoluteSD(pAbsoluteSD);
  631. return hr;
  632. }
  633. //
  634. // Make a new self-relative SD here before proceeding.
  635. //
  636. DWORD dwBufferLength = 0;
  637. MakeSelfRelativeSD( pAbsoluteSD, NULL,&dwBufferLength);
  638. DWORD dwLastError = GetLastError();
  639. if((dwLastError != ERROR_INSUFFICIENT_BUFFER) || !dwBufferLength)
  640. {
  641. FreeAbsoluteSD(pAbsoluteSD);
  642. return E_FAIL;
  643. }
  644. XPtrLF<SECURITY_DESCRIPTOR> xpNewSelfRelativeSD = reinterpret_cast<SECURITY_DESCRIPTOR*>(LocalAlloc(LPTR, dwBufferLength));
  645. if(!xpNewSelfRelativeSD)
  646. {
  647. FreeAbsoluteSD(pAbsoluteSD);
  648. return E_OUTOFMEMORY;
  649. }
  650. BOOL bRes = MakeSelfRelativeSD( pAbsoluteSD, xpNewSelfRelativeSD, &dwBufferLength);
  651. hr = FreeAbsoluteSD(pAbsoluteSD);
  652. if(!bRes || FAILED(hr))
  653. {
  654. return E_FAIL;
  655. }
  656. xpNewSelfRelativeSD->Control |= SE_DACL_PROTECTED;
  657. bRes = IsValidSecurityDescriptor(xpNewSelfRelativeSD);
  658. if(!bRes)
  659. {
  660. return E_FAIL;
  661. }
  662. hr = SetNamespaceSD( xpNewSelfRelativeSD, pWbemServices);
  663. return hr;
  664. }
  665. #undef dbg
  666. #define dbg dbgCommon
  667. const DWORD DEFAULT_ACE_NUM=10;
  668. CSecDesc::CSecDesc() :
  669. m_cAces(0), m_xpSidList(NULL),
  670. m_cAllocated(0), m_bInitialised(FALSE), m_bFailed(FALSE)
  671. {
  672. m_xpSidList = (SidStruct *)LocalAlloc(LPTR, sizeof(SidStruct)*DEFAULT_ACE_NUM);
  673. if (!m_xpSidList)
  674. return;
  675. m_cAllocated = DEFAULT_ACE_NUM;
  676. m_bInitialised = TRUE;
  677. }
  678. CSecDesc::~CSecDesc()
  679. {
  680. if (m_xpSidList)
  681. for (DWORD i = 0; i < m_cAllocated; i++)
  682. if (m_xpSidList[i].pSid)
  683. if (m_xpSidList[i].bUseLocalFree)
  684. LocalFree(m_xpSidList[i].pSid);
  685. else
  686. FreeSid(m_xpSidList[i].pSid);
  687. }
  688. BOOL CSecDesc::ReAllocSidList()
  689. {
  690. XPtrLF<SidStruct> xSidListNew;
  691. //
  692. // first allocate a larger buffer
  693. //
  694. xSidListNew = (SidStruct *)LocalAlloc(LPTR, sizeof(SidStruct)*(m_cAllocated+DEFAULT_ACE_NUM));
  695. if (!xSidListNew) {
  696. dbg.Msg( DEBUG_MESSAGE_WARNING, L"CSecDesc::ReallocArgStrings Cannot add memory, error = %d", GetLastError());
  697. m_bFailed = TRUE;
  698. return FALSE;
  699. }
  700. //
  701. // copy the arguments
  702. //
  703. for (DWORD i = 0; i < (m_cAllocated); i++) {
  704. xSidListNew[i] = m_xpSidList[i];
  705. }
  706. m_xpSidList = xSidListNew.Acquire();
  707. m_cAllocated+= DEFAULT_ACE_NUM;
  708. return TRUE;
  709. }
  710. BOOL CSecDesc::AddLocalSystem(DWORD dwAccess, DWORD AceFlags)
  711. {
  712. SID_IDENTIFIER_AUTHORITY authNT = SECURITY_NT_AUTHORITY;
  713. XPtr<SID, FreeSid> xSid;
  714. if ((!m_bInitialised) || (m_bFailed)) {
  715. dbg.Msg( DEBUG_MESSAGE_WARNING, L"AddLocalSystem: Not initialised or failure.");
  716. return FALSE;
  717. }
  718. m_bFailed = TRUE;
  719. if (!AllocateAndInitializeSid(&authNT, 1, SECURITY_LOCAL_SYSTEM_RID,
  720. 0, 0, 0, 0, 0, 0, 0, (PSID *)&xSid)) {
  721. dbg.Msg( DEBUG_MESSAGE_WARNING, L"AddLocalSystem: Failed to initialize sid. Error = %d", GetLastError());
  722. return FALSE;
  723. }
  724. if (m_cAces == m_cAllocated)
  725. if (!ReAllocSidList())
  726. return FALSE;
  727. m_xpSidList[m_cAces].pSid = xSid.Acquire();
  728. m_xpSidList[m_cAces].dwAccess = dwAccess;
  729. m_xpSidList[m_cAces].AceFlags = AceFlags;
  730. m_cAces++;
  731. m_bFailed = FALSE;
  732. return TRUE;
  733. }
  734. BOOL CSecDesc::AddAdministrators(DWORD dwAccess, DWORD AceFlags)
  735. {
  736. SID_IDENTIFIER_AUTHORITY authNT = SECURITY_NT_AUTHORITY;
  737. XPtr<SID, FreeSid> xSid;
  738. if ((!m_bInitialised) || (m_bFailed)) {
  739. dbg.Msg( DEBUG_MESSAGE_WARNING, L"AddAdministrators: Not initialised or failure.");
  740. return FALSE;
  741. }
  742. m_bFailed = TRUE;
  743. if (!AllocateAndInitializeSid(&authNT, 2, SECURITY_BUILTIN_DOMAIN_RID,
  744. DOMAIN_ALIAS_RID_ADMINS, 0, 0,
  745. 0, 0, 0, 0, (PSID *)&xSid)) {
  746. dbg.Msg( DEBUG_MESSAGE_WARNING, L"AddAdministrators: Failed to initialize sid. Error = %d", GetLastError());
  747. return FALSE;
  748. }
  749. if (m_cAces == m_cAllocated)
  750. if (!ReAllocSidList())
  751. return FALSE;
  752. m_xpSidList[m_cAces].pSid = xSid.Acquire();
  753. m_xpSidList[m_cAces].dwAccess = dwAccess;
  754. m_xpSidList[m_cAces].AceFlags = AceFlags;
  755. m_cAces++;
  756. m_bFailed = FALSE;
  757. return TRUE;
  758. }
  759. BOOL CSecDesc::AddAdministratorsAsOwner()
  760. {
  761. SID_IDENTIFIER_AUTHORITY authNT = SECURITY_NT_AUTHORITY;
  762. XPtr<SID, FreeSid> xSid;
  763. if ((!m_bInitialised) || (m_bFailed)) {
  764. dbg.Msg( DEBUG_MESSAGE_WARNING, L"AddAdministrators: Not initialised or failure.");
  765. return FALSE;
  766. }
  767. m_bFailed = TRUE;
  768. if (!AllocateAndInitializeSid(&authNT, 2, SECURITY_BUILTIN_DOMAIN_RID,
  769. DOMAIN_ALIAS_RID_ADMINS, 0, 0,
  770. 0, 0, 0, 0, (PSID *)&xSid)) {
  771. dbg.Msg( DEBUG_MESSAGE_WARNING, L"AddAdministrators: Failed to initialize sid. Error = %d", GetLastError());
  772. return FALSE;
  773. }
  774. m_xpOwnerSid = xSid.Acquire();
  775. m_bFailed = FALSE;
  776. return TRUE;
  777. }
  778. BOOL CSecDesc::AddAdministratorsAsGroup()
  779. {
  780. SID_IDENTIFIER_AUTHORITY authNT = SECURITY_NT_AUTHORITY;
  781. XPtr<SID, FreeSid> xSid;
  782. if ((!m_bInitialised) || (m_bFailed)) {
  783. dbg.Msg( DEBUG_MESSAGE_WARNING, L"AddAdministrators: Not initialised or failure.");
  784. return FALSE;
  785. }
  786. m_bFailed = TRUE;
  787. if (!AllocateAndInitializeSid(&authNT, 2, SECURITY_BUILTIN_DOMAIN_RID,
  788. DOMAIN_ALIAS_RID_ADMINS, 0, 0,
  789. 0, 0, 0, 0, (PSID *)&xSid)) {
  790. dbg.Msg( DEBUG_MESSAGE_WARNING, L"AddAdministrators: Failed to initialize sid. Error = %d", GetLastError());
  791. return FALSE;
  792. }
  793. m_xpGrpSid = xSid.Acquire();
  794. m_bFailed = FALSE;
  795. return TRUE;
  796. }
  797. BOOL CSecDesc::AddEveryOne(DWORD dwAccess, DWORD AceFlags)
  798. {
  799. SID_IDENTIFIER_AUTHORITY authWORLD = SECURITY_WORLD_SID_AUTHORITY;
  800. XPtr<SID, FreeSid> xSid;
  801. if ((!m_bInitialised) || (m_bFailed)) {
  802. dbg.Msg( DEBUG_MESSAGE_WARNING, L"AddEveryOne: Not initialised or failure.");
  803. return FALSE;
  804. }
  805. m_bFailed = TRUE;
  806. if (!AllocateAndInitializeSid(&authWORLD, 1, SECURITY_WORLD_RID,
  807. 0, 0, 0, 0, 0, 0, 0, (PSID *)&xSid)) {
  808. dbg.Msg( DEBUG_MESSAGE_WARNING, L"AddEveryOne: Failed to initialize sid. Error = %d", GetLastError());
  809. return FALSE;
  810. }
  811. if (m_cAces == m_cAllocated)
  812. if (!ReAllocSidList())
  813. return FALSE;
  814. m_xpSidList[m_cAces].pSid = xSid.Acquire();
  815. m_xpSidList[m_cAces].dwAccess = dwAccess;
  816. m_xpSidList[m_cAces].AceFlags = AceFlags;
  817. m_cAces++;
  818. m_bFailed = FALSE;
  819. return TRUE;
  820. }
  821. #if 0
  822. BOOL CSecDesc::AddThisUser(HANDLE hToken, DWORD dwAccess, DWORD AceFlags)
  823. {
  824. XPtrLF<SID> xSid;
  825. if ((!m_bInitialised) || (m_bFailed)) {
  826. dbg.Msg( DEBUG_MESSAGE_WARNING, L"AddThisUser: Not initialised or failure.");
  827. return FALSE;
  828. }
  829. m_bFailed = TRUE;
  830. xSid = (SID *)GetUserSid(hToken);
  831. if (!pSid) {
  832. dbg.Msg( DEBUG_MESSAGE_WARNING, L"AddThisUser: Failed to initialize sid. Error = %d", GetLastError());
  833. return FALSE;
  834. }
  835. if (m_cAces == m_cAllocated)
  836. if (!ReAllocSidList())
  837. return FALSE;
  838. m_xpSidList[m_cAces].pSid = xSid.Acquire();
  839. m_xpSidList[m_cAces].dwAccess = dwAccess;
  840. m_xpSidList[m_cAces].bUseLocalFree = TRUE;
  841. m_xpSidList[m_cAces].AceFlags = AceFlags;
  842. m_cAces++;
  843. m_bFailed = FALSE;
  844. return TRUE;
  845. }
  846. #endif
  847. BOOL CSecDesc::AddUsers(DWORD dwAccess, DWORD AceFlags)
  848. {
  849. SID_IDENTIFIER_AUTHORITY authNT = SECURITY_NT_AUTHORITY;
  850. XPtr<SID, FreeSid> xSid;
  851. if ((!m_bInitialised) || (m_bFailed)) {
  852. dbg.Msg( DEBUG_MESSAGE_WARNING, L"AddAdministrators: Not initialised or failure.");
  853. return FALSE;
  854. }
  855. m_bFailed = TRUE;
  856. if (!AllocateAndInitializeSid(&authNT, 2, SECURITY_BUILTIN_DOMAIN_RID,
  857. DOMAIN_ALIAS_RID_USERS,
  858. 0, 0, 0, 0, 0, 0, (PSID *)&xSid)) {
  859. dbg.Msg( DEBUG_MESSAGE_WARNING, L"AddUsers: Failed to initialize sid. Error = %d", GetLastError());
  860. return FALSE;
  861. }
  862. if (m_cAces == m_cAllocated)
  863. if (!ReAllocSidList())
  864. return FALSE;
  865. m_xpSidList[m_cAces].pSid = xSid.Acquire();
  866. m_xpSidList[m_cAces].dwAccess = dwAccess;
  867. m_xpSidList[m_cAces].AceFlags = AceFlags;
  868. m_cAces++;
  869. m_bFailed = FALSE;
  870. return TRUE;
  871. }
  872. BOOL CSecDesc::AddAuthUsers(DWORD dwAccess, DWORD AceFlags)
  873. {
  874. SID_IDENTIFIER_AUTHORITY authNT = SECURITY_NT_AUTHORITY;
  875. XPtr<SID, FreeSid> xSid;
  876. if ((!m_bInitialised) || (m_bFailed)) {
  877. dbg.Msg( DEBUG_MESSAGE_WARNING, L"AddAuthUsers: Not initialised or failure.");
  878. return FALSE;
  879. }
  880. m_bFailed = TRUE;
  881. if (!AllocateAndInitializeSid(&authNT, 1, SECURITY_AUTHENTICATED_USER_RID,
  882. 0, 0, 0, 0, 0, 0, 0, (PSID *)&xSid)) {
  883. dbg.Msg( DEBUG_MESSAGE_WARNING, L"AddAuthUsers: Failed to initialize authenticated users sid. Error = %d", GetLastError());
  884. return FALSE;
  885. }
  886. if (m_cAces == m_cAllocated)
  887. if (!ReAllocSidList())
  888. return FALSE;
  889. m_xpSidList[m_cAces].pSid = xSid.Acquire();
  890. m_xpSidList[m_cAces].dwAccess = dwAccess;
  891. m_xpSidList[m_cAces].AceFlags = AceFlags;
  892. m_cAces++;
  893. m_bFailed = FALSE;
  894. return TRUE;
  895. }
  896. BOOL CSecDesc::AddSid(PSID pSid, DWORD dwAccess, DWORD AceFlags)
  897. {
  898. XPtrLF<SID> pLocalSid = 0;
  899. DWORD dwSidLen = 0;
  900. if ((!m_bInitialised) || (m_bFailed)) {
  901. dbg.Msg( DEBUG_MESSAGE_WARNING, L"AddSid: Not initialised or failure.");
  902. return FALSE;
  903. }
  904. m_bFailed = TRUE;
  905. if (!IsValidSid(pSid)) {
  906. dbg.Msg( DEBUG_MESSAGE_WARNING, L"AddSid: Not a vaild Sid.");
  907. return FALSE;
  908. }
  909. dwSidLen = GetLengthSid(pSid);
  910. pLocalSid = (SID *)LocalAlloc(LPTR, dwSidLen);
  911. if (!pLocalSid) {
  912. dbg.Msg( DEBUG_MESSAGE_WARNING, L"AddSid: Couldn't allocate memory. Error %d", GetLastError());
  913. return FALSE;
  914. }
  915. if (!CopySid(dwSidLen, pLocalSid, pSid)) {
  916. dbg.Msg( DEBUG_MESSAGE_WARNING, L"AddSid: Couldn't copy Sid. Error %d", GetLastError());
  917. return FALSE;
  918. }
  919. m_xpSidList[m_cAces].pSid = (SID *)pLocalSid.Acquire();
  920. m_xpSidList[m_cAces].dwAccess = dwAccess;
  921. m_xpSidList[m_cAces].bUseLocalFree = TRUE;
  922. m_xpSidList[m_cAces].AceFlags = AceFlags;
  923. m_cAces++;
  924. m_bFailed = FALSE;
  925. return TRUE;
  926. }
  927. PISECURITY_DESCRIPTOR CSecDesc::MakeSD()
  928. {
  929. XPtrLF<SECURITY_DESCRIPTOR> xsd;
  930. PACL pAcl = 0;
  931. DWORD cbMemSize;
  932. DWORD cbAcl;
  933. DWORD i;
  934. if ((!m_bInitialised) || (m_bFailed)) {
  935. dbg.Msg( DEBUG_MESSAGE_WARNING, L"MakeSD: Not initialised or failure.");
  936. return NULL;
  937. }
  938. m_bFailed = TRUE;
  939. cbAcl = 0;
  940. for (i = 0; i < m_cAces; i++)
  941. cbAcl+= GetLengthSid((SID *)(m_xpSidList[i].pSid));
  942. cbAcl += sizeof(ACL) + m_cAces*(sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD));
  943. //
  944. // Allocate space for the SECURITY_DESCRIPTOR + ACL
  945. //
  946. cbMemSize = sizeof( SECURITY_DESCRIPTOR ) + cbAcl;
  947. xsd = (PISECURITY_DESCRIPTOR) LocalAlloc(LPTR, cbMemSize);
  948. if (!xsd) {
  949. dbg.Msg( DEBUG_MESSAGE_WARNING, L"CSecDesc::MakeSD: Failed to alocate security descriptor. Error = %d", GetLastError());
  950. return NULL;
  951. }
  952. //
  953. // increment psd by sizeof SECURITY_DESCRIPTOR
  954. //
  955. pAcl = (PACL) ( ( (unsigned char*)((SECURITY_DESCRIPTOR *)xsd) ) + sizeof(SECURITY_DESCRIPTOR) );
  956. if (!InitializeAcl(pAcl, cbAcl, ACL_REVISION)) {
  957. dbg.Msg( DEBUG_MESSAGE_WARNING, L"CSecDesc::MakeSD: Failed to initialize acl. Error = %d", GetLastError());
  958. return NULL;
  959. }
  960. //
  961. // Add each of the new ACEs
  962. //
  963. for (i = 0; i < m_cAces; i++) {
  964. if (!AddAccessAllowedAceEx(pAcl, ACL_REVISION, m_xpSidList[i].AceFlags, m_xpSidList[i].dwAccess, m_xpSidList[i].pSid)) {
  965. dbg.Msg( DEBUG_MESSAGE_WARNING, L"CSecDesc::MakeSD: Failed to add ace (%d). Error = %d", i, GetLastError());
  966. return NULL;
  967. }
  968. }
  969. //
  970. // Put together the security descriptor
  971. //
  972. if (!InitializeSecurityDescriptor(xsd, SECURITY_DESCRIPTOR_REVISION)) {
  973. dbg.Msg( DEBUG_MESSAGE_WARNING, L"MakeGenericSecurityDesc: Failed to initialize security descriptor. Error = %d", GetLastError());
  974. return NULL;
  975. }
  976. if (!SetSecurityDescriptorDacl(xsd, TRUE, pAcl, FALSE)) {
  977. dbg.Msg( DEBUG_MESSAGE_WARNING, L"MakeGenericSecurityDesc: Failed to set security descriptor dacl. Error = %d", GetLastError());
  978. return NULL;
  979. }
  980. if (m_xpOwnerSid) {
  981. if (!SetSecurityDescriptorOwner(xsd, m_xpOwnerSid, 0)) {
  982. dbg.Msg( DEBUG_MESSAGE_WARNING, L"MakeGenericSecurityDesc: Failed to set security descriptor dacl. Error = %d", GetLastError());
  983. return NULL;
  984. }
  985. }
  986. if (m_xpGrpSid) {
  987. if (!SetSecurityDescriptorGroup(xsd, m_xpGrpSid, 0)) {
  988. dbg.Msg( DEBUG_MESSAGE_WARNING, L"MakeGenericSecurityDesc: Failed to set security descriptor dacl. Error = %d", GetLastError());
  989. return NULL;
  990. }
  991. }
  992. m_bFailed = FALSE;
  993. return xsd.Acquire();
  994. }
  995. PISECURITY_DESCRIPTOR CSecDesc::MakeSelfRelativeSD()
  996. {
  997. XPtrLF<SECURITY_DESCRIPTOR> xAbsoluteSD;
  998. DWORD dwLastError;
  999. if ((!m_bInitialised) || (m_bFailed)) {
  1000. dbg.Msg( DEBUG_MESSAGE_WARNING, L"AddAdministrators: Not initialised or failure.");
  1001. return FALSE;
  1002. }
  1003. xAbsoluteSD = MakeSD();
  1004. if (!xAbsoluteSD) {
  1005. dbg.Msg( DEBUG_MESSAGE_WARNING, L"CSecDesc::MakeSelfRelativeSD: Failed to set security descriptor dacl. Error = %d", GetLastError());
  1006. return NULL;
  1007. }
  1008. m_bFailed = TRUE;
  1009. //
  1010. // Make a new self-relative SD here
  1011. //
  1012. DWORD dwBufferLength = 0;
  1013. ::MakeSelfRelativeSD( xAbsoluteSD, 0, &dwBufferLength);
  1014. dwLastError = GetLastError();
  1015. if((dwLastError != ERROR_INSUFFICIENT_BUFFER) || !dwBufferLength)
  1016. {
  1017. dbg.Msg( DEBUG_MESSAGE_VERBOSE, L"CSecDesc::MakeSelfRelativeSD: MakeSelfRelativeSD failed, 0x%X", dwLastError );
  1018. return NULL;
  1019. }
  1020. XPtrLF<SECURITY_DESCRIPTOR> xsd = reinterpret_cast<SECURITY_DESCRIPTOR*>(LocalAlloc(LPTR, dwBufferLength));
  1021. if(!xsd)
  1022. {
  1023. dbg.Msg( DEBUG_MESSAGE_VERBOSE, L"CSecDesc::MakeSelfRelativeSD: MakeSelfRelativeSD failed, 0x%X", E_OUTOFMEMORY );
  1024. return NULL;
  1025. }
  1026. BOOL bRes = ::MakeSelfRelativeSD( xAbsoluteSD, xsd, &dwBufferLength);
  1027. if (!bRes) {
  1028. dbg.Msg( DEBUG_MESSAGE_VERBOSE, L"CSecDesc::MakeSelfRelativeSD: MakeSelfRelativeSD failed, 0x%X", GetLastError() );
  1029. return NULL;
  1030. }
  1031. m_bFailed = FALSE;
  1032. return xsd.Acquire();
  1033. }