1 /* COPYRIGHT: See COPYING in the top level directory
2 * PROJECT: ReactOS system libraries
3 * PURPOSE: Security manager
5 * PROGRAMER: David Welch <welch@cwcom.net>
8 /* INCLUDES *****************************************************************/
15 /* FUNCTIONS ***************************************************************/
18 RtlFirstFreeAce(PACL Acl
,
27 Current
= (PACE
)(Acl
+ 1);
30 if (Acl
->AceCount
== 0)
37 AclEnd
= (ULONG_PTR
)Acl
+ Acl
->AclSize
;
40 if ((ULONG_PTR
)Current
>= AclEnd
)
44 if (Current
->Header
.AceType
== ACCESS_ALLOWED_COMPOUND_ACE_TYPE
&&
45 Acl
->AclRevision
< ACL_REVISION3
)
49 Current
= (PACE
)((ULONG_PTR
)Current
+ Current
->Header
.AceSize
);
51 while (++i
< Acl
->AceCount
);
53 if ((ULONG_PTR
)Current
< AclEnd
)
74 if (Acl
->AclRevision
< MIN_ACL_REVISION
||
75 Acl
->AclRevision
> MAX_ACL_REVISION
||
76 AceIndex
>= Acl
->AceCount
)
78 return(STATUS_INVALID_PARAMETER
);
81 *Ace
= (PVOID
)((PACE
)(Acl
+ 1));
83 for (i
= 0; i
< AceIndex
; i
++)
85 if ((ULONG_PTR
)*Ace
>= (ULONG_PTR
)Acl
+ Acl
->AclSize
)
87 return(STATUS_INVALID_PARAMETER
);
89 *Ace
= (PVOID
)((PACE
)((ULONG_PTR
)(*Ace
) + ((PACE
)(*Ace
))->Header
.AceSize
));
92 if ((ULONG_PTR
)*Ace
>= (ULONG_PTR
)Acl
+ Acl
->AclSize
)
94 return(STATUS_INVALID_PARAMETER
);
97 return(STATUS_SUCCESS
);
102 RtlpAddKnownAce (PACL Acl
,
105 ACCESS_MASK AccessMask
,
113 if (!RtlValidSid(Sid
))
115 return(STATUS_INVALID_SID
);
117 if (Acl
->AclRevision
> MAX_ACL_REVISION
||
118 Revision
> MAX_ACL_REVISION
)
120 return(STATUS_UNKNOWN_REVISION
);
122 if (Revision
< Acl
->AclRevision
)
124 Revision
= Acl
->AclRevision
;
126 if (!RtlFirstFreeAce(Acl
, &Ace
))
128 return(STATUS_INVALID_ACL
);
132 return(STATUS_ALLOTTED_SPACE_EXCEEDED
);
134 if ((ULONG_PTR
)Ace
+ RtlLengthSid(Sid
) + sizeof(ACE
) >
135 (ULONG_PTR
)Acl
+ Acl
->AclSize
)
137 return(STATUS_ALLOTTED_SPACE_EXCEEDED
);
139 Ace
->Header
.AceFlags
= Flags
;
140 Ace
->Header
.AceType
= Type
;
141 Ace
->Header
.AceSize
= RtlLengthSid(Sid
) + sizeof(ACE
);
142 Ace
->AccessMask
= AccessMask
;
143 RtlCopySid(RtlLengthSid(Sid
), (PSID
)(Ace
+ 1), Sid
);
145 Acl
->AclRevision
= Revision
;
146 return(STATUS_SUCCESS
);
154 RtlAddAccessAllowedAce (IN OUT PACL Acl
,
156 IN ACCESS_MASK AccessMask
,
161 return RtlpAddKnownAce (Acl
,
166 ACCESS_ALLOWED_ACE_TYPE
);
174 RtlAddAccessAllowedAceEx (IN OUT PACL Acl
,
177 IN ACCESS_MASK AccessMask
,
182 return RtlpAddKnownAce (Acl
,
187 ACCESS_ALLOWED_ACE_TYPE
);
195 RtlAddAccessDeniedAce (PACL Acl
,
197 ACCESS_MASK AccessMask
,
202 return RtlpAddKnownAce (Acl
,
207 ACCESS_DENIED_ACE_TYPE
);
215 RtlAddAccessDeniedAceEx (IN OUT PACL Acl
,
218 IN ACCESS_MASK AccessMask
,
223 return RtlpAddKnownAce (Acl
,
228 ACCESS_DENIED_ACE_TYPE
);
233 RtlpAddData(PVOID AceList
,
240 RtlCopyMemory((PVOID
)((ULONG_PTR
)Ace
+ AceListLength
),
245 if (AceListLength
!= 0)
271 if (Acl
->AclRevision
< MIN_ACL_REVISION
||
272 Acl
->AclRevision
> MAX_ACL_REVISION
||
273 !RtlFirstFreeAce(Acl
, &Ace
))
275 return(STATUS_INVALID_PARAMETER
);
278 if (Acl
->AclRevision
<= AclRevision
)
280 AclRevision
= Acl
->AclRevision
;
283 if (((ULONG_PTR
)AceList
+ AceListLength
) <= (ULONG_PTR
)AceList
)
285 return(STATUS_INVALID_PARAMETER
);
288 for (Current
= AceList
, NewAceCount
= 0;
289 (ULONG_PTR
)Current
< ((ULONG_PTR
)AceList
+ AceListLength
);
290 Current
= (PACE
)((ULONG_PTR
)Current
+ Current
->Header
.AceSize
),
293 if (((PACE
)AceList
)->Header
.AceType
== ACCESS_ALLOWED_COMPOUND_ACE_TYPE
&&
294 AclRevision
< ACL_REVISION3
)
296 return(STATUS_INVALID_PARAMETER
);
301 ((ULONG_PTR
)Ace
+ AceListLength
) > ((ULONG_PTR
)Acl
+ Acl
->AclSize
))
303 return(STATUS_BUFFER_TOO_SMALL
);
306 Current
= (PACE
)(Acl
+ 1);
307 for (Index
= 0; Index
< StartingIndex
&& Index
< Acl
->AceCount
; Index
++)
309 Current
= (PACE
)((ULONG_PTR
)Current
+ Current
->Header
.AceSize
);
315 (ULONG
)((ULONG_PTR
)Ace
- (ULONG_PTR
)Current
));
316 Acl
->AceCount
= Acl
->AceCount
+ NewAceCount
;
317 Acl
->AclRevision
= AclRevision
;
319 return(STATUS_SUCCESS
);
327 RtlAddAuditAccessAce(PACL Acl
,
329 ACCESS_MASK AccessMask
,
339 if (Success
!= FALSE
)
341 Flags
|= SUCCESSFUL_ACCESS_ACE_FLAG
;
344 if (Failure
!= FALSE
)
346 Flags
|= FAILED_ACCESS_ACE_FLAG
;
349 if (!RtlValidSid(Sid
))
351 return(STATUS_INVALID_SID
);
354 if (Acl
->AclRevision
> MAX_ACL_REVISION
||
355 Revision
> MAX_ACL_REVISION
)
357 return(STATUS_REVISION_MISMATCH
);
360 if (Revision
< Acl
->AclRevision
)
362 Revision
= Acl
->AclRevision
;
365 if (!RtlFirstFreeAce(Acl
, &Ace
))
367 return(STATUS_INVALID_ACL
);
371 ((ULONG_PTR
)Ace
+ RtlLengthSid(Sid
) + sizeof(ACE
)) > ((ULONG_PTR
)Acl
+ Acl
->AclSize
))
373 return(STATUS_ALLOTTED_SPACE_EXCEEDED
);
376 Ace
->Header
.AceFlags
= Flags
;
377 Ace
->Header
.AceType
= SYSTEM_AUDIT_ACE_TYPE
;
378 Ace
->Header
.AceSize
= RtlLengthSid(Sid
) + sizeof(ACE
);
379 Ace
->AccessMask
= AccessMask
;
380 RtlCopySid(RtlLengthSid(Sid
),
384 Acl
->AclRevision
= Revision
;
386 return(STATUS_SUCCESS
);
394 RtlAddAuditAccessAceEx(PACL Acl
,
397 ACCESS_MASK AccessMask
,
406 if (Success
!= FALSE
)
408 Flags
|= SUCCESSFUL_ACCESS_ACE_FLAG
;
411 if (Failure
!= FALSE
)
413 Flags
|= FAILED_ACCESS_ACE_FLAG
;
416 if (!RtlValidSid(Sid
))
418 return STATUS_INVALID_SID
;
421 if (Acl
->AclRevision
> MAX_ACL_REVISION
||
422 Revision
> MAX_ACL_REVISION
)
424 return STATUS_REVISION_MISMATCH
;
427 if (Revision
< Acl
->AclRevision
)
429 Revision
= Acl
->AclRevision
;
432 if (!RtlFirstFreeAce(Acl
, &Ace
))
434 return STATUS_INVALID_ACL
;
438 ((ULONG_PTR
)Ace
+ RtlLengthSid(Sid
) + sizeof(ACE
)) >= ((ULONG_PTR
)Acl
+ Acl
->AclSize
))
440 return STATUS_ALLOTTED_SPACE_EXCEEDED
;
443 Ace
->Header
.AceFlags
= Flags
;
444 Ace
->Header
.AceType
= SYSTEM_AUDIT_ACE_TYPE
;
445 Ace
->Header
.AceSize
= RtlLengthSid(Sid
) + sizeof(ACE
);
446 Ace
->AccessMask
= AccessMask
;
447 RtlCopySid(RtlLengthSid(Sid
),
451 Acl
->AclRevision
= Revision
;
453 return STATUS_SUCCESS
;
458 RtlpDeleteData(PVOID Ace
,
462 if (AceSize
< Offset
)
465 (PVOID
)((ULONG_PTR
)Ace
+ AceSize
),
469 if (Offset
- AceSize
< Offset
)
471 RtlZeroMemory((PVOID
)((ULONG_PTR
)Ace
+ Offset
- AceSize
),
481 RtlDeleteAce(PACL Acl
,
489 if (Acl
->AclRevision
< MIN_ACL_REVISION
||
490 Acl
->AclRevision
> MAX_ACL_REVISION
||
491 Acl
->AceCount
<= AceIndex
||
492 !RtlFirstFreeAce(Acl
, &Ace
))
494 return(STATUS_INVALID_PARAMETER
);
497 Current
= (PACE
)(Acl
+ 1);
501 Current
= (PACE
)((ULONG_PTR
)Current
+ Current
->Header
.AceSize
);
504 RtlpDeleteData(Current
,
505 Current
->Header
.AceSize
,
506 (ULONG
)((ULONG_PTR
)Ace
- (ULONG_PTR
)Current
));
509 return(STATUS_SUCCESS
);
517 RtlCreateAcl(PACL Acl
,
523 if (AclSize
< sizeof(ACL
))
525 return(STATUS_BUFFER_TOO_SMALL
);
528 if (AclRevision
< MIN_ACL_REVISION
||
529 AclRevision
> MAX_ACL_REVISION
||
532 return(STATUS_INVALID_PARAMETER
);
535 AclSize
= ROUND_UP(AclSize
, 4);
536 Acl
->AclSize
= AclSize
;
537 Acl
->AclRevision
= AclRevision
;
542 return(STATUS_SUCCESS
);
550 RtlQueryInformationAcl(PACL Acl
,
552 ULONG InformationLength
,
553 ACL_INFORMATION_CLASS InformationClass
)
559 if (Acl
->AclRevision
< MIN_ACL_REVISION
||
560 Acl
->AclRevision
> MAX_ACL_REVISION
)
562 return(STATUS_INVALID_PARAMETER
);
565 switch (InformationClass
)
567 case AclRevisionInformation
:
569 PACL_REVISION_INFORMATION Info
= (PACL_REVISION_INFORMATION
)Information
;
571 if (InformationLength
< sizeof(ACL_REVISION_INFORMATION
))
573 return(STATUS_BUFFER_TOO_SMALL
);
575 Info
->AclRevision
= Acl
->AclRevision
;
579 case AclSizeInformation
:
581 PACL_SIZE_INFORMATION Info
= (PACL_SIZE_INFORMATION
)Information
;
583 if (InformationLength
< sizeof(ACL_SIZE_INFORMATION
))
585 return(STATUS_BUFFER_TOO_SMALL
);
588 if (!RtlFirstFreeAce(Acl
, &Ace
))
590 return(STATUS_INVALID_PARAMETER
);
593 Info
->AceCount
= Acl
->AceCount
;
596 Info
->AclBytesInUse
= (DWORD
)((ULONG_PTR
)Ace
- (ULONG_PTR
)Acl
);
597 Info
->AclBytesFree
= Acl
->AclSize
- Info
->AclBytesInUse
;
601 Info
->AclBytesInUse
= Acl
->AclSize
;
602 Info
->AclBytesFree
= 0;
608 return(STATUS_INVALID_INFO_CLASS
);
611 return(STATUS_SUCCESS
);
619 RtlSetInformationAcl(PACL Acl
,
621 ULONG InformationLength
,
622 ACL_INFORMATION_CLASS InformationClass
)
626 if (Acl
->AclRevision
< MIN_ACL_REVISION
||
627 Acl
->AclRevision
> MAX_ACL_REVISION
)
629 return(STATUS_INVALID_PARAMETER
);
632 switch (InformationClass
)
634 case AclRevisionInformation
:
636 PACL_REVISION_INFORMATION Info
= (PACL_REVISION_INFORMATION
)Information
;
638 if (InformationLength
< sizeof(ACL_REVISION_INFORMATION
))
640 return(STATUS_BUFFER_TOO_SMALL
);
643 if (Acl
->AclRevision
>= Info
->AclRevision
)
645 return(STATUS_INVALID_PARAMETER
);
648 Acl
->AclRevision
= Info
->AclRevision
;
653 return(STATUS_INVALID_INFO_CLASS
);
656 return(STATUS_SUCCESS
);
664 RtlValidAcl (PACL Acl
)
671 Size
= ROUND_UP(Acl
->AclSize
, 4);
673 if (Acl
->AclRevision
< MIN_ACL_REVISION
||
674 Acl
->AclRevision
> MAX_ACL_REVISION
)
679 if (Size
!= Acl
->AclSize
)
684 return(RtlFirstFreeAce(Acl
, &Ace
));