Create missing default DACLs.
[reactos.git] / reactos / ntoskrnl / se / acl.c
1 /* $Id: acl.c,v 1.18 2004/07/17 20:32:11 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 INIT_FUNCTION
36 SepInitDACLs(VOID)
37 {
38 ULONG AclLength2;
39 ULONG AclLength3;
40 ULONG AclLength4;
41
42 AclLength2 = sizeof(ACL) +
43 2 * (RtlLengthRequiredSid(1) + sizeof(ACE));
44 AclLength3 = sizeof(ACL) +
45 3 * (RtlLengthRequiredSid(1) + sizeof(ACE));
46 AclLength4 = sizeof(ACL) +
47 4 * (RtlLengthRequiredSid(1) + sizeof(ACE));
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 ACL_REVISION);
59
60 RtlAddAccessAllowedAce(SePublicDefaultDacl,
61 ACL_REVISION,
62 GENERIC_EXECUTE,
63 SeWorldSid);
64
65 RtlAddAccessAllowedAce(SePublicDefaultDacl,
66 ACL_REVISION,
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 ACL_REVISION);
81
82 RtlAddAccessAllowedAce(SePublicDefaultUnrestrictedDacl,
83 ACL_REVISION,
84 GENERIC_EXECUTE,
85 SeWorldSid);
86
87 RtlAddAccessAllowedAce(SePublicDefaultUnrestrictedDacl,
88 ACL_REVISION,
89 GENERIC_ALL,
90 SeLocalSystemSid);
91
92 RtlAddAccessAllowedAce(SePublicDefaultUnrestrictedDacl,
93 ACL_REVISION,
94 GENERIC_ALL,
95 SeAliasAdminsSid);
96
97 RtlAddAccessAllowedAce(SePublicDefaultUnrestrictedDacl,
98 ACL_REVISION,
99 GENERIC_READ | GENERIC_EXECUTE | READ_CONTROL,
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 ACL_REVISION);
112
113 RtlAddAccessAllowedAce(SePublicOpenDacl,
114 ACL_REVISION,
115 GENERIC_READ | GENERIC_WRITE | GENERIC_EXECUTE,
116 SeWorldSid);
117
118 RtlAddAccessAllowedAce(SePublicOpenDacl,
119 ACL_REVISION,
120 GENERIC_ALL,
121 SeLocalSystemSid);
122
123 RtlAddAccessAllowedAce(SePublicOpenDacl,
124 ACL_REVISION,
125 GENERIC_ALL,
126 SeAliasAdminsSid);
127
128 /* create PublicOpenUnrestrictedDacl */
129 SePublicOpenUnrestrictedDacl = ExAllocatePoolWithTag(NonPagedPool,
130 AclLength4,
131 TAG_ACL);
132 if (SePublicOpenUnrestrictedDacl == NULL)
133 return FALSE;
134
135 RtlCreateAcl(SePublicOpenUnrestrictedDacl,
136 AclLength4,
137 ACL_REVISION);
138
139 RtlAddAccessAllowedAce(SePublicOpenUnrestrictedDacl,
140 ACL_REVISION,
141 GENERIC_ALL,
142 SeWorldSid);
143
144 RtlAddAccessAllowedAce(SePublicOpenUnrestrictedDacl,
145 ACL_REVISION,
146 GENERIC_ALL,
147 SeLocalSystemSid);
148
149 RtlAddAccessAllowedAce(SePublicOpenUnrestrictedDacl,
150 ACL_REVISION,
151 GENERIC_ALL,
152 SeAliasAdminsSid);
153
154 RtlAddAccessAllowedAce(SePublicOpenUnrestrictedDacl,
155 ACL_REVISION,
156 GENERIC_READ | GENERIC_EXECUTE,
157 SeRestrictedCodeSid);
158
159 /* create SystemDefaultDacl */
160 SeSystemDefaultDacl = ExAllocatePoolWithTag(NonPagedPool,
161 AclLength2,
162 TAG_ACL);
163 if (SeSystemDefaultDacl == NULL)
164 return FALSE;
165
166 RtlCreateAcl(SeSystemDefaultDacl,
167 AclLength2,
168 ACL_REVISION);
169
170 RtlAddAccessAllowedAce(SeSystemDefaultDacl,
171 ACL_REVISION,
172 GENERIC_ALL,
173 SeLocalSystemSid);
174
175 RtlAddAccessAllowedAce(SeSystemDefaultDacl,
176 ACL_REVISION,
177 GENERIC_READ | GENERIC_EXECUTE | READ_CONTROL,
178 SeAliasAdminsSid);
179
180 /* create UnrestrictedDacl */
181 SeUnrestrictedDacl = ExAllocatePoolWithTag(NonPagedPool,
182 AclLength2,
183 TAG_ACL);
184 if (SeUnrestrictedDacl == NULL)
185 return FALSE;
186
187 RtlCreateAcl(SeUnrestrictedDacl,
188 AclLength2,
189 ACL_REVISION);
190
191 RtlAddAccessAllowedAce(SeUnrestrictedDacl,
192 ACL_REVISION,
193 GENERIC_ALL,
194 SeWorldSid);
195
196 RtlAddAccessAllowedAce(SeUnrestrictedDacl,
197 ACL_REVISION,
198 GENERIC_READ | GENERIC_EXECUTE,
199 SeRestrictedCodeSid);
200
201 return(TRUE);
202 }
203
204
205 BOOLEAN STDCALL
206 RtlFirstFreeAce(PACL Acl,
207 PACE* Ace)
208 {
209 PACE Current;
210 PVOID AclEnd;
211 ULONG i;
212
213 Current = (PACE)(Acl + 1);
214 *Ace = NULL;
215 i = 0;
216 if (Acl->AceCount == 0)
217 {
218 *Ace = Current;
219 return(TRUE);
220 }
221
222 AclEnd = Acl->AclSize + (char*)Acl;
223 do
224 {
225 if ((PVOID)Current >= AclEnd)
226 {
227 return(FALSE);
228 }
229
230 if (Current->Header.AceType == ACCESS_ALLOWED_COMPOUND_ACE_TYPE &&
231 Acl->AclRevision < ACL_REVISION3)
232 {
233 return(FALSE);
234 }
235 Current = (PACE)((char*)Current + (ULONG)Current->Header.AceSize);
236 i++;
237 }
238 while (i < Acl->AceCount);
239
240 if ((PVOID)Current < AclEnd)
241 {
242 *Ace = Current;
243 }
244
245 return(TRUE);
246 }
247
248
249 NTSTATUS
250 RtlpAddKnownAce(PACL Acl,
251 ULONG Revision,
252 ACCESS_MASK AccessMask,
253 PSID Sid,
254 ULONG Type)
255 {
256 PACE Ace;
257
258 if (!RtlValidSid(Sid))
259 {
260 return(STATUS_INVALID_SID);
261 }
262 if (Acl->AclRevision > MAX_ACL_REVISION ||
263 Revision > MAX_ACL_REVISION)
264 {
265 return(STATUS_UNKNOWN_REVISION);
266 }
267 if (Revision < Acl->AclRevision)
268 {
269 Revision = Acl->AclRevision;
270 }
271 if (!RtlFirstFreeAce(Acl, &Ace))
272 {
273 return(STATUS_BUFFER_TOO_SMALL);
274 }
275 if (Ace == NULL)
276 {
277 return(STATUS_UNSUCCESSFUL);
278 }
279 if (((char*)Ace + RtlLengthSid(Sid) + sizeof(ACE)) >=
280 ((char*)Acl + Acl->AclSize))
281 {
282 return(STATUS_BUFFER_TOO_SMALL);
283 }
284 Ace->Header.AceFlags = 0;
285 Ace->Header.AceType = Type;
286 Ace->Header.AceSize = RtlLengthSid(Sid) + sizeof(ACE);
287 Ace->AccessMask = AccessMask;
288 RtlCopySid(RtlLengthSid(Sid), (PSID)(Ace + 1), Sid);
289 Acl->AceCount++;
290 Acl->AclRevision = Revision;
291 return(STATUS_SUCCESS);
292 }
293
294
295 /*
296 * @implemented
297 */
298 NTSTATUS STDCALL
299 RtlAddAccessAllowedAce (PACL Acl,
300 ULONG Revision,
301 ACCESS_MASK AccessMask,
302 PSID Sid)
303 {
304 return RtlpAddKnownAce (Acl,
305 Revision,
306 AccessMask,
307 Sid,
308 ACCESS_ALLOWED_ACE_TYPE);
309 }
310
311
312 /*
313 * @implemented
314 */
315 NTSTATUS STDCALL
316 RtlAddAce(PACL Acl,
317 ULONG AclRevision,
318 ULONG StartingIndex,
319 PACE AceList,
320 ULONG AceListLength)
321 {
322 PACE Ace;
323 ULONG i;
324 PACE Current;
325 ULONG j;
326
327 if (Acl->AclRevision < MIN_ACL_REVISION ||
328 Acl->AclRevision > MAX_ACL_REVISION)
329 {
330 return(STATUS_UNSUCCESSFUL);
331 }
332 if (!RtlFirstFreeAce(Acl,&Ace))
333 {
334 return(STATUS_UNSUCCESSFUL);
335 }
336 if (Acl->AclRevision <= AclRevision)
337 {
338 AclRevision = Acl->AclRevision;
339 }
340 if (((char*)AceList + AceListLength) <= (char*)AceList)
341 {
342 return(STATUS_UNSUCCESSFUL);
343 }
344 i = 0;
345 Current = (PACE)(Acl + 1);
346 while ((char*)Current < ((char*)AceList + AceListLength))
347 {
348 if (AceList->Header.AceType == ACCESS_ALLOWED_COMPOUND_ACE_TYPE &&
349 AclRevision < ACL_REVISION3)
350 {
351 return(STATUS_UNSUCCESSFUL);
352 }
353 Current = (PACE)((char*)Current + Current->Header.AceSize);
354 }
355 if (Ace == NULL)
356 {
357 return(STATUS_UNSUCCESSFUL);
358 }
359 if (((char*)Ace + AceListLength) >= ((char*)Acl + Acl->AclSize))
360 {
361 return(STATUS_UNSUCCESSFUL);
362 }
363 if (StartingIndex != 0)
364 {
365 if (Acl->AceCount > 0)
366 {
367 Current = (PACE)(Acl + 1);
368 for (j = 0; j < StartingIndex; j++)
369 {
370 Current = (PACE)((char*)Current + Current->Header.AceSize);
371 }
372 }
373 }
374 /* RtlpAddData(AceList, AceListLength, Current, (PVOID)Ace - Current)); */
375 memcpy(Current, AceList, AceListLength);
376 Acl->AceCount = Acl->AceCount + i;
377 Acl->AclRevision = AclRevision;
378 return(TRUE);
379 }
380
381
382 /*
383 * @implemented
384 */
385 NTSTATUS STDCALL
386 RtlCreateAcl(PACL Acl,
387 ULONG AclSize,
388 ULONG AclRevision)
389 {
390 if (AclSize < 8)
391 {
392 return(STATUS_BUFFER_TOO_SMALL);
393 }
394 if (AclRevision < MIN_ACL_REVISION ||
395 AclRevision > MAX_ACL_REVISION)
396 {
397 return(STATUS_UNKNOWN_REVISION);
398 }
399 if (AclSize > 0xffff)
400 {
401 return(STATUS_UNSUCCESSFUL);
402 }
403 AclSize = AclSize & ~(0x3);
404 Acl->AclSize = AclSize;
405 Acl->AclRevision = AclRevision;
406 Acl->AceCount = 0;
407 Acl->Sbz1 = 0;
408 Acl->Sbz2 = 0;
409 return(STATUS_SUCCESS);
410 }
411
412
413 BOOLEAN STDCALL
414 RtlValidAcl(PACL Acl)
415 {
416 PACE Ace;
417 USHORT Size;
418
419 if (Acl->AclRevision < MIN_ACL_REVISION ||
420 Acl->AclRevision > MAX_ACL_REVISION)
421 {
422 return(FALSE);
423 }
424
425 Size = (Acl->AclSize + 3) & ~3;
426 if (Size != Acl->AclSize)
427 {
428 return(FALSE);
429 }
430
431 return(RtlFirstFreeAce(Acl, &Ace));
432 }
433
434 /* EOF */