1 /* $Id: acl.c,v 1.8 2002/09/08 10:23:04 chorns 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>
16 #include <ntdll/ntdll.h>
18 /* FUNCTIONS ***************************************************************/
21 RtlFirstFreeAce(PACL Acl
,
28 Current
= (PACE
)(Acl
+ 1);
31 if (Acl
->AceCount
== 0)
36 AclEnd
= Acl
->AclSize
+ (PVOID
)Acl
;
39 if ((PVOID
)Current
>= AclEnd
)
43 if (Current
->Header
.AceType
== 4)
45 if (Acl
->AclRevision
< 3)
50 Current
= (PACE
)((PVOID
)Current
+ (ULONG
)Current
->Header
.AceSize
);
53 while (i
< Acl
->AceCount
);
55 if ((PVOID
)Current
< AclEnd
)
71 *Ace
= (PACE
)(Acl
+ 1);
73 if (Acl
->AclRevision
!= 2 &&
74 Acl
->AclRevision
!= 3)
76 return(STATUS_INVALID_PARAMETER
);
79 if (AceIndex
>= Acl
->AceCount
)
81 return(STATUS_INVALID_PARAMETER
);
84 for (i
= 0; i
< AceIndex
; i
++)
86 if ((PVOID
)*Ace
>= (PVOID
)Acl
+ Acl
->AclSize
)
88 return(STATUS_INVALID_PARAMETER
);
90 *Ace
= (PACE
)((PVOID
)(*Ace
) + (ULONG
)(*Ace
)->Header
.AceSize
);
93 if ((PVOID
)*Ace
>= (PVOID
)Acl
+ Acl
->AclSize
)
95 return(STATUS_INVALID_PARAMETER
);
98 return(STATUS_SUCCESS
);
103 RtlpAddKnownAce(PACL Acl
,
105 ACCESS_MASK AccessMask
,
111 if (!RtlValidSid(Sid
))
113 return(STATUS_INVALID_SID
);
115 if (Acl
->AclRevision
> 3 ||
118 return(STATUS_UNKNOWN_REVISION
);
120 if (Revision
< Acl
->AclRevision
)
122 Revision
= Acl
->AclRevision
;
124 if (!RtlFirstFreeAce(Acl
, &Ace
))
126 return(STATUS_INVALID_ACL
);
130 return(STATUS_ALLOTTED_SPACE_EXCEEDED
);
132 if (((PVOID
)Ace
+ RtlLengthSid(Sid
) + sizeof(ACE
)) >=
133 ((PVOID
)Acl
+ Acl
->AclSize
))
135 return(STATUS_ALLOTTED_SPACE_EXCEEDED
);
137 Ace
->Header
.AceFlags
= 0;
138 Ace
->Header
.AceType
= Type
;
139 Ace
->Header
.AceSize
= RtlLengthSid(Sid
) + sizeof(ACE
);
140 Ace
->Header
.AccessMask
= AccessMask
;
141 RtlCopySid(RtlLengthSid(Sid
), (PSID
)(Ace
+ 1), Sid
);
143 Acl
->AclRevision
= Revision
;
144 return(STATUS_SUCCESS
);
149 RtlAddAccessAllowedAce(PACL Acl
,
151 ACCESS_MASK AccessMask
,
154 return(RtlpAddKnownAce(Acl
, Revision
, AccessMask
, Sid
, 0));
159 RtlAddAccessDeniedAce(PACL Acl
,
161 ACCESS_MASK AccessMask
,
164 return(RtlpAddKnownAce(Acl
, Revision
, AccessMask
, Sid
, 1));
169 RtlpAddData(PVOID AceList
,
176 memcpy((PUCHAR
)Ace
+ AceListLength
,
181 if (AceListLength
!= 0)
202 if (Acl
->AclRevision
!= 2 &&
203 Acl
->AclRevision
!= 3)
205 return(STATUS_INVALID_PARAMETER
);
208 if (!RtlFirstFreeAce(Acl
,&Ace
))
210 return(STATUS_INVALID_PARAMETER
);
213 if (Acl
->AclRevision
<= AclRevision
)
215 AclRevision
= Acl
->AclRevision
;
218 if (((PVOID
)AceList
+ AceListLength
) <= (PVOID
)AceList
)
220 return(STATUS_INVALID_PARAMETER
);
224 Current
= (PACE
)(Acl
+ 1);
225 while ((PVOID
)Current
< ((PVOID
)AceList
+ AceListLength
))
227 if (AceList
->Header
.AceType
== 4 &&
230 return(STATUS_INVALID_PARAMETER
);
232 Current
= (PACE
)((PVOID
)Current
+ Current
->Header
.AceSize
);
237 return(STATUS_BUFFER_TOO_SMALL
);
240 if (((PVOID
)Ace
+ AceListLength
) >= ((PVOID
)Acl
+ Acl
->AclSize
))
242 return(STATUS_BUFFER_TOO_SMALL
);
245 if (StartingIndex
!= 0)
247 if (Acl
->AceCount
> 0)
249 Current
= (PACE
)(Acl
+ 1);
250 for (j
= 0; j
< StartingIndex
; j
++)
252 Current
= (PACE
)((PVOID
)Current
+ Current
->Header
.AceSize
);
260 (ULONG
)Ace
- (ULONG
)Current
);
261 Acl
->AceCount
= Acl
->AceCount
+ i
;
262 Acl
->AclRevision
= AclRevision
;
264 return(STATUS_SUCCESS
);
269 RtlAddAuditAccessAce(PACL Acl
,
271 ACCESS_MASK AccessMask
,
279 if (Success
!= FALSE
)
281 Flags
|= SUCCESSFUL_ACCESS_ACE_FLAG
;
284 if (Failure
!= FALSE
)
286 Flags
|= FAILED_ACCESS_ACE_FLAG
;
289 if (!RtlValidSid(Sid
))
291 return(STATUS_INVALID_SID
);
294 if (Acl
->AclRevision
> 3 ||
297 return(STATUS_REVISION_MISMATCH
);
300 if (Revision
< Acl
->AclRevision
)
302 Revision
= Acl
->AclRevision
;
305 if (!RtlFirstFreeAce(Acl
, &Ace
))
307 return(STATUS_INVALID_ACL
);
312 return(STATUS_ALLOTTED_SPACE_EXCEEDED
);
315 if (((PVOID
)Ace
+ RtlLengthSid(Sid
) + sizeof(ACE
)) >= ((PVOID
)Acl
+ Acl
->AclSize
))
317 return(STATUS_ALLOTTED_SPACE_EXCEEDED
);
320 Ace
->Header
.AceFlags
= Flags
;
321 Ace
->Header
.AceType
= 2;
322 Ace
->Header
.AceSize
= RtlLengthSid(Sid
) + sizeof(ACE
);
323 Ace
->Header
.AccessMask
= AccessMask
;
324 RtlCopySid(RtlLengthSid(Sid
),
328 Acl
->AclRevision
= Revision
;
330 return(STATUS_SUCCESS
);
335 RtlpDeleteData(PVOID Ace
,
339 if (AceSize
< Offset
)
342 (PUCHAR
)Ace
+ AceSize
,
346 if (Offset
- AceSize
< Offset
)
348 memset((PUCHAR
)Ace
+ Offset
- AceSize
,
356 RtlDeleteAce(PACL Acl
,
362 if (Acl
->AclRevision
!= 2 &&
363 Acl
->AclRevision
!= 3)
365 return(STATUS_INVALID_PARAMETER
);
368 if (Acl
->AceCount
<= AceIndex
)
370 return(STATUS_INVALID_PARAMETER
);
373 if (!RtlFirstFreeAce(Acl
, &Ace
))
375 return(STATUS_INVALID_PARAMETER
);
378 Current
= (PACE
)(Acl
+ 1);
382 Current
= (PACE
)((PVOID
)Current
+ Current
->Header
.AceSize
);
385 RtlpDeleteData(Current
,
386 Current
->Header
.AceSize
,
390 return(STATUS_SUCCESS
);
395 RtlCreateAcl(PACL Acl
,
401 return(STATUS_BUFFER_TOO_SMALL
);
404 if (AclRevision
!= 2 &&
407 return(STATUS_INVALID_PARAMETER
);
410 if (AclSize
> 0xffff)
412 return(STATUS_INVALID_PARAMETER
);
415 AclSize
= AclSize
& ~(0x3);
416 Acl
->AclSize
= AclSize
;
417 Acl
->AclRevision
= AclRevision
;
422 return(STATUS_SUCCESS
);
427 RtlQueryInformationAcl(PACL Acl
,
429 ULONG InformationLength
,
430 ACL_INFORMATION_CLASS InformationClass
)
434 if (Acl
->AclRevision
!= 2 &&
435 Acl
->AclRevision
!= 3)
437 return(STATUS_INVALID_PARAMETER
);
440 switch (InformationClass
)
442 case AclRevisionInformation
:
444 PACL_REVISION_INFORMATION Info
= (PACL_REVISION_INFORMATION
)Information
;
446 if (InformationLength
< sizeof(ACL_REVISION_INFORMATION
))
448 return(STATUS_BUFFER_TOO_SMALL
);
450 Info
->AclRevision
= Acl
->AclRevision
;
454 case AclSizeInformation
:
456 PACL_SIZE_INFORMATION Info
= (PACL_SIZE_INFORMATION
)Information
;
458 if (InformationLength
< sizeof(ACL_SIZE_INFORMATION
))
460 return(STATUS_BUFFER_TOO_SMALL
);
463 if (!RtlFirstFreeAce(Acl
, &Ace
))
465 return(STATUS_INVALID_PARAMETER
);
468 Info
->AceCount
= Acl
->AceCount
;
471 Info
->AclBytesInUse
= (PVOID
)Ace
- (PVOID
)Acl
;
472 Info
->AclBytesFree
= Acl
->AclSize
- Info
->AclBytesInUse
;
476 Info
->AclBytesInUse
= Acl
->AclSize
;
477 Info
->AclBytesFree
= 0;
483 return(STATUS_INVALID_INFO_CLASS
);
486 return(STATUS_SUCCESS
);
491 RtlSetInformationAcl(PACL Acl
,
493 ULONG InformationLength
,
494 ACL_INFORMATION_CLASS InformationClass
)
496 if (Acl
->AclRevision
!= 2 &&
497 Acl
->AclRevision
!= 3)
499 return(STATUS_INVALID_PARAMETER
);
502 switch (InformationClass
)
504 case AclRevisionInformation
:
506 PACL_REVISION_INFORMATION Info
= (PACL_REVISION_INFORMATION
)Information
;
508 if (InformationLength
< sizeof(ACL_REVISION_INFORMATION
))
510 return(STATUS_BUFFER_TOO_SMALL
);
513 if (Acl
->AclRevision
>= Info
->AclRevision
)
515 return(STATUS_INVALID_PARAMETER
);
518 Acl
->AclRevision
= Info
->AclRevision
;
523 return(STATUS_INVALID_INFO_CLASS
);
526 return(STATUS_SUCCESS
);
531 RtlValidAcl(PACL Acl
)
536 Size
= (Acl
->AclSize
+ 3) & ~3;
538 if (Acl
->AclRevision
!= 2 &&
539 Acl
->AclRevision
!= 3)
544 if (Size
!= Acl
->AclSize
)
549 return(RtlFirstFreeAce(Acl
, &Ace
));