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