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.

1179 lines
30 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 RSoPMakeAbsoluteSD(SECURITY_DESCRIPTOR* pSelfRelativeSD, SECURITY_DESCRIPTOR** ppAbsoluteSD)
  142. {
  143. BOOL bRes = IsValidSecurityDescriptor(pSelfRelativeSD);
  144. if(!bRes)
  145. {
  146. return WBEM_E_INVALID_PARAMETER;
  147. }
  148. XPtrLF<SECURITY_DESCRIPTOR> xpAbsoluteSD;
  149. XPtrLF<ACL> xpDacl;
  150. XPtrLF<ACL> xpSacl;
  151. XPtrLF<SID> xpOwner;
  152. XPtrLF<SID> xpPrimaryGroup;
  153. DWORD dwAbsoluteSecurityDescriptorSize = 0;
  154. DWORD dwDaclSize = 0;
  155. DWORD dwSaclSize = 0;
  156. DWORD dwOwnerSize = 0;
  157. DWORD dwPrimaryGroupSize = 0;
  158. bRes = ::MakeAbsoluteSD(
  159. pSelfRelativeSD,
  160. xpAbsoluteSD,
  161. &dwAbsoluteSecurityDescriptorSize,
  162. xpDacl, // discretionary ACL
  163. &dwDaclSize, // size of discretionary ACL
  164. xpSacl, // system ACL
  165. &dwSaclSize, // size of system ACL
  166. xpOwner, // owner SID
  167. &dwOwnerSize, // size of owner SID
  168. xpPrimaryGroup, // primary-group SID
  169. &dwPrimaryGroupSize // size of group SID
  170. );
  171. DWORD dwLastError = GetLastError();
  172. if(dwLastError != ERROR_INSUFFICIENT_BUFFER)
  173. {
  174. return E_FAIL;
  175. }
  176. if(!dwAbsoluteSecurityDescriptorSize)
  177. {
  178. return E_FAIL;
  179. }
  180. xpAbsoluteSD = reinterpret_cast<SECURITY_DESCRIPTOR*>(LocalAlloc(LPTR, dwAbsoluteSecurityDescriptorSize));
  181. if(!xpAbsoluteSD)
  182. {
  183. return E_OUTOFMEMORY;
  184. }
  185. if(dwDaclSize)
  186. {
  187. xpDacl = reinterpret_cast<ACL*>(LocalAlloc(LPTR, dwDaclSize));
  188. if(!xpDacl)
  189. {
  190. return E_OUTOFMEMORY;
  191. }
  192. }
  193. if(dwSaclSize)
  194. {
  195. xpSacl = reinterpret_cast<ACL*>(LocalAlloc(LPTR, dwSaclSize));
  196. if(!xpSacl)
  197. {
  198. return E_OUTOFMEMORY;
  199. }
  200. }
  201. if(dwOwnerSize)
  202. {
  203. xpOwner = reinterpret_cast<SID*>(LocalAlloc(LPTR, dwOwnerSize));
  204. if(!xpOwner)
  205. {
  206. return E_OUTOFMEMORY;
  207. }
  208. }
  209. if(dwPrimaryGroupSize)
  210. {
  211. xpPrimaryGroup = reinterpret_cast<SID*>(LocalAlloc(LPTR, dwPrimaryGroupSize));
  212. if(!xpPrimaryGroup)
  213. {
  214. return E_OUTOFMEMORY;
  215. }
  216. }
  217. bRes = ::MakeAbsoluteSD(
  218. pSelfRelativeSD,
  219. xpAbsoluteSD,
  220. &dwAbsoluteSecurityDescriptorSize,
  221. xpDacl, // discretionary ACL
  222. &dwDaclSize, // size of discretionary ACL
  223. xpSacl, // system ACL
  224. &dwSaclSize, // size of system ACL
  225. xpOwner, // owner SID
  226. &dwOwnerSize, // size of owner SID
  227. xpPrimaryGroup, // primary-group SID
  228. &dwPrimaryGroupSize // size of group SID
  229. );
  230. if(!bRes)
  231. {
  232. return E_FAIL;
  233. }
  234. bRes = IsValidSecurityDescriptor(xpAbsoluteSD);
  235. if(!bRes)
  236. {
  237. return E_FAIL;
  238. }
  239. xpDacl.Acquire();
  240. xpSacl.Acquire();
  241. xpOwner.Acquire();
  242. xpPrimaryGroup.Acquire();
  243. *ppAbsoluteSD = xpAbsoluteSD.Acquire();
  244. return S_OK;
  245. }
  246. //******************************************************************************
  247. //
  248. // Function:
  249. //
  250. // Description:
  251. //
  252. // Parameters:
  253. //
  254. // Return:
  255. //
  256. // History: 8-26-99 leonardm Created
  257. //
  258. //******************************************************************************
  259. STDMETHODIMP FreeAbsoluteSD(SECURITY_DESCRIPTOR* pAbsoluteSD)
  260. {
  261. if(!pAbsoluteSD)
  262. {
  263. return E_POINTER;
  264. }
  265. BOOL bRes;
  266. BOOL bDaclPresent;
  267. BOOL bDaclDefaulted;
  268. XPtrLF<ACL> xpDacl;
  269. bRes = GetSecurityDescriptorDacl( pAbsoluteSD,
  270. &bDaclPresent,
  271. &xpDacl,
  272. &bDaclDefaulted);
  273. if(!bRes)
  274. {
  275. return E_FAIL;
  276. }
  277. BOOL bSaclPresent;
  278. BOOL bSaclDefaulted;
  279. XPtrLF<ACL> xpSacl;
  280. bRes = GetSecurityDescriptorSacl( pAbsoluteSD,
  281. &bSaclPresent,
  282. &xpSacl,
  283. &bSaclDefaulted);
  284. if(!bRes)
  285. {
  286. return E_FAIL;
  287. }
  288. BOOL bOwnerDefaulted;
  289. XPtrLF<SID>xpOwner;
  290. bRes = GetSecurityDescriptorOwner(pAbsoluteSD, reinterpret_cast<void**>(&xpOwner), &bOwnerDefaulted);
  291. if(!bRes)
  292. {
  293. return E_FAIL;
  294. }
  295. BOOL bGroupDefaulted;
  296. XPtrLF<SID>xpPrimaryGroup;
  297. bRes = GetSecurityDescriptorGroup(pAbsoluteSD, reinterpret_cast<void**>(&xpPrimaryGroup), &bGroupDefaulted);
  298. if(!bRes)
  299. {
  300. return E_FAIL;
  301. }
  302. return S_OK;
  303. }
  304. //******************************************************************************
  305. //
  306. // Function:
  307. //
  308. // Description:
  309. //
  310. // Parameters:
  311. //
  312. // Return:
  313. //
  314. // History: 8-26-99 leonardm Created
  315. //
  316. //******************************************************************************
  317. STDMETHODIMP GetNamespaceSD(IWbemServices* pWbemServices, SECURITY_DESCRIPTOR** ppSD)
  318. {
  319. if(!pWbemServices)
  320. {
  321. return E_POINTER;
  322. }
  323. HRESULT hr;
  324. XInterface<IWbemClassObject> xpOutParams;
  325. const BSTR bstrInstancePath = SysAllocString(L"__systemsecurity=@");
  326. if(!bstrInstancePath)
  327. {
  328. return E_OUTOFMEMORY;
  329. }
  330. const BSTR bstrMethodName = SysAllocString(L"GetSD");
  331. if(!bstrMethodName)
  332. {
  333. SysFreeString(bstrInstancePath);
  334. return E_OUTOFMEMORY;
  335. }
  336. hr = pWbemServices->ExecMethod( bstrInstancePath,
  337. bstrMethodName,
  338. 0,
  339. NULL,
  340. NULL,
  341. &xpOutParams,
  342. NULL);
  343. SysFreeString(bstrInstancePath);
  344. SysFreeString(bstrMethodName);
  345. if(FAILED(hr))
  346. {
  347. return hr;
  348. }
  349. VARIANT v;
  350. XVariant xv(&v);
  351. VariantInit(&v);
  352. hr = xpOutParams->Get(L"sd", 0, &v, NULL, NULL);
  353. if(FAILED(hr))
  354. {
  355. return hr;
  356. }
  357. if(v.vt != (VT_ARRAY | VT_UI1))
  358. {
  359. return E_FAIL;
  360. }
  361. long lLowerBound;
  362. hr = SafeArrayGetLBound(v.parray, 1, &lLowerBound);
  363. if(FAILED(hr))
  364. {
  365. return hr;
  366. }
  367. long lUpperBound;
  368. hr = SafeArrayGetUBound(v.parray, 1, &lUpperBound);
  369. if(FAILED(hr))
  370. {
  371. return hr;
  372. }
  373. DWORD dwSize = static_cast<DWORD>(lUpperBound - lLowerBound + 1);
  374. XPtrLF<SECURITY_DESCRIPTOR> xpSelfRelativeSD = static_cast<SECURITY_DESCRIPTOR*>(LocalAlloc(LPTR, dwSize));
  375. if(!xpSelfRelativeSD)
  376. {
  377. return E_OUTOFMEMORY;
  378. }
  379. BYTE* pSrc;
  380. hr = SafeArrayAccessData(v.parray, reinterpret_cast<void**>(&pSrc));
  381. if(FAILED(hr))
  382. {
  383. return hr;
  384. }
  385. CopyMemory(xpSelfRelativeSD, pSrc, dwSize);
  386. hr = SafeArrayUnaccessData(v.parray);
  387. if(FAILED(hr))
  388. {
  389. return hr;
  390. }
  391. *ppSD = xpSelfRelativeSD.Acquire();
  392. return S_OK;
  393. }
  394. //******************************************************************************
  395. //
  396. // Function:
  397. //
  398. // Description:
  399. //
  400. // Parameters:
  401. //
  402. // Return:
  403. //
  404. // History: 8/20/99 leonardm Created.
  405. //
  406. //******************************************************************************
  407. STDMETHODIMP SetNamespaceSD(SECURITY_DESCRIPTOR* pSD, IWbemServices* pWbemServices)
  408. {
  409. if(!pWbemServices)
  410. {
  411. return E_POINTER;
  412. }
  413. HRESULT hr;
  414. //
  415. // Get the class object
  416. //
  417. XInterface<IWbemClassObject> xpClass;
  418. BSTR bstrClassPath = SysAllocString(L"__systemsecurity");
  419. if(!bstrClassPath)
  420. {
  421. return E_OUTOFMEMORY;
  422. }
  423. hr = pWbemServices->GetObject(bstrClassPath, 0, NULL, &xpClass, NULL);
  424. SysFreeString(bstrClassPath);
  425. if(FAILED(hr))
  426. {
  427. return hr;
  428. }
  429. //
  430. // Get the input parameter class
  431. //
  432. XInterface<IWbemClassObject> xpMethod;
  433. hr = xpClass->GetMethod(L"SetSD", 0, &xpMethod, NULL);
  434. if(FAILED(hr))
  435. {
  436. return hr;
  437. }
  438. //
  439. // move the SD into a variant.
  440. //
  441. SAFEARRAYBOUND rgsabound[1];
  442. rgsabound[0].lLbound = 0;
  443. DWORD dwLength = GetSecurityDescriptorLength(pSD);
  444. rgsabound[0].cElements = dwLength;
  445. SAFEARRAY* psa = SafeArrayCreate(VT_UI1, 1, rgsabound);
  446. if(!psa)
  447. {
  448. return E_FAIL;
  449. }
  450. BYTE* pDest = NULL;
  451. hr = SafeArrayAccessData(psa, reinterpret_cast<void**>(&pDest));
  452. if(FAILED(hr))
  453. {
  454. return hr;
  455. }
  456. CopyMemory(pDest, pSD, dwLength);
  457. hr = SafeArrayUnaccessData(psa);
  458. if(FAILED(hr))
  459. {
  460. return hr;
  461. }
  462. VARIANT v;
  463. XVariant xv(&v);
  464. v.vt = VT_UI1|VT_ARRAY;
  465. v.parray = psa;
  466. //
  467. // put the property
  468. //
  469. XInterface<IWbemClassObject> xpInParam;
  470. hr = xpMethod->SpawnInstance(0, &xpInParam);
  471. if(FAILED(hr))
  472. {
  473. return hr;
  474. }
  475. hr = xpInParam->Put(L"sd" , 0, &v, 0);
  476. if(FAILED(hr))
  477. {
  478. return hr;
  479. }
  480. //
  481. // Execute the method
  482. //
  483. BSTR bstrInstancePath = SysAllocString(L"__systemsecurity=@");
  484. if(!bstrInstancePath)
  485. {
  486. return E_OUTOFMEMORY;
  487. }
  488. BSTR bstrMethodName = SysAllocString(L"SetSD");
  489. if(!bstrMethodName)
  490. {
  491. SysFreeString(bstrInstancePath);
  492. return E_OUTOFMEMORY;
  493. }
  494. hr = pWbemServices->ExecMethod( bstrInstancePath,
  495. bstrMethodName,
  496. 0,
  497. NULL,
  498. xpInParam,
  499. NULL,
  500. NULL);
  501. SysFreeString(bstrInstancePath);
  502. SysFreeString(bstrMethodName);
  503. return hr;
  504. }
  505. #undef dbg
  506. #define dbg dbgCommon
  507. const DWORD DEFAULT_ACE_NUM=10;
  508. CSecDesc::CSecDesc() :
  509. m_cAces(0), m_xpSidList(NULL),
  510. m_cAllocated(0), m_bInitialised(FALSE), m_bFailed(FALSE)
  511. {
  512. m_xpSidList = (SidStruct *)LocalAlloc(LPTR, sizeof(SidStruct)*DEFAULT_ACE_NUM);
  513. if (!m_xpSidList)
  514. return;
  515. m_cAllocated = DEFAULT_ACE_NUM;
  516. m_bInitialised = TRUE;
  517. }
  518. CSecDesc::~CSecDesc()
  519. {
  520. if (m_xpSidList)
  521. for (DWORD i = 0; i < m_cAllocated; i++)
  522. if (m_xpSidList[i].pSid)
  523. if (m_xpSidList[i].bUseLocalFree)
  524. LocalFree(m_xpSidList[i].pSid);
  525. else
  526. FreeSid(m_xpSidList[i].pSid);
  527. }
  528. BOOL CSecDesc::ReAllocSidList()
  529. {
  530. XPtrLF<SidStruct> xSidListNew;
  531. //
  532. // first allocate a larger buffer
  533. //
  534. xSidListNew = (SidStruct *)LocalAlloc(LPTR, sizeof(SidStruct)*(m_cAllocated+DEFAULT_ACE_NUM));
  535. if (!xSidListNew) {
  536. dbg.Msg( DEBUG_MESSAGE_WARNING, L"CSecDesc::ReallocArgStrings Cannot add memory, error = %d", GetLastError());
  537. m_bFailed = TRUE;
  538. return FALSE;
  539. }
  540. //
  541. // copy the arguments
  542. //
  543. for (DWORD i = 0; i < (m_cAllocated); i++) {
  544. xSidListNew[i] = m_xpSidList[i];
  545. }
  546. m_xpSidList = xSidListNew.Acquire();
  547. m_cAllocated+= DEFAULT_ACE_NUM;
  548. return TRUE;
  549. }
  550. BOOL CSecDesc::AddLocalSystem(DWORD dwAccess, DWORD AceFlags)
  551. {
  552. SID_IDENTIFIER_AUTHORITY authNT = SECURITY_NT_AUTHORITY;
  553. XPtr<SID, FreeSid> xSid;
  554. if ((!m_bInitialised) || (m_bFailed)) {
  555. dbg.Msg( DEBUG_MESSAGE_WARNING, L"AddLocalSystem: Not initialised or failure.");
  556. return FALSE;
  557. }
  558. m_bFailed = TRUE;
  559. if (!AllocateAndInitializeSid(&authNT, 1, SECURITY_LOCAL_SYSTEM_RID,
  560. 0, 0, 0, 0, 0, 0, 0, (PSID *)&xSid)) {
  561. dbg.Msg( DEBUG_MESSAGE_WARNING, L"AddLocalSystem: Failed to initialize sid. Error = %d", GetLastError());
  562. return FALSE;
  563. }
  564. if (m_cAces == m_cAllocated)
  565. if (!ReAllocSidList())
  566. return FALSE;
  567. m_xpSidList[m_cAces].pSid = xSid.Acquire();
  568. m_xpSidList[m_cAces].dwAccess = dwAccess;
  569. m_xpSidList[m_cAces].AceFlags = AceFlags;
  570. m_cAces++;
  571. m_bFailed = FALSE;
  572. return TRUE;
  573. }
  574. BOOL CSecDesc::AddAdministrators(DWORD dwAccess, DWORD AceFlags)
  575. {
  576. SID_IDENTIFIER_AUTHORITY authNT = SECURITY_NT_AUTHORITY;
  577. XPtr<SID, FreeSid> xSid;
  578. if ((!m_bInitialised) || (m_bFailed)) {
  579. dbg.Msg( DEBUG_MESSAGE_WARNING, L"AddAdministrators: Not initialised or failure.");
  580. return FALSE;
  581. }
  582. m_bFailed = TRUE;
  583. if (!AllocateAndInitializeSid(&authNT, 2, SECURITY_BUILTIN_DOMAIN_RID,
  584. DOMAIN_ALIAS_RID_ADMINS, 0, 0,
  585. 0, 0, 0, 0, (PSID *)&xSid)) {
  586. dbg.Msg( DEBUG_MESSAGE_WARNING, L"AddAdministrators: Failed to initialize sid. Error = %d", GetLastError());
  587. return FALSE;
  588. }
  589. if (m_cAces == m_cAllocated)
  590. if (!ReAllocSidList())
  591. return FALSE;
  592. m_xpSidList[m_cAces].pSid = xSid.Acquire();
  593. m_xpSidList[m_cAces].dwAccess = dwAccess;
  594. m_xpSidList[m_cAces].AceFlags = AceFlags;
  595. m_cAces++;
  596. m_bFailed = FALSE;
  597. return TRUE;
  598. }
  599. BOOL CSecDesc::AddNetworkService(DWORD dwAccess, DWORD AceFlags)
  600. {
  601. SID_IDENTIFIER_AUTHORITY authNT = SECURITY_NT_AUTHORITY;
  602. XPtr<SID, FreeSid> xSid;
  603. if ((!m_bInitialised) || (m_bFailed)) {
  604. dbg.Msg( DEBUG_MESSAGE_WARNING, L"AddNetworkService: Not initialised or failure.");
  605. return FALSE;
  606. }
  607. m_bFailed = TRUE;
  608. if (!AllocateAndInitializeSid(&authNT, 1, SECURITY_NETWORK_SERVICE_RID,
  609. 0, 0, 0, 0, 0, 0, 0, (PSID *)&xSid)) {
  610. dbg.Msg( DEBUG_MESSAGE_WARNING, L"AddNetworkService: Failed to initialize sid. Error = %d", GetLastError());
  611. return FALSE;
  612. }
  613. if (m_cAces == m_cAllocated)
  614. if (!ReAllocSidList())
  615. return FALSE;
  616. m_xpSidList[m_cAces].pSid = xSid.Acquire();
  617. m_xpSidList[m_cAces].dwAccess = dwAccess;
  618. m_xpSidList[m_cAces].AceFlags = AceFlags;
  619. m_cAces++;
  620. m_bFailed = FALSE;
  621. return TRUE;
  622. }
  623. BOOL CSecDesc::AddAdministratorsAsOwner()
  624. {
  625. SID_IDENTIFIER_AUTHORITY authNT = SECURITY_NT_AUTHORITY;
  626. XPtr<SID, FreeSid> xSid;
  627. if ((!m_bInitialised) || (m_bFailed)) {
  628. dbg.Msg( DEBUG_MESSAGE_WARNING, L"AddAdministrators: Not initialised or failure.");
  629. return FALSE;
  630. }
  631. m_bFailed = TRUE;
  632. if (!AllocateAndInitializeSid(&authNT, 2, SECURITY_BUILTIN_DOMAIN_RID,
  633. DOMAIN_ALIAS_RID_ADMINS, 0, 0,
  634. 0, 0, 0, 0, (PSID *)&xSid)) {
  635. dbg.Msg( DEBUG_MESSAGE_WARNING, L"AddAdministrators: Failed to initialize sid. Error = %d", GetLastError());
  636. return FALSE;
  637. }
  638. m_xpOwnerSid = xSid.Acquire();
  639. m_bFailed = FALSE;
  640. return TRUE;
  641. }
  642. BOOL CSecDesc::AddAdministratorsAsGroup()
  643. {
  644. SID_IDENTIFIER_AUTHORITY authNT = SECURITY_NT_AUTHORITY;
  645. XPtr<SID, FreeSid> xSid;
  646. if ((!m_bInitialised) || (m_bFailed)) {
  647. dbg.Msg( DEBUG_MESSAGE_WARNING, L"AddAdministrators: Not initialised or failure.");
  648. return FALSE;
  649. }
  650. m_bFailed = TRUE;
  651. if (!AllocateAndInitializeSid(&authNT, 2, SECURITY_BUILTIN_DOMAIN_RID,
  652. DOMAIN_ALIAS_RID_ADMINS, 0, 0,
  653. 0, 0, 0, 0, (PSID *)&xSid)) {
  654. dbg.Msg( DEBUG_MESSAGE_WARNING, L"AddAdministrators: Failed to initialize sid. Error = %d", GetLastError());
  655. return FALSE;
  656. }
  657. m_xpGrpSid = xSid.Acquire();
  658. m_bFailed = FALSE;
  659. return TRUE;
  660. }
  661. BOOL CSecDesc::AddEveryOne(DWORD dwAccess, DWORD AceFlags)
  662. {
  663. SID_IDENTIFIER_AUTHORITY authWORLD = SECURITY_WORLD_SID_AUTHORITY;
  664. XPtr<SID, FreeSid> xSid;
  665. if ((!m_bInitialised) || (m_bFailed)) {
  666. dbg.Msg( DEBUG_MESSAGE_WARNING, L"AddEveryOne: Not initialised or failure.");
  667. return FALSE;
  668. }
  669. m_bFailed = TRUE;
  670. if (!AllocateAndInitializeSid(&authWORLD, 1, SECURITY_WORLD_RID,
  671. 0, 0, 0, 0, 0, 0, 0, (PSID *)&xSid)) {
  672. dbg.Msg( DEBUG_MESSAGE_WARNING, L"AddEveryOne: Failed to initialize sid. Error = %d", GetLastError());
  673. return FALSE;
  674. }
  675. if (m_cAces == m_cAllocated)
  676. if (!ReAllocSidList())
  677. return FALSE;
  678. m_xpSidList[m_cAces].pSid = xSid.Acquire();
  679. m_xpSidList[m_cAces].dwAccess = dwAccess;
  680. m_xpSidList[m_cAces].AceFlags = AceFlags;
  681. m_cAces++;
  682. m_bFailed = FALSE;
  683. return TRUE;
  684. }
  685. #if 0
  686. BOOL CSecDesc::AddThisUser(HANDLE hToken, DWORD dwAccess, DWORD AceFlags)
  687. {
  688. XPtrLF<SID> xSid;
  689. if ((!m_bInitialised) || (m_bFailed)) {
  690. dbg.Msg( DEBUG_MESSAGE_WARNING, L"AddThisUser: Not initialised or failure.");
  691. return FALSE;
  692. }
  693. m_bFailed = TRUE;
  694. xSid = (SID *)GetUserSid(hToken);
  695. if (!pSid) {
  696. dbg.Msg( DEBUG_MESSAGE_WARNING, L"AddThisUser: Failed to initialize sid. Error = %d", GetLastError());
  697. return FALSE;
  698. }
  699. if (m_cAces == m_cAllocated)
  700. if (!ReAllocSidList())
  701. return FALSE;
  702. m_xpSidList[m_cAces].pSid = xSid.Acquire();
  703. m_xpSidList[m_cAces].dwAccess = dwAccess;
  704. m_xpSidList[m_cAces].bUseLocalFree = TRUE;
  705. m_xpSidList[m_cAces].AceFlags = AceFlags;
  706. m_cAces++;
  707. m_bFailed = FALSE;
  708. return TRUE;
  709. }
  710. #endif
  711. BOOL CSecDesc::AddUsers(DWORD dwAccess, DWORD AceFlags)
  712. {
  713. SID_IDENTIFIER_AUTHORITY authNT = SECURITY_NT_AUTHORITY;
  714. XPtr<SID, FreeSid> xSid;
  715. if ((!m_bInitialised) || (m_bFailed)) {
  716. dbg.Msg( DEBUG_MESSAGE_WARNING, L"AddAdministrators: Not initialised or failure.");
  717. return FALSE;
  718. }
  719. m_bFailed = TRUE;
  720. if (!AllocateAndInitializeSid(&authNT, 2, SECURITY_BUILTIN_DOMAIN_RID,
  721. DOMAIN_ALIAS_RID_USERS,
  722. 0, 0, 0, 0, 0, 0, (PSID *)&xSid)) {
  723. dbg.Msg( DEBUG_MESSAGE_WARNING, L"AddUsers: Failed to initialize sid. Error = %d", GetLastError());
  724. return FALSE;
  725. }
  726. if (m_cAces == m_cAllocated)
  727. if (!ReAllocSidList())
  728. return FALSE;
  729. m_xpSidList[m_cAces].pSid = xSid.Acquire();
  730. m_xpSidList[m_cAces].dwAccess = dwAccess;
  731. m_xpSidList[m_cAces].AceFlags = AceFlags;
  732. m_cAces++;
  733. m_bFailed = FALSE;
  734. return TRUE;
  735. }
  736. BOOL CSecDesc::AddAuthUsers(DWORD dwAccess, DWORD AceFlags)
  737. {
  738. SID_IDENTIFIER_AUTHORITY authNT = SECURITY_NT_AUTHORITY;
  739. XPtr<SID, FreeSid> xSid;
  740. if ((!m_bInitialised) || (m_bFailed)) {
  741. dbg.Msg( DEBUG_MESSAGE_WARNING, L"AddAuthUsers: Not initialised or failure.");
  742. return FALSE;
  743. }
  744. m_bFailed = TRUE;
  745. if (!AllocateAndInitializeSid(&authNT, 1, SECURITY_AUTHENTICATED_USER_RID,
  746. 0, 0, 0, 0, 0, 0, 0, (PSID *)&xSid)) {
  747. dbg.Msg( DEBUG_MESSAGE_WARNING, L"AddAuthUsers: Failed to initialize authenticated users sid. Error = %d", GetLastError());
  748. return FALSE;
  749. }
  750. if (m_cAces == m_cAllocated)
  751. if (!ReAllocSidList())
  752. return FALSE;
  753. m_xpSidList[m_cAces].pSid = xSid.Acquire();
  754. m_xpSidList[m_cAces].dwAccess = dwAccess;
  755. m_xpSidList[m_cAces].AceFlags = AceFlags;
  756. m_cAces++;
  757. m_bFailed = FALSE;
  758. return TRUE;
  759. }
  760. BOOL CSecDesc::AddSid(PSID pSid, DWORD dwAccess, DWORD AceFlags)
  761. {
  762. XPtrLF<SID> pLocalSid = 0;
  763. DWORD dwSidLen = 0;
  764. if ((!m_bInitialised) || (m_bFailed)) {
  765. dbg.Msg( DEBUG_MESSAGE_WARNING, L"AddSid: Not initialised or failure.");
  766. return FALSE;
  767. }
  768. m_bFailed = TRUE;
  769. if (!IsValidSid(pSid)) {
  770. dbg.Msg( DEBUG_MESSAGE_WARNING, L"AddSid: Not a vaild Sid.");
  771. return FALSE;
  772. }
  773. dwSidLen = GetLengthSid(pSid);
  774. pLocalSid = (SID *)LocalAlloc(LPTR, dwSidLen);
  775. if (!pLocalSid) {
  776. dbg.Msg( DEBUG_MESSAGE_WARNING, L"AddSid: Couldn't allocate memory. Error %d", GetLastError());
  777. return FALSE;
  778. }
  779. if (!CopySid(dwSidLen, pLocalSid, pSid)) {
  780. dbg.Msg( DEBUG_MESSAGE_WARNING, L"AddSid: Couldn't copy Sid. Error %d", GetLastError());
  781. return FALSE;
  782. }
  783. m_xpSidList[m_cAces].pSid = (SID *)pLocalSid.Acquire();
  784. m_xpSidList[m_cAces].dwAccess = dwAccess;
  785. m_xpSidList[m_cAces].bUseLocalFree = TRUE;
  786. m_xpSidList[m_cAces].AceFlags = AceFlags;
  787. m_cAces++;
  788. m_bFailed = FALSE;
  789. return TRUE;
  790. }
  791. PISECURITY_DESCRIPTOR CSecDesc::MakeSD()
  792. {
  793. XPtrLF<SECURITY_DESCRIPTOR> xsd;
  794. PACL pAcl = 0;
  795. DWORD cbMemSize;
  796. DWORD cbAcl;
  797. DWORD i;
  798. if ((!m_bInitialised) || (m_bFailed)) {
  799. dbg.Msg( DEBUG_MESSAGE_WARNING, L"MakeSD: Not initialised or failure.");
  800. return NULL;
  801. }
  802. m_bFailed = TRUE;
  803. cbAcl = 0;
  804. for (i = 0; i < m_cAces; i++)
  805. cbAcl+= GetLengthSid((SID *)(m_xpSidList[i].pSid));
  806. cbAcl += sizeof(ACL) + m_cAces*(sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD));
  807. //
  808. // Allocate space for the SECURITY_DESCRIPTOR + ACL
  809. //
  810. cbMemSize = sizeof( SECURITY_DESCRIPTOR ) + cbAcl;
  811. xsd = (PISECURITY_DESCRIPTOR) LocalAlloc(LPTR, cbMemSize);
  812. if (!xsd) {
  813. dbg.Msg( DEBUG_MESSAGE_WARNING, L"CSecDesc::MakeSD: Failed to alocate security descriptor. Error = %d", GetLastError());
  814. return NULL;
  815. }
  816. //
  817. // increment psd by sizeof SECURITY_DESCRIPTOR
  818. //
  819. pAcl = (PACL) ( ( (unsigned char*)((SECURITY_DESCRIPTOR *)xsd) ) + sizeof(SECURITY_DESCRIPTOR) );
  820. if (!InitializeAcl(pAcl, cbAcl, ACL_REVISION)) {
  821. dbg.Msg( DEBUG_MESSAGE_WARNING, L"CSecDesc::MakeSD: Failed to initialize acl. Error = %d", GetLastError());
  822. return NULL;
  823. }
  824. //
  825. // Add each of the new ACEs
  826. //
  827. for (i = 0; i < m_cAces; i++) {
  828. if (!AddAccessAllowedAceEx(pAcl, ACL_REVISION, m_xpSidList[i].AceFlags, m_xpSidList[i].dwAccess, m_xpSidList[i].pSid)) {
  829. dbg.Msg( DEBUG_MESSAGE_WARNING, L"CSecDesc::MakeSD: Failed to add ace (%d). Error = %d", i, GetLastError());
  830. return NULL;
  831. }
  832. }
  833. //
  834. // Put together the security descriptor
  835. //
  836. if (!InitializeSecurityDescriptor(xsd, SECURITY_DESCRIPTOR_REVISION)) {
  837. dbg.Msg( DEBUG_MESSAGE_WARNING, L"MakeGenericSecurityDesc: Failed to initialize security descriptor. Error = %d", GetLastError());
  838. return NULL;
  839. }
  840. if (!SetSecurityDescriptorDacl(xsd, TRUE, pAcl, FALSE)) {
  841. dbg.Msg( DEBUG_MESSAGE_WARNING, L"MakeGenericSecurityDesc: Failed to set security descriptor dacl. Error = %d", GetLastError());
  842. return NULL;
  843. }
  844. if (m_xpOwnerSid) {
  845. if (!SetSecurityDescriptorOwner(xsd, m_xpOwnerSid, 0)) {
  846. dbg.Msg( DEBUG_MESSAGE_WARNING, L"MakeGenericSecurityDesc: Failed to set security descriptor dacl. Error = %d", GetLastError());
  847. return NULL;
  848. }
  849. }
  850. if (m_xpGrpSid) {
  851. if (!SetSecurityDescriptorGroup(xsd, m_xpGrpSid, 0)) {
  852. dbg.Msg( DEBUG_MESSAGE_WARNING, L"MakeGenericSecurityDesc: Failed to set security descriptor dacl. Error = %d", GetLastError());
  853. return NULL;
  854. }
  855. }
  856. m_bFailed = FALSE;
  857. return xsd.Acquire();
  858. }
  859. PISECURITY_DESCRIPTOR CSecDesc::MakeSelfRelativeSD()
  860. {
  861. XPtrLF<SECURITY_DESCRIPTOR> xAbsoluteSD;
  862. DWORD dwLastError;
  863. if ((!m_bInitialised) || (m_bFailed)) {
  864. dbg.Msg( DEBUG_MESSAGE_WARNING, L"AddAdministrators: Not initialised or failure.");
  865. return FALSE;
  866. }
  867. xAbsoluteSD = MakeSD();
  868. if (!xAbsoluteSD) {
  869. dbg.Msg( DEBUG_MESSAGE_WARNING, L"CSecDesc::MakeSelfRelativeSD: Failed to set security descriptor dacl. Error = %d", GetLastError());
  870. return NULL;
  871. }
  872. m_bFailed = TRUE;
  873. //
  874. // Make a new self-relative SD here
  875. //
  876. DWORD dwBufferLength = 0;
  877. ::MakeSelfRelativeSD( xAbsoluteSD, 0, &dwBufferLength);
  878. dwLastError = GetLastError();
  879. if((dwLastError != ERROR_INSUFFICIENT_BUFFER) || !dwBufferLength)
  880. {
  881. dbg.Msg( DEBUG_MESSAGE_VERBOSE, L"CSecDesc::MakeSelfRelativeSD: MakeSelfRelativeSD failed, 0x%X", dwLastError );
  882. return NULL;
  883. }
  884. XPtrLF<SECURITY_DESCRIPTOR> xsd = reinterpret_cast<SECURITY_DESCRIPTOR*>(LocalAlloc(LPTR, dwBufferLength));
  885. if(!xsd)
  886. {
  887. dbg.Msg( DEBUG_MESSAGE_VERBOSE, L"CSecDesc::MakeSelfRelativeSD: MakeSelfRelativeSD failed, 0x%X", E_OUTOFMEMORY );
  888. return NULL;
  889. }
  890. BOOL bRes = ::MakeSelfRelativeSD( xAbsoluteSD, xsd, &dwBufferLength);
  891. if (!bRes) {
  892. dbg.Msg( DEBUG_MESSAGE_VERBOSE, L"CSecDesc::MakeSelfRelativeSD: MakeSelfRelativeSD failed, 0x%X", GetLastError() );
  893. return NULL;
  894. }
  895. m_bFailed = FALSE;
  896. return xsd.Acquire();
  897. }