Results 1 to 7 of 7

Thread: Understanding Mask value of Acl Entry

  1. #1
    Join Date
    Oct 2007
    Posts
    24

    Default Understanding Mask value of Acl Entry

    Hello there.

    I have been struggling for some time to get to grips with the ACL side of Spring Security 2.

    I am currently trying to understand the mask value on AclEntry.


    Firstly, I have an object read voter configured like this:

    Code:
    <bean id="aclObjectReadVoter" class="org.springframework.security.vote.AclEntryVoter">
    		<constructor-arg ref="aclService" />
    		<constructor-arg value="ACL_OBJECT_READ" />
    		<constructor-arg>
    			<list>
    				<ref local="administrationPermission" />
    				<ref local="readPermission" />
    			</list>
    		</constructor-arg>
    		<property name="processDomainObjectClass" value="org.sample.MySecureClass" />
    	</bean>

    I understand from reading here that a mask value of '3' represents read and write access

    So I would have thought that a user whose ACL entry for a particular object was 3 would get a positive result when this voter votes. Unfortunately I cannot see this happening.

    So I have been digging into the source code and have come across this in AclImpl.isGranted

    Code:
    for (int i = 0; i < permission.length; i++) {
                for (int x = 0; x < sids.length; x++) {
                    // Attempt to find exact match for this permission mask and SID
                    Iterator acesIterator = aces.iterator();
                    boolean scanNextSid = true;
    
                    while (acesIterator.hasNext()) {
                        AccessControlEntry ace = (AccessControlEntry) acesIterator.next();
    
                        if ((ace.getPermission().getMask() == permission[i].getMask()) && ace.getSid().equals(sids[x])) {
                            // Found a matching ACE, so its authorization decision will prevail
                            if (ace.isGranting()) {
                                // Success
                                if (!administrativeMode) {
                                    auditLogger.logIfNeeded(true, ace);
                                }
    
                                return true;
                            } else {
                                // Failure for this permission, so stop search
                                // We will see if they have a different permission
                                // (this permission is 100% rejected for this SID)
                                if (firstRejection == null) {
                                    // Store first rejection for auditing reasons
                                    firstRejection = ace;
                                }
    
                                scanNextSid = false; // helps break the loop
    
                                break; // exit "aceIterator" while loop
                            }
                        }
                    }
    
                    if (!scanNextSid) {
                        break; // exit SID for loop (now try next permission)
                    }
                }
            }
    From my reading of this I understand that it is doing a direct comparrison (specifically an ==) on the mask of the accessControlEntry's permission, and that of the various permissions that the voter tests (in my case READ (1) and Administration (16) ). This would suggest that the mask does not actually get applied in terms of a bitwise comparrision. Am I missing something, or does this mean that a mask value of 3 will not allow READ?

  2. #2
    Join Date
    Oct 2007
    Posts
    24

    Default

    Came across some other (quite old) references to this line of code in the forum

    http://forum.springframework.org/sho...749#post139749

    This is so old I dont know if it still applies, but does this mean that masks do not work in the new acls package?

  3. #3
    Join Date
    Mar 2009
    Posts
    1

    Default

    Came across to the same problem.
    I believe here it should be something like
    (ace.getPermission().getMask() & permission[i].getMask() )== permission[i].getMask()

    Otherwise I have to specify all possible combination when using the following tag for the bit 1.

    <security:accesscontrollist
    domainObject="${grade}" hasPermission="1,3,7,9,............">
    <p>grade read ok</p>
    </security:accesscontrollist>




    Quote Originally Posted by magicduncan View Post
    Hello there.


    From my reading of this I understand that it is doing a direct comparrison (specifically an ==) on the mask of the accessControlEntry's permission, and that of the various permissions that the voter tests (in my case READ (1) and Administration (16) ). This would suggest that the mask does not actually get applied in terms of a bitwise comparrision. Am I missing something, or does this mean that a mask value of 3 will not allow READ?

  4. #4

    Question

    I'm also a newbie and don't quite understand this.
    The javadoc of AclImpl.isGranted():
    When the first full match is found (ie an ACE that has the SID currently being searched for and the exact permission bit mask being search for), the grant or deny flag for that ACE will prevail.
    seems to indicate, that this is the way it's meant to be.
    When I was playing around with the contacts-sample I saw that it's not possible in the example to add an ACE that has more than one bit set.
    e.g. if I want to grant READ and WRITE permissions for the same object to the same SID, it will result in 2 entries in the acl_entry table: and each of these entries has only the corresponding bit in its mask set.

    Now I wonder if the contacts example should be improved to store those 2 permissions in one acl_entry, or if this is the way it's meant to be (in the later case the acl_entry.mask column should maybe be renamed to permission)

  5. #5

    Default

    hmm... on the other hand, the security reference says:
    Finally, ACL_ENTRY stores the individual permissions assigned to each recipient. Columns include a foreign key to the ACL_OBJECT_IDENTITY, the recipient (ie a foreign key to ACL_SID), whether we'll be auditing or not, and the integer bit mask that represents the actual permission being granted or denied. We have a single row for every recipient that receives a permission to work with a domain object.

  6. #6

    Default

    Okay, here's what I've discovered.

    The documentation is either wrong or unclear. There is an entry in acl_entry for each permission set for each object/sid pair, period. There are no combined mask values. IOW, you will see nothing but powers of two in the "mask" field until you reach 2^32.

    This is, UNLESS you use CumulativePermission and do something like
    Code:
    permission.set(BasePermission.READ).set(BasePermission.WRITE);
    when setting an ACE, which will be written to the database as one ACE, with the mask field set to 3. However, this will screw things up with the AclEntryVoters.

    I am so tempted to do a complete rewrite of this. The whole Permission hierarchy just seems wrong when you can do everything with bitmask operators. Having to use instanceof to distinguish between PrincipalSids and GrantedAuthoritySids because they use different methods to get their names - getPrincipal() for PrincipalSids and getAuthority() for GrantedAuthoritySids? Give me a break! getName(), and either a) provide a common interface, b) make them subclasses of an abstract class, or c) make them the same class with a Boolean isPrincipal() method.
    Last edited by John Vance; Mar 27th, 2009 at 12:32 AM. Reason: Trying to cut back on the crack.

  7. #7
    Join Date
    Oct 2007
    Posts
    24

    Default

    So it looks like this has been logged in Jira.

    Reading the response from Ben, I get the impression the whole ACL side was designed to meet someone's highly specific and complex requierments. If your requierments are different or less complex, then too bad.

    Time for a redesign I think. ACL secuirity with Spring is complicated out of all proportion to any other Spring technology I have used.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •