-1

I need to add a bunch of ACLs for my database but am having hard time writing proper LDIF for it. Unfortunately, ldapmodify is not very helpful with its useless error message:

modifying entry "olcDatabase={1}mdb,cn=config"
ldap_modify: Other (e.g., implementation specific) error (80)
         additional info: <olcAccess> handler exited with 1

I currently have the following pretty basic configuration for my MDB database (it has been created by the Debian package configurator for the slapd package, version 2.4.40):

# {1}mdb, config
dn: olcDatabase={1}mdb,cn=config
objectClass: olcDatabaseConfig
objectClass: olcMdbConfig
olcDatabase: {1}mdb
olcDbDirectory: /var/lib/ldap
olcSuffix: dc=domain,dc=lan
olcAccess: {0}to attrs=userPassword,shadowLastChange
   by self write
   by anonymous auth
   by * none
olcAccess: {1}to dn.base="" by * read
olcAccess: {2}to * by * read
# ... and more

Since I'm setting the database to use as an authentication backend for SAMBA, the database schema has been updated to include SAMBA-specific types and attributes, and now I want to tighten the ACLs on the database accordingly.

What I want to accomplish can be stated like this:

  • The sambaLMPassword and sambaNTPassword SAMBA-specific attributes (available on entries of the posixAccount class) should only be readable/modifiable by their respective owners (self, that is).
  • A special user, dn=sambaAdmin,dc=domain,dc=lan has been created, and is designated to be used by SAMBA itself and smbldap-tools to manage SAMBA-specific users in the database. It should be granted full access to a set of SAMBA-specific OUs in the DIT.

I want my ACL entries be inserted between the rules {0} and {1} in the current config.

To achieve what's outlined above, I've prepared the following LDIF file which I'm trying to apply using ldapmodify and am getting the error presented above.

# {1}mdb, config
dn: olcDatabase={1}mdb,cn=config
changetype: modify
add: olcAccess
olcAccess: {1}to dn.subtree="ou=Users,dc=domain,dc=lan"
   attrs=sambaLMPassword,sambaNTPassword
   by self write
   by dn=sambaAdmin,dc=domain,dc=lan write
   by anonymous auth
   by * none
olcAccess: {2}to dn.subtree="ou=Computers,dc=domain,dc=lan"
   attrs=sambaLMPassword,sambaNTPassword
   by self write
   by dn=sambaAdmin,dc=domain,dc=lan write
   by anonymous auth
   by * none
 olcAccess: {3}to dn.subtree="ou=Users,dc=domain,dc=lan"
   by dn=sambaAdmin,dc=domain,dc=lan write
 olcAccess: {4}to dn.subtree="ou=Groups,dc=domain,dc=lan"
   by dn=sambaAdmin,dc=domain,dc=lan write
 olcAccess: {5}to dn.subtree="ou=Computers,dc=domain,dc=lan"
   by dn=sambaAdmin,dc=domain,dc=lan write
 olcAccess: {6}to dn.subtree="ou=Idmap,dc=domain,dc=lan"
   by dn=sambaAdmin,dc=domain,dc=lan write
 olcAccess: {7}to dn=sambaDomainName=MYSERVER,dc=domain,dc=lan
   by dn=sambaAdmin,dc=domain,dc=lan write

Unfortunately, LDIF passes the syntax check (ldapmodify -n -v <path/to/file.ldif), and the error message is really unhelpful.

Could anyway please help me fix my LDIF to be accepted by slapd? Or explain me a way to configure it (or ldapmodify may be?) to be more verbose about the real cause of this error?

kostix
  • 1,150
  • 1
  • 7
  • 13

2 Answers2

6

Another, much easier, answer is to use the ldapvi command to edit the olcAccess entries:

ldapvi -h ldapi:// -Y EXTERNAL -b cn=config 

It dumps all of cn=config into VIM, lets you edit it at your leisure, then when you save and quit figures out the LDIF for you. I just added another olcAccess: attribute, renumbered the existing ones, and it worked seamlessly.

TexasDex
  • 86
  • 1
  • 2
5

ldapmodify is lying to you about the validity of your file. If you take the LDIF file you created and run

ldapmodify -v -n -f <path/to/file.ldif>

The output looks like this:

add olcAccess:
    {1}to dn.subtree="ou=Users,dc=domain,dc=lan" attrs=sambaLMPassword,sambaNTPassword  by self write  by dn=sambaAdmin,dc=domain,dc=lan write  by anonymous auth  by * none
    {2}to dn.subtree="ou=Computers,dc=domain,dc=lan"  attrs=sambaLMPassword,sambaNTPassword  by self write  by dn=sambaAdmin,dc=domain,dc=lan write  by anonymous auth  by * noneolcAccess: {3}to dn.subtree="ou=Users,dc=domain,dc=lan"  by dn=sambaAdmin,dc=domain,dc=lan writeolcAccess: {4}to dn.subtree="ou=Groups,dc=domain,dc=lan"  by dn=sambaAdmin,dc=domain,dc=lan writeolcAccess: {5}to dn.subtree="ou=Computers,dc=domain,dc=lan"  by dn=sambaAdmin,dc=domain,dc=lan writeolcAccess: {6}to dn.subtree="ou=Idmap,dc=domain,dc=lan"  by dn=sambaAdmin,dc=domain,dc=lan writeolcAccess: {7}to dn=sambaDomainName=MYSERVER,dc=domain,dc=lan  by dn=sambaAdmin,dc=domain,dc=lan write
!modifying entry "olcDatabase={1}mdb,cn=config"

Notice how all of the ACLs are jammed together? This is because you don't have a "-" between each entry. For some reason ldapmodify passes this file when you run it with the "-n" switch in dry-run mode but fails when you actually try to implement it. You should change your LDIF file to look like this:

 dn: olcDatabase={1}mdb,cn=config
 add: olcAccess
 olcAccess: {0}to attrs=userPassword,shadowLastChange by self write
 by anonymous auth
 by * none
 -
 add: olcAccess
 olcAccess: {1}to dn.subtree="ou=Users,dc=domain,dc=lan"
 attrs=sambaLMPassword,sambaNTPassword by self write by
 dn="cn=sambaAdmin,dc=domain,dc=lan" write by anonymous auth by * none
 -
 add: olcAccess
 olcAccess: {2}to dn.subtree="ou=Computers,dc=domain,dc=lan"
 attrs=sambaLMPassword,sambaNTPassword by self write by 
 dn=sambaAdmin,dc=domain,dc=lan write by anonymous auth by * none
 -
 add: olcAccess
 olcAccess: {3}to dn.subtree="ou=Users,dc=domain,dc=lan" by
 dn=sambaAdmin,dc=domain,dc=lan write
 -
 add: olcAccess
 olcAccess: {4}to dn.subtree="ou=Groups,dc=domain,dc=lan" by 
 dn=sambaAdmin,dc=domain,dc=lan write
 -
 add: olcAccess
 olcAccess: {5}to dn.subtree="ou=Computers,dc=domain,dc=lan" by   
 dn=sambaAdmin,dc=domain,dc=lan write
 -
 add: olcAccess
 olcAccess: {6}to dn.subtree="ou=Idmap,dc=domain,dc=lan" by
 dn=sambaAdmin,dc=domain,dc=lan write
 -
 add: olcAccess
 olcAccess: {7}to dn=sambaDomainName=MYSERVER,dc=domain,dc=lan by
 dn=sambaAdmin,dc=domain,dc=lan write
 -
 add: olcAccess
 olcAccess: {8}to dn.base="" by * read
 -

The code formatting is deceptive, but you want to have each of the ACL definitions on a single line starting at column 0, you want to separate each entry with a "-" and you want to make sure that the ACL definition doesn't have a space at the end or ldapmodify will encrypt the string.

If you're editing with vi/vim use the :set list command to reveal punctuation characters like carriage returns and remove them and make sure that there isn't any whitespace at the end of the line. After you've done this the output of

ldapmodify -v -n -f <path/to/file.ldif>

will look like this:

add olcAccess:
    {0}to attrs=userPassword,shadowLastChange by self write by anonymous auth by * none
add olcAccess:
    {1}to dn.subtree="ou=Users,dc=domain,dc=lan"
attrs=sambaLMPassword,sambaNTPassword by self write by
dn="cn=sambaAdmin,dc=domain,dc=lan" write by anonymous auth by * none
add olcAccess:
    {2}to dn.subtree="ou=Computers,dc=domain,dc=lan"
attrs=sambaLMPassword,sambaNTPassword by self write by    
dn=sambaAdmin,dc=domain,dc=lan write by anonymous auth by * none
add olcAccess:
    {3}to dn.subtree="ou=Users,dc=domain,dc=lan" by
dn=sambaAdmin,dc=domain,dc=lan write
add olcAccess:
    {4}to dn.subtree="ou=Groups,dc=domain,dc=lan" by   
dn=sambaAdmin,dc=domain,dc=lan write
add olcAccess:
    {5}to dn.subtree="ou=Computers,dc=domain,dc=lan" by
dn=sambaAdmin,dc=domain,dc=lan write
add olcAccess:
    {6}to dn.subtree="ou=Idmap,dc=domain,dc=lan" by
dn=sambaAdmin,dc=domain,dc=lan write
add olcAccess:
    {7}to dn=sambaDomainName=MYSERVER,dc=domain,dc=lan by
dn=sambaAdmin,dc=domain,dc=lan write
add olcAccess:
    {8}to dn.base="" by * read
!modifying entry "olcDatabase={1}mdb,cn=config"

Another problem I noticed is your use of the "modify" keyword, if you're adding new entries to an LDAP schema or deleting entries you don't need to use modify, modify is only used when you're modifying an existing entry. I've found that the easiest way to modify a group of ACLs like this is to open a couple of windows on my LDAP server, prepare my new ACLs, test them with ldapmodify using the -n switch and then su to root in each window, delete the existing ACLs and then add the new ones. You can delete all of your existing ACLs with an LDIF file that looks like this:

# {1}mdb, config
dn: olcDatabase={1}mdb,cn=config
delete: olcAccess

and then run ldapmodify

ldapmodify -Y EXTERNAL -H ldapi:/// -f <path/to/acl_delete_file.ldif>

to delete them. After running ldapmodify run

slapcat -n 0

to verify that the ACLs have been deleted and then run

ldapmodify -Y EXTERNAL -H ldapi:/// -f <path/to/new_acl_file.ldif>

to add your new ACLs and then run

slapcat -n 0

again to verify that they're in place.