I have a domain (let's call it dc=example,dc=org)

The domain has a branch (ou=users,ou=ftp,ou=services,dc=k9999,dc=z9999,dc=infra,dc=example,dc=org).

There's a simpleSecurityObject in this domain (uid=admin,ou=managers,ou=ftp,ou=services,dc=k9999,dc=z9999,dc=infra,dc=example,dc=org).

I need the uid=admin,*** user to have full (manage) access to the ou=users,*** branch, so I added the following olcAccess record:


It has added to the default set of rules:

dn: olcDatabase={1}mdb,cn=config
olcAccess: {0}to * by dn.exact=gidNumber=0+uidNumber=0,cn=peercred,cn=external
 ,cn=auth manage by * break
olcAccess: {1}to attrs=userPassword,shadowLastChange by self write by dn="cn=a
 dmin,dc=example,dc=org" write by anonymous auth by * none
olcAccess: {2}to * by self read by dn="cn=admin,dc=example,dc=org" write by
 * none
olcAccess: {3}to dn.subtree="ou=users,ou=ftp,ou=services,dc=k9999,dc=z9999,dc=
 infra,dc=example,dc=org" by dn.exact="uid=admin,ou=managers,ou=ftp,ou=servi
 ces,dc=k9999,dc=z9999,dc=infra,dc=example,dc=org" manage

But something seems to be wrong. When I run ldapsearch -D uid=admin,ou=managers,ou=ftp,ou=services,dc=k9999,dc=z9999,dc=infra,dc=example,dc=org -W -b ou=users,ou=ftp,ou=services,dc=k9999,dc=z9999,dc=infra,dc=example,dc=org, I get the following result:

# extended LDIF
# LDAPv3
# base <ou=users,ou=ftp,ou=services,dc=k9999,dc=z9999,dc=infra,dc=example,dc=org> with scope subtree
# filter: (objectclass=*)
# requesting: ALL

# search result
search: 2
result: 32 No such object

# numResponses: 1
command terminated with exit code 32

The object is available and cn=admin,dc=example,dc=org can see it without any difficulties, so it seems that my access rule is wrong. But what exactly it is?

It seems that the default rule #2 ({2} to * by self read by dn="cn=admin,dc=example,dc=org" write by * none) fires up earlier than the rule I added. Does that mean that I should always add my custom rules before it?

And why does this rule has by * none? Doesn't it contradict the OpenLDAP documentation?

The default access control policy is allow read by all clients

It seems that rule #2 (I mean this one:

to * 
by self read
by dn="cn=admin,dc=example,dc=org" write
by * none

) isn't "default" at all. I've just found another instance of OpenLDAP (I deployed it about 4 years ago). This instance (2.4.40) doesn't have such rule at all. It seems that it has not been added by OpenLDAP itself, it rather has been added manually by someone or something else. Am I right? Doesn't OpenLDAP have such rule by default?

  • If you're serious about delegated administration, dynamic views for service etc. you might want to have a closer look at Æ-DIR. Being the author I'm biased of course. Jan 6, 2022 at 19:03

1 Answer 1


General advice:

  • Order matters!
    This general statement applies to order of ACLs and order of the <who> clauses.
  • Each ACL implicitly ends with a by * none which means control flows stops there.
  • Debug ACLs by running slapd with loglevel stats ACL
  • Read slapd.access(5) very carefully and not only once!

E.g. AFAICS in your example ACL #2 masks ACL #3.

Do yourself a favour: Instead of inventing this wheel ad-hoc again have a closer look at my Æ-DIR. It has many ACLs for enforcing delegated administration and limiting visibility based on a clear data model. Being the author I'm biased of course. Otherwise I know very well how much work is in front of you if you follow that route...

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .