:pserver:cvsanon@mok.lvcm.com:/CVS/ReactOS reactos
[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 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
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    AclEnd = Acl->AclSize + Acl;
150    do
151      {
152         if ((PVOID)Current >= AclEnd)
153           {
154              return(FALSE);
155           }
156         if (Current->Header.AceType == 4)
157           {
158              if (Acl->AclRevision < 3)
159                {
160                   return(FALSE);
161                }
162           }
163         Current = (PACE)((PVOID)Current + (ULONG)Current->Header.AceSize);
164         i++;
165      } while (i < Acl->AceCount);
166    if ((PVOID)Current >= AclEnd)
167      {
168         return(FALSE);
169      }
170    *Ace = Current;
171    return(TRUE);
172 }
173
174
175 NTSTATUS
176 RtlpAddKnownAce(PACL Acl,
177                 ULONG Revision,
178                 ACCESS_MASK AccessMask,
179                 PSID Sid,
180                 ULONG Type)
181 {
182   PACE Ace;
183
184   if (!RtlValidSid(Sid))
185     {
186       return(STATUS_INVALID_SID);
187     }
188   if (Acl->AclRevision > 3 ||
189       Revision > 3)
190     {
191       return(STATUS_UNKNOWN_REVISION);
192     }
193   if (Revision < Acl->AclRevision)
194     {
195       Revision = Acl->AclRevision;
196     }
197   if (!RtlFirstFreeAce(Acl, &Ace))
198     {
199       return(STATUS_BUFFER_TOO_SMALL);
200     }
201   if (Ace == NULL)
202     {
203       return(STATUS_UNSUCCESSFUL);
204     }
205   if (((PVOID)Ace + RtlLengthSid(Sid) + sizeof(ACE)) >= 
206       ((PVOID)Acl + Acl->AclSize))
207     {
208       return(STATUS_BUFFER_TOO_SMALL);
209     }
210   Ace->Header.AceFlags = 0;
211   Ace->Header.AceType = Type;
212   Ace->Header.AceSize = RtlLengthSid(Sid) + sizeof(ACE);
213   Ace->AccessMask = AccessMask;
214   RtlCopySid(RtlLengthSid(Sid), (PSID)(Ace + 1), Sid);
215   Acl->AceCount++;
216   Acl->AclRevision = Revision;
217   return(STATUS_SUCCESS);
218 }
219
220
221 NTSTATUS STDCALL
222 RtlAddAccessAllowedAce(PACL Acl,
223                        ULONG Revision,
224                        ACCESS_MASK AccessMask,
225                        PSID Sid)
226 {
227   return(RtlpAddKnownAce(Acl, Revision, AccessMask, Sid, 0));
228 }
229
230
231 NTSTATUS STDCALL
232 RtlAddAce(PACL Acl,
233           ULONG AclRevision,
234           ULONG StartingIndex,
235           PACE AceList,
236           ULONG AceListLength)
237 {
238    PACE Ace;
239    ULONG i;
240    PACE Current;
241    ULONG j;
242    
243    if (Acl->AclRevision != 2 &&
244        Acl->AclRevision != 3)
245      {
246         return(STATUS_UNSUCCESSFUL);
247      }
248    if (!RtlFirstFreeAce(Acl,&Ace))
249      {
250         return(STATUS_UNSUCCESSFUL);
251      }
252    if (Acl->AclRevision <= AclRevision)
253      {
254         AclRevision = Acl->AclRevision;
255      }
256    if (((PVOID)AceList + AceListLength) <= (PVOID)AceList)
257      {
258         return(STATUS_UNSUCCESSFUL);
259      }
260    i = 0;
261    Current = (PACE)(Acl + 1);
262    while ((PVOID)Current < ((PVOID)AceList + AceListLength))
263      {
264         if (AceList->Header.AceType == 4 &&
265             AclRevision < 3)
266           {
267              return(STATUS_UNSUCCESSFUL);
268           }
269         Current = (PACE)((PVOID)Current + Current->Header.AceSize);
270      }
271    if (Ace == NULL)
272      {
273         return(STATUS_UNSUCCESSFUL);
274      }
275    if (((PVOID)Ace + AceListLength) >= ((PVOID)Acl + Acl->AclSize))
276      {
277         return(STATUS_UNSUCCESSFUL);
278      }
279    if (StartingIndex != 0)
280      {
281         if (Acl->AceCount > 0)
282           {
283              Current = (PACE)(Acl + 1);
284              for (j = 0; j < StartingIndex; j++)
285                {
286                   Current = (PACE)((PVOID)Current + Current->Header.AceSize);
287                }
288           }
289      }
290    /* RtlpAddData(AceList, AceListLength, Current, (PVOID)Ace - Current)); */
291    memcpy(Current, AceList, AceListLength);
292    Acl->AceCount = Acl->AceCount + i;
293    Acl->AclRevision = AclRevision;
294    return(TRUE);
295 }
296
297
298 NTSTATUS STDCALL
299 RtlCreateAcl(PACL Acl,
300              ULONG AclSize,
301              ULONG AclRevision)
302 {
303   if (AclSize < 8)
304     {
305       return(STATUS_BUFFER_TOO_SMALL);
306     }
307   if (AclRevision != 2 &&
308       AclRevision != 3)
309     {
310       return(STATUS_UNKNOWN_REVISION);
311     }
312   if (AclSize > 0xffff)
313     {
314       return(STATUS_UNSUCCESSFUL);
315     }
316   AclSize = AclSize & ~(0x3);
317   Acl->AclSize = AclSize;
318   Acl->AclRevision = AclRevision;
319   Acl->AceCount = 0;
320   Acl->Sbz1 = 0;
321   Acl->Sbz2 = 0;
322   return(STATUS_SUCCESS);
323 }
324
325 /* EOF */