1 diff -Nru -x Makefile -x 'buildpkg.*' -x opensshd.init -x 'ssh_prng_*' openssh-4.3p1/Makefile.in openssh-4.3p1-lpk/Makefile.in
2 --- openssh-4.3p1/Makefile.in 2006-01-01 09:47:05.000000000 +0100
3 +++ openssh-4.3p1-lpk/Makefile.in 2006-04-18 15:46:59.000000000 +0200
6 auth2-gss.o gss-serv.o gss-serv-krb5.o \
7 loginrec.o auth-pam.o auth-shadow.o auth-sia.o md5crypt.o \
9 + audit.o audit-bsm.o ldapauth.o
11 MANPAGES = scp.1.out ssh-add.1.out ssh-agent.1.out ssh-keygen.1.out ssh-keyscan.1.out ssh.1.out sshd.8.out sftp-server.8.out sftp.1.out ssh-rand-helper.8.out ssh-keysign.8.out sshd_config.5.out ssh_config.5.out
12 MANPAGES_IN = scp.1 ssh-add.1 ssh-agent.1 ssh-keygen.1 ssh-keyscan.1 ssh.1 sshd.8 sftp-server.8 sftp.1 ssh-rand-helper.8 ssh-keysign.8 sshd_config.5 ssh_config.5
13 diff -Nru -x Makefile -x 'buildpkg.*' -x opensshd.init -x 'ssh_prng_*' openssh-4.3p1/README.lpk openssh-4.3p1-lpk/README.lpk
14 --- openssh-4.3p1/README.lpk 1970-01-01 01:00:00.000000000 +0100
15 +++ openssh-4.3p1-lpk/README.lpk 2006-04-18 15:46:59.000000000 +0200
17 +OpenSSH LDAP PUBLIC KEY PATCH
18 +Copyright (c) 2003 Eric AUGE (eau@phear.org)
21 +Redistribution and use in source and binary forms, with or without
22 +modification, are permitted provided that the following conditions
24 +1. Redistributions of source code must retain the above copyright
25 + notice, this list of conditions and the following disclaimer.
26 +2. Redistributions in binary form must reproduce the above copyright
27 + notice, this list of conditions and the following disclaimer in the
28 + documentation and/or other materials provided with the distribution.
29 +3. The name of the author may not be used to endorse or promote products
30 + derived from this software without specific prior written permission.
32 +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
33 +IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
34 +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
35 +IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
36 +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
37 +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
38 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
39 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
40 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
41 +THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
43 +purposes of this patch:
45 +This patch would help to have authentication centralization policy
46 +using ssh public key authentication.
47 +This patch could be an alternative to other "secure" authentication system
48 +working in a similar way (Kerberos, SecurID, etc...), except the fact
49 +that it's based on OpenSSH and its public key abilities.
52 +'uid': means unix accounts existing on the current server
53 +'lpkServerGroup:' mean server group configured on the current server ('lpkServerGroup' in sshd_config)
58 + server1 (uid: eau,rival,toto) (lpkServerGroup: unix)
60 + / \ --- - server3 (uid: eau, titi) (lpkServerGroup: unix)
62 + | eau ,rival | server2 (uid: rival, eau) (lpkServerGroup: unix)
64 + | userx,.... | server5 (uid: eau) (lpkServerGroup: mail)
66 + ----- - server4 (uid: eau, rival) (no group configured)
72 + * configured LDAP server somewhere on the network (i.e. OpenLDAP)
73 + * patched sshd (with this patch ;)
74 + * LDAP user(/group) entry (look at users.ldif (& groups.ldif)):
76 + - attached to the 'ldapPublicKey' objectclass
77 + - attached to the 'posixAccount' objectclass
78 + - with a filled 'sshPublicKey' attribute
80 + dn: uid=eau,ou=users,dc=cuckoos,dc=net
83 + objectclass: organizationalPerson
84 + objectclass: posixAccount
85 + objectclass: ldapPublicKey
86 + description: Eric AUGE Account
93 + homeDirectory: /export/home/eau
94 + sshPublicKey: ssh-dss AAAAB3...
95 + sshPublicKey: ssh-dss AAAAM5...
98 + - attached to the 'posixGroup' objectclass
99 + - with a 'cn' groupname attribute
100 + - with multiple 'memberUid' attributes filled with usernames allowed in this group
103 + dn: cn=unix,ou=groups,dc=cuckoos,dc=net
105 + objectclass: posixGroup
106 + description: Unix based servers group
117 + If a user wants to authenticate to log in a server the sshd, will first look for authentication method allowed (RSAauth,kerberos,etc..)
118 + and if RSAauth and tickets based auth fails, it will fallback to standard password authentication (if enabled).
121 + If a user want to authenticate to log in a server, the sshd will first look for auth method including LDAP pubkey, if the ldappubkey options is enabled.
122 + It will do an ldapsearch to get the public key directly from the LDAP instead of reading it from the server filesystem.
123 + (usually in $HOME/.ssh/authorized_keys)
125 + If groups are enabled, it will also check if the user that wants to login is in the group of the server he is trying to log into.
126 + If it fails, it falls back on RSA auth files ($HOME/.ssh/authorized_keys), etc.. and finally to standard password authentication (if enabled).
128 + 7 tokens are added to sshd_config :
129 + # here is the new patched ldap related tokens
130 + # entries in your LDAP must be posixAccount & strongAuthenticationUser & posixGroup
131 + UseLPK yes # look the pub key into LDAP
132 + LpkServers ldap://10.31.32.5/ ldap://10.31.32.4 ldap://10.31.32.3 # which LDAP server for users ? (URL format)
133 + LpkUserDN ou=users,dc=foobar,dc=net # which base DN for users ?
134 + LpkGroupDN ou=groups,dc=foobar,dc=net # which base DN for groups ?
135 + LpkBindDN cn=manager,dc=foobar,dc=net # which bind DN ?
136 + LpkBindPw asecret # bind DN credidentials
137 + LpkServerGroup agroupname # the group the server is part of
139 + Right now i'm using anonymous binding to get public keys, because getting public keys of someone doesn't impersonate him¸ but there is some
140 + flaws you have to take care of.
142 +- HOW TO INSERT A USER/KEY INTO AN LDAP ENTRY
144 + * my way (there is plenty :)
145 + - create ldif file (i.e. users.ldif)
146 + - cat ~/.ssh/id_dsa.pub OR cat ~/.ssh/id_rsa.pub OR cat ~/.ssh/identity.pub
147 + - my way in 4 steps :
150 + # you add this to the user entry in the LDIF file :
152 + objectclass: posixAccount
153 + objectclass: ldapPublicKey
155 + sshPubliKey: ssh-dss AAAABDh12DDUR2...
158 + # insert your entry and you're done :)
159 + ldapadd -D balblabla -w bleh < file.ldif
161 + all standard options can be present in the 'sshPublicKey' attribute.
165 + Simply because, i was looking for a way to centralize all sysadmins authentication, easily, without completely using LDAP
166 + as authentication method (like pam_ldap etc..).
168 + After looking into Kerberos, SecurID, and other centralized secure authentications systems, the use of RSA and LDAP to get
169 + public key for authentication allows us to control who has access to which server (the user needs an account and to be in 'strongAuthenticationUser'
170 + objectclass within LDAP and part of the group the SSH server is in).
172 + Passwords update are no longer a nightmare for a server farm (key pair passphrase is stored on each user's box and private key is locally encrypted using his passphrase
173 + so each user can change it as much as he wants).
175 + Blocking a user account can be done directly from the LDAP (if sshd is using RSAAuth + ldap only).
178 + Entry in the LDAP server must respect 'posixAccount' and 'ldapPublicKey' which are defined in core.schema.
179 + and the additionnal lpk.schema.
181 + This patch could allow a smooth transition between standard auth (/etc/passwd) and complete LDAP based authentication
182 + (pamldap, nss_ldap, etc..).
184 + This can be an alternative to other (old?/expensive?) authentication methods (Kerberos/SecurID/..).
186 + Referring to schema at the beginning of this file if user 'eau' is only in group 'unix'
187 + 'eau' would ONLY access 'server1', 'server2', 'server3' AND 'server4' BUT NOT 'server5'.
188 + If you then modify the LDAP 'mail' group entry to add 'memberUid: eau' THEN user 'eau' would be able
189 + to log in 'server5' (i hope you got the idea, my english is bad :).
191 + Each server's sshd is patched and configured to ask the public key and the group infos in the LDAP
193 + When you want to allow a new user to have access to the server parc, you just add him an account on
194 + your servers, you add his public key into his entry on the LDAP server, it's done.
196 + Because sshds are looking public keys into the LDAP directly instead of a file ($HOME/.ssh/authorized_keys).
198 + When the user needs to change his passphrase he can do it directly from his workstation by changing
199 + his own key set lock passphrase, and all servers are automatically aware.
201 + With a CAREFUL LDAP server configuration you could allow a user to add/delete/modify his own entry himself
202 + so he can add/modify/delete himself his public key when needed.
205 + LDAP must be well configured, getting the public key of some user is not a problem, but if anonymous LDAP
206 + allow write to users dn, somebody could replace someuser's public key by its own and impersonate some
207 + of your users in all your server farm be VERY CAREFUL.
209 + MITM attack when sshd is requesting the public key, could lead to a compromise of your servers allowing login
210 + as the impersonnated user.
212 + If LDAP server is down then, fallback on passwd auth.
214 + the ldap code part has not been well audited yet.
216 +- LDAP USER ENTRY EXAMPLES (LDIF Format, look in users.ldif)
218 + dn: uid=jdoe,ou=users,dc=foobar,dc=net
220 + objectclass: person
221 + objectclass: organizationalPerson
222 + objectclass: posixAccount
223 + objectclass: ldapPublicKey
224 + description: My account
230 + homeDirectory: /home/jdoe
231 + sshPublicKey: ssh-dss AAAAB3NzaC1kc3MAAAEBAOvL8pREUg9wSy/8+hQJ54YF3AXkB0OZrXB....
235 +- LDAP GROUP ENTRY EXAMPLES (LDIF Format, look in groups.ldif)
237 + dn: cn=unix,ou=groups,dc=cuckoos,dc=net
239 + objectclass: posixGroup
240 + description: Unix based servers group
250 +Multiple 'sshPublicKey' in a user entry are allowed, as well as multiple 'memberUid' attributes in a group entry
254 + 2. ./configure --with-your-options --with-ldap=/prefix/to/ldap_libs_and_includes
259 + I hope this could help, and i hope to be clear enough,, or give ideas. questions/comments/improvements are welcome.
262 + Redesign differently.
265 + http://pacsec.jp/core05/psj05-barisani-en.pdf
266 + http://fritz.potsdam.edu/projects/openssh-lpk/
267 + http://fritz.potsdam.edu/projects/sshgate/
268 + http://www.opendarwin.org/projects/openssh-lpk/files/examples/lpk-usrdoc.txt
269 + http://lam.sf.net/ ( http://lam.sourceforge.net/documentation/supportedSchemas.htm )
271 +- CONTRIBUTORS/IDEAS/GREETS :
272 + - Falk Siemonsmeier -> 3.7 patch port candidate
273 + - Jacob Rief -> ideas (group && cleanups)
274 + - Michael.Durchgraf@dregis.com -> Bugfixes thanks ;)
275 + - frederic.peters@free.fr -> X509 keys LDAP patch (old)
277 + - finlay dobbie -> new fresh start with this guy :)
280 + - Eric AUGE <eau@phear.org>, <eau@opendarwin.org>
281 + - Andrea Barisani <lcars@opendarwin.org>
282 diff -Nru -x Makefile -x 'buildpkg.*' -x opensshd.init -x 'ssh_prng_*' openssh-4.3p1/auth-rsa.c openssh-4.3p1-lpk/auth-rsa.c
283 --- openssh-4.3p1/auth-rsa.c 2005-06-17 04:59:35.000000000 +0200
284 +++ openssh-4.3p1-lpk/auth-rsa.c 2006-04-18 15:46:59.000000000 +0200
285 @@ -160,10 +160,96 @@
289 +#ifdef WITH_LDAP_PUBKEY
291 + unsigned int i = 0;
294 /* Temporarily use the user's uid. */
295 temporarily_use_uid(pw);
297 +#ifdef WITH_LDAP_PUBKEY
298 + /* here is the job */
299 + key = key_new(KEY_RSA1);
301 + if (options.lpk.on) {
302 + debug("[LDAP] trying LDAP first uid=%s", pw->pw_name);
303 + if ( ldap_ismember(&options.lpk, pw->pw_name) > 0) {
304 + if ( (k = ldap_getuserkey(&options.lpk, pw->pw_name)) != NULL) {
305 + for (i = 0 ; i < k->num ; i++) {
306 + char *cp, *options = NULL;
308 + for (cp = k->keys[i]->bv_val; *cp == ' ' || *cp == '\t'; cp++)
310 + if (!*cp || *cp == '\n' || *cp == '#')
314 + * Check if there are options for this key, and if so,
315 + * save their starting address and skip the option part
316 + * for now. If there are no options, set the starting
319 + if (*cp < '0' || *cp > '9') {
322 + for (; *cp && (quoted || (*cp != ' ' && *cp != '\t')); cp++) {
323 + if (*cp == '\\' && cp[1] == '"')
324 + cp++; /* Skip both */
325 + else if (*cp == '"')
331 + /* Parse the key from the line. */
332 + if (hostfile_read_key(&cp, &bits, key) == 0) {
333 + debug("[LDAP] line %d: non ssh1 key syntax", i);
336 + /* cp now points to the comment part. */
338 + /* Check if the we have found the desired key (identified by its modulus). */
339 + if (BN_cmp(key->rsa->n, client_n) != 0)
342 + /* check the real bits */
343 + if (bits != (unsigned int)BN_num_bits(key->rsa->n))
344 + logit("[LDAP] Warning: ldap, line %lu: keysize mismatch: "
345 + "actual %d vs. announced %d.", (unsigned long)i, BN_num_bits(key->rsa->n), bits);
347 + /* We have found the desired key. */
349 + * If our options do not allow this key to be used,
350 + * do not send challenge.
352 + if (!auth_parse_options(pw, options, "[LDAP]", (unsigned long) i))
355 + /* break out, this key is allowed */
358 + /* add the return stuff etc... */
359 + /* Restore the privileged uid. */
362 + /* return key if allowed */
363 + if (allowed && rkey != NULL)
372 + logit("[LDAP] no keys found for '%s'!", pw->pw_name);
375 + logit("[LDAP] '%s' is not in '%s'", pw->pw_name, options.lpk.sgroup);
379 /* The authorized keys. */
380 file = authorized_keys_file(pw);
381 debug("trying public RSA key file %s", file);
382 diff -Nru -x Makefile -x 'buildpkg.*' -x opensshd.init -x 'ssh_prng_*' openssh-4.3p1/auth2-pubkey.c openssh-4.3p1-lpk/auth2-pubkey.c
383 --- openssh-4.3p1/auth2-pubkey.c 2004-12-11 03:39:50.000000000 +0100
384 +++ openssh-4.3p1-lpk/auth2-pubkey.c 2006-04-18 15:46:59.000000000 +0200
386 #include "monitor_wrap.h"
389 +#ifdef WITH_LDAP_PUBKEY
390 +#include "ldapauth.h"
394 extern ServerOptions options;
395 extern u_char *session_id2;
396 @@ -176,10 +180,79 @@
400 +#ifdef WITH_LDAP_PUBKEY
402 + unsigned int i = 0;
405 /* Temporarily use the user's uid. */
406 temporarily_use_uid(pw);
408 +#ifdef WITH_LDAP_PUBKEY
410 + /* allocate a new key type */
411 + found = key_new(key->type);
413 + /* first check if the options is enabled, then try.. */
414 + if (options.lpk.on) {
415 + debug("[LDAP] trying LDAP first uid=%s",pw->pw_name);
416 + if (ldap_ismember(&options.lpk, pw->pw_name) > 0) {
417 + if ((k = ldap_getuserkey(&options.lpk, pw->pw_name)) != NULL) {
418 + /* Skip leading whitespace, empty and comment lines. */
419 + for (i = 0 ; i < k->num ; i++) {
420 + /* dont forget if multiple keys to reset options */
421 + char *cp, *options = NULL;
423 + for (cp = (char *)k->keys[i]->bv_val; *cp == ' ' || *cp == '\t'; cp++)
425 + if (!*cp || *cp == '\n' || *cp == '#')
428 + if (key_read(found, &cp) != 1) {
429 + /* no key? check if there are options for this key */
431 + debug2("[LDAP] user_key_allowed: check options: '%s'", cp);
433 + for (; *cp && (quoted || (*cp != ' ' && *cp != '\t')); cp++) {
434 + if (*cp == '\\' && cp[1] == '"')
435 + cp++; /* Skip both */
436 + else if (*cp == '"')
439 + /* Skip remaining whitespace. */
440 + for (; *cp == ' ' || *cp == '\t'; cp++)
442 + if (key_read(found, &cp) != 1) {
443 + debug2("[LDAP] user_key_allowed: advance: '%s'", cp);
444 + /* still no key? advance to next line*/
449 + if (key_equal(found, key) &&
450 + auth_parse_options(pw, options, file, linenum) == 1) {
452 + debug("[LDAP] matching key found");
453 + fp = key_fingerprint(found, SSH_FP_MD5, SSH_FP_HEX);
454 + verbose("[LDAP] Found matching %s key: %s", key_type(found), fp);
456 + /* restoring memory */
464 + }/* end of LDAP for() */
466 + logit("[LDAP] no keys found for '%s'!", pw->pw_name);
469 + logit("[LDAP] '%s' is not in '%s'", pw->pw_name, options.lpk.sgroup);
473 debug("trying public key file %s", file);
475 /* Fail quietly if file does not exist */
476 diff -Nru -x Makefile -x 'buildpkg.*' -x opensshd.init -x 'ssh_prng_*' openssh-4.3p1/config.h.in openssh-4.3p1-lpk/config.h.in
477 --- openssh-4.3p1/config.h.in 2006-02-01 12:33:49.000000000 +0100
478 +++ openssh-4.3p1-lpk/config.h.in 2006-04-18 15:46:59.000000000 +0200
480 /* Define to 1 if you have the <linux/if_tun.h> header file. */
481 #undef HAVE_LINUX_IF_TUN_H
483 +/* Define if you want LDAP support */
484 +#undef WITH_LDAP_PUBKEY
486 /* Define if your libraries define login() */
489 diff -Nru -x Makefile -x 'buildpkg.*' -x opensshd.init -x 'ssh_prng_*' openssh-4.3p1/configure openssh-4.3p1-lpk/configure
490 --- openssh-4.3p1/configure 2006-02-01 12:33:51.000000000 +0100
491 +++ openssh-4.3p1-lpk/configure 2006-04-18 15:46:59.000000000 +0200
493 --with-tcp-wrappers[=PATH] Enable tcpwrappers support (optionally in PATH)
494 --with-libedit[=PATH] Enable libedit support for sftp
495 --with-audit=module Enable EXPERIMENTAL audit support (modules=debug,bsm)
496 + --with-ldap[=PATH] Enable LDAP support (optionally in PATH)
497 --with-pam Enable PAM support
498 --with-ssl-dir=PATH Specify path to OpenSSL installation
499 --with-rand-helper Use subprocess to gather strong randomness
500 @@ -11242,6 +11243,88 @@
504 +# Check whether user wants LDAP support
507 +# Check whether --with-ldap or --without-ldap was given.
508 +if test "${with_ldap+set}" = set; then
509 + withval="$with_ldap"
511 + if test "x$withval" != "xno" ; then
513 + if test "x$withval" != "xyes" ; then
514 + CPPFLAGS="$CPPFLAGS -I${withval}/include"
515 + LDFLAGS="$LDFLAGS -L${withval}/lib"
518 + cat >>confdefs.h <<\_ACEOF
519 +#define WITH_LDAP_PUBKEY 1
522 + LIBS="-lldap $LIBS"
525 + echo "$as_me:$LINENO: checking for LDAP support" >&5
526 +echo $ECHO_N "checking for LDAP support... $ECHO_C" >&6
527 + cat >conftest.$ac_ext <<_ACEOF
530 +cat confdefs.h >>conftest.$ac_ext
531 +cat >>conftest.$ac_ext <<_ACEOF
532 +/* end confdefs.h. */
533 +#include <sys/types.h>
538 +(void)ldap_init(0, 0);
543 +rm -f conftest.$ac_objext
544 +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
545 + (eval $ac_compile) 2>conftest.er1
547 + grep -v '^ *+' conftest.er1 >conftest.err
549 + cat conftest.err >&5
550 + echo "$as_me:$LINENO: \$? = $ac_status" >&5
551 + (exit $ac_status); } &&
552 + { ac_try='test -z "$ac_c_werror_flag"
553 + || test ! -s conftest.err'
554 + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
555 + (eval $ac_try) 2>&5
557 + echo "$as_me:$LINENO: \$? = $ac_status" >&5
558 + (exit $ac_status); }; } &&
559 + { ac_try='test -s conftest.$ac_objext'
560 + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
561 + (eval $ac_try) 2>&5
563 + echo "$as_me:$LINENO: \$? = $ac_status" >&5
564 + (exit $ac_status); }; }; then
565 + echo "$as_me:$LINENO: result: yes" >&5
566 +echo "${ECHO_T}yes" >&6
568 + echo "$as_me: failed program was:" >&5
569 +sed 's/^/| /' conftest.$ac_ext >&5
572 + echo "$as_me:$LINENO: result: no" >&5
573 +echo "${ECHO_T}no" >&6
574 + { { echo "$as_me:$LINENO: error: ** Incomplete or missing ldap libraries **" >&5
575 +echo "$as_me: error: ** Incomplete or missing ldap libraries **" >&2;}
576 + { (exit 1); exit 1; }; }
580 +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
589 @@ -28025,6 +28108,7 @@
590 echo " Smartcard support: $SCARD_MSG"
591 echo " S/KEY support: $SKEY_MSG"
592 echo " TCP Wrappers support: $TCPW_MSG"
593 +echo " LDAP support: $LDAP_MSG"
594 echo " MD5 password support: $MD5_MSG"
595 echo " libedit support: $LIBEDIT_MSG"
596 echo " IP address in \$DISPLAY hack: $DISPLAY_HACK_MSG"
597 diff -Nru -x Makefile -x 'buildpkg.*' -x opensshd.init -x 'ssh_prng_*' openssh-4.3p1/configure.ac openssh-4.3p1-lpk/configure.ac
598 --- openssh-4.3p1/configure.ac 2006-01-29 14:22:39.000000000 +0100
599 +++ openssh-4.3p1-lpk/configure.ac 2006-04-18 15:46:59.000000000 +0200
600 @@ -1134,6 +1134,37 @@
604 +# Check whether user wants LDAP support
607 + [ --with-ldap[[=PATH]] Enable LDAP support (optionally in PATH)],
609 + if test "x$withval" != "xno" ; then
611 + if test "x$withval" != "xyes" ; then
612 + CPPFLAGS="$CPPFLAGS -I${withval}/include"
613 + LDFLAGS="$LDFLAGS -L${withval}/lib"
616 + AC_DEFINE(WITH_LDAP_PUBKEY)
617 + LIBS="-lldap $LIBS"
620 + AC_MSG_CHECKING([for LDAP support])
622 + [#include <sys/types.h>
623 + #include <ldap.h>],
624 + [(void)ldap_init(0, 0);],
625 + [AC_MSG_RESULT(yes)],
628 + AC_MSG_ERROR([** Incomplete or missing ldap libraries **])
635 dnl Checks for library functions. Please keep in alphabetical order
638 @@ -3766,6 +3797,7 @@
639 echo " Smartcard support: $SCARD_MSG"
640 echo " S/KEY support: $SKEY_MSG"
641 echo " TCP Wrappers support: $TCPW_MSG"
642 +echo " LDAP support: $LDAP_MSG"
643 echo " MD5 password support: $MD5_MSG"
644 echo " libedit support: $LIBEDIT_MSG"
645 echo " IP address in \$DISPLAY hack: $DISPLAY_HACK_MSG"
646 diff -Nru -x Makefile -x 'buildpkg.*' -x opensshd.init -x 'ssh_prng_*' openssh-4.3p1/ldapauth.c openssh-4.3p1-lpk/ldapauth.c
647 --- openssh-4.3p1/ldapauth.c 1970-01-01 01:00:00.000000000 +0100
648 +++ openssh-4.3p1-lpk/ldapauth.c 2006-04-18 15:46:59.000000000 +0200
656 + * Copyright (c) 2005, Eric AUGE <eau@phear.org>
657 + * All rights reserved.
659 + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
661 + * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
662 + * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
663 + * Neither the name of the phear.org nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
665 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
666 + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
667 + * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
668 + * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
669 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
670 + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
675 +#include "includes.h"
677 +#ifdef WITH_LDAP_PUBKEY
684 +#include "ldapauth.h"
687 +static char *attrs[] = {
692 +/* filter building infos */
693 +#define FILTER_GROUP_PREFIX "(&(objectclass=posixGroup)"
694 +#define FILTER_OR_PREFIX "(|"
695 +#define FILTER_OR_SUFFIX ")"
696 +#define FILTER_CN_PREFIX "(cn="
697 +#define FILTER_CN_SUFFIX ")"
698 +#define FILTER_UID_FORMAT "(memberUid=%s)"
699 +#define FILTER_GROUP_SUFFIX ")"
700 +#define FILTER_GROUP_SIZE(group) (size_t) (strlen(group)+(ldap_count_group(group)*5)+52)
702 +/* just filter building stuff */
703 +#define REQUEST_GROUP_SIZE(filter, uid) (size_t) (strlen(filter)+strlen(uid)+1)
704 +#define REQUEST_GROUP(buffer, prefilter, pwname) \
705 + buffer = (char *) calloc(REQUEST_GROUP_SIZE(prefilter, pwname), sizeof(char)); \
707 + perror("calloc()"); \
710 + snprintf(buffer, REQUEST_GROUP_SIZE(prefilter,pwname), prefilter, pwname)
712 +XXX OLD group building macros
713 +#define REQUEST_GROUP_SIZE(grp, uid) (size_t) (strlen(grp)+strlen(uid)+46)
714 +#define REQUEST_GROUP(buffer,pwname,grp) \
715 + buffer = (char *) calloc(REQUEST_GROUP_SIZE(grp, pwname), sizeof(char)); \
717 + perror("calloc()"); \
720 + snprintf(buffer,REQUEST_GROUP_SIZE(grp,pwname),"(&(objectclass=posixGroup)(cn=%s)(memberUid=%s))",grp,pwname)
723 +#define REQUEST_USER_SIZE(uid) (size_t) (strlen(uid)+64)
724 +#define REQUEST_USER(buffer, pwname) \
725 + buffer = (char *) calloc(REQUEST_USER_SIZE(pwname), sizeof(char)); \
727 + perror("calloc()"); \
730 + snprintf(buffer,REQUEST_USER_SIZE(pwname),"(&(objectclass=posixAccount)(objectclass=ldapPublicKey)(uid=%s))",pwname)
732 +/* some portable and working tokenizer, lame though */
733 +static int tokenize(char ** o, size_t size, char * input) {
734 + unsigned int i = 0, num;
735 + char * charset = " \t";
736 + char * ptr = input;
738 + /* leading white spaces are ignored */
739 + num = strspn(ptr, charset);
742 + while ((num = strcspn(ptr, charset))) {
754 +void ldap_close(ldap_opt_t * ldap) {
759 + if ( ldap_unbind_ext(ldap->ld, NULL, NULL) < 0)
760 + ldap_perror(ldap->ld, "ldap_unbind()");
763 + FLAG_SET_DISCONNECTED(ldap->flags);
769 +int ldap_connect(ldap_opt_t * ldap) {
770 + int version = LDAP_VERSION3;
772 + if (!ldap->servers)
775 + /* Connection Init and setup */
776 + ldap->ld = ldap_init(ldap->servers, LDAP_PORT);
778 + ldap_perror(ldap->ld, "ldap_init()");
782 + if ( ldap_set_option(ldap->ld, LDAP_OPT_PROTOCOL_VERSION, &version) != LDAP_OPT_SUCCESS) {
783 + ldap_perror(ldap->ld, "ldap_set_option(LDAP_OPT_PROTOCOL_VERSION)");
787 + /* Timeouts setup */
788 + if (ldap_set_option(ldap->ld, LDAP_OPT_NETWORK_TIMEOUT, &ldap->b_timeout) != LDAP_SUCCESS) {
789 + ldap_perror(ldap->ld, "ldap_set_option(LDAP_OPT_NETWORK_TIMEOUT)");
791 + if (ldap_set_option(ldap->ld, LDAP_OPT_TIMEOUT, &ldap->s_timeout) != LDAP_SUCCESS) {
792 + ldap_perror(ldap->ld, "ldap_set_option(LDAP_OPT_TIMEOUT)");
796 + if ( (ldap->tls == -1) || (ldap->tls == 1) ) {
797 + if (ldap_start_tls_s(ldap->ld, NULL, NULL ) != LDAP_SUCCESS) {
798 + /* failed then reinit the initial connect */
799 + ldap_perror(ldap->ld, "ldap_connect: (TLS) ldap_start_tls()");
800 + if (ldap->tls == 1)
803 + ldap->ld = ldap_init(ldap->servers, LDAP_PORT);
805 + ldap_perror(ldap->ld, "ldap_init()");
809 + if ( ldap_set_option(ldap->ld, LDAP_OPT_PROTOCOL_VERSION, &version) != LDAP_OPT_SUCCESS) {
810 + ldap_perror(ldap->ld, "ldap_set_option()");
817 + if ( ldap_simple_bind_s(ldap->ld, ldap->binddn, ldap->bindpw) != LDAP_SUCCESS) {
818 + ldap_perror(ldap->ld, "ldap_simple_bind_s()");
822 + /* says it is connected */
823 + FLAG_SET_CONNECTED(ldap->flags);
828 +/* must free allocated ressource */
829 +static char * ldap_build_host(char *host, int port) {
830 + unsigned int size = strlen(host)+11;
831 + char * h = (char *) calloc (size, sizeof(char));
836 + rc = snprintf(h, size, "%s:%d ", host, port);
842 +static int ldap_count_group(char * input) {
843 + char * charset = " \t";
844 + char * ptr = input;
845 + unsigned int count = 0;
848 + num = strspn(ptr, charset);
851 + while ((num = strcspn(ptr, charset))) {
861 +char * ldap_parse_groups(char * groups) {
862 + unsigned int buffer_size = FILTER_GROUP_SIZE(groups);
863 + char * buffer = (char *) calloc(buffer_size, sizeof(char));
866 + unsigned int i = 0;
868 + if ((!groups)||(!buffer))
871 + g = strdup(groups);
877 + /* first separate into n tokens */
878 + if ( tokenize(garray, sizeof(garray)/sizeof(*garray), g) < 0) {
884 + /* build the final filter format */
885 + strlcat(buffer, FILTER_GROUP_PREFIX, buffer_size);
886 + strlcat(buffer, FILTER_OR_PREFIX, buffer_size);
888 + while (garray[i]) {
889 + strlcat(buffer, FILTER_CN_PREFIX, buffer_size);
890 + strlcat(buffer, garray[i], buffer_size);
891 + strlcat(buffer, FILTER_CN_SUFFIX, buffer_size);
894 + strlcat(buffer, FILTER_OR_SUFFIX, buffer_size);
895 + strlcat(buffer, FILTER_UID_FORMAT, buffer_size);
896 + strlcat(buffer, FILTER_GROUP_SUFFIX, buffer_size);
902 +/* a bit dirty but leak free */
903 +char * ldap_parse_servers(char * servers) {
905 + char * tmp = NULL, *urls[32];
906 + unsigned int num = 0 , i = 0 , asize = 0;
907 + LDAPURLDesc *urld[32];
912 + /* local copy of the arg */
913 + s = strdup(servers);
917 + /* first separate into URL tokens */
918 + if ( tokenize(urls, sizeof(urls)/sizeof(*urls), s) < 0)
923 + if ( ldap_is_ldap_url(urls[i]) ) {
924 + if (ldap_url_parse(urls[i], &urld[i]) != 0)
933 + /* how much memory do we need */
935 + for (i = 0 ; i < num ; i++)
936 + asize += strlen(urld[i]->lud_host)+11;
939 + s = (char *) calloc( asize+1 , sizeof(char));
941 + for (i = 0 ; i < num ; i++)
942 + ldap_free_urldesc(urld[i]);
946 + /* then build the final host string */
947 + for (i = 0 ; i < num ; i++) {
948 + /* built host part */
949 + tmp = ldap_build_host(urld[i]->lud_host, urld[i]->lud_port);
950 + strncat(s, tmp, strlen(tmp));
951 + ldap_free_urldesc(urld[i]);
958 +void ldap_options_print(ldap_opt_t * ldap) {
959 + printf("ldap options:\n");
960 + printf("servers: %s\n", ldap->servers);
961 + if (ldap->u_basedn)
962 + printf("user basedn: %s\n", ldap->u_basedn);
963 + if (ldap->g_basedn)
964 + printf("group basedn: %s\n", ldap->g_basedn);
966 + printf("binddn: %s\n", ldap->binddn);
968 + printf("bindpw: %s\n", ldap->bindpw);
970 + printf("group: %s\n", ldap->sgroup);
973 +void ldap_options_free(ldap_opt_t * l) {
996 +void ldap_keys_free(ldap_key_t * k) {
997 + ldap_value_free_len(k->keys);
1002 +ldap_key_t * ldap_getuserkey(ldap_opt_t *l, char * user) {
1003 + ldap_key_t * k = (ldap_key_t *) calloc (1, sizeof(ldap_key_t));
1004 + LDAPMessage *res, *e;
1011 + /* Am i still connected ? RETRY n times */
1012 + /* XXX TODO: setup some conf value for retrying */
1013 + if (!(l->flags & FLAG_CONNECTED))
1014 + for (i = 0 ; i < 2 ; i++)
1015 + if (ldap_connect(l) == 0)
1018 + /* build filter for LDAP request */
1019 + REQUEST_USER(filter, user);
1021 + if ( ldap_search_st( l->ld,
1023 + LDAP_SCOPE_SUBTREE,
1025 + attrs, 0, &l->s_timeout, &res ) != LDAP_SUCCESS) {
1027 + ldap_perror(l->ld, "ldap_search_st()");
1032 + /* XXX error on search, timeout etc.. close ask for reconnect */
1041 + /* check if any results */
1042 + i = ldap_count_entries(l->ld,res);
1044 + ldap_msgfree(res);
1050 + printf("[LDAP] duplicate entries, using the FIRST entry returned\n");
1052 + e = ldap_first_entry(l->ld, res);
1053 + k->keys = ldap_get_values_len(l->ld, e, PUBKEYATTR);
1054 + k->num = ldap_count_values_len(k->keys);
1056 + ldap_msgfree(res);
1062 + 0 if user is NOT member of current server group
1063 + 1 if user IS MEMBER of current server group
1065 +int ldap_ismember(ldap_opt_t * l, char * user) {
1070 + if ((!l->sgroup) || !(l->g_basedn))
1073 + /* Am i still connected ? RETRY n times */
1074 + /* XXX TODO: setup some conf value for retrying */
1075 + if (!(l->flags & FLAG_CONNECTED))
1076 + for (i = 0 ; i < 2 ; i++)
1077 + if (ldap_connect(l) == 0)
1080 + /* build filter for LDAP request */
1081 + REQUEST_GROUP(filter, l->fgroup, user);
1083 + if (ldap_search_st( l->ld,
1085 + LDAP_SCOPE_SUBTREE,
1087 + NULL, 0, &l->s_timeout, &res) != LDAP_SUCCESS) {
1089 + ldap_perror(l->ld, "ldap_search_st()");
1093 + /* XXX error on search, timeout etc.. close ask for reconnect */
1101 + /* check if any results */
1102 + if (ldap_count_entries(l->ld, res) > 0) {
1103 + ldap_msgfree(res);
1107 + ldap_msgfree(res);
1112 + * ldap.conf simple parser
1113 + * XXX TODO: sanity checks
1115 + * - free the previous ldap_opt_before replacing entries
1116 + * - free each necessary previously parsed elements
1118 + * -1 on FAILURE, 0 on SUCCESS
1120 +int ldap_parse_lconf(ldap_opt_t * l) {
1121 + FILE * lcd; /* ldap.conf descriptor */
1123 + char * s = NULL, * k = NULL, * v = NULL;
1126 + lcd = fopen (l->l_conf, "r");
1127 + if (lcd == NULL) {
1128 + /* debug("Cannot open %s", l->l_conf); */
1129 + perror("ldap_parse_lconf()");
1133 + while (fgets (buf, sizeof (buf), lcd) != NULL) {
1135 + if (*buf == '\n' || *buf == '#')
1140 + while (*v != '\0' && *v != ' ' && *v != '\t')
1148 + while (*v == ' ' || *v == '\t')
1151 + li = strlen (v) - 1;
1152 + while (v[li] == ' ' || v[li] == '\t' || v[li] == '\n')
1156 + if (!strcasecmp (k, "uri")) {
1157 + if ((l->servers = ldap_parse_servers(strdup (v))) == NULL) {
1158 + fatal("error in ldap servers");
1163 + else if (!strcasecmp (k, "base")) {
1164 + s = strchr (v, '?');
1167 + l->u_basedn = malloc (len + 1);
1168 + strncpy (l->u_basedn, v, len);
1169 + l->u_basedn[len] = '\0';
1171 + l->u_basedn = strdup (v);
1174 + else if (!strcasecmp (k, "binddn")) {
1175 + l->binddn = strdup (v);
1177 + else if (!strcasecmp (k, "bindpw")) {
1178 + l->bindpw = strdup (v);
1180 + else if (!strcasecmp (k, "timelimit")) {
1181 + l->s_timeout.tv_sec = atoi (v);
1183 + else if (!strcasecmp (k, "bind_timelimit")) {
1184 + l->b_timeout.tv_sec = atoi (v);
1186 + else if (!strcasecmp (k, "ssl")) {
1187 + if (!strcasecmp (v, "start_tls"))
1196 +#endif /* WITH_LDAP_PUBKEY */
1197 diff -Nru -x Makefile -x 'buildpkg.*' -x opensshd.init -x 'ssh_prng_*' openssh-4.3p1/ldapauth.h openssh-4.3p1-lpk/ldapauth.h
1198 --- openssh-4.3p1/ldapauth.h 1970-01-01 01:00:00.000000000 +0100
1199 +++ openssh-4.3p1-lpk/ldapauth.h 2006-04-18 15:46:59.000000000 +0200
1207 + * Copyright (c) 2005, Eric AUGE <eau@phear.org>
1208 + * All rights reserved.
1210 + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
1212 + * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
1213 + * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
1214 + * Neither the name of the phear.org nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
1216 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
1217 + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
1218 + * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
1219 + * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
1220 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
1221 + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1229 +#include <string.h>
1234 +/* tokens in use for config */
1235 +#define _DEFAULT_LPK_TOKEN "UseLPK"
1236 +#define _DEFAULT_SRV_TOKEN "LpkServers"
1237 +#define _DEFAULT_USR_TOKEN "LpkUserDN"
1238 +#define _DEFAULT_GRP_TOKEN "LpkGroupDN"
1239 +#define _DEFAULT_BDN_TOKEN "LpkBindDN"
1240 +#define _DEFAULT_BPW_TOKEN "LpkBindPw"
1241 +#define _DEFAULT_MYG_TOKEN "LpkServerGroup"
1242 +#define _DEFAULT_TLS_TOKEN "LpkForceTLS"
1243 +#define _DEFAULT_BTI_TOKEN "LpkBindTimelimit"
1244 +#define _DEFAULT_STI_TOKEN "LpkSearchTimelimit"
1245 +#define _DEFAULT_LDP_TOKEN "LpkLdapConf"
1247 +/* default options */
1248 +#define _DEFAULT_LPK_ON 0
1249 +#define _DEFAULT_LPK_SERVERS NULL
1250 +#define _DEFAULT_LPK_UDN NULL
1251 +#define _DEFAULT_LPK_GDN NULL
1252 +#define _DEFAULT_LPK_BINDDN NULL
1253 +#define _DEFAULT_LPK_BINDPW NULL
1254 +#define _DEFAULT_LPK_SGROUP NULL
1255 +#define _DEFAULT_LPK_TLS -1
1256 +#define _DEFAULT_LPK_BTIMEOUT 10
1257 +#define _DEFAULT_LPK_STIMEOUT 10
1258 +#define _DEFAULT_LPK_LDP NULL
1261 +#define FLAG_EMPTY 0x00000000
1262 +#define FLAG_CONNECTED 0x00000001
1265 +#define FLAG_SET_EMPTY(x) x&=(FLAG_EMPTY)
1266 +#define FLAG_SET_CONNECTED(x) x|=(FLAG_CONNECTED)
1267 +#define FLAG_SET_DISCONNECTED(x) x&=~(FLAG_CONNECTED)
1272 +#define PUBKEYATTR "sshPublicKey"
1276 + * defined files path
1277 + * (should be relocated to pathnames.h,
1278 + * if one day it's included within the tree)
1281 +#define _PATH_LDAP_CONFIG_FILE "/etc/ldap.conf"
1284 +typedef struct ldap_options {
1285 + int on; /* Use it or NOT */
1286 + LDAP * ld; /* LDAP file desc */
1287 + char * servers; /* parsed servers for ldaplib failover handling */
1288 + char * u_basedn; /* user basedn */
1289 + char * g_basedn; /* group basedn */
1290 + char * binddn; /* binddn */
1291 + char * bindpw; /* bind password */
1292 + char * sgroup; /* server group */
1293 + char * fgroup; /* group filter */
1294 + char * l_conf; /* use ldap.conf */
1295 + int tls; /* TLS only */
1296 + struct timeval b_timeout; /* bind timeout */
1297 + struct timeval s_timeout; /* search timeout */
1298 + unsigned int flags; /* misc flags (reconnection, future use?) */
1301 +typedef struct ldap_keys {
1302 + struct berval ** keys; /* the public keys retrieved */
1303 + unsigned int num; /* number of keys */
1307 +/* function headers */
1308 +void ldap_close(ldap_opt_t *);
1309 +int ldap_connect(ldap_opt_t *);
1310 +char * ldap_parse_groups(char *);
1311 +char * ldap_parse_servers(char *);
1312 +void ldap_options_print(ldap_opt_t *);
1313 +void ldap_options_free(ldap_opt_t *);
1314 +void ldap_keys_free(ldap_key_t *);
1315 +int ldap_parse_lconf(ldap_opt_t *);
1316 +ldap_key_t * ldap_getuserkey(ldap_opt_t *, char *);
1317 +int ldap_ismember(ldap_opt_t *, char *);
1320 diff -Nru -x Makefile -x 'buildpkg.*' -x opensshd.init -x 'ssh_prng_*' openssh-4.3p1/lpk-user-example.txt openssh-4.3p1-lpk/lpk-user-example.txt
1321 --- openssh-4.3p1/lpk-user-example.txt 1970-01-01 01:00:00.000000000 +0100
1322 +++ openssh-4.3p1-lpk/lpk-user-example.txt 2006-04-18 15:46:59.000000000 +0200
1325 +Post to ML -> User Made Quick Install Doc.
1326 +Contribution from John Lane <john@lane.uk.net>
1328 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1330 +OpenSSH LDAP keystore Patch
1331 +===========================
1333 +NOTE: these notes are a transcript of a specific installation
1334 + they work for me, your specifics may be different!
1335 + from John Lane March 17th 2005 john@lane.uk.net
1337 +This is a patch to OpenSSH 4.0p1 to allow it to obtain users' public keys
1338 +from their LDAP record as an alternative to ~/.ssh/authorized_keys.
1340 +(Assuming here that necessary build stuff is in $BUILD)
1342 +cd $BUILD/openssh-4.0p1
1343 +patch -Np1 -i $BUILD/openssh-lpk-4.0p1-0.3.patch
1344 +mkdir -p /var/empty &&
1345 +./configure --prefix=/usr --sysconfdir=/etc/ssh \
1346 + --libexecdir=/usr/sbin --with-md5-passwords --with-pam \
1347 + --with-libs="-lldap" --with-cppflags="-DWITH_LDAP_PUBKEY"
1352 +Add the following config to /etc/ssh/ssh_config
1354 +LpkServers ldap://myhost.mydomain.com
1355 +LpkUserDN ou=People,dc=mydomain,dc=com
1357 +We need to tell sshd about the SSL keys during boot, as root's
1358 +environment does not exist at that time. Edit /etc/rc.d/init.d/sshd.
1359 +Change the startup code from this:
1360 + echo "Starting SSH Server..."
1361 + loadproc /usr/sbin/sshd
1364 + echo "Starting SSH Server..."
1365 + LDAPRC="/root/.ldaprc" loadproc /usr/sbin/sshd
1368 +Re-start the sshd daemon:
1369 +/etc/rc.d/init.d/sshd restart
1371 +Install the additional LDAP schema
1372 +cp $BUILD/openssh-lpk-0.2.schema /etc/openldap/schema/openssh.schema
1374 +Now add the openSSH LDAP schema to /etc/openldap/slapd.conf:
1375 +Add the following to the end of the existing block of schema includes
1376 +include /etc/openldap/schema/openssh.schema
1378 +Re-start the LDAP server:
1379 +/etc/rc.d/init.d/slapd restart
1381 +To add one or more public keys to a user, eg "testuser" :
1382 +ldapsearch -x -W -Z -LLL -b "uid=testuser,ou=People,dc=mydomain,dc=com" -D
1383 +"uid=testuser,ou=People,dc=mydomain,dc=com" > /tmp/testuser
1385 +append the following to this /tmp/testuser file
1386 +objectclass: ldapPublicKey
1387 +sshPublicKey: ssh-rsa
1388 +AAAAB3NzaC1yc2EAAAABJQAAAIB3dsrwqXqD7E4zYYrxwdDKBUQxKMioXy9pxFVai64kAPxjU9KS
1389 +qIo7QfkjslfsjflksjfldfkjsldfjLX/5zkzRmT28I5piGzunPv17S89z8XwSsuAoR1t86t+5dlI
1390 +7eZE/gVbn2UQkQq7+kdDTS2yXV6VnC52N/kKLG3ciBkBAw== General Purpose RSA Key
1393 +ldapmodify -x -D "uid=testuser,ou=People,dc=mydomain,dc=com" -W -f
1395 +Enter LDAP Password:
1396 +modifying entry "uid=testuser,ou=People,dc=mydomain,dc=com"
1397 +And check the modify is ok:
1398 +ldapsearch -x -W -Z -b "uid=testuser,ou=People,dc=mydomain,dc=com" -D
1399 +"uid=testuser,ou=People,dc=mydomain,dc=com"
1400 +Enter LDAP Password:
1404 +# base <uid=testuser,ou=People,dc=mydomain,dc=com> with scope sub
1405 +# filter: (objectclass=*)
1409 +# testuser, People, mydomain.com
1410 +dn: uid=testuser,ou=People,dc=mydomain,dc=com
1413 +objectClass: account
1414 +objectClass: posixAccount
1416 +objectClass: shadowAccount
1417 +objectClass: ldapPublicKey
1418 +shadowLastChange: 12757
1421 +loginShell: /bin/bash
1424 +homeDirectory: /home/testuser
1425 +userPassword:: e1NTSEF9UDgwV1hnM1VjUDRJK0k1YnFiL1d4ZUJObXlZZ3Z3UTU=
1426 +sshPublicKey: ssh-rsa
1427 +AAAAB3NzaC1yc2EAAAABJQAAAIB3dsrwqXqD7E4zYYrxwdDKBUQxKMioXy9pxFVai64kAPxjU9KSqIo7QfkjslfsjflksjfldfkjsldfjLX/5zkzRmT28I5piGzunPv17S89z
1428 +8XwSsuAoR1t86t+5dlI7eZE/gVbn2UQkQq7+kdDTS2yXV6VnC52N/kKLG3ciBkBAw== General Purpose RSA Key
1437 +Now start a ssh session to user "testuser" from usual ssh client (e.g.
1438 +puTTY). Login should succeed.
1440 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1441 diff -Nru -x Makefile -x 'buildpkg.*' -x opensshd.init -x 'ssh_prng_*' openssh-4.3p1/openssh-lpk.schema openssh-4.3p1-lpk/openssh-lpk.schema
1442 --- openssh-4.3p1/openssh-lpk.schema 1970-01-01 01:00:00.000000000 +0100
1443 +++ openssh-4.3p1-lpk/openssh-lpk.schema 2006-04-18 15:46:59.000000000 +0200
1448 +# LDAP Public Key Patch schema for use with openssh-ldappubkey
1449 +# Author: Eric AUGE <eau@phear.org>
1451 +# Based on the proposal of : Mark Ruijter
1455 +# octetString SYNTAX
1456 +attributetype ( 1.3.6.1.4.1.22054.500.1.1.1.13 NAME 'sshPublicKey'
1457 + DESC 'MANDATORY: OpenSSH Public key'
1458 + EQUALITY octetStringMatch
1459 + SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 )
1461 +# printableString SYNTAX yes|no
1462 +objectclass ( 1.3.6.1.4.1.22054.500.1.1.2.0 NAME 'ldapPublicKey' SUP top AUXILIARY
1463 + DESC 'MANDATORY: OpenSSH LPK objectclass'
1464 + MUST ( sshPublicKey $ uid )
1466 diff -Nru -x Makefile -x 'buildpkg.*' -x opensshd.init -x 'ssh_prng_*' openssh-4.3p1/servconf.c openssh-4.3p1-lpk/servconf.c
1467 --- openssh-4.3p1/servconf.c 2005-12-13 09:33:20.000000000 +0100
1468 +++ openssh-4.3p1-lpk/servconf.c 2006-04-18 15:46:59.000000000 +0200
1473 +#ifdef WITH_LDAP_PUBKEY
1474 +#include "ldapauth.h"
1477 static void add_listen_addr(ServerOptions *, char *, u_short);
1478 static void add_one_listen_addr(ServerOptions *, char *, u_short);
1480 @@ -102,6 +106,23 @@
1481 options->authorized_keys_file2 = NULL;
1482 options->num_accept_env = 0;
1483 options->permit_tun = -1;
1484 +#ifdef WITH_LDAP_PUBKEY
1486 + options->lpk.ld = NULL;
1487 + options->lpk.on = -1;
1488 + options->lpk.servers = NULL;
1489 + options->lpk.u_basedn = NULL;
1490 + options->lpk.g_basedn = NULL;
1491 + options->lpk.binddn = NULL;
1492 + options->lpk.bindpw = NULL;
1493 + options->lpk.sgroup = NULL;
1494 + options->lpk.fgroup = NULL;
1495 + options->lpk.l_conf = NULL;
1496 + options->lpk.tls = -1;
1497 + options->lpk.b_timeout.tv_sec = 0;
1498 + options->lpk.s_timeout.tv_sec = 0;
1499 + options->lpk.flags = FLAG_EMPTY;
1502 /* Needs to be accessable in many places */
1504 @@ -232,6 +253,30 @@
1505 options->authorized_keys_file = _PATH_SSH_USER_PERMITTED_KEYS;
1506 if (options->permit_tun == -1)
1507 options->permit_tun = SSH_TUNMODE_NO;
1508 +#ifdef WITH_LDAP_PUBKEY
1509 + if (options->lpk.on == -1)
1510 + options->lpk.on = _DEFAULT_LPK_ON;
1511 + if (options->lpk.servers == NULL)
1512 + options->lpk.servers = _DEFAULT_LPK_SERVERS;
1513 + if (options->lpk.u_basedn == NULL)
1514 + options->lpk.u_basedn = _DEFAULT_LPK_UDN;
1515 + if (options->lpk.g_basedn == NULL)
1516 + options->lpk.g_basedn = _DEFAULT_LPK_GDN;
1517 + if (options->lpk.binddn == NULL)
1518 + options->lpk.binddn = _DEFAULT_LPK_BINDDN;
1519 + if (options->lpk.bindpw == NULL)
1520 + options->lpk.bindpw = _DEFAULT_LPK_BINDPW;
1521 + if (options->lpk.sgroup == NULL)
1522 + options->lpk.sgroup = _DEFAULT_LPK_SGROUP;
1523 + if (options->lpk.tls == -1)
1524 + options->lpk.tls = _DEFAULT_LPK_TLS;
1525 + if (options->lpk.b_timeout.tv_sec == 0)
1526 + options->lpk.b_timeout.tv_sec = _DEFAULT_LPK_BTIMEOUT;
1527 + if (options->lpk.s_timeout.tv_sec == 0)
1528 + options->lpk.s_timeout.tv_sec = _DEFAULT_LPK_STIMEOUT;
1529 + if (options->lpk.l_conf == NULL)
1530 + options->lpk.l_conf = _DEFAULT_LPK_LDP;
1533 /* Turn privilege separation on by default */
1534 if (use_privsep == -1)
1535 @@ -276,6 +321,12 @@
1536 sGssAuthentication, sGssCleanupCreds, sAcceptEnv, sPermitTunnel,
1537 sUsePrivilegeSeparation,
1538 sDeprecated, sUnsupported
1539 +#ifdef WITH_LDAP_PUBKEY
1540 + ,sLdapPublickey, sLdapServers, sLdapUserDN
1541 + ,sLdapGroupDN, sBindDN, sBindPw, sMyGroup
1542 + ,sForceTLS, sBindTimeout, sSearchTimeout
1547 /* Textual representation of the tokens. */
1548 @@ -374,6 +425,19 @@
1549 { "clientalivecountmax", sClientAliveCountMax },
1550 { "authorizedkeysfile", sAuthorizedKeysFile },
1551 { "authorizedkeysfile2", sAuthorizedKeysFile2 },
1552 +#ifdef WITH_LDAP_PUBKEY
1553 + { _DEFAULT_LPK_TOKEN, sLdapPublickey },
1554 + { _DEFAULT_SRV_TOKEN, sLdapServers },
1555 + { _DEFAULT_USR_TOKEN, sLdapUserDN },
1556 + { _DEFAULT_GRP_TOKEN, sLdapGroupDN },
1557 + { _DEFAULT_BDN_TOKEN, sBindDN },
1558 + { _DEFAULT_BPW_TOKEN, sBindPw },
1559 + { _DEFAULT_MYG_TOKEN, sMyGroup },
1560 + { _DEFAULT_TLS_TOKEN, sForceTLS },
1561 + { _DEFAULT_BTI_TOKEN, sBindTimeout },
1562 + { _DEFAULT_STI_TOKEN, sSearchTimeout },
1563 + { _DEFAULT_LDP_TOKEN, sLdapConf },
1565 { "useprivilegeseparation", sUsePrivilegeSeparation},
1566 { "acceptenv", sAcceptEnv },
1567 { "permittunnel", sPermitTunnel },
1568 @@ -1001,6 +1065,116 @@
1570 arg = strdelim(&cp);
1572 +#ifdef WITH_LDAP_PUBKEY
1573 + case sLdapPublickey:
1574 + intptr = &options->lpk.on;
1576 + case sLdapServers:
1577 + /* arg = strdelim(&cp); */
1581 + if (!arg || *arg == '\0')
1582 + fatal("%s line %d: missing ldap server",filename,linenum);
1583 + arg[strlen(arg)] = '\0';
1584 + if ((options->lpk.servers = ldap_parse_servers(arg)) == NULL)
1585 + fatal("%s line %d: error in ldap servers", filename, linenum);
1586 + memset(arg,0,strlen(arg));
1589 + /* arg = strdelim(&cp); */
1593 + if (!arg || *arg == '\0')
1594 + fatal("%s line %d: missing ldap server",filename,linenum);
1595 + arg[strlen(arg)] = '\0';
1596 + options->lpk.u_basedn = xstrdup(arg);
1597 + memset(arg,0,strlen(arg));
1599 + case sLdapGroupDN:
1600 + /* arg = strdelim(&cp); */
1604 + if (!arg || *arg == '\0')
1605 + fatal("%s line %d: missing ldap server",filename,linenum);
1606 + arg[strlen(arg)] = '\0';
1607 + options->lpk.g_basedn = xstrdup(arg);
1608 + memset(arg,0,strlen(arg));
1611 + /* arg = strdelim(&cp); */
1615 + if (!arg || *arg == '\0')
1616 + fatal("%s line %d: missing binddn",filename,linenum);
1617 + arg[strlen(arg)] = '\0';
1618 + options->lpk.binddn = xstrdup(arg);
1619 + memset(arg,0,strlen(arg));
1622 + /* arg = strdelim(&cp); */
1626 + if (!arg || *arg == '\0')
1627 + fatal("%s line %d: missing bindpw",filename,linenum);
1628 + arg[strlen(arg)] = '\0';
1629 + options->lpk.bindpw = xstrdup(arg);
1630 + memset(arg,0,strlen(arg));
1636 + if (!arg || *arg == '\0')
1637 + fatal("%s line %d: missing groupname",filename, linenum);
1638 + arg[strlen(arg)] = '\0';
1639 + options->lpk.sgroup = xstrdup(arg);
1640 + if (options->lpk.sgroup)
1641 + options->lpk.fgroup = ldap_parse_groups(options->lpk.sgroup);
1642 + memset(arg,0,strlen(arg));
1645 + intptr = &options->lpk.tls;
1646 + arg = strdelim(&cp);
1647 + if (!arg || *arg == '\0')
1648 + fatal("%s line %d: missing yes/no argument.",
1649 + filename, linenum);
1650 + value = 0; /* silence compiler */
1651 + if (strcmp(arg, "yes") == 0)
1653 + else if (strcmp(arg, "no") == 0)
1655 + else if (strcmp(arg, "try") == 0)
1658 + fatal("%s line %d: Bad yes/no argument: %s",
1659 + filename, linenum, arg);
1660 + if (*intptr == -1)
1663 + case sBindTimeout:
1664 + intptr = (int *) &options->lpk.b_timeout.tv_sec;
1666 + case sSearchTimeout:
1667 + intptr = (int *) &options->lpk.s_timeout.tv_sec;
1671 + /* arg = strdelim(&cp); */
1675 + if (!arg || *arg == '\0')
1676 + fatal("%s line %d: missing LpkLdapConf", filename, linenum);
1677 + arg[strlen(arg)] = '\0';
1678 + options->lpk.l_conf = xstrdup(arg);
1679 + memset(arg, 0, strlen(arg));
1684 fatal("%s line %d: Missing handler for opcode %s (%d)",
1685 diff -Nru -x Makefile -x 'buildpkg.*' -x opensshd.init -x 'ssh_prng_*' openssh-4.3p1/servconf.h openssh-4.3p1-lpk/servconf.h
1686 --- openssh-4.3p1/servconf.h 2005-12-13 09:29:03.000000000 +0100
1687 +++ openssh-4.3p1-lpk/servconf.h 2006-04-18 15:46:59.000000000 +0200
1692 +#ifdef WITH_LDAP_PUBKEY
1693 +#include "ldapauth.h"
1696 #define MAX_PORTS 256 /* Max # ports. */
1698 #define MAX_ALLOW_USERS 256 /* Max # users on allow list. */
1700 int use_pam; /* Enable auth via PAM */
1703 +#ifdef WITH_LDAP_PUBKEY
1708 void initialize_server_options(ServerOptions *);
1709 diff -Nru -x Makefile -x 'buildpkg.*' -x opensshd.init -x 'ssh_prng_*' openssh-4.3p1/sshd.c openssh-4.3p1-lpk/sshd.c
1710 --- openssh-4.3p1/sshd.c 2005-12-24 04:59:12.000000000 +0100
1711 +++ openssh-4.3p1-lpk/sshd.c 2006-04-18 15:46:59.000000000 +0200
1713 int deny_severity = LOG_WARNING;
1714 #endif /* LIBWRAP */
1716 +#ifdef WITH_LDAP_PUBKEY
1717 +#include "ldapauth.h"
1723 @@ -1089,6 +1093,16 @@
1727 +#ifdef WITH_LDAP_PUBKEY
1728 + /* ldap_options_print(&options.lpk); */
1729 + /* XXX initialize/check ldap connection and set *LD */
1730 + if (options.lpk.on) {
1731 + if (options.lpk.l_conf && (ldap_parse_lconf(&options.lpk) < 0) )
1732 + error("[LDAP] could not parse %s", options.lpk.l_conf);
1733 + if (ldap_connect(&options.lpk) < 0)
1734 + error("[LDAP] could not initialize ldap connection");
1737 debug("sshd version %.100s", SSH_RELEASE);
1739 /* load private host keys */
1740 diff -Nru -x Makefile -x 'buildpkg.*' -x opensshd.init -x 'ssh_prng_*' openssh-4.3p1/sshd_config openssh-4.3p1-lpk/sshd_config
1741 --- openssh-4.3p1/sshd_config 2005-12-13 09:29:03.000000000 +0100
1742 +++ openssh-4.3p1-lpk/sshd_config 2006-04-18 15:49:45.000000000 +0200
1743 @@ -100,6 +100,20 @@
1745 # no default banner path
1748 +# here are the new patched ldap related tokens
1749 +# entries in your LDAP must have posixAccount & ldapPublicKey objectclass
1751 +#LpkLdapConf /etc/ldap.conf
1752 +#LpkServers ldap://10.1.7.1 ldap://10.1.7.2
1753 +#LpkUserDN ou=users,dc=phear,dc=org
1754 +#LpkGroupDN ou=groups,dc=phear,dc=org
1755 +#LpkBindDN cn=Manager,dc=phear,dc=org
1757 +#LpkServerGroup mail
1759 +#LpkSearchTimelimit 3
1760 +#LpkBindTimelimit 3
1762 # override default of no subsystems
1763 Subsystem sftp /usr/libexec/sftp-server
1764 diff -Nru -x Makefile -x 'buildpkg.*' -x opensshd.init -x 'ssh_prng_*' openssh-4.3p1/sshd_config.5 openssh-4.3p1-lpk/sshd_config.5
1765 --- openssh-4.3p1/sshd_config.5 2006-01-03 08:47:31.000000000 +0100
1766 +++ openssh-4.3p1-lpk/sshd_config.5 2006-04-18 15:46:59.000000000 +0200
1767 @@ -777,6 +777,58 @@
1770 .Pa /usr/X11R6/bin/xauth .
1772 +Specifies whether LDAP public key retrieval must be used or not. It allow
1773 +an easy centralisation of public keys within an LDAP directory. The argument must be
1778 +Specifies whether LDAP Public keys should parse the specified ldap.conf file
1779 +instead of sshd_config Tokens. The argument must be a valid path to an ldap.conf
1783 +Specifies LDAP one or more [:space:] separated server's url the following form may be used:
1785 +LpkServers ldaps://127.0.0.1 ldap://127.0.0.2 ldap://127.0.0.3
1787 +Specifies the LDAP user DN.
1789 +LpkUserDN ou=users,dc=phear,dc=org
1791 +Specifies the LDAP groups DN.
1793 +LpkGroupDN ou=groups,dc=phear,dc=org
1795 +Specifies the LDAP bind DN to use if necessary.
1797 +LpkBindDN cn=Manager,dc=phear,dc=org
1799 +Specifies the LDAP bind credential.
1802 +.It Cm LpkServerGroup
1803 +Specifies one or more [:space:] separated group the server is part of.
1805 +LpkServerGroup unix mail prod
1807 +Specifies if the LDAP server connection must be tried, forced or not used. The argument must be
1813 +.It Cm LpkSearchTimelimit
1814 +Sepcifies the search time limit before the search is considered over. value is
1817 +LpkSearchTimelimit 3
1818 +.It Cm LpkBindTimelimit
1819 +Sepcifies the bind time limit before the connection is considered dead. value is