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.

441 lines
10 KiB

  1. /*
  2. * Acl.c
  3. *
  4. * Author: BreenH
  5. *
  6. * Acl utilities.
  7. */
  8. /*
  9. * Includes
  10. */
  11. #include "precomp.h"
  12. #include "tsutil.h"
  13. #include "tsutilnt.h"
  14. /*
  15. * Function Implementations
  16. */
  17. BOOL WINAPI
  18. AddSidToObjectsSecurityDescriptor(
  19. HANDLE hObject,
  20. SE_OBJECT_TYPE ObjectType,
  21. PSID pSid,
  22. DWORD dwNewAccess,
  23. ACCESS_MODE AccessMode,
  24. DWORD dwInheritance
  25. )
  26. {
  27. BOOL fRet;
  28. DWORD dwRet;
  29. EXPLICIT_ACCESS ExpAccess;
  30. PACL pNewDacl;
  31. PACL pOldDacl;
  32. PSECURITY_DESCRIPTOR pSd;
  33. //
  34. // Get the objects security descriptor and current Dacl.
  35. //
  36. pSd = NULL;
  37. pOldDacl = NULL;
  38. dwRet = GetSecurityInfo(
  39. hObject,
  40. ObjectType,
  41. DACL_SECURITY_INFORMATION,
  42. NULL,
  43. NULL,
  44. &pOldDacl,
  45. NULL,
  46. &pSd
  47. );
  48. if (dwRet != ERROR_SUCCESS)
  49. {
  50. return(FALSE);
  51. }
  52. //
  53. // Initialize an EXPLICIT_ACCESS structure for the new ace.
  54. //
  55. ZeroMemory(&ExpAccess, sizeof(EXPLICIT_ACCESS));
  56. ExpAccess.grfAccessPermissions = dwNewAccess;
  57. ExpAccess.grfAccessMode = AccessMode;
  58. ExpAccess.grfInheritance = dwInheritance;
  59. BuildTrusteeWithSid(&(ExpAccess.Trustee), pSid);
  60. //
  61. // Merge the new ace into the existing Dacl.
  62. //
  63. fRet = FALSE;
  64. dwRet = SetEntriesInAcl(
  65. 1,
  66. &ExpAccess,
  67. pOldDacl,
  68. &pNewDacl
  69. );
  70. if (dwRet == ERROR_SUCCESS)
  71. {
  72. //
  73. // Set the new security for the object.
  74. //
  75. dwRet = SetSecurityInfo(
  76. hObject,
  77. ObjectType,
  78. DACL_SECURITY_INFORMATION,
  79. NULL,
  80. NULL,
  81. pNewDacl,
  82. NULL
  83. );
  84. if (dwRet == ERROR_SUCCESS)
  85. {
  86. fRet = TRUE;
  87. }
  88. }
  89. if (pNewDacl != NULL)
  90. {
  91. LocalFree(pNewDacl);
  92. }
  93. if (pSd != NULL)
  94. {
  95. LocalFree(pSd);
  96. }
  97. return(fRet);
  98. }
  99. BOOL WINAPI
  100. AddSidToSecurityDescriptor(
  101. PSECURITY_DESCRIPTOR *ppSd,
  102. PSID pSid,
  103. DWORD dwNewAccess,
  104. ACCESS_MODE AccessMode,
  105. DWORD dwInheritance
  106. )
  107. {
  108. BOOL fAbsoluteSd;
  109. BOOL fDaclDefaulted;
  110. BOOL fDaclPresent;
  111. BOOL fRet;
  112. PACL pDacl;
  113. PSECURITY_DESCRIPTOR pAbsoluteSd;
  114. PSECURITY_DESCRIPTOR pOriginalSd;
  115. ASSERT(ppSd != NULL);
  116. ASSERT(*ppSd != NULL);
  117. //
  118. // The security descriptors should be absolute to allow the addition of
  119. // the new ace.
  120. //
  121. pOriginalSd = *ppSd;
  122. fAbsoluteSd = IsSecurityDescriptorAbsolute(pOriginalSd);
  123. if (!fAbsoluteSd)
  124. {
  125. fRet = ConvertSelfRelativeToAbsolute(&pAbsoluteSd, pOriginalSd);
  126. if (!fRet)
  127. {
  128. return(FALSE);
  129. }
  130. }
  131. else
  132. {
  133. pAbsoluteSd = pOriginalSd;
  134. }
  135. //
  136. // Now that the type of security descriptor is absolute, get the Dacl.
  137. //
  138. pDacl = NULL;
  139. fRet = GetSecurityDescriptorDacl(
  140. pAbsoluteSd,
  141. &fDaclPresent,
  142. &pDacl,
  143. &fDaclDefaulted
  144. );
  145. if (fRet)
  146. {
  147. DWORD dwRet;
  148. EXPLICIT_ACCESS ExplicitAccess;
  149. PACL pNewDacl;
  150. //
  151. // Initialize an EXPLICIT_ACCESS structure for the new ace.
  152. //
  153. RtlZeroMemory(&ExplicitAccess, sizeof(EXPLICIT_ACCESS));
  154. ExplicitAccess.grfAccessPermissions = dwNewAccess;
  155. ExplicitAccess.grfAccessMode = AccessMode;
  156. ExplicitAccess.grfInheritance = dwInheritance;
  157. BuildTrusteeWithSid(&(ExplicitAccess.Trustee), pSid);
  158. //
  159. // Merge the ace into the existing Dacl. This will allocate a new
  160. // Dacl. Unfortunately this API is only available as a WINAPI.
  161. //
  162. pNewDacl = NULL;
  163. dwRet = SetEntriesInAcl(
  164. 1,
  165. &ExplicitAccess,
  166. pDacl,
  167. &pNewDacl
  168. );
  169. if (dwRet == ERROR_SUCCESS)
  170. {
  171. ASSERT(pNewDacl != NULL);
  172. //
  173. // Point the security descriptor's Dacl to the new Dacl.
  174. //
  175. fRet = SetSecurityDescriptorDacl(
  176. pAbsoluteSd,
  177. TRUE,
  178. pNewDacl,
  179. FALSE
  180. );
  181. if (fRet)
  182. {
  183. PULONG_PTR pBeginning;
  184. PULONG_PTR pEnd;
  185. PULONG_PTR pPtr;
  186. //
  187. // The new Dacl has been set, free the old. Be careful here;
  188. // the RTL folks like to put absolute security descriptors in
  189. // one big allocation, just like a self-relative security
  190. // descriptor. If the old Dacl is inside the security
  191. // descriptor allocation, it cannot be freed. Essentially,
  192. // that memory becomes unused, and the security descriptor
  193. // takes up more space than necessary.
  194. //
  195. pBeginning = (PULONG_PTR)pAbsoluteSd;
  196. pEnd = (PULONG_PTR)((PBYTE)pAbsoluteSd +
  197. LocalSize(pAbsoluteSd));
  198. pPtr = (PULONG_PTR)pDacl;
  199. if ((pPtr < pBeginning) || (pPtr > pEnd))
  200. {
  201. LocalFree(pDacl);
  202. }
  203. }
  204. else
  205. {
  206. //
  207. // A failure occurred setting the new Dacl. This should never
  208. // occur, but if it does, free the newly created Dacl.
  209. //
  210. LocalFree(pNewDacl);
  211. }
  212. }
  213. else
  214. {
  215. fRet = FALSE;
  216. }
  217. }
  218. //
  219. // The new security descriptor should be returned in the same format as
  220. // the original security descriptor. The returned security descriptor is
  221. // also dependent on the success of the function.
  222. //
  223. if (!fAbsoluteSd)
  224. {
  225. if (fRet)
  226. {
  227. PSECURITY_DESCRIPTOR pNewSd;
  228. //
  229. // The original security descriptor was self-relative, and until
  230. // now everything has succeeded. Convert the temporary absolute
  231. // security descriptor back to self-relative form. This creates a
  232. // third security descriptor (the other two being the original
  233. // and the absolute).
  234. //
  235. pNewSd = NULL;
  236. fRet = ConvertAbsoluteToSelfRelative(
  237. &pNewSd,
  238. pAbsoluteSd,
  239. NULL
  240. );
  241. if (fRet)
  242. {
  243. //
  244. // The final conversion was successful. Free the original
  245. // security descriptor. The absolute security descriptor is
  246. // freed later. The only possible error from destroying the
  247. // security descriptor is a version mismatch, but that would
  248. // have happened long ago.
  249. //
  250. *ppSd = pNewSd;
  251. (VOID)DestroySecurityDescriptor(&pOriginalSd);
  252. }
  253. else
  254. {
  255. //
  256. // The final conversion failed. At this point, the original
  257. // security descriptor is still intact. Free the absolute
  258. // security descriptor that was created earlier, and leave
  259. // the passed in security descriptor pointer alone. Note that
  260. // with the absolute security descriptor being freed later,
  261. // there is nothing to do here.
  262. //
  263. }
  264. }
  265. //
  266. // Regardless of success or failure, the absolute security descriptor
  267. // was created, so it must be freed. The only possible error from destroying the
  268. // security descriptor is a version mismatch, but that would
  269. // have happened long ago.
  270. //
  271. (VOID)DestroySecurityDescriptor(&pAbsoluteSd);
  272. }
  273. else
  274. {
  275. //
  276. // Regardless of what happened, there is nothing to do here. The
  277. // original security descriptor was absolute; therefore no copies
  278. // were made. The only data that changed was the Dacl, and whether
  279. // or not that succeeded is irrelevant, as that was handled above.
  280. //
  281. }
  282. return(fRet);
  283. }
  284. BOOL WINAPI
  285. ConvertAbsoluteToSelfRelative(
  286. PSECURITY_DESCRIPTOR *ppSelfRelativeSd,
  287. PSECURITY_DESCRIPTOR pAbsoluteSd,
  288. PDWORD pcbSelfRelativeSd
  289. )
  290. {
  291. BOOL fRet;
  292. NTSTATUS Status;
  293. Status = NtConvertAbsoluteToSelfRelative(
  294. ppSelfRelativeSd,
  295. pAbsoluteSd,
  296. pcbSelfRelativeSd
  297. );
  298. if (NT_SUCCESS(Status))
  299. {
  300. fRet = TRUE;
  301. }
  302. else
  303. {
  304. fRet = FALSE;
  305. SetLastError(RtlNtStatusToDosError(Status));
  306. }
  307. return(fRet);
  308. }
  309. BOOL WINAPI
  310. ConvertSelfRelativeToAbsolute(
  311. PSECURITY_DESCRIPTOR *ppAbsoluteSd,
  312. PSECURITY_DESCRIPTOR pSelfRelativeSd
  313. )
  314. {
  315. BOOL fRet;
  316. NTSTATUS Status;
  317. Status = NtConvertSelfRelativeToAbsolute(ppAbsoluteSd, pSelfRelativeSd);
  318. if (NT_SUCCESS(Status))
  319. {
  320. fRet = TRUE;
  321. }
  322. else
  323. {
  324. fRet = FALSE;
  325. SetLastError(RtlNtStatusToDosError(Status));
  326. }
  327. return(fRet);
  328. }
  329. BOOL WINAPI
  330. DestroySecurityDescriptor(
  331. PSECURITY_DESCRIPTOR *ppSd
  332. )
  333. {
  334. BOOL fRet;
  335. NTSTATUS Status;
  336. Status = NtDestroySecurityDescriptor(ppSd);
  337. if (NT_SUCCESS(Status))
  338. {
  339. fRet = TRUE;
  340. }
  341. else
  342. {
  343. fRet = FALSE;
  344. SetLastError(RtlNtStatusToDosError(Status));
  345. }
  346. return(fRet);
  347. }
  348. BOOL WINAPI
  349. IsSecurityDescriptorAbsolute(
  350. PSECURITY_DESCRIPTOR pSd
  351. )
  352. {
  353. BOOLEAN fAbsolute;
  354. BOOL fRet;
  355. NTSTATUS Status;
  356. fAbsolute = FALSE;
  357. Status = NtIsSecurityDescriptorAbsolute(pSd, &fAbsolute);
  358. fRet = ((NT_SUCCESS(Status)) && fAbsolute);
  359. return(fRet);
  360. }