Sophie

Sophie

distrib > Scientific%20Linux > 5x > x86_64 > media > main-src > by-pkgid > f2c9a24e570f82c24fd7074143d03478 > files > 7

nss_ldap-253-42.el5.src.rpm

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-253/config.h.in nss_ldap-253/config.h.in
--- nss_ldap-253/config.h.in	2009-12-11 16:54:38.000000000 -0500
+++ nss_ldap-253/config.h.in	2009-12-11 16:56:11.000000000 -0500
@@ -295,6 +295,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-253/configure.in nss_ldap-253/configure.in
--- nss_ldap-253/configure.in	2009-12-11 16:53:18.000000000 -0500
+++ nss_ldap-253/configure.in	2009-12-11 16:54:19.000000000 -0500
@@ -26,6 +26,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-253/depth.c nss_ldap-253/depth.c
--- nss_ldap-253/depth.c	2009-12-11 16:48:32.000000000 -0500
+++ nss_ldap-253/depth.c	2009-12-11 16:57:05.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-253/depth.h nss_ldap-253/depth.h
--- nss_ldap-253/depth.h	2009-12-11 16:48:28.000000000 -0500
+++ nss_ldap-253/depth.h	2009-12-11 16:48:23.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-253/ldap-hosts.c nss_ldap-253/ldap-hosts.c
--- nss_ldap-253/ldap-hosts.c	2009-12-11 16:49:58.000000000 -0500
+++ nss_ldap-253/ldap-hosts.c	2009-12-11 16:57:56.000000000 -0500
@@ -63,6 +63,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>
@@ -270,6 +271,11 @@ _nss_ldap_gethostbyname2_r (const char *
   NSS_STATUS status;
   ldap_args_t a;
 
+#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;
@@ -345,6 +351,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.
@@ -381,6 +392,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
@@ -393,6 +409,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
@@ -425,6 +446,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-253/ldap-nss.c nss_ldap-253/ldap-nss.c
--- nss_ldap-253/ldap-nss.c	2009-12-11 16:48:54.000000000 -0500
+++ nss_ldap-253/ldap-nss.c	2009-12-11 16:57:24.000000000 -0500
@@ -90,6 +90,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
@@ -582,6 +583,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:
@@ -627,6 +631,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-253/Makefile.am nss_ldap-253/Makefile.am
--- nss_ldap-253/Makefile.am	2009-12-11 16:49:29.000000000 -0500
+++ nss_ldap-253/Makefile.am	2009-12-11 16:49:34.000000000 -0500
@@ -22,7 +22,7 @@ nss_ldap_so_SOURCES = ldap-nss.c ldap-pw
 	ldap-hosts.c ldap-network.c ldap-proto.c ldap-spwd.c \
 	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
+	dnsconfig.c irs-nss.c pagectrl.c ldap-sldap.c depth.c
 
 nss_ldap_so_LDFLAGS = @nss_ldap_so_LDFLAGS@