030c1f9fe822a08678b2d7758405d87f0065ac52
[debian/sudo] / README.LDAP
1 This file explains how to use the optional LDAP functionality of SUDO to
2 store /etc/sudoers information.  This feature is distinct from LDAP passwords.
3
4 LDAP philosophy
5 ===============
6 As times change and servers become cheap, an enterprise can easily have 500+
7 UNIX servers.  Using LDAP to synchronize Users, Groups, Hosts, Mounts, and
8 others across an enterprise can greatly reduce the administrative overhead.
9
10 Sudo in the past has only used a single local configuration file /etc/sudoers.
11 Some have attempted to workaround this by synchronizing changes via
12 RCS/CVS/RSYNC/RDIST/RCP/SCP and even NFS.  Many have asked for a Hesiod, NIS,
13 or LDAP patch for sudo, so here is my attempt at LDAP'izing sudo.
14
15 For information on OpenLDAP, please see http://www.openldap.org/.
16
17 Definitions
18 ===========
19 Many times the word 'Directory' is used in the document to refer to the LDAP
20 server, structure and contents.
21
22 Many times 'options' are used in this document to refer to sudoer 'defaults'.
23 They are one and the same.
24
25 Design Features
26 ===============
27
28   * Sudo no longer needs to read sudoers in its entirety.  Parsing of
29     /etc/sudoers requires the entire file to be read.  The LDAP feature of sudo
30     uses two (sometimes three) LDAP queries per invocation.  It never reads all
31     the sudoer entries in the LDAP store.  This makes it especially fast and
32     particularly usable in LDAP environments.  The first query is to parse
33     default options (see below).  The second is to match against the username or
34     groups a user belongs to.  (The special ALL tag is matched in this query
35     too.) If no match is made against the username, the third query pulls the
36     entries that match against user netgroups to compare back to the user.
37
38   * Sudo no longer blows up if there is a typo.  Parsing of /etc/sudoers can
39     still blow up when sudo is invoked.  However when using the LDAP feature of
40     sudo, LDAP syntax rules are applied before the data is uploaded into the
41     LDAP server, so proper syntax is always guaranteed!  One can of course still
42     insert a bogus hostname or username, but sudo will not care.
43
44   * Options inside of entries now override global default options.
45     /etc/sudoers allowed for only default options and limited options associated
46     with user/host/command aliases.  The syntax can be difficult for the newbie.
47     The LDAP feature attempts to simplify this and yet still provide maximum
48     flexibility.
49
50     Sudo first looks for an entry called 'cn=default' in the SUDOers container.
51     If found, the multi-valued sudoOption attribute is parsed the same way the
52     global 'Defaults' line in /etc/sudoers is parsed.
53
54     If on the second or third query, a response contains a sudoRole which
55     matches against the user, host, and command, then the matched object is
56     scanned for a additional options to override the top-level defaults.  See
57     the example LDAP content below for more information.
58
59   * Visudo is no longer needed.  Visudo provides locking and syntax checking
60     against the /etc/sudoers file.  Since LDAP updates are atomic, locking is no
61     longer necessary.  Because syntax is checked when the data is inserted into
62     LDAP, the sudoers syntax check becomes unnecessary.
63
64   * Aliases are no longer needed.  User, Host, and Command Aliases were setup
65     to allow simplification and readability of the sudoers files.  Since the
66     LDAP sudoer entry allows multiple values for each of its attributes and
67     since most LDAP browsers are graphical and easy to work with, original
68     aliases are no longer needed.
69
70     If you want to specify lots of users into an entry or want to have similar
71     entries with identical users, then use either groups or user netgroups.
72     Thats what groups and netgroups are for and Sudo handles this well.
73     Alternately, one can just paste them all into the LDAP record.
74
75     If you want to specify lots of hosts into an entry, use netgroups or IP
76     address matches (10.2.3.4/255.255.0.0).  Thats what netgroups are for and
77     Sudo handles this well.  Or just past them all into the LDAP record.
78
79     If you want to specify lots of commands, use directories or wildcards, or
80     just paste them all into LDAP.  That's what it's for.
81
82   * The /etc/sudoers file can be disabled.  Paranoid security administrators
83     can now disallow parsing of any local /etc/sudoers file by an LDAP
84     sudoOption 'ignore_local_sudoers'.  This way all sudoers can be controlled
85     and audited in one place because local entries are not allowed.
86     In fact, if this option is included in the cn=defaults object of LDAP,
87     sudo won't even look for a /etc/sudoers file.
88
89   * The sudo binary compiled with LDAP support should be totally backward
90     compatible and be syntactically and source code equivalent to its non
91     LDAP-enabled build.
92
93
94 Build instructions
95 ==================
96 The most simplest way to build sudo with LDAP support is to include the
97 '--with-ldap' option.
98
99   $ ./configure --with-ldap
100
101 If your ldap libraries and headers are in a non-standard place, you will need
102 to specify them at configure time.  E.g.
103
104   $ ./configure --with-ldap=/usr/local/ldapsdk
105
106 Sudo is developed using OpenLDAP.  Other LDAP implementations may
107 require adding '-lldif' to SUDO_LIBS in the Makefile.
108
109 Your Mileage may vary.  Please let the sudo workers mailing list
110 <sudo-workers@sudo.ws> know what combinations worked best for your
111 OS and LDAP Combinations so we can improve sudo.
112
113 More Build Notes:
114 HP-UX 11.23 (gcc3) Galen Johnson <Galen.Johnson@sas.com>
115   CFLAGS="-D__10_10_compat_code" LDFLAGS="-L/opt/ldapux/lib"
116
117 Schema Changes
118 ==============
119 Add the appropriate schema to your LDAP server so that it may contain
120 sudoers content.
121
122 For OpenLDAP, simply copy schema.OpenLDAP to the schema directory
123 (e.g. /etc/openldap/schema) and 'include' it in your slapd.conf and
124 restart slapd.  For other LDAP servers, provide this to your LDAP
125 Administrator.  Make sure to index the attribute 'sudoUser'.
126
127 For the SunONE or iPlanet LDAP server, use the schema.iPlanet file.
128
129 Importing /etc/sudoers to LDAP
130 ==============================
131 Importing is a two step process.
132
133 Step 1:
134 Ask your LDAP Administrator where to create the ou=SUDOers container.
135
136 For instance, if using OpenLDAP:
137
138   dn: ou=SUDOers,dc=example,dc=com
139   objectClass: top
140   objectClass: organizationalUnit
141   ou: SUDOers
142
143 (An example location is shown below).  Then use the provided script to convert
144 your sudoers file into LDIF format.  The script will also convert any default
145 options.
146
147   # SUDOERS_BASE=ou=SUDOers,dc=example,dc=com
148   # export SUDOERS_BASE
149   # ./sudoers2ldif /etc/sudoers > /tmp/sudoers.ldif
150
151 Step 2:
152 Import into your directory server.  If you are using OpenLDAP, do the following
153 if you are using another directory, provide the LDIF file to your LDAP
154 Administrator.  An example is shown below.
155
156   # ldapadd -f /tmp/sudoers.ldif -h ldapserver \
157   > -D cn=Manager,dc=example,dc=com -W -x
158
159 Example sudoers Entries in LDAP
160 ===============================
161 The equivalent of a sudoer in LDAP is a 'sudoRole'.  It contains sudoUser(s),
162 sudoHost, sudoCommand and optional sudoOption(s) and sudoRunAs(s).
163 <put an example here>
164
165 Managing LDAP entries
166 =====================
167 Doing a one-time bulk load of your ldap entries is fine.  However what if you
168 need to make minor changes on a daily basis?  It doesn't make sense to delete
169 and re-add objects.  (You can, but this is tedious).
170
171 I recommend using any of the following LDAP browsers to administer your SUDOers.
172   * GQ - The gentleman's LDAP client - Open Source - I use this a lot on Linux
173     and since it is Schema aware, I don't need to create a sudoRole template.
174         http://biot.com/gq/
175
176   * LDAP Browser/Editor - by Jarek Gawor - I use this a lot on Windows
177     and Solaris.  It runs anywhere in a Java Virtual Machine including
178     web pages.  You have to make a template from an existing sudoRole entry.
179         http://www.iit.edu/~gawojar/ldap
180         http://www.mcs.anl.gov/~gawor/ldap
181         http://ldapmanager.com
182
183   There are dozens of others, some open source, some free, some not.
184
185
186 Configure your /etc/ldap.conf
187 =============================
188 The /etc/ldap.conf file is meant to be shared between sudo, pam_ldap, nss_ldap
189 and other ldap applications and modules.  IBM Secureway unfortunately uses
190 the same filename but has a different syntax.  If you need to rename where
191 this file is stored, recompile SUDO with the -DLDAP_CONFIG compile option.
192
193 Make sure you sudoers_base matches exactly with the location you specified
194 when you imported the sudoers.  Below is an example /etc/ldap.conf
195
196   # Either specify a uri or host & port
197   #host          ldapserver
198   #port          389
199   #
200   # URI will override host & port settings
201   # but only works with LDAP SDK's that support
202   # ldap_initialize() such as OpenLDAP
203   uri            ldap://ldapserver
204   #uri            ldaps://secureldapserver
205   #
206   # must be set or sudo will ignore LDAP
207   sudoers_base   ou=SUDOers,dc=example,dc=com
208   #
209   # verbose sudoers matching from ldap
210   #sudoers_debug 2
211   #
212   # optional proxy credentials
213   #binddn        <who to search as>
214   #bindpw        <password>
215   #rootbinddn    <who to search as, uses /etc/ldap.passwd for bindpw>
216   #
217   # LDAP Protocol Version defaults to 3
218   #ldap_version 3
219   #
220   # Define if you want to use port 389 and switch to
221   # encryption before the bind credentials are sent
222   #ssl start_tls
223   #
224   # Additional TLS options follow that allow tweaking
225   # of the SSL/TLS connection
226   #
227   #tls_checkpeer yes # verify server SSL certificate
228   #tls_checkpeer no  # ignore server SSL certificate
229   #
230   # If you enable tls_checkpeer, specify either tls_cacertfile
231   # or tls_cacertdir.
232   #
233   #tls_cacertfile /etc/certs/trusted_signers.pem
234   #tls_cacertdir  /etc/certs
235   #
236   # For systems that don't have /dev/random
237   # use this along with PRNGD or EGD.pl to seed the
238   # random number pool to generate cryptographic session keys.
239   #
240   #tls_randfile /etc/egd-pool
241   #
242   # You may restrict which ciphers are used.  Consult your SSL
243   # documentation for which options go here.
244   #
245   #tls_ciphers <cipher-list>
246   #
247   # Sudo can provide a client certificate when communicating to
248   # the LDAP server.
249   # Tips:
250   #   * Enable both lines at the same time.
251   #   * Do not password protect the key file.
252   #   * Ensure the keyfile is only readable by root.
253   #
254   #tls_cert /etc/certs/client_cert.pem
255   #tls_key  /etc/certs/client_key.pem
256   #
257
258 Debugging your LDAP configuration
259 =================================
260 Enable debugging if you believe sudo is not parsing LDAP the way you think it
261 it should.  A value of 1 shows moderate debugging.  A value of 2 shows the
262 results of the matches themselves.  Make sure to set the value back to zero
263 so that other users don't get confused by the debugging messages.  This value
264 is 'sudoers_debug' in the /etc/ldap.conf.
265
266 Parsing Differences between /etc/sudoers and LDAP
267 =================================================
268 There are some subtle differences in the way sudoers is handled once in LDAP.
269 Probably the biggest is that according to the RFC, LDAP's ordering is
270 arbitrary and you cannot expect that Attributes & Entries are returned in
271 any order.  If there are conflicting command rules on an entry, the negative
272 takes precedence.  This is called paranoid behavior (not necessarily the
273 most specific match).
274
275 Here is an example:
276
277   # /etc/sudoers:
278   # Allow all commands except shell
279   johnny  ALL=(root) ALL,!/bin/sh
280   # Always allows all commands because ALL is matched last
281   puddles ALL=(root) !/bin/sh,ALL
282
283   # LDAP equivalent of Johnny
284   # Allows all commands except shell
285   dn: cn=role1,ou=Sudoers,dc=my-domain,dc=com
286   objectClass: sudoRole
287   objectClass: top
288   cn: role1
289   sudoUser: johnny
290   sudoHost: ALL
291   sudoCommand: ALL
292   sudoCommand: !/bin/sh
293
294   # LDAP equivalent of Puddles
295   # Notice that even though ALL comes last, it still behaves like
296   # role1 since the LDAP code assumes the more paranoid configuration
297   dn: cn=role2,ou=Sudoers,dc=my-domain,dc=com
298   objectClass: sudoRole
299   objectClass: top
300   cn: role2
301   sudoUser: puddles
302   sudoHost: ALL
303   sudoCommand: !/bin/sh
304   sudoCommand: ALL
305
306 Another difference is that negations on the Host, User or Runas are
307 currently ignorred.  For example, these attributes do not work how they first
308 seem.  If you desperately want this to be changed, contact Aaron Spangler
309 (aaron@spangler.ods.org).
310
311   # does not match all but joe
312   # rather, does not match anyone
313   sudoUser: !joe
314
315   # does not match all but joe
316   # rather, matches everyone including Joe
317   sudoUser: ALL
318   sudoUser: !joe
319
320   # does not match all but web01
321   # rather, matches all hosts including web01
322   sudoHost: ALL
323   sudoHost: !web01
324
325
326 Configure your /etc/nsswitch.conf
327 =================================
328 At the time of this writing, sudo does not consult nsswitch.conf for the
329 search order.  But if it did, it would look like this:
330 This might be implemented in the future.  For now just skip this step.
331
332   sudoers: files ldap