[Date Prev][Date Next] [Chronological] [Thread] [Top]

ACL confusion



As I understand it, ACL's are processed in a top down fashion and the
process stops with the first match.  In that light you would make your
ACL's start with specific DN's and work toward more generic ones.

Here is the ldif of 'cn=master' and one sample user:
# master, ivenue.net
dn: cn=master,dc=ivenue,dc=net
objectClass: person
sn: master
cn: master
userPassword:: e2NyeXobfuscatedobfuscated=

# todd.misterball.com, users, ivenue.net
dn: uid=todd.misterball.com,ou=users,dc=ivenue,dc=net
loginShell: /sbin/nologin
gidNumber: 1000
uidNumber: 1019
shadowMax: 99999
objectClass: posixAccount
objectClass: top
objectClass: shadowAccount
objectClass: account
uid: todd@misterball.com
uid: todd.misterball.com
gecos:: IA==
shadowLastChange: 11740
cn:: IA==
homeDirectory: /maildirs/m/i/s/todd.misterball.com
description: customerNumber->58144
shadowWarning: 7
userPassword:: obfuscatedobfuscated


Here's the ACL that I'm working with that is not working the way that I
expected it to:
access to attr=userPassword
        by dn="cn=master,dc=ivenue,dc=net" write
        by dn="cn=courier,dc=ivenue,dc=net" read
        by dn="cn=sendmail,dc=ivenue,dc=net" read
        by dn="cn=pam,dc=ivenue,dc=net" read
        by self write
        by * none
access to *
        by dn="cn=master,dc=ivenue,dc=net" write
        by * read


Here is the command that I ran:
ldapsearch -x -h ldap2 -D 'cn=master,dc=ivenue,dc=net' -w secret -b
'dc=ivenue,dc=net' 'shadowMax=*'
ldap_bind: Insufficient access (50)


Here are the logs (log level 128) for the above command:
Sep 14 13:10:06 ldap2 slapd[6461]: => access_allowed: auth access to "cn=master,dc=ivenue,dc=net" "userPassword" requested
Sep 14 13:10:06 ldap2 slapd[6461]: => acl_get: [1] check attr userPassword
Sep 14 13:10:06 ldap2 slapd[6461]: <= acl_get: [1] acl cn=master,dc=ivenue,dc=net attr: userPassword
Sep 14 13:10:06 ldap2 slapd[6461]: => acl_mask: access to entry "cn=master,dc=ivenue,dc=net", attr "userPassword" requested
Sep 14 13:10:06 ldap2 slapd[6461]: => acl_mask: to all values by "", (=n) 
Sep 14 13:10:06 ldap2 slapd[6461]: <= check a_dn_pat: cn=master,dc=ivenue,dc=net
Sep 14 13:10:06 ldap2 slapd[6461]: <= check a_dn_pat: cn=courier,dc=ivenue,dc=net
Sep 14 13:10:06 ldap2 slapd[6461]: <= check a_dn_pat: cn=sendmail,dc=ivenue,dc=net
Sep 14 13:10:06 ldap2 slapd[6461]: <= check a_dn_pat: cn=pam,dc=ivenue,dc=net
Sep 14 13:10:06 ldap2 slapd[6461]: <= check a_dn_pat: self
Sep 14 13:10:06 ldap2 slapd[6461]: <= check a_dn_pat: *
Sep 14 13:10:06 ldap2 slapd[6461]: <= acl_mask: [6] applying none(=n) (stop)
Sep 14 13:10:06 ldap2 slapd[6461]: <= acl_mask: [6] mask: none(=n)
Sep 14 13:10:06 ldap2 slapd[6461]: => access_allowed: auth access denied by none

I can make the search work properly with "by * auth", but then that
seems like it would allow any user with a valid password to then view
the userPassword field.  That is not acceptable.

... 10 minutes later ...

I did more tests with "by * auth".  It does seem to be working properly
with it.  I did several searches for RDN 'uid=todd.misterball.com':
1) as anonymous returning everything except for userPassword field.
Proper.
2) as 'uid=todd.misterball.com' returning everything *including*
userPassword field.  Proper.
3) as 'uid=cannonball.misterball.com' returning everything except for
userPassword field.  Proper.
4) as 'cn=master' returning everything *including* userPassword field.
Proper.

So it does seem like the last thing should be auth instead of none.  It
seems counter-intuitive because I don't want just anybody that can
authenticate a password to be able to look at the userPassword field.
But I'm stumped as to why it works properly.

... 10 minutes later ...

Much clearer, I think I've got it.  I was seeing the bind attempt fail
because I had 'by * none' so it couldn't even check to see if the
password was correct for user 'cn=master' since the initial bind was as
anonymous.  After binding to auth the password, then it attempts to
elevate its priveleges to search.  Look at the following successful log
snippet, comments inline:

Sep 14 13:27:40 ldap2 slapd[6625]: => access_allowed: auth access to "uid=todd.misterball.com,ou=users,dc=ivenue,dc=net" "userPassword" requested
  ****** Comment: This is the initial bind attempt ******
Sep 14 13:27:40 ldap2 slapd[6625]: => acl_get: [1] check attr userPassword
Sep 14 13:27:40 ldap2 slapd[6625]: <= acl_get: [1] acl uid=todd.misterball.com,ou=users,dc=ivenue,dc=net attr: userPassword 
Sep 14 13:27:40 ldap2 slapd[6625]: => acl_mask: access to entry "uid=todd.misterball.com,ou=users,dc=ivenue,dc=net", attr "userPassword" requested
Sep 14 13:27:40 ldap2 slapd[6625]: => acl_mask: to all values by "", (=n) 
Sep 14 13:27:40 ldap2 slapd[6625]: <= check a_dn_pat: cn=master,dc=ivenue,dc=net
Sep 14 13:27:40 ldap2 slapd[6625]: <= check a_dn_pat: cn=courier,dc=ivenue,dc=net
Sep 14 13:27:40 ldap2 slapd[6625]: <= check a_dn_pat: cn=sendmail,dc=ivenue,dc=net
Sep 14 13:27:40 ldap2 slapd[6625]: <= check a_dn_pat: cn=pam,dc=ivenue,dc=net
Sep 14 13:27:40 ldap2 slapd[6625]: <= check a_dn_pat: self
Sep 14 13:27:40 ldap2 slapd[6625]: <= check a_dn_pat: *
Sep 14 13:27:40 ldap2 slapd[6625]: <= acl_mask: [6] applying auth(=x) (stop)
Sep 14 13:27:40 ldap2 slapd[6625]: <= acl_mask: [6] mask: auth(=x)
  ****** Comment: Means allowed to check password ******
Sep 14 13:27:40 ldap2 slapd[6625]: => access_allowed: auth access granted by auth(=x)
  ****** Comment: Password was correct ******
Sep 14 13:27:41 ldap2 slapd[6625]: => access_allowed: search access to "uid=todd.misterball.com,ou=users,dc=ivenue,dc=net" "uid" requested
  ****** Comment: now the real request ******
Sep 14 13:27:41 ldap2 slapd[6625]: => acl_get: [1] check attr uid
Sep 14 13:27:41 ldap2 slapd[6625]: => acl_get: [2] check attr uid
Sep 14 13:27:41 ldap2 slapd[6625]: <= acl_get: [2] acl uid=todd.misterball.com,ou=users,dc=ivenue,dc=net attr: uid
Sep 14 13:27:41 ldap2 slapd[6625]: => acl_mask: access to entry "uid=todd.misterball.com,ou=users,dc=ivenue,dc=net", attr "uid" requested
Sep 14 13:27:41 ldap2 slapd[6625]: => acl_mask: to value by "uid=todd.misterball.com,ou=users,dc=ivenue,dc=net", (=n) 
Sep 14 13:27:41 ldap2 slapd[6625]: <= check a_dn_pat: cn=master,dc=ivenue,dc=net
Sep 14 13:27:41 ldap2 slapd[6625]: <= check a_dn_pat: *
Sep 14 13:27:41 ldap2 slapd[6625]: <= acl_mask: [2] applying read(=rscx) (stop)
Sep 14 13:27:41 ldap2 slapd[6625]: <= acl_mask: [2] mask: read(=rscx)
Sep 14 13:27:41 ldap2 slapd[6625]: => access_allowed: search access granted by read(=rscx
  ****** Comment: Now given privilege to search for things ******

I'm sending this entire email because in the archives it might serve a
bit of understanding for ACL debugging and understanding.  Please
correct my interpretations if they are wrong.
-- 
Regards...		Todd
  We should not be building surveillance technology into standards.
  Law enforcement was not supposed to be easy.  Where it is easy, 
  it's called a police state.             -- Jeff Schiller on NANOG
Linux kernel 2.6.3-16mdkenterprise   load average: 0.08, 0.03, 0.01