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.

276 lines
6.8 KiB

  1. /****************************** Module Header ******************************\
  2. * Module Name: secdesc.cxx
  3. *
  4. * Copyright (c) 1991, Microsoft Corporation
  5. *
  6. * Routines that support creation and deletion of security descriptors
  7. *
  8. * History:
  9. * 02-06-92 Davidc Created.
  10. * 04-14-92 RichardW Changed ACE_HEADER
  11. * 04-01-94 AndyH Copied from winlogon. Changed to .CXX
  12. \***************************************************************************/
  13. #include "act.hxx"
  14. //
  15. // Private prototypes
  16. //
  17. PACCESS_ALLOWED_ACE
  18. CreateAccessAllowedAce(
  19. PSID Sid,
  20. ACCESS_MASK AccessMask,
  21. UCHAR AceFlags,
  22. UCHAR InheritFlags
  23. );
  24. VOID
  25. DestroyAce(
  26. PVOID Ace
  27. );
  28. //
  29. // Memory macros
  30. //
  31. #define Alloc(c) ((PVOID)LocalAlloc(LPTR, c))
  32. #define ReAlloc(p, c) ((PVOID)LocalReAlloc(p, c, LPTR | LMEM_MOVEABLE))
  33. #define Free(p) ((VOID)LocalFree(p))
  34. /***************************************************************************\
  35. * CreateSecurityDescriptor
  36. *
  37. * Creates a security descriptor containing an ACL containing the specified ACEs
  38. *
  39. * A SD created with this routine should be destroyed using
  40. * DeleteSecurityDescriptor
  41. *
  42. * Returns a pointer to the security descriptor or NULL on failure.
  43. *
  44. * 02-06-92 Davidc Created.
  45. \***************************************************************************/
  46. PSECURITY_DESCRIPTOR
  47. CreateSecurityDescriptor(
  48. PMYACE MyAce,
  49. ACEINDEX AceCount
  50. )
  51. {
  52. NTSTATUS Status;
  53. ACEINDEX AceIndex;
  54. PACCESS_ALLOWED_ACE *Ace;
  55. PACL Acl = NULL;
  56. PSECURITY_DESCRIPTOR SecurityDescriptor = NULL;
  57. ULONG LengthAces;
  58. ULONG LengthAcl;
  59. ULONG LengthSd;
  60. //
  61. // Allocate space for the ACE pointer array
  62. //
  63. Ace = (PACCESS_ALLOWED_ACE *)Alloc(sizeof(PACCESS_ALLOWED_ACE) * AceCount);
  64. if (Ace == NULL) {
  65. CairoleDebugOut((DEB_ERROR, "Failed to allocated ACE array\n"));
  66. return(NULL);
  67. }
  68. //
  69. // Create the ACEs and calculate total ACE size
  70. //
  71. LengthAces = 0;
  72. for (AceIndex=0; AceIndex < AceCount; AceIndex ++) {
  73. Ace[AceIndex] = CreateAccessAllowedAce(MyAce[AceIndex].Sid,
  74. MyAce[AceIndex].AccessMask,
  75. 0,
  76. MyAce[AceIndex].InheritFlags);
  77. if (Ace[AceIndex] == NULL) {
  78. CairoleDebugOut((DEB_ERROR, "Failed to allocated ACE\n"));
  79. } else {
  80. LengthAces += Ace[AceIndex]->Header.AceSize;
  81. }
  82. }
  83. //
  84. // Calculate ACL and SD sizes
  85. //
  86. LengthAcl = sizeof(ACL) + LengthAces;
  87. LengthSd = SECURITY_DESCRIPTOR_MIN_LENGTH;
  88. //
  89. // Create the ACL
  90. //
  91. Acl = (PACL) Alloc(LengthAcl);
  92. if (Acl != NULL) {
  93. Status = RtlCreateAcl(Acl, LengthAcl, ACL_REVISION);
  94. Win4Assert(NT_SUCCESS(Status));
  95. //
  96. // Add the ACES to the ACL and destroy the ACEs
  97. //
  98. for (AceIndex = 0; AceIndex < AceCount; AceIndex ++) {
  99. if (Ace[AceIndex] != NULL) {
  100. Status = RtlAddAce(Acl, ACL_REVISION, 0, Ace[AceIndex],
  101. Ace[AceIndex]->Header.AceSize);
  102. if (!NT_SUCCESS(Status)) {
  103. CairoleDebugOut((DEB_ERROR, "AddAce failed, status = 0x%lx\n", Status));
  104. }
  105. DestroyAce(Ace[AceIndex]);
  106. }
  107. }
  108. } else {
  109. CairoleDebugOut((DEB_ERROR, "Failed to allocated ACL\n"));
  110. }
  111. //
  112. // Free the ACE pointer array
  113. //
  114. Free(Ace);
  115. //
  116. // Create the security descriptor
  117. //
  118. SecurityDescriptor = Alloc(LengthSd);
  119. if (SecurityDescriptor != NULL) {
  120. Status = RtlCreateSecurityDescriptor(SecurityDescriptor, SECURITY_DESCRIPTOR_REVISION);
  121. Win4Assert(NT_SUCCESS(Status));
  122. //
  123. // Set the DACL on the security descriptor
  124. //
  125. Status = RtlSetDaclSecurityDescriptor(SecurityDescriptor, TRUE, Acl, FALSE);
  126. if (!NT_SUCCESS(Status)) {
  127. // BUGBUG CairoleDebugOut WLPrint(("SetDACLSD failed, status = 0x%lx", Status));
  128. }
  129. } else {
  130. // BUGBUG CairoleDebugOut WLPrint(("Failed to allocate security descriptor"));
  131. }
  132. //
  133. // Return with our spoils
  134. //
  135. return(SecurityDescriptor);
  136. }
  137. /***************************************************************************\
  138. * DeleteSecurityDescriptor
  139. *
  140. * Deletes a security descriptor created using CreateSecurityDescriptor
  141. *
  142. * Returns TRUE on success, FALSE on failure
  143. *
  144. * 02-06-92 Davidc Created.
  145. \***************************************************************************/
  146. BOOL
  147. DeleteSecurityDescriptor(
  148. PSECURITY_DESCRIPTOR SecurityDescriptor
  149. )
  150. {
  151. NTSTATUS Status;
  152. PACL Acl;
  153. BOOLEAN Present;
  154. BOOLEAN Defaulted;
  155. Win4Assert(SecurityDescriptor != NULL);
  156. //
  157. // Get the ACL
  158. //
  159. Status = RtlGetDaclSecurityDescriptor(SecurityDescriptor,
  160. &Present, &Acl, &Defaulted);
  161. if (NT_SUCCESS(Status)) {
  162. //
  163. // Destroy the ACL
  164. //
  165. if (Present && (Acl != NULL)) {
  166. Free(Acl);
  167. }
  168. } else {
  169. // BUGBUG CairoleDebugOut WLPrint(("Failed to get DACL from security descriptor being destroyed, Status = 0x%lx", Status));
  170. }
  171. //
  172. // Destroy the Security Descriptor
  173. //
  174. Free(SecurityDescriptor);
  175. return(TRUE);
  176. }
  177. /***************************************************************************\
  178. * CreateAccessAllowedAce
  179. *
  180. * Allocates memory for an ACCESS_ALLOWED_ACE and fills it in.
  181. * The memory should be freed by calling DestroyACE.
  182. *
  183. * Returns pointer to ACE on success, NULL on failure
  184. *
  185. * History:
  186. * 12-05-91 Davidc Created
  187. * 04-05-94 AndyH Changed return to ACE
  188. \***************************************************************************/
  189. PACCESS_ALLOWED_ACE
  190. CreateAccessAllowedAce(
  191. PSID Sid,
  192. ACCESS_MASK AccessMask,
  193. UCHAR AceFlags,
  194. UCHAR InheritFlags
  195. )
  196. {
  197. ULONG LengthSid = RtlLengthSid(Sid);
  198. ULONG LengthACE = sizeof(ACE_HEADER) + sizeof(ACCESS_MASK) + LengthSid;
  199. PACCESS_ALLOWED_ACE Ace;
  200. Ace = (PACCESS_ALLOWED_ACE)Alloc(LengthACE);
  201. if (Ace == NULL) {
  202. // BUGBUG CairoleDebugOut WLPrint(("CreateAccessAllowedAce : Failed to allocate ace"));
  203. return NULL;
  204. }
  205. Ace->Header.AceType = ACCESS_ALLOWED_ACE_TYPE;
  206. Ace->Header.AceSize = (UCHAR)LengthACE;
  207. Ace->Header.AceFlags = AceFlags | InheritFlags;
  208. Ace->Mask = AccessMask;
  209. RtlCopySid(LengthSid, (PSID)(&(Ace->SidStart)), Sid );
  210. return(Ace);
  211. }
  212. /***************************************************************************\
  213. * DestroyAce
  214. *
  215. * Frees the memory allocate for an ACE
  216. *
  217. * History:
  218. * 12-05-91 Davidc Created
  219. \***************************************************************************/
  220. VOID
  221. DestroyAce(
  222. PVOID Ace
  223. )
  224. {
  225. Free(Ace);
  226. }