openssh/openssh-5.5p1-ldap.patch

2548 lines
84 KiB
Diff
Raw Blame History

diff -up openssh-5.5p1/config.h.in.ldap openssh-5.5p1/config.h.in
--- openssh-5.5p1/config.h.in.ldap 2010-04-16 02:17:09.000000000 +0200
+++ openssh-5.5p1/config.h.in 2010-04-28 11:34:13.000000000 +0200
@@ -1,5 +1,8 @@
/* config.h.in. Generated from configure.ac by autoheader. */
+/* Define if building universal (internal helper macro) */
+#undef AC_APPLE_UNIVERSAL_BUILD
+
/* Define if you have a getaddrinfo that fails for the all-zeros IPv6 address
*/
#undef AIX_GETNAMEINFO_HACK
@@ -536,6 +539,57 @@
/* Define to 1 if you have the <lastlog.h> header file. */
#undef HAVE_LASTLOG_H
+/* Define to 1 if you have the <lber.h> header file. */
+#undef HAVE_LBER_H
+
+/* Define to 1 if you have the `ldapssl_init' function. */
+#undef HAVE_LDAPSSL_INIT
+
+/* Define to 1 if you have the `ldap_controls_free' function. */
+#undef HAVE_LDAP_CONTROLS_FREE
+
+/* Define to 1 if you have the `ldap_get_lderrno' function. */
+#undef HAVE_LDAP_GET_LDERRNO
+
+/* Define to 1 if you have the `ldap_get_option' function. */
+#undef HAVE_LDAP_GET_OPTION
+
+/* Define to 1 if you have the <ldap.h> header file. */
+#undef HAVE_LDAP_H
+
+/* Define to 1 if you have the `ldap_init' function. */
+#undef HAVE_LDAP_INIT
+
+/* Define to 1 if you have the `ldap_initialize' function. */
+#undef HAVE_LDAP_INITIALIZE
+
+/* Define to 1 if you have the `ldap_memfree' function. */
+#undef HAVE_LDAP_MEMFREE
+
+/* Define to 1 if you have the `ldap_parse_result' function. */
+#undef HAVE_LDAP_PARSE_RESULT
+
+/* Define to 1 if you have the `ldap_pvt_tls_set_option' function. */
+#undef HAVE_LDAP_PVT_TLS_SET_OPTION
+
+/* Define to 1 if you have the `ldap_set_lderrno' function. */
+#undef HAVE_LDAP_SET_LDERRNO
+
+/* Define to 1 if you have the `ldap_set_option' function. */
+#undef HAVE_LDAP_SET_OPTION
+
+/* Define to 1 if you have the `ldap_set_rebind_proc' function. */
+#undef HAVE_LDAP_SET_REBIND_PROC
+
+/* Define to 1 if you have the <ldap_ssl.h> header file. */
+#undef HAVE_LDAP_SSL_H
+
+/* Define to 1 if you have the `ldap_start_tls_s' function. */
+#undef HAVE_LDAP_START_TLS_S
+
+/* Define to 1 if you have the <libaudit.h> header file. */
+#undef HAVE_LIBAUDIT_H
+
/* Define to 1 if you have the `bsm' library (-lbsm). */
#undef HAVE_LIBBSM
@@ -575,6 +629,9 @@
/* Define to 1 if you have the <limits.h> header file. */
#undef HAVE_LIMITS_H
+/* Define if you want Linux audit support. */
+#undef HAVE_LINUX_AUDIT
+
/* Define to 1 if you have the <linux/if_tun.h> header file. */
#undef HAVE_LINUX_IF_TUN_H
@@ -771,6 +828,9 @@
/* Define to 1 if you have the `setgroups' function. */
#undef HAVE_SETGROUPS
+/* Define to 1 if you have the `setkeycreatecon' function. */
+#undef HAVE_SETKEYCREATECON
+
/* Define to 1 if you have the `setlogin' function. */
#undef HAVE_SETLOGIN
@@ -921,13 +981,13 @@
/* define if you have struct sockaddr_in6 data type */
#undef HAVE_STRUCT_SOCKADDR_IN6
-/* Define to 1 if `sin6_scope_id' is member of `struct sockaddr_in6'. */
+/* Define to 1 if `sin6_scope_id' is a member of `struct sockaddr_in6'. */
#undef HAVE_STRUCT_SOCKADDR_IN6_SIN6_SCOPE_ID
/* define if you have struct sockaddr_storage data type */
#undef HAVE_STRUCT_SOCKADDR_STORAGE
-/* Define to 1 if `st_blksize' is member of `struct stat'. */
+/* Define to 1 if `st_blksize' is a member of `struct stat'. */
#undef HAVE_STRUCT_STAT_ST_BLKSIZE
/* Define to 1 if the system has the type `struct timespec'. */
@@ -1191,6 +1251,9 @@
/* Define if pututxline updates lastlog too */
#undef LASTLOG_WRITE_PUTUTXLINE
+/* number arguments of ldap_set_rebind_proc */
+#undef LDAP_SET_REBIND_PROC_ARGS
+
/* Define if you want TCP Wrappers support */
#undef LIBWRAP
@@ -1274,6 +1337,9 @@
/* Define to the one symbol short name of this package. */
#undef PACKAGE_TARNAME
+/* Define to the home page for this package. */
+#undef PACKAGE_URL
+
/* Define to the version of this package. */
#undef PACKAGE_VERSION
@@ -1360,6 +1426,10 @@
/* Prepend the address family to IP tunnel traffic */
#undef SSH_TUN_PREPEND_AF
+/* Define to your vendor patch level, if it has been modified from the
+ upstream source release. */
+#undef SSH_VENDOR_PATCHLEVEL
+
/* Define to 1 if you have the ANSI C header files. */
#undef STDC_HEADERS
@@ -1384,6 +1454,9 @@
/* Use btmp to log bad logins */
#undef USE_BTMP
+/* platform uses an in-memory credentials cache */
+#undef USE_CCAPI
+
/* Use libedit for sftp */
#undef USE_LIBEDIT
@@ -1396,6 +1469,9 @@
/* Use PIPES instead of a socketpair() */
#undef USE_PIPES
+/* platform has the Security Authorization Session API */
+#undef USE_SECURITY_SESSION_API
+
/* Define if you have Solaris process contracts */
#undef USE_SOLARIS_PROCESS_CONTRACTS
@@ -1418,12 +1494,26 @@
/* Define if you want IRIX project management */
#undef WITH_IRIX_PROJECT
+/* Enable LDAP pubkey support */
+#undef WITH_LDAP_PUBKEY
+
+/* Enable pubkey agent support */
+#undef WITH_PUBKEY_AGENT
+
/* Define if you want SELinux support. */
#undef WITH_SELINUX
-/* Define to 1 if your processor stores words with the most significant byte
- first (like Motorola and SPARC, unlike Intel and VAX). */
-#undef WORDS_BIGENDIAN
+/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most
+ significant byte first (like Motorola and SPARC, unlike Intel). */
+#if defined AC_APPLE_UNIVERSAL_BUILD
+# if defined __BIG_ENDIAN__
+# define WORDS_BIGENDIAN 1
+# endif
+#else
+# ifndef WORDS_BIGENDIAN
+# undef WORDS_BIGENDIAN
+# endif
+#endif
/* Define if xauth is found in your path */
#undef XAUTH_PATH
diff -up openssh-5.5p1/configure.ac.ldap openssh-5.5p1/configure.ac
--- openssh-5.5p1/configure.ac.ldap 2010-04-28 11:34:09.000000000 +0200
+++ openssh-5.5p1/configure.ac 2010-04-28 11:34:13.000000000 +0200
@@ -1382,6 +1382,106 @@ AC_ARG_WITH(pka,
]
)
+# Check whether user wants LDAP support
+LDAP_MSG="no"
+INSTALL_SSH_LDAP_HELPER=""
+AC_ARG_WITH(ldap,
+ [ --with-ldap[[=PATH]] Enable LDAP pubkey support (optionally in PATH)],
+ [
+ if test "x$withval" != "xno" ; then
+
+ INSTALL_SSH_LDAP_HELPER="yes"
+ CPPFLAGS="$CPPFLAGS -DLDAP_DEPRECATED"
+
+ if test "x$withval" != "xyes" ; then
+ CPPFLAGS="$CPPFLAGS -I${withval}/include"
+ LDFLAGS="$LDFLAGS -L${withval}/lib"
+ fi
+
+ AC_DEFINE([WITH_LDAP_PUBKEY], 1, [Enable LDAP pubkey support])
+ LDAP_MSG="yes"
+
+ AC_CHECK_HEADERS(lber.h)
+ AC_CHECK_HEADERS(ldap.h, , AC_MSG_ERROR(could not locate <ldap.h>))
+ AC_CHECK_HEADERS(ldap_ssl.h)
+
+ AC_ARG_WITH(ldap-lib,
+ [ --with-ldap-lib=type select ldap library [auto|netscape5|netscape4|netscape3|umich|openldap]])
+
+ if test -z "$with_ldap_lib"; then
+ with_ldap_lib=auto
+ fi
+
+ if test -z "$found_ldap_lib" -a \( $with_ldap_lib = auto -o $with_ldap_lib = umich -o $with_ldap_lib = openldap \); then
+ AC_CHECK_LIB(lber, main, LIBS="-llber $LIBS" found_ldap_lib=yes)
+ AC_CHECK_LIB(ldap, main, LIBS="-lldap $LIBS" found_ldap_lib=yes)
+ fi
+
+ if test -z "$found_ldap_lib" -a \( $with_ldap_lib = auto -o $with_ldap_lib = netscape5 \); then
+ AC_CHECK_LIB(ldap50, main, LIBS="-lldap50 -lssldap50 -lssl3 -lnss3 -lnspr4 -lprldap50 -lplc4 -lplds4 $LIBS" found_ldap_lib=yes)
+ fi
+
+ if test -z "$found_ldap_lib" -a \( $with_ldap_lib = auto -o $with_ldap_lib = netscape4 \); then
+ AC_CHECK_LIB(ldapssl41, main, LIBS="-lldapssl41 -lplc3 -lplds3 -lnspr3 $LIBS" found_ldap_lib=yes)
+ if test -z "$found_ldap_lib"; then
+ AC_CHECK_LIB(ldapssl40, main, LIBS="-lldapssl40 $LIBS" found_ldap_lib=yes)
+ fi
+ if test -z "$found_ldap_lib"; then
+ AC_CHECK_LIB(ldap41, main, LIBS="-lldap41 $LIBS" found_ldap_lib=yes)
+ fi
+ if test -z "$found_ldap_lib"; then
+ AC_CHECK_LIB(ldap40, main, LIBS="-lldap40 $LIBS" found_ldap_lib=yes)
+ fi
+ fi
+
+ if test -z "$found_ldap_lib" -a \( $with_ldap_lib = auto -o $with_ldap_lib = netscape3 \); then
+ AC_CHECK_LIB(ldapssl30, main, LIBS="-lldapssl30 $LIBS" found_ldap_lib=yes)
+ fi
+
+ if test -z "$found_ldap_lib"; then
+ AC_MSG_ERROR(could not locate a valid LDAP library)
+ fi
+
+ AC_MSG_CHECKING([for working LDAP support])
+ AC_TRY_COMPILE(
+ [#include <sys/types.h>
+ #include <ldap.h>],
+ [(void)ldap_init(0, 0);],
+ [AC_MSG_RESULT(yes)],
+ [
+ AC_MSG_RESULT(no)
+ AC_MSG_ERROR([** Incomplete or missing ldap libraries **])
+ ])
+ AC_CHECK_FUNCS( \
+ ldap_init \
+ ldap_get_lderrno \
+ ldap_set_lderrno \
+ ldap_parse_result \
+ ldap_memfree \
+ ldap_controls_free \
+ ldap_set_option \
+ ldap_get_option \
+ ldapssl_init \
+ ldap_start_tls_s \
+ ldap_pvt_tls_set_option \
+ ldap_initialize \
+ )
+ AC_CHECK_FUNCS(ldap_set_rebind_proc,
+ AC_MSG_CHECKING([number arguments of ldap_set_rebind_proc])
+ AC_TRY_COMPILE(
+ [#include <lber.h>
+ #include <ldap.h>],
+ [ldap_set_rebind_proc(0, 0, 0);],
+ [ac_cv_ldap_set_rebind_proc=3],
+ [ac_cv_ldap_set_rebind_proc=2])
+ AC_MSG_RESULT($ac_cv_ldap_set_rebind_proc)
+ AC_DEFINE(LDAP_SET_REBIND_PROC_ARGS, $ac_cv_ldap_set_rebind_proc, [number arguments of ldap_set_rebind_proc])
+ )
+ fi
+ ]
+)
+AC_SUBST(INSTALL_SSH_LDAP_HELPER)
+
dnl Checks for library functions. Please keep in alphabetical order
AC_CHECK_FUNCS( \
arc4random \
@@ -4239,6 +4339,7 @@ echo " Smartcard support
echo " S/KEY support: $SKEY_MSG"
echo " TCP Wrappers support: $TCPW_MSG"
echo " PKA support: $PKA_MSG"
+echo " LDAP support: $LDAP_MSG"
echo " MD5 password support: $MD5_MSG"
echo " libedit support: $LIBEDIT_MSG"
echo " Solaris process contract support: $SPC_MSG"
diff -up openssh-5.5p1/ldapbody.c.ldap openssh-5.5p1/ldapbody.c
--- openssh-5.5p1/ldapbody.c.ldap 2010-04-28 11:34:13.000000000 +0200
+++ openssh-5.5p1/ldapbody.c 2010-04-28 11:34:13.000000000 +0200
@@ -0,0 +1,494 @@
+/* $OpenBSD: ldapbody.c,v 1.1 2009/12/03 03:34:42 jfch Exp $ */
+/*
+ * Copyright (c) 2009 Jan F. Chadima. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 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.
+ */
+
+#include "ldapincludes.h"
+#include "log.h"
+#include "xmalloc.h"
+#include "ldapconf.h"
+#include "ldapmisc.h"
+#include "ldapbody.h"
+#include <stdio.h>
+#include <unistd.h>
+
+#define LDAPSEARCH_FORMAT "(&(objectclass=posixAccount)(objectclass=ldapPublicKey)(uid=%s)%s)"
+#define PUBKEYATTR "sshPublicKey"
+#define LDAP_LOGFILE "%s/ldap.%d"
+
+static FILE *logfile = NULL;
+static LDAP *ld;
+
+static char *attrs[] = {
+ PUBKEYATTR,
+ NULL
+};
+
+void
+ldap_checkconfig (void)
+{
+#ifdef HAVE_LDAP_INITIALIZE
+ if (options.host == NULL && options.uri == NULL)
+#else
+ if (options.host == NULL)
+#endif
+ fatal ("missing \"host\" in config file");
+}
+
+#if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)
+static int
+_rebind_proc (LDAP * ld, LDAP_CONST char *url, int request, ber_int_t msgid)
+{
+ struct timeval timeout;
+ int rc;
+#if defined(HAVE_LDAP_PARSE_RESULT) && defined(HAVE_LDAP_CONTROLS_FREE)
+ LDAPMessage *result;
+#endif /* HAVE_LDAP_PARSE_RESULT && HAVE_LDAP_CONTROLS_FREE */
+
+ debug2 ("Doing LDAP rebind to %s", options.binddn);
+ if (options.ssl == SSL_START_TLS) {
+ if ((rc = ldap_start_tls_s (ld, NULL, NULL)) != LDAP_SUCCESS) {
+ error ("ldap_starttls_s: %s", ldap_err2string (rc));
+ return LDAP_OPERATIONS_ERROR;
+ }
+ }
+
+#if !defined(HAVE_LDAP_PARSE_RESULT) || !defined(HAVE_LDAP_CONTROLS_FREE)
+ return ldap_simple_bind_s (ld, options.binddn, options.bindpw);
+#else
+ if (ldap_simple_bind(ld, options.binddn, options.bindpw) < 0)
+ fatal ("ldap_simple_bind %s", ldap_err2string (ldap_get_lderrno (ld, 0, 0)));
+
+ timeout.tv_sec = options.bind_timelimit;
+ timeout.tv_usec = 0;
+ result = NULL;
+ if ((rc = ldap_result (ld, msgid, FALSE, &timeout, &result)) < 1) {
+ error ("ldap_result %s", ldap_err2string (ldap_get_lderrno (ld, 0, 0)));
+ ldap_msgfree (result);
+ return LDAP_OPERATIONS_ERROR;
+ }
+ debug3 ("LDAP rebind to %s succesfull", options.binddn);
+ return rc;
+#endif
+}
+#else
+
+static int
+_rebind_proc (LDAP * ld, char **whop, char **credp, int *methodp, int freeit)
+{
+ if (freeit)
+ return LDAP_SUCCESS;
+
+ *whop = strdup (options.binddn);
+ *credp = strdup (options.bindpw);
+ *methodp = LDAP_AUTH_SIMPLE;
+ debug2 ("Doing LDAP rebind for %s", *whop);
+ return LDAP_SUCCESS;
+}
+#endif
+
+void
+ldap_do_connect(void)
+{
+ int rc, msgid, ld_errno = 0;
+ struct timeval timeout;
+#if defined(HAVE_LDAP_PARSE_RESULT) && defined(HAVE_LDAP_CONTROLS_FREE)
+ int parserc;
+ LDAPMessage *result;
+ LDAPControl **controls;
+ int reconnect = 0;
+#endif /* HAVE_LDAP_PARSE_RESULT && HAVE_LDAP_CONTROLS_FREE */
+
+ debug ("LDAP do connect");
+
+retry:
+ if (reconnect) {
+ debug3 ("Reconnecting with ld_errno %d", ld_errno);
+ if (options.bind_policy == 0 ||
+ (ld_errno != LDAP_SERVER_DOWN && ld_errno != LDAP_TIMEOUT) ||
+ reconnect > 5)
+ fatal ("Cannot connect to LDAP server");
+
+ if (reconnect > 1)
+ sleep (reconnect - 1);
+
+ if (ld != NULL) {
+ ldap_unbind (ld);
+ ld = NULL;
+ }
+ logit("reconnecting to LDAP server...");
+ }
+
+ if (ld == NULL) {
+ int rc;
+ struct timeval tv;
+
+#ifdef HAVE_LDAP_SET_OPTION
+ if (options.debug > 0) {
+#ifdef LBER_OPT_LOG_PRINT_FILE
+ if (options.logdir) {
+ char *logfilename;
+ int logfilenamelen;
+
+ logfilenamelen = strlen (LDAP_LOGFILE) + strlen ("000000") + strlen (options.logdir);
+ logfilename = xmalloc (logfilenamelen);
+ snprintf (logfilename, logfilenamelen, LDAP_LOGFILE, options.logdir, (int) getpid ());
+ logfilename[logfilenamelen - 1] = 0;
+ if ((logfile = fopen (logfilename, "a")) == NULL)
+ fatal ("cannot append to %s: %s", logfilename, strerror (errno));
+ debug3 ("LDAP debug into %s", logfilename);
+ xfree (logfilename);
+ ber_set_option (NULL, LBER_OPT_LOG_PRINT_FILE, logfile);
+ }
+#endif
+ if (options.debug) {
+#ifdef LBER_OPT_DEBUG_LEVEL
+ ber_set_option (NULL, LBER_OPT_DEBUG_LEVEL, &options.debug);
+#endif /* LBER_OPT_DEBUG_LEVEL */
+#ifdef LDAP_OPT_DEBUG_LEVEL
+ ldap_set_option (NULL, LDAP_OPT_DEBUG_LEVEL, &options.debug);
+#endif /* LDAP_OPT_DEBUG_LEVEL */
+ debug3 ("Set LDAP debug to %d", options.debug);
+ }
+ }
+#endif /* HAVE_LDAP_SET_OPTION */
+
+ ld = NULL;
+#ifdef HAVE_LDAPSSL_INIT
+ if (options.host != NULL) {
+ if (options.ssl_on == SSL_LDAPS) {
+ if ((rc = ldapssl_client_init (options.sslpath, NULL)) != LDAP_SUCCESS)
+ fatal ("ldapssl_client_init %s", ldap_err2string (rc));
+ debug3 ("LDAPssl client init");
+ }
+
+ if (options.ssl_on != SSL_OFF) {
+ if ((ld = ldapssl_init (options.host, options.port, TRUE)) == NULL)
+ fatal ("ldapssl_init failed");
+ debug3 ("LDAPssl init");
+ }
+ }
+#endif /* HAVE_LDAPSSL_INIT */
+
+ /* continue with opening */
+ if (ld == NULL) {
+#if defined (HAVE_LDAP_START_TLS_S) || (defined(HAVE_LDAP_SET_OPTION) && defined(LDAP_OPT_X_TLS))
+ /* Some global TLS-specific options need to be set before we create our
+ * session context, so we set them here. */
+
+#ifdef LDAP_OPT_X_TLS_RANDOM_FILE
+ /* rand file */
+ if (options.tls_randfile != NULL) {
+ if ((rc = ldap_set_option (NULL, LDAP_OPT_X_TLS_RANDOM_FILE,
+ options.tls_randfile)) != LDAP_SUCCESS)
+ fatal ("ldap_set_option(LDAP_OPT_X_TLS_RANDOM_FILE): %s",
+ ldap_err2string (rc));
+ debug3 ("Set TLS random file %s", options.tls_randfile);
+ }
+#endif /* LDAP_OPT_X_TLS_RANDOM_FILE */
+
+ /* ca cert file */
+ if (options.tls_cacertfile != NULL) {
+ if ((rc = ldap_set_option (NULL, LDAP_OPT_X_TLS_CACERTFILE,
+ options.tls_cacertfile)) != LDAP_SUCCESS)
+ error ("ldap_set_option(LDAP_OPT_X_TLS_CACERTFILE): %s",
+ ldap_err2string (rc));
+ debug3 ("Set TLS CA cert file %s ", options.tls_cacertfile);
+ }
+
+ /* ca cert directory */
+ if (options.tls_cacertdir != NULL) {
+ if ((rc = ldap_set_option (NULL, LDAP_OPT_X_TLS_CACERTDIR,
+ options.tls_cacertdir)) != LDAP_SUCCESS)
+ fatal ("ldap_set_option(LDAP_OPT_X_TLS_CACERTDIR): %s",
+ ldap_err2string (rc));
+ debug3 ("Set TLS CA cert dir %s ", options.tls_cacertdir);
+ }
+
+ /* require cert? */
+ if ((rc = ldap_set_option (NULL, LDAP_OPT_X_TLS_REQUIRE_CERT,
+ &options.tls_checkpeer)) != LDAP_SUCCESS)
+ fatal ("ldap_set_option(LDAP_OPT_X_TLS_REQUIRE_CERT): %s",
+ ldap_err2string (rc));
+ debug3 ("Set TLS check peer to %d ", options.tls_checkpeer);
+
+ /* set cipher suite, certificate and private key: */
+ if (options.tls_ciphers != NULL) {
+ if ((rc = ldap_set_option (NULL, LDAP_OPT_X_TLS_CIPHER_SUITE,
+ options.tls_ciphers)) != LDAP_SUCCESS)
+ fatal ("ldap_set_option(LDAP_OPT_X_TLS_CIPHER_SUITE): %s",
+ ldap_err2string (rc));
+ debug3 ("Set TLS ciphers to %s ", options.tls_ciphers);
+ }
+
+ /* cert file */
+ if (options.tls_cert != NULL) {
+ if ((rc = ldap_set_option (NULL, LDAP_OPT_X_TLS_CERTFILE,
+ options.tls_cert)) != LDAP_SUCCESS)
+ fatal ("ldap_set_option(LDAP_OPT_X_TLS_CERTFILE): %s",
+ ldap_err2string (rc));
+ debug3 ("Set TLS cert file %s ", options.tls_cert);
+ }
+
+ /* key file */
+ if (options.tls_key != NULL) {
+ if ((rc = ldap_set_option (NULL, LDAP_OPT_X_TLS_KEYFILE,
+ options.tls_key)) != LDAP_SUCCESS)
+ fatal ("ldap_set_option(LDAP_OPT_X_TLS_KEYFILE): %s",
+ ldap_err2string (rc));
+ debug3 ("Set TLS key file %s ", options.tls_key);
+ }
+#endif
+#ifdef HAVE_LDAP_INITIALIZE
+ if (options.uri != NULL) {
+ if ((rc = ldap_initialize (&ld, options.uri)) != LDAP_SUCCESS)
+ fatal ("ldap_initialize %s", ldap_err2string (rc));
+ debug3 ("LDAP initialize %s", options.uri);
+ }
+ }
+#endif /* HAVE_LDAP_INTITIALIZE */
+
+ /* continue with opening */
+ if ((ld == NULL) && (options.host != NULL)) {
+#ifdef HAVE_LDAP_INIT
+ if ((ld = ldap_init (options.host, options.port)) == NULL)
+ fatal ("ldap_init failed");
+ debug3 ("LDAP init %s:%d", options.host, options.port);
+#else
+ if ((ld = ldap_open (options.host, options.port)) == NULL)
+ fatal ("ldap_open failed");
+ debug3 ("LDAP open %s:%d", options.host, options.port);
+#endif /* HAVE_LDAP_INIT */
+ }
+
+ if (ld == NULL)
+ fatal ("no way to open ldap");
+
+#if defined(HAVE_LDAP_SET_OPTION) && defined(LDAP_OPT_X_TLS)
+ if (options.ssl == SSL_LDAPS) {
+ if ((rc = ldap_set_option (ld, LDAP_OPT_X_TLS, &options.tls_checkpeer)) != LDAP_SUCCESS)
+ fatal ("ldap_set_option(LDAP_OPT_X_TLS) %s", ldap_err2string (rc));
+ debug3 ("LDAP set LDAP_OPT_X_TLS_%d", options.tls_checkpeer);
+ }
+#endif /* LDAP_OPT_X_TLS */
+
+#if defined(HAVE_LDAP_SET_OPTION) && defined(LDAP_OPT_PROTOCOL_VERSION)
+ (void) ldap_set_option (ld, LDAP_OPT_PROTOCOL_VERSION,
+ &options.ldap_version);
+#else
+ ld->ld_version = options.ldap_version;
+#endif
+ debug3 ("LDAP set version to %d", options.ldap_version);
+
+#if LDAP_SET_REBIND_PROC_ARGS == 3
+ ldap_set_rebind_proc (ld, _rebind_proc, NULL);
+#elif LDAP_SET_REBIND_PROC_ARGS == 2
+ ldap_set_rebind_proc (ld, _rebind_proc);
+#else
+#warning unknown LDAP_SET_REBIND_PROC_ARGS
+#endif
+ debug3 ("LDAP set rebind proc");
+
+#if defined(HAVE_LDAP_SET_OPTION) && defined(LDAP_OPT_DEREF)
+ (void) ldap_set_option (ld, LDAP_OPT_DEREF, &options.deref);
+#else
+ ld->ld_deref = options.deref;
+#endif
+ debug3 ("LDAP set deref to %d", options.deref);
+
+#if defined(HAVE_LDAP_SET_OPTION) && defined(LDAP_OPT_TIMELIMIT)
+ (void) ldap_set_option (ld, LDAP_OPT_TIMELIMIT,
+ &options.timelimit);
+#else
+ ld->ld_timelimit = options.timelimit;
+#endif
+ debug3 ("LDAP set timelimit to %d", options.timelimit);
+
+#if defined(HAVE_LDAP_SET_OPTION) && defined(LDAP_X_OPT_CONNECT_TIMEOUT)
+ /*
+ * This is a new option in the Netscape SDK which sets
+ * the TCP connect timeout. For want of a better value,
+ * we use the bind_timelimit to control this.
+ */
+ timeout = options.bind_timelimit * 1000;
+ (void) ldap_set_option (ld, LDAP_X_OPT_CONNECT_TIMEOUT, &timeout);
+ debug3 ("LDAP set opt connect timeout to %d", timeout);
+#endif
+
+#if defined(HAVE_LDAP_SET_OPTION) && defined(LDAP_OPT_NETWORK_TIMEOUT)
+ tv.tv_sec = options.bind_timelimit;
+ tv.tv_usec = 0;
+ (void) ldap_set_option (ld, LDAP_OPT_NETWORK_TIMEOUT, &tv);
+ debug3 ("LDAP set opt network timeout to %ld.0", tv.tv_sec);
+#endif
+
+#if defined(HAVE_LDAP_SET_OPTION) && defined(LDAP_OPT_REFERRALS)
+ (void) ldap_set_option (ld, LDAP_OPT_REFERRALS,
+ options.referrals ? LDAP_OPT_ON : LDAP_OPT_OFF);
+ debug3 ("LDAP set referrals to %d", options.referrals);
+#endif
+
+#if defined(HAVE_LDAP_SET_OPTION) && defined(LDAP_OPT_RESTART)
+ (void) ldap_set_option (ld, LDAP_OPT_RESTART,
+ options.restart ? LDAP_OPT_ON : LDAP_OPT_OFF);
+ debug3 ("LDAP set restart to %d", options.restart);
+#endif
+
+#ifdef HAVE_LDAP_START_TLS_S
+ if (options.ssl == SSL_START_TLS) {
+ int version;
+
+ if (ldap_get_option (ld, LDAP_OPT_PROTOCOL_VERSION, &version)
+ == LDAP_SUCCESS) {
+ if (version < LDAP_VERSION3) {
+ version = LDAP_VERSION3;
+ (void) ldap_set_option (ld, LDAP_OPT_PROTOCOL_VERSION,
+ &version);
+ debug3 ("LDAP set version to %d", version);
+ }
+ }
+
+ if ((rc = ldap_start_tls_s (ld, NULL, NULL)) != LDAP_SUCCESS)
+ fatal ("ldap_starttls_s: %s", ldap_err2string (rc));
+ debug3 ("LDAP start TLS");
+ }
+#endif /* HAVE_LDAP_START_TLS_S */
+ }
+
+ if ((msgid = ldap_simple_bind (ld, options.binddn,
+ options.bindpw)) == -1) {
+ ld_errno = ldap_get_lderrno (ld, 0, 0);
+
+ error ("ldap_simple_bind %s", ldap_err2string (ld_errno));
+ reconnect++;
+ goto retry;
+ }
+ debug3 ("LDAP simple bind (%s)", options.binddn);
+
+ timeout.tv_sec = options.bind_timelimit;
+ timeout.tv_usec = 0;
+ if ((rc = ldap_result (ld, msgid, FALSE, &timeout, &result)) < 1) {
+ ld_errno = ldap_get_lderrno (ld, 0, 0);
+
+ error ("ldap_result %s", ldap_err2string (ld_errno));
+ reconnect++;
+ goto retry;
+ }
+ debug3 ("LDAP result in time");
+
+#if defined(HAVE_LDAP_PARSE_RESULT) && defined(HAVE_LDAP_CONTROLS_FREE)
+ controls = NULL;
+ if ((parserc = ldap_parse_result (ld, result, &rc, 0, 0, 0, &controls, TRUE)) != LDAP_SUCCESS)
+ fatal ("ldap_parse_result %s", ldap_err2string (parserc));
+ debug3 ("LDAP parse result OK");
+
+ if (controls != NULL) {
+ ldap_controls_free (controls);
+ }
+#else
+ rc = ldap_result2error (session->ld, result, TRUE);
+#endif
+ if (rc != LDAP_SUCCESS)
+ fatal ("error trying to bind as user \"%s\" (%s)",
+ options.binddn, ldap_err2string (rc));
+
+ debug2 ("LDAP do connect OK");
+}
+
+void
+process_user (const char *user, FILE *output)
+{
+ LDAPMessage *res, *e;
+ char *buffer;
+ int bufflen, rc, i;
+ struct timeval timeout;
+
+ debug ("LDAP process user");
+
+ /* quick check for attempts to be evil */
+ if ((strchr(user, '(') != NULL) || (strchr(user, ')') != NULL) ||
+ (strchr(user, '*') != NULL) || (strchr(user, '\\') != NULL)) {
+ logit ("illegal user name %s not processed", user);
+ return;
+ }
+
+ /* build filter for LDAP request */
+ bufflen = strlen (LDAPSEARCH_FORMAT) + strlen (user);
+ if (options.ssh_filter != NULL)
+ bufflen += strlen (options.ssh_filter);
+ buffer = xmalloc (bufflen);
+ snprintf(buffer, bufflen, LDAPSEARCH_FORMAT, user, (options.ssh_filter != NULL) ? options.ssh_filter : NULL);
+ buffer[bufflen - 1] = 0;
+
+ debug3 ("LDAP search scope = %d %s", options.scope, buffer);
+
+ timeout.tv_sec = options.timelimit;
+ timeout.tv_usec = 0;
+ if ((rc = ldap_search_st(ld, options.base, options.scope, buffer, attrs, 0, &timeout, &res)) != LDAP_SUCCESS) {
+ error ("ldap_search_st(): %s", ldap_err2string (rc));
+ xfree (buffer);
+ return;
+ }
+
+ /* free */
+ xfree (buffer);
+
+ for (e = ldap_first_entry(ld, res); e != NULL; e = ldap_next_entry(ld, e)) {
+ int num;
+ struct berval **keys;
+
+ keys = ldap_get_values_len(ld, e, PUBKEYATTR);
+ num = ldap_count_values_len(keys);
+ for (i = 0 ; i < num ; i++) {
+ char *cp; //, *options = NULL;
+
+ for (cp = keys[i]->bv_val; *cp == ' ' || *cp == '\t'; cp++);
+ if (!*cp || *cp == '\n' || *cp == '#')
+ continue;
+
+ /* We have found the desired key. */
+ fprintf (output, "%s\n", keys[i]->bv_val);
+ }
+
+ ldap_value_free_len(keys);
+ }
+
+ ldap_msgfree(res);
+ debug2 ("LDAP process user finished");
+}
+
+void
+ldap_do_close(void)
+{
+ int rc;
+
+ debug ("LDAP do close");
+ if ((rc = ldap_unbind_ext(ld, NULL, NULL)) != LDAP_SUCCESS)
+ fatal ("ldap_unbind_ext: %s",
+ ldap_err2string (rc));
+
+ ld = NULL;
+ debug2 ("LDAP do close OK");
+ return;
+}
+
diff -up openssh-5.5p1/ldapbody.h.ldap openssh-5.5p1/ldapbody.h
--- openssh-5.5p1/ldapbody.h.ldap 2010-04-28 11:34:14.000000000 +0200
+++ openssh-5.5p1/ldapbody.h 2010-04-28 11:34:14.000000000 +0200
@@ -0,0 +1,37 @@
+/* $OpenBSD: ldapbody.h,v 1.1 2009/12/03 03:34:42 jfch Exp $ */
+/*
+ * Copyright (c) 2009 Jan F. Chadima. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 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.
+ */
+
+#ifndef LDAPBODY_H
+#define LDAPBODY_H
+
+#include <stdio.h>
+
+void ldap_checkconfig(void);
+void ldap_do_connect(void);
+void process_user(const char *, FILE *);
+void ldap_do_close(void);
+
+#endif /* LDAPBODY_H */
+
diff -up openssh-5.5p1/ldapconf.c.ldap openssh-5.5p1/ldapconf.c
--- openssh-5.5p1/ldapconf.c.ldap 2010-04-28 11:34:14.000000000 +0200
+++ openssh-5.5p1/ldapconf.c 2010-04-28 11:34:14.000000000 +0200
@@ -0,0 +1,665 @@
+/* $OpenBSD: ldapconf.c,v 1.1 2009/12/03 03:34:42 jfch Exp $ */
+/*
+ * Copyright (c) 2009 Jan F. Chadima. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 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.
+ */
+
+#include "ldapincludes.h"
+#include "ldap-helper.h"
+#include "log.h"
+#include "misc.h"
+#include "xmalloc.h"
+#include "ldapconf.h"
+#include <unistd.h>
+#include <string.h>
+
+/* Keyword tokens. */
+
+typedef enum {
+ lBadOption,
+ lHost, lURI, lBase, lBindDN, lBindPW, lRootBindDN,
+ lScope, lDeref, lPort, lTimeLimit, lBind_TimeLimit,
+ lLdap_Version, lBind_Policy, lSSLPath, lSSL, lReferrals,
+ lRestart, lTLS_CheckPeer, lTLS_Certificate, lTLS_CaCertFile,
+ lTLS_CaCertDir, lTLS_Ciphers, lTLS_Cert, lTLS_Key,
+ lTLS_RandFile, lLogdir, lDebug, lSSH_Filter,
+ lDeprecated, lUnsupported
+} OpCodes;
+
+/* Textual representations of the tokens. */
+
+static struct {
+ const char *name;
+ OpCodes opcode;
+} keywords[] = {
+ { "Host", lHost },
+ { "URI", lURI },
+ { "Base", lBase },
+ { "BindDN", lBindDN },
+ { "BindPW", lBindPW },
+ { "RootBindDN", lRootBindDN },
+ { "Scope", lScope },
+ { "Deref", lDeref },
+ { "Port", lPort },
+ { "Timelimit", lTimeLimit },
+ { "Bind_Timelimit", lBind_TimeLimit },
+ { "Ldap_Version", lLdap_Version },
+ { "Bind_Policy", lBind_Policy },
+ { "SSLPath", lSSLPath },
+ { "SSL", lSSL },
+ { "Referrals", lReferrals },
+ { "Restart", lRestart },
+ { "TLS_CheckPeer", lTLS_CheckPeer },
+ { "TLS_Certificate", lTLS_Certificate },
+ { "TLS_CaCertFile", lTLS_CaCertFile },
+ { "TLS_CaCertDir", lTLS_CaCertDir },
+ { "TLS_Ciphers", lTLS_Ciphers },
+ { "TLS_Cert", lTLS_Cert },
+ { "TLS_Key", lTLS_Key },
+ { "TLS_RandFile", lTLS_RandFile },
+ { "Logdir", lLogdir },
+ { "Debug", lDebug },
+ { "SSH_Filter", lSSH_Filter },
+ { NULL, lBadOption }
+};
+
+/* Configuration ptions. */
+
+Options options;
+
+/*
+ * Returns the number of the token pointed to by cp or oBadOption.
+ */
+
+static OpCodes
+parse_token(const char *cp, const char *filename, int linenum)
+{
+ u_int i;
+
+ for (i = 0; keywords[i].name; i++)
+ if (strcasecmp(cp, keywords[i].name) == 0)
+ return keywords[i].opcode;
+
+ if (config_warning_config_file)
+ logit("%s: line %d: Bad configuration option: %s",
+ filename, linenum, cp);
+ return lBadOption;
+}
+
+/*
+ * Processes a single option line as used in the configuration files. This
+ * only sets those values that have not already been set.
+ */
+#define WHITESPACE " \t\r\n"
+
+static int
+process_config_line(char *line, const char *filename, int linenum)
+{
+ char *s, **charptr, **xstringptr, *endofnumber, *keyword, *arg;
+ char *rootbinddn = NULL;
+ int opcode, *intptr, value;
+ size_t len;
+
+ /* Strip trailing whitespace */
+ for (len = strlen(line) - 1; len > 0; len--) {
+ if (strchr(WHITESPACE, line[len]) == NULL)
+ break;
+ line[len] = '\0';
+ }
+
+ s = line;
+ /* Get the keyword. (Each line is supposed to begin with a keyword). */
+ if ((keyword = strdelim(&s)) == NULL)
+ return 0;
+ /* Ignore leading whitespace. */
+ if (*keyword == '\0')
+ keyword = strdelim(&s);
+ if (keyword == NULL || !*keyword || *keyword == '\n' || *keyword == '#')
+ return 0;
+
+ opcode = parse_token(keyword, filename, linenum);
+
+ switch (opcode) {
+ case lBadOption:
+ /* don't panic, but count bad options */
+ return -1;
+ /* NOTREACHED */
+
+ case lHost:
+ xstringptr = &options.host;
+parse_xstring:
+ if (!s || *s == '\0')
+ fatal("%s line %d: missing dn",filename,linenum);
+ if (*xstringptr == NULL)
+ *xstringptr = xstrdup(s);
+ return 0;
+
+ case lURI:
+ xstringptr = &options.uri;
+ goto parse_xstring;
+
+ case lBase:
+ xstringptr = &options.base;
+ goto parse_xstring;
+
+ case lBindDN:
+ xstringptr = &options.binddn;
+ goto parse_xstring;
+
+ case lBindPW:
+ charptr = &options.bindpw;
+parse_string:
+ arg = strdelim(&s);
+ if (!arg || *arg == '\0')
+ fatal("%.200s line %d: Missing argument.", filename, linenum);
+ if (*charptr == NULL)
+ *charptr = xstrdup(arg);
+ break;
+
+ case lRootBindDN:
+ xstringptr = &rootbinddn;
+ goto parse_xstring;
+
+ case lScope:
+ intptr = &options.scope;
+ arg = strdelim(&s);
+ if (!arg || *arg == '\0')
+ fatal("%.200s line %d: Missing sub/one/base argument.", filename, linenum);
+ value = 0; /* To avoid compiler warning... */
+ if (!strcasecmp (arg, "sub"))
+ value = LDAP_SCOPE_SUBTREE;
+ else if (!strcasecmp (arg, "one"))
+ value = LDAP_SCOPE_ONELEVEL;
+ else if (!strcasecmp (arg, "base"))
+ value = LDAP_SCOPE_BASE;
+ else
+ fatal("%.200s line %d: Bad sub/one/base argument.", filename, linenum);
+ if (*intptr == -1)
+ *intptr = value;
+ break;
+
+ case lDeref:
+ intptr = &options.scope;
+ arg = strdelim(&s);
+ if (!arg || *arg == '\0')
+ fatal("%.200s line %d: Missing never/searching/finding/always argument.", filename, linenum);
+ value = 0; /* To avoid compiler warning... */
+ if (!strcasecmp (arg, "never"))
+ value = LDAP_DEREF_NEVER;
+ else if (!strcasecmp (arg, "searching"))
+ value = LDAP_DEREF_SEARCHING;
+ else if (!strcasecmp (arg, "finding"))
+ value = LDAP_DEREF_FINDING;
+ else if (!strcasecmp (arg, "always"))
+ value = LDAP_DEREF_ALWAYS;
+ else
+ fatal("%.200s line %d: Bad never/searching/finding/always argument.", filename, linenum);
+ if (*intptr == -1)
+ *intptr = value;
+ break;
+
+ case lPort:
+ intptr = &options.port;
+parse_int:
+ arg = strdelim(&s);
+ if (!arg || *arg == '\0')
+ fatal("%.200s line %d: Missing argument.", filename, linenum);
+ if (arg[0] < '0' || arg[0] > '9')
+ fatal("%.200s line %d: Bad number.", filename, linenum);
+
+ /* Octal, decimal, or hex format? */
+ value = strtol(arg, &endofnumber, 0);
+ if (arg == endofnumber)
+ fatal("%.200s line %d: Bad number.", filename, linenum);
+ if (*intptr == -1)
+ *intptr = value;
+ break;
+
+ case lTimeLimit:
+ intptr = &options.timelimit;
+parse_time:
+ arg = strdelim(&s);
+ if (!arg || *arg == '\0')
+ fatal("%s line %d: missing time value.",
+ filename, linenum);
+ if ((value = convtime(arg)) == -1)
+ fatal("%s line %d: invalid time value.",
+ filename, linenum);
+ if (*intptr == -1)
+ *intptr = value;
+ break;
+
+ case lBind_TimeLimit:
+ intptr = &options.bind_timelimit;
+ goto parse_time;
+
+ case lLdap_Version:
+ intptr = &options.ldap_version;
+ goto parse_int;
+
+ case lBind_Policy:
+ intptr = &options.bind_policy;
+ arg = strdelim(&s);
+ if (!arg || *arg == '\0')
+ fatal("%.200s line %d: Missing soft/hard argument.", filename, linenum);
+ value = 0; /* To avoid compiler warning... */
+ if (strcasecmp(arg, "hard") == 0)
+ value = 1;
+ else if (strcasecmp(arg, "soft") == 0)
+ value = 0;
+ else
+ fatal("%.200s line %d: Bad soft/hard argument.", filename, linenum);
+ if (*intptr == -1)
+ break;
+
+ case lSSLPath:
+ charptr = &options.sslpath;
+ goto parse_string;
+
+ case lSSL:
+ intptr = &options.ssl;
+ arg = strdelim(&s);
+ if (!arg || *arg == '\0')
+ fatal("%.200s line %d: Missing yes/no/start_tls argument.", filename, linenum);
+ value = 0; /* To avoid compiler warning... */
+ if (strcasecmp(arg, "yes") == 0 || strcasecmp(arg, "true") == 0 || strcasecmp(arg, "on") == 0)
+ value = SSL_LDAPS;
+ else if (strcasecmp(arg, "no") == 0 || strcasecmp(arg, "false") == 0 || strcasecmp(arg, "off") == 0)
+ value = SSL_OFF;
+ else if (!strcasecmp (arg, "start_tls"))
+ value = SSL_START_TLS;
+ else
+ fatal("%.200s line %d: Bad yes/no/start_tls argument.", filename, linenum);
+ if (*intptr == -1)
+ *intptr = value;
+ break;
+
+ case lReferrals:
+ intptr = &options.referrals;
+parse_flag:
+ arg = strdelim(&s);
+ if (!arg || *arg == '\0')
+ fatal("%.200s line %d: Missing yes/no argument.", filename, linenum);
+ value = 0; /* To avoid compiler warning... */
+ if (strcasecmp(arg, "yes") == 0 || strcasecmp(arg, "true") == 0 || strcasecmp(arg, "on") == 0)
+ value = 1;
+ else if (strcasecmp(arg, "no") == 0 || strcasecmp(arg, "false") == 0 || strcasecmp(arg, "off") == 0)
+ value = 0;
+ else
+ fatal("%.200s line %d: Bad yes/no argument.", filename, linenum);
+ if (*intptr == -1)
+ *intptr = value;
+ break;
+
+ case lRestart:
+ intptr = &options.restart;
+ goto parse_flag;
+
+ case lTLS_CheckPeer:
+ intptr = &options.tls_checkpeer;
+ arg = strdelim(&s);
+ if (!arg || *arg == '\0')
+ fatal("%.200s line %d: Missing never/hard/demand/alow/try argument.", filename, linenum);
+ value = 0; /* To avoid compiler warning... */
+ if (strcasecmp(arg, "never") == 0)
+ value = LDAP_OPT_X_TLS_NEVER;
+ else if (strcasecmp(arg, "hard") == 0)
+ value = LDAP_OPT_X_TLS_HARD;
+ else if (strcasecmp(arg, "demand") == 0)
+ value = LDAP_OPT_X_TLS_DEMAND;
+ else if (strcasecmp(arg, "allow") == 0)
+ value = LDAP_OPT_X_TLS_ALLOW;
+ else if (strcasecmp(arg, "try") == 0)
+ value = LDAP_OPT_X_TLS_TRY;
+ else
+ fatal("%.200s line %d: Bad never/hard/demand/alow/try argument.", filename, linenum);
+ if (*intptr == -1)
+ break;
+
+ case lTLS_CaCertFile:
+ charptr = &options.tls_cacertfile;
+ goto parse_string;
+
+ case lTLS_CaCertDir:
+ charptr = &options.tls_cacertdir;
+ goto parse_string;
+
+ case lTLS_Ciphers:
+ xstringptr = &options.tls_ciphers;
+ goto parse_xstring;
+
+ case lTLS_Cert:
+ charptr = &options.tls_cert;
+ goto parse_string;
+
+ case lTLS_Key:
+ charptr = &options.tls_key;
+ goto parse_string;
+
+ case lTLS_RandFile:
+ charptr = &options.tls_randfile;
+ goto parse_string;
+
+ case lLogdir:
+ charptr = &options.logdir;
+ goto parse_string;
+
+ case lDebug:
+ intptr = &options.debug;
+ goto parse_int;
+
+ case lSSH_Filter:
+ xstringptr = &options.ssh_filter;
+ goto parse_xstring;
+
+ case lDeprecated:
+ debug("%s line %d: Deprecated option \"%s\"",
+ filename, linenum, keyword);
+ return 0;
+
+ case lUnsupported:
+ error("%s line %d: Unsupported option \"%s\"",
+ filename, linenum, keyword);
+ return 0;
+
+ default:
+ fatal("process_config_line: Unimplemented opcode %d", opcode);
+ }
+
+ /* Check that there is no garbage at end of line. */
+ if ((arg = strdelim(&s)) != NULL && *arg != '\0') {
+ fatal("%.200s line %d: garbage at end of line; \"%.200s\".",
+ filename, linenum, arg);
+ }
+ return 0;
+}
+
+/*
+ * Reads the config file and modifies the options accordingly. Options
+ * should already be initialized before this call. This never returns if
+ * there is an error. If the file does not exist, this returns 0.
+ */
+
+void
+read_config_file(const char *filename)
+{
+ FILE *f;
+ char line[1024];
+ int active, linenum;
+ int bad_options = 0;
+ struct stat sb;
+
+ if ((f = fopen(filename, "r")) == NULL)
+ fatal("fopen %s: %s", filename, strerror(errno));
+
+ if (fstat(fileno(f), &sb) == -1)
+ fatal("fstat %s: %s", filename, strerror(errno));
+ if (((sb.st_uid != 0 && sb.st_uid != getuid()) ||
+ (sb.st_mode & 022) != 0))
+ fatal("Bad owner or permissions on %s", filename);
+
+ debug("Reading configuration data %.200s", filename);
+
+ /*
+ * Mark that we are now processing the options. This flag is turned
+ * on/off by Host specifications.
+ */
+ active = 1;
+ linenum = 0;
+ while (fgets(line, sizeof(line), f)) {
+ /* Update line number counter. */
+ linenum++;
+ if (process_config_line(line, filename, linenum) != 0)
+ bad_options++;
+ }
+ fclose(f);
+ if ((bad_options > 0) && config_exclusive_config_file)
+ fatal("%s: terminating, %d bad configuration options",
+ filename, bad_options);
+}
+
+/*
+ * Initializes options to special values that indicate that they have not yet
+ * been set. Read_config_file will only set options with this value. Options
+ * are processed in the following order: command line, user config file,
+ * system config file. Last, fill_default_options is called.
+ */
+
+void
+initialize_options(void)
+{
+ memset(&options, 'X', sizeof(options));
+ options.host = NULL;
+ options.uri = NULL;
+ options.base = NULL;
+ options.binddn = NULL;
+ options.bindpw = NULL;
+ options.scope = -1;
+ options.deref = -1;
+ options.port = -1;
+ options.timelimit = -1;
+ options.bind_timelimit = -1;
+ options.ldap_version = -1;
+ options.bind_policy = -1;
+ options.sslpath = NULL;
+ options.ssl = -1;
+ options.referrals = -1;
+ options.restart = -1;
+ options.tls_checkpeer = -1;
+ options.tls_cacertfile = NULL;
+ options.tls_cacertdir = NULL;
+ options.tls_ciphers = NULL;
+ options.tls_cert = NULL;
+ options.tls_key = NULL;
+ options.tls_randfile = NULL;
+ options.logdir = NULL;
+ options.debug = -1;
+ options.ssh_filter = NULL;
+}
+
+/*
+ * Called after processing other sources of option data, this fills those
+ * options for which no value has been specified with their default values.
+ */
+
+void
+fill_default_options(void)
+{
+ if (options.uri != NULL) {
+ LDAPURLDesc *ludp;
+
+ if (ldap_url_parse(options.uri, &ludp) == LDAP_SUCCESS) {
+ if (options.ssl == -1) {
+ if (strcmp (ludp->lud_scheme, "ldap") || strcmp (ludp->lud_scheme, "ldapi"))
+ options.ssl = 0;
+ else if (strcmp (ludp->lud_scheme, "ldaps"))
+ options.ssl = 2;
+ }
+ if (options.host == NULL)
+ options.host = xstrdup (ludp->lud_host);
+ if (options.port == -1)
+ options.port = ludp->lud_port;
+
+ ldap_free_urldesc (ludp);
+ }
+ }
+ if (options.ssl == -1)
+ options.ssl = SSL_START_TLS;
+ if (options.port == -1)
+ options.port = (options.ssl == 0) ? 389 : 636;
+ if (options.uri == NULL) {
+ int len;
+#define MAXURILEN 4096
+
+ options.uri = xmalloc (MAXURILEN);
+ len = snprintf (options.uri, MAXURILEN, "ldap%s://%s:%d",
+ (options.ssl == 0) ? "" : "s", options.host, options.port);
+ options.uri[MAXURILEN - 1] = 0;
+ options.uri = xrealloc (options.uri, len + 1, 1);
+ }
+ if (options.binddn == NULL)
+ options.binddn = "";
+ if (options.bindpw == NULL)
+ options.bindpw = "";
+ if (options.scope == -1)
+ options.scope = LDAP_SCOPE_SUBTREE;
+ if (options.deref == -1)
+ options.deref = LDAP_DEREF_NEVER;
+ if (options.timelimit == -1)
+ options.timelimit = 10;
+ if (options.bind_timelimit == -1)
+ options.bind_timelimit = 10;
+ if (options.ldap_version == -1)
+ options.ldap_version = 3;
+ if (options.bind_policy == -1)
+ options.bind_policy = 1;
+ if (options.referrals == -1)
+ options.referrals = 1;
+ if (options.restart == -1)
+ options.restart = 1;
+ if (options.tls_checkpeer == -1)
+ options.tls_checkpeer = LDAP_OPT_X_TLS_HARD;
+ if (options.debug == -1)
+ options.debug = 0;
+ if (options.ssh_filter == NULL)
+ options.ssh_filter = "";
+}
+
+static const char *
+lookup_opcode_name(OpCodes code)
+{
+ u_int i;
+
+ for (i = 0; keywords[i].name != NULL; i++)
+ if (keywords[i].opcode == code)
+ return(keywords[i].name);
+ return "UNKNOWN";
+}
+
+static void
+dump_cfg_string(OpCodes code, const char *val)
+{
+ if (val == NULL)
+ debug3("%s <UNDEFINED>", lookup_opcode_name(code));
+ else
+ debug3("%s %s", lookup_opcode_name(code), val);
+}
+
+static void
+dump_cfg_int(OpCodes code, int val)
+{
+ if (val == -1)
+ debug3("%s <UNDEFINED>", lookup_opcode_name(code));
+ else
+ debug3("%s %d", lookup_opcode_name(code), val);
+}
+
+struct names {
+ int value;
+ char *name;
+};
+
+static void
+dump_cfg_namedint(OpCodes code, int val, struct names *names)
+{
+ u_int i;
+
+ if (val == -1)
+ debug3("%s <UNDEFINED>", lookup_opcode_name(code));
+ else {
+ for (i = 0; names[i].value != -1; i++)
+ if (names[i].value == val) {
+ debug3("%s %s", lookup_opcode_name(code), names[i].name);
+ return;
+ }
+ debug3("%s unknown: %d", lookup_opcode_name(code), val);
+ }
+}
+
+static struct names _yesnotls[] = {
+ { 0, "No" },
+ { 1, "Yes" },
+ { 2, "Start_TLS" },
+ { -1, NULL }};
+
+static struct names _scope[] = {
+ { LDAP_SCOPE_BASE, "Base" },
+ { LDAP_SCOPE_ONELEVEL, "One" },
+ { LDAP_SCOPE_SUBTREE, "Sub"},
+ { -1, NULL }};
+
+static struct names _deref[] = {
+ { LDAP_DEREF_NEVER, "Never" },
+ { LDAP_DEREF_SEARCHING, "Searching" },
+ { LDAP_DEREF_FINDING, "Finding" },
+ { LDAP_DEREF_ALWAYS, "Always" },
+ { -1, NULL }};
+
+static struct names _yesno[] = {
+ { 0, "No" },
+ { 1, "Yes" },
+ { -1, NULL }};
+
+static struct names _bindpolicy[] = {
+ { 0, "Soft" },
+ { 1, "Hard" },
+ { -1, NULL }};
+
+static struct names _checkpeer[] = {
+ { LDAP_OPT_X_TLS_NEVER, "Never" },
+ { LDAP_OPT_X_TLS_HARD, "Hard" },
+ { LDAP_OPT_X_TLS_DEMAND, "Demand" },
+ { LDAP_OPT_X_TLS_ALLOW, "Allow" },
+ { LDAP_OPT_X_TLS_TRY, "TRY" },
+ { -1, NULL }};
+
+void
+dump_config(void)
+{
+ dump_cfg_string(lURI, options.uri);
+ dump_cfg_string(lHost, options.host);
+ dump_cfg_int(lPort, options.port);
+ dump_cfg_namedint(lSSL, options.ssl, _yesnotls);
+ dump_cfg_int(lLdap_Version, options.ldap_version);
+ dump_cfg_int(lTimeLimit, options.timelimit);
+ dump_cfg_int(lBind_TimeLimit, options.bind_timelimit);
+ dump_cfg_string(lBase, options.base);
+ dump_cfg_string(lBindDN, options.binddn);
+ dump_cfg_string(lBindPW, options.bindpw);
+ dump_cfg_namedint(lScope, options.scope, _scope);
+ dump_cfg_namedint(lDeref, options.deref, _deref);
+ dump_cfg_namedint(lReferrals, options.referrals, _yesno);
+ dump_cfg_namedint(lRestart, options.restart, _yesno);
+ dump_cfg_namedint(lBind_Policy, options.bind_policy, _bindpolicy);
+ dump_cfg_string(lSSLPath, options.sslpath);
+ dump_cfg_namedint(lTLS_CheckPeer, options.tls_checkpeer, _checkpeer);
+ dump_cfg_string(lTLS_CaCertFile, options.tls_cacertfile);
+ dump_cfg_string(lTLS_CaCertDir, options.tls_cacertdir);
+ dump_cfg_string(lTLS_Ciphers, options.tls_ciphers);
+ dump_cfg_string(lTLS_Cert, options.tls_cert);
+ dump_cfg_string(lTLS_Key, options.tls_key);
+ dump_cfg_string(lTLS_RandFile, options.tls_randfile);
+ dump_cfg_string(lLogdir, options.logdir);
+ dump_cfg_int(lDebug, options.debug);
+ dump_cfg_string(lSSH_Filter, options.ssh_filter);
+}
+
diff -up openssh-5.5p1/ldapconf.h.ldap openssh-5.5p1/ldapconf.h
--- openssh-5.5p1/ldapconf.h.ldap 2010-04-28 11:34:14.000000000 +0200
+++ openssh-5.5p1/ldapconf.h 2010-04-28 11:34:14.000000000 +0200
@@ -0,0 +1,71 @@
+/* $OpenBSD: ldapconf.c,v 1.1 2009/12/03 03:34:42 jfch Exp $ */
+/*
+ * Copyright (c) 2009 Jan F. Chadima. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 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.
+ */
+
+#ifndef LDAPCONF_H
+#define LDAPCONF_H
+
+#define SSL_OFF 0
+#define SSL_LDAPS 1
+#define SSL_START_TLS 2
+
+/* Data structure for representing option data. */
+
+typedef struct {
+ char *host;
+ char *uri;
+ char *base;
+ char *binddn;
+ char *bindpw;
+ int scope;
+ int deref;
+ int port;
+ int timelimit;
+ int bind_timelimit;
+ int ldap_version;
+ int bind_policy;
+ char *sslpath;
+ int ssl;
+ int referrals;
+ int restart;
+ int tls_checkpeer;
+ char *tls_cacertfile;
+ char *tls_cacertdir;
+ char *tls_ciphers;
+ char *tls_cert;
+ char *tls_key;
+ char *tls_randfile;
+ char *logdir;
+ int debug;
+ char *ssh_filter;
+} Options;
+
+extern Options options;
+
+void read_config_file(const char *);
+void initialize_options(void);
+void fill_default_options(void);
+void dump_config(void);
+
+#endif /* LDAPCONF_H */
diff -up openssh-5.5p1/ldap-helper.c.ldap openssh-5.5p1/ldap-helper.c
--- openssh-5.5p1/ldap-helper.c.ldap 2010-04-28 11:34:14.000000000 +0200
+++ openssh-5.5p1/ldap-helper.c 2010-04-28 11:34:14.000000000 +0200
@@ -0,0 +1,154 @@
+/* $OpenBSD: ssh-pka-ldap.c,v 1.1 2009/12/03 03:34:42 jfch Exp $ */
+/*
+ * Copyright (c) 2009 Jan F. Chadima. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 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.
+ */
+
+#include "ldapincludes.h"
+#include "log.h"
+#include "misc.h"
+#include "xmalloc.h"
+#include "ldapconf.h"
+#include "ldapbody.h"
+#include <string.h>
+#include <unistd.h>
+
+static int config_debug = 0;
+int config_exclusive_config_file = 0;
+static char *config_file_name = "/etc/ldap.conf";
+static char *config_single_user = NULL;
+static int config_verbose = SYSLOG_LEVEL_VERBOSE;
+int config_warning_config_file = 0;
+extern char *__progname;
+
+static void
+usage(void)
+{
+ fprintf(stderr, "usage: %s [options]\n",
+ __progname);
+ fprintf(stderr, "Options:\n");
+ fprintf(stderr, " -d Output the log messages to stderr.\n");
+ fprintf(stderr, " -e Check the config file for unknown commands.\n");
+ fprintf(stderr, " -f file Use alternate config file (default is /etc/ldap.conf).\n");
+ fprintf(stderr, " -s user Do not demonize, send the user's key to stdout.\n");
+ fprintf(stderr, " -v Increase verbosity of the debug output (implies -d).\n");
+ fprintf(stderr, " -w Warn on unknown commands int the config file.\n");
+ exit(1);
+}
+
+/*
+ * Main program for the ssh pka ldap agent.
+ */
+
+int
+main(int ac, char **av)
+{
+ int opt;
+ FILE *outfile = NULL;
+
+ __progname = ssh_get_progname(av[0]);
+
+ log_init(__progname, SYSLOG_LEVEL_DEBUG3, SYSLOG_FACILITY_AUTH, 0);
+
+ /*
+ * Initialize option structure to indicate that no values have been
+ * set.
+ */
+ initialize_options();
+
+ /* Parse command-line arguments. */
+ while ((opt = getopt(ac, av, "def:s:vw")) != -1) {
+ switch (opt) {
+ case 'd':
+ config_debug = 1;
+ break;
+
+ case 'e':
+ config_exclusive_config_file = 1;
+ config_warning_config_file = 1;
+ break;
+
+ case 'f':
+ config_file_name = optarg;
+ break;
+
+ case 's':
+ config_single_user = optarg;
+ outfile = fdopen (dup (fileno (stdout)), "w");
+ break;
+
+ case 'v':
+ config_debug = 1;
+ if (config_verbose < SYSLOG_LEVEL_DEBUG3)
+ config_verbose++;
+ break;
+
+ case 'w':
+ config_warning_config_file = 1;
+ break;
+
+ case '?':
+ default:
+ usage();
+ break;
+ }
+ }
+
+ /* Initialize loging */
+ log_init(__progname, config_verbose, SYSLOG_FACILITY_AUTH, config_debug);
+
+ if (ac != optind)
+ fatal ("illegal extra parameter %s", av[1]);
+
+ /* Ensure that fds 0 and 2 are open or directed to /dev/null */
+ if (config_debug == 0)
+ sanitise_stdfd();
+
+ /* Read config file */
+ read_config_file(config_file_name);
+ fill_default_options();
+ if (config_verbose == SYSLOG_LEVEL_DEBUG3) {
+ debug3 ("=== Configuration ===");
+ dump_config();
+ debug3 ("=== *** ===");
+ }
+
+ ldap_checkconfig();
+ ldap_do_connect();
+
+ if (config_single_user) {
+ process_user (config_single_user, outfile);
+ } else {
+ fatal ("Not yet implemented");
+/* TODO
+ * open unix socket a run the loop on it
+ */
+ }
+
+ ldap_do_close();
+ return 0;
+}
+
+/* Ugly hack */
+void *buffer_get_string(Buffer *b, u_int *l) {}
+void buffer_put_string(Buffer *b, const void *f, u_int l) {}
+
diff -up openssh-5.5p1/ldap-helper.h.ldap openssh-5.5p1/ldap-helper.h
--- openssh-5.5p1/ldap-helper.h.ldap 2010-04-28 11:34:14.000000000 +0200
+++ openssh-5.5p1/ldap-helper.h 2010-04-28 11:34:14.000000000 +0200
@@ -0,0 +1,32 @@
+/* $OpenBSD: ldap-helper.h,v 1.1 2009/12/03 03:34:42 jfch Exp $ */
+/*
+ * Copyright (c) 2009 Jan F. Chadima. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 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.
+ */
+
+#ifndef LDAP_HELPER_H
+#define LDAP_HELPER_H
+
+extern int config_exclusive_config_file;
+extern int config_warning_config_file;
+
+#endif /* LDAP_HELPER_H */
diff -up openssh-5.5p1/ldapincludes.h.ldap openssh-5.5p1/ldapincludes.h
--- openssh-5.5p1/ldapincludes.h.ldap 2010-04-28 11:34:14.000000000 +0200
+++ openssh-5.5p1/ldapincludes.h 2010-04-28 11:34:14.000000000 +0200
@@ -0,0 +1,41 @@
+/* $OpenBSD: ldapconf.c,v 1.1 2009/12/03 03:34:42 jfch Exp $ */
+/*
+ * Copyright (c) 2009 Jan F. Chadima. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 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.
+ */
+
+#ifndef LDAPINCLUDES_H
+#define LDAPINCLUDES_H
+
+#include "includes.h"
+
+#ifdef HAVE_LBER_H
+#include <lber.h>
+#endif
+#ifdef HAVE_LDAP_H
+#include <ldap.h>
+#endif
+#ifdef HAVE_LDAP_SSL_H
+#include <ldap_ssl.h>
+#endif
+
+#endif /* LDAPINCLUDES_H */
diff -up openssh-5.5p1/ldapmisc.c.ldap openssh-5.5p1/ldapmisc.c
--- openssh-5.5p1/ldapmisc.c.ldap 2010-04-28 11:34:14.000000000 +0200
+++ openssh-5.5p1/ldapmisc.c 2010-04-28 11:34:14.000000000 +0200
@@ -0,0 +1,79 @@
+
+#include "ldapincludes.h"
+#include "ldapmisc.h"
+
+#ifndef HAVE_LDAP_GET_LDERRNO
+int
+ldap_get_lderrno (LDAP * ld, char **m, char **s)
+{
+#ifdef HAVE_LDAP_GET_OPTION
+ int rc;
+#endif
+ int lderrno;
+
+#if defined(HAVE_LDAP_GET_OPTION) && defined(LDAP_OPT_ERROR_NUMBER)
+ if ((rc = ldap_get_option (ld, LDAP_OPT_ERROR_NUMBER, &lderrno)) != LDAP_SUCCESS)
+ return rc;
+#else
+ lderrno = ld->ld_errno;
+#endif
+
+ if (s != NULL) {
+#if defined(HAVE_LDAP_GET_OPTION) && defined(LDAP_OPT_ERROR_STRING)
+ if ((rc = ldap_get_option (ld, LDAP_OPT_ERROR_STRING, s)) != LDAP_SUCCESS)
+ return rc;
+#else
+ *s = ld->ld_error;
+#endif
+ }
+
+ if (m != NULL) {
+#if defined(HAVE_LDAP_GET_OPTION) && defined(LDAP_OPT_MATCHED_DN)
+ if ((rc = ldap_get_option (ld, LDAP_OPT_MATCHED_DN, m)) != LDAP_SUCCESS)
+ return rc;
+#else
+ *m = ld->ld_matched;
+#endif
+ }
+
+ return lderrno;
+}
+#endif
+
+#ifndef HAVE_LDAP_SET_LDERRNO
+int
+ldap_set_lderrno (LDAP * ld, int lderrno, const char *m, const char *s)
+{
+#ifdef HAVE_LDAP_SET_OPTION
+ int rc;
+#endif
+
+#if defined(HAVE_LDAP_SET_OPTION) && defined(LDAP_OPT_ERROR_NUMBER)
+ if ((rc = ldap_set_option (ld, LDAP_OPT_ERROR_NUMBER, &lderrno)) != LDAP_SUCCESS)
+ return rc;
+#else
+ ld->ld_errno = lderrno;
+#endif
+
+ if (s != NULL) {
+#if defined(HAVE_LDAP_SET_OPTION) && defined(LDAP_OPT_ERROR_STRING)
+ if ((rc = ldap_set_option (ld, LDAP_OPT_ERROR_STRING, s)) != LDAP_SUCCESS)
+ return rc;
+#else
+ ld->ld_error = s;
+#endif
+ }
+
+ if (m != NULL) {
+#if defined(HAVE_LDAP_SET_OPTION) && defined(LDAP_OPT_MATCHED_DN)
+ if ((rc = ldap_set_option (ld, LDAP_OPT_MATCHED_DN, m)) != LDAP_SUCCESS)
+ return rc;
+#else
+ ld->ld_matched = m;
+#endif
+ }
+
+ return LDAP_SUCCESS;
+}
+#endif
+
diff -up openssh-5.5p1/ldapmisc.h.ldap openssh-5.5p1/ldapmisc.h
--- openssh-5.5p1/ldapmisc.h.ldap 2010-04-28 11:34:14.000000000 +0200
+++ openssh-5.5p1/ldapmisc.h 2010-04-28 11:34:14.000000000 +0200
@@ -0,0 +1,35 @@
+/* $OpenBSD: ldapbody.h,v 1.1 2009/12/03 03:34:42 jfch Exp $ */
+/*
+ * Copyright (c) 2009 Jan F. Chadima. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 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.
+ */
+
+#ifndef LDAPMISC_H
+#define LDAPMISC_H
+
+#include "ldapincludes.h"
+
+int ldap_get_lderrno (LDAP *, char **, char **);
+int ldap_set_lderrno (LDAP *, int, const char *, const char *);
+
+#endif /* LDAPMISC_H */
+
diff -up openssh-5.5p1/lpk-user-example.txt.ldap openssh-5.5p1/lpk-user-example.txt
--- openssh-5.5p1/lpk-user-example.txt.ldap 2010-04-28 11:34:14.000000000 +0200
+++ openssh-5.5p1/lpk-user-example.txt 2010-04-28 11:34:14.000000000 +0200
@@ -0,0 +1,117 @@
+
+Post to ML -> User Made Quick Install Doc.
+Contribution from John Lane <john@lane.uk.net>
+
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+OpenSSH LDAP keystore Patch
+===========================
+
+NOTE: these notes are a transcript of a specific installation
+ they work for me, your specifics may be different!
+ from John Lane March 17th 2005 john@lane.uk.net
+
+This is a patch to OpenSSH 4.0p1 to allow it to obtain users' public keys
+from their LDAP record as an alternative to ~/.ssh/authorized_keys.
+
+(Assuming here that necessary build stuff is in $BUILD)
+
+cd $BUILD/openssh-4.0p1
+patch -Np1 -i $BUILD/openssh-lpk-4.0p1-0.3.patch
+mkdir -p /var/empty &&
+./configure --prefix=/usr --sysconfdir=/etc/ssh \
+ --libexecdir=/usr/sbin --with-md5-passwords --with-pam \
+ --with-libs="-lldap" --with-cppflags="-DWITH_LDAP_PUBKEY"
+Now do.
+make &&
+make install
+
+Add the following config to /etc/ssh/ssh_config
+UseLPK yes
+LpkServers ldap://myhost.mydomain.com
+LpkUserDN ou=People,dc=mydomain,dc=com
+
+We need to tell sshd about the SSL keys during boot, as root's
+environment does not exist at that time. Edit /etc/rc.d/init.d/sshd.
+Change the startup code from this:
+ echo "Starting SSH Server..."
+ loadproc /usr/sbin/sshd
+ ;;
+to this:
+ echo "Starting SSH Server..."
+ LDAPRC="/root/.ldaprc" loadproc /usr/sbin/sshd
+ ;;
+
+Re-start the sshd daemon:
+/etc/rc.d/init.d/sshd restart
+
+Install the additional LDAP schema
+cp $BUILD/openssh-lpk-0.2.schema /etc/openldap/schema/openssh.schema
+
+Now add the openSSH LDAP schema to /etc/openldap/slapd.conf:
+Add the following to the end of the existing block of schema includes
+include /etc/openldap/schema/openssh.schema
+
+Re-start the LDAP server:
+/etc/rc.d/init.d/slapd restart
+
+To add one or more public keys to a user, eg "testuser" :
+ldapsearch -x -W -Z -LLL -b "uid=testuser,ou=People,dc=mydomain,dc=com" -D
+"uid=testuser,ou=People,dc=mydomain,dc=com" > /tmp/testuser
+
+append the following to this /tmp/testuser file
+objectclass: ldapPublicKey
+sshPublicKey: ssh-rsa
+AAAAB3NzaC1yc2EAAAABJQAAAIB3dsrwqXqD7E4zYYrxwdDKBUQxKMioXy9pxFVai64kAPxjU9KS
+qIo7QfkjslfsjflksjfldfkjsldfjLX/5zkzRmT28I5piGzunPv17S89z8XwSsuAoR1t86t+5dlI
+7eZE/gVbn2UQkQq7+kdDTS2yXV6VnC52N/kKLG3ciBkBAw== General Purpose RSA Key
+
+Then do a modify:
+ldapmodify -x -D "uid=testuser,ou=People,dc=mydomain,dc=com" -W -f
+/tmp/testuser -Z
+Enter LDAP Password:
+modifying entry "uid=testuser,ou=People,dc=mydomain,dc=com"
+And check the modify is ok:
+ldapsearch -x -W -Z -b "uid=testuser,ou=People,dc=mydomain,dc=com" -D
+"uid=testuser,ou=People,dc=mydomain,dc=com"
+Enter LDAP Password:
+# extended LDIF
+#
+# LDAPv3
+# base <uid=testuser,ou=People,dc=mydomain,dc=com> with scope sub
+# filter: (objectclass=*)
+# requesting: ALL
+#
+
+# testuser, People, mydomain.com
+dn: uid=testuser,ou=People,dc=mydomain,dc=com
+uid: testuser
+cn: testuser
+objectClass: account
+objectClass: posixAccount
+objectClass: top
+objectClass: shadowAccount
+objectClass: ldapPublicKey
+shadowLastChange: 12757
+shadowMax: 99999
+shadowWarning: 7
+loginShell: /bin/bash
+uidNumber: 9999
+gidNumber: 501
+homeDirectory: /home/testuser
+userPassword:: e1NTSEF9UDgwV1hnM1VjUDRJK0k1YnFiL1d4ZUJObXlZZ3Z3UTU=
+sshPublicKey: ssh-rsa
+AAAAB3NzaC1yc2EAAAABJQAAAIB3dsrwqXqD7E4zYYrxwdDKBUQxKMioXy9pxFVai64kAPxjU9KSqIo7QfkjslfsjflksjfldfkjsldfjLX/5zkzRmT28I5piGzunPv17S89z
+8XwSsuAoR1t86t+5dlI7eZE/gVbn2UQkQq7+kdDTS2yXV6VnC52N/kKLG3ciBkBAw== General Purpose RSA Key
+
+# search result
+search: 3
+result: 0 Success
+
+# numResponses: 2
+# numEntries: 1
+
+Now start a ssh session to user "testuser" from usual ssh client (e.g.
+puTTY). Login should succeed.
+
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
diff -up openssh-5.5p1/Makefile.in.ldap openssh-5.5p1/Makefile.in
--- openssh-5.5p1/Makefile.in.ldap 2010-04-28 11:34:10.000000000 +0200
+++ openssh-5.5p1/Makefile.in 2010-04-28 11:34:15.000000000 +0200
@@ -26,6 +26,7 @@ ASKPASS_PROGRAM=$(libexecdir)/ssh-askpas
SFTP_SERVER=$(libexecdir)/sftp-server
SSH_KEYSIGN=$(libexecdir)/ssh-keysign
SSH_PKCS11_HELPER=$(libexecdir)/ssh-pkcs11-helper
+SSH_LDAP_HELPER=$(libexecdir)/ssh-ldap-helper
RAND_HELPER=$(libexecdir)/ssh-rand-helper
PRIVSEP_PATH=@PRIVSEP_PATH@
SSH_PRIVSEP_USER=@SSH_PRIVSEP_USER@
@@ -61,8 +62,9 @@ EXEEXT=@EXEEXT@
INSTALL_SSH_PRNG_CMDS=@INSTALL_SSH_PRNG_CMDS@
INSTALL_SSH_RAND_HELPER=@INSTALL_SSH_RAND_HELPER@
+INSTALL_SSH_LDAP_HELPER=@INSTALL_SSH_LDAP_HELPER@
-TARGETS=ssh$(EXEEXT) sshd$(EXEEXT) ssh-add$(EXEEXT) ssh-keygen$(EXEEXT) ssh-keyscan${EXEEXT} ssh-keysign${EXEEXT} ssh-pkcs11-helper$(EXEEXT) ssh-agent$(EXEEXT) scp$(EXEEXT) ssh-rand-helper${EXEEXT} sftp-server$(EXEEXT) sftp$(EXEEXT)
+TARGETS=ssh$(EXEEXT) sshd$(EXEEXT) ssh-add$(EXEEXT) ssh-keygen$(EXEEXT) ssh-keyscan${EXEEXT} ssh-keysign${EXEEXT} ssh-pkcs11-helper$(EXEEXT) ssh-agent$(EXEEXT) scp$(EXEEXT) ssh-rand-helper${EXEEXT} sftp-server$(EXEEXT) sftp$(EXEEXT) ssh-ldap-helper$(EXEEXT)
LIBSSH_OBJS=acss.o authfd.o authfile.o bufaux.o bufbn.o buffer.o \
canohost.o channels.o cipher.o cipher-acss.o cipher-aes.o \
@@ -93,8 +95,8 @@ SSHDOBJS=sshd.o auth-rhosts.o auth-passw
audit.o audit-bsm.o platform.o sftp-server.o sftp-common.o \
roaming_common.o roaming_serv.o kexgsss.o
-MANPAGES = moduli.5.out 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 ssh-pkcs11-helper.8.out sshd_config.5.out ssh_config.5.out
-MANPAGES_IN = moduli.5 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 ssh-pkcs11-helper.8 sshd_config.5 ssh_config.5
+MANPAGES = moduli.5.out 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 ssh-pkcs11-helper.8.out ssh-ldap-helper.8.out sshd_config.5.out ssh_config.5.out
+MANPAGES_IN = moduli.5 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 ssh-pkcs11-helper.8 ssh-ldap-helper.8 sshd_config.5 ssh_config.5
MANTYPE = @MANTYPE@
CONFIGFILES=sshd_config.out ssh_config.out moduli.out
@@ -165,6 +167,9 @@ ssh-pkcs11-helper$(EXEEXT): $(LIBCOMPAT)
ssh-keyscan$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keyscan.o roaming_dummy.o
$(LD) -o $@ ssh-keyscan.o roaming_dummy.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh -lfipscheck $(LIBS)
+ssh-ldap-helper$(EXEEXT): $(LIBCOMPAT) libssh.a ldapconf.o ldapbody.o ldapmisc.o ldap-helper.o
+ $(LD) -o $@ ldapconf.o ldapbody.o ldapmisc.o ldap-helper.o $(LDFLAGS) -lssh -lopenbsd-compat -lfipscheck $(LIBS)
+
sftp-server$(EXEEXT): $(LIBCOMPAT) libssh.a sftp.o sftp-common.o sftp-server.o sftp-server-main.o
$(LD) -o $@ sftp-server.o sftp-common.o sftp-server-main.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS)
@@ -266,6 +271,9 @@ install-files:
fi
$(INSTALL) -m 4711 $(STRIP_OPT) ssh-keysign$(EXEEXT) $(DESTDIR)$(SSH_KEYSIGN)$(EXEEXT)
$(INSTALL) -m 0755 $(STRIP_OPT) ssh-pkcs11-helper$(EXEEXT) $(DESTDIR)$(SSH_PKCS11_HELPER)$(EXEEXT)
+ if test ! -z "$(INSTALL_SSH_LDAP_HELPER)" ; then \
+ $(INSTALL) -m 0700 $(STRIP_OPT) ssh-ldap-helper $(DESTDIR)$(SSH_LDAP_HELPER) ; \
+ fi
$(INSTALL) -m 0755 $(STRIP_OPT) sftp$(EXEEXT) $(DESTDIR)$(bindir)/sftp$(EXEEXT)
$(INSTALL) -m 0755 $(STRIP_OPT) sftp-server$(EXEEXT) $(DESTDIR)$(SFTP_SERVER)$(EXEEXT)
$(INSTALL) -m 644 ssh.1.out $(DESTDIR)$(mandir)/$(mansubdir)1/ssh.1
@@ -285,6 +293,9 @@ install-files:
$(INSTALL) -m 644 sftp-server.8.out $(DESTDIR)$(mandir)/$(mansubdir)8/sftp-server.8
$(INSTALL) -m 644 ssh-keysign.8.out $(DESTDIR)$(mandir)/$(mansubdir)8/ssh-keysign.8
$(INSTALL) -m 644 ssh-pkcs11-helper.8.out $(DESTDIR)$(mandir)/$(mansubdir)8/ssh-pkcs11-helper.8
+ if test ! -z "$(INSTALL_SSH_LDAP_HELPER)" ; then \
+ $(INSTALL) -m 644 ssh-ldap-helper.8.out $(DESTDIR)$(mandir)/$(mansubdir)8/ssh-ldap-helper.8 ; \
+ fi
-rm -f $(DESTDIR)$(bindir)/slogin
ln -s ./ssh$(EXEEXT) $(DESTDIR)$(bindir)/slogin
-rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/slogin.1
@@ -384,6 +395,7 @@ uninstall:
-rm -f $(DESTDIR)$(mandir)/$(mansubdir)8/sftp-server.8
-rm -f $(DESTDIR)$(mandir)/$(mansubdir)8/ssh-keysign.8
-rm -f $(DESTDIR)$(mandir)/$(mansubdir)8/ssh-pkcs11-helper.8
+ -rm -f $(DESTDIR)$(mandir)/$(mansubdir)8/ssh-ldap-helper.8
-rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/slogin.1
tests interop-tests: $(TARGETS)
diff -up openssh-5.5p1/openssh-lpk-openldap.schema.ldap openssh-5.5p1/openssh-lpk-openldap.schema
--- openssh-5.5p1/openssh-lpk-openldap.schema.ldap 2010-04-28 11:34:15.000000000 +0200
+++ openssh-5.5p1/openssh-lpk-openldap.schema 2010-04-28 11:34:15.000000000 +0200
@@ -0,0 +1,21 @@
+#
+# LDAP Public Key Patch schema for use with openssh-ldappubkey
+# useful with PKA-LDAP also
+#
+# Author: Eric AUGE <eau@phear.org>
+#
+# Based on the proposal of : Mark Ruijter
+#
+
+
+# octetString SYNTAX
+attributetype ( 1.3.6.1.4.1.24552.500.1.1.1.13 NAME 'sshPublicKey'
+ DESC 'MANDATORY: OpenSSH Public key'
+ EQUALITY octetStringMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 )
+
+# printableString SYNTAX yes|no
+objectclass ( 1.3.6.1.4.1.24552.500.1.1.2.0 NAME 'ldapPublicKey' SUP top AUXILIARY
+ DESC 'MANDATORY: OpenSSH LPK objectclass'
+ MUST ( sshPublicKey $ uid )
+ )
diff -up openssh-5.5p1/openssh-lpk-sun.schema.ldap openssh-5.5p1/openssh-lpk-sun.schema
--- openssh-5.5p1/openssh-lpk-sun.schema.ldap 2010-04-28 11:34:15.000000000 +0200
+++ openssh-5.5p1/openssh-lpk-sun.schema 2010-04-28 11:34:15.000000000 +0200
@@ -0,0 +1,23 @@
+#
+# LDAP Public Key Patch schema for use with openssh-ldappubkey
+# useful with PKA-LDAP also
+#
+# Author: Eric AUGE <eau@phear.org>
+#
+# Schema for Sun Directory Server.
+# Based on the original schema, modified by Stefan Fischer.
+#
+
+dn: cn=schema
+
+# octetString SYNTAX
+attributeTypes: ( 1.3.6.1.4.1.24552.500.1.1.1.13 NAME 'sshPublicKey'
+ DESC 'MANDATORY: OpenSSH Public key'
+ EQUALITY octetStringMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 )
+
+# printableString SYNTAX yes|no
+objectClasses: ( 1.3.6.1.4.1.24552.500.1.1.2.0 NAME 'ldapPublicKey' SUP top AUXILIARY
+ DESC 'MANDATORY: OpenSSH LPK objectclass'
+ MUST ( sshPublicKey $ uid )
+ )
diff -up openssh-5.5p1/README.lpk.ldap openssh-5.5p1/README.lpk
--- openssh-5.5p1/README.lpk.ldap 2010-04-28 11:34:15.000000000 +0200
+++ openssh-5.5p1/README.lpk 2010-04-28 12:33:34.000000000 +0200
@@ -0,0 +1,268 @@
+OpenSSH LDAP PUBLIC KEY PATCH
+Copyright (c) 2003 Eric AUGE (eau@phear.org)
+All rights reserved.
+
+Rewriten by Jan F.<2E>Chadima (jchadima@redhat.com)
+Copyright (c) 2010 Red Hat, Inc.
+The new PKA-LDAP patch is rewritten from the scratch.
+LDAP schema and part of the documentation is based on original
+LPK project (http://code.google.com/p/openssh-lpk),
+copyright (c) 2003 Eric AUGE
+The new openssh configuration is different from the original LPK one.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+2. 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.
+3. The name of the author may not be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 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.
+
+purposes of this patch:
+
+This patch would help to have authentication centralization policy
+using ssh public key authentication.
+This patch could be an alternative to other "secure" authentication system
+working in a similar way (Kerberos, SecurID, etc...), except the fact
+that it's based on OpenSSH and its public key abilities.
+
+>> FYI: <<
+'uid': means unix accounts existing on the current server
+'ServerGroup:' mean server group configured on the current server by the SSH_Filter option in the ldap.conf.
+
+example schema:
+
+
+ server1 (uid: eau,rival,toto) (ServerGroup: unix)
+ ___________ /
+ / \ --- - server3 (uid: eau, titi) (ServerGroup: unix)
+ | LDAP Server | \
+ | eau ,rival | server2 (uid: rival, eau) (ServerGroup: unix)
+ | titi ,toto |
+ | userx,.... | server5 (uid: eau) (ServerGroup: mail)
+ \___________/ \ /
+ ----- - server4 (uid: eau, rival) (no group configured)
+ \
+ etc...
+
+- WHAT WE NEED :
+
+ * configured LDAP server somewhere on the network (i.e. OpenLDAP)
+ * patched sshd (with this patch ;)
+ * LDAP user(/group) entry (look at users.ldif (& groups.ldif)):
+ User entry:
+ - attached to the 'ldapPublicKey' objectclass
+ - attached to the 'posixAccount' objectclass
+ - with a filled 'sshPublicKey' attribute
+ Example:
+ dn: uid=eau,ou=users,dc=cuckoos,dc=net
+ objectclass: top
+ objectclass: person
+ objectclass: organizationalPerson
+ objectclass: posixAccount
+ objectclass: ldapPublicKey
+ description: Eric AUGE Account
+ userPassword: blah
+ cn: Eric AUGE
+ sn: Eric AUGE
+ uid: eau
+ uidNumber: 1034
+ gidNumber: 1
+ homeDirectory: /export/home/eau
+ sshPublicKey: ssh-dss AAAAB3...
+ sshPublicKey: ssh-dss AAAAM5...
+
+ Group entry:
+ - attached to the 'posixGroup' objectclass
+ - with a 'cn' groupname attribute
+ - with multiple 'memberUid' attributes filled with usernames allowed in this group
+ Example:
+ # few members
+ dn: cn=unix,ou=groups,dc=cuckoos,dc=net
+ objectclass: top
+ objectclass: posixGroup
+ description: Unix based servers group
+ cn: unix
+ gidNumber: 1002
+ memberUid: eau
+ memberUid: user1
+ memberUid: user2
+
+
+- HOW IT WORKS :
+
+ * without patch
+ If a user wants to authenticate to log in a server the sshd, will first look for authentication method allowed (RSAauth,kerberos,etc..)
+ and if RSAauth and tickets based auth fails, it will fallback to standard password authentication (if enabled).
+
+ * with the patch
+ 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.
+ It will do an ldapsearch to get the public key directly from the LDAP instead of reading it from the server filesystem.
+ (usually in $HOME/.ssh/authorized_keys)
+
+ 2 tokens are added to sshd_config :
+ # here is the new patched ldap related tokens
+ PubkeyAgent /usr/libexec/openssh/ssh-ldap-helper -s %u
+ PubkeyAgentRunAs nobody
+
+ The LDAP configuratin is read from common /etc/ldap.conf configuration file.
+There is also one optional parameter in the LDAP configuration file, SSH_Filter, which is a LDAP filter limiting keys to be searched.
+
+- HOW TO INSERT A USER/KEY INTO AN LDAP ENTRY
+
+ * my way (there is plenty :)
+ - create ldif file (i.e. users.ldif)
+ - cat ~/.ssh/id_dsa.pub OR cat ~/.ssh/id_rsa.pub OR cat ~/.ssh/identity.pub
+ - my way in 4 steps :
+ Example:
+
+ # you add this to the user entry in the LDIF file :
+ [...]
+ objectclass: posixAccount
+ objectclass: ldapPublicKey
+ [...]
+ sshPubliKey: ssh-dss AAAABDh12DDUR2...
+ [...]
+
+ # insert your entry and you're done :)
+ ldapadd -D balblabla -w bleh < file.ldif
+
+ all standard options can be present in the 'sshPublicKey' attribute.
+
+- WHY :
+
+ Simply because, i was looking for a way to centralize all sysadmins authentication, easily, without completely using LDAP
+ as authentication method (like pam_ldap etc..).
+
+ After looking into Kerberos, SecurID, and other centralized secure authentications systems, the use of RSA and LDAP to get
+ public key for authentication allows us to control who has access to which server (the user needs an account and to be in 'strongAuthenticationUser'
+ objectclass within LDAP and part of the group the SSH server is in).
+
+ 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
+ so each user can change it as much as he wants).
+
+ Blocking a user account can be done directly from the LDAP (if sshd is using RSAAuth + ldap only).
+
+- RULES :
+ Entry in the LDAP server must respect 'posixAccount' and 'ldapPublicKey' which are defined in core.schema.
+ and the additionnal lpk.schema.
+
+ This patch could allow a smooth transition between standard auth (/etc/passwd) and complete LDAP based authentication
+ (pamldap, nss_ldap, etc..).
+
+ This can be an alternative to other (old?/expensive?) authentication methods (Kerberos/SecurID/..).
+
+ Referring to schema at the beginning of this file if user 'eau' is only in group 'unix'
+ 'eau' would ONLY access 'server1', 'server2', 'server3' AND 'server4' BUT NOT 'server5'.
+ If you then modify the LDAP 'mail' group entry to add 'memberUid: eau' THEN user 'eau' would be able
+ to log in 'server5' (i hope you got the idea, my english is bad :).
+
+ Each server's sshd is patched and configured to ask the public key and the group infos in the LDAP
+ server.
+ When you want to allow a new user to have access to the server parc, you just add him an account on
+ your servers, you add his public key into his entry on the LDAP server, it's done.
+
+ Because sshds are looking public keys into the LDAP directly instead of a file ($HOME/.ssh/authorized_keys).
+
+ When the user needs to change his passphrase he can do it directly from his workstation by changing
+ his own key set lock passphrase, and all servers are automatically aware.
+
+ With a CAREFUL LDAP server configuration you could allow a user to add/delete/modify his own entry himself
+ so he can add/modify/delete himself his public key when needed.
+
+<2B> FLAWS :
+ LDAP must be well configured, getting the public key of some user is not a problem, but if anonymous LDAP
+ allow write to users dn, somebody could replace someuser's public key by its own and impersonate some
+ of your users in all your server farm be VERY CAREFUL.
+
+ MITM attack when sshd is requesting the public key, could lead to a compromise of your servers allowing login
+ as the impersonnated user.
+
+ If LDAP server is down then, no fallback on passwd auth.
+
+ the ldap code part has not been well audited yet.
+
+- LDAP USER ENTRY EXAMPLES (LDIF Format, look in users.ldif)
+ --- CUT HERE ---
+ dn: uid=jdoe,ou=users,dc=foobar,dc=net
+ objectclass: top
+ objectclass: person
+ objectclass: organizationalPerson
+ objectclass: posixAccount
+ objectclass: ldapPublicKey
+ description: My account
+ cn: John Doe
+ sn: John Doe
+ uid: jdoe
+ uidNumber: 100
+ gidNumber: 100
+ homeDirectory: /home/jdoe
+ sshPublicKey: ssh-dss AAAAB3NzaC1kc3MAAAEBAOvL8pREUg9wSy/8+hQJ54YF3AXkB0OZrXB....
+ [...]
+ --- CUT HERE ---
+
+- LDAP GROUP ENTRY EXAMPLES (LDIF Format, look in groups.ldif)
+ --- CUT HERE ---
+ dn: cn=unix,ou=groups,dc=cuckoos,dc=net
+ objectclass: top
+ objectclass: posixGroup
+ description: Unix based servers group
+ cn: unix
+ gidNumber: 1002
+ memberUid: jdoe
+ memberUid: user1
+ memberUid: user2
+ [...]
+ --- CUT HERE ---
+
+>> FYI: <<
+Multiple 'sshPublicKey' in a user entry are allowed, as well as multiple 'memberUid' attributes in a group entry
+
+- COMPILING:
+ 1. Apply the patch
+ 2. ./configure --with-your-options --with-ldap=/prefix/to/ldap_libs_and_includes
+ 3. make
+ 4. it's done.
+
+- BLA :
+ I hope this could help, and i hope to be clear enough,, or give ideas. questions/comments/improvements are welcome.
+
+- TODO :
+ Redesign differently.
+
+- DOCS/LINK :
+ http://pacsec.jp/core05/psj05-barisani-en.pdf
+ http://fritz.potsdam.edu/projects/openssh-lpk/
+ http://fritz.potsdam.edu/projects/sshgate/
+ http://dev.inversepath.com/trac/openssh-lpk
+ http://lam.sf.net/ ( http://lam.sourceforge.net/documentation/supportedSchemas.htm )
+
+- CONTRIBUTORS/IDEAS/GREETS :
+ - Eric AUGE <eau@phear.org>
+ - Andrea Barisani <andrea@inversepath.com>
+ - Falk Siemonsmeier.
+ - Jacob Rief.
+ - Michael Durchgraf.
+ - frederic peters.
+ - Finlay dobbie.
+ - Stefan Fisher.
+ - Robin H. Johnson.
+ - Adrian Bridgett.
+
+- CONTACT :
+ Jan F. Chadima <jchadima@redhat.com>
+
diff -up openssh-5.5p1/ssh-ldap-helper.8.ldap openssh-5.5p1/ssh-ldap-helper.8
--- openssh-5.5p1/ssh-ldap-helper.8.ldap 2010-04-28 11:34:15.000000000 +0200
+++ openssh-5.5p1/ssh-ldap-helper.8 2010-04-28 11:34:15.000000000 +0200
@@ -0,0 +1,78 @@
+.\" $OpenBSD: ssh-ldap-helper.8,v 1.1 2010/02/10 23:20:38 markus Exp $
+.\"
+.\" Copyright (c) 2010 Jan F. Chadima. All rights reserved.
+.\"
+.\" Permission to use, copy, modify, and distribute this software for any
+.\" purpose with or without fee is hereby granted, provided that the above
+.\" copyright notice and this permission notice appear in all copies.
+.\"
+.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+.\"
+.Dd $Mdocdate: April 29 2010 $
+.Dt SSH-LDAP-HELPER 8
+.Os
+.Sh NAME
+.Nm ssh-ldap-helper
+.Nd sshd helper program for ldap support
+.Sh SYNOPSIS
+.Nm ssh-ldap-helper
+.Op Fl devw
+.Op Fl f Ar file
+.Op Fl s Ar user
+.Sh DESCRIPTION
+.Nm
+is used by
+.Xr sshd 1
+to access keys provided by a LDAP.
+.Nm
+is disabled by default and can only be enabled in the
+sshd configuration file
+.Pa /etc/ssh/sshd_config
+by setting
+.Cm PubkeyAgent
+to
+.Dq /usr/libexec/ssh-ldap-helper -s %u .
+.Pp
+.Nm
+is not intended to be invoked by the user, but from
+.Xr sshd 8 .
+.Pp
+The options are as follows:
+.Bl -tag -width Ds
+.It Fl d
+Set the debug mode,
+.Nm
+prints all logs to stderr instead of syslog.
+.It Fl e
+Implies \-w
+.Nm
+halt when an unknown item is found in the ldap.conf file.
+.It Fl f
+Default /etc/ldap.conf.
+.Nm
+uses this file as a ldap configuration file.
+.It Fl s
+.Nm
+print out the keys of the user on stdout and exits.
+.It Fl v
+Implies \-d
+increases verbosity.
+.It Fl w
+.Nm
+writes warnings about unknown items in the ldap.conf file.
+
+.Sh SEE ALSO
+.Xr sshd 8 ,
+.Xr sshd_config 5 ,
+.Sh HISTORY
+.Nm
+first appeared in
+OpenSSH 5.5 + PKA-LDAP .
+.Sh AUTHORS
+.An Jan F. Chadima Aq jchadima@redhat.com