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.

710 lines
18 KiB

  1. //+--------------------------------------------------------------------------
  2. // File: officer.cpp
  3. // Contents: officer rights implementation
  4. //---------------------------------------------------------------------------
  5. #include <pch.cpp>
  6. #include <certsd.h>
  7. #include <certacl.h>
  8. #include <sid.h>
  9. using namespace CertSrv;
  10. HRESULT
  11. COfficerRightsSD::Merge(
  12. PSECURITY_DESCRIPTOR pOfficerSD,
  13. PSECURITY_DESCRIPTOR pCASD)
  14. {
  15. HRESULT hr;
  16. PACL pCAAcl; // no free
  17. PACL pOfficerAcl; // no free
  18. PACL pNewOfficerAcl = NULL;
  19. ACL_SIZE_INFORMATION CAAclInfo, OfficerAclInfo;
  20. PBOOL pCAFound = NULL, pOfficerFound = NULL;
  21. DWORD cCAAce, cOfficerAce;
  22. PACCESS_ALLOWED_ACE pCAAce;
  23. PACCESS_ALLOWED_CALLBACK_ACE pOfficerAce;
  24. PACCESS_ALLOWED_CALLBACK_ACE pNewAce = NULL;
  25. DWORD dwNewAclSize = sizeof(ACL);
  26. PSID pSidEveryone = NULL, pSidBuiltinAdministrators = NULL;
  27. SID_IDENTIFIER_AUTHORITY SIDAuth = SECURITY_WORLD_SID_AUTHORITY;
  28. DWORD dwSidEveryoneSize, dwAceSize, dwSidSize;
  29. PSID_LIST pSidList;
  30. PSECURITY_DESCRIPTOR pNewOfficerSD = NULL;
  31. ACL EmptyAcl;
  32. SECURITY_DESCRIPTOR EmptySD;
  33. CSASSERT(NULL==pOfficerSD || IsValidSecurityDescriptor(pOfficerSD));
  34. CSASSERT(IsValidSecurityDescriptor(pCASD));
  35. // allow NULL officer SD, in that case build an empty SD and use it
  36. if(NULL==pOfficerSD)
  37. {
  38. if(!InitializeAcl(&EmptyAcl, sizeof(ACL), ACL_REVISION))
  39. {
  40. hr = myHLastError();
  41. _JumpError(hr, error, "InitializeAcl");
  42. }
  43. if (!InitializeSecurityDescriptor(&EmptySD, SECURITY_DESCRIPTOR_REVISION))
  44. {
  45. hr = myHLastError();
  46. _JumpError(hr, error, "InitializeSecurityDescriptor");
  47. }
  48. if(!SetSecurityDescriptorDacl(
  49. &EmptySD,
  50. TRUE, // DACL present
  51. &EmptyAcl,
  52. FALSE)) // DACL defaulted
  53. {
  54. hr = myHLastError();
  55. _JumpError(hr, error, "SetSecurityDescriptorControl");
  56. }
  57. pOfficerSD = &EmptySD;
  58. }
  59. hr = myGetSecurityDescriptorDacl(pCASD, &pCAAcl);
  60. _JumpIfError(hr, error, "myGetSecurityDescriptorDacl");
  61. hr = myGetSecurityDescriptorDacl(pOfficerSD, &pOfficerAcl);
  62. _JumpIfError(hr, error, "myGetSecurityDescriptorDacl");
  63. // allocate a bool array for each DACL
  64. if(!GetAclInformation(pCAAcl,
  65. &CAAclInfo,
  66. sizeof(CAAclInfo),
  67. AclSizeInformation))
  68. {
  69. hr = myHLastError();
  70. _JumpError(hr, error, "GetAclInformation");
  71. }
  72. if(!GetAclInformation(pOfficerAcl,
  73. &OfficerAclInfo,
  74. sizeof(OfficerAclInfo),
  75. AclSizeInformation))
  76. {
  77. hr = myHLastError();
  78. _JumpError(hr, error, "GetAclInformation");
  79. }
  80. pCAFound = (PBOOL)LocalAlloc(LMEM_FIXED, sizeof(BOOL)*CAAclInfo.AceCount);
  81. if(!pCAFound)
  82. {
  83. hr = E_OUTOFMEMORY;
  84. _JumpError(hr, error, "LocalAlloc");
  85. }
  86. ZeroMemory(pCAFound, sizeof(BOOL)*CAAclInfo.AceCount);
  87. pOfficerFound = (PBOOL)LocalAlloc(LMEM_FIXED, sizeof(BOOL)*OfficerAclInfo.AceCount);
  88. if(!pOfficerFound)
  89. {
  90. hr = E_OUTOFMEMORY;
  91. _JumpError(hr, error, "LocalAlloc");
  92. }
  93. ZeroMemory(pOfficerFound, sizeof(BOOL)*OfficerAclInfo.AceCount);
  94. hr = GetEveryoneSID(&pSidEveryone);
  95. _JumpIfError(hr, error, "GetEveryoneSID");
  96. dwSidEveryoneSize = GetLengthSid(pSidEveryone);
  97. // mark in the bool arrays each ace whose SID is found in both DACLs;
  98. // also mark CA ACEs we are not interested in (denied ACEs and
  99. // non-officer ACEs)
  100. for(cCAAce=0; cCAAce<CAAclInfo.AceCount; cCAAce++)
  101. {
  102. if(!GetAce(pCAAcl, cCAAce, (PVOID*)&pCAAce))
  103. {
  104. hr = myHLastError();
  105. _JumpError(hr, error, "GetAce");
  106. }
  107. // process only officer allow aces
  108. if(0==(pCAAce->Mask & CA_ACCESS_OFFICER))
  109. {
  110. pCAFound[cCAAce] = TRUE;
  111. continue;
  112. }
  113. // compare SIDs in each officer ace with current CA ace and mark
  114. // corresponding bool in arrays if equal
  115. for(cOfficerAce=0; cOfficerAce<OfficerAclInfo.AceCount; cOfficerAce++)
  116. {
  117. if(!GetAce(pOfficerAcl, cOfficerAce, (PVOID*)&pOfficerAce))
  118. {
  119. hr = myHLastError();
  120. _JumpError(hr, error, "GetAce");
  121. }
  122. if(EqualSid((PSID)&pOfficerAce->SidStart,
  123. (PSID)&pCAAce->SidStart))
  124. {
  125. pCAFound[cCAAce] = TRUE;
  126. pOfficerFound[cOfficerAce] = TRUE;
  127. }
  128. }
  129. // if the officer is found in the CA ACL but not in the officer ACL,
  130. // we will add a new ACE allowing him to manage certs for Everyone
  131. if(!pCAFound[cCAAce])
  132. {
  133. dwNewAclSize += sizeof(ACCESS_ALLOWED_CALLBACK_ACE)+
  134. GetLengthSid((PSID)&pCAAce->SidStart)+
  135. dwSidEveryoneSize;
  136. }
  137. }
  138. // Calculate the size of the new officer ACL; we already added in the header
  139. // size and the size of the new ACEs to be added. Now we add the ACEs to be
  140. // copied over from the old ACL
  141. for(cOfficerAce=0; cOfficerAce<OfficerAclInfo.AceCount; cOfficerAce++)
  142. {
  143. if(pOfficerFound[cOfficerAce])
  144. {
  145. if(!GetAce(pOfficerAcl, cOfficerAce, (PVOID*)&pOfficerAce))
  146. {
  147. hr = myHLastError();
  148. _JumpError(hr, error, "GetAce");
  149. }
  150. dwNewAclSize += pOfficerAce->Header.AceSize;
  151. }
  152. }
  153. // allocate a new DACL
  154. pNewOfficerAcl = (PACL)LocalAlloc(LMEM_FIXED, dwNewAclSize);
  155. if(!pNewOfficerAcl)
  156. {
  157. hr = E_OUTOFMEMORY;
  158. _JumpError(hr, error, "LocalAlloc");
  159. }
  160. #ifdef _DEBUG
  161. ZeroMemory(pNewOfficerAcl, dwNewAclSize);
  162. #endif
  163. if(!InitializeAcl(pNewOfficerAcl, dwNewAclSize, ACL_REVISION))
  164. {
  165. hr = myHLastError();
  166. _JumpError(hr, error, "InitializeAcl");
  167. }
  168. // build the new DACL
  169. // traverse officer DACL and add only marked ACEs (whose SID was found
  170. // in the CA DACL, ie principal is an officer)
  171. for(cOfficerAce=0; cOfficerAce<OfficerAclInfo.AceCount; cOfficerAce++)
  172. {
  173. if(pOfficerFound[cOfficerAce])
  174. {
  175. if(!GetAce(pOfficerAcl, cOfficerAce, (PVOID*)&pOfficerAce))
  176. {
  177. hr = myHLastError();
  178. _JumpError(hr, error, "GetAce");
  179. }
  180. if(!AddAce(
  181. pNewOfficerAcl,
  182. ACL_REVISION,
  183. MAXDWORD,
  184. pOfficerAce,
  185. pOfficerAce->Header.AceSize))
  186. {
  187. hr = myHLastError();
  188. _JumpError(hr, error, "GetAce");
  189. }
  190. }
  191. }
  192. CSASSERT(IsValidAcl(pNewOfficerAcl));
  193. hr = GetBuiltinAdministratorsSID(&pSidBuiltinAdministrators);
  194. _JumpIfError(hr, error, "GetBuiltinAdministratorsSID");
  195. // traverse the CA DACL and add a new officer to list, allowed to manage
  196. // Everyone
  197. for(cCAAce=0; cCAAce<CAAclInfo.AceCount; cCAAce++)
  198. {
  199. if(pCAFound[cCAAce])
  200. continue;
  201. if(!GetAce(pCAAcl, cCAAce, (PVOID*)&pCAAce))
  202. {
  203. hr = myHLastError();
  204. _JumpError(hr, error, "GetAce");
  205. }
  206. // create a new ACE
  207. dwSidSize = GetLengthSid((PSID)&pCAAce->SidStart);
  208. dwAceSize = sizeof(ACCESS_ALLOWED_CALLBACK_ACE)+
  209. dwSidEveryoneSize+dwSidSize;
  210. pNewAce = (ACCESS_ALLOWED_CALLBACK_ACE*) LocalAlloc(LMEM_FIXED, dwAceSize);
  211. if(!pNewAce)
  212. {
  213. hr = E_OUTOFMEMORY;
  214. _JumpError(hr, error, "LocalAlloc");
  215. }
  216. #ifdef _DEBUG
  217. ZeroMemory(pNewAce, dwAceSize);
  218. #endif
  219. pNewAce->Header.AceType = ACCESS_ALLOWED_CALLBACK_ACE_TYPE;
  220. pNewAce->Header.AceFlags= 0;
  221. pNewAce->Header.AceSize = (USHORT)dwAceSize;
  222. pNewAce->Mask = DELETE;
  223. CopySid(dwSidSize,
  224. (PSID)&pNewAce->SidStart,
  225. (PSID)&pCAAce->SidStart);
  226. pSidList = (PSID_LIST)(((BYTE*)&pNewAce->SidStart)+dwSidSize);
  227. pSidList->dwSidCount = 1;
  228. CopySid(dwSidEveryoneSize,
  229. (PSID)&pSidList->SidListStart,
  230. pSidEveryone);
  231. CSASSERT(IsValidSid((PSID)&pNewAce->SidStart));
  232. if(!AddAce(
  233. pNewOfficerAcl,
  234. ACL_REVISION,
  235. MAXDWORD,
  236. pNewAce,
  237. dwAceSize))
  238. {
  239. hr = myHLastError();
  240. _JumpError(hr, error, "AddAce");
  241. }
  242. LocalFree(pNewAce);
  243. pNewAce = NULL;
  244. }
  245. CSASSERT(IsValidAcl(pNewOfficerAcl));
  246. // setup the new security descriptor
  247. pNewOfficerSD = (PSECURITY_DESCRIPTOR)LocalAlloc(LMEM_FIXED,
  248. SECURITY_DESCRIPTOR_MIN_LENGTH);
  249. if (pNewOfficerSD == NULL)
  250. {
  251. hr = E_OUTOFMEMORY;
  252. _JumpError(hr, error, "LocalAlloc");
  253. }
  254. #ifdef _DEBUG
  255. ZeroMemory(pNewOfficerSD, SECURITY_DESCRIPTOR_MIN_LENGTH);
  256. #endif
  257. if (!InitializeSecurityDescriptor(pNewOfficerSD, SECURITY_DESCRIPTOR_REVISION))
  258. {
  259. hr = myHLastError();
  260. _JumpError(hr, error, "InitializeSecurityDescriptor");
  261. }
  262. if(!SetSecurityDescriptorOwner(
  263. pNewOfficerSD,
  264. pSidBuiltinAdministrators,
  265. FALSE))
  266. {
  267. hr = myHLastError();
  268. _JumpError(hr, error, "SetSecurityDescriptorControl");
  269. }
  270. if(!SetSecurityDescriptorDacl(
  271. pNewOfficerSD,
  272. TRUE, // DACL present
  273. pNewOfficerAcl,
  274. FALSE)) // DACL defaulted
  275. {
  276. hr = myHLastError();
  277. _JumpError(hr, error, "SetSecurityDescriptorDacl");
  278. }
  279. CSASSERT(IsValidSecurityDescriptor(pNewOfficerSD));
  280. hr = Set(pNewOfficerSD);
  281. _JumpIfError(hr, error, "CProtectedSecurityDescriptor::Set");
  282. error:
  283. if(pNewAce)
  284. {
  285. LocalFree(pNewAce);
  286. }
  287. if(pSidEveryone)
  288. {
  289. FreeSid(pSidEveryone);
  290. }
  291. if(pSidBuiltinAdministrators)
  292. {
  293. FreeSid(pSidBuiltinAdministrators);
  294. }
  295. if(pNewOfficerAcl)
  296. {
  297. LocalFree(pNewOfficerAcl);
  298. }
  299. if(pNewOfficerSD)
  300. {
  301. LocalFree(pNewOfficerSD);
  302. }
  303. return hr;
  304. }
  305. HRESULT
  306. COfficerRightsSD::Adjust(PSECURITY_DESCRIPTOR pCASD)
  307. {
  308. return Merge(Get(), pCASD);
  309. }
  310. HRESULT
  311. COfficerRightsSD::InitializeEmpty()
  312. {
  313. HRESULT hr = S_OK;
  314. ACL Acl;
  315. SECURITY_DESCRIPTOR SD;
  316. hr = Init(NULL);
  317. _JumpIfError(hr, error, "CProtectedSecurityDescriptor::Init");
  318. if(!InitializeAcl(&Acl, sizeof(ACL), ACL_REVISION))
  319. {
  320. hr = myHLastError();
  321. _JumpError(hr, error, "InitializeAcl");
  322. }
  323. if (!InitializeSecurityDescriptor(&SD, SECURITY_DESCRIPTOR_REVISION))
  324. {
  325. hr = myHLastError();
  326. _JumpError(hr, error, "InitializeSecurityDescriptor");
  327. }
  328. if(!SetSecurityDescriptorDacl(
  329. &SD,
  330. TRUE, // DACL present
  331. &Acl,
  332. FALSE)) // DACL defaulted
  333. {
  334. hr = myHLastError();
  335. _JumpError(hr, error, "SetSecurityDescriptorControl");
  336. }
  337. m_fInitialized = true;
  338. hr = Set(&SD);
  339. _JumpIfError(hr, error, "CProtectedSecurityDescriptor::Set");
  340. error:
  341. return hr;
  342. }
  343. HRESULT COfficerRightsSD::Save()
  344. {
  345. HRESULT hr = S_OK;
  346. if(IsEnabled())
  347. {
  348. hr = CProtectedSecurityDescriptor::Save();
  349. _JumpIfError(hr, error, "CProtectedSecurityDescriptor::Save");
  350. }
  351. else
  352. {
  353. hr = CProtectedSecurityDescriptor::Delete();
  354. _JumpIfError(hr, error, "CProtectedSecurityDescriptor::Delete");
  355. }
  356. error:
  357. return hr;
  358. }
  359. HRESULT COfficerRightsSD::Load()
  360. {
  361. HRESULT hr;
  362. hr = CProtectedSecurityDescriptor::Load();
  363. if(S_OK==hr || HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND)==hr)
  364. {
  365. SetEnable(S_OK==hr);
  366. hr = S_OK;
  367. }
  368. _JumpIfError(hr, error, "CProtectedSecurityDescriptor::Save");
  369. error:
  370. return hr;
  371. }
  372. HRESULT COfficerRightsSD::Initialize(LPCWSTR pwszSanitizedName)
  373. {
  374. HRESULT hr;
  375. hr = CProtectedSecurityDescriptor::Initialize(pwszSanitizedName);
  376. _JumpIfError(hr, error, "CProtectedSecurityDescriptor::Save");
  377. SetEnable(NULL!=m_pSD);
  378. error:
  379. return hr;
  380. }
  381. HRESULT COfficerRightsSD::ConvertToString(
  382. IN PSECURITY_DESCRIPTOR pSD,
  383. OUT LPWSTR& rpwszSD)
  384. {
  385. HRESULT hr = S_OK;
  386. LPCWSTR pcwszHeader = L"\n"; // start with a new line
  387. DWORD dwBufSize = sizeof(WCHAR)*(wcslen(pcwszHeader)+1);
  388. ACL_SIZE_INFORMATION AclInfo;
  389. DWORD dwIndex;
  390. PACCESS_ALLOWED_CALLBACK_ACE pAce; // no free
  391. PACL pDacl; // no free
  392. LPWSTR pwszAce; // no free
  393. CSASSERT(IsValidSecurityDescriptor(pSD));
  394. rpwszSD = NULL;
  395. // get acl
  396. hr = myGetSecurityDescriptorDacl(
  397. pSD,
  398. &pDacl);
  399. _JumpIfError(hr, error, "myGetDaclFromInfoSecurityDescriptor");
  400. if(!GetAclInformation(pDacl,
  401. &AclInfo,
  402. sizeof(ACL_SIZE_INFORMATION),
  403. AclSizeInformation))
  404. {
  405. hr = myHLastError();
  406. _JumpError(hr, error, "GetAclInformation");
  407. }
  408. // calculate text size
  409. for(dwIndex = 0; dwIndex < AclInfo.AceCount; dwIndex++)
  410. {
  411. DWORD dwAceSize;
  412. if(!GetAce(pDacl, dwIndex, (LPVOID*)&pAce))
  413. {
  414. hr = myHLastError();
  415. _JumpError(hr, error, "GetAce");
  416. }
  417. hr = ConvertAceToString(
  418. pAce,
  419. &dwAceSize,
  420. NULL);
  421. _JumpIfError(hr, error, "ConvertAceToString");
  422. dwBufSize += dwAceSize;
  423. }
  424. rpwszSD = (LPWSTR)LocalAlloc(LMEM_FIXED, dwBufSize);
  425. _JumpIfAllocFailed(rpwszSD, error);
  426. // build the output string
  427. wcscpy(rpwszSD, pcwszHeader);
  428. pwszAce = rpwszSD + wcslen(pcwszHeader);
  429. for(dwIndex = 0; dwIndex < AclInfo.AceCount; dwIndex++)
  430. {
  431. DWORD dwAceSize;
  432. if(!GetAce(pDacl, dwIndex, (LPVOID*)&pAce))
  433. {
  434. hr = myHLastError();
  435. _JumpError(hr, error, "GetAce");
  436. }
  437. hr = ConvertAceToString(
  438. pAce,
  439. &dwAceSize,
  440. pwszAce);
  441. _JumpIfError(hr, error, "ConvertAceToString");
  442. pwszAce += dwAceSize/sizeof(WCHAR);
  443. }
  444. error:
  445. return hr;
  446. }
  447. // Returned string has the following format:
  448. //
  449. // [Allow|Deny]\t[OfficerName|SID]\n
  450. // \t[Client1Name|SID]\n
  451. // \t[Client2Name|SID]\n
  452. // ...
  453. //
  454. // Example:
  455. //
  456. // Allow OfficerGroup1
  457. // ClientGroup1
  458. // ClientGroup2
  459. //
  460. // If SID cannot be converted to friendly name it is displayed
  461. // as a string SID
  462. //
  463. HRESULT COfficerRightsSD::ConvertAceToString(
  464. IN PACCESS_ALLOWED_CALLBACK_ACE pAce,
  465. OUT OPTIONAL PDWORD pdwSize,
  466. IN OUT OPTIONAL LPWSTR pwszSD)
  467. {
  468. HRESULT hr = S_OK;
  469. DWORD dwSize = 1; // trailing '\0'
  470. CSid sid((PSID)(&pAce->SidStart));
  471. PSID_LIST pSidList = (PSID_LIST) (((BYTE*)&pAce->SidStart)+
  472. GetLengthSid(&pAce->SidStart));
  473. PSID pSid;
  474. DWORD cSids;
  475. LPCWSTR pcwszAllow = m_pcwszResources[0];
  476. LPCWSTR pcwszDeny = m_pcwszResources[1];
  477. LPCWSTR pcwszPermissionType =
  478. (ACCESS_ALLOWED_CALLBACK_ACE_TYPE==pAce->Header.AceType)?
  479. pcwszAllow:pcwszDeny;
  480. LPCWSTR pcwszSid; // no free
  481. // asked for size and/or ace string
  482. CSASSERT(pdwSize || pwszSD);
  483. if(pAce->Header.AceType != ACCESS_ALLOWED_CALLBACK_ACE_TYPE &&
  484. pAce->Header.AceType != ACCESS_DENIED_CALLBACK_ACE_TYPE)
  485. {
  486. return E_INVALIDARG;
  487. }
  488. pcwszSid = sid.GetName();
  489. if(!pcwszSid)
  490. {
  491. return E_OUTOFMEMORY;
  492. }
  493. dwSize = wcslen(pcwszSid);
  494. dwSize += wcslen(pcwszPermissionType);
  495. dwSize += 2; // '\t' between sid an permission and a '\n' after
  496. if(pwszSD)
  497. {
  498. wcscat(pwszSD, pcwszPermissionType);
  499. wcscat(pwszSD, L"\t");
  500. wcscat(pwszSD, pcwszSid);
  501. wcscat(pwszSD, L"\n");
  502. }
  503. for(pSid=(PSID)&pSidList->SidListStart, cSids=0; cSids<pSidList->dwSidCount;
  504. cSids++, pSid = (PSID)(((BYTE*)pSid)+GetLengthSid(pSid)))
  505. {
  506. CSASSERT(IsValidSid(pSid));
  507. CSid sidClient(pSid);
  508. LPCWSTR pcwszSidClient;
  509. pcwszSidClient = sidClient.GetName();
  510. if(!pcwszSidClient)
  511. {
  512. return E_OUTOFMEMORY;
  513. }
  514. dwSize += wcslen(pcwszSidClient) + 2; // \tClientNameOrSid\n
  515. if(pwszSD)
  516. {
  517. wcscat(pwszSD, L"\t");
  518. wcscat(pwszSD, pcwszSidClient);
  519. wcscat(pwszSD, L"\n");
  520. }
  521. }
  522. dwSize *= sizeof(WCHAR);
  523. if(pdwSize)
  524. {
  525. *pdwSize = dwSize;
  526. }
  527. return hr;
  528. }
  529. HRESULT
  530. CertSrv::GetWellKnownSID(
  531. PSID *ppSid,
  532. SID_IDENTIFIER_AUTHORITY *pAuth,
  533. BYTE SubauthorityCount,
  534. DWORD SubAuthority1,
  535. DWORD SubAuthority2,
  536. DWORD SubAuthority3,
  537. DWORD SubAuthority4,
  538. DWORD SubAuthority5,
  539. DWORD SubAuthority6,
  540. DWORD SubAuthority7,
  541. DWORD SubAuthority8)
  542. {
  543. HRESULT hr = S_OK;
  544. // build Everyone SID
  545. if(!AllocateAndInitializeSid(
  546. pAuth,
  547. SubauthorityCount,
  548. SubAuthority1,
  549. SubAuthority2,
  550. SubAuthority3,
  551. SubAuthority4,
  552. SubAuthority5,
  553. SubAuthority6,
  554. SubAuthority7,
  555. SubAuthority8,
  556. ppSid))
  557. {
  558. hr = myHLastError();
  559. _JumpError(hr, error, "AllocateAndInitializeSid");
  560. }
  561. error:
  562. return hr;
  563. }
  564. // caller is responsible for LocalFree'ing PSID
  565. HRESULT CertSrv::GetEveryoneSID(PSID *ppSid)
  566. {
  567. SID_IDENTIFIER_AUTHORITY SIDAuth = SECURITY_WORLD_SID_AUTHORITY;
  568. return GetWellKnownSID(
  569. ppSid,
  570. &SIDAuth,
  571. 1,
  572. SECURITY_WORLD_RID);
  573. return S_OK;
  574. }
  575. // caller is responsible for LocalFree'ing PSID
  576. HRESULT CertSrv::GetLocalSystemSID(PSID *ppSid)
  577. {
  578. SID_IDENTIFIER_AUTHORITY SIDAuth = SECURITY_NT_AUTHORITY;
  579. return GetWellKnownSID(
  580. ppSid,
  581. &SIDAuth,
  582. 1,
  583. SECURITY_LOCAL_SYSTEM_RID);
  584. }
  585. // caller is responsible for LocalFree'ing PSID
  586. HRESULT CertSrv::GetBuiltinAdministratorsSID(PSID *ppSid)
  587. {
  588. SID_IDENTIFIER_AUTHORITY SIDAuth = SECURITY_NT_AUTHORITY;
  589. return GetWellKnownSID(
  590. ppSid,
  591. &SIDAuth,
  592. 2,
  593. SECURITY_BUILTIN_DOMAIN_RID,
  594. DOMAIN_ALIAS_RID_ADMINS);
  595. }