1 /* $Id: acl.c,v 1.14 2003/12/30 18:52:06 fireball Exp $
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>
9 * 26/07/98: Added stubs for security functions
12 /* INCLUDES *****************************************************************/
14 #include <ddk/ntddk.h>
15 #include <internal/se.h>
17 #include <internal/debug.h>
19 #define TAG_ACL TAG('A', 'C', 'L', 'T')
22 /* GLOBALS ******************************************************************/
24 PACL EXPORTED SePublicDefaultDacl
= NULL
;
25 PACL EXPORTED SeSystemDefaultDacl
= NULL
;
27 PACL SePublicDefaultUnrestrictedDacl
= NULL
;
28 PACL SePublicOpenDacl
= NULL
;
29 PACL SePublicOpenUnrestrictedDacl
= NULL
;
30 PACL SeUnrestrictedDacl
= NULL
;
33 /* FUNCTIONS ****************************************************************/
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
));
49 /* create PublicDefaultDacl */
50 SePublicDefaultDacl
= ExAllocatePoolWithTag(NonPagedPool
,
53 if (SePublicDefaultDacl
== NULL
)
56 RtlCreateAcl(SePublicDefaultDacl
,
60 RtlAddAccessAllowedAce(SePublicDefaultDacl
,
65 RtlAddAccessAllowedAce(SePublicDefaultDacl
,
71 /* create PublicDefaultUnrestrictedDacl */
72 SePublicDefaultUnrestrictedDacl
= ExAllocatePoolWithTag(NonPagedPool
,
75 if (SePublicDefaultUnrestrictedDacl
== NULL
)
78 RtlCreateAcl(SePublicDefaultUnrestrictedDacl
,
82 RtlAddAccessAllowedAce(SePublicDefaultUnrestrictedDacl
,
87 RtlAddAccessAllowedAce(SePublicDefaultUnrestrictedDacl
,
92 RtlAddAccessAllowedAce(SePublicDefaultUnrestrictedDacl
,
97 RtlAddAccessAllowedAce(SePublicDefaultUnrestrictedDacl
,
99 GENERIC_READ
| GENERIC_EXECUTE
| STANDARD_RIGHTS_READ
,
100 SeRestrictedCodeSid
);
102 /* create PublicOpenDacl */
103 SePublicOpenDacl
= ExAllocatePoolWithTag(NonPagedPool
,
106 if (SePublicOpenDacl
== NULL
)
109 RtlCreateAcl(SePublicOpenDacl
,
113 RtlAddAccessAllowedAce(SePublicOpenDacl
,
115 GENERIC_READ
| GENERIC_WRITE
| GENERIC_EXECUTE
,
118 RtlAddAccessAllowedAce(SePublicOpenDacl
,
123 RtlAddAccessAllowedAce(SePublicOpenDacl
,
134 RtlFirstFreeAce(PACL Acl
,
141 Current
= (PACE
)(Acl
+ 1);
144 if (Acl
->AceCount
== 0)
150 AclEnd
= Acl
->AclSize
+ (char*)Acl
;
153 if ((PVOID
)Current
>= AclEnd
)
158 if (Current
->Header
.AceType
== 4)
160 if (Acl
->AclRevision
< 3)
165 Current
= (PACE
)((char*)Current
+ (ULONG
)Current
->Header
.AceSize
);
168 while (i
< Acl
->AceCount
);
170 if ((PVOID
)Current
< AclEnd
)
180 RtlpAddKnownAce(PACL Acl
,
182 ACCESS_MASK AccessMask
,
188 if (!RtlValidSid(Sid
))
190 return(STATUS_INVALID_SID
);
192 if (Acl
->AclRevision
> 3 ||
195 return(STATUS_UNKNOWN_REVISION
);
197 if (Revision
< Acl
->AclRevision
)
199 Revision
= Acl
->AclRevision
;
201 if (!RtlFirstFreeAce(Acl
, &Ace
))
203 return(STATUS_BUFFER_TOO_SMALL
);
207 return(STATUS_UNSUCCESSFUL
);
209 if (((char*)Ace
+ RtlLengthSid(Sid
) + sizeof(ACE
)) >=
210 ((char*)Acl
+ Acl
->AclSize
))
212 return(STATUS_BUFFER_TOO_SMALL
);
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
);
220 Acl
->AclRevision
= Revision
;
221 return(STATUS_SUCCESS
);
229 RtlAddAccessAllowedAce(PACL Acl
,
231 ACCESS_MASK AccessMask
,
234 return(RtlpAddKnownAce(Acl
, Revision
, AccessMask
, Sid
, 0));
253 if (Acl
->AclRevision
!= 2 &&
254 Acl
->AclRevision
!= 3)
256 return(STATUS_UNSUCCESSFUL
);
258 if (!RtlFirstFreeAce(Acl
,&Ace
))
260 return(STATUS_UNSUCCESSFUL
);
262 if (Acl
->AclRevision
<= AclRevision
)
264 AclRevision
= Acl
->AclRevision
;
266 if ((PVOID
)((char*)AceList
+ AceListLength
) <= (PVOID
)AceList
)
268 return(STATUS_UNSUCCESSFUL
);
271 Current
= (PACE
)(Acl
+ 1);
272 while ((char*)Current
< ((char*)AceList
+ AceListLength
))
274 if (AceList
->Header
.AceType
== 4 &&
277 return(STATUS_UNSUCCESSFUL
);
279 Current
= (PACE
)((char*)Current
+ Current
->Header
.AceSize
);
283 return(STATUS_UNSUCCESSFUL
);
285 if (((char*)Ace
+ AceListLength
) >= ((char*)Acl
+ Acl
->AclSize
))
287 return(STATUS_UNSUCCESSFUL
);
289 if (StartingIndex
!= 0)
291 if (Acl
->AceCount
> 0)
293 Current
= (PACE
)(Acl
+ 1);
294 for (j
= 0; j
< StartingIndex
; j
++)
296 Current
= (PACE
)((char*)Current
+ Current
->Header
.AceSize
);
300 /* RtlpAddData(AceList, AceListLength, Current, (PVOID)Ace - Current)); */
301 memcpy(Current
, AceList
, AceListLength
);
302 Acl
->AceCount
= Acl
->AceCount
+ i
;
303 Acl
->AclRevision
= AclRevision
;
312 RtlCreateAcl(PACL Acl
,
318 return(STATUS_BUFFER_TOO_SMALL
);
320 if (AclRevision
!= 2 &&
323 return(STATUS_UNKNOWN_REVISION
);
325 if (AclSize
> 0xffff)
327 return(STATUS_UNSUCCESSFUL
);
329 AclSize
= AclSize
& ~(0x3);
330 Acl
->AclSize
= AclSize
;
331 Acl
->AclRevision
= AclRevision
;
335 return(STATUS_SUCCESS
);
340 RtlValidAcl(PACL Acl
)
345 Size
= (Acl
->AclSize
+ 3) & ~3;
347 if (Acl
->AclRevision
!= 2 &&
348 Acl
->AclRevision
!= 3)
353 if (Size
!= Acl
->AclSize
)
358 return(RtlFirstFreeAce(Acl
, &Ace
));