Postpone connection teardown in the child until we call into the module. We still need to ensure that the open connection is marked close-on-exec so that we don't inherit it across an exec(). diff -up nss_ldap-253/ldap-nss.c nss_ldap-253/ldap-nss.c --- nss_ldap-253/ldap-nss.c 2010-08-05 16:36:49.000000000 -0400 +++ nss_ldap-253/ldap-nss.c 2010-09-21 14:44:06.000000000 -0400 @@ -119,6 +119,7 @@ extern int ldap_ld_free (LDAP * ld, int #endif /* HAVE_LDAP_LD_FREE */ NSS_LDAP_DEFINE_LOCK (__lock); +NSS_LDAP_DEFINE_LOCK (__child_atfork_lock); /* * the configuration is read by the first call to do_open(). @@ -530,16 +531,32 @@ do_atfork_parent (void) debug ("<== do_atfork_parent"); } +static int +_nss_ldap_need_deferred_close_no_unbind; + static void -do_atfork_child (void) +do_deferred_close_no_unbind (void) { sigset_t unblock, mask; - debug ("==> do_atfork_child"); + debug ("==> do_deferred_close_no_unbind"); sigemptyset(&unblock); sigaddset(&unblock, SIGPIPE); sigprocmask(SIG_UNBLOCK, &unblock, &mask); do_close_no_unbind (); sigprocmask(SIG_SETMASK, &mask, NULL); + debug ("<== do_deferred_close_no_unbind"); +} + +static void +do_atfork_child (void) +{ + int sd = -1; + debug ("==> do_atfork_child"); + NSS_LDAP_LOCK (__child_atfork_lock); + _nss_ldap_need_deferred_close_no_unbind = 1; + if (do_get_our_socket (&sd)) + fcntl (sd, F_SETFD, FD_CLOEXEC); + NSS_LDAP_UNLOCK (__child_atfork_lock); _nss_ldap_leave (); debug ("<== do_atfork_child"); } @@ -606,6 +623,14 @@ _nss_ldap_enter (void) __sigpipe_handler = signal (SIGPIPE, SIG_IGN); #endif /* HAVE_SIGSET */ + NSS_LDAP_LOCK (__child_atfork_lock); + if (_nss_ldap_need_deferred_close_no_unbind) + { + do_deferred_close_no_unbind (); + _nss_ldap_need_deferred_close_no_unbind = 0; + } + NSS_LDAP_UNLOCK (__child_atfork_lock); + debug ("<== _nss_ldap_enter"); } @@ -857,6 +857,8 @@ peernamelen); } } + else + isOurSocket = 0; #endif /* HAVE_LDAPSSL_CLIENT_INIT */ return isOurSocket; }