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