[nss_ldap/f13/master] - add proposed patch for avoiding recursion-until-death while resolving hosts - take another stab at
Nalin Dahyabhai
nalin at fedoraproject.org
Fri Aug 20 19:09:40 UTC 2010
commit be06ad2bcca1a4ebb037a408bd63ac15faf929cf
Author: Nalin Dahyabhai <nalin at redhat.com>
Date: Thu Aug 19 19:18:48 2010 -0400
- add proposed patch for avoiding recursion-until-death while resolving hosts
- take another stab at implementing a working nss_initgroups_minimum_uid
setting, and default it to 500
- add proposed patch for upstream #421: sometimes errno gets reset before we
return control to libc
nss_ldap-264-depth.patch | 186 +++++++++++++++++++++++++++++
nss_ldap-264-initgroups-minimum_uid.patch | 177 +++++++++++++++++++++++++++
nss_ldap-265-erange.patch | 17 +++
nss_ldap.spec | 18 +++-
pam_ldap-185-initgroups-minimum_uid.patch | 17 +++
5 files changed, 413 insertions(+), 2 deletions(-)
---
diff --git a/nss_ldap-264-depth.patch b/nss_ldap-264-depth.patch
new file mode 100644
index 0000000..9d6e6d6
--- /dev/null
+++ b/nss_ldap-264-depth.patch
@@ -0,0 +1,186 @@
+Check if we can use thread-local storage, and if we can, use one to avoid a
+self-deadlock if we recurse into our own host resolution routines from inside
+of another lookup attempt.
+
+diff -up nss_ldap-265/config.h.in nss_ldap-265/config.h.in
+--- nss_ldap-265/config.h.in 2009-11-06 05:28:08.000000000 -0500
++++ nss_ldap-265/config.h.in 2010-01-08 17:29:49.000000000 -0500
+@@ -304,6 +304,11 @@
+ /* Define to 1 if you have the <thread.h> header file. */
+ #undef HAVE_THREAD_H
+
++/* Define if your toolchain supports thread-local storage, which can be used
++ for detecting self- and mutual-recursion problems when performing
++ host/address lookups. */
++#undef HAVE_THREAD_LOCAL_STORAGE
++
+ /* Define to 1 if you have the <unistd.h> header file. */
+ #undef HAVE_UNISTD_H
+
+diff -up nss_ldap-265/configure.in nss_ldap-265/configure.in
+--- nss_ldap-265/configure.in 2009-11-06 05:28:08.000000000 -0500
++++ nss_ldap-265/configure.in 2010-01-08 17:29:49.000000000 -0500
+@@ -27,6 +27,14 @@ dnl
+
+ AC_ARG_ENABLE(debugging, [ --enable-debugging enable debug code ], [AC_DEFINE(DEBUG)])
+
++AC_MSG_CHECKING(for thread-local storage)
++AC_TRY_COMPILE([],[static __thread int _nss_ldap_recursion_count;],
++ [
++ AC_MSG_RESULT(yes)
++ AC_DEFINE(HAVE_THREAD_LOCAL_STORAGE,1,[Define if your toolchain supports thread-local storage, which can be used for detecting self- and mutual-recursion problems when performing host/address lookups.])
++ ],
++ AC_MSG_RESULT(no))
++
+ dnl
+ dnl --enable-paged-results is now deprecated; if this option is set,
+ dnl then paged results will be enabled by default. However, it can
+diff -up nss_ldap-265/depth.c nss_ldap-265/depth.c
+--- nss_ldap-265/depth.c 2010-01-08 17:29:49.000000000 -0500
++++ nss_ldap-265/depth.c 2010-01-08 17:29:49.000000000 -0500
+@@ -0,0 +1,24 @@
++#include "config.h"
++#include "depth.h"
++
++#ifdef HAVE_THREAD_LOCAL_STORAGE
++static __thread int depth = 0;
++
++int
++_nss_ldap_get_depth (void)
++{
++ return depth;
++}
++
++int
++_nss_ldap_inc_depth (void)
++{
++ return ++depth;
++}
++
++int
++_nss_ldap_dec_depth (void)
++{
++ return --depth;
++}
++#endif
+diff -up nss_ldap-265/depth.h nss_ldap-265/depth.h
+--- nss_ldap-265/depth.h 2010-01-08 17:29:49.000000000 -0500
++++ nss_ldap-265/depth.h 2010-01-08 17:29:49.000000000 -0500
+@@ -0,0 +1,3 @@
++int _nss_ldap_get_depth (void);
++int _nss_ldap_inc_depth (void);
++int _nss_ldap_dec_depth (void);
+diff -up nss_ldap-265/ldap-hosts.c nss_ldap-265/ldap-hosts.c
+--- nss_ldap-265/ldap-hosts.c 2009-11-06 05:28:08.000000000 -0500
++++ nss_ldap-265/ldap-hosts.c 2010-01-08 17:33:38.000000000 -0500
+@@ -66,6 +66,7 @@ static char rcsId[] =
+ #include "ldap-nss.h"
+ #include "ldap-hosts.h"
+ #include "util.h"
++#include "depth.h"
+
+ #ifdef HAVE_PORT_AFTER_H
+ #include <port_after.h>
+@@ -280,6 +281,11 @@ _nss_ldap_gethostbyname2_r (const char *
+ }
+ #endif
+
++#ifdef HAVE_THREAD_LOCAL_STORAGE
++ if (_nss_ldap_get_depth() > 0)
++ return NSS_STATUS_UNAVAIL;
++#endif
++
+ LA_INIT (a);
+ LA_STRING (a) = name;
+ LA_TYPE (a) = LA_TYPE_STRING;
+@@ -355,6 +361,11 @@ _nss_ldap_gethostbyaddr_r (struct in_add
+ NSS_STATUS status;
+ ldap_args_t a;
+
++#ifdef HAVE_THREAD_LOCAL_STORAGE
++ if (_nss_ldap_get_depth() > 0)
++ return NSS_STATUS_UNAVAIL;
++#endif
++
+ /* if querying by IPv6 address, make sure the address is "normalized" --
+ * it should contain no leading zeros and all components of the address.
+ * still we can't fit an IPv6 address in an int, so who cares for now.
+@@ -391,6 +402,11 @@ _nss_ldap_sethostent_r (nss_backend_t *
+ #endif
+ #if defined(HAVE_NSS_H) || defined(HAVE_NSSWITCH_H)
+ {
++#ifdef HAVE_THREAD_LOCAL_STORAGE
++ if (_nss_ldap_get_depth() > 0)
++ return NSS_STATUS_UNAVAIL;
++#endif
++
+ LOOKUP_SETENT (hosts_context);
+ }
+ #endif
+@@ -403,6 +419,11 @@ _nss_ldap_endhostent_r (nss_backend_t *
+ #endif
+ #if defined(HAVE_NSS_H) || defined(HAVE_NSSWITCH_H)
+ {
++#ifdef HAVE_THREAD_LOCAL_STORAGE
++ if (_nss_ldap_get_depth() > 0)
++ return NSS_STATUS_UNAVAIL;
++#endif
++
+ LOOKUP_ENDENT (hosts_context);
+ }
+ #endif
+@@ -435,6 +456,11 @@ _nss_ldap_gethostent_r (struct hostent *
+ {
+ NSS_STATUS status;
+
++#ifdef HAVE_THREAD_LOCAL_STORAGE
++ if (_nss_ldap_get_depth() > 0)
++ return NSS_STATUS_UNAVAIL;
++#endif
++
+ status = _nss_ldap_getent (&hosts_context,
+ result,
+ buffer,
+diff -up nss_ldap-265/ldap-nss.c nss_ldap-265/ldap-nss.c
+--- nss_ldap-265/ldap-nss.c 2009-11-06 05:28:08.000000000 -0500
++++ nss_ldap-265/ldap-nss.c 2010-01-08 17:29:49.000000000 -0500
+@@ -93,6 +93,7 @@ static char rcsId[] =
+ #include "util.h"
+ #include "dnsconfig.h"
+ #include "pagectrl.h"
++#include "depth.h"
+
+ #if defined(HAVE_THREAD_H) && !defined(_AIX)
+ #ifdef HAVE_PTHREAD_ATFORK
+@@ -578,6 +579,9 @@ _nss_ldap_enter (void)
+ debug ("==> _nss_ldap_enter");
+
+ NSS_LDAP_LOCK (__lock);
++#ifdef HAVE_THREAD_LOCAL_STORAGE
++ _nss_ldap_inc_depth();
++#endif
+
+ /*
+ * Patch for Debian Bug 130006:
+@@ -623,6 +627,9 @@ _nss_ldap_leave (void)
+ }
+ #endif /* HAVE_SIGACTION */
+
++#ifdef HAVE_THREAD_LOCAL_STORAGE
++ _nss_ldap_dec_depth();
++#endif
+ NSS_LDAP_UNLOCK (__lock);
+
+ debug ("<== _nss_ldap_leave");
+diff -up nss_ldap-265/Makefile.am nss_ldap-265/Makefile.am
+--- nss_ldap-265/Makefile.am 2009-11-06 05:28:08.000000000 -0500
++++ nss_ldap-265/Makefile.am 2010-01-08 17:31:45.000000000 -0500
+@@ -23,6 +23,7 @@ nss_ldap_so_SOURCES = ldap-nss.c ldap-pw
+ ldap-alias.c ldap-service.c ldap-schema.c ldap-ethers.c \
+ ldap-bp.c ldap-automount.c util.c ltf.c snprintf.c resolve.c \
+- dnsconfig.c irs-nss.c pagectrl.c ldap-sldap.c ldap-init-krb5-cache.c
++ dnsconfig.c irs-nss.c pagectrl.c ldap-sldap.c ldap-init-krb5-cache.c \
++ depth.c
+
+ nss_ldap_so_LDFLAGS = @nss_ldap_so_LDFLAGS@
+
diff --git a/nss_ldap-264-initgroups-minimum_uid.patch b/nss_ldap-264-initgroups-minimum_uid.patch
new file mode 100644
index 0000000..d76ce43
--- /dev/null
+++ b/nss_ldap-264-initgroups-minimum_uid.patch
@@ -0,0 +1,177 @@
+This builds off of the recursion checking introduced by -depth to avoid
+a deadlock if/when we recurse into ourselves while looking up the user's
+UID to compare it to the configured value.
+
+diff -ur nss_ldap-265/ldap-nss.c nss_ldap-265-2/ldap-nss.c
+--- nss_ldap-265/ldap-nss.c 2010-08-19 17:16:51.000000000 -0400
++++ nss_ldap-265-2/ldap-nss.c 2010-08-19 17:25:09.000000000 -0400
+@@ -34,6 +34,7 @@
+ #endif
+
+ #include <assert.h>
++#include <pwd.h>
+ #include <stdlib.h>
+ #include <unistd.h>
+ #include <string.h>
+@@ -4356,20 +4357,55 @@
+ int
+ _nss_ldap_test_initgroups_ignoreuser (const char *user)
+ {
+- char **p;
++ char **p, *buf;
++ size_t buflen;
++ struct passwd pwd, *passwd;
+
+- if (__config == NULL)
+- return 0;
+-
+- if (__config->ldc_initgroups_ignoreusers == NULL)
+- return 0;
+-
+- for (p = __config->ldc_initgroups_ignoreusers; *p != NULL; p++)
++ if (__config != NULL)
+ {
+- if (strcmp (*p, user) == 0)
+- return 1;
++ if (__config->ldc_initgroups_ignoreusers != NULL)
++ for (p = __config->ldc_initgroups_ignoreusers; *p != NULL; p++)
++ {
++ if (strcmp (*p, user) == 0)
++ return 1;
++ }
++ if (__config->ldc_initgroups_minimum_uid >= 0)
++ {
++ memset (&pwd, 0, sizeof(pwd));
++ buflen = 16;
++ buf = malloc(buflen);
++ if (buf != NULL)
++ {
++ passwd = NULL;
++ while ((getpwnam_r(user, &pwd, buf, buflen, &passwd) != 0) &&
++ (passwd != &pwd))
++ {
++ switch (errno)
++ {
++ case ERANGE:
++ buflen *= 2;
++ free(buf);
++ if (buflen > 0x100000)
++ buf = NULL;
++ else
++ buf = malloc(buflen);
++ break;
++ case EINTR:
++ continue;
++ break;
++ default:
++ free(buf);
++ buf = NULL;
++ break;
++ }
++ if (buf == NULL)
++ break;
++ }
++ }
++ if ((passwd == &pwd) && (passwd->pw_uid < 1000))
++ return 1;
++ }
+ }
+-
+ return 0;
+ }
+
+diff -ur nss_ldap-265/ldap-nss.h nss_ldap-265-2/ldap-nss.h
+--- nss_ldap-265/ldap-nss.h 2010-08-19 17:16:51.000000000 -0400
++++ nss_ldap-265-2/ldap-nss.h 2010-08-19 17:18:47.000000000 -0400
+@@ -400,6 +400,7 @@
+ time_t ldc_mtime;
+
+ char **ldc_initgroups_ignoreusers;
++ int ldc_initgroups_minimum_uid;
+
+ /* disable the do-res_init()-on-resolv.conf-changes hack */
+ unsigned int ldc_resolv_conf_res_init_hack;
+diff -ur nss_ldap-265/ldap-pwd.c nss_ldap-265-2/ldap-pwd.c
+--- nss_ldap-265/ldap-pwd.c 2010-08-19 17:16:51.000000000 -0400
++++ nss_ldap-265-2/ldap-pwd.c 2010-08-19 16:40:43.000000000 -0400
+@@ -49,6 +49,7 @@
+ #include "ldap-nss.h"
+ #include "ldap-pwd.h"
+ #include "util.h"
++#include "depth.h"
+
+ #ifdef HAVE_PORT_AFTER_H
+ #include <port_after.h>
+@@ -242,6 +243,10 @@
+ struct passwd * result,
+ char *buffer, size_t buflen, int *errnop)
+ {
++#ifdef HAVE_THREAD_LOCAL_STORAGE
++ if (_nss_ldap_get_depth() > 0)
++ return NSS_STATUS_UNAVAIL;
++#endif
+ LOOKUP_NAME (name, result, buffer, buflen, errnop, _nss_ldap_filt_getpwnam,
+ LM_PASSWD, _nss_ldap_parse_pw, LDAP_NSS_BUFLEN_DEFAULT);
+ }
+@@ -261,6 +266,10 @@
+ struct passwd *result,
+ char *buffer, size_t buflen, int *errnop)
+ {
++#ifdef HAVE_THREAD_LOCAL_STORAGE
++ if (_nss_ldap_get_depth() > 0)
++ return NSS_STATUS_UNAVAIL;
++#endif
+ LOOKUP_NUMBER (uid, result, buffer, buflen, errnop, _nss_ldap_filt_getpwuid,
+ LM_PASSWD, _nss_ldap_parse_pw, LDAP_NSS_BUFLEN_DEFAULT);
+ }
+diff -ur nss_ldap-265/nss_ldap.5 nss_ldap-265-2/nss_ldap.5
+--- nss_ldap-265/nss_ldap.5 2010-08-19 17:16:51.000000000 -0400
++++ nss_ldap-265-2/nss_ldap.5 2010-08-19 17:19:23.000000000 -0400
+@@ -445,6 +445,14 @@
+ to return NSS_STATUS_NOTFOUND if called with a listed users as
+ its argument.
+ .TP
++.B nss_initgroups_minimum_uid <uid>
++This option directs the
++.B nss_ldap
++implementation of
++.BR initgroups(3)
++to return NSS_STATUS_NOTFOUND if called with a user whose UID is
++below the value given as the argument.
++.TP
+ .B nss_getgrent_skipmembers <yes|no>
+ Specifies whether or not to populate the members list in
+ the group structure for group lookups. If very large groups
+diff -ur nss_ldap-265/util.c nss_ldap-265-2/util.c
+--- nss_ldap-265/util.c 2010-08-19 17:16:51.000000000 -0400
++++ nss_ldap-265-2/util.c 2010-08-19 17:18:33.000000000 -0400
+@@ -669,6 +669,7 @@
+ result->ldc_reconnect_maxsleeptime = LDAP_NSS_MAXSLEEPTIME;
+ result->ldc_reconnect_maxconntries = LDAP_NSS_MAXCONNTRIES;
+ result->ldc_initgroups_ignoreusers = NULL;
++ result->ldc_initgroups_minimum_uid = -1;
+
+ for (i = 0; i <= LM_NONE; i++)
+ {
+@@ -1180,6 +1181,10 @@
+ break;
+ }
+ }
++ else if (!strcasecmp (k, NSS_LDAP_KEY_INITGROUPS_MINIMUM_UID))
++ {
++ result->ldc_initgroups_minimum_uid = atoi(v);
++ }
+ else if (!strcasecmp (k, NSS_LDAP_KEY_GETGRENT_SKIPMEMBERS))
+ {
+ if (!strcasecmp (v, "on") || !strcasecmp (v, "yes")
+diff -ur nss_ldap-265/util.h nss_ldap-265-2/util.h
+--- nss_ldap-265/util.h 2009-11-06 05:28:08.000000000 -0500
++++ nss_ldap-265-2/util.h 2010-08-19 17:19:46.000000000 -0400
+@@ -92,6 +92,7 @@
+ #define NSS_LDAP_KEY_PAGESIZE "pagesize"
+ #define NSS_LDAP_KEY_INITGROUPS "nss_initgroups"
+ #define NSS_LDAP_KEY_INITGROUPS_IGNOREUSERS "nss_initgroups_ignoreusers"
++#define NSS_LDAP_KEY_INITGROUPS_MINIMUM_UID "nss_initgroups_minimum_uid"
+ #define NSS_LDAP_KEY_GETGRENT_SKIPMEMBERS "nss_getgrent_skipmembers"
+
+ /* more reconnect policy fine-tuning */
diff --git a/nss_ldap-265-erange.patch b/nss_ldap-265-erange.patch
new file mode 100644
index 0000000..0bdfe5a
--- /dev/null
+++ b/nss_ldap-265-erange.patch
@@ -0,0 +1,17 @@
+If we were supposed to set ERANGE, do so again, in case do_close() or
+_nss_ldap_leave() overwrote errno with some other value. Upstream #421.
+
+diff -up nss_ldap-265/ldap-nss.ce nss_ldap-265/ldap-nss.c
+--- nss_ldap-265/ldap-nss.ce 2010-07-08 16:17:07.000000000 -0400
++++ nss_ldap-265/ldap-nss.c 2010-07-08 16:17:03.000000000 -0400
+@@ -3572,6 +3572,10 @@ _nss_ldap_getbyname (ldap_args_t * args,
+
+ debug ("<== _nss_ldap_getbyname");
+
++ /* at least for the cases where we know we have to return ERANGE */
++ if (stat == NSS_TRYAGAIN)
++ do_map_errno(stat, errnop);
++
+ return stat;
+ }
+
diff --git a/nss_ldap.spec b/nss_ldap.spec
index 0018cec..33e5eef 100644
--- a/nss_ldap.spec
+++ b/nss_ldap.spec
@@ -2,7 +2,7 @@
Summary: NSS library and PAM module for LDAP
Name: nss_ldap
Version: 264
-Release: 9%{?dist}
+Release: 10%{?dist}
Source0: ftp://ftp.padl.com/pub/nss_ldap-%{version}.tar.gz
Source1: ftp://ftp.padl.com/pub/pam_ldap-%{pam_ldap_version}.tar.gz
Source5: README.TLS
@@ -15,7 +15,6 @@ Patch4: pam_ldap-180-bind.patch
Patch6: nss_ldap-257-over-recursion.patch
Patch7: pam_ldap-182-manpointer.patch
Patch8: nss_ldap-254-soname.patch
-Patch11: nss_ldap-257-initgroups-minimum_uid.patch
Patch13: pam_ldap-176-exop-modify.patch
Patch15: nss_ldap-257-mozldap.patch
Patch16: pam_ldap-184-referral-passwd2.patch
@@ -26,6 +25,10 @@ Patch21: nss_ldap-264-checkcase.patch
Patch22: nss_ldap-264-ent_internal.patch
Patch23: pam_ldap-183-releaseconfig.patch
Patch24: nss_ldap-264-cloexec.patch
+Patch25: nss_ldap-264-depth.patch
+Patch26: nss_ldap-265-erange.patch
+Patch27: nss_ldap-264-initgroups-minimum_uid.patch
+Patch28: pam_ldap-185-initgroups-minimum_uid.patch
URL: http://www.padl.com/
License: LGPLv2+
@@ -69,6 +72,9 @@ pushd nss_ldap-%{version}
#%patch21 -p1 -b .checkcase
%patch22 -p1 -b .ent_internal
%patch24 -p1 -b .cloexec
+%patch25 -p1 -b .depth
+%patch26 -p1 -b .erange
+%patch27 -p1 -b .initgroups-minimum_uid
autoreconf -f -i
popd
@@ -83,6 +89,7 @@ pushd pam_ldap-%{pam_ldap_version}
%patch19 -p1 -b .broken-sasl-rebind
%patch20 -p1 -b .nsrole
%patch23 -p1 -b .releaseconfig
+%patch28 -p1 -b .initgroups-minimum_uid
autoreconf -f -i
popd
@@ -197,6 +204,13 @@ fi
%doc pam_ldap-%{pam_ldap_version}/ns-pwd-policy.schema
%changelog
+* Thu Jul 8 2010 Nalin Dahyabhai <nalin at redhat.com> 264-10
+- add proposed patch for avoiding recursion-until-death while resolving hosts
+- take another stab at implementing a working nss_initgroups_minimum_uid
+ setting, and default it to 500
+- add proposed patch for upstream #421: sometimes errno gets reset before we
+ return control to libc
+
* Mon Feb 15 2010 Nalin Dahyabhai <nalin at redhat.com> 264-9
- switch to linking with the evolution-specific libldap, because that's still
available as a static library (#565065)
diff --git a/pam_ldap-185-initgroups-minimum_uid.patch b/pam_ldap-185-initgroups-minimum_uid.patch
new file mode 100644
index 0000000..49e6173
--- /dev/null
+++ b/pam_ldap-185-initgroups-minimum_uid.patch
@@ -0,0 +1,17 @@
+This builds off of the recursion checking introduced by -depth to avoid
+a deadlock if/when we recurse into ourselves while looking up the user's
+UID to compare it to the configured value.
+
+--- pam_ldap-185/ldap.conf 2005-08-17 18:35:13.000000000 -0400
++++ pam_ldap-185/ldap.conf 2006-02-09 14:14:05.000000000 -0500
+@@ -177,8 +177,8 @@
+ #nss_base_aliases ou=Aliases,dc=padl,dc=com?one
+ #nss_base_netgroup ou=Netgroup,dc=padl,dc=com?one
+
+-# Just assume that there are no supplemental groups for these named users
+-nss_initgroups_ignoreusers root,ldap,named,avahi,haldaemon,dbus,radvd,tomcat,radiusd,news,mailman,nscd,gdm,polkituser,rtkit,pulse
++# Just assume that there are no supplemental groups for system users.
++nss_initgroups_minimum_uid 500
+
+ # attribute/objectclass mapping
+ # Syntax:
More information about the scm-commits
mailing list