Compartilhar via


2.5.3.4.2 ComputeACL

The ComputeACL subroutine determines the new ACL based on supplied Parent ACL, Creator ACL, and possibly the Token's DefaultDACL, depending on the supplied parameters and policy. This function is generally applicable to both the DACL and SACL portions of the security descriptor, although there are some specific behaviors that differ between the two types of DACL, so care has to be taken during implementation to honor the ComputeType parameter.

Parameters

  • ComputeType: Enumeration of COMPUTE_DACL and COMPUTE_SACL.

  • ParentACL: ACL from the parent security descriptor.

  • AutoInheritFlags: as specified in section 2.5.3.4.1. Note that it is possible to have the DACL_AUTO_INHERIT flag set when ComputeType is set to COMPUTE_SACL (or vice-versa).

  • ParentControl: Control flags from the parent security descriptor.

  • CreatorACL: ACL supplied in the security descriptor by the creator.

  • CreatorControl: Control flags supplied in the security descriptor by the creator.

  • IsContainerObject: TRUE if the object is a container; otherwise, FALSE.

  • ObjectTypes: Array of GUIDs for the object type being created.

  • GenericMapping: Mapping of generic permissions to resource manager-specific permissions supplied by the caller.

  • Owner: Owner to use in substituting the CreatorOwner SID.

  • Group: Group to use in substituting the CreatorGroup SID.

  • Token: Token for default values.

Returns

  • Computed ACL

  • ComputedControl

     // The details of the algorithm to merge the parent ACL and the supplied ACL.
     // The Control flags computed are slightly different based on whether it is the 
     // ACL in the DACL or the SACL field of the descriptor.
     // The caller specifies whether it is a DACL or a SACL using the parameter,
     // ComputeType.
     Set ComputedACL to NULL
     Set ComputedControl to NULL
      
     CALL ContainsInheritableACEs WITH ParentACL RETURNING ParentHasInheritableACEs
      
     IF ParentHasInheritableACEs = TRUE THEN
      
         // The Parent ACL has inheritable ACEs.  The Parent ACL should be used if no Creator
         // ACL is supplied, or if the Creator ACL was supplied AND it is a default ACL based
         // on object type information
      
         IF(CreatorACL is not present) OR
           ((CreatorACL is present) AND
           (AutoInheritFlags contains DEFAULT_DESCRIPTOR_FOR_OBJECT))
         THEN
             // Use only the inherited ACEs from the parent.  First compute the ACL from the 
             // parent ACL, then clean it up by resolving the generic mappings etc.
      
             CALL ComputeInheritedACLFromParent WITH
               ACL set to ParentACL,
               IsContainerObject set to IsContainerObject,
               ObjectTypes set to ObjectTypes
      
             RETURNING NextACL
             CALL PostProcessACL WITH
               ACL set to NextACL,
               CopyFilter set to CopyInheritedAces,
               Owner set to Owner,
               Group set to Group,
               GenericMapping set to GenericMapping
      
             RETURNING FinalACL
      
             Set ComputedACL to FinalACL
             RETURN
         ENDIF
      
         IF ((CreatorACL is present) AND
           (AutoInheritFlags does not contain DEFAULT_DESCRIPTOR_FOR_OBJECT))
         THEN
             // Since a creator ACL is present, and we're not defaulting the
             // descriptor, determine which ACEs are inherited and compute the new ACL
             CALL PreProcessACLFromCreator WITH 
                ACL set to CreatorACL
             RETURNING PreACL
      
             CALL ComputeInheritedACLFromCreator WITH
                ACL set to PreACL,
                IsContainerObject set to IsContainerObject,
                ObjectTypes set to ObjectTypes
             RETURNING TmpACL
      
      
             //  Special handling for DACL types of ACLs
      
             IF (ComputeType = DACL_COMPUTE) THEN
             
                 // DACL-specific operations
      
                 IF (CreatorControl does not have DACL_PROTECTED flag set) AND
                    (AutoInheritFlags contains DACL_AUTO_INHERIT)
                 THEN 
      
                     //  We're not working from a protected DACL, and we're supposed to
                     //  allow automatic inheritance.  Compute the inherited ACEs from
                     //  Parent ACL this time, and append that to the ACL that we're building
      
                     CALL ComputeInheritedACLFromParent WITH
                       ACL set to ParentACL,
                       IsContainerObject set to IsContainerObject,
                       ObjectTypes set to ObjectTypes
                     RETURNING InheritedParentACL
      
                     Append InheritedParentACL.ACEs to TmpACL.ACE
                     Set DACL_AUTO_INHERITED flag in ComputedControl
      
                 ENDIF
      
             ENDIF  // DACL-Specific behavior
             IF (ComputeType = SACL_COMPUTE) THEN
      
                 // Similar to the above, perform SACL-specific operations
      
                 IF (CreatorControl does not have SACL_PROTECTED flag set) AND
                    (AutoInheritFlags contains SACL_AUTO_INHERIT flag)
                 THEN
      
                     //  We're not working from a protected SACL, and we're supposed to
                     //  allow automatic inheritance.  Compute the inherited ACEs from
                     //  Parent ACL this time, and append that to the ACL that we're building
      
                     CALL ComputeInheritedACLFromParent WITH
                       ACL set to ParentACL,
                       IsContainerObject set to IsContainerObject,
                       ObjectTypes set to ObjectTypes
                     RETURNING InheritedParentACL
      
                     Append InheritedParentACL.ACEs to TmpACL.ACE
                     Set SACL_AUTO_INHERITED flag in ComputedControl
      
                 ENDIF
      
             ENDIF  // SACL-Specific behavior
      
             
      
      
      
             CALL PostProcessACL WITH
               ACL set to TmpACL,
               CopyFilter set to CopyInheritedAces,
               Owner set to Owner,
               Group set to Group,
               GenericMapping set to GenericMapping
             RETURNING ProcessedACL
      
             Set ComputedACL to ProcessedACL
             RETURN
         ENDIF  // CreatorACL is present
      
      
     ELSE // ParentACL does not contain inheritable ACEs
      
         IF CreatorACL = NULL THEN
             // No ACL supplied for the object
             IF (ComputeType = DACL_COMPUTE) THEN
                 Set TmpACL to Token.DefaultDACL
             ELSE
                 // No default for SACL; left as NULL
             ENDIF
      
         ELSE
             // Explicit ACL was supplied for the object - either default or not.
             // In either case, use it for the object, since there are no inherited ACEs.
             CALL PreProcessACLFromCreator WITH CreatorACL
             RETURNING TmpACL
         ENDIF
      
         CALL PostProcessACL WITH
           ACL set to TmpACL,
           CopyFilter set to CopyAllAces,
           Owner set to Owner,
           Group set to Group,
           GenericMapping set to GenericMapping
      
             RETURNING ProcessedACL
             Set ComputedACL to ProcessedACL
      
     ENDIF
     // END ComputeACL