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.

278 lines
7.6 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1992 - 1996.
  5. //
  6. // File: security.cxx
  7. //
  8. // Contents: Security-related helper functions used by the Task Scheduler
  9. // setup program to set security on the job folder.
  10. //
  11. // Classes: None.
  12. //
  13. // Functions:
  14. //
  15. // History: 23-Sep-96 AnirudhS Copied with minor modifications from
  16. // ..\job\security.cxx.
  17. //
  18. //----------------------------------------------------------------------------
  19. #include <windows.h>
  20. #include "..\inc\security.hxx"
  21. #define schDebugOut(x)
  22. #define schAssert(x)
  23. //+---------------------------------------------------------------------------
  24. //
  25. // Function: CreateSecurityDescriptor
  26. //
  27. // Synopsis: Create a security descriptor with the ACE information
  28. // specified.
  29. //
  30. // Arguments: [AceCount] -- ACE count (no. of rgMyAce and rgAce elements).
  31. // [rgMyAce] -- ACE specification array.
  32. // [rgAce] -- Caller allocated array of ptrs to ACEs so
  33. // this function doesn't have to allocate it.
  34. //
  35. // Returns: TRUE -- Function succeeded,
  36. // FALSE -- Otherwise.
  37. //
  38. // Notes: None.
  39. //
  40. //----------------------------------------------------------------------------
  41. PSECURITY_DESCRIPTOR
  42. CreateSecurityDescriptor(
  43. DWORD AceCount,
  44. MYACE rgMyAce[],
  45. PACCESS_ALLOWED_ACE rgAce[],
  46. DWORD * pStatus)
  47. {
  48. PSECURITY_DESCRIPTOR pSecurityDescriptor = NULL;
  49. PACL pAcl = NULL;
  50. DWORD LengthAces = 0;
  51. DWORD LengthAcl;
  52. DWORD i;
  53. DWORD Status;
  54. for (i = 0; i < AceCount; i++)
  55. {
  56. rgAce[i] = CreateAccessAllowedAce(rgMyAce[i].pSid,
  57. rgMyAce[i].AccessMask,
  58. 0,
  59. rgMyAce[i].InheritFlags,
  60. &Status);
  61. if (rgAce[i] == NULL)
  62. {
  63. goto ErrorExit;
  64. }
  65. LengthAces += rgAce[i]->Header.AceSize;
  66. }
  67. //
  68. // Calculate ACL and SD sizes
  69. //
  70. LengthAcl = sizeof(ACL) + LengthAces;
  71. //
  72. // Create the ACL.
  73. //
  74. pAcl = (PACL)LocalAlloc(LMEM_FIXED, LengthAcl);
  75. if (pAcl == NULL)
  76. {
  77. Status = ERROR_NOT_ENOUGH_MEMORY;
  78. schDebugOut((DEB_ERROR,
  79. "CreateSecurityDescriptor, ACL allocation failed\n"));
  80. goto ErrorExit;
  81. }
  82. if (!InitializeAcl(pAcl, LengthAcl, ACL_REVISION))
  83. {
  84. Status = GetLastError();
  85. schDebugOut((DEB_ERROR,
  86. "CreateSecurityDescriptor, InitializeAcl failed, " \
  87. "status = 0x%lx\n",
  88. Status));
  89. goto ErrorExit;
  90. }
  91. for (i = 0; i < AceCount; i++)
  92. {
  93. if (!AddAce(pAcl,
  94. ACL_REVISION,
  95. 0,
  96. rgAce[i],
  97. rgAce[i]->Header.AceSize))
  98. {
  99. Status = GetLastError();
  100. schDebugOut((DEB_ERROR,
  101. "CreateSecurityDescriptor, AddAce[%l] failed, " \
  102. "status = 0x%lx\n", i, Status));
  103. goto ErrorExit;
  104. }
  105. LocalFree(rgAce[i]);
  106. rgAce[i] = NULL;
  107. }
  108. //
  109. // Create the security descriptor.
  110. //
  111. pSecurityDescriptor = LocalAlloc(LMEM_FIXED,
  112. SECURITY_DESCRIPTOR_MIN_LENGTH);
  113. if (pSecurityDescriptor == NULL)
  114. {
  115. Status = ERROR_NOT_ENOUGH_MEMORY;
  116. schDebugOut((DEB_ERROR,
  117. "CreateSecurityDescriptor, SECURITY_DESCRIPTOR allocation " \
  118. "failed\n"));
  119. goto ErrorExit;
  120. }
  121. if (!InitializeSecurityDescriptor(pSecurityDescriptor,
  122. SECURITY_DESCRIPTOR_REVISION))
  123. {
  124. Status = GetLastError();
  125. schDebugOut((DEB_ERROR,
  126. "CreateSecurityDescriptor, InitializeSecurityDescriptor " \
  127. "failed, status = 0x%lx\n",
  128. Status));
  129. goto ErrorExit;
  130. }
  131. if (!SetSecurityDescriptorDacl(pSecurityDescriptor,
  132. TRUE,
  133. pAcl,
  134. FALSE))
  135. {
  136. Status = GetLastError();
  137. schDebugOut((DEB_ERROR,
  138. "CreateSecurityDescriptor, SetSecurityDescriptorDacl " \
  139. "failed, status = 0x%lx\n",
  140. Status));
  141. goto ErrorExit;
  142. }
  143. if (pStatus != NULL) *pStatus = ERROR_SUCCESS;
  144. return(pSecurityDescriptor);
  145. ErrorExit:
  146. for (i = 0; i < AceCount; i++)
  147. {
  148. if (rgAce[i] != NULL)
  149. {
  150. LocalFree(rgAce[i]);
  151. rgAce[i] = NULL;
  152. }
  153. }
  154. if (pAcl != NULL) LocalFree(pAcl);
  155. if (pSecurityDescriptor != NULL) LocalFree(pSecurityDescriptor);
  156. if (pStatus != NULL) *pStatus = Status;
  157. return(NULL);
  158. }
  159. //+---------------------------------------------------------------------------
  160. //
  161. // Function: DeleteSecurityDescriptor
  162. //
  163. // Synopsis: Deallocate the security descriptor allocated in
  164. // CreateSecurityDescriptor.
  165. //
  166. // Arguments: [pSecurityDescriptor] -- SD returned from
  167. // CreateSecurityDescriptor.
  168. //
  169. // Returns: None.
  170. //
  171. // Notes: None.
  172. //
  173. //----------------------------------------------------------------------------
  174. void
  175. DeleteSecurityDescriptor(PSECURITY_DESCRIPTOR pSecurityDescriptor)
  176. {
  177. BOOL fPresent;
  178. BOOL fDefaulted;
  179. PACL pAcl;
  180. schAssert(pSecurityDescriptor != NULL);
  181. if (GetSecurityDescriptorDacl(pSecurityDescriptor,
  182. &fPresent,
  183. &pAcl,
  184. &fDefaulted))
  185. {
  186. if (fPresent && pAcl != NULL)
  187. {
  188. LocalFree(pAcl);
  189. }
  190. }
  191. else
  192. {
  193. schDebugOut((DEB_ERROR,
  194. "DeleteSecurityDescriptor, GetSecurityDescriptorDacl failed, " \
  195. "status = 0x%lx\n",
  196. GetLastError()));
  197. }
  198. LocalFree(pSecurityDescriptor);
  199. }
  200. //+---------------------------------------------------------------------------
  201. //
  202. // Function: CreateAccessAllowedAce
  203. //
  204. // Synopsis: Scavenged code from winlogon to create an access allowed ACE.
  205. // Modified a bit to use Win32 vs. Rtl.
  206. //
  207. // Arguments: [pSid] -- Sid to which this ACE is applied.
  208. // [AccessMask] -- ACE access mask value.
  209. // [AceFlags] -- ACE flags value.
  210. // [InheritFlags] -- ACE inherit flags value.
  211. //
  212. // Returns: Created ACE if successful.
  213. // NULL on error.
  214. //
  215. // Notes: None.
  216. //
  217. //----------------------------------------------------------------------------
  218. PACCESS_ALLOWED_ACE
  219. CreateAccessAllowedAce(
  220. PSID pSid,
  221. ACCESS_MASK AccessMask,
  222. UCHAR AceFlags,
  223. UCHAR InheritFlags,
  224. DWORD * pStatus)
  225. {
  226. ULONG LengthSid = GetLengthSid(pSid);
  227. ULONG LengthACE = sizeof(ACE_HEADER) + sizeof(ACCESS_MASK) + LengthSid;
  228. PACCESS_ALLOWED_ACE Ace;
  229. Ace = (PACCESS_ALLOWED_ACE)LocalAlloc(LMEM_FIXED, LengthACE);
  230. if (Ace == NULL)
  231. {
  232. if (pStatus != NULL) *pStatus = ERROR_NOT_ENOUGH_MEMORY;
  233. schDebugOut((DEB_ERROR,
  234. "CreateAccessAllowedAce, ACE allocation failed\n"));
  235. return(NULL);
  236. }
  237. Ace->Header.AceType = ACCESS_ALLOWED_ACE_TYPE;
  238. Ace->Header.AceSize = (UCHAR)LengthACE;
  239. Ace->Header.AceFlags = AceFlags | InheritFlags;
  240. Ace->Mask = AccessMask;
  241. CopySid(LengthSid, (PSID)(&(Ace->SidStart)), pSid);
  242. if (pStatus != NULL) *pStatus = ERROR_SUCCESS;
  243. return(Ace);
  244. }