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.

272 lines
6.5 KiB

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