]> git.pld-linux.org Git - packages/openssh.git/commitdiff
updated rebased ldap patch from fedora (adds AccountClass ldap.conf param)
authorElan Ruusamäe <glen@delfi.ee>
Sat, 2 Nov 2013 15:09:00 +0000 (17:09 +0200)
committerElan Ruusamäe <glen@delfi.ee>
Sat, 2 Nov 2013 15:09:00 +0000 (17:09 +0200)
openssh-ldap.patch

index 0961124aea215acbafdf5aa361f73acc1291bb5d..994ef59a43af613ac34fc3a0d739ca024bea8a8a 100644 (file)
@@ -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@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@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@redhat.com
+diff -up openssh-6.2p1/ssh-ldap-helper.8.ldap openssh-6.2p1/ssh-ldap-helper.8
+--- openssh-6.2p1/ssh-ldap-helper.8.ldap       2013-03-25 21:27:15.895248117 +0100
++++ openssh-6.2p1/ssh-ldap-helper.8    2013-03-25 21:27:15.895248117 +0100
+@@ -0,0 +1,79 @@
++.\" $OpenBSD: ssh-ldap-helper.8,v 1.1 2010/02/10 23:20:38 markus Exp $
++.\"
++.\" Copyright (c) 2010 Jan F. Chadima.  All rights reserved.
++.\"
++.\" Permission to use, copy, modify, and distribute this software for any
++.\" purpose with or without fee is hereby granted, provided that the above
++.\" copyright notice and this permission notice appear in all copies.
++.\"
++.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
++.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
++.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
++.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++.\"
++.Dd $Mdocdate: April 29 2010 $
++.Dt SSH-LDAP-HELPER 8
++.Os
++.Sh NAME
++.Nm ssh-ldap-helper
++.Nd sshd helper program for ldap support
++.Sh SYNOPSIS
++.Nm ssh-ldap-helper
++.Op Fl devw
++.Op Fl f Ar file
++.Op Fl s Ar user
++.Sh DESCRIPTION
++.Nm
++is used by
++.Xr sshd 1
++to access keys provided by an LDAP.
++.Nm
++is disabled by default and can only be enabled in the
++sshd configuration file
++.Pa /etc/ssh/sshd_config
++by setting
++.Cm AuthorizedKeysCommand
++to
++.Dq /usr/libexec/ssh-ldap-wrapper .
++.Pp
++.Nm
++is not intended to be invoked by the user, but from
++.Xr sshd 8 via
++.Xr ssh-ldap-wrapper .
++.Pp
++The options are as follows:
++.Bl -tag -width Ds
++.It Fl d
++Set the debug mode; 
++.Nm
++prints all logs to stderr instead of syslog.
++.It Fl e
++Implies \-w;
++.Nm
++halts if it encounters an unknown item in the ldap.conf file.
++.It Fl f
++.Nm
++uses this file as the ldap configuration file instead of /etc/ssh/ldap.conf (default).
++.It Fl s
++.Nm
++prints out the user's keys to stdout and exits.
++.It Fl v
++Implies \-d;
++increases verbosity.
++.It Fl w
++.Nm
++writes warnings about unknown items in the ldap.conf configuration file.
++.El
++.Sh SEE ALSO
++.Xr sshd 8 ,
++.Xr sshd_config 5 ,
++.Xr ssh-ldap.conf 5 ,
++.Sh HISTORY
++.Nm
++first appeared in
++OpenSSH 5.5 + PKA-LDAP .
++.Sh AUTHORS
++.An Jan F. Chadima Aq jchadima@redhat.com
+diff -up openssh-6.2p1/ssh-ldap-wrapper.ldap openssh-6.2p1/ssh-ldap-wrapper
+--- openssh-6.2p1/ssh-ldap-wrapper.ldap        2013-03-25 21:27:15.896248124 +0100
++++ openssh-6.2p1/ssh-ldap-wrapper     2013-03-25 21:27:15.896248124 +0100
+@@ -0,0 +1,4 @@
++#!/bin/sh
++
++exec /usr/libexec/openssh/ssh-ldap-helper -s "$1"
++
This page took 0.863352 seconds and 4 git commands to generate.