--- /dev/null
+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. Revised from patch originally submitted for #340.
+
+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,7 +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 \
+- vers.c
++ vers.c depth.c
+
+ nss_ldap_so_LDFLAGS = @nss_ldap_so_LDFLAGS@
+