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.

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