]> git.ipfire.org Git - ipfire-3.x.git/commitdiff
pam_ldap: Update to 186.
authorStefan Schantl <stefan.schantl@ipfire.org>
Sun, 19 Jun 2011 19:47:02 +0000 (21:47 +0200)
committerStefan Schantl <stefan.schantl@ipfire.org>
Sun, 19 Jun 2011 19:47:44 +0000 (21:47 +0200)
Fixes #209.

pkgs/pam_ldap/pam_ldap.nm
pkgs/pam_ldap/patches/pam_ldap-176-authenticateOnChangeExpiredAuthtok.patch [new file with mode: 0644]
pkgs/pam_ldap/patches/pam_ldap-176-exop-modify.patch [new file with mode: 0644]
pkgs/pam_ldap/patches/pam_ldap-180-install-perms.patch [new file with mode: 0644]
pkgs/pam_ldap/patches/pam_ldap-182-manpointer.patch [new file with mode: 0644]
pkgs/pam_ldap/patches/pam_ldap-183-releaseconfig.patch [new file with mode: 0644]
pkgs/pam_ldap/patches/pam_ldap-184-nsrole.patch [new file with mode: 0644]
pkgs/pam_ldap/patches/pam_ldap-185-dnsconfig.patch [new file with mode: 0644]
pkgs/pam_ldap/patches/pam_ldap-185-expiration4.patch [new file with mode: 0644]

index d3683468b98fff6cb3099363795fa655e7902d19..f12b7275eee3d325341d339e6a69e238e6d547cd 100644 (file)
@@ -25,7 +25,7 @@
 include $(PKGROOT)/Include
 
 PKG_NAME       = pam_ldap
-PKG_VER        = 184
+PKG_VER        = 186
 PKG_REL        = 1
 
 PKG_MAINTAINER =
@@ -34,7 +34,7 @@ PKG_URL        = http://www.padl.com/OSS/pam_ldap.html
 PKG_LICENSE    = GPL and LGPL
 PKG_SUMMARY    = A pam/ldap module that supports password changes.
 
-PKG_BUILD_DEPS+= openldap-devel pam-devel
+PKG_BUILD_DEPS+= autoconf automake openldap-devel pam-devel
 
 define PKG_DESCRIPTION
        The pam_ldap module provides the means for Solaris and Linux servers \
@@ -42,9 +42,54 @@ define PKG_DESCRIPTION
        change their passwords in the directory.
 endef
 
+# Always change this if the nss_ldap package has been updated!
+NSS_LDAP_VER = 265
+
 PKG_TARBALL    = $(THISAPP).tar.gz
+PKG_OBJECTS += nss_ldap-$(NSS_LDAP_VER).tar.gz
 
 CONFIGURE_OPTIONS += \
        --sysconfdir=/etc \
        --libdir=/lib \
-       --mandir=/usr/share/man
+       --mandir=/usr/share/man \
+       --with-ldap-conf-file=/etc/pam_ldap.conf \
+       --with-ldap-secret-file=/etc/pam_ldap.secret
+
+define STAGE_PREPARE_CMDS
+       # Extract source tarball of nss_ldap
+       cd $(DIR_SRC) && $(DO_EXTRACT) $(DIR_DL)/nss_ldap-$(NSS_LDAP_VER).tar.gz
+       
+       # Copy needed files from nss_ldap
+       cd $(DIR_APP) && cp -av $(DIR_SRC)/nss_ldap-$(NSS_LDAP_VER)/resolve.c .
+       cd $(DIR_APP) && cp -av $(DIR_SRC)/nss_ldap-$(NSS_LDAP_VER)/resolve.h .
+       cd $(DIR_APP) && cp -av $(DIR_SRC)/nss_ldap-$(NSS_LDAP_VER)/snprintf.c .
+       cd $(DIR_APP) && cp -av $(DIR_SRC)/nss_ldap-$(NSS_LDAP_VER)/snprintf.h .
+       
+       cd $(DIR_APP) && sed -i -e 's,^ldap.conf$$,pam_ldap.conf,g' *.5
+       cd $(DIR_APP) && sed -i -e 's,^/etc/ldap\.,/etc/pam_ldap.,g' *.5
+       cd $(DIR_APP) && sed -i -e 's,in ldap.co$nf,in pam_ldap.conf,g' *.5
+       cd $(DIR_APP) && sed -i -e 's,of ldap.conf,of pam_ldap.conf,g' *.5
+       cd $(DIR_APP) && sed -i -e 's,ldap.secret,pam_ldap.secret,g' *.5
+       cd $(DIR_APP) && sed -i -e 's,(ldap.conf),(pam_ldap.conf),g' *.5
+
+       cd $(DIR_APP) && autoreconf -f -i
+endef
+
+STAGE_BUILD_TARGETS += LDFLAGS="-Wl,-z,nodelete"
+
+define STAGE_INSTALL
+       # Create directory layout 
+       mkdir -pv $(BUILDROOT)/{etc,/lib/security,/usr/lib}
+
+       # Prevent to install an ldap.conf
+       touch $(BUILDROOT)/etc/ldap.conf
+       cd $(DIR_APP) && make install DESTDIR=$(BUILDROOT)
+       rm -rvf $(BUILDROOT)/etc/ldap.conf
+       
+       # Install the default configuration file and change padl to example
+       cd $(DIR_APP) && sed 's|dc=padl|dc=example|g' ldap.conf > $(BUILDROOT)/etc/pam_ldap.conf
+       chmod 644 $(BUILDROOT)/etc/pam_ldap.conf
+
+       # Create an empty ldap.secret file
+       touch $(BUILDROOT)/etc/pam_ldap.secret
+endef
diff --git a/pkgs/pam_ldap/patches/pam_ldap-176-authenticateOnChangeExpiredAuthtok.patch b/pkgs/pam_ldap/patches/pam_ldap-176-authenticateOnChangeExpiredAuthtok.patch
new file mode 100644 (file)
index 0000000..009326f
--- /dev/null
@@ -0,0 +1,11 @@
+--- pam_ldap-176/pam_ldap.c    2011-01-06 07:37:12.000000000 -0800
++++ pam_ldap-176/pam_ldap.c    2011-01-06 07:38:59.000000000 -0800
+@@ -3415,7 +3415,7 @@
+       if (rc != PAM_SUCCESS)
+       return rc;
+-      if (!(session->conf->rootbinddn && getuid () == 0))
++      if (!(session->conf->rootbinddn && getuid () == 0 && !(flags & PAM_CHANGE_EXPIRED_AUTHTOK)))
+       {
+         /* we are not root, authenticate old password */
+         if (try_first_pass || use_first_pass)
diff --git a/pkgs/pam_ldap/patches/pam_ldap-176-exop-modify.patch b/pkgs/pam_ldap/patches/pam_ldap-176-exop-modify.patch
new file mode 100644 (file)
index 0000000..3b377d3
--- /dev/null
@@ -0,0 +1,17 @@
+When deciding whether or not to try to use ldap_modify to change the user's
+password, skip it if we're in "pam_password exop_send_old", just as we would
+for "pam_password exop".  Upstream #321.
+
+diff -up pam_ldap-176/pam_ldap.c pam_ldap-176/pam_ldap.c
+--- pam_ldap-176/pam_ldap.c    2007-10-04 10:07:32.000000000 -0400
++++ pam_ldap-176/pam_ldap.c    2007-10-04 10:07:40.000000000 -0400
+@@ -3025,7 +3025,8 @@ _update_authtok (pam_handle_t *pamh,
+       break;
+     }                         /* end switch */
+-  if (session->conf->password_type != PASSWORD_EXOP)
++  if ((session->conf->password_type != PASSWORD_EXOP) &&
++      (session->conf->password_type != PASSWORD_EXOP_SEND_OLD))
+     {
+       rc = ldap_modify_s (session->ld, session->info->userdn, mods);
+       if (rc != LDAP_SUCCESS)
diff --git a/pkgs/pam_ldap/patches/pam_ldap-180-install-perms.patch b/pkgs/pam_ldap/patches/pam_ldap-180-install-perms.patch
new file mode 100644 (file)
index 0000000..92926b9
--- /dev/null
@@ -0,0 +1,18 @@
+--- pam_ldap-180/Makefile.am   2006-01-11 14:52:17.000000000 -0500
++++ pam_ldap-180/Makefile.am   2006-01-11 14:52:11.000000000 -0500
+@@ -23,12 +23,12 @@
+       @$(NORMAL_INSTALL)
+       $(mkinstalldirs) $(DESTDIR)$(libdir)/security
+ if EXTENSION_SO
+-      $(INSTALL_PROGRAM) -o root -g root pam_ldap.so $(DESTDIR)$(libdir)/security/pam_ldap.so
++      $(INSTALL_PROGRAM) pam_ldap.so $(DESTDIR)$(libdir)/security/pam_ldap.so
+ else
+ if EXTENSION_1
+-      $(INSTALL_PROGRAM) -o root -g root pam_ldap.so $(DESTDIR)$(libdir)/security/libpam_ldap.1
++      $(INSTALL_PROGRAM) pam_ldap.so $(DESTDIR)$(libdir)/security/libpam_ldap.1
+ else
+-      $(INSTALL_PROGRAM) -o root -g root pam_ldap.so $(DESTDIR)$(libdir)/security/pam_ldap.so.1
++      $(INSTALL_PROGRAM) pam_ldap.so $(DESTDIR)$(libdir)/security/pam_ldap.so.1
+       (cd $(DESTDIR)$(libdir)/security; rm -f pam_ldap.so; ln -s pam_ldap.so.1 pam_ldap.so)
+ endif
+ endif
diff --git a/pkgs/pam_ldap/patches/pam_ldap-182-manpointer.patch b/pkgs/pam_ldap/patches/pam_ldap-182-manpointer.patch
new file mode 100644 (file)
index 0000000..8144d05
--- /dev/null
@@ -0,0 +1,14 @@
+Give people a pointer to the pam_ldap man page, because the name of this file
+actually has changed over time.
+
+--- pam_ldap/ldap.conf 2006-07-25 17:16:11.000000000 -0400
++++ pam_ldap/ldap.conf 2006-07-25 17:16:06.000000000 -0400
+@@ -3,6 +3,8 @@
+ # This is the configuration file for the LDAP nameservice
+ # switch library and the LDAP PAM module.
+ #
++# The man page for this file is pam_ldap(5)
++#
+ # PADL Software
+ # http://www.padl.com
+ #
diff --git a/pkgs/pam_ldap/patches/pam_ldap-183-releaseconfig.patch b/pkgs/pam_ldap/patches/pam_ldap-183-releaseconfig.patch
new file mode 100644 (file)
index 0000000..beb336e
--- /dev/null
@@ -0,0 +1,77 @@
+Fix a memory leak at cleanup-time.
+
+diff -up pam_ldap/pam_ldap.c pam_ldap/pam_ldap.c
+--- pam_ldap/pam_ldap.c        2009-07-22 15:55:42.000000000 -0400
++++ pam_ldap/pam_ldap.c        2009-07-22 16:00:23.000000000 -0400
+@@ -437,6 +437,7 @@ static void
+ _release_config (pam_ldap_config_t ** pconfig)
+ {
+   pam_ldap_config_t *c;
++  pam_ssd_t *ssd, *next_ssd;
+   c = *pconfig;
+   if (c == NULL)
+@@ -445,6 +446,9 @@ _release_config (pam_ldap_config_t ** pc
+   if (c->configFile != NULL)
+     free (c->configFile);
++  if (c->uri != NULL)
++    free (c->uri);
++
+   if (c->host != NULL)
+     free (c->host);
+@@ -474,6 +478,16 @@ _release_config (pam_ldap_config_t ** pc
+       free (c->sslpath);
+     }
++  ssd = c->ssd;
++  while ( ssd != NULL )
++    {
++      next_ssd = ssd->next;
++      free (ssd->base);
++      free (ssd->filter);
++      free (ssd);
++      ssd = next_ssd;
++    }
++
+   if (c->userattr != NULL)
+     {
+       free (c->userattr);
+@@ -509,6 +523,36 @@ _release_config (pam_ldap_config_t ** pc
+       free (c->logdir);
+     }
++  if (c->tls_cacertfile != NULL)
++    {
++      free (c->tls_cacertfile);
++    }
++
++  if (c->tls_cacertdir != NULL)
++    {
++      free (c->tls_cacertdir);
++    }
++
++  if (c->tls_ciphers != NULL)
++    {
++      free (c->tls_ciphers);
++    }
++
++  if (c->tls_cert != NULL)
++    {
++      free (c->tls_cert);
++    }
++
++  if (c->tls_key != NULL)
++    {
++      free (c->tls_key);
++    }
++
++  if (c->tls_randfile != NULL)
++    {
++      free (c->tls_randfile);
++    }
++
+   if (c->sasl_mechanism != NULL)
+     {
+       free (c->sasl_mechanism);
diff --git a/pkgs/pam_ldap/patches/pam_ldap-184-nsrole.patch b/pkgs/pam_ldap/patches/pam_ldap-184-nsrole.patch
new file mode 100644 (file)
index 0000000..29f2bb7
--- /dev/null
@@ -0,0 +1,86 @@
+Add a role check, like the existing group membership check.
+Submitted to upstream #382.
+
+diff -up pam_ldap-184/pam_ldap.5 pam_ldap-184/pam_ldap.5
+--- pam_ldap-184/pam_ldap.5    2008-11-17 13:36:03.000000000 -0500
++++ pam_ldap-184/pam_ldap.5    2008-11-17 13:37:35.000000000 -0500
+@@ -333,6 +333,10 @@ group specified in the
+ .B pam_groupdn
+ option.
+ .TP
++.B pam_nsrole <role>
++Specifies a value which the user's entry's "nsRole" attribute must match
++for logon authorization to succeed.
++.TP
+ .B pam_min_uid <uid>
+ If specified, a user must have a POSIX user ID of at least
+ .B uid
+diff -up pam_ldap-184/pam_ldap.c pam_ldap-184/pam_ldap.c
+--- pam_ldap-184/pam_ldap.c    2008-11-17 13:35:52.000000000 -0500
++++ pam_ldap-184/pam_ldap.c    2008-11-17 13:35:56.000000000 -0500
+@@ -499,6 +499,11 @@ _release_config (pam_ldap_config_t ** pc
+       free (c->groupdn);
+     }
++  if (c->nsrole != NULL)
++    {
++      free (c->nsrole);
++    }
++
+   if (c->filter != NULL)
+     {
+       free (c->filter);
+@@ -639,6 +644,7 @@ _alloc_config (pam_ldap_config_t ** pres
+   result->userattr = NULL;
+   result->groupattr = NULL;
+   result->groupdn = NULL;
++  result->nsrole = NULL;
+   result->getpolicy = 0;
+   result->checkhostattr = 0;
+   result->checkserviceattr = 0;
+@@ -1043,6 +1049,10 @@ _read_config (const char *configFile, pa
+       {
+         CHECKPOINTER (result->groupattr = strdup (v));
+       }
++      else if (!strcasecmp (k, "pam_nsrole"))
++      {
++        CHECKPOINTER (result->nsrole = strdup (v));
++      }
+       else if (!strcasecmp (k, "pam_min_uid"))
+       {
+         result->min_uid = (uid_t) atol (v);
+@@ -4136,6 +4146,23 @@ pam_sm_acct_mgmt (pam_handle_t * pamh, i
+       rc = success;
+     }
++  /* check the user's entry's nsRole attribute for the required value */
++  if (rc == success && session->conf->nsrole != NULL)
++    {
++      rc = ldap_compare_s (session->ld,
++                         session->info->userdn,
++                         "nsRole", session->conf->nsrole);
++      if (rc != LDAP_COMPARE_TRUE)
++      {
++        snprintf (buf, sizeof buf, "You must have the %s role to login.",
++                  session->conf->nsrole);
++        _conv_sendmsg (appconv, buf, PAM_ERROR_MSG, no_warn);
++        return PAM_PERM_DENIED;
++      }
++      else
++      rc = success;
++    }
++
+   if (rc == success && session->conf->checkserviceattr)
+     {
+       rc = _service_ok (pamh, session);
+--- pam_ldap-184/pam_ldap.h    2008-11-17 13:39:49.000000000 -0500
++++ pam_ldap-184/pam_ldap.h    2008-11-17 13:39:50.000000000 -0500
+@@ -95,6 +95,8 @@
+     char *groupdn;
+     /* group membership attribute; defaults to uniquemember */
+     char *groupattr;
++    /* role name; optional, for access authorization */
++    char *nsrole;
+     /* LDAP protocol version */
+     int version;
+     /* search timelimit */
diff --git a/pkgs/pam_ldap/patches/pam_ldap-185-dnsconfig.patch b/pkgs/pam_ldap/patches/pam_ldap-185-dnsconfig.patch
new file mode 100644 (file)
index 0000000..191ac5f
--- /dev/null
@@ -0,0 +1,337 @@
+--- pam_ldap-176/Makefile.am   2004-09-30 22:33:14.000000000 -0400
++++ pam_ldap-176/Makefile.am   2004-10-28 17:24:13.691936696 -0400
+@@ -2,7 +2,7 @@ noinst_PROGRAMS = pam_ldap.so
+ EXTRA_DIST = COPYING.LIB CVSVersionInfo.txt ChangeLog README \
+            ldap.conf pam.conf pam_ldap.spec pam.d
+-pam_ldap_so_SOURCES = pam_ldap.c pam_ldap.h md5.c md5.h vers.c
++pam_ldap_so_SOURCES = pam_ldap.c pam_ldap.h md5.c md5.h vers.c resolve.c resolve.h dnsconfig.c dnsconfig.h snprintf.c snprintf.h
+ pam_ldap_so_LDFLAGS = @pam_ldap_so_LDFLAGS@
+ man_MANS = pam_ldap.5
+--- pam_ldap-176/configure.in  2004-09-30 22:33:14.000000000 -0400
++++ pam_ldap-176/configure.in  2004-10-28 17:24:13.692936544 -0400
+@@ -133,6 +133,38 @@
+ AC_CHECK_FUNCS(ldap_initialize)
+ AC_CHECK_FUNCS(ldap_sasl_bind ldap_sasl_interactive_bind_s)
+ AC_CHECK_FUNCS(gethostbyname_r)
++AC_CHECK_FUNCS(snprintf strtok_r)
++AC_CHECK_LIB(resolv, main)
++AC_CHECK_HEADERS(resolv.h)
++AC_CHECK_FUNCS(res_search dn_expand)
++if test x$ac_cv_func_res_search = xno ; then
++      AC_MSG_CHECKING([for res_search again])
++      AC_TRY_LINK([#ifdef HAVE_RESOLV_H
++                   #include <resolv.h>
++                   #endif
++                   #ifdef HAVE_STDLIB_H
++                   #include <stdlib.h>
++                   #endif],
++                  [res_search(NULL,0,0,NULL,0);],
++                  AC_DEFINE(HAVE_RES_SEARCH,1,
++                            [Define if you have res_search().])
++                  ac_cv_func_res_search=yes)
++      AC_CHECK_FUNCS(res_search)
++fi
++if test x$ac_cv_func_dn_expand = xno ; then
++      AC_MSG_CHECKING([for dn_expand again])
++      AC_TRY_LINK([#ifdef HAVE_RESOLV_H
++                   #include <resolv.h>
++                   #endif
++                   #ifdef HAVE_STDLIB_H
++                   #include <stdlib.h>
++                   #endif],
++                  [dn_expand(NULL,NULL,NULL,NULL,0);],
++                  AC_DEFINE(HAVE_DN_EXPAND,1,
++                            [Define if you have dn_expand().])
++                  ac_cv_func_dn_expand=yes)
++      AC_CHECK_FUNCS(dn_expand)
++fi
+ if test "$ac_cv_func_gethostbyname_r" = "yes"; then
+ AC_CACHE_CHECK(whether gethostbyname_r takes 6 arguments, xad_cv_gethostbyname_r_args, [
+--- /dev/null  2004-10-19 17:45:17.794252000 -0400
++++ pam_ldap-176/dnsconfig.c   2004-10-28 17:32:36.915435096 -0400
+@@ -0,0 +1,214 @@
++
++/* Copyright (C) 1997-2001 Luke Howard.
++   This file started off as part of the nss_ldap library.
++   Contributed by Luke Howard, <lukeh@padl.com>, 1997.
++   (The author maintains a non-exclusive licence to distribute this file
++   under their own conditions.)
++
++   The nss_ldap library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Library General Public License as
++   published by the Free Software Foundation; either version 2 of the
++   License, or (at your option) any later version.
++
++   The nss_ldap library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Library General Public License for more details.
++
++   You should have received a copy of the GNU Library General Public
++   License along with the nss_ldap library; see the file COPYING.LIB.  If not,
++   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
++   Boston, MA 02111-1307, USA.
++ */
++
++/*
++ * Support DNS SRV records. I look up the SRV record for
++ * _ldap._tcp.gnu.org.
++ * and build the DN DC=gnu,DC=org.
++ * Thanks to Assar & co for resolve.[ch].
++ */
++
++static char rcsId[] = "$Id: dnsconfig.c,v 2.24 2001/02/27 14:44:31 lukeh Exp $";
++
++#include "config.h"
++
++#include <stdio.h>
++#include <string.h>
++#include <stdlib.h>
++#include <sys/param.h>
++#include <netdb.h>
++#include <syslog.h>
++#include <netinet/in.h>
++#include <arpa/nameser.h>
++#include <resolv.h>
++#include <string.h>
++
++#ifdef HAVE_LBER_H
++#include <lber.h>
++#endif
++#ifdef HAVE_LDAP_H
++#include <ldap.h>
++#endif
++
++#ifndef HAVE_SNPRINTF
++#include "snprintf.h"
++#endif
++
++#include "pam_ldap.h"
++#include "resolve.h"
++#include "dnsconfig.h"
++
++#define DC_ATTR "DC"
++#define DC_ATTR_AVA DC_ATTR "="
++#define DC_ATTR_AVA_LEN (sizeof(DC_ATTR_AVA) - 1)
++
++/* map gnu.org into DC=gnu,DC=org */
++int
++_pam_ldap_getdnsdn (char *src_domain, char **rval)
++{
++  char *p;
++  int len = 0;
++#ifdef HAVE_STRTOK_R
++  char *st = NULL;
++#endif
++  char *domain;
++  char domain_copy[BUFSIZ], buffer[BUFSIZ];
++
++  /* we need to take a copy of domain, because strtok() modifies
++   * it in place. Bad.
++   */
++  if (strlen (src_domain) >= sizeof (domain_copy))
++    {
++      return PAM_SYSTEM_ERR;
++    }
++  memset (domain_copy, '\0', sizeof (domain_copy));
++  memset (buffer, '\0', sizeof (buffer));
++  strcpy (domain_copy, src_domain);
++
++  domain = domain_copy;
++
++#ifndef HAVE_STRTOK_R
++  while ((p = strtok (domain, ".")))
++#else
++  while ((p = strtok_r (domain, ".", &st)))
++#endif
++    {
++      len = strlen (p);
++
++      if (strlen (buffer) + DC_ATTR_AVA_LEN + len + 1 >= sizeof (buffer))
++      {
++        return PAM_SYSTEM_ERR;
++      }
++
++      if (domain == NULL)
++      {
++        strcat (buffer, ",");
++      }
++      else
++      {
++        domain = NULL;
++      }
++
++      strcat (buffer, DC_ATTR_AVA);
++      strcat (buffer, p);
++    }
++
++  if (rval != NULL)
++    {
++      *rval = strdup (buffer);
++    }
++
++  return PAM_SUCCESS;
++}
++
++
++int
++_pam_ldap_readconfigfromdns (pam_ldap_config_t * result)
++{
++  int stat = PAM_SUCCESS;
++  struct dns_reply *r;
++  struct resource_record *rr;
++  char domain[MAXHOSTNAMELEN + 1];
++
++  /* only reinitialize variables we'll change here */
++  result->host = NULL;
++  result->base = NULL;
++  result->port = LDAP_PORT;
++#ifdef LDAP_VERSION3
++  result->version = LDAP_VERSION3;
++#else
++  result->version = LDAP_VERSION2;
++#endif /* LDAP_VERSION3 */
++
++  if ((_res.options & RES_INIT) == 0 && res_init () == -1)
++    {
++      return PAM_SYSTEM_ERR;
++    }
++
++  snprintf (domain, sizeof (domain), "_ldap._tcp.%s.", _res.defdname);
++
++  r = dns_lookup (domain, "srv");
++  if (r == NULL)
++    {
++      return PAM_SYSTEM_ERR;
++    }
++
++  /* XXX need to sort by priority and reorder using weights */
++  for (rr = r->head; rr != NULL; rr = rr->next)
++    {
++      if (rr->type == T_SRV)
++      {
++        if (result->host != NULL)
++          {
++            /* need more space */
++            int length;
++            char *tmp;
++            length = strlen (result->host) + 1 +
++                     strlen (rr->u.srv->target) + 1 + 5 + 1;
++            tmp = malloc (length);
++            if (tmp == NULL)
++              {
++                dns_free_data (r);
++                return PAM_BUF_ERR;
++              }
++            sprintf (tmp, "%s %s:%d", result->host, rr->u.srv->target,
++                     rr->u.srv->port);
++            free (result->host);
++            result->host = tmp;
++          }
++        else
++          {
++            /* Server Host */
++            result->host = strdup (rr->u.srv->target);
++            if (result->host == NULL)
++              {
++                dns_free_data (r);
++                return PAM_BUF_ERR;
++              }
++            /* Port */
++            result->port = rr->u.srv->port;
++          }
++
++#ifdef LDAPS_PORT
++        /* Hack: if the port is the registered SSL port, enable SSL. */
++        if (result->port == LDAPS_PORT)
++          {
++            result->ssl_on = SSL_LDAPS;
++          }
++#endif /* SSL */
++
++        /* DN */
++        stat = _pam_ldap_getdnsdn (_res.defdname, &result->base);
++        if (stat != PAM_SUCCESS)
++          {
++            dns_free_data (r);
++            return stat;
++          }
++      }
++    }
++
++  dns_free_data (r);
++  stat = PAM_SUCCESS;
++
++  return stat;
++}
+--- /dev/null  2004-10-19 17:45:17.794252000 -0400
++++ pam_ldap-176/dnsconfig.h   2004-10-28 17:24:13.694936240 -0400
+@@ -0,0 +1,35 @@
++/* Copyright (C) 1997-2001 Luke Howard.
++   This file started off as part of the nss_ldap library.
++   Contributed by Luke Howard, <lukeh@padl.com>, 1997.
++   (The author maintains a non-exclusive licence to distribute this file
++   under their own conditions.)
++
++   The nss_ldap library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Library General Public License as
++   published by the Free Software Foundation; either version 2 of the
++   License, or (at your option) any later version.
++
++   The nss_ldap library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Library General Public License for more details.
++
++   You should have received a copy of the GNU Library General Public
++   License along with the nss_ldap library; see the file COPYING.LIB.  If not,
++   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
++   Boston, MA 02111-1307, USA.
++ */
++
++#ifndef _LDAP_PAM_LDAP_DNSCONFIG_H
++#define _LDAP_PAM_LDAP_DNSCONFIG_H
++
++/* utility routines.  */
++
++int _pam_ldap_getdnsdn (
++                      char *domain,
++                      char **rval);
++
++int _pam_ldap_readconfigfromdns (
++                               pam_ldap_config_t *result);
++
++#endif /* _LDAP_PAM_LDAP_DNSCONFIG_H */
+--- pam_ldap-176/pam_ldap.c    2004-09-30 22:33:14.000000000 -0400
++++ pam_ldap-176/pam_ldap.c    2004-10-28 17:40:56.918423088 -0400
+@@ -130,6 +130,7 @@
+ #include "pam_ldap.h"
+ #include "md5.h"
++#include "dnsconfig.h"
+ #if defined(HAVE_SECURITY_PAM_MISC_H) || defined(HAVE_PAM_PAM_MISC_H)
+  /* FIXME: is there something better to check? */
+@@ -1107,11 +1108,15 @@
+     {
+       /* 
+        * According to PAM Documentation, such an error in a config file
+-       * SHOULD be logged at LOG_ALERT level
++       * SHOULD be logged at LOG_ALERT level, but we suppress it if DNS
++       * can provide us with the needed information
+        */
+-      syslog (LOG_ALERT, "pam_ldap: missing \"host\" in file \"%s\"",
+-            configFile);
+-      return PAM_SERVICE_ERR;
++      if (_pam_ldap_readconfigfromdns (result) != PAM_SUCCESS)
++        {
++          syslog (LOG_ALERT, "pam_ldap: missing \"host\" in file \"%s\"",
++                configFile);
++          return PAM_SERVICE_ERR;
++        }
+     }
+ #if !(defined(HAVE_SASL_SASL_H) || defined(HAVE_SASL_H)) && !defined(HAVE_LDAP_SASL_INTERACTIVE_BIND_S)
diff --git a/pkgs/pam_ldap/patches/pam_ldap-185-expiration4.patch b/pkgs/pam_ldap/patches/pam_ldap-185-expiration4.patch
new file mode 100644 (file)
index 0000000..ac71f70
--- /dev/null
@@ -0,0 +1,61 @@
+Heavily based on a patch from Masahiro Matsuya.
+
+diff -up pam_ldap-185/pam_ldap.c pam_ldap-185/pam_ldap.c
+--- pam_ldap-185/pam_ldap.c    2010-09-22 18:35:55.377828002 -0400
++++ pam_ldap-185/pam_ldap.c    2010-09-22 19:08:34.938828001 -0400
+@@ -4014,6 +4014,8 @@ pam_sm_acct_mgmt (pam_handle_t * pamh, i
+   time_t currenttime;
+   long int currentday;
+   long int expirein = 0;      /* seconds until password expires */
++  long int expireh = 0;
++  long int expires = 0;
+   const char *configFile = NULL;
+   for (i = 0; i < argc; i++)
+@@ -4190,14 +4191,29 @@ pam_sm_acct_mgmt (pam_handle_t * pamh, i
+       }
+       else
+       {
+-        expirein = session->info->password_expiration_time / SECSPERDAY;
++          if ( session->info->password_expiration_time != 0 )
++            {
++             expires = session->info->password_expiration_time;
++            expirein = session->info->password_expiration_time / SECSPERDAY;
++              if ( expirein == 0 )
++                {
++                  expireh = session->info->password_expiration_time / SECSPERHOUR;
++                }
++            }
++          else
++            {
++              expirein = 0;
++            }
+       }
+-      if (expirein > 0)
++      if ((expirein > 0) || (expireh > 0) || (expires > 0))
+       {
+         snprintf (buf, sizeof buf,
+-                  "Your LDAP password will expire in %ld day%s.",
+-                  expirein, (expirein == 1) ? "" : "s");
++                  "Your LDAP password will expire in %ld %s.",
++                  (expirein == 0) ? expireh : expirein,
++                  (expirein == 0) ?
++                  ((expireh == 1) ? "hour" : "hours") :
++                  ((expirein == 1) ? "day" : "days"));
+         _conv_sendmsg (appconv, buf, PAM_ERROR_MSG, no_warn);
+         /* we set this to make sure that user can't abort a password change */
+diff -up pam_ldap-185/pam_ldap.h pam_ldap-185/pam_ldap.h
+--- pam_ldap-185/pam_ldap.h    2010-09-22 18:35:55.359828002 -0400
++++ pam_ldap-185/pam_ldap.h    2010-09-22 19:00:56.787828000 -0400
+@@ -226,6 +226,9 @@ pam_ldap_shadow_t;
+ /* Seconds in a day */
+ #define SECSPERDAY 86400
++/* Seconds in an hour */
++#define SECSPERHOUR 3600
++
+ /* Netscape per-use password attributes. Unused except for DN. */
+ typedef struct pam_ldap_user_info
+   {