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)
41 AclEnd
= (ULONG_PTR
)Acl
+ Acl
->AclSize
;
44 if ((ULONG_PTR
)Current
>= AclEnd
)
48 if (Current
->Header
.AceType
== ACCESS_ALLOWED_COMPOUND_ACE_TYPE
&&
49 Acl
->AclRevision
< ACL_REVISION3
)
53 Current
= (PACE
)((ULONG_PTR
)Current
+ Current
->Header
.AceSize
);
55 while (++i
< Acl
->AceCount
);
57 if ((ULONG_PTR
)Current
< AclEnd
)
78 if (Acl
->AclRevision
< MIN_ACL_REVISION
||
79 Acl
->AclRevision
> MAX_ACL_REVISION
||
80 AceIndex
>= Acl
->AceCount
)
82 return(STATUS_INVALID_PARAMETER
);
85 *Ace
= (PACE
)(Acl
+ 1);
87 for (i
= 0; i
< AceIndex
; i
++)
89 if ((ULONG_PTR
)*Ace
>= (ULONG_PTR
)Acl
+ Acl
->AclSize
)
91 return(STATUS_INVALID_PARAMETER
);
93 *Ace
= (PACE
)((ULONG_PTR
)(*Ace
) + (*Ace
)->Header
.AceSize
);
96 if ((ULONG_PTR
)*Ace
>= (ULONG_PTR
)Acl
+ Acl
->AclSize
)
98 return(STATUS_INVALID_PARAMETER
);
101 return(STATUS_SUCCESS
);
106 RtlpAddKnownAce (PACL Acl
,
109 ACCESS_MASK AccessMask
,
117 if (!RtlValidSid(Sid
))
119 return(STATUS_INVALID_SID
);
121 if (Acl
->AclRevision
> MAX_ACL_REVISION
||
122 Revision
> MAX_ACL_REVISION
)
124 return(STATUS_UNKNOWN_REVISION
);
126 if (Revision
< Acl
->AclRevision
)
128 Revision
= Acl
->AclRevision
;
130 if (!RtlFirstFreeAce(Acl
, &Ace
))
132 return(STATUS_INVALID_ACL
);
136 return(STATUS_ALLOTTED_SPACE_EXCEEDED
);
138 if ((ULONG_PTR
)Ace
+ RtlLengthSid(Sid
) + sizeof(ACE
) >
139 (ULONG_PTR
)Acl
+ Acl
->AclSize
)
141 return(STATUS_ALLOTTED_SPACE_EXCEEDED
);
143 Ace
->Header
.AceFlags
= Flags
;
144 Ace
->Header
.AceType
= Type
;
145 Ace
->Header
.AceSize
= RtlLengthSid(Sid
) + sizeof(ACE
);
146 Ace
->AccessMask
= AccessMask
;
147 RtlCopySid(RtlLengthSid(Sid
), (PSID
)(Ace
+ 1), Sid
);
149 Acl
->AclRevision
= Revision
;
150 return(STATUS_SUCCESS
);
158 RtlAddAccessAllowedAce (IN OUT PACL Acl
,
160 IN ACCESS_MASK AccessMask
,
165 return RtlpAddKnownAce (Acl
,
170 ACCESS_ALLOWED_ACE_TYPE
);
178 RtlAddAccessAllowedAceEx (IN OUT PACL Acl
,
181 IN ACCESS_MASK AccessMask
,
186 return RtlpAddKnownAce (Acl
,
191 ACCESS_ALLOWED_ACE_TYPE
);
199 RtlAddAccessDeniedAce (PACL Acl
,
201 ACCESS_MASK AccessMask
,
206 return RtlpAddKnownAce (Acl
,
211 ACCESS_DENIED_ACE_TYPE
);
219 RtlAddAccessDeniedAceEx (IN OUT PACL Acl
,
222 IN ACCESS_MASK AccessMask
,
227 return RtlpAddKnownAce (Acl
,
232 ACCESS_DENIED_ACE_TYPE
);
237 RtlpAddData(PVOID AceList
,
244 RtlCopyMemory((PVOID
)((ULONG_PTR
)Ace
+ AceListLength
),
249 if (AceListLength
!= 0)
275 if (Acl
->AclRevision
< MIN_ACL_REVISION
||
276 Acl
->AclRevision
> MAX_ACL_REVISION
||
277 !RtlFirstFreeAce(Acl
, &Ace
))
279 return(STATUS_INVALID_PARAMETER
);
282 if (Acl
->AclRevision
<= AclRevision
)
284 AclRevision
= Acl
->AclRevision
;
287 if (((ULONG_PTR
)AceList
+ AceListLength
) <= (ULONG_PTR
)AceList
)
289 return(STATUS_INVALID_PARAMETER
);
293 Current
= (PACE
)(Acl
+ 1);
294 while ((ULONG_PTR
)Current
< ((ULONG_PTR
)AceList
+ AceListLength
))
296 if (AceList
->Header
.AceType
== ACCESS_ALLOWED_COMPOUND_ACE_TYPE
&&
297 AclRevision
< ACL_REVISION3
)
299 return(STATUS_INVALID_PARAMETER
);
301 Current
= (PACE
)((ULONG_PTR
)Current
+ Current
->Header
.AceSize
);
305 ((ULONG_PTR
)Ace
+ AceListLength
) >= ((ULONG_PTR
)Acl
+ Acl
->AclSize
))
307 return(STATUS_BUFFER_TOO_SMALL
);
310 if (StartingIndex
!= 0)
312 if (Acl
->AceCount
> 0)
314 Current
= (PACE
)(Acl
+ 1);
315 for (j
= 0; j
< StartingIndex
; j
++)
317 Current
= (PACE
)((ULONG_PTR
)Current
+ Current
->Header
.AceSize
);
325 (ULONG
)((ULONG_PTR
)Ace
- (ULONG_PTR
)Current
));
326 Acl
->AceCount
= Acl
->AceCount
+ i
;
327 Acl
->AclRevision
= AclRevision
;
329 return(STATUS_SUCCESS
);
337 RtlAddAuditAccessAce(PACL Acl
,
339 ACCESS_MASK AccessMask
,
349 if (Success
!= FALSE
)
351 Flags
|= SUCCESSFUL_ACCESS_ACE_FLAG
;
354 if (Failure
!= FALSE
)
356 Flags
|= FAILED_ACCESS_ACE_FLAG
;
359 if (!RtlValidSid(Sid
))
361 return(STATUS_INVALID_SID
);
364 if (Acl
->AclRevision
> MAX_ACL_REVISION
||
365 Revision
> MAX_ACL_REVISION
)
367 return(STATUS_REVISION_MISMATCH
);
370 if (Revision
< Acl
->AclRevision
)
372 Revision
= Acl
->AclRevision
;
375 if (!RtlFirstFreeAce(Acl
, &Ace
))
377 return(STATUS_INVALID_ACL
);
381 ((ULONG_PTR
)Ace
+ RtlLengthSid(Sid
) + sizeof(ACE
)) > ((ULONG_PTR
)Acl
+ Acl
->AclSize
))
383 return(STATUS_ALLOTTED_SPACE_EXCEEDED
);
386 Ace
->Header
.AceFlags
= Flags
;
387 Ace
->Header
.AceType
= SYSTEM_AUDIT_ACE_TYPE
;
388 Ace
->Header
.AceSize
= RtlLengthSid(Sid
) + sizeof(ACE
);
389 Ace
->AccessMask
= AccessMask
;
390 RtlCopySid(RtlLengthSid(Sid
),
394 Acl
->AclRevision
= Revision
;
396 return(STATUS_SUCCESS
);
404 RtlAddAuditAccessAceEx(PACL Acl
,
407 ACCESS_MASK AccessMask
,
416 if (Success
!= FALSE
)
418 Flags
|= SUCCESSFUL_ACCESS_ACE_FLAG
;
421 if (Failure
!= FALSE
)
423 Flags
|= FAILED_ACCESS_ACE_FLAG
;
426 if (!RtlValidSid(Sid
))
428 return STATUS_INVALID_SID
;
431 if (Acl
->AclRevision
> MAX_ACL_REVISION
||
432 Revision
> MAX_ACL_REVISION
)
434 return STATUS_REVISION_MISMATCH
;
437 if (Revision
< Acl
->AclRevision
)
439 Revision
= Acl
->AclRevision
;
442 if (!RtlFirstFreeAce(Acl
, &Ace
))
444 return STATUS_INVALID_ACL
;
448 ((ULONG_PTR
)Ace
+ RtlLengthSid(Sid
) + sizeof(ACE
)) >= ((ULONG_PTR
)Acl
+ Acl
->AclSize
))
450 return STATUS_ALLOTTED_SPACE_EXCEEDED
;
453 Ace
->Header
.AceFlags
= Flags
;
454 Ace
->Header
.AceType
= SYSTEM_AUDIT_ACE_TYPE
;
455 Ace
->Header
.AceSize
= RtlLengthSid(Sid
) + sizeof(ACE
);
456 Ace
->AccessMask
= AccessMask
;
457 RtlCopySid(RtlLengthSid(Sid
),
461 Acl
->AclRevision
= Revision
;
463 return STATUS_SUCCESS
;
468 RtlpDeleteData(PVOID Ace
,
472 if (AceSize
< Offset
)
475 (PVOID
)((ULONG_PTR
)Ace
+ AceSize
),
479 if (Offset
- AceSize
< Offset
)
481 RtlZeroMemory((PVOID
)((ULONG_PTR
)Ace
+ Offset
- AceSize
),
491 RtlDeleteAce(PACL Acl
,
499 if (Acl
->AclRevision
< MIN_ACL_REVISION
||
500 Acl
->AclRevision
> MAX_ACL_REVISION
||
501 Acl
->AceCount
<= AceIndex
||
502 !RtlFirstFreeAce(Acl
, &Ace
))
504 return(STATUS_INVALID_PARAMETER
);
507 Current
= (PACE
)(Acl
+ 1);
511 Current
= (PACE
)((ULONG_PTR
)Current
+ Current
->Header
.AceSize
);
514 RtlpDeleteData(Current
,
515 Current
->Header
.AceSize
,
516 (ULONG
)((ULONG_PTR
)Ace
- (ULONG_PTR
)Current
));
519 return(STATUS_SUCCESS
);
527 RtlCreateAcl(PACL Acl
,
533 if (AclSize
< sizeof(ACL
))
535 return(STATUS_BUFFER_TOO_SMALL
);
538 if (AclRevision
< MIN_ACL_REVISION
||
539 AclRevision
> MAX_ACL_REVISION
||
542 return(STATUS_INVALID_PARAMETER
);
545 AclSize
= ROUND_UP(AclSize
, 4);
546 Acl
->AclSize
= AclSize
;
547 Acl
->AclRevision
= AclRevision
;
552 return(STATUS_SUCCESS
);
560 RtlQueryInformationAcl(PACL Acl
,
562 ULONG InformationLength
,
563 ACL_INFORMATION_CLASS InformationClass
)
569 if (Acl
->AclRevision
< MIN_ACL_REVISION
||
570 Acl
->AclRevision
> MAX_ACL_REVISION
)
572 return(STATUS_INVALID_PARAMETER
);
575 switch (InformationClass
)
577 case AclRevisionInformation
:
579 PACL_REVISION_INFORMATION Info
= (PACL_REVISION_INFORMATION
)Information
;
581 if (InformationLength
< sizeof(ACL_REVISION_INFORMATION
))
583 return(STATUS_BUFFER_TOO_SMALL
);
585 Info
->AclRevision
= Acl
->AclRevision
;
589 case AclSizeInformation
:
591 PACL_SIZE_INFORMATION Info
= (PACL_SIZE_INFORMATION
)Information
;
593 if (InformationLength
< sizeof(ACL_SIZE_INFORMATION
))
595 return(STATUS_BUFFER_TOO_SMALL
);
598 if (!RtlFirstFreeAce(Acl
, &Ace
))
600 return(STATUS_INVALID_PARAMETER
);
603 Info
->AceCount
= Acl
->AceCount
;
606 Info
->AclBytesInUse
= (DWORD
)((ULONG_PTR
)Ace
- (ULONG_PTR
)Acl
);
607 Info
->AclBytesFree
= Acl
->AclSize
- Info
->AclBytesInUse
;
611 Info
->AclBytesInUse
= Acl
->AclSize
;
612 Info
->AclBytesFree
= 0;
618 return(STATUS_INVALID_INFO_CLASS
);
621 return(STATUS_SUCCESS
);
629 RtlSetInformationAcl(PACL Acl
,
631 ULONG InformationLength
,
632 ACL_INFORMATION_CLASS InformationClass
)
636 if (Acl
->AclRevision
< MIN_ACL_REVISION
||
637 Acl
->AclRevision
> MAX_ACL_REVISION
)
639 return(STATUS_INVALID_PARAMETER
);
642 switch (InformationClass
)
644 case AclRevisionInformation
:
646 PACL_REVISION_INFORMATION Info
= (PACL_REVISION_INFORMATION
)Information
;
648 if (InformationLength
< sizeof(ACL_REVISION_INFORMATION
))
650 return(STATUS_BUFFER_TOO_SMALL
);
653 if (Acl
->AclRevision
>= Info
->AclRevision
)
655 return(STATUS_INVALID_PARAMETER
);
658 Acl
->AclRevision
= Info
->AclRevision
;
663 return(STATUS_INVALID_INFO_CLASS
);
666 return(STATUS_SUCCESS
);
674 RtlValidAcl (PACL Acl
)
681 Size
= ROUND_UP(Acl
->AclSize
, 4);
683 if (Acl
->AclRevision
< MIN_ACL_REVISION
||
684 Acl
->AclRevision
> MAX_ACL_REVISION
)
689 if (Size
!= Acl
->AclSize
)
694 return(RtlFirstFreeAce(Acl
, &Ace
));