Fix bug in RtlpAddKnownAce() that caused it to place the SID in the wrong location.
[reactos.git] / reactos / ntoskrnl / se / acl.c
1 /* $Id: acl.c,v 1.7 2002/06/15 10:09:17 ekohl Exp $
2 *
3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS kernel
5 * PURPOSE: Security manager
6 * FILE: kernel/se/acl.c
7 * PROGRAMER: David Welch <welch@cwcom.net>
8 * REVISION HISTORY:
9 * 26/07/98: Added stubs for security functions
10 */
11
12 /* INCLUDES *****************************************************************/
13
14 #include <ddk/ntddk.h>
15 #include <internal/se.h>
16
17 #include <internal/debug.h>
18
19 #define TAG_ACL TAG('A', 'C', 'L', 'T')
20
21
22 /* GLOBALS ******************************************************************/
23
24 PACL EXPORTED SePublicDefaultDacl = NULL;
25 PACL EXPORTED SeSystemDefaultDacl = NULL;
26
27 PACL SePublicDefaultUnrestrictedDacl = NULL;
28 PACL SePublicOpenDacl = NULL;
29 PACL SePublicOpenUnrestrictedDacl = NULL;
30 PACL SeUnrestrictedDacl = NULL;
31
32
33 /* FUNCTIONS ****************************************************************/
34
35 BOOLEAN
36 SepInitDACLs(VOID)
37 {
38 ULONG AclLength2;
39 ULONG AclLength3;
40 ULONG AclLength4;
41
42 AclLength2 = sizeof(ACL) +
43 2 * (RtlLengthRequiredSid(1) + sizeof(ACE_HEADER));
44 AclLength3 = sizeof(ACL) +
45 3 * (RtlLengthRequiredSid(1) + sizeof(ACE_HEADER));
46 AclLength4 = sizeof(ACL) +
47 4 * (RtlLengthRequiredSid(1) + sizeof(ACE_HEADER));
48
49 /* create PublicDefaultDacl */
50 SePublicDefaultDacl = ExAllocatePoolWithTag(NonPagedPool,
51 AclLength2,
52 TAG_ACL);
53 if (SePublicDefaultDacl == NULL)
54 return(FALSE);
55
56 RtlCreateAcl(SePublicDefaultDacl,
57 AclLength2,
58 2);
59
60 RtlAddAccessAllowedAce(SePublicDefaultDacl,
61 2,
62 GENERIC_EXECUTE,
63 SeWorldSid);
64
65 RtlAddAccessAllowedAce(SePublicDefaultDacl,
66 2,
67 GENERIC_ALL,
68 SeLocalSystemSid);
69
70
71 /* create PublicDefaultUnrestrictedDacl */
72 SePublicDefaultUnrestrictedDacl = ExAllocatePoolWithTag(NonPagedPool,
73 AclLength4,
74 TAG_ACL);
75 if (SePublicDefaultUnrestrictedDacl == NULL)
76 return(FALSE);
77
78 RtlCreateAcl(SePublicDefaultUnrestrictedDacl,
79 AclLength4,
80 2);
81
82 RtlAddAccessAllowedAce(SePublicDefaultUnrestrictedDacl,
83 4,
84 GENERIC_EXECUTE,
85 SeWorldSid);
86
87 RtlAddAccessAllowedAce(SePublicDefaultUnrestrictedDacl,
88 4,
89 GENERIC_ALL,
90 SeLocalSystemSid);
91
92 RtlAddAccessAllowedAce(SePublicDefaultUnrestrictedDacl,
93 4,
94 GENERIC_ALL,
95 SeAliasAdminsSid);
96
97 RtlAddAccessAllowedAce(SePublicDefaultUnrestrictedDacl,
98 4,
99 GENERIC_READ | GENERIC_EXECUTE | STANDARD_RIGHTS_READ,
100 SeRestrictedCodeSid);
101
102 /* create PublicOpenDacl */
103 SePublicOpenDacl = ExAllocatePoolWithTag(NonPagedPool,
104 AclLength3,
105 TAG_ACL);
106 if (SePublicOpenDacl == NULL)
107 return(FALSE);
108
109 RtlCreateAcl(SePublicOpenDacl,
110 AclLength3,
111 3);
112
113 RtlAddAccessAllowedAce(SePublicOpenDacl,
114 2,
115 GENERIC_READ | GENERIC_WRITE | GENERIC_EXECUTE,
116 SeWorldSid);
117
118 RtlAddAccessAllowedAce(SePublicOpenDacl,
119 2,
120 GENERIC_ALL,
121 SeLocalSystemSid);
122
123 RtlAddAccessAllowedAce(SePublicOpenDacl,
124 2,
125 GENERIC_ALL,
126 SeAliasAdminsSid);
127
128
129 return(TRUE);
130 }
131
132
133 BOOLEAN STDCALL
134 RtlFirstFreeAce(PACL Acl,
135 PACE* Ace)
136 {
137 PACE Current;
138 PVOID AclEnd;
139 ULONG i;
140
141 Current = (PACE)(Acl + 1);
142 *Ace = NULL;
143 i = 0;
144 if (Acl->AceCount == 0)
145 {
146 *Ace = Current;
147 return(TRUE);
148 }
149 AclEnd = Acl->AclSize + Acl;
150 do
151 {
152 if ((PVOID)Current >= AclEnd)
153 {
154 return(FALSE);
155 }
156 if (Current->Header.AceType == 4)
157 {
158 if (Acl->AclRevision < 3)
159 {
160 return(FALSE);
161 }
162 }
163 Current = (PACE)((PVOID)Current + (ULONG)Current->Header.AceSize);
164 i++;
165 } while (i < Acl->AceCount);
166 if ((PVOID)Current >= AclEnd)
167 {
168 return(FALSE);
169 }
170 *Ace = Current;
171 return(TRUE);
172 }
173
174
175 NTSTATUS
176 RtlpAddKnownAce(PACL Acl,
177 ULONG Revision,
178 ACCESS_MASK AccessMask,
179 PSID Sid,
180 ULONG Type)
181 {
182 PACE Ace;
183
184 if (!RtlValidSid(Sid))
185 {
186 return(STATUS_INVALID_SID);
187 }
188 if (Acl->AclRevision > 3 ||
189 Revision > 3)
190 {
191 return(STATUS_UNKNOWN_REVISION);
192 }
193 if (Revision < Acl->AclRevision)
194 {
195 Revision = Acl->AclRevision;
196 }
197 if (!RtlFirstFreeAce(Acl, &Ace))
198 {
199 return(STATUS_BUFFER_TOO_SMALL);
200 }
201 if (Ace == NULL)
202 {
203 return(STATUS_UNSUCCESSFUL);
204 }
205 if (((PVOID)Ace + RtlLengthSid(Sid) + sizeof(ACE)) >=
206 ((PVOID)Acl + Acl->AclSize))
207 {
208 return(STATUS_BUFFER_TOO_SMALL);
209 }
210 Ace->Header.AceFlags = 0;
211 Ace->Header.AceType = Type;
212 Ace->Header.AceSize = RtlLengthSid(Sid) + sizeof(ACE);
213 Ace->Header.AccessMask = AccessMask;
214 RtlCopySid(RtlLengthSid(Sid), (PSID)(Ace + 1), Sid);
215 Acl->AceCount++;
216 Acl->AclRevision = Revision;
217 return(STATUS_SUCCESS);
218 }
219
220
221 NTSTATUS STDCALL
222 RtlAddAccessAllowedAce(PACL Acl,
223 ULONG Revision,
224 ACCESS_MASK AccessMask,
225 PSID Sid)
226 {
227 return(RtlpAddKnownAce(Acl, Revision, AccessMask, Sid, 0));
228 }
229
230
231 NTSTATUS STDCALL
232 RtlAddAce(PACL Acl,
233 ULONG AclRevision,
234 ULONG StartingIndex,
235 PACE AceList,
236 ULONG AceListLength)
237 {
238 PACE Ace;
239 ULONG i;
240 PACE Current;
241 ULONG j;
242
243 if (Acl->AclRevision != 2 &&
244 Acl->AclRevision != 3)
245 {
246 return(STATUS_UNSUCCESSFUL);
247 }
248 if (!RtlFirstFreeAce(Acl,&Ace))
249 {
250 return(STATUS_UNSUCCESSFUL);
251 }
252 if (Acl->AclRevision <= AclRevision)
253 {
254 AclRevision = Acl->AclRevision;
255 }
256 if (((PVOID)AceList + AceListLength) <= (PVOID)AceList)
257 {
258 return(STATUS_UNSUCCESSFUL);
259 }
260 i = 0;
261 Current = (PACE)(Acl + 1);
262 while ((PVOID)Current < ((PVOID)AceList + AceListLength))
263 {
264 if (AceList->Header.AceType == 4 &&
265 AclRevision < 3)
266 {
267 return(STATUS_UNSUCCESSFUL);
268 }
269 Current = (PACE)((PVOID)Current + Current->Header.AceSize);
270 }
271 if (Ace == NULL)
272 {
273 return(STATUS_UNSUCCESSFUL);
274 }
275 if (((PVOID)Ace + AceListLength) >= ((PVOID)Acl + Acl->AclSize))
276 {
277 return(STATUS_UNSUCCESSFUL);
278 }
279 if (StartingIndex != 0)
280 {
281 if (Acl->AceCount > 0)
282 {
283 Current = (PACE)(Acl + 1);
284 for (j = 0; j < StartingIndex; j++)
285 {
286 Current = (PACE)((PVOID)Current + Current->Header.AceSize);
287 }
288 }
289 }
290 /* RtlpAddData(AceList, AceListLength, Current, (PVOID)Ace - Current)); */
291 memcpy(Current, AceList, AceListLength);
292 Acl->AceCount = Acl->AceCount + i;
293 Acl->AclRevision = AclRevision;
294 return(TRUE);
295 }
296
297
298 NTSTATUS STDCALL
299 RtlCreateAcl(PACL Acl,
300 ULONG AclSize,
301 ULONG AclRevision)
302 {
303 if (AclSize < 8)
304 {
305 return(STATUS_BUFFER_TOO_SMALL);
306 }
307 if (AclRevision != 2 &&
308 AclRevision != 3)
309 {
310 return(STATUS_UNKNOWN_REVISION);
311 }
312 if (AclSize > 0xffff)
313 {
314 return(STATUS_UNSUCCESSFUL);
315 }
316 AclSize = AclSize & ~(0x3);
317 Acl->AclSize = AclSize;
318 Acl->AclRevision = AclRevision;
319 Acl->AceCount = 0;
320 Acl->Sbz1 = 0;
321 Acl->Sbz2 = 0;
322 return(STATUS_SUCCESS);
323 }
324
325 /* EOF */