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