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.

482 lines
13 KiB

  1. //+--------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1996 - 1999
  5. //
  6. // File: acl.cpp
  7. //
  8. // Contents: Access Control helpers for certsrv
  9. //
  10. // History: 11-16-98 petesk created
  11. // 10/99 xtan, major changes
  12. //
  13. //---------------------------------------------------------------------------
  14. #include <pch.cpp>
  15. #pragma hdrstop
  16. #include <ntdsapi.h>
  17. #define SECURITY_WIN32
  18. #include <security.h>
  19. #include <sddl.h>
  20. #include <aclapi.h>
  21. #include "certca.h"
  22. #include "cscsp.h"
  23. #include "certacl.h"
  24. #include "certsd.h"
  25. #define __dwFILE__ __dwFILE_CERTLIB_ACL_CPP__
  26. // defines
  27. const GUID GUID_APPRV_REQ = { /* 0e10c966-78fb-11d2-90d4-00c04f79dc55 */
  28. 0x0e10c966,
  29. 0x78fb,
  30. 0x11d2,
  31. {0x90, 0xd4, 0x00, 0xc0, 0x4f, 0x79, 0xdc, 0x55} };
  32. const GUID GUID_REVOKE= { /* 0e10c967-78fb-11d2-90d4-00c04f79dc55 */
  33. 0x0e10c967,
  34. 0x78fb,
  35. 0x11d2,
  36. {0x90, 0xd4, 0x00, 0xc0, 0x4f, 0x79, 0xdc, 0x55} };
  37. // Important, keep enroll GUID in sync with string define in certacl.h
  38. const GUID GUID_ENROLL = { /* 0e10c968-78fb-11d2-90d4-00c04f79dc55 */
  39. 0x0e10c968,
  40. 0x78fb,
  41. 0x11d2,
  42. {0x90, 0xd4, 0x00, 0xc0, 0x4f, 0x79, 0xdc, 0x55} };
  43. const GUID GUID_AUTOENROLL = { /* a05b8cc2-17bc-4802-a710-e7c15ab866a2 */
  44. 0xa05b8cc2,
  45. 0x17bc,
  46. 0x4802,
  47. {0xa7, 0x10, 0xe7, 0xc1, 0x5a, 0xb8, 0x66, 0xa2} };
  48. const GUID GUID_READ_DB = { /* 0e10c969-78fb-11d2-90d4-00c04f79dc55 */
  49. 0x0e10c969,
  50. 0x78fb,
  51. 0x11d2,
  52. {0x90, 0xd4, 0x00, 0xc0, 0x4f, 0x79, 0xdc, 0x55} };
  53. HRESULT
  54. myGetSDFromTemplate(
  55. IN WCHAR const *pwszStringSD,
  56. IN OPTIONAL WCHAR const *pwszReplace,
  57. OUT PSECURITY_DESCRIPTOR *ppSD)
  58. {
  59. HRESULT hr;
  60. WCHAR *pwszReplaceSD = NULL;
  61. WCHAR const *pwszFinalSD = pwszStringSD;
  62. CSASSERT(NULL != ppSD);
  63. if (NULL == ppSD)
  64. {
  65. hr = E_POINTER;
  66. _JumpError(hr, error, "null SD pointer");
  67. }
  68. if (NULL != pwszReplace)
  69. {
  70. // replace the token
  71. CSASSERT(NULL != wcsstr(pwszStringSD, L"%ws"));
  72. pwszReplaceSD = (WCHAR*)LocalAlloc(LMEM_FIXED,
  73. (wcslen(pwszStringSD) +
  74. wcslen(pwszReplace) + 1) * sizeof(WCHAR) );
  75. if (NULL == pwszReplaceSD)
  76. {
  77. hr = E_OUTOFMEMORY;
  78. _JumpError(hr, error, "LocalAlloc");
  79. }
  80. wsprintf(pwszReplaceSD, pwszStringSD, pwszReplace);
  81. pwszFinalSD = pwszReplaceSD;
  82. }
  83. // build the security descriptor including the local machine.
  84. if (!myConvertStringSecurityDescriptorToSecurityDescriptor(
  85. pwszFinalSD,
  86. SDDL_REVISION,
  87. ppSD,
  88. NULL))
  89. {
  90. hr = myHLastError();
  91. _JumpErrorStr(
  92. hr,
  93. error,
  94. "myConvertStringSecurityDescriptorToSecurityDescriptor",pwszFinalSD);
  95. }
  96. DBGPRINT((DBG_SS_CERTLIBI, "security descriptor:%ws\n", pwszFinalSD));
  97. hr = S_OK;
  98. error:
  99. if (NULL != pwszReplaceSD)
  100. {
  101. LocalFree(pwszReplaceSD);
  102. }
  103. return hr;
  104. }
  105. HRESULT
  106. myGetSecurityDescriptorDacl(
  107. IN PSECURITY_DESCRIPTOR pSD,
  108. OUT PACL *ppDacl) // no free
  109. {
  110. HRESULT hr;
  111. PACL pDacl = NULL; //no free
  112. BOOL bDaclPresent = FALSE;
  113. BOOL bDaclDefaulted = FALSE;
  114. CSASSERT(NULL != ppDacl);
  115. //init
  116. *ppDacl = NULL;
  117. // get dacl pointers
  118. if (!GetSecurityDescriptorDacl(pSD,
  119. &bDaclPresent,
  120. &pDacl,
  121. &bDaclDefaulted))
  122. {
  123. hr = myHLastError();
  124. _JumpError(hr, error, "GetSecurityDescriptorDacl");
  125. }
  126. if(!bDaclPresent || (pDacl == NULL))
  127. {
  128. hr = E_UNEXPECTED;
  129. _JumpError(hr, error, "GetSecurityDescriptorDacl");
  130. }
  131. *ppDacl = pDacl;
  132. hr = S_OK;
  133. error:
  134. return hr;
  135. }
  136. HRESULT
  137. myGetSecurityDescriptorSacl(
  138. IN PSECURITY_DESCRIPTOR pSD,
  139. OUT PACL *ppSacl) // no free
  140. {
  141. HRESULT hr;
  142. PACL pSacl = NULL; //no free
  143. BOOL bSaclPresent = FALSE;
  144. BOOL bSaclDefaulted = FALSE;
  145. CSASSERT(NULL != ppSacl);
  146. //init
  147. *ppSacl = NULL;
  148. // get dacl pointers
  149. if (!GetSecurityDescriptorSacl(pSD,
  150. &bSaclPresent,
  151. &pSacl,
  152. &bSaclDefaulted))
  153. {
  154. hr = myHLastError();
  155. _JumpError(hr, error, "GetSecurityDescriptorDacl");
  156. }
  157. if(!bSaclPresent || (pSacl == NULL))
  158. {
  159. hr = E_UNEXPECTED;
  160. _JumpError(hr, error, "GetSecurityDescriptorDacl");
  161. }
  162. *ppSacl = pSacl;
  163. hr = S_OK;
  164. error:
  165. return hr;
  166. }
  167. #define CERTSRV_DACL_CONTROL_MASK SE_DACL_AUTO_INHERIT_REQ | \
  168. SE_DACL_AUTO_INHERITED | \
  169. SE_DACL_PROTECTED
  170. #define CERTSRV_SACL_CONTROL_MASK SE_SACL_AUTO_INHERIT_REQ | \
  171. SE_SACL_AUTO_INHERITED | \
  172. SE_SACL_PROTECTED
  173. // Merge parts of a new SD with an old SD based on the SI flags:
  174. // DACL_SECURITY_INFORMATION - use new SD DACL
  175. // SACL_SECURITY_INFORMATION - use new SD SACL
  176. // OWNER_SECURITY_INFORMATION - use new SD owner
  177. // GROUP_SECURITY_INFORMATION - use new SD group
  178. HRESULT
  179. myMergeSD(
  180. IN PSECURITY_DESCRIPTOR pSDOld,
  181. IN PSECURITY_DESCRIPTOR pSDMerge,
  182. IN SECURITY_INFORMATION si,
  183. OUT PSECURITY_DESCRIPTOR *ppSDNew)
  184. {
  185. HRESULT hr;
  186. PSECURITY_DESCRIPTOR pSDDaclSource =
  187. si & DACL_SECURITY_INFORMATION ? pSDMerge : pSDOld;
  188. PSECURITY_DESCRIPTOR pSDSaclSource =
  189. si & SACL_SECURITY_INFORMATION ? pSDMerge : pSDOld;
  190. PSECURITY_DESCRIPTOR pSDOwnerSource =
  191. si & OWNER_SECURITY_INFORMATION ? pSDMerge : pSDOld;
  192. PSECURITY_DESCRIPTOR pSDGroupSource =
  193. si & GROUP_SECURITY_INFORMATION ? pSDMerge : pSDOld;
  194. PSECURITY_DESCRIPTOR pSDNew = NULL;
  195. PSECURITY_DESCRIPTOR pSDNewRelative = NULL;
  196. SECURITY_DESCRIPTOR_CONTROL sdc;
  197. PACL pDacl = NULL; //no free
  198. PSID pGroupSid = NULL; //no free
  199. BOOL fGroupDefaulted = FALSE;
  200. PSID pOwnerSid = NULL; //no free
  201. BOOL fOwnerDefaulted = FALSE;
  202. DWORD dwSize;
  203. BOOL fSaclPresent = FALSE;
  204. BOOL fSaclDefaulted = FALSE;
  205. PACL pSacl = NULL; //no free
  206. DWORD dwRevision;
  207. CSASSERT(NULL != pSDOld);
  208. CSASSERT(NULL != pSDMerge);
  209. CSASSERT(NULL != ppSDNew);
  210. *ppSDNew = NULL;
  211. pSDNew = (PSECURITY_DESCRIPTOR)LocalAlloc(LMEM_FIXED,
  212. SECURITY_DESCRIPTOR_MIN_LENGTH);
  213. if (pSDNew == NULL)
  214. {
  215. hr = E_OUTOFMEMORY;
  216. _JumpError(hr, error, "LocalAlloc");
  217. }
  218. if (!InitializeSecurityDescriptor(pSDNew, SECURITY_DESCRIPTOR_REVISION))
  219. {
  220. hr = myHLastError();
  221. _JumpError(hr, error, "InitializeSecurityDescriptor");
  222. }
  223. // set SD control
  224. if (!GetSecurityDescriptorControl(pSDOld, &sdc, &dwRevision))
  225. {
  226. hr = myHLastError();
  227. _JumpError(hr, error, "GetSecurityDescriptorControl");
  228. }
  229. if (!SetSecurityDescriptorControl(
  230. pSDNew,
  231. CERTSRV_DACL_CONTROL_MASK|
  232. CERTSRV_SACL_CONTROL_MASK,
  233. sdc &
  234. (CERTSRV_DACL_CONTROL_MASK|
  235. CERTSRV_SACL_CONTROL_MASK)))
  236. {
  237. hr = myHLastError();
  238. _JumpError(hr, error, "SetSecurityDescriptorControl");
  239. }
  240. // get CA security acl info
  241. hr = myGetSecurityDescriptorDacl(
  242. pSDDaclSource,
  243. &pDacl);
  244. _JumpIfError(hr, error, "myGetDaclFromInfoSecurityDescriptor");
  245. // set new SD dacl
  246. if(!SetSecurityDescriptorDacl(pSDNew,
  247. TRUE,
  248. pDacl,
  249. FALSE))
  250. {
  251. hr = myHLastError();
  252. _JumpError(hr, error, "SetSecurityDescriptorDacl");
  253. }
  254. // set new SD group
  255. if(!GetSecurityDescriptorGroup(pSDGroupSource, &pGroupSid, &fGroupDefaulted))
  256. {
  257. hr = myHLastError();
  258. _JumpError(hr, error, "GetSecurityDescriptorGroup");
  259. }
  260. if(!SetSecurityDescriptorGroup(pSDNew, pGroupSid, fGroupDefaulted))
  261. {
  262. hr = myHLastError();
  263. _JumpError(hr, error, "SetSecurityDescriptorGroup");
  264. }
  265. // set new SD owner
  266. if(!GetSecurityDescriptorOwner(pSDOwnerSource, &pOwnerSid, &fOwnerDefaulted))
  267. {
  268. hr = myHLastError();
  269. _JumpError(hr, error, "GetSecurityDescriptorGroup");
  270. }
  271. if(!SetSecurityDescriptorOwner(pSDNew, pOwnerSid, fOwnerDefaulted))
  272. {
  273. hr = myHLastError();
  274. _JumpError(hr, error, "SetSecurityDescriptorGroup");
  275. }
  276. // set new SD sacl
  277. if(!GetSecurityDescriptorSacl(pSDSaclSource, &fSaclPresent, &pSacl, &fSaclDefaulted))
  278. {
  279. hr = myHLastError();
  280. _JumpError(hr, error, "GetSecurityDescriptorSacl");
  281. }
  282. if(!SetSecurityDescriptorSacl(pSDNew, fSaclPresent, pSacl, fSaclDefaulted))
  283. {
  284. hr = myHLastError();
  285. _JumpError(hr, error, "SetSecurityDescriptorSacl");
  286. }
  287. if (!IsValidSecurityDescriptor(pSDNew))
  288. {
  289. hr = myHLastError();
  290. _JumpError(hr, error, "IsValidSecurityDescriptor");
  291. }
  292. dwSize = GetSecurityDescriptorLength(pSDNew);
  293. pSDNewRelative = (PSECURITY_DESCRIPTOR)LocalAlloc(LMEM_FIXED, dwSize);
  294. if(pSDNewRelative == NULL)
  295. {
  296. hr = E_OUTOFMEMORY;
  297. _JumpError(hr, error, "LocalAlloc");
  298. }
  299. if(!MakeSelfRelativeSD(pSDNew, pSDNewRelative, &dwSize))
  300. {
  301. hr = myHLastError();
  302. _JumpError(hr, error, "LocalAlloc");
  303. }
  304. if (!IsValidSecurityDescriptor(pSDNewRelative))
  305. {
  306. hr = myHLastError();
  307. _JumpError(hr, error, "IsValidSecurityDescriptor");
  308. }
  309. *ppSDNew = pSDNewRelative;
  310. pSDNewRelative = NULL;
  311. hr = S_OK;
  312. error:
  313. if(pSDNew)
  314. {
  315. LocalFree(pSDNew);
  316. }
  317. if(pSDNewRelative)
  318. {
  319. LocalFree(pSDNewRelative);
  320. }
  321. return hr;
  322. }
  323. HRESULT
  324. UpdateServiceSacl(bool fTurnOnAuditing)
  325. {
  326. HRESULT hr = S_OK;
  327. PSECURITY_DESCRIPTOR pSaclSD = NULL;
  328. PACL pSacl = NULL; // no free
  329. bool fPrivilegeEnabled = false;
  330. hr = myGetSDFromTemplate(
  331. fTurnOnAuditing?
  332. CERTSRV_SERVICE_SACL_ON:
  333. CERTSRV_SERVICE_SACL_OFF,
  334. NULL, // no insertion string
  335. &pSaclSD);
  336. _JumpIfError(hr, error, "myGetSDFromTemplate");
  337. hr = myGetSecurityDescriptorSacl(
  338. pSaclSD,
  339. &pSacl);
  340. _JumpIfError(hr, error, "myGet");
  341. hr = myEnablePrivilege(SE_SECURITY_NAME, TRUE);
  342. _JumpIfError(hr, error, "myEnablePrivilege");
  343. fPrivilegeEnabled = true;
  344. hr = SetNamedSecurityInfo(
  345. wszSERVICE_NAME,
  346. SE_SERVICE,
  347. SACL_SECURITY_INFORMATION,
  348. NULL,
  349. NULL,
  350. NULL,
  351. pSacl);
  352. if(ERROR_SUCCESS != hr)
  353. {
  354. hr = myHError(hr);
  355. _JumpError(hr, error, "SetNamedSecurityInfo");
  356. }
  357. error:
  358. if(fPrivilegeEnabled)
  359. {
  360. myEnablePrivilege(SE_SECURITY_NAME, FALSE);
  361. }
  362. LOCAL_FREE(pSaclSD);
  363. return hr;
  364. }
  365. HRESULT
  366. SetFolderDacl(LPCWSTR pcwszFolderPath, LPCWSTR pcwszSDDL)
  367. {
  368. HRESULT hr = S_OK;
  369. PSECURITY_DESCRIPTOR pSD = NULL;
  370. hr = myGetSDFromTemplate(pcwszSDDL, NULL, &pSD);
  371. _JumpIfErrorStr(hr, error, "myGetSDFromTemplate", pcwszSDDL);
  372. if (!SetFileSecurity(
  373. pcwszFolderPath,
  374. DACL_SECURITY_INFORMATION,
  375. pSD))
  376. {
  377. hr = myHLastError();
  378. _JumpError(hr, error, "SetFileSecurity");
  379. }
  380. error:
  381. LOCAL_FREE(pSD);
  382. return hr;
  383. }
  384. HRESULT
  385. mySetKeyContainerSecurity(
  386. IN HCRYPTPROV hProv)
  387. {
  388. HRESULT hr;
  389. PSECURITY_DESCRIPTOR pSD = NULL;
  390. hr = myGetSDFromTemplate(WSZ_DEFAULT_KEYCONTAINER_SECURITY, NULL, &pSD);
  391. _JumpIfError(hr, error, "myGetSDFromTemplate");
  392. // apply the security descriptor to the key container
  393. if (!CryptSetProvParam(
  394. hProv,
  395. PP_KEYSET_SEC_DESCR,
  396. (BYTE *) pSD,
  397. (DWORD) DACL_SECURITY_INFORMATION))
  398. {
  399. hr = myHLastError();
  400. _JumpError(hr, error, "CryptSetProvParam");
  401. }
  402. hr = S_OK;
  403. error:
  404. if (NULL != pSD)
  405. {
  406. LocalFree(pSD);
  407. }
  408. return(hr);
  409. }