Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

acledit.c File Reference

#include <ntrtlp.h>
#include <seopaque.h>

Go to the source code of this file.

Defines

#define FirstAce(Acl)   ((PVOID)((PUCHAR)(Acl) + sizeof(ACL)))
#define NextAce(Ace)   ((PVOID)((PUCHAR)(Ace) + ((PACE_HEADER)(Ace))->AceSize))
#define LongAligned(ptr)   (LongAlign(ptr) == ((PVOID)(ptr)))
#define WordAligned(ptr)   (WordAlign(ptr) == ((PVOID)(ptr)))

Functions

VOID RtlpAddData (IN PVOID From, IN ULONG FromSize, IN PVOID To, IN ULONG ToSize)
VOID RtlpDeleteData (IN PVOID Data, IN ULONG RemoveSize, IN ULONG TotalSize)
NTSTATUS RtlCreateAcl (IN PACL Acl, IN ULONG AclLength, IN ULONG AclRevision)
BOOLEAN RtlValidAcl (IN PACL Acl)
NTSTATUS RtlQueryInformationAcl (IN PACL Acl, OUT PVOID AclInformation, IN ULONG AclInformationLength, IN ACL_INFORMATION_CLASS AclInformationClass)
NTSTATUS RtlSetInformationAcl (IN PACL Acl, IN PVOID AclInformation, IN ULONG AclInformationLength, IN ACL_INFORMATION_CLASS AclInformationClass)
NTSTATUS RtlAddAce (IN OUT PACL Acl, IN ULONG AceRevision, IN ULONG StartingAceIndex, IN PVOID AceList, IN ULONG AceListLength)
NTSTATUS RtlDeleteAce (IN OUT PACL Acl, IN ULONG AceIndex)
NTSTATUS RtlGetAce (IN PACL Acl, ULONG AceIndex, OUT PVOID *Ace)
NTSTATUS RtlAddCompoundAce (IN PACL Acl, IN ULONG AceRevision, IN UCHAR CompoundAceType, IN ACCESS_MASK AccessMask, IN PSID ServerSid, IN PSID ClientSid)
NTSTATUS RtlpAddKnownAce (IN OUT PACL Acl, IN ULONG AceRevision, IN ULONG AceFlags, IN ACCESS_MASK AccessMask, IN PSID Sid, IN UCHAR NewType)
NTSTATUS RtlpAddKnownObjectAce (IN OUT PACL Acl, IN ULONG AceRevision, IN ULONG AceFlags, IN ACCESS_MASK AccessMask, IN GUID *ObjectTypeGuid OPTIONAL, IN GUID *InheritedObjectTypeGuid OPTIONAL, IN PSID Sid, IN UCHAR NewType)
NTSTATUS RtlAddAccessAllowedAce (IN OUT PACL Acl, IN ULONG AceRevision, IN ACCESS_MASK AccessMask, IN PSID Sid)
NTSTATUS RtlAddAccessAllowedAceEx (IN OUT PACL Acl, IN ULONG AceRevision, IN ULONG AceFlags, IN ACCESS_MASK AccessMask, IN PSID Sid)
NTSTATUS RtlAddAccessDeniedAce (IN OUT PACL Acl, IN ULONG AceRevision, IN ACCESS_MASK AccessMask, IN PSID Sid)
NTSTATUS RtlAddAccessDeniedAceEx (IN OUT PACL Acl, IN ULONG AceRevision, IN ULONG AceFlags, IN ACCESS_MASK AccessMask, IN PSID Sid)
NTSTATUS RtlAddAuditAccessAce (IN OUT PACL Acl, IN ULONG AceRevision, IN ACCESS_MASK AccessMask, IN PSID Sid, IN BOOLEAN AuditSuccess, IN BOOLEAN AuditFailure)
NTSTATUS RtlAddAuditAccessAceEx (IN OUT PACL Acl, IN ULONG AceRevision, IN ULONG AceFlags, IN ACCESS_MASK AccessMask, IN PSID Sid, IN BOOLEAN AuditSuccess, IN BOOLEAN AuditFailure)
NTSTATUS RtlAddAccessAllowedObjectAce (IN OUT PACL Acl, IN ULONG AceRevision, IN ULONG AceFlags, IN ACCESS_MASK AccessMask, IN GUID *ObjectTypeGuid OPTIONAL, IN GUID *InheritedObjectTypeGuid OPTIONAL, IN PSID Sid)
NTSTATUS RtlAddAccessDeniedObjectAce (IN OUT PACL Acl, IN ULONG AceRevision, IN ULONG AceFlags, IN ACCESS_MASK AccessMask, IN GUID *ObjectTypeGuid OPTIONAL, IN GUID *InheritedObjectTypeGuid OPTIONAL, IN PSID Sid)
NTSTATUS RtlAddAuditAccessObjectAce (IN OUT PACL Acl, IN ULONG AceRevision, IN ULONG AceFlags, IN ACCESS_MASK AccessMask, IN GUID *ObjectTypeGuid OPTIONAL, IN GUID *InheritedObjectTypeGuid OPTIONAL, IN PSID Sid, IN BOOLEAN AuditSuccess, IN BOOLEAN AuditFailure)
BOOLEAN RtlFirstFreeAce (IN PACL Acl, OUT PVOID *FirstFree)


Define Documentation

#define FirstAce Acl   )     ((PVOID)((PUCHAR)(Acl) + sizeof(ACL)))
 

Definition at line 42 of file acledit.c.

#define LongAligned ptr   )     (LongAlign(ptr) == ((PVOID)(ptr)))
 

Definition at line 56 of file acledit.c.

Referenced by RtlValidAcl(), and SeValidSecurityDescriptor().

#define NextAce Ace   )     ((PVOID)((PUCHAR)(Ace) + ((PACE_HEADER)(Ace))->AceSize))
 

Definition at line 54 of file acledit.c.

#define WordAligned ptr   )     (WordAlign(ptr) == ((PVOID)(ptr)))
 

Definition at line 57 of file acledit.c.

Referenced by RtlValidAcl().


Function Documentation

NTSTATUS RtlAddAccessAllowedAce IN OUT PACL  Acl,
IN ULONG  AceRevision,
IN ACCESS_MASK  AccessMask,
IN PSID  Sid
 

Definition at line 1607 of file acledit.c.

References RTL_PAGED_CODE, and RtlpAddKnownAce().

Referenced by CmpHiveRootSecurityDescriptor(), CreateBSMEventSD(), IopApplySystemPartitionProt(), ObpGetDosDevicesProtection(), RtlDefaultNpAcl(), SeMakeAnonymousLogonToken(), SeMakeSystemToken(), SepCreateImpersonationTokenDacl(), SepInitializationPhase1(), SepInitSystemDacls(), SeRmInitPhase1(), and SmbTraceStart().

01616 : 01617 01618 This routine adds an ACCESS_ALLOWED ACE to an ACL. This is 01619 expected to be a common form of ACL modification. 01620 01621 A very bland ACE header is placed in the ACE. It provides no 01622 inheritance and no ACE flags. 01623 01624 Arguments: 01625 01626 Acl - Supplies the Acl being modified 01627 01628 AceRevision - Supplies the Acl/Ace revision of the ACE being added 01629 01630 AccessMask - The mask of accesses to be granted to the specified SID. 01631 01632 Sid - Pointer to the SID being granted access. 01633 01634 Return Value: 01635 01636 STATUS_SUCCESS - The ACE was successfully added. 01637 01638 STATUS_INVALID_ACL - The specified ACL is not properly formed. 01639 01640 STATUS_REVISION_MISMATCH - The specified revision is not known 01641 or is incompatible with that of the ACL. 01642 01643 STATUS_ALLOTTED_SPACE_EXCEEDED - The new ACE does not fit into the 01644 ACL. A larger ACL buffer is required. 01645 01646 STATUS_INVALID_SID - The provided SID is not a structurally valid 01647 SID. 01648 01649 --*/ 01650 01651 { 01652 RTL_PAGED_CODE(); 01653 01654 return RtlpAddKnownAce ( 01655 Acl, 01656 AceRevision, 01657 0, // No inherit flags 01658 AccessMask, 01659 Sid, 01660 ACCESS_ALLOWED_ACE_TYPE 01661 ); 01662 }

NTSTATUS RtlAddAccessAllowedAceEx IN OUT PACL  Acl,
IN ULONG  AceRevision,
IN ULONG  AceFlags,
IN ACCESS_MASK  AccessMask,
IN PSID  Sid
 

Definition at line 1666 of file acledit.c.

References RTL_PAGED_CODE, and RtlpAddKnownAce().

Referenced by IopInitializePlugPlayServices(), and IopOpenDeviceParametersSubkey().

01676 : 01677 01678 This routine adds an ACCESS_ALLOWED ACE to an ACL. This is 01679 expected to be a common form of ACL modification. 01680 01681 Arguments: 01682 01683 Acl - Supplies the Acl being modified 01684 01685 AceRevision - Supplies the Acl/Ace revision of the ACE being added 01686 01687 AceFlags - Supplies the inherit flags for the ACE. 01688 01689 AccessMask - The mask of accesses to be granted to the specified SID. 01690 01691 Sid - Pointer to the SID being granted access. 01692 01693 Return Value: 01694 01695 STATUS_SUCCESS - The ACE was successfully added. 01696 01697 STATUS_INVALID_ACL - The specified ACL is not properly formed. 01698 01699 STATUS_REVISION_MISMATCH - The specified revision is not known 01700 or is incompatible with that of the ACL. 01701 01702 STATUS_ALLOTTED_SPACE_EXCEEDED - The new ACE does not fit into the 01703 ACL. A larger ACL buffer is required. 01704 01705 STATUS_INVALID_SID - The provided SID is not a structurally valid 01706 SID. 01707 01708 STATUS_INVALID_PARAMETER - The AceFlags parameter was invalid. 01709 01710 --*/ 01711 01712 { 01713 RTL_PAGED_CODE(); 01714 01715 return RtlpAddKnownAce ( 01716 Acl, 01717 AceRevision, 01718 AceFlags, 01719 AccessMask, 01720 Sid, 01721 ACCESS_ALLOWED_ACE_TYPE 01722 ); 01723 }

NTSTATUS RtlAddAccessAllowedObjectAce IN OUT PACL  Acl,
IN ULONG  AceRevision,
IN ULONG  AceFlags,
IN ACCESS_MASK  AccessMask,
IN GUID *ObjectTypeGuid  OPTIONAL,
IN GUID *InheritedObjectTypeGuid  OPTIONAL,
IN PSID  Sid
 

Definition at line 2008 of file acledit.c.

References NULL, RTL_PAGED_CODE, RtlpAddKnownAce(), and RtlpAddKnownObjectAce().

02020 : 02021 02022 This routine adds an object specific ACCESS_ALLOWED ACE to an ACL. This is 02023 expected to be a common form of ACL modification. 02024 02025 Arguments: 02026 02027 Acl - Supplies the Acl being modified 02028 02029 AceRevision - Supplies the Acl/Ace revision of the ACE being added 02030 02031 AceFlags - Supplies the inherit flags for the ACE. 02032 02033 AccessMask - The mask of accesses to be granted to the specified SID. 02034 02035 ObjectTypeGuid - Supplies the GUID of the object this ACE applies to. 02036 If NULL, no object type GUID is placed in the ACE. 02037 02038 InheritedObjectTypeGuid - Supplies the GUID of the object type that will 02039 inherit this ACE. If NULL, no inherited object type GUID is placed in 02040 the ACE. 02041 02042 Sid - Pointer to the SID being granted access. 02043 02044 Return Value: 02045 02046 STATUS_SUCCESS - The ACE was successfully added. 02047 02048 STATUS_INVALID_ACL - The specified ACL is not properly formed. 02049 02050 STATUS_REVISION_MISMATCH - The specified revision is not known 02051 or is incompatible with that of the ACL. 02052 02053 STATUS_ALLOTTED_SPACE_EXCEEDED - The new ACE does not fit into the 02054 ACL. A larger ACL buffer is required. 02055 02056 STATUS_INVALID_SID - The provided SID is not a structurally valid 02057 SID. 02058 02059 STATUS_INVALID_PARAMETER - The AceFlags parameter was invalid. 02060 02061 --*/ 02062 02063 { 02064 RTL_PAGED_CODE(); 02065 02066 // 02067 // If no object types are specified, 02068 // build a non-object ACE. 02069 // 02070 if (ObjectTypeGuid == NULL && InheritedObjectTypeGuid == NULL ) { 02071 return RtlpAddKnownAce ( 02072 Acl, 02073 AceRevision, 02074 AceFlags, 02075 AccessMask, 02076 Sid, 02077 ACCESS_ALLOWED_ACE_TYPE 02078 ); 02079 } 02080 02081 return RtlpAddKnownObjectAce ( 02082 Acl, 02083 AceRevision, 02084 AceFlags, 02085 AccessMask, 02086 ObjectTypeGuid, 02087 InheritedObjectTypeGuid, 02088 Sid, 02089 ACCESS_ALLOWED_OBJECT_ACE_TYPE 02090 ); 02091 }

NTSTATUS RtlAddAccessDeniedAce IN OUT PACL  Acl,
IN ULONG  AceRevision,
IN ACCESS_MASK  AccessMask,
IN PSID  Sid
 

Definition at line 1727 of file acledit.c.

References RTL_PAGED_CODE, and RtlpAddKnownAce().

01736 : 01737 01738 This routine adds an ACCESS_DENIED ACE to an ACL. This is 01739 expected to be a common form of ACL modification. 01740 01741 A very bland ACE header is placed in the ACE. It provides no 01742 inheritance and no ACE flags. 01743 01744 Arguments: 01745 01746 Acl - Supplies the Acl being modified 01747 01748 AceRevision - Supplies the Acl/Ace revision of the ACE being added 01749 01750 AccessMask - The mask of accesses to be denied to the specified SID. 01751 01752 Sid - Pointer to the SID being denied access. 01753 01754 Return Value: 01755 01756 STATUS_SUCCESS - The ACE was successfully added. 01757 01758 STATUS_INVALID_ACL - The specified ACL is not properly formed. 01759 01760 STATUS_REVISION_MISMATCH - The specified revision is not known 01761 or is incompatible with that of the ACL. 01762 01763 STATUS_ALLOTTED_SPACE_EXCEEDED - The new ACE does not fit into the 01764 ACL. A larger ACL buffer is required. 01765 01766 STATUS_INVALID_SID - The provided SID is not a structurally valid 01767 SID. 01768 01769 --*/ 01770 01771 { 01772 RTL_PAGED_CODE(); 01773 01774 return RtlpAddKnownAce ( 01775 Acl, 01776 AceRevision, 01777 0, // No inherit flags 01778 AccessMask, 01779 Sid, 01780 ACCESS_DENIED_ACE_TYPE 01781 ); 01782 01783 }

NTSTATUS RtlAddAccessDeniedAceEx IN OUT PACL  Acl,
IN ULONG  AceRevision,
IN ULONG  AceFlags,
IN ACCESS_MASK  AccessMask,
IN PSID  Sid
 

Definition at line 1787 of file acledit.c.

References RTL_PAGED_CODE, and RtlpAddKnownAce().

01797 : 01798 01799 This routine adds an ACCESS_DENIED ACE to an ACL. This is 01800 expected to be a common form of ACL modification. 01801 01802 Arguments: 01803 01804 Acl - Supplies the Acl being modified 01805 01806 AceRevision - Supplies the Acl/Ace revision of the ACE being added 01807 01808 AceFlags - Supplies the inherit flags for the ACE. 01809 01810 AccessMask - The mask of accesses to be denied to the specified SID. 01811 01812 Sid - Pointer to the SID being denied access. 01813 01814 Return Value: 01815 01816 STATUS_SUCCESS - The ACE was successfully added. 01817 01818 STATUS_INVALID_ACL - The specified ACL is not properly formed. 01819 01820 STATUS_REVISION_MISMATCH - The specified revision is not known 01821 or is incompatible with that of the ACL. 01822 01823 STATUS_ALLOTTED_SPACE_EXCEEDED - The new ACE does not fit into the 01824 ACL. A larger ACL buffer is required. 01825 01826 STATUS_INVALID_SID - The provided SID is not a structurally valid 01827 SID. 01828 01829 STATUS_INVALID_PARAMETER - The AceFlags parameter was invalid. 01830 01831 --*/ 01832 01833 { 01834 RTL_PAGED_CODE(); 01835 01836 return RtlpAddKnownAce ( 01837 Acl, 01838 AceRevision, 01839 AceFlags, 01840 AccessMask, 01841 Sid, 01842 ACCESS_DENIED_ACE_TYPE 01843 ); 01844 01845 }

NTSTATUS RtlAddAccessDeniedObjectAce IN OUT PACL  Acl,
IN ULONG  AceRevision,
IN ULONG  AceFlags,
IN ACCESS_MASK  AccessMask,
IN GUID *ObjectTypeGuid  OPTIONAL,
IN GUID *InheritedObjectTypeGuid  OPTIONAL,
IN PSID  Sid
 

Definition at line 2095 of file acledit.c.

References NULL, RTL_PAGED_CODE, RtlpAddKnownAce(), and RtlpAddKnownObjectAce().

02107 : 02108 02109 This routine adds an object specific ACCESS_DENIED ACE to an ACL. This is 02110 expected to be a common form of ACL modification. 02111 02112 Arguments: 02113 02114 Acl - Supplies the Acl being modified 02115 02116 AceRevision - Supplies the Acl/Ace revision of the ACE being added 02117 02118 AceFlags - Supplies the inherit flags for the ACE. 02119 02120 AccessMask - The mask of accesses to be granted to the specified SID. 02121 02122 ObjectTypeGuid - Supplies the GUID of the object this ACE applies to. 02123 If NULL, no object type GUID is placed in the ACE. 02124 02125 InheritedObjectTypeGuid - Supplies the GUID of the object type that will 02126 inherit this ACE. If NULL, no inherited object type GUID is placed in 02127 the ACE. 02128 02129 Sid - Pointer to the SID being denied access. 02130 02131 Return Value: 02132 02133 STATUS_SUCCESS - The ACE was successfully added. 02134 02135 STATUS_INVALID_ACL - The specified ACL is not properly formed. 02136 02137 STATUS_REVISION_MISMATCH - The specified revision is not known 02138 or is incompatible with that of the ACL. 02139 02140 STATUS_ALLOTTED_SPACE_EXCEEDED - The new ACE does not fit into the 02141 ACL. A larger ACL buffer is required. 02142 02143 STATUS_INVALID_SID - The provided SID is not a structurally valid 02144 SID. 02145 02146 STATUS_INVALID_PARAMETER - The AceFlags parameter was invalid. 02147 02148 --*/ 02149 02150 { 02151 RTL_PAGED_CODE(); 02152 02153 // 02154 // If no object types are specified, 02155 // build a non-object ACE. 02156 // 02157 if (ObjectTypeGuid == NULL && InheritedObjectTypeGuid == NULL ) { 02158 return RtlpAddKnownAce ( 02159 Acl, 02160 AceRevision, 02161 AceFlags, 02162 AccessMask, 02163 Sid, 02164 ACCESS_DENIED_ACE_TYPE 02165 ); 02166 } 02167 02168 return RtlpAddKnownObjectAce ( 02169 Acl, 02170 AceRevision, 02171 AceFlags, 02172 AccessMask, 02173 ObjectTypeGuid, 02174 InheritedObjectTypeGuid, 02175 Sid, 02176 ACCESS_DENIED_OBJECT_ACE_TYPE 02177 ); 02178 }

NTSTATUS RtlAddAce IN OUT PACL  Acl,
IN ULONG  AceRevision,
IN ULONG  StartingAceIndex,
IN PVOID  AceList,
IN ULONG  AceListLength
 

Definition at line 718 of file acledit.c.

References FirstAce, NextAce, NULL, RTL_PAGED_CODE, RtlFirstFreeAce(), RtlpAddData(), RtlValidAcl(), and USHORT.

Referenced by CreateDAclToken(), CreateSecurityDescriptor(), GenerateDescriptor(), IopOpenDeviceParametersSubkey(), main(), RtlCreateAndSetSD(), TestAddAce(), and TestSeAclRtl().

00728 : 00729 00730 This routine adds a string of ACEs to an ACL. 00731 00732 Arguments: 00733 00734 Acl - Supplies the Acl being modified 00735 00736 AceRevision - Supplies the Acl/Ace revision of the ACE being added 00737 00738 StartingAceIndex - Supplies the ACE index which will be the index of 00739 the first ace inserted in the acl. 0 for the beginning of the list 00740 and MAXULONG for the end of the list. 00741 00742 AceList - Supplies the list of Aces to be added to the Acl 00743 00744 AceListLength - Supplies the size, in bytes, of the AceList buffer 00745 00746 Return Value: 00747 00748 NTSTATUS - STATUS_SUCCESS if successful, and an appropriate error 00749 status otherwise 00750 00751 --*/ 00752 00753 { 00754 PVOID FirstFree; 00755 00756 PACE_HEADER Ace; 00757 ULONG NewAceCount; 00758 00759 PVOID AcePosition; 00760 ULONG i; 00761 UCHAR NewRevision; 00762 00763 RTL_PAGED_CODE(); 00764 00765 // 00766 // Check the ACL structure 00767 // 00768 00769 if (!RtlValidAcl(Acl)) { 00770 00771 return STATUS_INVALID_PARAMETER; 00772 00773 } 00774 00775 // 00776 // Locate the first free ace and check to see that the Acl is 00777 // well formed. 00778 // 00779 00780 if (!RtlFirstFreeAce( Acl, &FirstFree )) { 00781 00782 return STATUS_INVALID_PARAMETER; 00783 00784 } 00785 00786 // 00787 // If the AceRevision is greater than the ACL revision, then we want to 00788 // increase the ACL revision to be the same as the new ACE revision. 00789 // We can do this because our previously defined ACE types ( 0 -> 3 ) have 00790 // not changed structure nor been discontinued in the new revision. So 00791 // we can bump the revision and the older types will not be misinterpreted. 00792 // 00793 // Compute what the final revision of the ACL is going to be, and save it 00794 // for later so we can update it once we know we're going to succeed. 00795 // 00796 00797 NewRevision = (UCHAR)AceRevision > Acl->AclRevision ? (UCHAR)AceRevision : Acl->AclRevision; 00798 00799 // 00800 // Check that the AceList is well formed, we do this by simply zooming 00801 // down the Ace list until we're equal to or have exceeded the ace list 00802 // length. If we are equal to the length then we're well formed otherwise 00803 // we're ill-formed. We'll also calculate how many Ace's there are 00804 // in the AceList 00805 // 00806 // In addition, now we have to make sure that we haven't been handed an 00807 // ACE type that is inappropriate for the AceRevision that was passed 00808 // in. 00809 // 00810 00811 for (Ace = AceList, NewAceCount = 0; 00812 Ace < (PACE_HEADER)((PUCHAR)AceList + AceListLength); 00813 Ace = NextAce( Ace ), NewAceCount++) { 00814 00815 // 00816 // Ensure the ACL revision allows this ACE type. 00817 // 00818 00819 if ( Ace->AceType <= ACCESS_MAX_MS_V2_ACE_TYPE ) { 00820 // V2 ACE are always valid. 00821 } else if ( Ace->AceType <= ACCESS_MAX_MS_V3_ACE_TYPE ) { 00822 if ( AceRevision < ACL_REVISION3 ) { 00823 return STATUS_INVALID_PARAMETER; 00824 } 00825 } else if ( Ace->AceType <= ACCESS_MAX_MS_V4_ACE_TYPE ) { 00826 if ( AceRevision < ACL_REVISION4 ) { 00827 return STATUS_INVALID_PARAMETER; 00828 } 00829 } 00830 } 00831 00832 // 00833 // Check to see if we've exceeded the ace list length 00834 // 00835 00836 if (Ace > (PACE_HEADER)((PUCHAR)AceList + AceListLength)) { 00837 00838 return STATUS_INVALID_PARAMETER; 00839 00840 } 00841 00842 // 00843 // Check to see if there is enough room in the Acl to store the additional 00844 // Ace list 00845 // 00846 00847 if (FirstFree == NULL || 00848 (PUCHAR)FirstFree + AceListLength > (PUCHAR)Acl + Acl->AclSize) { 00849 00850 return STATUS_BUFFER_TOO_SMALL; 00851 00852 } 00853 00854 // 00855 // All of the input has checked okay, we now need to locate the position 00856 // where to insert the new ace list. We won't check the acl for 00857 // validity because we did earlier when got the first free ace position. 00858 // 00859 00860 AcePosition = FirstAce( Acl ); 00861 00862 for (i = 0; i < StartingAceIndex && i < Acl->AceCount; i++) { 00863 00864 AcePosition = NextAce( AcePosition ); 00865 00866 } 00867 00868 // 00869 // Now Ace points to where we want to insert the ace list, We do the 00870 // insertion by adding ace list to the acl and shoving over the remainder 00871 // of the list down the acl. We know this will work because we earlier 00872 // check to make sure the new acl list will fit in the acl size 00873 // 00874 00875 RtlpAddData( AceList, AceListLength, 00876 AcePosition, (ULONG) ((PUCHAR)FirstFree - (PUCHAR)AcePosition)); 00877 00878 // 00879 // Update the Acl Header 00880 // 00881 00882 Acl->AceCount = (USHORT)(Acl->AceCount + NewAceCount); 00883 00884 Acl->AclRevision = NewRevision; 00885 00886 // 00887 // And return to our caller 00888 // 00889 00890 return STATUS_SUCCESS; 00891 }

NTSTATUS RtlAddAuditAccessAce IN OUT PACL  Acl,
IN ULONG  AceRevision,
IN ACCESS_MASK  AccessMask,
IN PSID  Sid,
IN BOOLEAN  AuditSuccess,
IN BOOLEAN  AuditFailure
 

Definition at line 1849 of file acledit.c.

References RTL_PAGED_CODE, and RtlpAddKnownAce().

Referenced by ObInitSystem().

01860 : 01861 01862 This routine adds a SYSTEM_AUDIT ACE to an ACL. This is 01863 expected to be a common form of ACL modification. 01864 01865 A very bland ACE header is placed in the ACE. It provides no 01866 inheritance. 01867 01868 Parameters are used to indicate whether auditing is to be performed 01869 on success, failure, or both. 01870 01871 Arguments: 01872 01873 Acl - Supplies the Acl being modified 01874 01875 AceRevision - Supplies the Acl/Ace revision of the ACE being added 01876 01877 AccessMask - The mask of accesses to be denied to the specified SID. 01878 01879 Sid - Pointer to the SID to be audited. 01880 01881 AuditSuccess - If TRUE, indicates successful access attempts are to be 01882 audited. 01883 01884 AuditFailure - If TRUE, indicated failed access attempts are to be 01885 audited. 01886 01887 Return Value: 01888 01889 STATUS_SUCCESS - The ACE was successfully added. 01890 01891 STATUS_INVALID_ACL - The specified ACL is not properly formed. 01892 01893 STATUS_REVISION_MISMATCH - The specified revision is not known 01894 or is incompatible with that of the ACL. 01895 01896 STATUS_ALLOTTED_SPACE_EXCEEDED - The new ACE does not fit into the 01897 ACL. A larger ACL buffer is required. 01898 01899 STATUS_INVALID_SID - The provided SID is not a structurally valid 01900 SID. 01901 01902 --*/ 01903 01904 { 01905 ULONG AceFlags = 0; 01906 RTL_PAGED_CODE(); 01907 01908 if (AuditSuccess) { 01909 AceFlags |= SUCCESSFUL_ACCESS_ACE_FLAG; 01910 } 01911 if (AuditFailure) { 01912 AceFlags |= FAILED_ACCESS_ACE_FLAG; 01913 } 01914 01915 return RtlpAddKnownAce ( 01916 Acl, 01917 AceRevision, 01918 AceFlags, 01919 AccessMask, 01920 Sid, 01921 SYSTEM_AUDIT_ACE_TYPE ); 01922 01923 }

NTSTATUS RtlAddAuditAccessAceEx IN OUT PACL  Acl,
IN ULONG  AceRevision,
IN ULONG  AceFlags,
IN ACCESS_MASK  AccessMask,
IN PSID  Sid,
IN BOOLEAN  AuditSuccess,
IN BOOLEAN  AuditFailure
 

Definition at line 1926 of file acledit.c.

References RTL_PAGED_CODE, and RtlpAddKnownAce().

01938 : 01939 01940 This routine adds a SYSTEM_AUDIT ACE to an ACL. This is 01941 expected to be a common form of ACL modification. 01942 01943 A very bland ACE header is placed in the ACE. It provides no 01944 inheritance. 01945 01946 Parameters are used to indicate whether auditing is to be performed 01947 on success, failure, or both. 01948 01949 Arguments: 01950 01951 Acl - Supplies the Acl being modified 01952 01953 AceRevision - Supplies the Acl/Ace revision of the ACE being added 01954 01955 AceFlags - Supplies the inherit flags for the ACE. 01956 01957 AccessMask - The mask of accesses to be denied to the specified SID. 01958 01959 Sid - Pointer to the SID to be audited. 01960 01961 AuditSuccess - If TRUE, indicates successful access attempts are to be 01962 audited. 01963 01964 AuditFailure - If TRUE, indicated failed access attempts are to be 01965 audited. 01966 01967 Return Value: 01968 01969 STATUS_SUCCESS - The ACE was successfully added. 01970 01971 STATUS_INVALID_ACL - The specified ACL is not properly formed. 01972 01973 STATUS_REVISION_MISMATCH - The specified revision is not known 01974 or is incompatible with that of the ACL. 01975 01976 STATUS_ALLOTTED_SPACE_EXCEEDED - The new ACE does not fit into the 01977 ACL. A larger ACL buffer is required. 01978 01979 STATUS_INVALID_SID - The provided SID is not a structurally valid 01980 SID. 01981 01982 STATUS_INVALID_PARAMETER - The AceFlags parameter was invalid. 01983 01984 --*/ 01985 01986 { 01987 RTL_PAGED_CODE(); 01988 01989 if (AuditSuccess) { 01990 AceFlags |= SUCCESSFUL_ACCESS_ACE_FLAG; 01991 } 01992 if (AuditFailure) { 01993 AceFlags |= FAILED_ACCESS_ACE_FLAG; 01994 } 01995 01996 return RtlpAddKnownAce ( 01997 Acl, 01998 AceRevision, 01999 AceFlags, 02000 AccessMask, 02001 Sid, 02002 SYSTEM_AUDIT_ACE_TYPE ); 02003 02004 }

NTSTATUS RtlAddAuditAccessObjectAce IN OUT PACL  Acl,
IN ULONG  AceRevision,
IN ULONG  AceFlags,
IN ACCESS_MASK  AccessMask,
IN GUID *ObjectTypeGuid  OPTIONAL,
IN GUID *InheritedObjectTypeGuid  OPTIONAL,
IN PSID  Sid,
IN BOOLEAN  AuditSuccess,
IN BOOLEAN  AuditFailure
 

Definition at line 2182 of file acledit.c.

References NULL, RTL_PAGED_CODE, RtlpAddKnownAce(), and RtlpAddKnownObjectAce().

02196 : 02197 02198 This routine adds an object specific ACCESS_DENIED ACE to an ACL. This is 02199 expected to be a common form of ACL modification. 02200 02201 Arguments: 02202 02203 Acl - Supplies the Acl being modified 02204 02205 AceRevision - Supplies the Acl/Ace revision of the ACE being added 02206 02207 AceFlags - Supplies the inherit flags for the ACE. 02208 02209 AccessMask - The mask of accesses to be granted to the specified SID. 02210 02211 ObjectTypeGuid - Supplies the GUID of the object this ACE applies to. 02212 If NULL, no object type GUID is placed in the ACE. 02213 02214 InheritedObjectTypeGuid - Supplies the GUID of the object type that will 02215 inherit this ACE. If NULL, no inherited object type GUID is placed in 02216 the ACE. 02217 02218 Sid - Pointer to the SID to be audited. 02219 02220 AuditSuccess - If TRUE, indicates successful access attempts are to be 02221 audited. 02222 02223 AuditFailure - If TRUE, indicated failed access attempts are to be 02224 audited. 02225 02226 Return Value: 02227 02228 STATUS_SUCCESS - The ACE was successfully added. 02229 02230 STATUS_INVALID_ACL - The specified ACL is not properly formed. 02231 02232 STATUS_REVISION_MISMATCH - The specified revision is not known 02233 or is incompatible with that of the ACL. 02234 02235 STATUS_ALLOTTED_SPACE_EXCEEDED - The new ACE does not fit into the 02236 ACL. A larger ACL buffer is required. 02237 02238 STATUS_INVALID_SID - The provided SID is not a structurally valid 02239 SID. 02240 02241 STATUS_INVALID_PARAMETER - The AceFlags parameter was invalid. 02242 02243 --*/ 02244 02245 { 02246 RTL_PAGED_CODE(); 02247 02248 if (AuditSuccess) { 02249 AceFlags |= SUCCESSFUL_ACCESS_ACE_FLAG; 02250 } 02251 if (AuditFailure) { 02252 AceFlags |= FAILED_ACCESS_ACE_FLAG; 02253 } 02254 02255 // 02256 // If no object types are specified, 02257 // build a non-object ACE. 02258 // 02259 if (ObjectTypeGuid == NULL && InheritedObjectTypeGuid == NULL ) { 02260 return RtlpAddKnownAce ( 02261 Acl, 02262 AceRevision, 02263 AceFlags, 02264 AccessMask, 02265 Sid, 02266 SYSTEM_AUDIT_ACE_TYPE 02267 ); 02268 } 02269 02270 return RtlpAddKnownObjectAce ( 02271 Acl, 02272 AceRevision, 02273 AceFlags, 02274 AccessMask, 02275 ObjectTypeGuid, 02276 InheritedObjectTypeGuid, 02277 Sid, 02278 SYSTEM_AUDIT_OBJECT_ACE_TYPE 02279 ); 02280 }

NTSTATUS RtlAddCompoundAce IN PACL  Acl,
IN ULONG  AceRevision,
IN UCHAR  CompoundAceType,
IN ACCESS_MASK  AccessMask,
IN PSID  ServerSid,
IN PSID  ClientSid
 

Definition at line 1098 of file acledit.c.

References NULL, RTL_PAGED_CODE, RtlCopySid(), RtlFirstFreeAce(), RtlValidAcl(), RtlValidSid(), SeLengthSid, and USHORT.

01109 : 01110 01111 This routine adds a KNOWN_COMPOUND_ACE to an ACL. This is 01112 expected to be a common form of ACL modification. 01113 01114 Arguments: 01115 01116 Acl - Supplies the Acl being modified 01117 01118 AceRevision - Supplies the Acl/Ace revision of the ACE being added 01119 01120 CompoundAceType - Supplies the type of compound ACE being added. 01121 Currently the only defined type is COMPOUND_ACE_IMPERSONATION. 01122 01123 AccessMask - The mask of accesses to be granted to the specified SID pair. 01124 01125 ServerSid - Pointer to the Server SID to be placed in the ACE. 01126 01127 ClientSid - Pointer to the Client SID to be placed in the ACE. 01128 01129 Return Value: 01130 01131 NTSTATUS - STATUS_SUCCESS if successful and an appropriate error 01132 status otherwise 01133 01134 STATUS_INVALID_PARAMETER - The AceFlags parameter was invalid. 01135 01136 --*/ 01137 01138 01139 01140 01141 { 01142 PVOID FirstFree; 01143 USHORT AceSize; 01144 PKNOWN_COMPOUND_ACE GrantAce; 01145 UCHAR NewRevision; 01146 01147 RTL_PAGED_CODE(); 01148 01149 // 01150 // Validate the structure of the SID 01151 // 01152 01153 if (!RtlValidSid(ServerSid) || !RtlValidSid(ClientSid)) { 01154 return STATUS_INVALID_SID; 01155 } 01156 01157 // 01158 // Check the ACL & ACE revision levels 01159 // Compund ACEs become valid in version 3. 01160 // 01161 01162 if ( Acl->AclRevision > ACL_REVISION4 || 01163 AceRevision < ACL_REVISION3 || 01164 AceRevision > ACL_REVISION4 ) { 01165 return STATUS_REVISION_MISMATCH; 01166 } 01167 01168 // 01169 // Calculate the new revision of the ACL. The new revision is the maximum 01170 // of the old revision and and new ACE's revision. This is possible because 01171 // the format of previously defined ACEs did not change across revisions. 01172 // 01173 01174 NewRevision = Acl->AclRevision > (UCHAR)AceRevision ? Acl->AclRevision : (UCHAR)AceRevision; 01175 01176 // 01177 // Locate the first free ace and check to see that the Acl is 01178 // well formed. 01179 // 01180 01181 if (!RtlValidAcl( Acl )) { 01182 return STATUS_INVALID_ACL; 01183 } 01184 01185 if (!RtlFirstFreeAce( Acl, &FirstFree )) { 01186 01187 return STATUS_INVALID_ACL; 01188 } 01189 01190 // 01191 // Check to see if there is enough room in the Acl to store the new 01192 // ACE 01193 // 01194 01195 AceSize = (USHORT)(sizeof(KNOWN_COMPOUND_ACE) - 01196 sizeof(ULONG) + 01197 SeLengthSid(ClientSid) + 01198 SeLengthSid(ServerSid) 01199 ); 01200 01201 if ( FirstFree == NULL || 01202 ((PUCHAR)FirstFree + AceSize > ((PUCHAR)Acl + Acl->AclSize)) 01203 ) { 01204 01205 return STATUS_ALLOTTED_SPACE_EXCEEDED; 01206 } 01207 01208 // 01209 // Add the ACE to the end of the ACL 01210 // 01211 01212 GrantAce = (PKNOWN_COMPOUND_ACE)FirstFree; 01213 GrantAce->Header.AceFlags = 0; 01214 GrantAce->Header.AceType = ACCESS_ALLOWED_COMPOUND_ACE_TYPE; 01215 GrantAce->Header.AceSize = AceSize; 01216 GrantAce->Mask = AccessMask; 01217 GrantAce->CompoundAceType = CompoundAceType; 01218 RtlCopySid( SeLengthSid(ServerSid), (PSID)(&GrantAce->SidStart), ServerSid ); 01219 RtlCopySid( SeLengthSid(ClientSid), (PSID)(((PCHAR)&GrantAce->SidStart) + SeLengthSid(ServerSid)), ClientSid ); 01220 01221 // 01222 // Increment the number of ACEs by 1. 01223 // 01224 01225 Acl->AceCount += 1; 01226 01227 // 01228 // Adjust the Acl revision, if necessary 01229 // 01230 01231 Acl->AclRevision = NewRevision; 01232 01233 // 01234 // And return to our caller 01235 // 01236 01237 return STATUS_SUCCESS; 01238 }

NTSTATUS RtlCreateAcl IN PACL  Acl,
IN ULONG  AclLength,
IN ULONG  AclRevision
 

Definition at line 99 of file acledit.c.

References RTL_PAGED_CODE, and USHORT.

Referenced by CmpHiveRootSecurityDescriptor(), CreateBSMEventSD(), CreateDAclToken(), CreateSecurityDescriptor(), GenerateDescriptor(), IopApplySystemPartitionProt(), IopInitializePlugPlayServices(), IopOpenDeviceParametersSubkey(), main(), ObInitSystem(), ObpGetDosDevicesProtection(), RtlCreateAndSetSD(), RtlDefaultNpAcl(), RtlpComputeMergedAcl2(), RtlpConvertAclToAutoInherit(), RtlpCreateServerAcl(), RtlpInheritAcl2(), SeMakeAnonymousLogonToken(), SeMakeSystemToken(), SepCreateImpersonationTokenDacl(), SepInitializationPhase1(), SepInitSystemDacls(), SeRmInitPhase1(), SmbTraceStart(), TestAddAce(), TestCreateAcl(), TestSeAclRtl(), TestTokenAssignPrimary(), TestTokenCreate(), and TestTokenSet().

00107 : 00108 00109 This routine initializes an ACL data structure. After initialization 00110 it is an ACL with no ACE (i.e., a deny all access type ACL) 00111 00112 Arguments: 00113 00114 Acl - Supplies the buffer containing the ACL being initialized 00115 00116 AclLength - Supplies the length of the ace buffer in bytes 00117 00118 AclRevision - Supplies the revision for this Acl 00119 00120 Return Value: 00121 00122 NTSTATUS - STATUS_SUCCESS if successful 00123 00124 STATUS_BUFFER_TOO_SMALL if the AclLength is too small, 00125 00126 STATUS_INVALID_PARAMETER if the revision is out of range 00127 00128 --*/ 00129 00130 { 00131 RTL_PAGED_CODE(); 00132 00133 // 00134 // Check to see the size of the buffer is large enough to hold at 00135 // least the ACL header 00136 // 00137 00138 if (AclLength < sizeof(ACL)) { 00139 00140 // 00141 // Buffer to small even for the ACL header 00142 // 00143 00144 return STATUS_BUFFER_TOO_SMALL; 00145 00146 } 00147 00148 // 00149 // Check to see if the revision is currently valid. Later versions 00150 // of this procedure might accept more revision levels 00151 // 00152 00153 if (AclRevision < MIN_ACL_REVISION || AclRevision > MAX_ACL_REVISION) { 00154 00155 // 00156 // Revision not current 00157 // 00158 00159 return STATUS_INVALID_PARAMETER; 00160 00161 } 00162 00163 if ( AclLength > MAXUSHORT ) { 00164 00165 return STATUS_INVALID_PARAMETER; 00166 } 00167 00168 // 00169 // Initialize the ACL 00170 // 00171 00172 Acl->AclRevision = (UCHAR)AclRevision; // Used to hardwire ACL_REVISION2 here 00173 Acl->Sbz1 = 0; 00174 Acl->AclSize = (USHORT) (AclLength & 0xfffc); 00175 Acl->AceCount = 0; 00176 Acl->Sbz2 = 0; 00177 00178 // 00179 // And return to our caller 00180 // 00181 00182 return STATUS_SUCCESS; 00183 }

NTSTATUS RtlDeleteAce IN OUT PACL  Acl,
IN ULONG  AceIndex
 

Definition at line 895 of file acledit.c.

References FirstAce, NextAce, RTL_PAGED_CODE, RtlFirstFreeAce(), RtlpDeleteData(), and RtlValidAcl().

Referenced by CreateDAclToken(), main(), TestDeleteAce(), and TestSeAclRtl().

00902 : 00903 00904 This routine deletes one ACE from an ACL. 00905 00906 Arguments: 00907 00908 Acl - Supplies the Acl being modified 00909 00910 AceIndex - Supplies the index of the Ace to delete. 00911 00912 Return Value: 00913 00914 NTSTATUS - STATUS_SUCCESS if successful and an appropriate error 00915 status otherwise 00916 00917 --*/ 00918 00919 { 00920 PVOID FirstFree; 00921 00922 PACE_HEADER Ace; 00923 ULONG i; 00924 00925 RTL_PAGED_CODE(); 00926 00927 // 00928 // Check the ACL structure 00929 // 00930 00931 if (!RtlValidAcl(Acl)) { 00932 00933 return STATUS_INVALID_PARAMETER; 00934 00935 } 00936 00937 // 00938 // Make sure the AceIndex is within proper range, it's ulong so we know 00939 // it can't be negative 00940 // 00941 00942 if (AceIndex >= Acl->AceCount) { 00943 00944 return STATUS_INVALID_PARAMETER; 00945 00946 } 00947 00948 // 00949 // Locate the first free spot, this will tell us how much data 00950 // we'll need to colapse. If the results is false then the acl is 00951 // ill-formed 00952 // 00953 00954 if (!RtlFirstFreeAce( Acl, &FirstFree )) { 00955 00956 return STATUS_INVALID_PARAMETER; 00957 00958 } 00959 00960 // 00961 // Now locate the ace that we're going to delete. This loop 00962 // doesn't need to check the acl for being well formed. 00963 // 00964 00965 Ace = FirstAce( Acl ); 00966 00967 for (i = 0; i < AceIndex; i++) { 00968 00969 Ace = NextAce( Ace ); 00970 00971 } 00972 00973 // 00974 // We've found the ace to delete to simply copy over the rest of 00975 // the acl over this ace. The delete data procedure also deletes 00976 // rest of the string that it's moving over so we don't have to 00977 // 00978 00979 RtlpDeleteData( Ace, Ace->AceSize, (ULONG) ((PUCHAR)FirstFree - (PUCHAR)Ace)); 00980 00981 // 00982 // Update the Acl header 00983 // 00984 00985 Acl->AceCount--; 00986 00987 // 00988 // And return to our caller 00989 // 00990 00991 return STATUS_SUCCESS; 00992 }

BOOLEAN RtlFirstFreeAce IN PACL  Acl,
OUT PVOID *  FirstFree
 

Definition at line 2599 of file acledit.c.

References FALSE, FirstAce, NextAce, NULL, RTL_PAGED_CODE, and TRUE.

Referenced by RtlAddAce(), RtlAddCompoundAce(), RtlDeleteAce(), RtlpAddKnownAce(), RtlpAddKnownObjectAce(), RtlpCopyAces(), RtlpGenerateInheritedAce(), RtlpInheritAcl2(), and RtlQueryInformationAcl().

02606 : 02607 02608 This routine returns a pointer to the first free byte in an Acl 02609 or NULL if the acl is ill-formed. If the Acl is full then the 02610 return pointer is to the byte immediately following the acl, and 02611 TRUE will be returned. 02612 02613 Arguments: 02614 02615 Acl - Supplies a pointer to the Acl to examine 02616 02617 FirstFree - Receives a pointer to the first free position in the Acl 02618 02619 Return Value: 02620 02621 BOOLEAN - TRUE if the Acl is well formed and FALSE otherwise 02622 02623 --*/ 02624 02625 { 02626 PACE_HEADER Ace; 02627 ULONG i; 02628 02629 RTL_PAGED_CODE(); 02630 02631 // 02632 // To find the first free spot in the Acl we need to search for 02633 // the last ace. We do this by zooming down the list until 02634 // we've exhausted the ace count or the ace size (which ever comes 02635 // first). In the following loop Ace points to the next spot 02636 // for an Ace and I is the ace index 02637 // 02638 02639 *FirstFree = NULL; 02640 02641 for ( i=0, Ace = FirstAce( Acl ); 02642 i < Acl->AceCount; 02643 i++, Ace = NextAce( Ace )) { 02644 02645 // 02646 // Check to make sure we haven't overrun the Acl buffer 02647 // with our Ace pointer. If we have then our input is bogus. 02648 // 02649 02650 if (Ace >= (PACE_HEADER)((PUCHAR)Acl + Acl->AclSize)) { 02651 02652 return FALSE; 02653 02654 } 02655 02656 } 02657 02658 // 02659 // Now Ace points to the first free spot in the Acl so set the 02660 // output variable and check to make sure it is still in the Acl 02661 // or just one beyond the end of the acl (i.e., the acl is full). 02662 // 02663 02664 if (Ace <= (PACE_HEADER)((PUCHAR)Acl + Acl->AclSize)) { 02665 02666 *FirstFree = Ace; 02667 } 02668 02669 // 02670 // The Acl is well formed so return the first free spot we've found 02671 // (or NULL if there is no free space for another ACE) 02672 // 02673 02674 return TRUE; 02675 02676 }

NTSTATUS RtlGetAce IN PACL  Acl,
ULONG  AceIndex,
OUT PVOID *  Ace
 

Definition at line 996 of file acledit.c.

References FirstAce, NextAce, and RTL_PAGED_CODE.

Referenced by CmpHiveRootSecurityDescriptor(), IopCreateDefaultDeviceSecurityDescriptor(), IopOpenDeviceParametersSubkey(), main(), ObInitSystem(), ObpGetDosDevicesProtection(), TestGetAce(), and TestSeAclRtl().

01004 : 01005 01006 This routine returns a pointer to an ACE in an ACl referenced by 01007 ACE index 01008 01009 Arguments: 01010 01011 Acl - Supplies the ACL being queried 01012 01013 AceIndex - Supplies the Ace index to locate 01014 01015 Ace - Receives the address of the ACE within the ACL 01016 01017 Return Value: 01018 01019 NTSTATUS - STATUS_SUCCESS if successful and an appropriate error 01020 status otherwise 01021 01022 --*/ 01023 01024 { 01025 ULONG i; 01026 01027 RTL_PAGED_CODE(); 01028 01029 // 01030 // Check the ACL revision level 01031 // 01032 01033 if (!ValidAclRevision(Acl)) { 01034 01035 return STATUS_INVALID_PARAMETER; 01036 01037 } 01038 01039 // 01040 // Check the AceIndex against the Ace count of the Acl, it's ulong so 01041 // we know it can't be negative 01042 // 01043 01044 if (AceIndex >= Acl->AceCount) { 01045 01046 return STATUS_INVALID_PARAMETER; 01047 01048 } 01049 01050 // 01051 // To find the Ace requested by zooming down the Ace List. 01052 // 01053 01054 *Ace = FirstAce( Acl ); 01055 01056 for (i = 0; i < AceIndex; i++) { 01057 01058 // 01059 // Check to make sure we haven't overrun the Acl buffer 01060 // with our ace pointer. If we have then our input is bogus 01061 // 01062 01063 if (*Ace >= (PVOID)((PUCHAR)Acl + Acl->AclSize)) { 01064 01065 return STATUS_INVALID_PARAMETER; 01066 01067 } 01068 01069 // 01070 // And move Ace to the next ace position 01071 // 01072 01073 *Ace = NextAce( *Ace ); 01074 01075 } 01076 01077 // 01078 // Now Ace points to the Ace we're after, but make sure we aren't 01079 // beyond the Acl. 01080 // 01081 01082 if (*Ace >= (PVOID)((PUCHAR)Acl + Acl->AclSize)) { 01083 01084 return STATUS_INVALID_PARAMETER; 01085 01086 } 01087 01088 // 01089 // The Ace is still within the Acl so return success to our caller 01090 // 01091 01092 return STATUS_SUCCESS; 01093 01094 }

VOID RtlpAddData IN PVOID  From,
IN ULONG  FromSize,
IN PVOID  To,
IN ULONG  ToSize
 

Definition at line 2684 of file acledit.c.

Referenced by RtlAddAce().

02693 : 02694 02695 This routine copies data to a string of bytes. It does this by moving 02696 over data in the to string so that the from string will fit. It also 02697 assumes that the checks that the data will fit in memory have already 02698 been done. Pictorally the results are as follows. 02699 02700 Before: 02701 02702 From -> ffffffffff 02703 02704 To -> tttttttttttttttt 02705 02706 After: 02707 02708 From -> ffffffffff 02709 02710 To -> fffffffffftttttttttttttttt 02711 02712 Arguments: 02713 02714 From - Supplies a pointer to the source buffer 02715 02716 FromSize - Supplies the size of the from buffer in bytes 02717 02718 To - Supplies a pointer to the destination buffer 02719 02720 ToSize - Supplies the size of the to buffer in bytes 02721 02722 Return Value: 02723 02724 None 02725 02726 --*/ 02727 02728 { 02729 LONG i; 02730 02731 // 02732 // Shift over the To buffer enough to fit in the From buffer 02733 // 02734 02735 for (i = ToSize - 1; i >= 0; i--) { 02736 02737 ((PUCHAR)To)[i+FromSize] = ((PUCHAR)To)[i]; 02738 } 02739 02740 // 02741 // Now copy over the From buffer 02742 // 02743 02744 for (i = 0; (ULONG)i < FromSize; i += 1) { 02745 02746 ((PUCHAR)To)[i] = ((PUCHAR)From)[i]; 02747 02748 } 02749 02750 // 02751 // and return to our caller 02752 // 02753 02754 return; 02755 02756 }

NTSTATUS RtlpAddKnownAce IN OUT PACL  Acl,
IN ULONG  AceRevision,
IN ULONG  AceFlags,
IN ACCESS_MASK  AccessMask,
IN PSID  Sid,
IN UCHAR  NewType
 

Definition at line 1242 of file acledit.c.

References _KNOWN_ACE::Header, _KNOWN_ACE::Mask, NULL, RTL_PAGED_CODE, RtlCopySid(), RtlFirstFreeAce(), RtlValidAcl(), RtlValidSid(), SeLengthSid, _KNOWN_ACE::SidStart, and USHORT.

Referenced by RtlAddAccessAllowedAce(), RtlAddAccessAllowedAceEx(), RtlAddAccessAllowedObjectAce(), RtlAddAccessDeniedAce(), RtlAddAccessDeniedAceEx(), RtlAddAccessDeniedObjectAce(), RtlAddAuditAccessAce(), RtlAddAuditAccessAceEx(), and RtlAddAuditAccessObjectAce().

01253 : 01254 01255 This routine adds KNOWN_ACE to an ACL. This is 01256 expected to be a common form of ACL modification. 01257 01258 A very bland ACE header is placed in the ACE. It provides no 01259 inheritance and no ACE flags. The type is specified by the caller. 01260 01261 Arguments: 01262 01263 Acl - Supplies the Acl being modified 01264 01265 AceRevision - Supplies the Acl/Ace revision of the ACE being added 01266 01267 AceFlags - Supplies the inherit flags for the ACE. 01268 01269 AccessMask - The mask of accesses to be denied to the specified SID. 01270 01271 Sid - Pointer to the SID being denied access. 01272 01273 NewType - Type of ACE to be added. 01274 01275 Return Value: 01276 01277 STATUS_SUCCESS - The ACE was successfully added. 01278 01279 STATUS_INVALID_ACL - The specified ACL is not properly formed. 01280 01281 STATUS_REVISION_MISMATCH - The specified revision is not known 01282 or is incompatible with that of the ACL. 01283 01284 STATUS_ALLOTTED_SPACE_EXCEEDED - The new ACE does not fit into the 01285 ACL. A larger ACL buffer is required. 01286 01287 STATUS_INVALID_SID - The provided SID is not a structurally valid 01288 SID. 01289 01290 STATUS_INVALID_PARAMETER - The AceFlags parameter was invalid. 01291 01292 --*/ 01293 01294 { 01295 PVOID FirstFree; 01296 USHORT AceSize; 01297 PKNOWN_ACE GrantAce; 01298 UCHAR NewRevision; 01299 ULONG TestedAceFlags; 01300 01301 RTL_PAGED_CODE(); 01302 01303 // 01304 // Validate the structure of the SID 01305 // 01306 01307 if (!RtlValidSid(Sid)) { 01308 return STATUS_INVALID_SID; 01309 } 01310 01311 // 01312 // Check the ACL & ACE revision levels 01313 // 01314 01315 if ( Acl->AclRevision > ACL_REVISION4 || AceRevision > ACL_REVISION4 ) { 01316 01317 return STATUS_REVISION_MISMATCH; 01318 } 01319 01320 // 01321 // Calculate the new revision of the ACL. The new revision is the maximum 01322 // of the old revision and and new ACE's revision. This is possible because 01323 // the format of previously defined ACEs did not change across revisions. 01324 // 01325 01326 NewRevision = Acl->AclRevision > (UCHAR)AceRevision ? Acl->AclRevision : (UCHAR)AceRevision; 01327 01328 // 01329 // Validate the AceFlags. 01330 // 01331 01332 TestedAceFlags = AceFlags & ~VALID_INHERIT_FLAGS; 01333 if ( TestedAceFlags != 0 ) { 01334 01335 if ( NewType == SYSTEM_AUDIT_ACE_TYPE ) { 01336 TestedAceFlags &= 01337 ~(SUCCESSFUL_ACCESS_ACE_FLAG|FAILED_ACCESS_ACE_FLAG); 01338 } 01339 01340 if ( TestedAceFlags != 0 ) { 01341 return STATUS_INVALID_PARAMETER; 01342 } 01343 } 01344 01345 // 01346 // Locate the first free ace and check to see that the Acl is 01347 // well formed. 01348 // 01349 01350 if (!RtlValidAcl( Acl )) { 01351 return STATUS_INVALID_ACL; 01352 } 01353 if (!RtlFirstFreeAce( Acl, &FirstFree )) { 01354 01355 return STATUS_INVALID_ACL; 01356 } 01357 01358 // 01359 // Check to see if there is enough room in the Acl to store the new 01360 // ACE 01361 // 01362 01363 AceSize = (USHORT)(sizeof(ACE_HEADER) + 01364 sizeof(ACCESS_MASK) + 01365 SeLengthSid(Sid)); 01366 01367 if ( FirstFree == NULL || 01368 ((PUCHAR)FirstFree + AceSize > ((PUCHAR)Acl + Acl->AclSize)) 01369 ) { 01370 01371 return STATUS_ALLOTTED_SPACE_EXCEEDED; 01372 } 01373 01374 // 01375 // Add the ACE to the end of the ACL 01376 // 01377 01378 GrantAce = (PKNOWN_ACE)FirstFree; 01379 GrantAce->Header.AceFlags = (UCHAR)AceFlags; 01380 GrantAce->Header.AceType = NewType; 01381 GrantAce->Header.AceSize = AceSize; 01382 GrantAce->Mask = AccessMask; 01383 RtlCopySid( SeLengthSid(Sid), (PSID)(&GrantAce->SidStart), Sid ); 01384 01385 // 01386 // Increment the number of ACEs by 1. 01387 // 01388 01389 Acl->AceCount += 1; 01390 01391 // 01392 // Adjust the Acl revision, if necessary 01393 // 01394 01395 Acl->AclRevision = NewRevision; 01396 01397 // 01398 // And return to our caller 01399 // 01400 01401 return STATUS_SUCCESS; 01402 }

NTSTATUS RtlpAddKnownObjectAce IN OUT PACL  Acl,
IN ULONG  AceRevision,
IN ULONG  AceFlags,
IN ACCESS_MASK  AccessMask,
IN GUID *ObjectTypeGuid  OPTIONAL,
IN GUID *InheritedObjectTypeGuid  OPTIONAL,
IN PSID  Sid,
IN UCHAR  NewType
 

Definition at line 1405 of file acledit.c.

References NULL, RTL_PAGED_CODE, RtlCopySid(), RtlFirstFreeAce(), RtlValidAcl(), RtlValidSid(), SeLengthSid, and USHORT.

Referenced by RtlAddAccessAllowedObjectAce(), RtlAddAccessDeniedObjectAce(), and RtlAddAuditAccessObjectAce().

01418 : 01419 01420 This routine adds KNOWN_ACE to an ACL. This is 01421 expected to be a common form of ACL modification. 01422 01423 A very bland ACE header is placed in the ACE. It provides no 01424 inheritance and no ACE flags. The type is specified by the caller. 01425 01426 Arguments: 01427 01428 Acl - Supplies the Acl being modified 01429 01430 AceRevision - Supplies the Acl/Ace revision of the ACE being added 01431 01432 AceFlags - Supplies the inherit flags for the ACE. 01433 01434 AccessMask - The mask of accesses to be denied to the specified SID. 01435 01436 ObjectTypeGuid - Supplies the GUID of the object this ACE applies to. 01437 If NULL, no object type GUID is placed in the ACE. 01438 01439 InheritedObjectTypeGuid - Supplies the GUID of the object type that will 01440 inherit this ACE. If NULL, no inherited object type GUID is placed in 01441 the ACE. 01442 01443 Sid - Pointer to the SID being denied access. 01444 01445 NewType - Type of ACE to be added. 01446 01447 Return Value: 01448 01449 STATUS_SUCCESS - The ACE was successfully added. 01450 01451 STATUS_INVALID_ACL - The specified ACL is not properly formed. 01452 01453 STATUS_REVISION_MISMATCH - The specified revision is not known 01454 or is incompatible with that of the ACL. 01455 01456 STATUS_ALLOTTED_SPACE_EXCEEDED - The new ACE does not fit into the 01457 ACL. A larger ACL buffer is required. 01458 01459 STATUS_INVALID_SID - The provided SID is not a structurally valid 01460 SID. 01461 01462 STATUS_INVALID_PARAMETER - The AceFlags parameter was invalid. 01463 01464 --*/ 01465 01466 { 01467 PVOID FirstFree; 01468 USHORT AceSize; 01469 PKNOWN_OBJECT_ACE GrantAce; 01470 UCHAR NewRevision; 01471 ULONG TestedAceFlags; 01472 ULONG AceObjectFlags = 0; 01473 ULONG SidSize; 01474 PCHAR Where; 01475 01476 RTL_PAGED_CODE(); 01477 01478 // 01479 // Validate the structure of the SID 01480 // 01481 01482 if (!RtlValidSid(Sid)) { 01483 return STATUS_INVALID_SID; 01484 } 01485 01486 // 01487 // Check the ACL & ACE revision levels 01488 // Object ACEs became valid in version 4. 01489 // 01490 01491 if ( Acl->AclRevision > ACL_REVISION4 || AceRevision != ACL_REVISION4 ) { 01492 01493 return STATUS_REVISION_MISMATCH; 01494 } 01495 01496 // 01497 // Calculate the new revision of the ACL. The new revision is the maximum 01498 // of the old revision and and new ACE's revision. This is possible because 01499 // the format of previously defined ACEs did not change across revisions. 01500 // 01501 01502 NewRevision = Acl->AclRevision > (UCHAR)AceRevision ? Acl->AclRevision : (UCHAR)AceRevision; 01503 01504 // 01505 // Validate the AceFlags. 01506 // 01507 01508 01509 TestedAceFlags = AceFlags & ~VALID_INHERIT_FLAGS; 01510 if ( TestedAceFlags != 0 ) { 01511 01512 if ( NewType == SYSTEM_AUDIT_ACE_TYPE || 01513 NewType == SYSTEM_AUDIT_OBJECT_ACE_TYPE ) { 01514 TestedAceFlags &= 01515 ~(SUCCESSFUL_ACCESS_ACE_FLAG|FAILED_ACCESS_ACE_FLAG); 01516 } 01517 01518 if ( TestedAceFlags != 0 ) { 01519 return STATUS_INVALID_PARAMETER; 01520 } 01521 } 01522 01523 // 01524 // Locate the first free ace and check to see that the Acl is 01525 // well formed. 01526 // 01527 01528 if (!RtlValidAcl( Acl )) { 01529 return STATUS_INVALID_ACL; 01530 } 01531 if (!RtlFirstFreeAce( Acl, &FirstFree )) { 01532 01533 return STATUS_INVALID_ACL; 01534 } 01535 01536 // 01537 // Check to see if there is enough room in the Acl to store the new 01538 // ACE 01539 // 01540 01541 SidSize = SeLengthSid(Sid); 01542 AceSize = (USHORT)(sizeof(ACE_HEADER) + 01543 sizeof(ACCESS_MASK) + 01544 sizeof(ULONG) + 01545 SidSize); 01546 01547 if ( ARGUMENT_PRESENT(ObjectTypeGuid) ) { 01548 AceObjectFlags |= ACE_OBJECT_TYPE_PRESENT; 01549 AceSize += sizeof(GUID); 01550 } 01551 01552 if ( ARGUMENT_PRESENT(InheritedObjectTypeGuid) ) { 01553 AceObjectFlags |= ACE_INHERITED_OBJECT_TYPE_PRESENT; 01554 AceSize += sizeof(GUID); 01555 } 01556 01557 if ( FirstFree == NULL || 01558 ((PUCHAR)FirstFree + AceSize > ((PUCHAR)Acl + Acl->AclSize)) 01559 ) { 01560 01561 return STATUS_ALLOTTED_SPACE_EXCEEDED; 01562 } 01563 01564 // 01565 // Add the ACE to the end of the ACL 01566 // 01567 01568 GrantAce = (PKNOWN_OBJECT_ACE)FirstFree; 01569 GrantAce->Header.AceFlags = (UCHAR) AceFlags; 01570 GrantAce->Header.AceType = NewType; 01571 GrantAce->Header.AceSize = AceSize; 01572 GrantAce->Mask = AccessMask; 01573 GrantAce->Flags = AceObjectFlags; 01574 Where = (PCHAR) (&GrantAce->SidStart); 01575 if ( ARGUMENT_PRESENT(ObjectTypeGuid) ) { 01576 RtlCopyMemory( Where, ObjectTypeGuid, sizeof(GUID) ); 01577 Where += sizeof(GUID); 01578 } 01579 if ( ARGUMENT_PRESENT(InheritedObjectTypeGuid) ) { 01580 RtlCopyMemory( Where, InheritedObjectTypeGuid, sizeof(GUID) ); 01581 Where += sizeof(GUID); 01582 } 01583 RtlCopySid( SidSize, (PSID)Where, Sid ); 01584 Where += SidSize; 01585 01586 // 01587 // Increment the number of ACEs by 1. 01588 // 01589 01590 Acl->AceCount += 1; 01591 01592 // 01593 // Adjust the Acl revision, if necessary 01594 // 01595 01596 Acl->AclRevision = NewRevision; 01597 01598 // 01599 // And return to our caller 01600 // 01601 01602 return STATUS_SUCCESS; 01603 }

VOID RtlpDeleteData IN PVOID  Data,
IN ULONG  RemoveSize,
IN ULONG  TotalSize
 

Definition at line 2764 of file acledit.c.

Referenced by RtlDeleteAce().

02772 : 02773 02774 This routine deletes a string of bytes from the front of a data buffer 02775 and compresses the data. It also zeros out the part of the string 02776 that is no longer in use. Pictorially the results are as follows 02777 02778 Before: 02779 02780 Data = DDDDDddddd 02781 RemoveSize = 5 02782 TotalSize = 10 02783 02784 After: 02785 02786 Data = ddddd00000 02787 02788 Arguments: 02789 02790 Data - Supplies a pointer to the data being altered 02791 02792 RemoveSize - Supplies the number of bytes to delete from the front 02793 of the data buffer 02794 02795 TotalSize - Supplies the total number of bytes in the data buffer 02796 before the delete operation 02797 02798 Return Value: 02799 02800 None 02801 02802 --*/ 02803 02804 { 02805 ULONG i; 02806 02807 // 02808 // Shift over the buffer to remove the amount 02809 // 02810 02811 for (i = RemoveSize; i < TotalSize; i++) { 02812 02813 ((PUCHAR)Data)[i-RemoveSize] = ((PUCHAR)Data)[i]; 02814 02815 } 02816 02817 // 02818 // Now as a safety precaution we'll zero out the rest of the string 02819 // 02820 02821 for (i = TotalSize - RemoveSize; i < TotalSize; i++) { 02822 02823 ((PUCHAR)Data)[i] = 0; 02824 } 02825 02826 // 02827 // And return to our caller 02828 // 02829 02830 return; 02831 02832 } }

NTSTATUS RtlQueryInformationAcl IN PACL  Acl,
OUT PVOID  AclInformation,
IN ULONG  AclInformationLength,
IN ACL_INFORMATION_CLASS  AclInformationClass
 

Definition at line 460 of file acledit.c.

References NTSTATUS(), NULL, RTL_PAGED_CODE, RtlFirstFreeAce(), and Status.

Referenced by IopOpenDeviceParametersSubkey(), main(), RtlLengthUsedSecurityDescriptor(), TestQueryInformationAcl(), and TestSeAclRtl().

00469 : 00470 00471 This routine returns to the caller information about an ACL. The requested 00472 information can be AclRevisionInformation, or AclSizeInformation. 00473 00474 Arguments: 00475 00476 Acl - Supplies the Acl being examined 00477 00478 AclInformation - Supplies the buffer to receive the information being 00479 requested 00480 00481 AclInformationLength - Supplies the length of the AclInformation buffer 00482 in bytes 00483 00484 AclInformationClass - Supplies the type of information being requested 00485 00486 Return Value: 00487 00488 NTSTATUS - STATUS_SUCCESS if successful and an appropriate error 00489 status otherwise 00490 00491 --*/ 00492 00493 { 00494 PACL_REVISION_INFORMATION RevisionInfo; 00495 PACL_SIZE_INFORMATION SizeInfo; 00496 00497 00498 PVOID FirstFree; 00499 NTSTATUS Status; 00500 00501 RTL_PAGED_CODE(); 00502 00503 // 00504 // Check the ACL revision level 00505 // 00506 00507 if (!ValidAclRevision( Acl )) { 00508 00509 return STATUS_INVALID_PARAMETER; 00510 00511 } 00512 00513 // 00514 // Case on the information class being requested 00515 // 00516 00517 switch (AclInformationClass) { 00518 00519 case AclRevisionInformation: 00520 00521 // 00522 // Make sure the buffer size is correct 00523 // 00524 00525 if (AclInformationLength < sizeof(ACL_REVISION_INFORMATION)) { 00526 00527 return STATUS_BUFFER_TOO_SMALL; 00528 00529 } 00530 00531 // 00532 // Get the Acl revision and return 00533 // 00534 00535 RevisionInfo = (PACL_REVISION_INFORMATION)AclInformation; 00536 RevisionInfo->AclRevision = Acl->AclRevision; 00537 00538 break; 00539 00540 case AclSizeInformation: 00541 00542 // 00543 // Make sure the buffer size is correct 00544 // 00545 00546 if (AclInformationLength < sizeof(ACL_SIZE_INFORMATION)) { 00547 00548 return STATUS_BUFFER_TOO_SMALL; 00549 00550 } 00551 00552 // 00553 // Locate the first free spot in the Acl 00554 // 00555 00556 if (!RtlFirstFreeAce( Acl, &FirstFree )) { 00557 00558 // 00559 // The input Acl is ill-formed 00560 // 00561 00562 return STATUS_INVALID_PARAMETER; 00563 00564 } 00565 00566 // 00567 // Given a pointer to the first free spot we can now easily compute 00568 // the number of free bytes and used bytes in the Acl. 00569 // 00570 00571 SizeInfo = (PACL_SIZE_INFORMATION)AclInformation; 00572 SizeInfo->AceCount = Acl->AceCount; 00573 00574 if (FirstFree == NULL) { 00575 00576 // 00577 // With a null first free we don't have any free space in the Acl 00578 // 00579 00580 SizeInfo->AclBytesInUse = Acl->AclSize; 00581 00582 SizeInfo->AclBytesFree = 0; 00583 00584 } else { 00585 00586 // 00587 // The first free is not null so we have some free room left in 00588 // the acl 00589 // 00590 00591 SizeInfo->AclBytesInUse = (ULONG)((PUCHAR)FirstFree - (PUCHAR)Acl); 00592 00593 SizeInfo->AclBytesFree = Acl->AclSize - SizeInfo->AclBytesInUse; 00594 00595 } 00596 00597 break; 00598 00599 default: 00600 00601 return STATUS_INVALID_INFO_CLASS; 00602 00603 } 00604 00605 // 00606 // and return to our caller 00607 // 00608 00609 return STATUS_SUCCESS; 00610 }

NTSTATUS RtlSetInformationAcl IN PACL  Acl,
IN PVOID  AclInformation,
IN ULONG  AclInformationLength,
IN ACL_INFORMATION_CLASS  AclInformationClass
 

Definition at line 614 of file acledit.c.

References RTL_PAGED_CODE.

Referenced by TestSeAclRtl(), and TestSetInformationAcl().

00623 : 00624 00625 This routine sets the state of an ACL. For now only the revision 00626 level can be set and for now only a revision level of 1 is accepted 00627 so this procedure is rather simple 00628 00629 Arguments: 00630 00631 Acl - Supplies the Acl being altered 00632 00633 AclInformation - Supplies the buffer containing the information being 00634 set 00635 00636 AclInformationLength - Supplies the length of the Acl information buffer 00637 00638 AclInformationClass - Supplies the type of information begin set 00639 00640 Return Value: 00641 00642 NTSTATUS - STATUS_SUCCESS if successful and an appropriate error 00643 status otherwise 00644 00645 --*/ 00646 00647 { 00648 PACL_REVISION_INFORMATION RevisionInfo; 00649 00650 RTL_PAGED_CODE(); 00651 00652 // 00653 // Check the ACL revision level 00654 // 00655 00656 if (!ValidAclRevision( Acl )) { 00657 00658 return STATUS_INVALID_PARAMETER; 00659 00660 } 00661 00662 // 00663 // Case on the information class being requested 00664 // 00665 00666 switch (AclInformationClass) { 00667 00668 case AclRevisionInformation: 00669 00670 // 00671 // Make sure the buffer size is correct 00672 // 00673 00674 if (AclInformationLength < sizeof(ACL_REVISION_INFORMATION)) { 00675 00676 return STATUS_BUFFER_TOO_SMALL; 00677 00678 } 00679 00680 // 00681 // Get the Acl requested ACL revision level 00682 // 00683 00684 RevisionInfo = (PACL_REVISION_INFORMATION)AclInformation; 00685 00686 // 00687 // Don't let them lower the revision of an ACL. 00688 // 00689 00690 if (RevisionInfo->AclRevision < Acl->AclRevision ) { 00691 00692 return STATUS_INVALID_PARAMETER; 00693 } 00694 00695 // 00696 // Assign the new revision. 00697 // 00698 00699 Acl->AclRevision = (UCHAR)RevisionInfo->AclRevision; 00700 00701 break; 00702 00703 default: 00704 00705 return STATUS_INVALID_INFO_CLASS; 00706 00707 } 00708 00709 // 00710 // and return to our caller 00711 // 00712 00713 return STATUS_SUCCESS; 00714 }

BOOLEAN RtlValidAcl IN PACL  Acl  ) 
 

Definition at line 187 of file acledit.c.

References EXCEPTION_EXECUTE_HANDLER, FALSE, KNOWN_ACE, LongAligned, PKNOWN_ACE, RTL_PAGED_CODE, SeLengthSid, TRUE, and WordAligned.

Referenced by RtlAddAce(), RtlAddCompoundAce(), RtlDeleteAce(), RtlpAddKnownAce(), RtlpAddKnownObjectAce(), RtlpConvertAclToAutoInherit(), RtlValidRelativeSecurityDescriptor(), RtlValidSecurityDescriptor(), SepCheckAcl(), SeValidSecurityDescriptor(), TestSeAclRtl(), and TestTokenQuery().

00193 : 00194 00195 This procedure validates an ACL. 00196 00197 This involves validating the revision level of the ACL and ensuring 00198 that the number of ACEs specified in the AceCount fit in the space 00199 specified by the AclSize field of the ACL header. 00200 00201 Arguments: 00202 00203 Acl - Pointer to the ACL structure to validate. 00204 00205 Return Value: 00206 00207 BOOLEAN - TRUE if the structure of Acl is valid. 00208 00209 --*/ 00210 00211 { 00212 RTL_PAGED_CODE(); 00213 00214 try { 00215 PACE_HEADER Ace; 00216 PISID Sid; 00217 PISID Sid2; 00218 ULONG i; 00219 UCHAR AclRevision = ACL_REVISION2; 00220 00221 00222 // 00223 // Check the ACL revision level 00224 // 00225 if (!ValidAclRevision(Acl)) { 00226 return(FALSE); 00227 } 00228 00229 00230 if (!WordAligned(&Acl->AclSize)) { 00231 return(FALSE); 00232 } 00233 00234 if (Acl->AclSize < sizeof(ACL)) { 00235 return(FALSE); 00236 } 00237 // 00238 // Validate all of the ACEs. 00239 // 00240 00241 Ace = ((PVOID)((PUCHAR)(Acl) + sizeof(ACL))); 00242 00243 for (i = 0; i < Acl->AceCount; i++) { 00244 00245 // 00246 // Check to make sure we haven't overrun the Acl buffer 00247 // with our ace pointer. Make sure the ACE_HEADER is in 00248 // the ACL also. 00249 // 00250 00251 if ((PUCHAR)Ace + sizeof(ACE_HEADER) >= ((PUCHAR)Acl + Acl->AclSize)) { 00252 return(FALSE); 00253 } 00254 00255 if (!WordAligned(&Ace->AceSize)) { 00256 return(FALSE); 00257 } 00258 00259 if ((PUCHAR)Ace + Ace->AceSize > ((PUCHAR)Acl + Acl->AclSize)) { 00260 return(FALSE); 00261 } 00262 00263 // 00264 // It is now safe to reference fields in the ACE header. 00265 // 00266 00267 // 00268 // The ACE header fits into the ACL, if this is a known type of ACE, 00269 // make sure the SID is within the bounds of the ACE 00270 // 00271 00272 if (IsKnownAceType(Ace)) { 00273 00274 if (!LongAligned(Ace->AceSize)) { 00275 return(FALSE); 00276 } 00277 00278 if (Ace->AceSize < sizeof(KNOWN_ACE) - sizeof(ULONG) + sizeof(SID) - sizeof(ULONG)) { 00279 return(FALSE); 00280 } 00281 00282 // 00283 // It's now safe to reference the parts of the SID structure, though 00284 // not the SID itself. 00285 // 00286 00287 Sid = (PISID) & (((PKNOWN_ACE)Ace)->SidStart); 00288 00289 if (Sid->Revision != SID_REVISION) { 00290 return(FALSE); 00291 } 00292 00293 if (Sid->SubAuthorityCount > SID_MAX_SUB_AUTHORITIES) { 00294 return(FALSE); 00295 } 00296 00297 // 00298 // SeLengthSid computes the size of the SID based on the subauthority count, 00299 // so it is safe to use even though we don't know that the body of the SID 00300 // is safe to reference. 00301 // 00302 00303 if (Ace->AceSize < sizeof(KNOWN_ACE) - sizeof(ULONG) + SeLengthSid( Sid )) { 00304 return(FALSE); 00305 } 00306 00307 00308 // 00309 // If it's a compound ACE, then perform roughly the same set of tests, but 00310 // check the validity of both SIDs. 00311 // 00312 00313 } else if (IsCompoundAceType(Ace)) { 00314 00315 // 00316 // Compound ACEs became valid in revision 3 00317 // 00318 if ( Acl->AclRevision < ACL_REVISION3 ) { 00319 return FALSE; 00320 } 00321 00322 if (!LongAligned(Ace->AceSize)) { 00323 return(FALSE); 00324 } 00325 00326 if (Ace->AceSize < sizeof(KNOWN_COMPOUND_ACE) - sizeof(ULONG) + sizeof(SID)) { 00327 return(FALSE); 00328 } 00329 00330 // 00331 // The only currently defined Compound ACE is an Impersonation ACE. 00332 // 00333 00334 if (((PKNOWN_COMPOUND_ACE)Ace)->CompoundAceType != COMPOUND_ACE_IMPERSONATION) { 00335 return(FALSE); 00336 } 00337 00338 // 00339 // Examine the first SID and make sure it's structurally valid, 00340 // and it lies within the boundaries of the ACE. 00341 // 00342 00343 Sid = (PISID) & (((PKNOWN_COMPOUND_ACE)Ace)->SidStart); 00344 00345 if (Sid->Revision != SID_REVISION) { 00346 return(FALSE); 00347 } 00348 00349 if (Sid->SubAuthorityCount > SID_MAX_SUB_AUTHORITIES) { 00350 return(FALSE); 00351 } 00352 00353 // 00354 // Compound ACEs contain two SIDs. Make sure this ACE is large enough to contain 00355 // not only the first SID, but the body of the 2nd. 00356 // 00357 00358 if (Ace->AceSize < sizeof(KNOWN_COMPOUND_ACE) - sizeof(ULONG) + SeLengthSid( Sid ) + sizeof(SID)) { 00359 return(FALSE); 00360 } 00361 00362 // 00363 // It is safe to reference the interior of the 2nd SID. 00364 // 00365 00366 Sid2 = (PISID) ((PUCHAR)Sid + SeLengthSid( Sid )); 00367 00368 if (Sid2->Revision != SID_REVISION) { 00369 return(FALSE); 00370 } 00371 00372 if (Sid2->SubAuthorityCount > SID_MAX_SUB_AUTHORITIES) { 00373 return(FALSE); 00374 } 00375 00376 if (Ace->AceSize < sizeof(KNOWN_COMPOUND_ACE) - sizeof(ULONG) + SeLengthSid( Sid ) + SeLengthSid( Sid2 )) { 00377 return(FALSE); 00378 } 00379 00380 00381 // 00382 // If it's an object ACE, then perform roughly the same set of tests. 00383 // 00384 00385 } else if (IsObjectAceType(Ace)) { 00386 ULONG GuidSize=0; 00387 00388 // 00389 // Object ACEs became valid in revision 4 00390 // 00391 if ( Acl->AclRevision < ACL_REVISION4 ) { 00392 return FALSE; 00393 } 00394 00395 if (!LongAligned(Ace->AceSize)) { 00396 return(FALSE); 00397 } 00398 00399 // 00400 // Ensure there is room for the ACE header. 00401 // 00402 if (Ace->AceSize < sizeof(KNOWN_OBJECT_ACE) - sizeof(ULONG)) { 00403 return(FALSE); 00404 } 00405 00406 00407 // 00408 // Ensure there is room for the GUIDs and SID header 00409 // 00410 if ( RtlObjectAceObjectTypePresent( Ace ) ) { 00411 GuidSize += sizeof(GUID); 00412 } 00413 00414 if ( RtlObjectAceInheritedObjectTypePresent( Ace ) ) { 00415 GuidSize += sizeof(GUID); 00416 } 00417 00418 if (Ace->AceSize < sizeof(KNOWN_OBJECT_ACE) - sizeof(ULONG) + GuidSize + sizeof(SID)) { 00419 return(FALSE); 00420 } 00421 00422 // 00423 // It's now safe to reference the parts of the SID structure, though 00424 // not the SID itself. 00425 // 00426 00427 Sid = (PISID) RtlObjectAceSid( Ace ); 00428 00429 if (Sid->Revision != SID_REVISION) { 00430 return(FALSE); 00431 } 00432 00433 if (Sid->SubAuthorityCount > SID_MAX_SUB_AUTHORITIES) { 00434 return(FALSE); 00435 } 00436 00437 if (Ace->AceSize < sizeof(KNOWN_OBJECT_ACE) - sizeof(ULONG) + GuidSize + SeLengthSid( Sid ) ) { 00438 return(FALSE); 00439 } 00440 } 00441 00442 // 00443 // And move Ace to the next ace position 00444 // 00445 00446 Ace = ((PVOID)((PUCHAR)(Ace) + ((PACE_HEADER)(Ace))->AceSize)); 00447 } 00448 00449 return(TRUE); 00450 00451 } except(EXCEPTION_EXECUTE_HANDLER) { 00452 00453 return FALSE; 00454 } 00455 00456 }


Generated on Sat May 15 19:42:49 2004 for test by doxygen 1.3.7