Now that we’ve installed the openLDAP server, it is possible to add data to it. Data in a directory is modelled as a tree (called a DIT for directory information tree). We’ve created the root of the tree when we installed and configured slapd. The root or top of the tree is the “base” entry and it has a distinguished name of “dc=telperion,dc=org”. We want to add a user branch (called “people”) and a group branch (called “groups”). Entries in the “people” branch of the DIT are leaves of the tree and contain the uid and other information about users. Entries in the “groups” branch are leaves and contain information about Unix groups.
We’ll create a user named “lobelia” who is a member of the group “telperionusers”. The tree looks like this:
If we were to add more users and another special group for privileged users, the tree may expand to look something like this:
To create the user, we’ll create the tree in an LDIF file (we’ll name this one add-user.ldif). A unix user needs more than just a name. Even if Lobelia doesn’t get the keys to Bag End, she’ll at least need a home directory.
dn: ou=people,dc=telperion,dc=org objectClass: organizationalUnit ou: people dn: ou=groups,dc=telperion,dc=org objectClass: organizationalUnit ou: groups dn: cn=telperionusers,ou=groups,dc=telperion,dc=org objectClass: posixGroup cn: telperionusers gidNumber: 5000 dn: uid=lobelia,ou=people,dc=telperion,dc=org objectClass: inetOrgPerson objectClass: posixAccount objectClass: shadowAccount uid: lobelia sn: Sackville-Baggins givenName: Lobelia cn: Lobelia Sackville-Baggins displayName: Lobelia uidNumber: 10000 gidNumber: 5000 userPassword: lobelialdappassword gecos: Lobelia Sackville-Baggins loginShell: /bin/bash homeDirectory: /home/lobelia
Use ldapadd command to add the user by passing the LDIF file.
root@barad-dur:~# ldapadd -x -D cn=admin,dc=telperion,dc=org -W -f add-user.ldif Enter LDAP Password: adding new entry "ou=people,dc=telperion,dc=org" adding new entry "ou=groups,dc=telperion,dc=org" adding new entry "cn=telperionusers,ou=groups,dc=telperion,dc=org" adding new entry "uid=lobelia,ou=people,dc=telperion,dc=org"
Now that we’ve added a user, we can lookup that user by using ldapsearch. This ldapsearch command looks in the base tree “dc=telperion,dc-org” for an entry with a “uid” attribute equal to “lobelia”. It also displays the cn, the uidNumber, and the gidNumber.
root@barad-dur:~# ldapsearch -x -LLL -b dc=telperion,dc=org 'uid=lobelia' cn uidNumber gidNumber userPassword dn: uid=lobelia,ou=people,dc=telperion,dc=org cn: Lobelia Sackville-Baggins uidNumber: 10000 gidNumber: 5000
The default access control list does not let a user other than lobelia access her password. You can see that it was not displayed even though it was requested. We can now authenticate as lobelia (either local or from another server) to see the password (stored as a hash)
dave@fangorn:~/ldapsetup$ ldapsearch -x -D uid=lobelia,ou=people,dc=telperion,dc=org -W -LLL -H ldap://barad-dur.telperion.org -b dc=telperion,dc=org uid=lobelia userPassword Enter LDAP Password: <type 'lobelialdappassword'> dn: uid=lobelia,ou=people,dc=telperion,dc=org userPassword:: bG9iZWxpYWxkYXBwYXNzd29yZA==
We can see the default access control lists by querying the config file information on database access:
root@barad-dur:~# ldapsearch -Q -LLL -Y EXTERNAL -H ldapi:/// -b olcDatabase={1}mdb,cn=config olcAccess dn: olcDatabase={1}mdb,cn=config olcAccess: {0}to attrs=userPassword by self write by anonymous auth by * none olcAccess: {1}to attrs=shadowLastChange by self write by * read olcAccess: {2}to * by * read
Access Control Lists (ACLs) are parsed and the first one found that matches the situation is applied. When we searched earlier for lobelia’s password, the userPassword attribute was found and because we were anonymously logging in, we were given the “none” access. When we logged in as lobelia and requested the password, lobelia matched as “self” and we were given read access to the userPassword attribute value (write implies read access). The second access control statement defines access to the shadowLastChange attribute. A user can update it (self) and all users can read it. The third access control statement permits read access to everything else.
Now that lobelia has access, she probably should change her password. We haven’t configured any front ends to handle this yet and we can use ldapmodify to update the password field but ldap utils provides the ldappasswd command explicitly for this purpose. After changing the password, we can verify that it changed by authenticating with it to perform an ldapsearch.
dave@fangorn:~$ ldappasswd -x -D uid=lobelia,ou=people,dc=telperion,dc=org -H ldap://barad-dur.telperion.org -w lobelialdappassword -a lobelialdappassword -s ihatebilbo davd@fangorn:~$ ldapsearch -x -D uid=lobelia,ou=people,dc=telperion,dc=org -LLL -H ldap://barad-dur.telperion.org -w ihatebilbo -b uid=lobelia,ou=people,dc=telperion,dc=org dn: uid=lobelia,ou=people,dc=telperion,dc=org objectClass: inetOrgPerson objectClass: posixAccount objectClass: shadowAccount uid: lobelia sn: Sackville-Baggins givenName: Lobelia cn: Lobelia Sackville-Baggins displayName: Lobelia uidNumber: 10000 gidNumber: 5000 gecos: Lobelia Sackville-Baggins loginShell: /bin/bash homeDirectory: /home/lobelia userPassword:: e1NTSEF9dmJ5N0Iwbk5IeEx1VXR0WjBXSWRUQVdrQWlXRlpsSzQ=
We performed the password update from the fangorn client computer. Cool, right? NO. Not cool. All of that traffic was sent in cleartext over an open network. Eventually we can authenticate with SASL and kerberos but first, we can encrypt the transport layer with TLS to prevent little golems from stealing password information. I’ll cover that in another post.