"no global superior knowledge" while adding a country

I must add an organizationalunit like this into a freshly installed OpenLDAP (on Ubuntu 12.04) :

dn: ou=MYREGION, ou=MYAPP, ou=GROUPS, o=myorganization, c=fr
ou: MYREGION
objectClass: top
objectClass: organizationalunit

So as it's a new LDAP, I think I must first add the fr country, and I create that file :

dn: c=fr
c: fr
objectClass: top
objectClass: country

Now I try to import it with that command (I have no domain for that server) :

ldapadd -x -D cn=admin,dc=nodomain -W -f country_fr.ldif

but OpenLDAP rejects that command with :

adding new entry "c=fr"
ldap_add: Server is unwilling to perform (53)
    additional info: no global superior knowledge

Any hint?


Solution 1:

The error no global superior knowledge means that slapd doesn't know where to put your new entry. This typically means that you have not defined an appropriate database. With newer systems (ones using cn=config instead of slapd.conf), you would typically first add a new database or modify an existing database entry using ldapadd or ldapmodify. For example, on my Fedora 17 system, the default install sets up a database like this for hosting dc=my-domain,dc=com:

dn: olcDatabase={2}hdb
objectClass: olcDatabaseConfig
objectClass: olcHdbConfig
olcDatabase: {2}hdb
olcDbDirectory: /var/lib/ldap
olcDbIndex: objectClass eq,pres
olcDbIndex: ou,cn,mail,surname,givenname eq,pres,sub
structuralObjectClass: olcHdbConfig
creatorsName: cn=config
olcSuffix: dc=my-domain,dc=com
olcRootDN: cn=Manager,dc=my-domain,dc=com

To host your organization (o=myorganization, c=fr), I would need to create the following LDIF file:

dn: olcDatabase={2}hdb,cn=config
changetype: modify
replace: olcSuffix
olcSuffix: o=myorganization, c=fr
-
replace: olcRootDN
olcRootDN: cn=Manager,o=myorganization,c=fr
-
replace: olcAccess
olcAccess: {0}to * 
  by dn.base="gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth" write 
  by dn.base="cn=Manager,o=myorganization,c=fr" write
  by * none

And I would then load these modifications like this:

ldapmodify -Y EXTERNAL -H ldapi:/// -f mychanges.ldif

This works because of the following olcAccess lines already present in the configuration:

dn: olcDatabase={0}config,cn=config
objectClass: olcDatabaseConfig
olcDatabase: {0}config
olcAccess: {0}to * 
  by dn.base="gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth" manage
  by * none

This grants root, contacting slapd over the ldapi:/// socket, password-free access to the cn=config tree.

I would then load in my top-level entry:

dn: o=myorganization, c=fr
objectclass: organization
o: myorganization

By running:

ldapadd -Y EXTERNAL -H ldapi:/// -f myobject.ldif

This works because I've added a similar ACL to this database. Note that I didn't need to start with c=fr here, because the database is defined to hold o=myorganization,c=fr

Solution 2:

Thanks to larsks answer, here is what I did.

First here is an extract of the default configuration with Ubuntu 12.04 (file /etc/ldap/slapd.d/cn=config/olcDatabase={1}hdb.ldif):

dn: olcDatabase={1}hdb
objectClass: olcDatabaseConfig
objectClass: olcHdbConfig
olcDatabase: {1}hdb
olcDbDirectory: /var/lib/ldap
olcSuffix: dc=nodomain
olcAccess: {0}to attrs=userPassword,shadowLastChange by self write by anonymou
 s auth by dn="cn=admin,dc=nodomain" write by * none
olcAccess: {1}to dn.base="" by * read
olcAccess: {2}to * by self write by dn="cn=admin,dc=nodomain" write by * read
olcLastMod: TRUE
olcRootDN: cn=admin,dc=nodomain

So I created the following change_suffix.ldif:

dn: olcDatabase={1}hdb,cn=config
changetype: modify
replace: olcSuffix
olcSuffix: o=myorganization,c=fr
-
replace: olcRootDN
olcRootDN: cn=admin,o=myorganization,c=fr
-
replace: olcAccess
olcAccess: {0}to attrs=userPassword,shadowLastChange by self write by anonymous auth by dn="cn=admin,o=myorganization,c=fr" write by * none
olcAccess: {2}to * by self write by dn="cn=admin,o=myorganization,c=fr" write by * read

and added it to my ldap with the following command:

sudo ldapmodify -Y EXTERNAL -H ldapi:/// -f change_suffix.ldif

Now I had to create the organization node with the following myorganization.ldif:

dn: o=myorganization,c=fr
objectclass: organization
o: myorganization

And finally add it with the following command (the first one didn't work due to Insufficient access (50)):

ldapadd -x -D cn=admin,o=myorganization,c=fr -W -f myorganization.ldif

Now I could add the organizational units:

dn: ou=GROUPS, o=myorganization,c=fr
ou: GROUPS
objectClass: top
objectClass: organizationalunit

dn: ou=MYAPP, ou=GROUPS, o=myorganization,c=fr
ou: MYAPP
objectClass: top
objectClass: organizationalunit

dn: ou=MYREGION, ou=MYAPP, ou=GROUPS, o=myorganization,c=fr
ou: MYREGION
objectClass: top
objectClass: organizationalunit