OpenLDAP and related stuff
From NBSWiki
Contents |
posixGroups to groupOfNames
Some notes on when I had to move from the archaic posixGroups objectClass to groupOfNames (which also implied moving from OpenLDAP 2.3 to 2.4...but that has no relevance here):
Environment vars
These variables will be used in most command lines to simplify the documentation:
DC="dc=division,dc=domain,dc=tld" LDAP_MANAGER="cn=Manager,$DC" LDAP_PWD="the_ldap_password" LDAP_SRC="ldap.division.domain.tld" LDAP_DEST="localhost" # we assume localhost is used to perform migration tests ;)
Preparations
- Make sure no empty groups exist as this is not permitted for groupOfNames. I had few groups so I used Luma for that (:P).
- Dump the database into LDIF format
ldapsearch -x -LLL -D $LDAP_MANAGER -w $LDAP_PWD -h $LDAP_SRC -b $DC > backup.ldif
slapd.conf
Modifications to be made to slapd.conf, we essentially replace nis.schema with rfc2307bis.schema (which we got from http://simonraven.kisikew.org/src/ldap/rfc2307bis.schema and commented out the 2 first entries as they are 'built in') and add the memberof overlay capabilities:
cd /etc/openldap/schema wget http://simonraven.kisikew.org/src/ldap/rfc2307bis.schema
Remove the 2 first entries:
vi rfc2307bis.schema # builtin #attributetype ( 1.3.6.1.1.1.1.0 NAME 'uidNumber' # DESC 'An integer uniquely identifying a user in an administrative domain' # EQUALITY integerMatch # SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) # builtin #attributetype ( 1.3.6.1.1.1.1.1 NAME 'gidNumber' # DESC 'An integer uniquely identifying a group in an administrative domain' # EQUALITY integerMatch # SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) ...
In the following, note the addition of moduleload memberof.la in the global configuration and overlay memberof in the database specific section.
| File: Contents of slapd.conf |
My final slapd.conf file looks like: include /etc/openldap/schema/core.schema include /etc/openldap/schema/cosine.schema include /etc/openldap/schema/inetorgperson.schema include /etc/openldap/schema/openldap.schema include /etc/openldap/schema/rfc2307bis.schema include /etc/openldap/schema/misc.schema include /etc/openldap/schema/samba.schema modulepath /usr/lib/openldap/openldap moduleload memberof.la pidfile /var/run/openldap/slapd.pid argsfile /var/run/openldap/slapd.args timelimit 600 database bdb suffix "dc=division,dc=domain,dc=tld" rootdn "cn=Manager,dc=division,dc=domain,dc=tld" rootpw the_ldap_password directory /var/lib/openldap-bdb lastmod on index objectClass eq index cn,sn,uid pres,sub,eq index displayName pres,sub,eq index uidNumber eq index gidNumber eq index memberUID eq overlay memberof threads 128 tool-threads 3 loglevel 0 |
New DB initalization
To start off the LDAP DB, we need a base, here is an example for an LDAP server which is a standalone division of a bigger domain (division.domain.tld):
| File: Contents of base.ldif |
dn: dc=division,dc=domain,dc=tld dc: division objectClass: dcObject objectClass: organization description: A division o: Division of the big company structuralObjectClass: organization creatorsName: cn=Manager,dc=division,dc=domain,dc=tld modifiersName: cn=Manager,dc=division,dc=domain,dc=tld dn: cn=Manager,dc=division,dc=domain,dc=tld cn: Manager objectClass: organizationalRole structuralObjectClass: organizationalRole creatorsName: cn=Manager,dc=division,dc=domain,dc=tld modifiersName: cn=Manager,dc=division,dc=domain,dc=tld |
Since I tend to go through many trial and errors while importing LDAP DBs, I tend to pack a few commands into a single line to reset the test environment if something goes wrong. The following line effectively deletes the current DB (as per the above slapd.conf file), re-creates the folder, imports the base.ldif file and restarts the slapd daemon in foreground in debug mode:
rm -Rf /var/lib/openldap-bdb && mkdir /var/lib/openldap-bdb && slapadd -l base.ldif && /usr/lib64/openldap/slapd -d 256
Importing People
Directly from the current LDAP server, we import the People OU:
ldapsearch -x -LLL -D $LDAP_MANAGER -w $LDAP_PWD -h $LDAP_SRC -b ou=People,$DC | ldapadd -h $LDAP_DEST -D $LDAP_MANAGER -w $LDAP_PWD
Importing Groups
Same thing, except that we convert posixGroup into groupOfNames 'on the fly':
ldapsearch -x -LLL -h $LDAP_SRC -b ou=Group,$DC -D $LDAP_MANAGER -w $LDAP_PWD | \ sed -e 's/objectClass: posixGroup/objectClass: posixGroup\nobjectClass: groupOfNames/' -e "s/memberUid: \(.*\)/member: uid=\1,ou=People,$DC/" | \ ldapadd -h $LDAP_DEST -D $LDAP_MANAGER -w $LDAP_PWD
(cool huh :P )
cleaning up groups
for I in `ldapsearch -x -LLL -h localhost -b ou=Group,$DC member|grep member: | cut -f2 -d' '|sort|uniq`; do ldapsearch -LLL -h localhost -b "$I" >/dev/null 2>&1 || echo $I; done|egrep -v '^$'
ldap.conf
Here is a very simplistic ldap.conf file used for TESTING the authorization (in my context, kerberos is used for authentification). Now, note that host is localhost, to be eventually replaced by the proper LDAP server host. Also note that I am purposefully leaving in the actual Domain Context and an example filter for nss_base_passwd for usage purposes. The employeeType is a text field I use to sort out user types (given a lack of proper departmental schema to describe such relationships and user states):
| File: Contents of ldap.conf |
host localhost base dc=livia,dc=etsmtl,dc=ca #rootbinddn cn=Manager,dc=livia,dc=etsmtl,dc=ca nss_base_passwd ou=People,dc=livia,dc=etsmtl,dc=ca?one?|(employeeType=prof)(employeeType=etudiant)(employeeType=ancien) nss_base_shadow ou=People,dc=livia,dc=etsmtl,dc=ca?one nss_base_group ou=Group,dc=livia,dc=etsmtl,dc=ca?one # Nouveau 'mapping' des groupes (E.T. 01-2010) nss_schema rfc2307bis nss_map_attribute memberUid member nss_reconnect_tries 2 nss_initgroups_ignoreusers root,ldap,named,avahi,haldaemon,dbus,news,mailman,nscd,gdm,apache |
References
This mailing list thread hinted on the "nss_map_attribute member memberUid" for ldap.conf, although it goies the other way around (inverted to be memberUid member).
I found late in this process that the Gentoo wiki has a rather elaborate article on using LDAP and Kerberos as an AD from which I picked a few tricks
