X-Git-Url: http://git.pld-linux.org/?a=blobdiff_plain;f=openssh-ldap.patch;h=cfc761558816daab1c7fd73ac419fe0f8fde3eaa;hb=52f772a66c46a35bb94fe8a0ca5c2591ee5a4b9b;hp=36265580052328ced38aa56d6571e0334d72aee7;hpb=048795bff78e5e4541f7c1e6d02aaae3476ebcb8;p=packages%2Fopenssh.git diff --git a/openssh-ldap.patch b/openssh-ldap.patch index 3626558..cfc7615 100644 --- a/openssh-ldap.patch +++ b/openssh-ldap.patch @@ -1,116 +1,6 @@ -diff -up openssh-6.2p1/configure.ac.ldap openssh-6.2p1/configure.ac ---- openssh-6.2p1/configure.ac.ldap 2013-03-20 02:55:15.000000000 +0100 -+++ openssh-6.2p1/configure.ac 2013-03-25 21:27:15.888248071 +0100 -@@ -1509,6 +1509,106 @@ AC_ARG_WITH([audit], - esac ] - ) - -+# 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 )) -+ 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 -+ #include ], -+ [(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 -+ #include ], -+ [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 \ -diff -up openssh-6.2p1/HOWTO.ldap-keys.ldap openssh-6.2p1/HOWTO.ldap-keys ---- openssh-6.2p1/HOWTO.ldap-keys.ldap 2013-03-25 21:27:15.889248078 +0100 -+++ openssh-6.2p1/HOWTO.ldap-keys 2013-03-25 21:27:15.889248078 +0100 +diff -urNp -x '*.orig' openssh-8.4p1.org/HOWTO.ldap-keys openssh-8.4p1/HOWTO.ldap-keys +--- openssh-8.4p1.org/HOWTO.ldap-keys 1970-01-01 01:00:00.000000000 +0100 ++++ openssh-8.4p1/HOWTO.ldap-keys 2021-03-01 11:29:31.277623165 +0100 @@ -0,0 +1,108 @@ + +HOW TO START @@ -220,509 +110,379 @@ diff -up openssh-6.2p1/HOWTO.ldap-keys.ldap openssh-6.2p1/HOWTO.ldap-keys +5) Author + Jan F. Chadima + -diff -up openssh-6.2p1/ldapbody.c.ldap openssh-6.2p1/ldapbody.c ---- openssh-6.2p1/ldapbody.c.ldap 2013-03-25 21:27:15.889248078 +0100 -+++ openssh-6.2p1/ldapbody.c 2013-03-25 21:27:15.889248078 +0100 -@@ -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. -+ */ +diff -urNp -x '*.orig' openssh-8.4p1.org/Makefile.in openssh-8.4p1/Makefile.in +--- openssh-8.4p1.org/Makefile.in 2020-09-27 09:25:01.000000000 +0200 ++++ openssh-8.4p1/Makefile.in 2021-03-01 11:29:31.280956671 +0100 +@@ -23,6 +23,8 @@ SSH_PROGRAM=@bindir@/ssh + ASKPASS_PROGRAM=$(libexecdir)/ssh-askpass + SFTP_SERVER=$(libexecdir)/sftp-server + SSH_KEYSIGN=$(libexecdir)/ssh-keysign ++SSH_LDAP_HELPER=$(libexecdir)/ssh-ldap-helper ++SSH_LDAP_WRAPPER=$(libexecdir)/ssh-ldap-wrapper + SSH_PKCS11_HELPER=$(libexecdir)/ssh-pkcs11-helper + SSH_SK_HELPER=$(libexecdir)/ssh-sk-helper + PRIVSEP_PATH=@PRIVSEP_PATH@ +@@ -63,10 +65,11 @@ LDFLAGS_NOPIE=-L. -Lopenbsd-compat/ @LDF + EXEEXT=@EXEEXT@ + MANFMT=@MANFMT@ + MKDIR_P=@MKDIR_P@ ++INSTALL_SSH_LDAP_HELPER=@INSTALL_SSH_LDAP_HELPER@ + + .SUFFIXES: .lo + +-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) sftp-server$(EXEEXT) sftp$(EXEEXT) ssh-sk-helper$(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) sftp-server$(EXEEXT) sftp$(EXEEXT) ssh-sk-helper$(EXEEXT) ssh-ldap-helper$(EXEEXT) + + XMSS_OBJS=\ + ssh-xmss.o \ +@@ -150,8 +153,8 @@ SFTPSERVER_OBJS=sftp-common.o sftp-serve + + SFTP_OBJS= sftp.o sftp-usergroup.o progressmeter.o $(SFTP_CLIENT_OBJS) + +-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-keysign.8.out ssh-pkcs11-helper.8.out ssh-sk-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-keysign.8 ssh-pkcs11-helper.8 ssh-sk-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-keysign.8.out ssh-pkcs11-helper.8.out ssh-sk-helper.8.out ssh-ldap-helper.8.out sshd_config.5.out ssh_config.5.out ssh-ldap.conf.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-keysign.8 ssh-pkcs11-helper.8 ssh-sk-helper.8 ssh-ldap-helper.8 sshd_config.5 ssh_config.5 ssh-ldap.conf.5 + MANTYPE = @MANTYPE@ + + CONFIGFILES=sshd_config.out ssh_config.out moduli.out +@@ -230,6 +233,9 @@ ssh-pkcs11-helper$(EXEEXT): $(LIBCOMPAT) + ssh-sk-helper$(EXEEXT): $(LIBCOMPAT) libssh.a $(SKHELPER_OBJS) + $(LD) -o $@ $(SKHELPER_OBJS) $(LDFLAGS) -lssh -lopenbsd-compat -lssh -lopenbsd-compat $(LIBS) $(LIBFIDO2) $(CHANNELLIBS) + ++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) + -+#include "ldapincludes.h" -+#include "log.h" -+#include "xmalloc.h" -+#include "ldapconf.h" -+#include "ldapmisc.h" -+#include "ldapbody.h" -+#include -+#include + ssh-keyscan$(EXEEXT): $(LIBCOMPAT) libssh.a $(SSHKEYSCAN_OBJS) + $(LD) -o $@ $(SSHKEYSCAN_OBJS) $(LDFLAGS) -lssh -lopenbsd-compat -lssh $(LIBS) $(CHANNELLIBS) + +@@ -395,6 +401,10 @@ install-files: + $(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) + $(INSTALL) -m 0755 $(STRIP_OPT) ssh-sk-helper$(EXEEXT) $(DESTDIR)$(SSH_SK_HELPER)$(EXEEXT) ++ if test ! -z "$(INSTALL_SSH_LDAP_HELPER)" ; then \ ++ $(INSTALL) -m 0700 $(STRIP_OPT) ssh-ldap-helper $(DESTDIR)$(SSH_LDAP_HELPER) ; \ ++ $(INSTALL) -m 0700 ssh-ldap-wrapper $(DESTDIR)$(SSH_LDAP_WRAPPER) ; \ ++ 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 +@@ -412,6 +422,10 @@ install-files: + $(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 + $(INSTALL) -m 644 ssh-sk-helper.8.out $(DESTDIR)$(mandir)/$(mansubdir)8/ssh-sk-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 ; \ ++ $(INSTALL) -m 644 ssh-ldap.conf.5.out $(DESTDIR)$(mandir)/$(mansubdir)5/ssh-ldap.conf.5 ; \ ++ fi + + install-sysconf: + $(MKDIR_P) $(DESTDIR)$(sysconfdir) +@@ -435,6 +449,13 @@ install-sysconf: + else \ + echo "$(DESTDIR)$(sysconfdir)/moduli already exists, install will not overwrite"; \ + fi ++ if test ! -z "$(INSTALL_SSH_LDAP_HELPER)" ; then \ ++ if [ ! -f $(DESTDIR)$(sysconfdir)/ldap.conf ]; then \ ++ $(INSTALL) -m 644 ldap.conf $(DESTDIR)$(sysconfdir)/ldap.conf; \ ++ else \ ++ echo "$(DESTDIR)$(sysconfdir)/ldap.conf already exists, install will not overwrite"; \ ++ fi ; \ ++ fi + + host-key: ssh-keygen$(EXEEXT) + @if [ -z "$(DESTDIR)" ] ; then \ +@@ -473,6 +494,8 @@ uninstall: + -rm -f $(DESTDIR)$(SSH_KEYSIGN)$(EXEEXT) + -rm -f $(DESTDIR)$(SSH_PKCS11_HELPER)$(EXEEXT) + -rm -f $(DESTDIR)$(SSH_SK_HELPER)$(EXEEXT) ++ -rm -f $(DESTDIR)$(SSH_LDAP_HELPER)$(EXEEXT) ++ -rm -f $(DESTDIR)$(SSH_LDAP_WRAPPER)$(EXEEXT) + -rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/ssh.1 + -rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/scp.1 + -rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/ssh-add.1 +@@ -485,6 +508,7 @@ uninstall: + -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-sk-helper.8 ++ -rm -f $(DESTDIR)$(mandir)/$(mansubdir)8/ssh-ldap-helper.8 + + regress-prep: + $(MKDIR_P) `pwd`/regress/unittests/test_helper +diff -urNp -x '*.orig' openssh-8.4p1.org/configure.ac openssh-8.4p1/configure.ac +--- openssh-8.4p1.org/configure.ac 2021-03-01 11:29:31.004275724 +0100 ++++ openssh-8.4p1/configure.ac 2021-03-01 11:29:31.277623165 +0100 +@@ -1763,6 +1763,106 @@ AC_COMPILE_IFELSE( + CFLAGS="$SAVED_CFLAGS" + AC_SUBST([PICFLAG]) + ++# 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 + -+#define LDAPSEARCH_FORMAT "(&(objectclass=%s)(objectclass=ldapPublicKey)(uid=%s)%s)" -+#define PUBKEYATTR "sshPublicKey" -+#define LDAP_LOGFILE "%s/ldap.%d" ++ INSTALL_SSH_LDAP_HELPER="yes" ++ CPPFLAGS="$CPPFLAGS -DLDAP_DEPRECATED" + -+static FILE *logfile = NULL; -+static LDAP *ld; ++ if test "x$withval" != "xyes" ; then ++ CPPFLAGS="$CPPFLAGS -I${withval}/include" ++ LDFLAGS="$LDFLAGS -L${withval}/lib" ++ fi + -+static char *attrs[] = { -+ PUBKEYATTR, -+ NULL -+}; ++ AC_DEFINE([WITH_LDAP_PUBKEY], 1, [Enable LDAP pubkey support]) ++ LDAP_MSG="yes" + -+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"); -+} ++ AC_CHECK_HEADERS(lber.h) ++ AC_CHECK_HEADERS(ldap.h, , AC_MSG_ERROR(could not locate )) ++ AC_CHECK_HEADERS(ldap_ssl.h) + -+#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 */ ++ AC_ARG_WITH(ldap-lib, ++ [ --with-ldap-lib=type select ldap library [auto|netscape5|netscape4|netscape3|umich|openldap]]) + -+ 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 test -z "$with_ldap_lib"; then ++ with_ldap_lib=auto ++ fi + -+#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); -+ free (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 -+ (void) 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 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 (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 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 ((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 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 ((msgid = ldap_simple_bind (ld, options.binddn, -+ options.bindpw)) == -1) { -+ ld_errno = ldap_get_lderrno (ld, 0, 0); ++ 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 + -+ error ("ldap_simple_bind %s", ldap_err2string (ld_errno)); -+ reconnect++; -+ goto retry; -+ } -+ debug3 ("LDAP simple bind (%s)", options.binddn); ++ if test -z "$found_ldap_lib"; then ++ AC_MSG_ERROR(could not locate a valid LDAP library) ++ fi + -+ 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); ++ AC_MSG_CHECKING([for working LDAP support]) ++ AC_TRY_COMPILE( ++ [#include ++ #include ], ++ [(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 ++ #include ], ++ [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) + -+ error ("ldap_result %s", ldap_err2string (ld_errno)); -+ reconnect++; -+ goto retry; -+ } -+ debug3 ("LDAP result in time"); + dnl Checks for library functions. Please keep in alphabetical order + AC_CHECK_FUNCS([ \ + Blowfish_initstate \ +diff -urNp -x '*.orig' openssh-8.4p1.org/ldap-helper.c openssh-8.4p1/ldap-helper.c +--- openssh-8.4p1.org/ldap-helper.c 1970-01-01 01:00:00.000000000 +0100 ++++ openssh-8.4p1/ldap-helper.c 2021-03-01 11:29:31.280956671 +0100 +@@ -0,0 +1,155 @@ ++/* $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. ++ */ + -+#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"); ++#include "ldapincludes.h" ++#include "log.h" ++#include "misc.h" ++#include "xmalloc.h" ++#include "ldapconf.h" ++#include "ldapbody.h" ++#include ++#include + -+ 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)); ++static int config_debug = 0; ++int config_exclusive_config_file = 0; ++static char *config_file_name = "/etc/ssh/ldap.conf"; ++static char *config_single_user = NULL; ++static int config_verbose = SYSLOG_LEVEL_VERBOSE; ++int config_warning_config_file = 0; ++extern char *__progname; + -+ debug2 ("LDAP do connect OK"); ++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/ssh/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 in the config file.\n"); ++ exit(1); +} + -+void -+process_user (const char *user, FILE *output) ++/* ++ * Main program for the ssh pka ldap agent. ++ */ ++ ++int ++main(int ac, char **av) +{ -+ LDAPMessage *res, *e; -+ char *buffer; -+ int bufflen, rc, i; -+ struct timeval timeout; ++ int opt; ++ FILE *outfile = NULL; + -+ debug ("LDAP process user"); ++ __progname = ssh_get_progname(av[0]); + -+ /* 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; -+ } ++ log_init(__progname, SYSLOG_LEVEL_DEBUG3, SYSLOG_FACILITY_AUTH, 0); + -+ /* build filter for LDAP request */ -+ bufflen = strlen (LDAPSEARCH_FORMAT) + strlen(options.account_class) + strlen (user); -+ if (options.ssh_filter != NULL) -+ bufflen += strlen (options.ssh_filter); -+ buffer = xmalloc (bufflen); -+ snprintf(buffer, bufflen, LDAPSEARCH_FORMAT, options.account_class, user, (options.ssh_filter != NULL) ? options.ssh_filter : NULL); -+ buffer[bufflen - 1] = 0; ++ /* ++ * Initialize option structure to indicate that no values have been ++ * set. ++ */ ++ initialize_options(); + -+ debug3 ("LDAP search scope = %d %s", options.scope, buffer); ++ /* Parse command-line arguments. */ ++ while ((opt = getopt(ac, av, "def:s:vw")) != -1) { ++ switch (opt) { ++ case 'd': ++ config_debug = 1; ++ break; + -+ 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)); -+ free (buffer); -+ return; -+ } ++ case 'e': ++ config_exclusive_config_file = 1; ++ config_warning_config_file = 1; ++ break; + -+ /* free */ -+ free (buffer); ++ case 'f': ++ config_file_name = optarg; ++ break; + -+ for (e = ldap_first_entry(ld, res); e != NULL; e = ldap_next_entry(ld, e)) { -+ int num; -+ struct berval **keys; ++ case 's': ++ config_single_user = optarg; ++ outfile = fdopen (dup (fileno (stdout)), "w"); ++ break; + -+ keys = ldap_get_values_len(ld, e, PUBKEYATTR); -+ num = ldap_count_values_len(keys); -+ for (i = 0 ; i < num ; i++) { -+ char *cp; //, *options = NULL; ++ case 'v': ++ config_debug = 1; ++ if (config_verbose < SYSLOG_LEVEL_DEBUG3) ++ config_verbose++; ++ break; + -+ for (cp = keys[i]->bv_val; *cp == ' ' || *cp == '\t'; cp++); -+ if (!*cp || *cp == '\n' || *cp == '#') -+ continue; ++ case 'w': ++ config_warning_config_file = 1; ++ break; + -+ /* We have found the desired key. */ -+ fprintf (output, "%s\n", keys[i]->bv_val); ++ case '?': ++ default: ++ usage(); ++ break; + } -+ -+ ldap_value_free_len(keys); + } + -+ ldap_msgfree(res); -+ debug2 ("LDAP process user finished"); -+} ++ /* Initialize loging */ ++ log_init(__progname, config_verbose, SYSLOG_FACILITY_AUTH, config_debug); + -+void -+ldap_do_close(void) -+{ -+ int rc; ++ if (ac != optind) ++ fatal ("illegal extra parameter %s", av[1]); + -+ debug ("LDAP do close"); -+ if ((rc = ldap_unbind_ext(ld, NULL, NULL)) != LDAP_SUCCESS) -+ fatal ("ldap_unbind_ext: %s", -+ ldap_err2string (rc)); ++ /* 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 { ++ usage(); ++ fatal ("Not yet implemented"); ++/* TODO ++ * open unix socket a run the loop on it ++ */ ++ } + -+ ld = NULL; -+ debug2 ("LDAP do close OK"); -+ return; ++ ldap_do_close(); ++ return 0; +} + -diff -up openssh-6.2p1/ldapbody.h.ldap openssh-6.2p1/ldapbody.h ---- openssh-6.2p1/ldapbody.h.ldap 2013-03-25 21:27:15.889248078 +0100 -+++ openssh-6.2p1/ldapbody.h 2013-03-25 21:27:15.889248078 +0100 -@@ -0,0 +1,37 @@ -+/* $OpenBSD: ldapbody.h,v 1.1 2009/12/03 03:34:42 jfch Exp $ */ ++/* Ugly hack */ ++void *buffer_get_string(struct sshbuf *b, u_int *l) { return NULL; } ++void buffer_put_string(struct sshbuf *b, const void *f, u_int l) {} ++ +diff -urNp -x '*.orig' openssh-8.4p1.org/ldap-helper.h openssh-8.4p1/ldap-helper.h +--- openssh-8.4p1.org/ldap-helper.h 1970-01-01 01:00:00.000000000 +0100 ++++ openssh-8.4p1/ldap-helper.h 2021-03-01 11:29:31.280956671 +0100 +@@ -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. + * @@ -747,23 +507,110 @@ diff -up openssh-6.2p1/ldapbody.h.ldap openssh-6.2p1/ldapbody.h + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + -+#ifndef LDAPBODY_H -+#define LDAPBODY_H ++#ifndef LDAP_HELPER_H ++#define LDAP_HELPER_H + -+#include ++extern int config_exclusive_config_file; ++extern int config_warning_config_file; + -+void ldap_checkconfig(void); -+void ldap_do_connect(void); -+void process_user(const char *, FILE *); -+void ldap_do_close(void); ++#endif /* LDAP_HELPER_H */ +diff -urNp -x '*.orig' openssh-8.4p1.org/ldap.conf openssh-8.4p1/ldap.conf +--- openssh-8.4p1.org/ldap.conf 1970-01-01 01:00:00.000000000 +0100 ++++ openssh-8.4p1/ldap.conf 2021-03-01 11:29:31.280956671 +0100 +@@ -0,0 +1,88 @@ ++# $Id: openssh-5.5p1-ldap.patch,v 1.3 2010/07/07 13:48:36 jfch2222 Exp $ ++# ++# This is the example configuration file for the OpenSSH ++# LDAP backend ++# ++# see ssh-ldap.conf(5) ++# + -+#endif /* LDAPBODY_H */ ++# URI with your LDAP server name. This allows to use ++# Unix Domain Sockets to connect to a local LDAP Server. ++#uri ldap://127.0.0.1/ ++#uri ldaps://127.0.0.1/ ++#uri ldapi://%2fvar%2frun%2fldapi_sock/ ++# Note: %2f encodes the '/' used as directory separator + -diff -up openssh-6.2p2/ldapconf.c.ldap openssh-6.2p2/ldapconf.c ---- openssh-6.2p2/ldapconf.c.ldap 2013-06-07 15:10:05.601942693 +0200 -+++ openssh-6.2p2/ldapconf.c 2013-06-07 15:10:24.928857566 +0200 -@@ -0,0 +1,691 @@ -+/* $OpenBSD: ldapconf.c,v 1.1 2009/12/03 03:34:42 jfch Exp $ */ ++# Another way to specify your LDAP server is to provide an ++# host name and the port of our LDAP server. Host name ++# must be resolvable without using LDAP. ++# Multiple hosts may be specified, each separated by a ++# space. How long nss_ldap takes to failover depends on ++# whether your LDAP client library supports configurable ++# network or connect timeouts (see bind_timelimit). ++#host 127.0.0.1 ++ ++# The port. ++# Optional: default is 389. ++#port 389 ++ ++# The distinguished name to bind to the server with. ++# Optional: default is to bind anonymously. ++#binddn cn=openssh_keys,dc=example,dc=org ++ ++# The credentials to bind with. ++# Optional: default is no credential. ++#bindpw TopSecret ++ ++# The distinguished name of the search base. ++#base dc=example,dc=org ++ ++# The LDAP version to use (defaults to 3 ++# if supported by client library) ++#ldap_version 3 ++ ++# The search scope. ++#scope sub ++#scope one ++#scope base ++ ++# Search timelimit ++#timelimit 30 ++ ++# Bind/connect timelimit ++#bind_timelimit 30 ++ ++# Reconnect policy: hard (default) will retry connecting to ++# the software with exponential backoff, soft will fail ++# immediately. ++#bind_policy hard ++ ++# SSL setup, may be implied by URI also. ++#ssl no ++#ssl on ++#ssl start_tls ++ ++# OpenLDAP SSL options ++# Require and verify server certificate (yes/no) ++# Default is to use libldap's default behavior, which can be configured in ++# /etc/openldap/ldap.conf using the TLS_REQCERT setting. The default for ++# OpenLDAP 2.0 and earlier is "no", for 2.1 and later is "yes". ++#tls_checkpeer hard ++ ++# CA certificates for server certificate verification ++# At least one of these are required if tls_checkpeer is "yes" ++#tls_cacertfile /etc/ssl/ca.cert ++#tls_cacertdir /etc/pki/tls/certs ++ ++# Seed the PRNG if /dev/urandom is not provided ++#tls_randfile /var/run/egd-pool ++ ++# SSL cipher suite ++# See man ciphers for syntax ++#tls_ciphers TLSv1 ++ ++# Client certificate and key ++# Use these, if your server requires client authentication. ++#tls_cert ++#tls_key ++ +diff -urNp -x '*.orig' openssh-8.4p1.org/ldapbody.c openssh-8.4p1/ldapbody.c +--- openssh-8.4p1.org/ldapbody.c 1970-01-01 01:00:00.000000000 +0100 ++++ openssh-8.4p1/ldapbody.c 2021-03-01 11:29:31.280956671 +0100 +@@ -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. + * @@ -789,1003 +636,1215 @@ diff -up openssh-6.2p2/ldapconf.c.ldap openssh-6.2p2/ldapconf.c + */ + +#include "ldapincludes.h" -+#include "ldap-helper.h" +#include "log.h" -+#include "misc.h" +#include "xmalloc.h" +#include "ldapconf.h" ++#include "ldapmisc.h" ++#include "ldapbody.h" ++#include +#include -+#include + -+/* Keyword tokens. */ ++#define LDAPSEARCH_FORMAT "(&(objectclass=%s)(objectclass=ldapPublicKey)(uid=%s)%s)" ++#define PUBKEYATTR "sshPublicKey" ++#define LDAP_LOGFILE "%s/ldap.%d" + -+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_CaCertFile, -+ lTLS_CaCertDir, lTLS_Ciphers, lTLS_Cert, lTLS_Key, -+ lTLS_RandFile, lLogDir, lDebug, lSSH_Filter, -+ lAccountClass, lDeprecated, lUnsupported -+} OpCodes; ++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; + -+/* Textual representations of the tokens. */ ++ 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); ++ free (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 ++ (void) 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 */ + -+static struct { -+ const char *name; -+ OpCodes opcode; -+} keywords[] = { -+ { "URI", lURI }, -+ { "Base", lBase }, -+ { "BindDN", lBindDN }, -+ { "BindPW", lBindPW }, -+ { "RootBindDN", lRootBindDN }, -+ { "Host", lHost }, -+ { "Port", lPort }, -+ { "Scope", lScope }, -+ { "Deref", lDeref }, -+ { "TimeLimit", lTimeLimit }, -+ { "TimeOut", lTimeLimit }, -+ { "Bind_Timelimit", lBind_TimeLimit }, -+ { "Network_TimeOut", lBind_TimeLimit }, -+/* -+ * Todo -+ * SIZELIMIT -+ */ -+ { "Ldap_Version", lLdap_Version }, -+ { "Version", lLdap_Version }, -+ { "Bind_Policy", lBind_Policy }, -+ { "SSLPath", lSSLPath }, -+ { "SSL", lSSL }, -+ { "Referrals", lReferrals }, -+ { "Restart", lRestart }, -+ { "TLS_CheckPeer", lTLS_CheckPeer }, -+ { "TLS_ReqCert", lTLS_CheckPeer }, -+ { "TLS_CaCertFile", lTLS_CaCertFile }, -+ { "TLS_CaCert", lTLS_CaCertFile }, -+ { "TLS_CaCertDir", lTLS_CaCertDir }, -+ { "TLS_Ciphers", lTLS_Ciphers }, -+ { "TLS_Cipher_Suite", lTLS_Ciphers }, -+ { "TLS_Cert", lTLS_Cert }, -+ { "TLS_Certificate", lTLS_Cert }, -+ { "TLS_Key", lTLS_Key }, -+ { "TLS_RandFile", lTLS_RandFile }, -+/* -+ * Todo -+ * TLS_CRLCHECK -+ * TLS_CRLFILE -+ */ -+ { "LogDir", lLogDir }, -+ { "Debug", lDebug }, -+ { "SSH_Filter", lSSH_Filter }, -+ { "AccountClass", lAccountClass }, -+ { NULL, lBadOption } -+}; ++ 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"); ++ } + -+/* Configuration ptions. */ ++ 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 */ + -+Options options; ++ /* 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. */ + -+/* -+ * Returns the number of the token pointed to by cp or oBadOption. -+ */ ++#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 */ + -+static OpCodes -+parse_token(const char *cp, const char *filename, int linenum) -+{ -+ u_int i; ++ /* 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); ++ } + -+ for (i = 0; keywords[i].name; i++) -+ if (strcasecmp(cp, keywords[i].name) == 0) -+ return keywords[i].opcode; ++ /* 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); ++ } + -+ if (config_warning_config_file) -+ logit("%s: line %d: Bad configuration option: %s", -+ filename, linenum, cp); -+ return lBadOption; -+} ++ /* 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); + -+/* -+ * 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" ++ /* 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); ++ } + -+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; ++ /* 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); ++ } + -+ /* Strip trailing whitespace */ -+ for (len = strlen(line) - 1; len > 0; len--) { -+ if (strchr(WHITESPACE, line[len]) == NULL) -+ break; -+ line[len] = '\0'; ++ /* 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 */ + -+ 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; ++ /* 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 */ ++ } + -+ opcode = parse_token(keyword, filename, linenum); ++ if (ld == NULL) ++ fatal ("no way to open ldap"); + -+ switch (opcode) { -+ case lBadOption: -+ /* don't panic, but count bad options */ -+ return -1; -+ /* NOTREACHED */ ++#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 */ + -+ 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; ++#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); + -+ case lURI: -+ xstringptr = &options.uri; -+ goto parse_xstring; ++#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); + -+ case lBase: -+ xstringptr = &options.base; -+ goto parse_xstring; ++#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); + -+ case lBindDN: -+ xstringptr = &options.binddn; -+ goto parse_xstring; ++#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 + -+ 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; ++#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 + -+ case lRootBindDN: -+ xstringptr = &rootbinddn; -+ goto parse_xstring; ++#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 + -+ 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") == 0 || strcasecmp (arg, "subtree") == 0) -+ value = LDAP_SCOPE_SUBTREE; -+ else if (strcasecmp (arg, "one") == 0) -+ value = LDAP_SCOPE_ONELEVEL; -+ else if (strcasecmp (arg, "base") == 0) -+ value = LDAP_SCOPE_BASE; -+ else -+ fatal("%.200s line %d: Bad sub/one/base argument.", filename, linenum); -+ if (*intptr == -1) -+ *intptr = value; -+ break; ++#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 + -+ 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; ++#ifdef HAVE_LDAP_START_TLS_S ++ if (options.ssl == SSL_START_TLS) { ++ int version; + -+ 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); ++ 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); ++ } ++ } + -+ /* 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; ++ 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 */ ++ } + -+ 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; ++ if ((msgid = ldap_simple_bind (ld, options.binddn, ++ options.bindpw)) == -1) { ++ ld_errno = ldap_get_lderrno (ld, 0, 0); + -+ case lBind_TimeLimit: -+ intptr = &options.bind_timelimit; -+ goto parse_time; ++ error ("ldap_simple_bind %s", ldap_err2string (ld_errno)); ++ reconnect++; ++ goto retry; ++ } ++ debug3 ("LDAP simple bind (%s)", options.binddn); + -+ case lLdap_Version: -+ intptr = &options.ldap_version; -+ goto parse_int; ++ 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); + -+ 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 || strcasecmp(arg, "hard_open") == 0 || strcasecmp(arg, "hard_init") == 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; ++ error ("ldap_result %s", ldap_err2string (ld_errno)); ++ reconnect++; ++ goto retry; ++ } ++ debug3 ("LDAP result in time"); + -+ case lSSLPath: -+ charptr = &options.sslpath; -+ goto parse_string; ++#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"); + -+ 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; ++ 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)); + -+ 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; ++ debug2 ("LDAP do connect OK"); ++} + -+ case lRestart: -+ intptr = &options.restart; -+ goto parse_flag; ++void ++process_user (const char *user, FILE *output) ++{ ++ LDAPMessage *res, *e; ++ char *buffer; ++ int bufflen, rc, i; ++ struct timeval timeout; + -+ 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 || strcasecmp(arg, "no") == 0 || strcasecmp(arg, "false") == 0 || strcasecmp(arg, "off") == 0) -+ value = LDAP_OPT_X_TLS_NEVER; -+ else if (strcasecmp(arg, "hard") == 0 || strcasecmp(arg, "yes") == 0 || strcasecmp(arg, "true") == 0 || strcasecmp(arg, "on") == 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; ++ debug ("LDAP process user"); + -+ case lTLS_CaCertFile: -+ charptr = &options.tls_cacertfile; -+ goto parse_string; ++ /* 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; ++ } + -+ case lTLS_CaCertDir: -+ charptr = &options.tls_cacertdir; -+ goto parse_string; ++ /* build filter for LDAP request */ ++ bufflen = strlen (LDAPSEARCH_FORMAT) + strlen(options.account_class) + strlen (user); ++ if (options.ssh_filter != NULL) ++ bufflen += strlen (options.ssh_filter); ++ buffer = xmalloc (bufflen); ++ snprintf(buffer, bufflen, LDAPSEARCH_FORMAT, options.account_class, user, (options.ssh_filter != NULL) ? options.ssh_filter : NULL); ++ buffer[bufflen - 1] = 0; + -+ case lTLS_Ciphers: -+ xstringptr = &options.tls_ciphers; -+ goto parse_xstring; ++ debug3 ("LDAP search scope = %d %s", options.scope, buffer); + -+ case lTLS_Cert: -+ charptr = &options.tls_cert; -+ goto parse_string; ++ 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)); ++ free (buffer); ++ return; ++ } + -+ case lTLS_Key: -+ charptr = &options.tls_key; -+ goto parse_string; ++ /* free */ ++ free (buffer); + -+ case lTLS_RandFile: -+ charptr = &options.tls_randfile; -+ goto parse_string; ++ for (e = ldap_first_entry(ld, res); e != NULL; e = ldap_next_entry(ld, e)) { ++ int num; ++ struct berval **keys; + -+ case lLogDir: -+ charptr = &options.logdir; -+ goto parse_string; ++ keys = ldap_get_values_len(ld, e, PUBKEYATTR); ++ num = ldap_count_values_len(keys); ++ for (i = 0 ; i < num ; i++) { ++ char *cp; //, *options = NULL; + -+ case lDebug: -+ intptr = &options.debug; -+ goto parse_int; ++ for (cp = keys[i]->bv_val; *cp == ' ' || *cp == '\t'; cp++); ++ if (!*cp || *cp == '\n' || *cp == '#') ++ continue; + -+ case lSSH_Filter: -+ xstringptr = &options.ssh_filter; -+ goto parse_xstring; ++ /* We have found the desired key. */ ++ fprintf (output, "%s\n", keys[i]->bv_val); ++ } + -+ case lAccountClass: -+ charptr = &options.account_class; -+ goto parse_string; ++ ldap_value_free_len(keys); ++ } + -+ case lDeprecated: -+ debug("%s line %d: Deprecated option \"%s\"", -+ filename, linenum, keyword); -+ return 0; ++ ldap_msgfree(res); ++ debug2 ("LDAP process user finished"); ++} + -+ case lUnsupported: -+ error("%s line %d: Unsupported option \"%s\"", -+ filename, linenum, keyword); -+ return 0; ++void ++ldap_do_close(void) ++{ ++ int rc; + -+ default: -+ fatal("process_config_line: Unimplemented opcode %d", opcode); -+ } ++ debug ("LDAP do close"); ++ if ((rc = ldap_unbind_ext(ld, NULL, NULL)) != LDAP_SUCCESS) ++ fatal ("ldap_unbind_ext: %s", ++ ldap_err2string (rc)); + -+ /* 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; ++ ld = NULL; ++ debug2 ("LDAP do close OK"); ++ return; +} + +diff -urNp -x '*.orig' openssh-8.4p1.org/ldapbody.h openssh-8.4p1/ldapbody.h +--- openssh-8.4p1.org/ldapbody.h 1970-01-01 01:00:00.000000000 +0100 ++++ openssh-8.4p1/ldapbody.h 2021-03-01 11:29:31.280956671 +0100 +@@ -0,0 +1,37 @@ ++/* $OpenBSD: ldapbody.h,v 1.1 2009/12/03 03:34:42 jfch Exp $ */ +/* -+ * 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. ++ * 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. + */ + -+void -+read_config_file(const char *filename) -+{ -+ FILE *f; -+ char line[1024]; -+ int active, linenum; -+ int bad_options = 0; -+ struct stat sb; ++#ifndef LDAPBODY_H ++#define LDAPBODY_H + -+ if ((f = fopen(filename, "r")) == NULL) -+ fatal("fopen %s: %s", filename, strerror(errno)); ++#include + -+ 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); ++void ldap_checkconfig(void); ++void ldap_do_connect(void); ++void process_user(const char *, FILE *); ++void ldap_do_close(void); + -+ debug("Reading configuration data %.200s", filename); ++#endif /* LDAPBODY_H */ + -+ /* -+ * 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); -+} +diff -urNp -x '*.orig' openssh-8.4p1.org/ldapconf.c openssh-8.4p1/ldapconf.c +--- openssh-8.4p1.org/ldapconf.c 1970-01-01 01:00:00.000000000 +0100 ++++ openssh-8.4p1/ldapconf.c 2021-03-01 11:29:31.280956671 +0100 +@@ -0,0 +1,691 @@ ++/* $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 ++#include ++ ++/* 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_CaCertFile, ++ lTLS_CaCertDir, lTLS_Ciphers, lTLS_Cert, lTLS_Key, ++ lTLS_RandFile, lLogDir, lDebug, lSSH_Filter, ++ lAccountClass, lDeprecated, lUnsupported ++} OpCodes; ++ ++/* Textual representations of the tokens. */ ++ ++static struct { ++ const char *name; ++ OpCodes opcode; ++} keywords[] = { ++ { "URI", lURI }, ++ { "Base", lBase }, ++ { "BindDN", lBindDN }, ++ { "BindPW", lBindPW }, ++ { "RootBindDN", lRootBindDN }, ++ { "Host", lHost }, ++ { "Port", lPort }, ++ { "Scope", lScope }, ++ { "Deref", lDeref }, ++ { "TimeLimit", lTimeLimit }, ++ { "TimeOut", lTimeLimit }, ++ { "Bind_Timelimit", lBind_TimeLimit }, ++ { "Network_TimeOut", lBind_TimeLimit }, ++/* ++ * Todo ++ * SIZELIMIT ++ */ ++ { "Ldap_Version", lLdap_Version }, ++ { "Version", lLdap_Version }, ++ { "Bind_Policy", lBind_Policy }, ++ { "SSLPath", lSSLPath }, ++ { "SSL", lSSL }, ++ { "Referrals", lReferrals }, ++ { "Restart", lRestart }, ++ { "TLS_CheckPeer", lTLS_CheckPeer }, ++ { "TLS_ReqCert", lTLS_CheckPeer }, ++ { "TLS_CaCertFile", lTLS_CaCertFile }, ++ { "TLS_CaCert", lTLS_CaCertFile }, ++ { "TLS_CaCertDir", lTLS_CaCertDir }, ++ { "TLS_Ciphers", lTLS_Ciphers }, ++ { "TLS_Cipher_Suite", lTLS_Ciphers }, ++ { "TLS_Cert", lTLS_Cert }, ++ { "TLS_Certificate", lTLS_Cert }, ++ { "TLS_Key", lTLS_Key }, ++ { "TLS_RandFile", lTLS_RandFile }, ++/* ++ * Todo ++ * TLS_CRLCHECK ++ * TLS_CRLFILE ++ */ ++ { "LogDir", lLogDir }, ++ { "Debug", lDebug }, ++ { "SSH_Filter", lSSH_Filter }, ++ { "AccountClass", lAccountClass }, ++ { NULL, lBadOption } ++}; ++ ++/* Configuration ptions. */ ++ ++Options 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. ++ * Returns the number of the token pointed to by cp or oBadOption. + */ + -+void -+initialize_options(void) ++static OpCodes ++parse_token(const char *cp, const char *filename, int linenum) +{ -+ 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; -+ options.account_class = NULL; ++ 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; +} + +/* -+ * Called after processing other sources of option data, this fills those -+ * options for which no value has been specified with their default values. ++ * 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" + -+void -+fill_default_options(void) ++static int ++process_config_line(char *line, const char *filename, int linenum) +{ -+ if (options.uri != NULL) { -+ LDAPURLDesc *ludp; ++ char *s, **charptr, **xstringptr, *endofnumber, *keyword, *arg; ++ char *rootbinddn = NULL; ++ int opcode, *intptr, value; ++ size_t len; + -+ if (ldap_url_parse(options.uri, &ludp) == LDAP_SUCCESS) { -+ if (options.ssl == -1) { -+ if (strcmp (ludp->lud_scheme, "ldap") == 0) -+ options.ssl = 2; -+ if (strcmp (ludp->lud_scheme, "ldapi") == 0) -+ options.ssl = 0; -+ else if (strcmp (ludp->lud_scheme, "ldaps") == 0) -+ options.ssl = 1; -+ } -+ if (options.host == NULL) -+ options.host = xstrdup (ludp->lud_host); -+ if (options.port == -1) -+ options.port = ludp->lud_port; ++ /* Strip trailing whitespace */ ++ for (len = strlen(line) - 1; len > 0; len--) { ++ if (strchr(WHITESPACE, line[len]) == NULL) ++ break; ++ line[len] = '\0'; ++ } + -+ 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 ++ 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; + -+ 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 = xreallocarray (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 = ""; -+ if (options.account_class == NULL) -+ options.account_class = "posixAccount"; -+} ++ opcode = parse_token(keyword, filename, linenum); + -+static const char * -+lookup_opcode_name(OpCodes code) -+{ -+ u_int i; ++ switch (opcode) { ++ case lBadOption: ++ /* don't panic, but count bad options */ ++ return -1; ++ /* NOTREACHED */ + -+ for (i = 0; keywords[i].name != NULL; i++) -+ if (keywords[i].opcode == code) -+ return(keywords[i].name); -+ return "UNKNOWN"; -+} ++ 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; + -+static void -+dump_cfg_string(OpCodes code, const char *val) -+{ -+ if (val == NULL) -+ debug3("%s ", lookup_opcode_name(code)); -+ else -+ debug3("%s %s", lookup_opcode_name(code), val); -+} ++ case lURI: ++ xstringptr = &options.uri; ++ goto parse_xstring; + -+static void -+dump_cfg_int(OpCodes code, int val) -+{ -+ if (val == -1) -+ debug3("%s ", lookup_opcode_name(code)); -+ else -+ debug3("%s %d", lookup_opcode_name(code), val); -+} ++ case lBase: ++ xstringptr = &options.base; ++ goto parse_xstring; + -+struct names { -+ int value; -+ char *name; -+}; ++ case lBindDN: ++ xstringptr = &options.binddn; ++ goto parse_xstring; + -+static void -+dump_cfg_namedint(OpCodes code, int val, struct names *names) -+{ -+ u_int i; ++ 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") == 0 || strcasecmp (arg, "subtree") == 0) ++ value = LDAP_SCOPE_SUBTREE; ++ else if (strcasecmp (arg, "one") == 0) ++ value = LDAP_SCOPE_ONELEVEL; ++ else if (strcasecmp (arg, "base") == 0) ++ 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; + -+ if (val == -1) -+ debug3("%s ", 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); -+ } -+} ++ 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); + -+static struct names _yesnotls[] = { -+ { 0, "No" }, -+ { 1, "Yes" }, -+ { 2, "Start_TLS" }, -+ { -1, NULL }}; ++ /* 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; + -+static struct names _scope[] = { -+ { LDAP_SCOPE_BASE, "Base" }, -+ { LDAP_SCOPE_ONELEVEL, "One" }, -+ { LDAP_SCOPE_SUBTREE, "Sub"}, -+ { -1, NULL }}; ++ 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; + -+static struct names _deref[] = { -+ { LDAP_DEREF_NEVER, "Never" }, -+ { LDAP_DEREF_SEARCHING, "Searching" }, -+ { LDAP_DEREF_FINDING, "Finding" }, -+ { LDAP_DEREF_ALWAYS, "Always" }, -+ { -1, NULL }}; ++ case lBind_TimeLimit: ++ intptr = &options.bind_timelimit; ++ goto parse_time; + -+static struct names _yesno[] = { -+ { 0, "No" }, -+ { 1, "Yes" }, -+ { -1, NULL }}; ++ case lLdap_Version: ++ intptr = &options.ldap_version; ++ goto parse_int; + -+static struct names _bindpolicy[] = { -+ { 0, "Soft" }, -+ { 1, "Hard" }, -+ { -1, NULL }}; ++ 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 || strcasecmp(arg, "hard_open") == 0 || strcasecmp(arg, "hard_init") == 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; + -+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 }}; ++ case lSSLPath: ++ charptr = &options.sslpath; ++ goto parse_string; + -+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); -+ dump_cfg_string(lAccountClass, options.logdir); -+} ++ 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; + -diff -up openssh-6.2p2/ldapconf.h.ldap openssh-6.2p2/ldapconf.h ---- openssh-6.2p2/ldapconf.h.ldap 2013-06-07 15:10:05.602942689 +0200 -+++ openssh-6.2p2/ldapconf.h 2013-06-07 15:10:24.928857566 +0200 -@@ -0,0 +1,72 @@ -+/* $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. -+ */ ++ 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; + -+#ifndef LDAPCONF_H -+#define LDAPCONF_H ++ case lRestart: ++ intptr = &options.restart; ++ goto parse_flag; + -+#define SSL_OFF 0 -+#define SSL_LDAPS 1 -+#define SSL_START_TLS 2 ++ 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 || strcasecmp(arg, "no") == 0 || strcasecmp(arg, "false") == 0 || strcasecmp(arg, "off") == 0) ++ value = LDAP_OPT_X_TLS_NEVER; ++ else if (strcasecmp(arg, "hard") == 0 || strcasecmp(arg, "yes") == 0 || strcasecmp(arg, "true") == 0 || strcasecmp(arg, "on") == 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; + -+/* Data structure for representing option data. */ ++ case lTLS_CaCertFile: ++ charptr = &options.tls_cacertfile; ++ goto parse_string; + -+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; -+ char *account_class; -+} Options; ++ case lTLS_CaCertDir: ++ charptr = &options.tls_cacertdir; ++ goto parse_string; + -+extern Options options; ++ case lTLS_Ciphers: ++ xstringptr = &options.tls_ciphers; ++ goto parse_xstring; + -+void read_config_file(const char *); -+void initialize_options(void); -+void fill_default_options(void); -+void dump_config(void); ++ case lTLS_Cert: ++ charptr = &options.tls_cert; ++ goto parse_string; + -+#endif /* LDAPCONF_H */ -diff -up openssh-6.2p1/ldap.conf.ldap openssh-6.2p1/ldap.conf ---- openssh-6.2p1/ldap.conf.ldap 2013-03-25 21:27:15.891248091 +0100 -+++ openssh-6.2p1/ldap.conf 2013-03-25 21:27:15.891248091 +0100 -@@ -0,0 +1,88 @@ -+# $Id: openssh-5.5p1-ldap.patch,v 1.3 2010/07/07 13:48:36 jfch2222 Exp $ -+# -+# This is the example configuration file for the OpenSSH -+# LDAP backend -+# -+# see ssh-ldap.conf(5) -+# ++ case lTLS_Key: ++ charptr = &options.tls_key; ++ goto parse_string; + -+# URI with your LDAP server name. This allows to use -+# Unix Domain Sockets to connect to a local LDAP Server. -+#uri ldap://127.0.0.1/ -+#uri ldaps://127.0.0.1/ -+#uri ldapi://%2fvar%2frun%2fldapi_sock/ -+# Note: %2f encodes the '/' used as directory separator ++ case lTLS_RandFile: ++ charptr = &options.tls_randfile; ++ goto parse_string; + -+# Another way to specify your LDAP server is to provide an -+# host name and the port of our LDAP server. Host name -+# must be resolvable without using LDAP. -+# Multiple hosts may be specified, each separated by a -+# space. How long nss_ldap takes to failover depends on -+# whether your LDAP client library supports configurable -+# network or connect timeouts (see bind_timelimit). -+#host 127.0.0.1 ++ case lLogDir: ++ charptr = &options.logdir; ++ goto parse_string; + -+# The port. -+# Optional: default is 389. -+#port 389 ++ case lDebug: ++ intptr = &options.debug; ++ goto parse_int; + -+# The distinguished name to bind to the server with. -+# Optional: default is to bind anonymously. -+#binddn cn=openssh_keys,dc=example,dc=org ++ case lSSH_Filter: ++ xstringptr = &options.ssh_filter; ++ goto parse_xstring; + -+# The credentials to bind with. -+# Optional: default is no credential. -+#bindpw TopSecret ++ case lAccountClass: ++ charptr = &options.account_class; ++ goto parse_string; + -+# The distinguished name of the search base. -+#base dc=example,dc=org ++ case lDeprecated: ++ debug("%s line %d: Deprecated option \"%s\"", ++ filename, linenum, keyword); ++ return 0; + -+# The LDAP version to use (defaults to 3 -+# if supported by client library) -+#ldap_version 3 ++ case lUnsupported: ++ error("%s line %d: Unsupported option \"%s\"", ++ filename, linenum, keyword); ++ return 0; + -+# The search scope. -+#scope sub -+#scope one -+#scope base ++ default: ++ fatal("process_config_line: Unimplemented opcode %d", opcode); ++ } + -+# Search timelimit -+#timelimit 30 ++ /* 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; ++} + -+# Bind/connect timelimit -+#bind_timelimit 30 ++/* ++ * 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. ++ */ + -+# Reconnect policy: hard (default) will retry connecting to -+# the software with exponential backoff, soft will fail -+# immediately. -+#bind_policy hard ++void ++read_config_file(const char *filename) ++{ ++ FILE *f; ++ char line[1024]; ++ int active, linenum; ++ int bad_options = 0; ++ struct stat sb; + -+# SSL setup, may be implied by URI also. -+#ssl no -+#ssl on -+#ssl start_tls ++ if ((f = fopen(filename, "r")) == NULL) ++ fatal("fopen %s: %s", filename, strerror(errno)); + -+# OpenLDAP SSL options -+# Require and verify server certificate (yes/no) -+# Default is to use libldap's default behavior, which can be configured in -+# /etc/openldap/ldap.conf using the TLS_REQCERT setting. The default for -+# OpenLDAP 2.0 and earlier is "no", for 2.1 and later is "yes". -+#tls_checkpeer hard ++ 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); + -+# CA certificates for server certificate verification -+# At least one of these are required if tls_checkpeer is "yes" -+#tls_cacertfile /etc/ssl/ca.cert -+#tls_cacertdir /etc/pki/tls/certs ++ debug("Reading configuration data %.200s", filename); + -+# Seed the PRNG if /dev/urandom is not provided -+#tls_randfile /var/run/egd-pool ++ /* ++ * 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); ++} + -+# SSL cipher suite -+# See man ciphers for syntax -+#tls_ciphers TLSv1 ++/* ++ * 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. ++ */ + -+# Client certificate and key -+# Use these, if your server requires client authentication. -+#tls_cert -+#tls_key ++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; ++ options.account_class = NULL; ++} + -diff -up openssh-6.2p1/ldap-helper.c.ldap openssh-6.2p1/ldap-helper.c ---- openssh-6.2p1/ldap-helper.c.ldap 2013-03-25 21:27:15.892248097 +0100 -+++ openssh-6.2p1/ldap-helper.c 2013-03-25 21:27:15.892248097 +0100 -@@ -0,0 +1,155 @@ -+/* $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. ++ * Called after processing other sources of option data, this fills those ++ * options for which no value has been specified with their default values. + */ + -+#include "ldapincludes.h" -+#include "log.h" -+#include "misc.h" -+#include "xmalloc.h" -+#include "ldapconf.h" -+#include "ldapbody.h" -+#include -+#include ++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") == 0) ++ options.ssl = 2; ++ if (strcmp (ludp->lud_scheme, "ldapi") == 0) ++ options.ssl = 0; ++ else if (strcmp (ludp->lud_scheme, "ldaps") == 0) ++ options.ssl = 1; ++ } ++ 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 = xreallocarray (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 = ""; ++ if (options.account_class == NULL) ++ options.account_class = "posixAccount"; ++} ++ ++static const char * ++lookup_opcode_name(OpCodes code) ++{ ++ u_int i; + -+static int config_debug = 0; -+int config_exclusive_config_file = 0; -+static char *config_file_name = "/etc/ssh/ldap.conf"; -+static char *config_single_user = NULL; -+static int config_verbose = SYSLOG_LEVEL_VERBOSE; -+int config_warning_config_file = 0; -+extern char *__progname; ++ for (i = 0; keywords[i].name != NULL; i++) ++ if (keywords[i].opcode == code) ++ return(keywords[i].name); ++ return "UNKNOWN"; ++} + +static void -+usage(void) ++dump_cfg_string(OpCodes code, const char *val) +{ -+ 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/ssh/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 in the config file.\n"); -+ exit(1); ++ if (val == NULL) ++ debug3("%s ", lookup_opcode_name(code)); ++ else ++ debug3("%s %s", lookup_opcode_name(code), val); +} + -+/* -+ * Main program for the ssh pka ldap agent. -+ */ -+ -+int -+main(int ac, char **av) ++static void ++dump_cfg_int(OpCodes code, int val) +{ -+ 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; ++ if (val == -1) ++ debug3("%s ", lookup_opcode_name(code)); ++ else ++ debug3("%s %d", lookup_opcode_name(code), val); ++} + -+ case 'v': -+ config_debug = 1; -+ if (config_verbose < SYSLOG_LEVEL_DEBUG3) -+ config_verbose++; -+ break; ++struct names { ++ int value; ++ char *name; ++}; + -+ case 'w': -+ config_warning_config_file = 1; -+ break; ++static void ++dump_cfg_namedint(OpCodes code, int val, struct names *names) ++{ ++ u_int i; + -+ case '?': -+ default: -+ usage(); -+ break; ++ if (val == -1) ++ debug3("%s ", 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); + } ++} + -+ /* Initialize loging */ -+ log_init(__progname, config_verbose, SYSLOG_FACILITY_AUTH, config_debug); ++static struct names _yesnotls[] = { ++ { 0, "No" }, ++ { 1, "Yes" }, ++ { 2, "Start_TLS" }, ++ { -1, NULL }}; + -+ if (ac != optind) -+ fatal ("illegal extra parameter %s", av[1]); ++static struct names _scope[] = { ++ { LDAP_SCOPE_BASE, "Base" }, ++ { LDAP_SCOPE_ONELEVEL, "One" }, ++ { LDAP_SCOPE_SUBTREE, "Sub"}, ++ { -1, NULL }}; + -+ /* Ensure that fds 0 and 2 are open or directed to /dev/null */ -+ if (config_debug == 0) -+ sanitise_stdfd(); ++static struct names _deref[] = { ++ { LDAP_DEREF_NEVER, "Never" }, ++ { LDAP_DEREF_SEARCHING, "Searching" }, ++ { LDAP_DEREF_FINDING, "Finding" }, ++ { LDAP_DEREF_ALWAYS, "Always" }, ++ { -1, NULL }}; + -+ /* Read config file */ -+ read_config_file(config_file_name); -+ fill_default_options(); -+ if (config_verbose == SYSLOG_LEVEL_DEBUG3) { -+ debug3 ("=== Configuration ==="); -+ dump_config(); -+ debug3 ("=== *** ==="); -+ } ++static struct names _yesno[] = { ++ { 0, "No" }, ++ { 1, "Yes" }, ++ { -1, NULL }}; + -+ ldap_checkconfig(); -+ ldap_do_connect(); ++static struct names _bindpolicy[] = { ++ { 0, "Soft" }, ++ { 1, "Hard" }, ++ { -1, NULL }}; + -+ if (config_single_user) { -+ process_user (config_single_user, outfile); -+ } else { -+ usage(); -+ fatal ("Not yet implemented"); -+/* TODO -+ * open unix socket a run the loop on it -+ */ -+ } ++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 }}; + -+ ldap_do_close(); -+ return 0; ++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); ++ dump_cfg_string(lAccountClass, options.logdir); +} + -+/* Ugly hack */ -+void *buffer_get_string(Buffer *b, u_int *l) { return NULL; } -+void buffer_put_string(Buffer *b, const void *f, u_int l) {} -+ -diff -up openssh-6.2p1/ldap-helper.h.ldap openssh-6.2p1/ldap-helper.h ---- openssh-6.2p1/ldap-helper.h.ldap 2013-03-25 21:27:15.892248097 +0100 -+++ openssh-6.2p1/ldap-helper.h 2013-03-25 21:27:15.892248097 +0100 -@@ -0,0 +1,32 @@ -+/* $OpenBSD: ldap-helper.h,v 1.1 2009/12/03 03:34:42 jfch Exp $ */ +diff -urNp -x '*.orig' openssh-8.4p1.org/ldapconf.h openssh-8.4p1/ldapconf.h +--- openssh-8.4p1.org/ldapconf.h 1970-01-01 01:00:00.000000000 +0100 ++++ openssh-8.4p1/ldapconf.h 2021-03-01 11:29:31.280956671 +0100 +@@ -0,0 +1,72 @@ ++/* $OpenBSD: ldapconf.c,v 1.1 2009/12/03 03:34:42 jfch Exp $ */ +/* + * Copyright (c) 2009 Jan F. Chadima. All rights reserved. + * @@ -1810,16 +1869,56 @@ diff -up openssh-6.2p1/ldap-helper.h.ldap openssh-6.2p1/ldap-helper.h + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + -+#ifndef LDAP_HELPER_H -+#define LDAP_HELPER_H ++#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; ++ char *account_class; ++} Options; ++ ++extern Options options; + -+extern int config_exclusive_config_file; -+extern int config_warning_config_file; ++void read_config_file(const char *); ++void initialize_options(void); ++void fill_default_options(void); ++void dump_config(void); + -+#endif /* LDAP_HELPER_H */ -diff -up openssh-6.2p1/ldapincludes.h.ldap openssh-6.2p1/ldapincludes.h ---- openssh-6.2p1/ldapincludes.h.ldap 2013-03-25 21:27:15.892248097 +0100 -+++ openssh-6.2p1/ldapincludes.h 2013-03-25 21:27:15.892248097 +0100 ++#endif /* LDAPCONF_H */ +diff -urNp -x '*.orig' openssh-8.4p1.org/ldapincludes.h openssh-8.4p1/ldapincludes.h +--- openssh-8.4p1.org/ldapincludes.h 1970-01-01 01:00:00.000000000 +0100 ++++ openssh-8.4p1/ldapincludes.h 2021-03-01 11:29:31.280956671 +0100 @@ -0,0 +1,41 @@ +/* $OpenBSD: ldapconf.c,v 1.1 2009/12/03 03:34:42 jfch Exp $ */ +/* @@ -1862,9 +1961,9 @@ diff -up openssh-6.2p1/ldapincludes.h.ldap openssh-6.2p1/ldapincludes.h +#endif + +#endif /* LDAPINCLUDES_H */ -diff -up openssh-6.2p1/ldapmisc.c.ldap openssh-6.2p1/ldapmisc.c ---- openssh-6.2p1/ldapmisc.c.ldap 2013-03-25 21:27:15.893248104 +0100 -+++ openssh-6.2p1/ldapmisc.c 2013-03-25 21:27:15.893248104 +0100 +diff -urNp -x '*.orig' openssh-8.4p1.org/ldapmisc.c openssh-8.4p1/ldapmisc.c +--- openssh-8.4p1.org/ldapmisc.c 1970-01-01 01:00:00.000000000 +0100 ++++ openssh-8.4p1/ldapmisc.c 2021-03-01 11:29:31.280956671 +0100 @@ -0,0 +1,79 @@ + +#include "ldapincludes.h" @@ -1945,9 +2044,9 @@ diff -up openssh-6.2p1/ldapmisc.c.ldap openssh-6.2p1/ldapmisc.c +} +#endif + -diff -up openssh-6.2p1/ldapmisc.h.ldap openssh-6.2p1/ldapmisc.h ---- openssh-6.2p1/ldapmisc.h.ldap 2013-03-25 21:27:15.893248104 +0100 -+++ openssh-6.2p1/ldapmisc.h 2013-03-25 21:27:15.893248104 +0100 +diff -urNp -x '*.orig' openssh-8.4p1.org/ldapmisc.h openssh-8.4p1/ldapmisc.h +--- openssh-8.4p1.org/ldapmisc.h 1970-01-01 01:00:00.000000000 +0100 ++++ openssh-8.4p1/ldapmisc.h 2021-03-01 11:29:31.280956671 +0100 @@ -0,0 +1,35 @@ +/* $OpenBSD: ldapbody.h,v 1.1 2009/12/03 03:34:42 jfch Exp $ */ +/* @@ -1984,105 +2083,9 @@ diff -up openssh-6.2p1/ldapmisc.h.ldap openssh-6.2p1/ldapmisc.h + +#endif /* LDAPMISC_H */ + ---- openssh-7.2p1/Makefile.in.orig 2016-02-26 04:40:04.000000000 +0100 -+++ openssh-7.2p1/Makefile.in 2016-03-04 19:44:30.903306337 +0100 -@@ -25,6 +25,8 @@ - ASKPASS_PROGRAM=$(libexecdir)/ssh-askpass - SFTP_SERVER=$(libexecdir)/sftp-server - SSH_KEYSIGN=$(libexecdir)/ssh-keysign -+SSH_LDAP_HELPER=$(libexecdir)/ssh-ldap-helper -+SSH_LDAP_WRAPPER=$(libexecdir)/ssh-ldap-wrapper - SSH_PKCS11_HELPER=$(libexecdir)/ssh-pkcs11-helper - PRIVSEP_PATH=@PRIVSEP_PATH@ - SSH_PRIVSEP_USER=@SSH_PRIVSEP_USER@ -@@ -61,8 +63,9 @@ - EXEEXT=@EXEEXT@ - MANFMT=@MANFMT@ - MKDIR_P=@MKDIR_P@ -+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) 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) sftp-server$(EXEEXT) sftp$(EXEEXT) ssh-ldap-helper$(EXEEXT) - - LIBOPENSSH_OBJS=\ - ssh_api.o \ -@@ -112,8 +115,8 @@ - sandbox-seccomp-filter.o sandbox-capsicum.o sandbox-pledge.o \ - sandbox-solaris.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-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-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-keysign.8.out ssh-pkcs11-helper.8.out ssh-ldap-helper.8.out sshd_config.5.out ssh_config.5.out ssh-ldap.conf.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-keysign.8 ssh-pkcs11-helper.8 ssh-ldap-helper.8 sshd_config.5 ssh_config.5 ssh-ldap.conf.5 - MANTYPE = @MANTYPE@ - - CONFIGFILES=sshd_config.out ssh_config.out moduli.out -@@ -184,6 +187,9 @@ - ssh-pkcs11-helper$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-pkcs11-helper.o ssh-pkcs11.o - $(LD) -o $@ ssh-pkcs11-helper.o ssh-pkcs11.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh -lopenbsd-compat $(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) -+ - ssh-keyscan$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keyscan.o - $(LD) -o $@ ssh-keyscan.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh $(LIBS) - -@@ -311,6 +317,10 @@ - $(INSTALL) -m 0755 $(STRIP_OPT) sshd$(EXEEXT) $(DESTDIR)$(sbindir)/sshd$(EXEEXT) - $(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) ; \ -+ $(INSTALL) -m 0700 ssh-ldap-wrapper $(DESTDIR)$(SSH_LDAP_WRAPPER) ; \ -+ 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 -@@ -327,6 +337,10 @@ - $(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 ; \ -+ $(INSTALL) -m 644 ssh-ldap.conf.5.out $(DESTDIR)$(mandir)/$(mansubdir)5/ssh-ldap.conf.5 ; \ -+ fi - - install-sysconf: - if [ ! -d $(DESTDIR)$(sysconfdir) ]; then \ -@@ -352,6 +366,13 @@ - else \ - echo "$(DESTDIR)$(sysconfdir)/moduli already exists, install will not overwrite"; \ - fi -+ if test ! -z "$(INSTALL_SSH_LDAP_HELPER)" ; then \ -+ if [ ! -f $(DESTDIR)$(sysconfdir)/ldap.conf ]; then \ -+ $(INSTALL) -m 644 ldap.conf $(DESTDIR)$(sysconfdir)/ldap.conf; \ -+ else \ -+ echo "$(DESTDIR)$(sysconfdir)/ldap.conf already exists, install will not overwrite"; \ -+ fi ; \ -+ fi - - host-key: ssh-keygen$(EXEEXT) - @if [ -z "$(DESTDIR)" ] ; then \ -@@ -392,6 +413,8 @@ - -rm -r $(DESTDIR)$(SFTP_SERVER)$(EXEEXT) - -rm -f $(DESTDIR)$(SSH_KEYSIGN)$(EXEEXT) - -rm -f $(DESTDIR)$(SSH_PKCS11_HELPER)$(EXEEXT) -+ -rm -f $(DESTDIR)$(SSH_LDAP_HELPER)$(EXEEXT) -+ -rm -f $(DESTDIR)$(SSH_LDAP_WRAPPER)$(EXEEXT) - -rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/ssh.1 - -rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/scp.1 - -rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/ssh-add.1 -@@ -403,6 +426,7 @@ - -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 - - regress-prep: - [ -d `pwd`/regress ] || mkdir -p `pwd`/regress -diff -up openssh-6.2p1/openssh-lpk-openldap.schema.ldap openssh-6.2p1/openssh-lpk-openldap.schema ---- openssh-6.2p1/openssh-lpk-openldap.schema.ldap 2013-03-25 21:27:15.894248110 +0100 -+++ openssh-6.2p1/openssh-lpk-openldap.schema 2013-03-25 21:27:15.894248110 +0100 +diff -urNp -x '*.orig' openssh-8.4p1.org/openssh-lpk-openldap.schema openssh-8.4p1/openssh-lpk-openldap.schema +--- openssh-8.4p1.org/openssh-lpk-openldap.schema 1970-01-01 01:00:00.000000000 +0100 ++++ openssh-8.4p1/openssh-lpk-openldap.schema 2021-03-01 11:29:31.280956671 +0100 @@ -0,0 +1,21 @@ +# +# LDAP Public Key Patch schema for use with openssh-ldappubkey @@ -2105,9 +2108,9 @@ diff -up openssh-6.2p1/openssh-lpk-openldap.schema.ldap openssh-6.2p1/openssh-lp + DESC 'MANDATORY: OpenSSH LPK objectclass' + MUST ( sshPublicKey $ uid ) + ) -diff -up openssh-6.2p1/openssh-lpk-sun.schema.ldap openssh-6.2p1/openssh-lpk-sun.schema ---- openssh-6.2p1/openssh-lpk-sun.schema.ldap 2013-03-25 21:27:15.894248110 +0100 -+++ openssh-6.2p1/openssh-lpk-sun.schema 2013-03-25 21:27:15.894248110 +0100 +diff -urNp -x '*.orig' openssh-8.4p1.org/openssh-lpk-sun.schema openssh-8.4p1/openssh-lpk-sun.schema +--- openssh-8.4p1.org/openssh-lpk-sun.schema 1970-01-01 01:00:00.000000000 +0100 ++++ openssh-8.4p1/openssh-lpk-sun.schema 2021-03-01 11:29:31.284290176 +0100 @@ -0,0 +1,23 @@ +# +# LDAP Public Key Patch schema for use with openssh-ldappubkey @@ -2132,9 +2135,100 @@ diff -up openssh-6.2p1/openssh-lpk-sun.schema.ldap openssh-6.2p1/openssh-lpk-sun + DESC 'MANDATORY: OpenSSH LPK objectclass' + MUST ( sshPublicKey $ uid ) + ) -diff -up openssh-6.2p2/ssh-ldap.conf.5.ldap openssh-6.2p2/ssh-ldap.conf.5 ---- openssh-6.2p2/ssh-ldap.conf.5.ldap 2013-06-07 15:10:05.604942680 +0200 -+++ openssh-6.2p2/ssh-ldap.conf.5 2013-06-07 15:10:24.928857566 +0200 +diff -urNp -x '*.orig' openssh-8.4p1.org/ssh-ldap-helper.8 openssh-8.4p1/ssh-ldap-helper.8 +--- openssh-8.4p1.org/ssh-ldap-helper.8 1970-01-01 01:00:00.000000000 +0100 ++++ openssh-8.4p1/ssh-ldap-helper.8 2021-03-01 11:29:31.284290176 +0100 +@@ -0,0 +1,79 @@ ++.\" $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 an LDAP. ++.Nm ++is disabled by default and can only be enabled in the ++sshd configuration file ++.Pa /etc/ssh/sshd_config ++by setting ++.Cm AuthorizedKeysCommand ++to ++.Dq /usr/libexec/ssh-ldap-wrapper . ++.Pp ++.Nm ++is not intended to be invoked by the user, but from ++.Xr sshd 8 via ++.Xr ssh-ldap-wrapper . ++.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 ++halts if it encounters an unknown item in the ldap.conf file. ++.It Fl f ++.Nm ++uses this file as the ldap configuration file instead of /etc/ssh/ldap.conf (default). ++.It Fl s ++.Nm ++prints out the user's keys to stdout and exits. ++.It Fl v ++Implies \-d; ++increases verbosity. ++.It Fl w ++.Nm ++writes warnings about unknown items in the ldap.conf configuration file. ++.El ++.Sh SEE ALSO ++.Xr sshd 8 , ++.Xr sshd_config 5 , ++.Xr ssh-ldap.conf 5 , ++.Sh HISTORY ++.Nm ++first appeared in ++OpenSSH 5.5 + PKA-LDAP . ++.Sh AUTHORS ++.An Jan F. Chadima Aq jchadima@redhat.com +diff -urNp -x '*.orig' openssh-8.4p1.org/ssh-ldap-wrapper openssh-8.4p1/ssh-ldap-wrapper +--- openssh-8.4p1.org/ssh-ldap-wrapper 1970-01-01 01:00:00.000000000 +0100 ++++ openssh-8.4p1/ssh-ldap-wrapper 2021-03-01 11:29:31.284290176 +0100 +@@ -0,0 +1,4 @@ ++#!/bin/sh ++ ++exec /usr/libexec/openssh/ssh-ldap-helper -s "$1" ++ +diff -urNp -x '*.orig' openssh-8.4p1.org/ssh-ldap.conf.5 openssh-8.4p1/ssh-ldap.conf.5 +--- openssh-8.4p1.org/ssh-ldap.conf.5 1970-01-01 01:00:00.000000000 +0100 ++++ openssh-8.4p1/ssh-ldap.conf.5 2021-03-01 11:29:31.284290176 +0100 @@ -0,0 +1,379 @@ +.\" $OpenBSD: ssh-ldap.conf.5,v 1.1 2010/02/10 23:20:38 markus Exp $ +.\" @@ -2515,94 +2609,3 @@ diff -up openssh-6.2p2/ssh-ldap.conf.5.ldap openssh-6.2p2/ssh-ldap.conf.5 +OpenSSH 5.5 + PKA-LDAP . +.Sh AUTHORS +.An Jan F. Chadima Aq jchadima@redhat.com -diff -up openssh-6.2p1/ssh-ldap-helper.8.ldap openssh-6.2p1/ssh-ldap-helper.8 ---- openssh-6.2p1/ssh-ldap-helper.8.ldap 2013-03-25 21:27:15.895248117 +0100 -+++ openssh-6.2p1/ssh-ldap-helper.8 2013-03-25 21:27:15.895248117 +0100 -@@ -0,0 +1,79 @@ -+.\" $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 an LDAP. -+.Nm -+is disabled by default and can only be enabled in the -+sshd configuration file -+.Pa /etc/ssh/sshd_config -+by setting -+.Cm AuthorizedKeysCommand -+to -+.Dq /usr/libexec/ssh-ldap-wrapper . -+.Pp -+.Nm -+is not intended to be invoked by the user, but from -+.Xr sshd 8 via -+.Xr ssh-ldap-wrapper . -+.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 -+halts if it encounters an unknown item in the ldap.conf file. -+.It Fl f -+.Nm -+uses this file as the ldap configuration file instead of /etc/ssh/ldap.conf (default). -+.It Fl s -+.Nm -+prints out the user's keys to stdout and exits. -+.It Fl v -+Implies \-d; -+increases verbosity. -+.It Fl w -+.Nm -+writes warnings about unknown items in the ldap.conf configuration file. -+.El -+.Sh SEE ALSO -+.Xr sshd 8 , -+.Xr sshd_config 5 , -+.Xr ssh-ldap.conf 5 , -+.Sh HISTORY -+.Nm -+first appeared in -+OpenSSH 5.5 + PKA-LDAP . -+.Sh AUTHORS -+.An Jan F. Chadima Aq jchadima@redhat.com -diff -up openssh-6.2p1/ssh-ldap-wrapper.ldap openssh-6.2p1/ssh-ldap-wrapper ---- openssh-6.2p1/ssh-ldap-wrapper.ldap 2013-03-25 21:27:15.896248124 +0100 -+++ openssh-6.2p1/ssh-ldap-wrapper 2013-03-25 21:27:15.896248124 +0100 -@@ -0,0 +1,4 @@ -+#!/bin/sh -+ -+exec /usr/libexec/openssh/ssh-ldap-helper -s "$1" -+