2548 lines
84 KiB
Diff
2548 lines
84 KiB
Diff
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
|