tamlin's work on compiling the kernel with another compiler than GCC. Patch by Mike...
[reactos.git] / reactos / ntoskrnl / se / acl.c
1 /* $Id: acl.c,v 1.15 2004/01/05 14:28:21 weiden 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 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
150 AclEnd = Acl->AclSize + (char*)Acl;
151 do
152 {
153 if ((PVOID)Current >= AclEnd)
154 {
155 return(FALSE);
156 }
157
158 if (Current->Header.AceType == 4)
159 {
160 if (Acl->AclRevision < 3)
161 {
162 return(FALSE);
163 }
164 }
165 Current = (PACE)((char*)Current + (ULONG)Current->Header.AceSize);
166 i++;
167 }
168 while (i < Acl->AceCount);
169
170 if ((PVOID)Current < AclEnd)
171 {
172 *Ace = Current;
173 }
174
175 return(TRUE);
176 }
177
178
179 NTSTATUS
180 RtlpAddKnownAce(PACL Acl,
181 ULONG Revision,
182 ACCESS_MASK AccessMask,
183 PSID Sid,
184 ULONG Type)
185 {
186 PACE Ace;
187
188 if (!RtlValidSid(Sid))
189 {
190 return(STATUS_INVALID_SID);
191 }
192 if (Acl->AclRevision > 3 ||
193 Revision > 3)
194 {
195 return(STATUS_UNKNOWN_REVISION);
196 }
197 if (Revision < Acl->AclRevision)
198 {
199 Revision = Acl->AclRevision;
200 }
201 if (!RtlFirstFreeAce(Acl, &Ace))
202 {
203 return(STATUS_BUFFER_TOO_SMALL);
204 }
205 if (Ace == NULL)
206 {
207 return(STATUS_UNSUCCESSFUL);
208 }
209 if (((char*)Ace + RtlLengthSid(Sid) + sizeof(ACE)) >=
210 ((char*)Acl + Acl->AclSize))
211 {
212 return(STATUS_BUFFER_TOO_SMALL);
213 }
214 Ace->Header.AceFlags = 0;
215 Ace->Header.AceType = Type;
216 Ace->Header.AceSize = RtlLengthSid(Sid) + sizeof(ACE);
217 Ace->AccessMask = AccessMask;
218 RtlCopySid(RtlLengthSid(Sid), (PSID)(Ace + 1), Sid);
219 Acl->AceCount++;
220 Acl->AclRevision = Revision;
221 return(STATUS_SUCCESS);
222 }
223
224
225 /*
226 * @implemented
227 */
228 NTSTATUS STDCALL
229 RtlAddAccessAllowedAce(PACL Acl,
230 ULONG Revision,
231 ACCESS_MASK AccessMask,
232 PSID Sid)
233 {
234 return(RtlpAddKnownAce(Acl, Revision, AccessMask, Sid, 0));
235 }
236
237
238 /*
239 * @implemented
240 */
241 NTSTATUS STDCALL
242 RtlAddAce(PACL Acl,
243 ULONG AclRevision,
244 ULONG StartingIndex,
245 PACE AceList,
246 ULONG AceListLength)
247 {
248 PACE Ace;
249 ULONG i;
250 PACE Current;
251 ULONG j;
252
253 if (Acl->AclRevision != 2 &&
254 Acl->AclRevision != 3)
255 {
256 return(STATUS_UNSUCCESSFUL);
257 }
258 if (!RtlFirstFreeAce(Acl,&Ace))
259 {
260 return(STATUS_UNSUCCESSFUL);
261 }
262 if (Acl->AclRevision <= AclRevision)
263 {
264 AclRevision = Acl->AclRevision;
265 }
266 if (((char*)AceList + AceListLength) <= (char*)AceList)
267 {
268 return(STATUS_UNSUCCESSFUL);
269 }
270 i = 0;
271 Current = (PACE)(Acl + 1);
272 while ((char*)Current < ((char*)AceList + AceListLength))
273 {
274 if (AceList->Header.AceType == 4 &&
275 AclRevision < 3)
276 {
277 return(STATUS_UNSUCCESSFUL);
278 }
279 Current = (PACE)((char*)Current + Current->Header.AceSize);
280 }
281 if (Ace == NULL)
282 {
283 return(STATUS_UNSUCCESSFUL);
284 }
285 if (((char*)Ace + AceListLength) >= ((char*)Acl + Acl->AclSize))
286 {
287 return(STATUS_UNSUCCESSFUL);
288 }
289 if (StartingIndex != 0)
290 {
291 if (Acl->AceCount > 0)
292 {
293 Current = (PACE)(Acl + 1);
294 for (j = 0; j < StartingIndex; j++)
295 {
296 Current = (PACE)((char*)Current + Current->Header.AceSize);
297 }
298 }
299 }
300 /* RtlpAddData(AceList, AceListLength, Current, (PVOID)Ace - Current)); */
301 memcpy(Current, AceList, AceListLength);
302 Acl->AceCount = Acl->AceCount + i;
303 Acl->AclRevision = AclRevision;
304 return(TRUE);
305 }
306
307
308 /*
309 * @implemented
310 */
311 NTSTATUS STDCALL
312 RtlCreateAcl(PACL Acl,
313 ULONG AclSize,
314 ULONG AclRevision)
315 {
316 if (AclSize < 8)
317 {
318 return(STATUS_BUFFER_TOO_SMALL);
319 }
320 if (AclRevision != 2 &&
321 AclRevision != 3)
322 {
323 return(STATUS_UNKNOWN_REVISION);
324 }
325 if (AclSize > 0xffff)
326 {
327 return(STATUS_UNSUCCESSFUL);
328 }
329 AclSize = AclSize & ~(0x3);
330 Acl->AclSize = AclSize;
331 Acl->AclRevision = AclRevision;
332 Acl->AceCount = 0;
333 Acl->Sbz1 = 0;
334 Acl->Sbz2 = 0;
335 return(STATUS_SUCCESS);
336 }
337
338
339 BOOLEAN STDCALL
340 RtlValidAcl(PACL Acl)
341 {
342 PACE Ace;
343 USHORT Size;
344
345 Size = (Acl->AclSize + 3) & ~3;
346
347 if (Acl->AclRevision != 2 &&
348 Acl->AclRevision != 3)
349 {
350 return(FALSE);
351 }
352
353 if (Size != Acl->AclSize)
354 {
355 return(FALSE);
356 }
357
358 return(RtlFirstFreeAce(Acl, &Ace));
359 }
360
361 /* EOF */