3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS kernel
5 * PURPOSE: Security manager
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 <ntdll/rtl.h>
20 /* FUNCTIONS ***************************************************************/
23 RtlFirstFreeAce(PACL Acl
,
32 Current
= (PACE
)(Acl
+ 1);
35 if (Acl
->AceCount
== 0)
40 AclEnd
= Acl
->AclSize
+ (PVOID
)Acl
;
43 if ((PVOID
)Current
>= AclEnd
)
47 if (Current
->Header
.AceType
== ACCESS_ALLOWED_COMPOUND_ACE_TYPE
&&
48 Acl
->AclRevision
< ACL_REVISION3
)
52 Current
= (PACE
)((ULONG_PTR
)Current
+ (ULONG_PTR
)Current
->Header
.AceSize
);
55 while (i
< Acl
->AceCount
);
57 if ((PVOID
)Current
< AclEnd
)
78 *Ace
= (PACE
)(Acl
+ 1);
80 if (Acl
->AclRevision
< MIN_ACL_REVISION
||
81 Acl
->AclRevision
> MAX_ACL_REVISION
)
83 return(STATUS_INVALID_PARAMETER
);
86 if (AceIndex
>= Acl
->AceCount
)
88 return(STATUS_INVALID_PARAMETER
);
91 for (i
= 0; i
< AceIndex
; i
++)
93 if ((PVOID
)*Ace
>= (PVOID
)Acl
+ Acl
->AclSize
)
95 return(STATUS_INVALID_PARAMETER
);
97 *Ace
= (PACE
)((PVOID
)(*Ace
) + (ULONG
)(*Ace
)->Header
.AceSize
);
100 if ((PVOID
)*Ace
>= (PVOID
)Acl
+ Acl
->AclSize
)
102 return(STATUS_INVALID_PARAMETER
);
105 return(STATUS_SUCCESS
);
110 RtlpAddKnownAce (PACL Acl
,
113 ACCESS_MASK AccessMask
,
121 if (!RtlValidSid(Sid
))
123 return(STATUS_INVALID_SID
);
125 if (Acl
->AclRevision
> MAX_ACL_REVISION
||
126 Revision
> MAX_ACL_REVISION
)
128 return(STATUS_UNKNOWN_REVISION
);
130 if (Revision
< Acl
->AclRevision
)
132 Revision
= Acl
->AclRevision
;
134 if (!RtlFirstFreeAce(Acl
, &Ace
))
136 return(STATUS_INVALID_ACL
);
140 return(STATUS_ALLOTTED_SPACE_EXCEEDED
);
142 if ((ULONG_PTR
)Ace
+ RtlLengthSid(Sid
) + sizeof(ACE
) >
143 (ULONG_PTR
)Acl
+ Acl
->AclSize
)
145 return(STATUS_ALLOTTED_SPACE_EXCEEDED
);
147 Ace
->Header
.AceFlags
= Flags
;
148 Ace
->Header
.AceType
= Type
;
149 Ace
->Header
.AceSize
= RtlLengthSid(Sid
) + sizeof(ACE
);
150 Ace
->AccessMask
= AccessMask
;
151 RtlCopySid(RtlLengthSid(Sid
), (PSID
)(Ace
+ 1), Sid
);
153 Acl
->AclRevision
= Revision
;
154 return(STATUS_SUCCESS
);
162 RtlAddAccessAllowedAce (IN OUT PACL Acl
,
164 IN ACCESS_MASK AccessMask
,
169 return RtlpAddKnownAce (Acl
,
174 ACCESS_ALLOWED_ACE_TYPE
);
182 RtlAddAccessAllowedAceEx (IN OUT PACL Acl
,
185 IN ACCESS_MASK AccessMask
,
190 return RtlpAddKnownAce (Acl
,
195 ACCESS_ALLOWED_ACE_TYPE
);
203 RtlAddAccessDeniedAce (PACL Acl
,
205 ACCESS_MASK AccessMask
,
210 return RtlpAddKnownAce (Acl
,
215 ACCESS_DENIED_ACE_TYPE
);
223 RtlAddAccessDeniedAceEx (IN OUT PACL Acl
,
226 IN ACCESS_MASK AccessMask
,
231 return RtlpAddKnownAce (Acl
,
236 ACCESS_DENIED_ACE_TYPE
);
241 RtlpAddData(PVOID AceList
,
248 memcpy((PVOID
)Ace
+ AceListLength
,
253 if (AceListLength
!= 0)
279 if (Acl
->AclRevision
< MIN_ACL_REVISION
||
280 Acl
->AclRevision
> MAX_ACL_REVISION
)
282 return(STATUS_INVALID_PARAMETER
);
285 if (!RtlFirstFreeAce(Acl
,&Ace
))
287 return(STATUS_INVALID_PARAMETER
);
290 if (Acl
->AclRevision
<= AclRevision
)
292 AclRevision
= Acl
->AclRevision
;
295 if (((PVOID
)AceList
+ AceListLength
) <= (PVOID
)AceList
)
297 return(STATUS_INVALID_PARAMETER
);
301 Current
= (PACE
)(Acl
+ 1);
302 while ((PVOID
)Current
< ((PVOID
)AceList
+ AceListLength
))
304 if (AceList
->Header
.AceType
== ACCESS_ALLOWED_COMPOUND_ACE_TYPE
&&
305 AclRevision
< ACL_REVISION3
)
307 return(STATUS_INVALID_PARAMETER
);
309 Current
= (PACE
)((PVOID
)Current
+ Current
->Header
.AceSize
);
314 return(STATUS_BUFFER_TOO_SMALL
);
317 if (((PVOID
)Ace
+ AceListLength
) >= ((PVOID
)Acl
+ Acl
->AclSize
))
319 return(STATUS_BUFFER_TOO_SMALL
);
322 if (StartingIndex
!= 0)
324 if (Acl
->AceCount
> 0)
326 Current
= (PACE
)(Acl
+ 1);
327 for (j
= 0; j
< StartingIndex
; j
++)
329 Current
= (PACE
)((PVOID
)Current
+ Current
->Header
.AceSize
);
337 (ULONG
)Ace
- (ULONG
)Current
);
338 Acl
->AceCount
= Acl
->AceCount
+ i
;
339 Acl
->AclRevision
= AclRevision
;
341 return(STATUS_SUCCESS
);
349 RtlAddAuditAccessAce(PACL Acl
,
351 ACCESS_MASK AccessMask
,
361 if (Success
!= FALSE
)
363 Flags
|= SUCCESSFUL_ACCESS_ACE_FLAG
;
366 if (Failure
!= FALSE
)
368 Flags
|= FAILED_ACCESS_ACE_FLAG
;
371 if (!RtlValidSid(Sid
))
373 return(STATUS_INVALID_SID
);
376 if (Acl
->AclRevision
> MAX_ACL_REVISION
||
377 Revision
> MAX_ACL_REVISION
)
379 return(STATUS_REVISION_MISMATCH
);
382 if (Revision
< Acl
->AclRevision
)
384 Revision
= Acl
->AclRevision
;
387 if (!RtlFirstFreeAce(Acl
, &Ace
))
389 return(STATUS_INVALID_ACL
);
394 return(STATUS_ALLOTTED_SPACE_EXCEEDED
);
397 if (((PVOID
)Ace
+ RtlLengthSid(Sid
) + sizeof(ACE
)) >= ((PVOID
)Acl
+ Acl
->AclSize
))
399 return(STATUS_ALLOTTED_SPACE_EXCEEDED
);
402 Ace
->Header
.AceFlags
= Flags
;
403 Ace
->Header
.AceType
= SYSTEM_AUDIT_ACE_TYPE
;
404 Ace
->Header
.AceSize
= RtlLengthSid(Sid
) + sizeof(ACE
);
405 Ace
->AccessMask
= AccessMask
;
406 RtlCopySid(RtlLengthSid(Sid
),
410 Acl
->AclRevision
= Revision
;
412 return(STATUS_SUCCESS
);
420 RtlAddAuditAccessAceEx(PACL Acl
,
423 ACCESS_MASK AccessMask
,
432 if (Success
!= FALSE
)
434 Flags
|= SUCCESSFUL_ACCESS_ACE_FLAG
;
437 if (Failure
!= FALSE
)
439 Flags
|= FAILED_ACCESS_ACE_FLAG
;
442 if (!RtlValidSid(Sid
))
444 return STATUS_INVALID_SID
;
447 if (Acl
->AclRevision
> MAX_ACL_REVISION
||
448 Revision
> MAX_ACL_REVISION
)
450 return STATUS_REVISION_MISMATCH
;
453 if (Revision
< Acl
->AclRevision
)
455 Revision
= Acl
->AclRevision
;
458 if (!RtlFirstFreeAce(Acl
, &Ace
))
460 return STATUS_INVALID_ACL
;
465 return STATUS_ALLOTTED_SPACE_EXCEEDED
;
468 if (((PVOID
)Ace
+ RtlLengthSid(Sid
) + sizeof(ACE
)) >= ((PVOID
)Acl
+ Acl
->AclSize
))
470 return STATUS_ALLOTTED_SPACE_EXCEEDED
;
473 Ace
->Header
.AceFlags
= Flags
;
474 Ace
->Header
.AceType
= SYSTEM_AUDIT_ACE_TYPE
;
475 Ace
->Header
.AceSize
= RtlLengthSid(Sid
) + sizeof(ACE
);
476 Ace
->AccessMask
= AccessMask
;
477 RtlCopySid(RtlLengthSid(Sid
),
481 Acl
->AclRevision
= Revision
;
483 return STATUS_SUCCESS
;
488 RtlpDeleteData(PVOID Ace
,
492 if (AceSize
< Offset
)
495 (PUCHAR
)Ace
+ AceSize
,
499 if (Offset
- AceSize
< Offset
)
501 memset((PUCHAR
)Ace
+ Offset
- AceSize
,
512 RtlDeleteAce(PACL Acl
,
520 if (Acl
->AclRevision
< MIN_ACL_REVISION
||
521 Acl
->AclRevision
> MAX_ACL_REVISION
)
523 return(STATUS_INVALID_PARAMETER
);
526 if (Acl
->AceCount
<= AceIndex
)
528 return(STATUS_INVALID_PARAMETER
);
531 if (!RtlFirstFreeAce(Acl
, &Ace
))
533 return(STATUS_INVALID_PARAMETER
);
536 Current
= (PACE
)(Acl
+ 1);
540 Current
= (PACE
)((PVOID
)Current
+ Current
->Header
.AceSize
);
543 RtlpDeleteData(Current
,
544 Current
->Header
.AceSize
,
548 return(STATUS_SUCCESS
);
556 RtlCreateAcl(PACL Acl
,
564 return(STATUS_BUFFER_TOO_SMALL
);
567 if (AclRevision
< MIN_ACL_REVISION
||
568 AclRevision
> MAX_ACL_REVISION
)
570 return(STATUS_INVALID_PARAMETER
);
573 if (AclSize
> 0xffff)
575 return(STATUS_INVALID_PARAMETER
);
578 AclSize
= ROUND_UP(AclSize
, 4);
579 Acl
->AclSize
= AclSize
;
580 Acl
->AclRevision
= AclRevision
;
585 return(STATUS_SUCCESS
);
593 RtlQueryInformationAcl(PACL Acl
,
595 ULONG InformationLength
,
596 ACL_INFORMATION_CLASS InformationClass
)
602 if (Acl
->AclRevision
< MIN_ACL_REVISION
||
603 Acl
->AclRevision
> MAX_ACL_REVISION
)
605 return(STATUS_INVALID_PARAMETER
);
608 switch (InformationClass
)
610 case AclRevisionInformation
:
612 PACL_REVISION_INFORMATION Info
= (PACL_REVISION_INFORMATION
)Information
;
614 if (InformationLength
< sizeof(ACL_REVISION_INFORMATION
))
616 return(STATUS_BUFFER_TOO_SMALL
);
618 Info
->AclRevision
= Acl
->AclRevision
;
622 case AclSizeInformation
:
624 PACL_SIZE_INFORMATION Info
= (PACL_SIZE_INFORMATION
)Information
;
626 if (InformationLength
< sizeof(ACL_SIZE_INFORMATION
))
628 return(STATUS_BUFFER_TOO_SMALL
);
631 if (!RtlFirstFreeAce(Acl
, &Ace
))
633 return(STATUS_INVALID_PARAMETER
);
636 Info
->AceCount
= Acl
->AceCount
;
639 Info
->AclBytesInUse
= (PVOID
)Ace
- (PVOID
)Acl
;
640 Info
->AclBytesFree
= Acl
->AclSize
- Info
->AclBytesInUse
;
644 Info
->AclBytesInUse
= Acl
->AclSize
;
645 Info
->AclBytesFree
= 0;
651 return(STATUS_INVALID_INFO_CLASS
);
654 return(STATUS_SUCCESS
);
662 RtlSetInformationAcl(PACL Acl
,
664 ULONG InformationLength
,
665 ACL_INFORMATION_CLASS InformationClass
)
669 if (Acl
->AclRevision
< MIN_ACL_REVISION
||
670 Acl
->AclRevision
> MAX_ACL_REVISION
)
672 return(STATUS_INVALID_PARAMETER
);
675 switch (InformationClass
)
677 case AclRevisionInformation
:
679 PACL_REVISION_INFORMATION Info
= (PACL_REVISION_INFORMATION
)Information
;
681 if (InformationLength
< sizeof(ACL_REVISION_INFORMATION
))
683 return(STATUS_BUFFER_TOO_SMALL
);
686 if (Acl
->AclRevision
>= Info
->AclRevision
)
688 return(STATUS_INVALID_PARAMETER
);
691 Acl
->AclRevision
= Info
->AclRevision
;
696 return(STATUS_INVALID_INFO_CLASS
);
699 return(STATUS_SUCCESS
);
707 RtlValidAcl (PACL Acl
)
714 Size
= ROUND_UP(Acl
->AclSize
, 4);
716 if (Acl
->AclRevision
< MIN_ACL_REVISION
||
717 Acl
->AclRevision
> MAX_ACL_REVISION
)
722 if (Size
!= Acl
->AclSize
)
727 return(RtlFirstFreeAce(Acl
, &Ace
));