[Date Prev][Date Next]
[Chronological]
[Thread]
[Top]
Problem with break keyword in ACLs
Hi all,
I've got a problem with the 'break' keyword in ACLs in
OpenLDAP 2.1.23. I have reduced the problem to the
following ACLs:
access to *
by * =csr break
access to dn.children=ou=admin,dc=science,dc=uva,dc=nl
by * none stop
The following search returns nothing:
% ldapsearch -h server -x -b ou=people,dc=science,dc=uva,dc=nl '(uid=robbert)' givenName
version: 2
#
# filter: (uid=robbert)
# requesting: givenName
#
# search result
search: 2
result: 0 Success
# numResponses: 1
The corresponding slapd logging output (-d 128):
Backend ACL: access to *
by * =rsc break
Backend ACL: access to dn.children=ou=admin,dc=science,dc=uva,dc=nl
by * none(=n)
slapd starting
=> access_allowed: search access to "uid=robbert,ou=people,dc=science,dc=uva,dc=nl" "uid" requested
=> acl_get: [1] check attr uid
<= acl_get: [1] acl uid=robbert,ou=people,dc=science,dc=uva,dc=nl attr: uid
=> acl_mask: access to entry "uid=robbert,ou=people,dc=science,dc=uva,dc=nl", attr "uid" requested
=> acl_mask: to value by "", (=n)
<= check a_dn_pat: *
<= acl_mask: [1] applying =rsc (break)
<= acl_mask: [1] mask: =rsc
=> dn: [2] ou=admin,dc=science,dc=uva,dc=nl
<= acl_get: done.
=> access_allowed: no more rules
So I change the ACLs (to something I don't want) by replacing
'break' by 'stop' in the first ACL:
access to *
by * =csr stop
access to dn.children=ou=admin,dc=science,dc=uva,dc=nl
by * none stop
The same search now returns one record:
version: 2
#
# filter: (uid=robbert)
# requesting: givenName
#
# robbert, people, science, uva, nl
dn: uid=robbert,ou=people,dc=science,dc=uva,dc=nl
givenName: Robbert
# search result
search: 2
result: 0 Success
# numResponses: 2
# numEntries: 1
Relevant part of the corresponding slapd logging output:
Backend ACL: access to *
by * =rsc
Backend ACL: access to dn.children=ou=admin,dc=science,dc=uva,dc=nl
by * none(=n)
slapd starting
=> access_allowed: search access to "uid=robbert,ou=people,dc=science,dc=uva,dc=nl" "uid" requested
=> acl_get: [1] check attr uid
<= acl_get: [1] acl uid=robbert,ou=people,dc=science,dc=uva,dc=nl attr: uid
=> acl_mask: access to entry "uid=robbert,ou=people,dc=science,dc=uva,dc=nl", attr "uid" requested
=> acl_mask: to value by "", (=n)
<= check a_dn_pat: *
<= acl_mask: [1] applying =rsc (stop)
<= acl_mask: [1] mask: =rsc
=> access_allowed: search access granted by =rsc
Going back to the first set of ACLs:
access to *
by * =csr break
access to dn.children=ou=admin,dc=science,dc=uva,dc=nl
by * none stop
My interpretation of the 'break' keyword is that it amends the
access bits (=csr in this case) but allows other ACLs to apply
as well. In this case, the access bits set by the first ACL are ignored.
The second ACL doesn't apply in this search.
Looking at the slapd code, I think this happens in servers/slapd/acl.c
at line 339:
} else if ( control == ACL_BREAK ) {
#ifdef NEW_LOGGING
LDAP_LOG( ACL, DETAIL1,
"access_allowed: conn %lu no more rules\n", conn->c_connid, 0,0 );
#else
Debug( LDAP_DEBUG_ACL,
"=> access_allowed: no more rules\n", 0, 0, 0);
#endif
goto done;
}
This code causes a jump to 'done:' if the last ACL processed returns
ACL_BREAK. The effect is that the line (364)
ret = ACL_GRANT(mask, access);
is skipped and thus the first ACL is not effective.
According to diff there are no differences between acl.c in OpenLDAP
version 2.1.23 and version 2.1.25.
Is break meant to behave this way?
Kind regards,
Wout