[packages/openssh] updated rebased ldap patch from fedora (adds AccountClass ldap.conf param)

glen glen at pld-linux.org
Sat Nov 2 16:15:09 CET 2013


commit 3eddefd2d1953889fd8b629a3fba9d7b0d7c7890
Author: Elan Ruusamäe <glen at delfi.ee>
Date:   Sat Nov 2 17:09:00 2013 +0200

    updated rebased ldap patch from fedora (adds AccountClass ldap.conf param)

 openssh-ldap.patch | 3343 ++++++++++++++++++++++++++--------------------------
 1 file changed, 1678 insertions(+), 1665 deletions(-)
---
diff --git a/openssh-ldap.patch b/openssh-ldap.patch
index 0961124..994ef59 100644
--- a/openssh-ldap.patch
+++ b/openssh-ldap.patch
@@ -1,6 +1,116 @@
-diff -up openssh-5.9p0/HOWTO.ldap-keys.ldap openssh-5.9p0/HOWTO.ldap-keys
---- openssh-5.9p0/HOWTO.ldap-keys.ldap	2011-08-30 15:57:12.449212853 +0200
-+++ openssh-5.9p0/HOWTO.ldap-keys	2011-08-30 15:57:12.453101662 +0200
+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 <ldap.h>))
++			AC_CHECK_HEADERS(ldap_ssl.h)
++
++			AC_ARG_WITH(ldap-lib,
++				[  --with-ldap-lib=type    select ldap library [auto|netscape5|netscape4|netscape3|umich|openldap]])
++
++			if test -z "$with_ldap_lib"; then
++				with_ldap_lib=auto
++			fi
++
++			if test -z "$found_ldap_lib" -a \( $with_ldap_lib = auto -o $with_ldap_lib = umich -o $with_ldap_lib = openldap \); then
++				AC_CHECK_LIB(lber, main, LIBS="-llber $LIBS" found_ldap_lib=yes)
++				AC_CHECK_LIB(ldap, main, LIBS="-lldap $LIBS" found_ldap_lib=yes)
++			fi
++
++			if test -z "$found_ldap_lib" -a \( $with_ldap_lib = auto -o $with_ldap_lib = netscape5 \); then
++				AC_CHECK_LIB(ldap50, main, LIBS="-lldap50 -lssldap50 -lssl3 -lnss3 -lnspr4 -lprldap50 -lplc4 -lplds4 $LIBS" found_ldap_lib=yes)
++			fi
++
++			if test -z "$found_ldap_lib" -a \( $with_ldap_lib = auto -o $with_ldap_lib = netscape4 \); then
++				AC_CHECK_LIB(ldapssl41, main, LIBS="-lldapssl41 -lplc3 -lplds3 -lnspr3 $LIBS" found_ldap_lib=yes)
++				if test -z "$found_ldap_lib"; then
++					AC_CHECK_LIB(ldapssl40, main, LIBS="-lldapssl40 $LIBS" found_ldap_lib=yes)
++				fi
++				if test -z "$found_ldap_lib"; then
++					AC_CHECK_LIB(ldap41, main, LIBS="-lldap41 $LIBS" found_ldap_lib=yes)
++				fi
++				if test -z "$found_ldap_lib"; then
++					AC_CHECK_LIB(ldap40, main, LIBS="-lldap40 $LIBS" found_ldap_lib=yes)
++				fi
++			fi
++
++			if test -z "$found_ldap_lib" -a \( $with_ldap_lib = auto -o $with_ldap_lib = netscape3 \); then
++				AC_CHECK_LIB(ldapssl30, main, LIBS="-lldapssl30 $LIBS" found_ldap_lib=yes)
++			fi
++
++			if test -z "$found_ldap_lib"; then
++				AC_MSG_ERROR(could not locate a valid LDAP library)
++			fi
++
++			AC_MSG_CHECKING([for working LDAP support])
++			AC_TRY_COMPILE(
++				[#include <sys/types.h>
++				 #include <ldap.h>],
++				[(void)ldap_init(0, 0);],
++				[AC_MSG_RESULT(yes)],
++				[
++				    AC_MSG_RESULT(no) 
++					AC_MSG_ERROR([** Incomplete or missing ldap libraries **])
++				])
++			AC_CHECK_FUNCS( \
++				ldap_init \
++				ldap_get_lderrno \
++				ldap_set_lderrno \
++				ldap_parse_result \
++				ldap_memfree \
++				ldap_controls_free \
++				ldap_set_option \
++				ldap_get_option \
++				ldapssl_init \
++				ldap_start_tls_s \
++				ldap_pvt_tls_set_option \
++				ldap_initialize \
++			)
++			AC_CHECK_FUNCS(ldap_set_rebind_proc,
++				AC_MSG_CHECKING([number arguments of ldap_set_rebind_proc])
++				AC_TRY_COMPILE(
++					[#include <lber.h>
++					#include <ldap.h>],
++					[ldap_set_rebind_proc(0, 0, 0);],
++					[ac_cv_ldap_set_rebind_proc=3],
++					[ac_cv_ldap_set_rebind_proc=2])
++				AC_MSG_RESULT($ac_cv_ldap_set_rebind_proc)
++				AC_DEFINE(LDAP_SET_REBIND_PROC_ARGS, $ac_cv_ldap_set_rebind_proc, [number arguments of ldap_set_rebind_proc])
++			)
++		fi
++	]
++)
++AC_SUBST(INSTALL_SSH_LDAP_HELPER)
++
+ dnl    Checks for library functions. Please keep in alphabetical order
+ AC_CHECK_FUNCS([ \
+ 	arc4random \
+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
 @@ -0,0 +1,108 @@
 +
 +HOW TO START
@@ -36,8 +146,8 @@ diff -up openssh-5.9p0/HOWTO.ldap-keys.ldap openssh-5.9p0/HOWTO.ldap-keys
 +	sshPublicKey: command="kill -9 1" ssh-rss AAAAM5...
 +4) on the ssh side set in sshd_config
 +  * Set up the backend
-+	AuthorizedKeysCommand "/usr/libexec/openssh/ssh-ldap-wrapper"
-+	AuthorizedKeysCommandRunAs <appropriate user to run LDAP>
++	AuthorizedKeysCommand /usr/libexec/openssh/ssh-ldap-wrapper
++	AuthorizedKeysCommandUser <appropriate user to run LDAP>
 +  * Do not forget to set
 +	PubkeyAuthentication yes
 +  * Swith off unnecessary auth methods
@@ -110,505 +220,509 @@ diff -up openssh-5.9p0/HOWTO.ldap-keys.ldap openssh-5.9p0/HOWTO.ldap-keys
 +5) Author
 +    Jan F. Chadima <jchadima at redhat.com>
 +
-diff -up openssh-5.9p0/Makefile.in.ldap openssh-5.9p0/Makefile.in
---- openssh-5.9p0/Makefile.in.ldap	2011-08-30 15:57:01.693024742 +0200
-+++ openssh-5.9p0/Makefile.in	2011-08-30 16:00:02.478212295 +0200
-@@ -25,6 +25,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
- PRIVSEP_PATH=@PRIVSEP_PATH@
- SSH_PRIVSEP_USER=@SSH_PRIVSEP_USER@
-@@ -58,8 +60,9 @@ XAUTH_PATH=@XAUTH_PATH@
- LDFLAGS=-L. -Lopenbsd-compat/ @LDFLAGS@
- EXEEXT=@EXEEXT@
- MANFMT=@MANFMT@
-+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)
- 
- LIBSSH_OBJS=acss.o authfd.o authfile.o bufaux.o bufbn.o buffer.o \
- 	canohost.o channels.o cipher.o cipher-acss.o cipher-aes.o \
-@@ -92,8 +95,8 @@ SSHDOBJS=sshd.o auth-rhosts.o auth-passw
- 	roaming_common.o roaming_serv.o \
- 	sandbox-null.o sandbox-rlimit.o sandbox-systrace.o sandbox-darwin.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
-@@ -161,6 +164,9 @@ ssh-keysign$(EXEEXT): $(LIBCOMPAT) libss
- 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)
+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.
++ */
 +
- ssh-keyscan$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keyscan.o roaming_dummy.o
- 	$(LD) -o $@ ssh-keyscan.o roaming_dummy.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh $(LIBS)
- 
-@@ -256,6 +262,10 @@ install-files:
- 	$(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
-@@ -272,6 +282,10 @@ install-files:
- 	$(INSTALL) -m 644 sftp-server.8.out $(DESTDIR)$(mandir)/$(mansubdir)8/sftp-server.8
- 	$(INSTALL) -m 644 ssh-keysign.8.out $(DESTDIR)$(mandir)/$(mansubdir)8/ssh-keysign.8
- 	$(INSTALL) -m 644 ssh-pkcs11-helper.8.out $(DESTDIR)$(mandir)/$(mansubdir)8/ssh-pkcs11-helper.8
-+	if test ! -z "$(INSTALL_SSH_LDAP_HELPER)" ; then \
-+		$(INSTALL) -m 644 ssh-ldap-helper.8.out $(DESTDIR)$(mandir)/$(mansubdir)8/ssh-ldap-helper.8 ; \
-+		$(INSTALL) -m 644 ssh-ldap.conf.5.out $(DESTDIR)$(mandir)/$(mansubdir)5/ssh-ldap.conf.5 ; \
-+	fi
- 	-rm -f $(DESTDIR)$(bindir)/slogin
- 	ln -s ./ssh$(EXEEXT) $(DESTDIR)$(bindir)/slogin
- 	-rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/slogin.1
-@@ -301,6 +315,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 \
-@@ -358,6 +379,8 @@ uninstall:
- 	-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
-@@ -369,6 +392,7 @@ uninstall:
- 	-rm -f $(DESTDIR)$(mandir)/$(mansubdir)8/sftp-server.8
- 	-rm -f $(DESTDIR)$(mandir)/$(mansubdir)8/ssh-keysign.8
- 	-rm -f $(DESTDIR)$(mandir)/$(mansubdir)8/ssh-pkcs11-helper.8
-+	-rm -f $(DESTDIR)$(mandir)/$(mansubdir)8/ssh-ldap-helper.8
- 	-rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/slogin.1
- 
- tests interop-tests:	$(TARGETS)
-diff -up openssh-5.9p0/configure.ac.ldap openssh-5.9p0/configure.ac
---- openssh-5.9p0/configure.ac.ldap	2011-08-30 15:57:11.297032991 +0200
-+++ openssh-5.9p0/configure.ac	2011-08-30 15:57:12.664024959 +0200
-@@ -1433,6 +1433,106 @@ AC_ARG_WITH(authorized-keys-command,
- 	]
- )
- 
-+# 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
++#include "ldapincludes.h"
++#include "log.h"
++#include "xmalloc.h"
++#include "ldapconf.h"
++#include "ldapmisc.h"
++#include "ldapbody.h"
++#include <stdio.h>
++#include <unistd.h>
 +
-+			INSTALL_SSH_LDAP_HELPER="yes"
-+			CPPFLAGS="$CPPFLAGS -DLDAP_DEPRECATED"
++#define LDAPSEARCH_FORMAT "(&(objectclass=%s)(objectclass=ldapPublicKey)(uid=%s)%s)"
++#define PUBKEYATTR "sshPublicKey"
++#define LDAP_LOGFILE	"%s/ldap.%d"
 +
-+			if test "x$withval" != "xyes" ; then
-+				CPPFLAGS="$CPPFLAGS -I${withval}/include"
-+				LDFLAGS="$LDFLAGS -L${withval}/lib"
-+			fi
++static FILE *logfile = NULL;
++static LDAP *ld;
 +
-+			AC_DEFINE([WITH_LDAP_PUBKEY], 1, [Enable LDAP pubkey support])
-+			LDAP_MSG="yes"
++static char *attrs[] = {
++    PUBKEYATTR,
++    NULL
++};
 +
-+			AC_CHECK_HEADERS(lber.h)
-+			AC_CHECK_HEADERS(ldap.h, , AC_MSG_ERROR(could not locate <ldap.h>))
-+			AC_CHECK_HEADERS(ldap_ssl.h)
++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_ARG_WITH(ldap-lib,
-+				[  --with-ldap-lib=type    select ldap library [auto|netscape5|netscape4|netscape3|umich|openldap]])
++#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 */
 +
-+			if test -z "$with_ldap_lib"; then
-+				with_ldap_lib=auto
-+			fi
++	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 "$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 !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)));
 +
-+			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
++	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
 +
-+			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
++static int
++_rebind_proc (LDAP * ld, char **whop, char **credp, int *methodp, int freeit)
++{
++	if (freeit)
++	    return LDAP_SUCCESS;
 +
-+			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
++	*whop = strdup (options.binddn);
++	*credp = strdup (options.bindpw);
++	*methodp = LDAP_AUTH_SIMPLE;
++	debug2 ("Doing LDAP rebind for %s", *whop);
++	return LDAP_SUCCESS;
++}
++#endif
 +
-+			if test -z "$found_ldap_lib"; then
-+				AC_MSG_ERROR(could not locate a valid LDAP library)
-+			fi
++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 */
 +
-+			AC_MSG_CHECKING([for working LDAP support])
-+			AC_TRY_COMPILE(
-+				[#include <sys/types.h>
-+				 #include <ldap.h>],
-+				[(void)ldap_init(0, 0);],
-+				[AC_MSG_RESULT(yes)],
-+				[
-+				    AC_MSG_RESULT(no) 
-+					AC_MSG_ERROR([** Incomplete or missing ldap libraries **])
-+				])
-+			AC_CHECK_FUNCS( \
-+				ldap_init \
-+				ldap_get_lderrno \
-+				ldap_set_lderrno \
-+				ldap_parse_result \
-+				ldap_memfree \
-+				ldap_controls_free \
-+				ldap_set_option \
-+				ldap_get_option \
-+				ldapssl_init \
-+				ldap_start_tls_s \
-+				ldap_pvt_tls_set_option \
-+				ldap_initialize \
-+			)
-+			AC_CHECK_FUNCS(ldap_set_rebind_proc,
-+				AC_MSG_CHECKING([number arguments of ldap_set_rebind_proc])
-+				AC_TRY_COMPILE(
-+					[#include <lber.h>
-+					#include <ldap.h>],
-+					[ldap_set_rebind_proc(0, 0, 0);],
-+					[ac_cv_ldap_set_rebind_proc=3],
-+					[ac_cv_ldap_set_rebind_proc=2])
-+				AC_MSG_RESULT($ac_cv_ldap_set_rebind_proc)
-+				AC_DEFINE(LDAP_SET_REBIND_PROC_ARGS, $ac_cv_ldap_set_rebind_proc, [number arguments of ldap_set_rebind_proc])
-+			)
-+		fi
-+	]
-+)
-+AC_SUBST(INSTALL_SSH_LDAP_HELPER)
++	debug ("LDAP do connect");
 +
- dnl    Checks for library functions. Please keep in alphabetical order
- AC_CHECK_FUNCS([ \
- 	arc4random \
-diff -up openssh-5.9p0/ldap-helper.c.ldap openssh-5.9p0/ldap-helper.c
---- openssh-5.9p0/ldap-helper.c.ldap	2011-08-30 15:57:12.754025033 +0200
-+++ openssh-5.9p0/ldap-helper.c	2011-08-30 15:57:12.759025510 +0200
-@@ -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.
-+ */
++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);
 +
-+#include "ldapincludes.h"
-+#include "log.h"
-+#include "misc.h"
-+#include "xmalloc.h"
-+#include "ldapconf.h"
-+#include "ldapbody.h"
-+#include <string.h>
-+#include <unistd.h>
++		if (ld != NULL) {
++			ldap_unbind (ld);
++			ld = NULL;
++		}
++		logit("reconnecting to LDAP server...");
++	}
 +
-+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;
++	if (ld == NULL) {
++		int rc;
++		struct timeval tv;
 +
-+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);
-+}
++#ifdef HAVE_LDAP_SET_OPTION
++		if (options.debug > 0) {
++#ifdef LBER_OPT_LOG_PRINT_FILE
++			if (options.logdir) {
++				char *logfilename;
++				int logfilenamelen;
 +
-+/*
-+ * Main program for the ssh pka ldap agent.
-+ */
++				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 */
 +
-+int
-+main(int ac, char **av)
-+{
-+	int opt;
-+	FILE *outfile = NULL;
++		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);
 +
-+	__progname = ssh_get_progname(av[0]);
++#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");
 +
-+	log_init(__progname, SYSLOG_LEVEL_DEBUG3, SYSLOG_FACILITY_AUTH, 0);
++#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);
 +
-+	/*
-+	 * Initialize option structure to indicate that no values have been
-+	 * set.
-+	 */
-+	initialize_options();
++#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);
 +
-+	/* Parse command-line arguments. */
-+	while ((opt = getopt(ac, av, "def:s:vw")) != -1) {
-+		switch (opt) {
-+		case 'd':
-+			config_debug = 1;
-+			break;
++#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 'e':
-+			config_exclusive_config_file = 1;
-+			config_warning_config_file = 1;
-+			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 'f':
-+			config_file_name = optarg;
-+			break;
++#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 's':
-+			config_single_user = optarg;
-+			outfile = fdopen (dup (fileno (stdout)), "w");
-+			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 'v':
-+			config_debug = 1;
-+			if (config_verbose < SYSLOG_LEVEL_DEBUG3)
-+			    config_verbose++;
-+			break;
++#ifdef HAVE_LDAP_START_TLS_S
++		if (options.ssl == SSL_START_TLS) {
++			int version;
 +
-+		case 'w':
-+			config_warning_config_file = 1;
-+			break;
++			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);
++				}
++			}
 +
-+		case '?':
-+		default:
-+			usage();
-+			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 */
 +	}
 +
-+	/* Initialize loging */
-+	log_init(__progname, config_verbose, SYSLOG_FACILITY_AUTH, config_debug);
++	if ((msgid = ldap_simple_bind (ld, options.binddn,
++	    options.bindpw)) == -1) {
++		ld_errno = ldap_get_lderrno (ld, 0, 0);
 +
-+	if (ac != optind)
-+	    fatal ("illegal extra parameter %s", av[1]);
++		error ("ldap_simple_bind %s", ldap_err2string (ld_errno));
++		reconnect++;
++		goto retry;
++	}
++	debug3 ("LDAP simple bind (%s)", options.binddn);
 +
-+	/* Ensure that fds 0 and 2 are open or directed to /dev/null */
-+	if (config_debug == 0)
-+	    sanitise_stdfd();
++	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);
 +
-+	/* Read config file */
-+	read_config_file(config_file_name);
-+	fill_default_options();
-+	if (config_verbose == SYSLOG_LEVEL_DEBUG3) {
-+		debug3 ("=== Configuration ===");
-+		dump_config();
-+		debug3 ("=== *** ===");
++		error ("ldap_result %s", ldap_err2string (ld_errno));
++		reconnect++;
++		goto retry;
 +	}
++	debug3 ("LDAP result in time");
 +
-+	ldap_checkconfig();
-+	ldap_do_connect();
++#if defined(HAVE_LDAP_PARSE_RESULT) && defined(HAVE_LDAP_CONTROLS_FREE)
++	controls = NULL;
++	if ((parserc = ldap_parse_result (ld, result, &rc, 0, 0, 0, &controls, TRUE)) != LDAP_SUCCESS)
++	    fatal ("ldap_parse_result %s", ldap_err2string (parserc));
++	debug3 ("LDAP parse result OK");
 +
-+	if (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
-+ */
++	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));
 +
-+	ldap_do_close();
-+	return 0;
++	debug2 ("LDAP do connect OK");
 +}
 +
-+/* 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-5.9p0/ldap-helper.h.ldap openssh-5.9p0/ldap-helper.h
---- openssh-5.9p0/ldap-helper.h.ldap	2011-08-30 15:57:12.835024792 +0200
-+++ openssh-5.9p0/ldap-helper.h	2011-08-30 15:57:12.839024637 +0200
-@@ -0,0 +1,32 @@
-+/* $OpenBSD: ldap-helper.h,v 1.1 2009/12/03 03:34:42 jfch Exp $ */
-+/*
-+ * Copyright (c) 2009 Jan F. Chadima.  All rights reserved.
-+ *
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions
-+ * are met:
-+ * 1. Redistributions of source code must retain the above copyright
-+ *    notice, this list of conditions and the following disclaimer.
-+ * 2. Redistributions in binary form must reproduce the above copyright
-+ *    notice, this list of conditions and the following disclaimer in the
-+ *    documentation and/or other materials provided with the distribution.
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
-+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
-+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
-+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
-+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
-+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
-+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-+ */
-+
-+#ifndef LDAP_HELPER_H
-+#define LDAP_HELPER_H
-+
-+extern int config_exclusive_config_file;
-+extern int config_warning_config_file;
-+
-+#endif /* LDAP_HELPER_H */
-diff -up openssh-5.9p0/ldap.conf.ldap openssh-5.9p0/ldap.conf
---- openssh-5.9p0/ldap.conf.ldap	2011-08-30 15:57:12.929026186 +0200
-+++ openssh-5.9p0/ldap.conf	2011-08-30 15:57:12.933024937 +0200
-@@ -0,0 +1,88 @@
-+# $Id$
-+#
-+# This is the example configuration file for the OpenSSH
-+# LDAP backend
-+# 
-+# see ssh-ldap.conf(5)
-+#
-+
-+# 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
-+
-+# 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
++void
++process_user (const char *user, FILE *output)
++{
++	LDAPMessage *res, *e;
++	char *buffer;
++	int bufflen, rc, i;
++	struct timeval timeout;
 +
-+# The distinguished name to bind to the server with.
-+# Optional: default is to bind anonymously.
-+#binddn cn=openssh_keys,dc=example,dc=org
++	debug ("LDAP process user");
 +
-+# The credentials to bind with. 
-+# Optional: default is no credential.
-+#bindpw TopSecret
++	/* 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;
++	}
 +
-+# The distinguished name of the search base.
-+#base dc=example,dc=org
++	/* 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;
 +
-+# The LDAP version to use (defaults to 3
-+# if supported by client library)
-+#ldap_version 3
++	debug3 ("LDAP search scope = %d %s", options.scope, buffer);
 +
-+# The search scope.
-+#scope sub
-+#scope one
-+#scope base
++	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;
++	}
 +
-+# Search timelimit
-+#timelimit 30
++	/* free */
++	free (buffer);
 +
-+# Bind/connect timelimit
-+#bind_timelimit 30
++	for (e = ldap_first_entry(ld, res); e != NULL; e = ldap_next_entry(ld, e)) {
++		int num;
++		struct berval **keys;
 +
-+# Reconnect policy: hard (default) will retry connecting to
-+# the software with exponential backoff, soft will fail
-+# immediately.
-+#bind_policy hard
++		keys = ldap_get_values_len(ld, e, PUBKEYATTR);
++		num = ldap_count_values_len(keys);
++		for (i = 0 ; i < num ; i++) {
++			char *cp; //, *options = NULL;
 +
-+# SSL setup, may be implied by URI also.
-+#ssl no
-+#ssl on
-+#ssl start_tls
++			for (cp = keys[i]->bv_val; *cp == ' ' || *cp == '\t'; cp++);
++			if (!*cp || *cp == '\n' || *cp == '#')
++			    continue;
 +
-+# 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
++			/* We have found the desired key. */
++			fprintf (output, "%s\n", keys[i]->bv_val);
++		}
 +
-+# 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
++		ldap_value_free_len(keys);
++	}
 +
-+# Seed the PRNG if /dev/urandom is not provided
-+#tls_randfile /var/run/egd-pool
++	ldap_msgfree(res);
++	debug2 ("LDAP process user finished");
++}
 +
-+# SSL cipher suite
-+# See man ciphers for syntax
-+#tls_ciphers TLSv1
++void
++ldap_do_close(void)
++{
++	int rc;
 +
-+# Client certificate and key
-+# Use these, if your server requires client authentication.
-+#tls_cert
-+#tls_key
++	debug ("LDAP do close");
++	if ((rc = ldap_unbind_ext(ld, NULL, NULL)) != LDAP_SUCCESS)
++	    fatal ("ldap_unbind_ext: %s",
++                                    ldap_err2string (rc));
 +
-diff -up openssh-5.9p0/ldapbody.c.ldap openssh-5.9p0/ldapbody.c
---- openssh-5.9p0/ldapbody.c.ldap	2011-08-30 15:57:13.005024661 +0200
-+++ openssh-5.9p0/ldapbody.c	2011-08-30 15:57:13.011024848 +0200
-@@ -0,0 +1,494 @@
-+/* $OpenBSD: ldapbody.c,v 1.1 2009/12/03 03:34:42 jfch Exp $ */
++	ld = NULL;
++	debug2 ("LDAP do close OK");
++	return;
++}
++
+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 $ */
 +/*
 + * Copyright (c) 2009 Jan F. Chadima.  All rights reserved.
 + *
@@ -633,1207 +747,1045 @@ diff -up openssh-5.9p0/ldapbody.c.ldap openssh-5.9p0/ldapbody.c
 + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 + */
 +
-+#include "ldapincludes.h"
-+#include "log.h"
-+#include "xmalloc.h"
-+#include "ldapconf.h"
-+#include "ldapmisc.h"
-+#include "ldapbody.h"
-+#include <stdio.h>
-+#include <unistd.h>
-+
-+#define LDAPSEARCH_FORMAT "(&(objectclass=posixAccount)(objectclass=ldapPublicKey)(uid=%s)%s)"
-+#define PUBKEYATTR "sshPublicKey"
-+#define LDAP_LOGFILE	"%s/ldap.%d"
-+
-+static FILE *logfile = NULL;
-+static LDAP *ld;
-+
-+static char *attrs[] = {
-+    PUBKEYATTR,
-+    NULL
-+};
-+
-+void
-+ldap_checkconfig (void)
-+{
-+#ifdef HAVE_LDAP_INITIALIZE
-+		if (options.host == NULL && options.uri == NULL)
-+#else
-+		if (options.host == NULL)
-+#endif
-+		    fatal ("missing  \"host\" in config file");
-+}
-+
-+#if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)
-+static int
-+_rebind_proc (LDAP * ld, LDAP_CONST char *url, int request, ber_int_t msgid)
-+{
-+	struct timeval timeout;
-+	int rc;
-+#if defined(HAVE_LDAP_PARSE_RESULT) && defined(HAVE_LDAP_CONTROLS_FREE)
-+	LDAPMessage *result;
-+#endif /* HAVE_LDAP_PARSE_RESULT && HAVE_LDAP_CONTROLS_FREE */
-+
-+	debug2 ("Doing LDAP rebind to %s", options.binddn);
-+	if (options.ssl == SSL_START_TLS) {
-+		if ((rc = ldap_start_tls_s (ld, NULL, NULL)) != LDAP_SUCCESS) {
-+			error ("ldap_starttls_s: %s", ldap_err2string (rc));
-+			return LDAP_OPERATIONS_ERROR;
-+		}
-+	}
-+
-+#if !defined(HAVE_LDAP_PARSE_RESULT) || !defined(HAVE_LDAP_CONTROLS_FREE)
-+	return ldap_simple_bind_s (ld, options.binddn, options.bindpw);
-+#else
-+	if (ldap_simple_bind(ld, options.binddn, options.bindpw) < 0)
-+	    fatal ("ldap_simple_bind %s", ldap_err2string (ldap_get_lderrno (ld, 0, 0)));
-+
-+	timeout.tv_sec = options.bind_timelimit;
-+	timeout.tv_usec = 0;
-+	result = NULL;
-+	if ((rc = ldap_result (ld, msgid, FALSE, &timeout, &result)) < 1) {
-+		error ("ldap_result %s", ldap_err2string (ldap_get_lderrno (ld, 0, 0)));
-+		ldap_msgfree (result);
-+		return LDAP_OPERATIONS_ERROR;
-+	}
-+	debug3 ("LDAP rebind to %s succesfull", options.binddn);
-+	return rc;
-+#endif
-+}
-+#else
-+
-+static int
-+_rebind_proc (LDAP * ld, char **whop, char **credp, int *methodp, int freeit)
-+{
-+	if (freeit)
-+	    return LDAP_SUCCESS;
-+
-+	*whop = strdup (options.binddn);
-+	*credp = strdup (options.bindpw);
-+	*methodp = LDAP_AUTH_SIMPLE;
-+	debug2 ("Doing LDAP rebind for %s", *whop);
-+	return LDAP_SUCCESS;
-+}
-+#endif
-+
-+void
-+ldap_do_connect(void)
-+{
-+	int rc, msgid, ld_errno = 0;
-+	struct timeval timeout;
-+#if defined(HAVE_LDAP_PARSE_RESULT) && defined(HAVE_LDAP_CONTROLS_FREE)
-+	int parserc;
-+	LDAPMessage *result;
-+	LDAPControl **controls;
-+	int reconnect = 0;
-+#endif /* HAVE_LDAP_PARSE_RESULT && HAVE_LDAP_CONTROLS_FREE */
-+
-+	debug ("LDAP do connect");
-+
-+retry:
-+	if (reconnect) {
-+		debug3 ("Reconnecting with ld_errno %d", ld_errno);
-+		if (options.bind_policy == 0 ||
-+		    (ld_errno != LDAP_SERVER_DOWN && ld_errno != LDAP_TIMEOUT) ||
-+			reconnect > 5)
-+			    fatal ("Cannot connect to LDAP server");
-+	
-+		if (reconnect > 1)
-+			sleep (reconnect - 1);
-+
-+		if (ld != NULL) {
-+			ldap_unbind (ld);
-+			ld = NULL;
-+		}
-+		logit("reconnecting to LDAP server...");
-+	}
-+
-+	if (ld == NULL) {
-+		int rc;
-+		struct timeval tv;
-+
-+#ifdef HAVE_LDAP_SET_OPTION
-+		if (options.debug > 0) {
-+#ifdef LBER_OPT_LOG_PRINT_FILE
-+			if (options.logdir) {
-+				char *logfilename;
-+				int logfilenamelen;
-+
-+				logfilenamelen = strlen (LDAP_LOGFILE) + strlen ("000000") + strlen (options.logdir);
-+				logfilename = xmalloc (logfilenamelen);
-+				snprintf (logfilename, logfilenamelen, LDAP_LOGFILE, options.logdir, (int) getpid ());
-+				logfilename[logfilenamelen - 1] = 0;
-+				if ((logfile = fopen (logfilename, "a")) == NULL)
-+				    fatal ("cannot append to %s: %s", logfilename, strerror (errno));
-+				debug3 ("LDAP debug into %s", logfilename);
-+				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 */
++#ifndef LDAPBODY_H
++#define LDAPBODY_H
 +
-+		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");
-+			}
++#include <stdio.h>
 +
-+			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 */
++void ldap_checkconfig(void);
++void ldap_do_connect(void);
++void process_user(const char *, FILE *);
++void ldap_do_close(void);
 +
-+		/* 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. */
++#endif /* LDAPBODY_H */
 +
-+#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 */
+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 $ */
++/*
++ * 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.
++ */
 +
-+			/* 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);
-+			}
++#include "ldapincludes.h"
++#include "ldap-helper.h"
++#include "log.h"
++#include "misc.h"
++#include "xmalloc.h"
++#include "ldapconf.h"
++#include <unistd.h>
++#include <string.h>
 +
-+			/* 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);
-+			}
++/* Keyword tokens. */
 +
-+			/* 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);
++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;
 +
-+			/* 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);
-+			}
++/* Textual representations of the tokens. */
 +
-+			/* 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);
-+			}
++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 }
++};
 +
-+			/* 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 */
++/* Configuration ptions. */
 +
-+		/* 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 */
-+		}
++Options options;
 +
-+		if (ld == NULL)
-+			fatal ("no way to open ldap");
++/*
++ * Returns the number of the token pointed to by cp or oBadOption.
++ */
 +
-+#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 */
++static OpCodes
++parse_token(const char *cp, const char *filename, int linenum)
++{
++	u_int i;
 +
-+#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);
++	for (i = 0; keywords[i].name; i++)
++		if (strcasecmp(cp, keywords[i].name) == 0)
++			return keywords[i].opcode;
 +
-+#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 (config_warning_config_file) 
++	    logit("%s: line %d: Bad configuration option: %s",
++		filename, linenum, cp);
++	return lBadOption;
++}
 +
-+#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);
++/*
++ * 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"
 +
-+#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);
++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;
 +
-+#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
++	/* Strip trailing whitespace */
++	for (len = strlen(line) - 1; len > 0; len--) {
++		if (strchr(WHITESPACE, line[len]) == NULL)
++			break;
++		line[len] = '\0';
++	}
++
++	s = line;
++	/* Get the keyword. (Each line is supposed to begin with a keyword). */
++	if ((keyword = strdelim(&s)) == NULL)
++		return 0;
++	/* Ignore leading whitespace. */
++	if (*keyword == '\0')
++		keyword = strdelim(&s);
++	if (keyword == NULL || !*keyword || *keyword == '\n' || *keyword == '#')
++		return 0;
 +
-+#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
++	opcode = parse_token(keyword, filename, linenum);
 +
-+#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
++	switch (opcode) {
++	case lBadOption:
++		/* don't panic, but count bad options */
++		return -1;
++		/* NOTREACHED */
 +
-+#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 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;
 +
-+#ifdef HAVE_LDAP_START_TLS_S
-+		if (options.ssl == SSL_START_TLS) {
-+			int version;
++	case lURI:
++		xstringptr = &options.uri;
++		goto parse_xstring;
 +
-+			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);
-+				}
-+			}
++	case lBase:
++		xstringptr = &options.base;
++		goto parse_xstring;
 +
-+			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 lBindDN:
++		xstringptr = &options.binddn;
++		goto parse_xstring;
 +
-+	if ((msgid = ldap_simple_bind (ld, options.binddn,
-+	    options.bindpw)) == -1) {
-+		ld_errno = ldap_get_lderrno (ld, 0, 0);
++	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;
 +
-+		error ("ldap_simple_bind %s", ldap_err2string (ld_errno));
-+		reconnect++;
-+		goto retry;
-+	}
-+	debug3 ("LDAP simple bind (%s)", options.binddn);
++	case lRootBindDN:
++		xstringptr = &rootbinddn;
++		goto parse_xstring;
 +
-+	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 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;
 +
-+		error ("ldap_result %s", ldap_err2string (ld_errno));
-+		reconnect++;
-+		goto retry;
-+	}
-+	debug3 ("LDAP result in time");
++	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 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 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 (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));
++		/* 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;
 +
-+	debug2 ("LDAP do connect OK");
-+}
++	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;
 +
-+void
-+process_user (const char *user, FILE *output)
-+{
-+	LDAPMessage *res, *e;
-+	char *buffer;
-+	int bufflen, rc, i;
-+	struct timeval timeout;
++	case lBind_TimeLimit:
++		intptr = &options.bind_timelimit;
++		goto parse_time;
 +
-+	debug ("LDAP process user");
++	case lLdap_Version:
++		intptr = &options.ldap_version;
++		goto parse_int;
 +
-+	/* 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 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;
 +
-+	/* build  filter for LDAP request */
-+	bufflen = strlen (LDAPSEARCH_FORMAT) + strlen (user);
-+	if (options.ssh_filter != NULL)
-+	    bufflen += strlen (options.ssh_filter);
-+	buffer = xmalloc (bufflen);
-+	snprintf(buffer, bufflen, LDAPSEARCH_FORMAT, user, (options.ssh_filter != NULL) ? options.ssh_filter : NULL);
-+	buffer[bufflen - 1] = 0;
++	case lSSLPath:
++		charptr = &options.sslpath;
++		goto parse_string;
 +
-+	debug3 ("LDAP search scope = %d %s", options.scope, buffer);
++	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;
 +
-+	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 lReferrals:
++		intptr = &options.referrals;
++parse_flag:
++		arg = strdelim(&s);
++		if (!arg || *arg == '\0')
++			fatal("%.200s line %d: Missing yes/no argument.", filename, linenum);
++		value = 0;	/* To avoid compiler warning... */
++		if (strcasecmp(arg, "yes") == 0 || strcasecmp(arg, "true") == 0 || strcasecmp(arg, "on") == 0)
++			value = 1;
++		else if (strcasecmp(arg, "no") == 0 || strcasecmp(arg, "false") == 0 || strcasecmp(arg, "off") == 0)
++			value = 0;
++		else
++			fatal("%.200s line %d: Bad yes/no argument.", filename, linenum);
++		if (*intptr == -1)
++			*intptr = value;
++		break;
++
++	case lRestart:
++		intptr = &options.restart;
++		goto parse_flag;
 +
-+	/* free */
-+	free (buffer);
++	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;
 +
-+	for (e = ldap_first_entry(ld, res); e != NULL; e = ldap_next_entry(ld, e)) {
-+		int num;
-+		struct berval **keys;
++	case lTLS_CaCertFile:
++		charptr = &options.tls_cacertfile;
++		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 lTLS_CaCertDir:
++		charptr = &options.tls_cacertdir;
++		goto parse_string;
 +
-+			for (cp = keys[i]->bv_val; *cp == ' ' || *cp == '\t'; cp++);
-+			if (!*cp || *cp == '\n' || *cp == '#')
-+			    continue;
++	case lTLS_Ciphers:
++		xstringptr = &options.tls_ciphers;
++		goto parse_xstring;
 +
-+			/* We have found the desired key. */
-+			fprintf (output, "%s\n", keys[i]->bv_val);
-+		}
++	case lTLS_Cert:
++		charptr = &options.tls_cert;
++		goto parse_string;
 +
-+		ldap_value_free_len(keys);
-+	}
++	case lTLS_Key:
++		charptr = &options.tls_key;
++		goto parse_string;
 +
-+	ldap_msgfree(res);
-+	debug2 ("LDAP process user finished");
-+}
++	case lTLS_RandFile:
++		charptr = &options.tls_randfile;
++		goto parse_string;
 +
-+void
-+ldap_do_close(void)
-+{
-+	int rc;
++	case lLogDir:
++		charptr = &options.logdir;
++		goto parse_string;
 +
-+	debug ("LDAP do close");
-+	if ((rc = ldap_unbind_ext(ld, NULL, NULL)) != LDAP_SUCCESS)
-+	    fatal ("ldap_unbind_ext: %s",
-+                                    ldap_err2string (rc));
++	case lDebug:
++		intptr = &options.debug;
++		goto parse_int;
 +
-+	ld = NULL;
-+	debug2 ("LDAP do close OK");
-+	return;
-+}
++	case lSSH_Filter:
++		xstringptr = &options.ssh_filter;
++		goto parse_xstring;
 +
-diff -up openssh-5.9p0/ldapbody.h.ldap openssh-5.9p0/ldapbody.h
---- openssh-5.9p0/ldapbody.h.ldap	2011-08-30 15:57:13.087150596 +0200
-+++ openssh-5.9p0/ldapbody.h	2011-08-30 15:57:13.091149461 +0200
-@@ -0,0 +1,37 @@
-+/* $OpenBSD: ldapbody.h,v 1.1 2009/12/03 03:34:42 jfch Exp $ */
-+/*
-+ * Copyright (c) 2009 Jan F. Chadima.  All rights reserved.
-+ *
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions
-+ * are met:
-+ * 1. Redistributions of source code must retain the above copyright
-+ *    notice, this list of conditions and the following disclaimer.
-+ * 2. Redistributions in binary form must reproduce the above copyright
-+ *    notice, this list of conditions and the following disclaimer in the
-+ *    documentation and/or other materials provided with the distribution.
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
-+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
-+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
-+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
-+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
-+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
-+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-+ */
++	case lAccountClass:
++		charptr = &options.account_class;
++		goto parse_string;
 +
-+#ifndef LDAPBODY_H
-+#define LDAPBODY_H
++	case lDeprecated:
++		debug("%s line %d: Deprecated option \"%s\"",
++		    filename, linenum, keyword);
++		return 0;
 +
-+#include <stdio.h>
++	case lUnsupported:
++		error("%s line %d: Unsupported option \"%s\"",
++		    filename, linenum, keyword);
++		return 0;
 +
-+void ldap_checkconfig(void);
-+void ldap_do_connect(void);
-+void process_user(const char *, FILE *);
-+void ldap_do_close(void);
++	default:
++		fatal("process_config_line: Unimplemented opcode %d", opcode);
++	}
 +
-+#endif /* LDAPBODY_H */
++	/* 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;
++}
 +
-diff -up openssh-5.9p0/ldapconf.c.ldap openssh-5.9p0/ldapconf.c
---- openssh-5.9p0/ldapconf.c.ldap	2011-08-30 15:57:13.164036922 +0200
-+++ openssh-5.9p0/ldapconf.c	2011-08-30 15:57:13.171065499 +0200
-@@ -0,0 +1,682 @@
-+/* $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.
++ * 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.
 + */
 +
-+#include "ldapincludes.h"
-+#include "ldap-helper.h"
-+#include "log.h"
-+#include "misc.h"
-+#include "xmalloc.h"
-+#include "ldapconf.h"
-+#include <unistd.h>
-+#include <string.h>
-+
-+/* Keyword tokens. */
-+
-+typedef enum {
-+	lBadOption,
-+	lHost, lURI, lBase, lBindDN, lBindPW, lRootBindDN,
-+	lScope, lDeref, lPort, lTimeLimit, lBind_TimeLimit,
-+	lLdap_Version, lBind_Policy, lSSLPath, lSSL, lReferrals,
-+	lRestart, lTLS_CheckPeer, lTLS_CaCertFile,
-+	lTLS_CaCertDir, lTLS_Ciphers, lTLS_Cert, lTLS_Key,
-+	lTLS_RandFile, lLogDir, lDebug, lSSH_Filter,
-+	lDeprecated, lUnsupported
-+} OpCodes;
++void
++read_config_file(const char *filename)
++{
++	FILE *f;
++	char line[1024];
++	int active, linenum;
++	int bad_options = 0;
++	struct stat sb;
 +
-+/* Textual representations of the tokens. */
++	if ((f = fopen(filename, "r")) == NULL)
++		fatal("fopen %s: %s", filename, strerror(errno));
 +
-+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 },
-+	{ NULL, lBadOption }
-+};
++	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);
 +
-+/* Configuration ptions. */
++	debug("Reading configuration data %.200s", filename);
 +
-+Options options;
++	/*
++	 * 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);
++}
 +
 +/*
-+ * Returns the number of the token pointed to by cp or oBadOption.
++ * 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.
 + */
 +
-+static OpCodes
-+parse_token(const char *cp, const char *filename, int linenum)
++void
++initialize_options(void)
 +{
-+	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;
++	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;
 +}
 +
 +/*
-+ * Processes a single option line as used in the configuration files. This
-+ * only sets those values that have not already been set.
++ * Called after processing other sources of option data, this fills those
++ * options for which no value has been specified with their default values.
 + */
-+#define WHITESPACE " \t\r\n"
 +
-+static int
-+process_config_line(char *line, const char *filename, int linenum)
++void
++fill_default_options(void)
 +{
-+	char *s, **charptr, **xstringptr, *endofnumber, *keyword, *arg;
-+	char *rootbinddn = NULL;
-+	int opcode, *intptr, value;
-+	size_t len;
-+
-+	/* Strip trailing whitespace */
-+	for (len = strlen(line) - 1; len > 0; len--) {
-+		if (strchr(WHITESPACE, line[len]) == NULL)
-+			break;
-+		line[len] = '\0';
-+	}
-+
-+	s = line;
-+	/* Get the keyword. (Each line is supposed to begin with a keyword). */
-+	if ((keyword = strdelim(&s)) == NULL)
-+		return 0;
-+	/* Ignore leading whitespace. */
-+	if (*keyword == '\0')
-+		keyword = strdelim(&s);
-+	if (keyword == NULL || !*keyword || *keyword == '\n' || *keyword == '#')
-+		return 0;
++	if (options.uri != NULL) {
++		LDAPURLDesc *ludp;
 +
-+	opcode = parse_token(keyword, filename, linenum);
++		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;
 +
-+	switch (opcode) {
-+	case lBadOption:
-+		/* don't panic, but count bad options */
-+		return -1;
-+		/* NOTREACHED */
++			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
 +
-+	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;
++		options.uri = xmalloc (MAXURILEN);
++		len = snprintf (options.uri, MAXURILEN, "ldap%s://%s:%d",
++		    (options.ssl == 0) ? "" : "s", options.host, options.port);
++		options.uri[MAXURILEN - 1] = 0;
++		options.uri = xrealloc (options.uri, len + 1, 1);
++	}
++	if (options.binddn == NULL)
++	    options.binddn = "";
++	if (options.bindpw == NULL)
++	    options.bindpw = "";
++	if (options.scope == -1)
++	    options.scope = LDAP_SCOPE_SUBTREE;
++	if (options.deref == -1)
++	    options.deref = LDAP_DEREF_NEVER;
++	if (options.timelimit == -1)
++	    options.timelimit = 10;
++	if (options.bind_timelimit == -1)
++	    options.bind_timelimit = 10;
++	if (options.ldap_version == -1)
++	    options.ldap_version = 3;
++	if (options.bind_policy == -1)
++	    options.bind_policy = 1;
++	if (options.referrals == -1)
++	    options.referrals = 1;
++	if (options.restart == -1)
++	    options.restart = 1;
++	if (options.tls_checkpeer == -1)
++	    options.tls_checkpeer = LDAP_OPT_X_TLS_HARD;
++	if (options.debug == -1)
++	    options.debug = 0;
++	if (options.ssh_filter == NULL)
++	    options.ssh_filter = "";
++	if (options.account_class == NULL)
++	    options.account_class = "posixAccount";
++}
 +
-+	case lURI:
-+		xstringptr = &options.uri;
-+		goto parse_xstring;
++static const char *
++lookup_opcode_name(OpCodes code)
++{
++	u_int i;
 +
-+	case lBase:
-+		xstringptr = &options.base;
-+		goto parse_xstring;
++	for (i = 0; keywords[i].name != NULL; i++)
++	    if (keywords[i].opcode == code)
++		return(keywords[i].name);
++	return "UNKNOWN";
++}
 +
-+	case lBindDN:
-+		xstringptr = &options.binddn;
-+		goto parse_xstring;
++static void
++dump_cfg_string(OpCodes code, const char *val)
++{
++	if (val == NULL)
++	    debug3("%s <UNDEFINED>", lookup_opcode_name(code));
++	else
++	    debug3("%s %s", lookup_opcode_name(code), val);
++}
 +
-+	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;
++static void
++dump_cfg_int(OpCodes code, int val)
++{
++	if (val == -1)
++	    debug3("%s <UNDEFINED>", lookup_opcode_name(code));
++	else
++	    debug3("%s %d", lookup_opcode_name(code), val);
++}
 +
-+	case lRootBindDN:
-+		xstringptr = &rootbinddn;
-+		goto parse_xstring;
++struct names {
++	int value;
++	char *name;
++};
 +
-+	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;
++static void
++dump_cfg_namedint(OpCodes code, int val, struct names *names)
++{
++	u_int i;
 +
-+	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 <UNDEFINED>", lookup_opcode_name(code));
++	else {
++		for (i = 0; names[i].value != -1; i++)
++	 	    if (names[i].value == val) {
++	    		debug3("%s %s", lookup_opcode_name(code), names[i].name);
++			    return;
++		}
++		debug3("%s unknown: %d", lookup_opcode_name(code), val);
++	}
++}
 +
-+	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 lDeprecated:
-+		debug("%s line %d: Deprecated option \"%s\"",
-+		    filename, linenum, keyword);
-+		return 0;
++# The distinguished name of the search base.
++#base dc=example,dc=org
 +
-+	case lUnsupported:
-+		error("%s line %d: Unsupported option \"%s\"",
-+		    filename, linenum, keyword);
-+		return 0;
++# The LDAP version to use (defaults to 3
++# if supported by client library)
++#ldap_version 3
 +
-+	default:
-+		fatal("process_config_line: Unimplemented opcode %d", opcode);
-+	}
++# The search scope.
++#scope sub
++#scope one
++#scope base
 +
-+	/* 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;
-+}
++# Search timelimit
++#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.
-+ */
++# Bind/connect timelimit
++#bind_timelimit 30
 +
-+void
-+read_config_file(const char *filename)
-+{
-+	FILE *f;
-+	char line[1024];
-+	int active, linenum;
-+	int bad_options = 0;
-+	struct stat sb;
++# Reconnect policy: hard (default) will retry connecting to
++# the software with exponential backoff, soft will fail
++# immediately.
++#bind_policy hard
 +
-+	if ((f = fopen(filename, "r")) == NULL)
-+		fatal("fopen %s: %s", filename, strerror(errno));
++# SSL setup, may be implied by URI also.
++#ssl no
++#ssl on
++#ssl start_tls
 +
-+	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);
++# 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
 +
-+	debug("Reading configuration data %.200s", 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
 +
-+	/*
-+	 * 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);
-+}
++# Seed the PRNG if /dev/urandom is not provided
++#tls_randfile /var/run/egd-pool
 +
-+/*
-+ * 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.
-+ */
++# SSL cipher suite
++# See man ciphers for syntax
++#tls_ciphers TLSv1
 +
-+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;
-+}
++# Client certificate and key
++# Use these, if your server requires client authentication.
++#tls_cert
++#tls_key
 +
+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 $ */
 +/*
-+ * Called after processing other sources of option data, this fills those
-+ * options for which no value has been specified with their default values.
++ * 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
-+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 = xrealloc (options.uri, len + 1, 1);
-+	}
-+	if (options.binddn == NULL)
-+	    options.binddn = "";
-+	if (options.bindpw == NULL)
-+	    options.bindpw = "";
-+	if (options.scope == -1)
-+	    options.scope = LDAP_SCOPE_SUBTREE;
-+	if (options.deref == -1)
-+	    options.deref = LDAP_DEREF_NEVER;
-+	if (options.timelimit == -1)
-+	    options.timelimit = 10;
-+	if (options.bind_timelimit == -1)
-+	    options.bind_timelimit = 10;
-+	if (options.ldap_version == -1)
-+	    options.ldap_version = 3;
-+	if (options.bind_policy == -1)
-+	    options.bind_policy = 1;
-+	if (options.referrals == -1)
-+	    options.referrals = 1;
-+	if (options.restart == -1)
-+	    options.restart = 1;
-+	if (options.tls_checkpeer == -1)
-+	    options.tls_checkpeer = LDAP_OPT_X_TLS_HARD;
-+	if (options.debug == -1)
-+	    options.debug = 0;
-+	if (options.ssh_filter == NULL)
-+	    options.ssh_filter = "";
-+}
-+
-+static const char *
-+lookup_opcode_name(OpCodes code)
-+{
-+	u_int i;
++#include "ldapincludes.h"
++#include "log.h"
++#include "misc.h"
++#include "xmalloc.h"
++#include "ldapconf.h"
++#include "ldapbody.h"
++#include <string.h>
++#include <unistd.h>
 +
-+	for (i = 0; keywords[i].name != NULL; i++)
-+	    if (keywords[i].opcode == code)
-+		return(keywords[i].name);
-+	return "UNKNOWN";
-+}
++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;
 +
 +static void
-+dump_cfg_string(OpCodes code, const char *val)
++usage(void)
 +{
-+	if (val == NULL)
-+	    debug3("%s <UNDEFINED>", lookup_opcode_name(code));
-+	else
-+	    debug3("%s %s", lookup_opcode_name(code), 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);
 +}
 +
-+static void
-+dump_cfg_int(OpCodes code, int val)
++/*
++ * Main program for the ssh pka ldap agent.
++ */
++
++int
++main(int ac, char **av)
 +{
-+	if (val == -1)
-+	    debug3("%s <UNDEFINED>", lookup_opcode_name(code));
-+	else
-+	    debug3("%s %d", lookup_opcode_name(code), val);
-+}
++	int opt;
++	FILE *outfile = NULL;
 +
-+struct names {
-+	int value;
-+	char *name;
-+};
++	__progname = ssh_get_progname(av[0]);
 +
-+static void
-+dump_cfg_namedint(OpCodes code, int val, struct names *names)
-+{
-+	u_int i;
++	log_init(__progname, SYSLOG_LEVEL_DEBUG3, SYSLOG_FACILITY_AUTH, 0);
 +
-+	if (val == -1)
-+	    debug3("%s <UNDEFINED>", lookup_opcode_name(code));
-+	else {
-+		for (i = 0; names[i].value != -1; i++)
-+	 	    if (names[i].value == val) {
-+	    		debug3("%s %s", lookup_opcode_name(code), names[i].name);
-+			    return;
++	/*
++	 * Initialize option structure to indicate that no values have been
++	 * set.
++	 */
++	initialize_options();
++
++	/* Parse command-line arguments. */
++	while ((opt = getopt(ac, av, "def:s:vw")) != -1) {
++		switch (opt) {
++		case 'd':
++			config_debug = 1;
++			break;
++
++		case 'e':
++			config_exclusive_config_file = 1;
++			config_warning_config_file = 1;
++			break;
++
++		case 'f':
++			config_file_name = optarg;
++			break;
++
++		case 's':
++			config_single_user = optarg;
++			outfile = fdopen (dup (fileno (stdout)), "w");
++			break;
++
++		case 'v':
++			config_debug = 1;
++			if (config_verbose < SYSLOG_LEVEL_DEBUG3)
++			    config_verbose++;
++			break;
++
++		case 'w':
++			config_warning_config_file = 1;
++			break;
++
++		case '?':
++		default:
++			usage();
++			break;
 +		}
-+		debug3("%s unknown: %d", lookup_opcode_name(code), val);
 +	}
-+}
 +
-+static struct names _yesnotls[] = {
-+	{ 0, "No" },
-+	{ 1, "Yes" },
-+	{ 2, "Start_TLS" },
-+	{ -1, NULL }};
++	/* Initialize loging */
++	log_init(__progname, config_verbose, SYSLOG_FACILITY_AUTH, config_debug);
 +
-+static struct names _scope[] = {
-+	{ LDAP_SCOPE_BASE, "Base" },
-+	{ LDAP_SCOPE_ONELEVEL, "One" },
-+	{ LDAP_SCOPE_SUBTREE, "Sub"},
-+	{ -1, NULL }};
++	if (ac != optind)
++	    fatal ("illegal extra parameter %s", av[1]);
 +
-+static struct names _deref[] = {
-+	{ LDAP_DEREF_NEVER, "Never" },
-+	{ LDAP_DEREF_SEARCHING, "Searching" },
-+	{ LDAP_DEREF_FINDING, "Finding" },
-+	{ LDAP_DEREF_ALWAYS, "Always" },
-+	{ -1, NULL }};
++	/* Ensure that fds 0 and 2 are open or directed to /dev/null */
++	if (config_debug == 0)
++	    sanitise_stdfd();
 +
-+static struct names _yesno[] = {
-+	{ 0, "No" },
-+	{ 1, "Yes" },
-+	{ -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 _bindpolicy[] = {
-+	{ 0, "Soft" },
-+	{ 1, "Hard" },
-+	{ -1, NULL }};
++	ldap_checkconfig();
++	ldap_do_connect();
 +
-+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 }};
++	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
++ */
++	}
 +
-+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);
++	ldap_do_close();
++	return 0;
 +}
 +
-diff -up openssh-5.9p0/ldapconf.h.ldap openssh-5.9p0/ldapconf.h
---- openssh-5.9p0/ldapconf.h.ldap	2011-08-30 15:57:13.265149057 +0200
-+++ openssh-5.9p0/ldapconf.h	2011-08-30 15:57:13.271153923 +0200
-@@ -0,0 +1,71 @@
-+/* $OpenBSD: ldapconf.c,v 1.1 2009/12/03 03:34:42 jfch Exp $ */
++/* 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 $ */
 +/*
 + * Copyright (c) 2009 Jan F. Chadima.  All rights reserved.
 + *
@@ -1858,55 +1810,16 @@ diff -up openssh-5.9p0/ldapconf.h.ldap openssh-5.9p0/ldapconf.h
 + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 + */
 +
-+#ifndef LDAPCONF_H
-+#define LDAPCONF_H
-+
-+#define SSL_OFF          0
-+#define SSL_LDAPS        1
-+#define SSL_START_TLS    2
-+
-+/* Data structure for representing option data. */
-+
-+typedef struct {
-+	char *host;
-+	char *uri;
-+	char *base;
-+	char *binddn;
-+	char *bindpw;
-+	int scope;
-+	int deref;
-+	int port;
-+	int timelimit;
-+	int bind_timelimit;
-+	int ldap_version;
-+	int bind_policy;
-+	char *sslpath;
-+	int ssl;
-+	int referrals;
-+	int restart;
-+	int tls_checkpeer;
-+	char *tls_cacertfile;
-+	char *tls_cacertdir;
-+	char *tls_ciphers;
-+	char *tls_cert;
-+	char *tls_key;
-+	char *tls_randfile;
-+	char *logdir;
-+	int debug;
-+	char *ssh_filter;
-+}       Options;
-+
-+extern Options options;
-+
-+void read_config_file(const char *);
-+void initialize_options(void);
-+void fill_default_options(void);
-+void dump_config(void);
++#ifndef LDAP_HELPER_H
++#define LDAP_HELPER_H
 +
-+#endif /* LDAPCONF_H */
-diff -up openssh-5.9p0/ldapincludes.h.ldap openssh-5.9p0/ldapincludes.h
---- openssh-5.9p0/ldapincludes.h.ldap	2011-08-30 15:57:13.344023601 +0200
-+++ openssh-5.9p0/ldapincludes.h	2011-08-30 15:57:13.348024596 +0200
++extern int config_exclusive_config_file;
++extern int config_warning_config_file;
++
++#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
 @@ -0,0 +1,41 @@
 +/* $OpenBSD: ldapconf.c,v 1.1 2009/12/03 03:34:42 jfch Exp $ */
 +/*
@@ -1949,9 +1862,9 @@ diff -up openssh-5.9p0/ldapincludes.h.ldap openssh-5.9p0/ldapincludes.h
 +#endif
 +
 +#endif /* LDAPINCLUDES_H */
-diff -up openssh-5.9p0/ldapmisc.c.ldap openssh-5.9p0/ldapmisc.c
---- openssh-5.9p0/ldapmisc.c.ldap	2011-08-30 15:57:13.429148896 +0200
-+++ openssh-5.9p0/ldapmisc.c	2011-08-30 15:57:13.433150396 +0200
+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
 @@ -0,0 +1,79 @@
 +
 +#include "ldapincludes.h"
@@ -2032,9 +1945,9 @@ diff -up openssh-5.9p0/ldapmisc.c.ldap openssh-5.9p0/ldapmisc.c
 +}
 +#endif
 +
-diff -up openssh-5.9p0/ldapmisc.h.ldap openssh-5.9p0/ldapmisc.h
---- openssh-5.9p0/ldapmisc.h.ldap	2011-08-30 15:57:13.531150853 +0200
-+++ openssh-5.9p0/ldapmisc.h	2011-08-30 15:57:13.537153831 +0200
+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
 @@ -0,0 +1,35 @@
 +/* $OpenBSD: ldapbody.h,v 1.1 2009/12/03 03:34:42 jfch Exp $ */
 +/*
@@ -2071,9 +1984,106 @@ diff -up openssh-5.9p0/ldapmisc.h.ldap openssh-5.9p0/ldapmisc.h
 +
 +#endif /* LDAPMISC_H */
 +
-diff -up openssh-5.9p0/openssh-lpk-openldap.schema.ldap openssh-5.9p0/openssh-lpk-openldap.schema
---- openssh-5.9p0/openssh-lpk-openldap.schema.ldap	2011-08-30 15:57:13.607025841 +0200
-+++ openssh-5.9p0/openssh-lpk-openldap.schema	2011-08-30 15:57:13.612150461 +0200
+diff -up openssh-6.2p1/Makefile.in.ldap openssh-6.2p1/Makefile.in
+--- openssh-6.2p1/Makefile.in.ldap	2013-03-25 21:27:15.850247822 +0100
++++ openssh-6.2p1/Makefile.in	2013-03-25 21:27:57.356518817 +0100
+@@ -25,6 +25,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
+ PRIVSEP_PATH=@PRIVSEP_PATH@
+ SSH_PRIVSEP_USER=@SSH_PRIVSEP_USER@
+@@ -60,8 +62,9 @@ XAUTH_PATH=@XAUTH_PATH@
+ LDFLAGS=-L. -Lopenbsd-compat/ @LDFLAGS@
+ EXEEXT=@EXEEXT@
+ MANFMT=@MANFMT@
++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)
+ 
+ LIBSSH_OBJS=authfd.o authfile.o bufaux.o bufbn.o buffer.o \
+ 	canohost.o channels.o cipher.o cipher-aes.o \
+@@ -95,8 +98,8 @@ SSHDOBJS=sshd.o auth-rhosts.o auth-passw
+ 	sandbox-null.o sandbox-rlimit.o sandbox-systrace.o sandbox-darwin.o \
+ 	sandbox-seccomp-filter.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
+@@ -164,6 +167,9 @@ ssh-keysign$(EXEEXT): $(LIBCOMPAT) libss
+ 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 roaming_dummy.o
+ 	$(LD) -o $@ ssh-keyscan.o roaming_dummy.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh $(LIBS)
+ 
+@@ -266,6 +272,10 @@ install-files:
+ 	$(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
+@@ -282,6 +292,10 @@ install-files:
+ 	$(INSTALL) -m 644 sftp-server.8.out $(DESTDIR)$(mandir)/$(mansubdir)8/sftp-server.8
+ 	$(INSTALL) -m 644 ssh-keysign.8.out $(DESTDIR)$(mandir)/$(mansubdir)8/ssh-keysign.8
+ 	$(INSTALL) -m 644 ssh-pkcs11-helper.8.out $(DESTDIR)$(mandir)/$(mansubdir)8/ssh-pkcs11-helper.8
++	if test ! -z "$(INSTALL_SSH_LDAP_HELPER)" ; then \
++		$(INSTALL) -m 644 ssh-ldap-helper.8.out $(DESTDIR)$(mandir)/$(mansubdir)8/ssh-ldap-helper.8 ; \
++		$(INSTALL) -m 644 ssh-ldap.conf.5.out $(DESTDIR)$(mandir)/$(mansubdir)5/ssh-ldap.conf.5 ; \
++	fi
+ 	-rm -f $(DESTDIR)$(bindir)/slogin
+ 	ln -s ./ssh$(EXEEXT) $(DESTDIR)$(bindir)/slogin
+ 	-rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/slogin.1
+@@ -311,6 +325,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 \
+@@ -368,6 +389,8 @@ uninstall:
+ 	-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
+@@ -379,6 +402,7 @@ uninstall:
+ 	-rm -f $(DESTDIR)$(mandir)/$(mansubdir)8/sftp-server.8
+ 	-rm -f $(DESTDIR)$(mandir)/$(mansubdir)8/ssh-keysign.8
+ 	-rm -f $(DESTDIR)$(mandir)/$(mansubdir)8/ssh-pkcs11-helper.8
++	-rm -f $(DESTDIR)$(mandir)/$(mansubdir)8/ssh-ldap-helper.8
+ 	-rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/slogin.1
+ 
+ regress/modpipe$(EXEEXT): $(srcdir)/regress/modpipe.c
+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
 @@ -0,0 +1,21 @@
 +#
 +# LDAP Public Key Patch schema for use with openssh-ldappubkey
@@ -2096,9 +2106,9 @@ diff -up openssh-5.9p0/openssh-lpk-openldap.schema.ldap openssh-5.9p0/openssh-lp
 +	DESC 'MANDATORY: OpenSSH LPK objectclass'
 +	MUST ( sshPublicKey $ uid ) 
 +	)
-diff -up openssh-5.9p0/openssh-lpk-sun.schema.ldap openssh-5.9p0/openssh-lpk-sun.schema
---- openssh-5.9p0/openssh-lpk-sun.schema.ldap	2011-08-30 15:57:13.696025724 +0200
-+++ openssh-5.9p0/openssh-lpk-sun.schema	2011-08-30 15:57:13.699024704 +0200
+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
 @@ -0,0 +1,23 @@
 +#
 +# LDAP Public Key Patch schema for use with openssh-ldappubkey
@@ -2123,101 +2133,10 @@ diff -up openssh-5.9p0/openssh-lpk-sun.schema.ldap openssh-5.9p0/openssh-lpk-sun
 +	DESC 'MANDATORY: OpenSSH LPK objectclass'
 +	MUST ( sshPublicKey $ uid ) 
 +	)
-diff -up openssh-5.9p0/ssh-ldap-helper.8.ldap openssh-5.9p0/ssh-ldap-helper.8
---- openssh-5.9p0/ssh-ldap-helper.8.ldap	2011-08-30 15:57:13.772026539 +0200
-+++ openssh-5.9p0/ssh-ldap-helper.8	2011-08-30 15:57:13.778026299 +0200
-@@ -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 at redhat.com
-diff -up openssh-5.9p0/ssh-ldap-wrapper.ldap openssh-5.9p0/ssh-ldap-wrapper
---- openssh-5.9p0/ssh-ldap-wrapper.ldap	2011-08-30 15:57:13.854024986 +0200
-+++ openssh-5.9p0/ssh-ldap-wrapper	2011-08-30 15:57:13.858149926 +0200
-@@ -0,0 +1,4 @@
-+#!/bin/sh
-+
-+exec /usr/libexec/openssh/ssh-ldap-helper -s "$1"
-+
-diff -up openssh-5.9p0/ssh-ldap.conf.5.ldap openssh-5.9p0/ssh-ldap.conf.5
---- openssh-5.9p0/ssh-ldap.conf.5.ldap	2011-08-30 15:57:13.934151066 +0200
-+++ openssh-5.9p0/ssh-ldap.conf.5	2011-08-30 15:57:13.942024641 +0200
-@@ -0,0 +1,376 @@
+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
+@@ -0,0 +1,379 @@
 +.\" $OpenBSD: ssh-ldap.conf.5,v 1.1 2010/02/10 23:20:38 markus Exp $
 +.\"
 +.\" Copyright (c) 2010 Jan F. Chadima.  All rights reserved.
@@ -2578,6 +2497,9 @@ diff -up openssh-5.9p0/ssh-ldap.conf.5.ldap openssh-5.9p0/ssh-ldap.conf.5
 +.It Cm SSH_Filter
 +Specifies the user filter applied on the LDAP serch.
 +The default is no filter.
++.It Cm AccountClass
++Specifies the LDAP class used to find user accounts.
++The default is posixAccount.
 +.El
 +.Sh FILES
 +.Bl -tag -width Ds
@@ -2594,3 +2516,94 @@ diff -up openssh-5.9p0/ssh-ldap.conf.5.ldap openssh-5.9p0/ssh-ldap.conf.5
 +OpenSSH 5.5 + PKA-LDAP .
 +.Sh AUTHORS
 +.An Jan F. Chadima Aq jchadima at 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 at 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"
++
================================================================

---- gitweb:

http://git.pld-linux.org/gitweb.cgi/packages/openssh.git/commitdiff/11890360648d1fc5e0efc7048671efe7aed02f9c



More information about the pld-cvs-commit mailing list