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 *****************************************************************/
19 /* FUNCTIONS ***************************************************************/
22 RtlFirstFreeAce(PACL Acl
,
31 Current
= (PACE
)(Acl
+ 1);
34 if (Acl
->AceCount
== 0)
39 AclEnd
= Acl
->AclSize
+ (PVOID
)Acl
;
42 if ((PVOID
)Current
>= AclEnd
)
46 if (Current
->Header
.AceType
== ACCESS_ALLOWED_COMPOUND_ACE_TYPE
&&
47 Acl
->AclRevision
< ACL_REVISION3
)
51 Current
= (PACE
)((ULONG_PTR
)Current
+ (ULONG_PTR
)Current
->Header
.AceSize
);
54 while (i
< Acl
->AceCount
);
56 if ((PVOID
)Current
< AclEnd
)
77 *Ace
= (PACE
)(Acl
+ 1);
79 if (Acl
->AclRevision
< MIN_ACL_REVISION
||
80 Acl
->AclRevision
> MAX_ACL_REVISION
)
82 return(STATUS_INVALID_PARAMETER
);
85 if (AceIndex
>= Acl
->AceCount
)
87 return(STATUS_INVALID_PARAMETER
);
90 for (i
= 0; i
< AceIndex
; i
++)
92 if ((PVOID
)*Ace
>= (PVOID
)Acl
+ Acl
->AclSize
)
94 return(STATUS_INVALID_PARAMETER
);
96 *Ace
= (PACE
)((PVOID
)(*Ace
) + (ULONG
)(*Ace
)->Header
.AceSize
);
99 if ((PVOID
)*Ace
>= (PVOID
)Acl
+ Acl
->AclSize
)
101 return(STATUS_INVALID_PARAMETER
);
104 return(STATUS_SUCCESS
);
109 RtlpAddKnownAce (PACL Acl
,
112 ACCESS_MASK AccessMask
,
120 if (!RtlValidSid(Sid
))
122 return(STATUS_INVALID_SID
);
124 if (Acl
->AclRevision
> MAX_ACL_REVISION
||
125 Revision
> MAX_ACL_REVISION
)
127 return(STATUS_UNKNOWN_REVISION
);
129 if (Revision
< Acl
->AclRevision
)
131 Revision
= Acl
->AclRevision
;
133 if (!RtlFirstFreeAce(Acl
, &Ace
))
135 return(STATUS_INVALID_ACL
);
139 return(STATUS_ALLOTTED_SPACE_EXCEEDED
);
141 if ((ULONG_PTR
)Ace
+ RtlLengthSid(Sid
) + sizeof(ACE
) >
142 (ULONG_PTR
)Acl
+ Acl
->AclSize
)
144 return(STATUS_ALLOTTED_SPACE_EXCEEDED
);
146 Ace
->Header
.AceFlags
= Flags
;
147 Ace
->Header
.AceType
= Type
;
148 Ace
->Header
.AceSize
= RtlLengthSid(Sid
) + sizeof(ACE
);
149 Ace
->AccessMask
= AccessMask
;
150 RtlCopySid(RtlLengthSid(Sid
), (PSID
)(Ace
+ 1), Sid
);
152 Acl
->AclRevision
= Revision
;
153 return(STATUS_SUCCESS
);
161 RtlAddAccessAllowedAce (IN OUT PACL Acl
,
163 IN ACCESS_MASK AccessMask
,
168 return RtlpAddKnownAce (Acl
,
173 ACCESS_ALLOWED_ACE_TYPE
);
181 RtlAddAccessAllowedAceEx (IN OUT PACL Acl
,
184 IN ACCESS_MASK AccessMask
,
189 return RtlpAddKnownAce (Acl
,
194 ACCESS_ALLOWED_ACE_TYPE
);
202 RtlAddAccessDeniedAce (PACL Acl
,
204 ACCESS_MASK AccessMask
,
209 return RtlpAddKnownAce (Acl
,
214 ACCESS_DENIED_ACE_TYPE
);
222 RtlAddAccessDeniedAceEx (IN OUT PACL Acl
,
225 IN ACCESS_MASK AccessMask
,
230 return RtlpAddKnownAce (Acl
,
235 ACCESS_DENIED_ACE_TYPE
);
240 RtlpAddData(PVOID AceList
,
247 memcpy((PVOID
)Ace
+ AceListLength
,
252 if (AceListLength
!= 0)
278 if (Acl
->AclRevision
< MIN_ACL_REVISION
||
279 Acl
->AclRevision
> MAX_ACL_REVISION
)
281 return(STATUS_INVALID_PARAMETER
);
284 if (!RtlFirstFreeAce(Acl
,&Ace
))
286 return(STATUS_INVALID_PARAMETER
);
289 if (Acl
->AclRevision
<= AclRevision
)
291 AclRevision
= Acl
->AclRevision
;
294 if (((PVOID
)AceList
+ AceListLength
) <= (PVOID
)AceList
)
296 return(STATUS_INVALID_PARAMETER
);
300 Current
= (PACE
)(Acl
+ 1);
301 while ((PVOID
)Current
< ((PVOID
)AceList
+ AceListLength
))
303 if (AceList
->Header
.AceType
== ACCESS_ALLOWED_COMPOUND_ACE_TYPE
&&
304 AclRevision
< ACL_REVISION3
)
306 return(STATUS_INVALID_PARAMETER
);
308 Current
= (PACE
)((PVOID
)Current
+ Current
->Header
.AceSize
);
313 return(STATUS_BUFFER_TOO_SMALL
);
316 if (((PVOID
)Ace
+ AceListLength
) >= ((PVOID
)Acl
+ Acl
->AclSize
))
318 return(STATUS_BUFFER_TOO_SMALL
);
321 if (StartingIndex
!= 0)
323 if (Acl
->AceCount
> 0)
325 Current
= (PACE
)(Acl
+ 1);
326 for (j
= 0; j
< StartingIndex
; j
++)
328 Current
= (PACE
)((PVOID
)Current
+ Current
->Header
.AceSize
);
336 (ULONG
)Ace
- (ULONG
)Current
);
337 Acl
->AceCount
= Acl
->AceCount
+ i
;
338 Acl
->AclRevision
= AclRevision
;
340 return(STATUS_SUCCESS
);
348 RtlAddAuditAccessAce(PACL Acl
,
350 ACCESS_MASK AccessMask
,
360 if (Success
!= FALSE
)
362 Flags
|= SUCCESSFUL_ACCESS_ACE_FLAG
;
365 if (Failure
!= FALSE
)
367 Flags
|= FAILED_ACCESS_ACE_FLAG
;
370 if (!RtlValidSid(Sid
))
372 return(STATUS_INVALID_SID
);
375 if (Acl
->AclRevision
> MAX_ACL_REVISION
||
376 Revision
> MAX_ACL_REVISION
)
378 return(STATUS_REVISION_MISMATCH
);
381 if (Revision
< Acl
->AclRevision
)
383 Revision
= Acl
->AclRevision
;
386 if (!RtlFirstFreeAce(Acl
, &Ace
))
388 return(STATUS_INVALID_ACL
);
393 return(STATUS_ALLOTTED_SPACE_EXCEEDED
);
396 if (((PVOID
)Ace
+ RtlLengthSid(Sid
) + sizeof(ACE
)) >= ((PVOID
)Acl
+ Acl
->AclSize
))
398 return(STATUS_ALLOTTED_SPACE_EXCEEDED
);
401 Ace
->Header
.AceFlags
= Flags
;
402 Ace
->Header
.AceType
= SYSTEM_AUDIT_ACE_TYPE
;
403 Ace
->Header
.AceSize
= RtlLengthSid(Sid
) + sizeof(ACE
);
404 Ace
->AccessMask
= AccessMask
;
405 RtlCopySid(RtlLengthSid(Sid
),
409 Acl
->AclRevision
= Revision
;
411 return(STATUS_SUCCESS
);
419 RtlAddAuditAccessAceEx(PACL Acl
,
422 ACCESS_MASK AccessMask
,
431 if (Success
!= FALSE
)
433 Flags
|= SUCCESSFUL_ACCESS_ACE_FLAG
;
436 if (Failure
!= FALSE
)
438 Flags
|= FAILED_ACCESS_ACE_FLAG
;
441 if (!RtlValidSid(Sid
))
443 return STATUS_INVALID_SID
;
446 if (Acl
->AclRevision
> MAX_ACL_REVISION
||
447 Revision
> MAX_ACL_REVISION
)
449 return STATUS_REVISION_MISMATCH
;
452 if (Revision
< Acl
->AclRevision
)
454 Revision
= Acl
->AclRevision
;
457 if (!RtlFirstFreeAce(Acl
, &Ace
))
459 return STATUS_INVALID_ACL
;
464 return STATUS_ALLOTTED_SPACE_EXCEEDED
;
467 if (((PVOID
)Ace
+ RtlLengthSid(Sid
) + sizeof(ACE
)) >= ((PVOID
)Acl
+ Acl
->AclSize
))
469 return STATUS_ALLOTTED_SPACE_EXCEEDED
;
472 Ace
->Header
.AceFlags
= Flags
;
473 Ace
->Header
.AceType
= SYSTEM_AUDIT_ACE_TYPE
;
474 Ace
->Header
.AceSize
= RtlLengthSid(Sid
) + sizeof(ACE
);
475 Ace
->AccessMask
= AccessMask
;
476 RtlCopySid(RtlLengthSid(Sid
),
480 Acl
->AclRevision
= Revision
;
482 return STATUS_SUCCESS
;
487 RtlpDeleteData(PVOID Ace
,
491 if (AceSize
< Offset
)
494 (PUCHAR
)Ace
+ AceSize
,
498 if (Offset
- AceSize
< Offset
)
500 memset((PUCHAR
)Ace
+ Offset
- AceSize
,
511 RtlDeleteAce(PACL Acl
,
519 if (Acl
->AclRevision
< MIN_ACL_REVISION
||
520 Acl
->AclRevision
> MAX_ACL_REVISION
)
522 return(STATUS_INVALID_PARAMETER
);
525 if (Acl
->AceCount
<= AceIndex
)
527 return(STATUS_INVALID_PARAMETER
);
530 if (!RtlFirstFreeAce(Acl
, &Ace
))
532 return(STATUS_INVALID_PARAMETER
);
535 Current
= (PACE
)(Acl
+ 1);
539 Current
= (PACE
)((PVOID
)Current
+ Current
->Header
.AceSize
);
542 RtlpDeleteData(Current
,
543 Current
->Header
.AceSize
,
547 return(STATUS_SUCCESS
);
555 RtlCreateAcl(PACL Acl
,
563 return(STATUS_BUFFER_TOO_SMALL
);
566 if (AclRevision
< MIN_ACL_REVISION
||
567 AclRevision
> MAX_ACL_REVISION
)
569 return(STATUS_INVALID_PARAMETER
);
572 if (AclSize
> 0xffff)
574 return(STATUS_INVALID_PARAMETER
);
577 AclSize
= ROUND_UP(AclSize
, 4);
578 Acl
->AclSize
= AclSize
;
579 Acl
->AclRevision
= AclRevision
;
584 return(STATUS_SUCCESS
);
592 RtlQueryInformationAcl(PACL Acl
,
594 ULONG InformationLength
,
595 ACL_INFORMATION_CLASS InformationClass
)
601 if (Acl
->AclRevision
< MIN_ACL_REVISION
||
602 Acl
->AclRevision
> MAX_ACL_REVISION
)
604 return(STATUS_INVALID_PARAMETER
);
607 switch (InformationClass
)
609 case AclRevisionInformation
:
611 PACL_REVISION_INFORMATION Info
= (PACL_REVISION_INFORMATION
)Information
;
613 if (InformationLength
< sizeof(ACL_REVISION_INFORMATION
))
615 return(STATUS_BUFFER_TOO_SMALL
);
617 Info
->AclRevision
= Acl
->AclRevision
;
621 case AclSizeInformation
:
623 PACL_SIZE_INFORMATION Info
= (PACL_SIZE_INFORMATION
)Information
;
625 if (InformationLength
< sizeof(ACL_SIZE_INFORMATION
))
627 return(STATUS_BUFFER_TOO_SMALL
);
630 if (!RtlFirstFreeAce(Acl
, &Ace
))
632 return(STATUS_INVALID_PARAMETER
);
635 Info
->AceCount
= Acl
->AceCount
;
638 Info
->AclBytesInUse
= (PVOID
)Ace
- (PVOID
)Acl
;
639 Info
->AclBytesFree
= Acl
->AclSize
- Info
->AclBytesInUse
;
643 Info
->AclBytesInUse
= Acl
->AclSize
;
644 Info
->AclBytesFree
= 0;
650 return(STATUS_INVALID_INFO_CLASS
);
653 return(STATUS_SUCCESS
);
661 RtlSetInformationAcl(PACL Acl
,
663 ULONG InformationLength
,
664 ACL_INFORMATION_CLASS InformationClass
)
668 if (Acl
->AclRevision
< MIN_ACL_REVISION
||
669 Acl
->AclRevision
> MAX_ACL_REVISION
)
671 return(STATUS_INVALID_PARAMETER
);
674 switch (InformationClass
)
676 case AclRevisionInformation
:
678 PACL_REVISION_INFORMATION Info
= (PACL_REVISION_INFORMATION
)Information
;
680 if (InformationLength
< sizeof(ACL_REVISION_INFORMATION
))
682 return(STATUS_BUFFER_TOO_SMALL
);
685 if (Acl
->AclRevision
>= Info
->AclRevision
)
687 return(STATUS_INVALID_PARAMETER
);
690 Acl
->AclRevision
= Info
->AclRevision
;
695 return(STATUS_INVALID_INFO_CLASS
);
698 return(STATUS_SUCCESS
);
706 RtlValidAcl (PACL Acl
)
713 Size
= ROUND_UP(Acl
->AclSize
, 4);
715 if (Acl
->AclRevision
< MIN_ACL_REVISION
||
716 Acl
->AclRevision
> MAX_ACL_REVISION
)
721 if (Size
!= Acl
->AclSize
)
726 return(RtlFirstFreeAce(Acl
, &Ace
));