Tabs to spaces in LDAP post.
[blog.git] / posts / LDAP.mdwn
1 I'm using [LDAP][] ([RFC 4510][rfc4510]) to maintain a centralized
2 address book at home.  Here are my setup notes, mostly following
3 Gentoo's [LDAP howto][howto].
4
5 Install [OpenLDAP][] with the `ldap` USE flag enabled:
6
7     # emerge -av openldap
8
9 If you get complaints about a `cyrus-sasl` ↔ `openldap` dependency
10 cycle, you should temporarily (or permanently) disable the `ldap` USE
11 flag for `cyrus-sasl`:
12
13     # echo 'dev-libs/cyrus-sasl -ldap' > /etc/portage/package.use/ldap
14     # -ldap" emerge -av1 cyrus-sasl
15     # emerge -av openldap
16
17 Generate an administrative password:
18
19     $ slappasswd 
20     New password: 
21     Re-enter new password: 
22     {SSHA}EzP6I82DZRnW+ou6lyiXHGxSpSOw2XO4
23
24 Configure the `slapd` LDAP server.  Here is a very minimal
25 configuration, read the [OpenLDAP Admin Guide][admin] for details:
26
27     # emacs /etc/openldap/slapd.conf
28     # cat /etc/openldap/slapd.conf
29     include         /etc/openldap/schema/core.schema
30     include         /etc/openldap/schema/cosine.schema
31     include         /etc/openldap/schema/inetorgperson.schema
32     pidfile         /var/run/openldap/slapd.pid
33     argsfile        /var/run/openldap/slapd.args
34     database        hdb
35     suffix          "dc=example,dc=com"
36     checkpoint      32      30
37     rootdn          "cn=Manager,dc=example,dc=com"
38     rootpw          {SSHA}EzP6I82DZRnW+ou6lyiXHGxSpSOw2XO4
39     directory       /var/lib/openldap-data
40     index   objectClass     eq
41
42 Note that [inetorgperson][] is huge, but it's standardized.  I think
43 it's better to pick a big standard right off, than to outgrow
44 something smaller and need to migrate.
45
46 Gentoo creates the default database directory for you, so you can ignore warnings about needing to create it yourself.
47
48 Configure LDAP client access.  Again, read the docs for details on
49 adapting this to your particular situation:
50
51     # emacs /etc/openldap/ldap.conf
52     $ cat /etc/openldap/ldap.conf
53     BASE    dc=example,dc=com
54     URI     ldap://ldapserver.example.com
55
56 You can edit '/etc/conf.d/slapd' if you want command line options
57 passed to `slapd` when the service starts, but the defaults looked
58 fine to me.
59
60 Start `slapd`:
61
62     # /etc/init.d/slapd start
63
64 Add it to your default runlevel:
65
66     # eselect rc add /etc/init.d/slapd default
67
68 Test the server with
69
70     $ ldapsearch -x -b '' -s base '(objectclass=*)'
71
72 Build a hierarchy in your database (this will depend on your
73 organizational structure):
74
75     $ emacs /tmp/people.ldif
76     $ cat /tmp/people.ldif
77     version: 1
78
79     dn: dc=example, dc=com
80     objectClass: dcObject
81     objectClass: organization
82     o: Example, Inc.
83     dc: example
84
85     dn: ou=people, dc=example,dc=com
86     objectClass: organizationalUnit
87     ou: people
88     description: All people in organisation
89
90     dn: cn=Manager, dc=example,dc=com
91     objectClass: organizationalRole
92     cn: Manager
93     description: Directory Manager
94     $ ldapadd -D "cn=Manager,dc=example,dc=com" -xW -f /tmp/people.ldif
95     $ rm /tmp/people.ldif
96
97 abook
98 -----
99
100 If you currently keep your addresses in [abook][], you can export them
101 to [LDIF][] with:
102
103     $ abook --convert --infile ~/.abook/addressbook --outformat ldif \
104       | abook-ldif-cleanup.py --basedn 'ou=people,dc=example,dc=com' > dump.ldif
105
106 where [[abook-ldif-cleanup.py]] does some compatibility processing
107 using the [python-ldap][] module.
108
109 Add the people to your LDAP database:
110
111     $ ldapadd -D "cn=Manager,dc=example,dc=com" -xW -f dump.ldif
112
113 To check if that worked, you can list all the entries in your
114 database:
115
116     $ ldapsearch -x -b 'dc=example,dc=com' '(objectclass=*)'
117
118 Then remove the temporary files:
119
120     $ rm -rf dump.ldif
121
122 Aliases
123 -------
124
125 Ok, we've put lots of people into the `people` OU, but what if we want
126 to assign them to another department?  We can use aliases ([RFC
127 4512][rfc4512]), the symlinks of the LDAP world.  To see how this
128 works, lets create a test OU to play with:
129
130     $ emacs /tmp/test.ldif
131     $ cat /tmp/test.ldif
132     version: 1
133     dn: ou=test, dc=example,dc=com
134     objectClass: organizationalUnit
135     ou: testing
136     $ ldapadd -D "cn=Manager,dc=example,dc=com" -xW -f /tmp/test.ldif
137     $ rm /tmp/test.ldif
138
139 Now assign one of your people to that group:
140
141     $ emacs /tmp/alias.ldif
142     $ cat /tmp/alias.ldif
143     version: 1
144     dn: cn=Jane Doe, ou=test,dc=example,dc=com
145     objectClass: alias
146     aliasedObjectName: cn=Jane Doe, ou=people,dc=example,dc=com
147     $ ldapadd -D "cn=Manager,dc=example,dc=com" -xW -f /tmp/alias.ldif
148     $ rm /tmp/alias.ldif
149
150 The `extensibleObject` class allows us to add the DN field, without it
151 you get:
152
153     $ ldapadd -D "cn=Manager,dc=example,dc=com" -xW -f /tmp/alias.ldif
154     Enter LDAP Password: 
155     adding new entry "cn=Jane Doe, ou=test,dc=example,dc=com"
156     ldap_add: Object class violation (65)
157             additional info: attribute 'cn' not allowed
158
159 You can search for all entries (including aliases) with
160
161     $ ldapsearch -x -b 'ou=test, dc=example,dc=com' '(objectclass=*)'
162     ...
163     dn: cn=Jane Doe,ou=test,dc=example,dc=com
164     objectClass: alias
165     objectClass: extensibleObject
166     aliasedObjectName:: Y249TWljaGVsIFZhbGxpw6hyZXMsb3U9cGVvcGxlLGRjPXRyZW1pbHksZGM9dXM=
167     ...
168
169 You can control dereferencing with the `-a` option:
170
171     $ ldapsearch -x -a always -b 'ou=test, dc=example,dc=com' '(objectclass=*)'
172     ...
173     dn: cn=Jane Doe,ou=people,dc=example,dc=com
174     cn: Jane Doe
175     sn: Doe
176     ...
177
178 Once you've played around, you can remove the `test` OU and its
179 descendants:
180
181     $ ldapdelete -D "cn=Manager,dc=example,dc=com" -xW -r ou=test,dc=example,dc=com
182
183 shelldap
184 --------
185
186 There are a number of tools to make it easier to manage LDAP
187 databases.  Command line junkies will probably like [shelldap][]:
188
189     $ shelldap --server ldapserver.example.com
190     ~ > ls
191     cn=Manager
192     ou=people
193     ~ > cat cn=Manager 
194     
195     dn: cn=Manager,dc=example,dc=com
196     objectClass: organizationalRole
197     cn: Manager
198     
199     ~ > cd ou=people 
200     ou=people,~ > ls
201
202 References
203 ----------
204
205 There's a [good overview][schema] of schema and objectclasses by Brian
206 Jones on O'Reilly.  If you want to use inetOrgPerson but also include
207 the countryName attribute, ...
208
209 [LDAP]: http://en.wikipedia.org/wiki/LDAP
210 [rfc4510]: http://tools.ietf.org/html/rfc4510
211 [howto]: http://www.gentoo.org/doc/en/ldap-howto.xml
212 [OpenLDAP]: http://www.openldap.org/
213 [admin]: http://www.openldap.org/doc/admin/
214 [inetorgperson]: http://www.apps.ietf.org/rfc/rfc2798.html
215 [abook]: http://abook.sourceforge.net/
216 [LDIF]: http://en.wikipedia.org/wiki/LDAP_Data_Interchange_Format
217 [python-ldap]: http://www.python-ldap.org/
218 [rfc4512]: http://tools.ietf.org/html/rfc4512
219 [shelldap]: http://projects.martini.nu/shelldap/
220 [schema]: http://www.oreillynet.com/pub/a/sysadmin/2006/11/09/demystifying-ldap-data.html