changeset 12646:6faf82030b5c

6935594 libldap needs to deal with changed NSS behaviour after fork
author Milan Jurik <Milan.Jurik@Sun.COM>
date Fri, 18 Jun 2010 15:31:30 +0100
parents 0de9ed7d05ab
children ca11a9750060
files usr/src/cmd/ypcmd/yp.sh usr/src/lib/libldap5/sources/ldap/ssldap/clientinit.c
diffstat 2 files changed, 114 insertions(+), 9 deletions(-) [+]
line wrap: on
line diff
--- a/usr/src/cmd/ypcmd/yp.sh	Fri Jun 18 13:58:16 2010 +0200
+++ b/usr/src/cmd/ypcmd/yp.sh	Fri Jun 18 15:31:30 2010 +0100
@@ -20,8 +20,7 @@
 # CDDL HEADER END
 #
 #
-# Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
-# Use is subject to license terms.
+# Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
 #
 
 . /lib/svc/share/smf_include.sh
@@ -152,9 +151,9 @@
 		fi
 
 		if [ -f /etc/resolv.conf ]; then
-			/usr/bin/env NSS_STRICT_NOFORK=DISABLED $YPDIR/ypserv -d
+			$YPDIR/ypserv -d
 		else
-			/usr/bin/env NSS_STRICT_NOFORK=DISABLED $YPDIR/ypserv
+			$YPDIR/ypserv
 		fi
 
 		rc=$?
--- a/usr/src/lib/libldap5/sources/ldap/ssldap/clientinit.c	Fri Jun 18 13:58:16 2010 +0200
+++ b/usr/src/lib/libldap5/sources/ldap/ssldap/clientinit.c	Fri Jun 18 15:31:30 2010 +0100
@@ -1,6 +1,5 @@
 /*
- * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.
  */
 
 /*
@@ -25,8 +24,6 @@
  * Contributor(s):
  */
 
-#pragma ident	"%Z%%M%	%I%	%E% SMI"
-
 /*
  * clientinit.c
  */
@@ -238,6 +235,56 @@
 }
 
 
+#ifdef _SOLARIS_SDK
+/*
+ * Disable strict fork detection of NSS library to allow safe fork of
+ * consumers. Otherwise NSS will not work after fork because it was not
+ * deinitialized before fork and there is no safe way how to do it after fork.
+ *
+ * Return values:
+ *     1 - DISABLED was already set, no modification to environment
+ *     0 - successfully modified environment, old value saved to enval if there
+ *         was some
+ *    -1 - setenv or strdup failed, the environment was left unchanged
+ *
+ */
+static int
+update_nss_strict_fork_env(char **enval)
+{
+	char *temps = getenv("NSS_STRICT_NOFORK");
+	if (temps == NULL) {
+		*enval = NULL;
+	} else if (strncmp(temps, "DISABLED", 9) == 0) {
+		/* Do not need to set as DISABLED, it is already set. */
+		*enval = NULL;
+		return (1);
+	} else {
+		if ((*enval = ldapssl_strdup(temps)) == NULL)
+			return (-1);
+	}
+	return (setenv("NSS_STRICT_NOFORK", "DISABLED", 1));
+}
+
+/*
+ * Reset environment variable NSS_STRICT_NOFORK to value before
+ * update_nss_strict_fork_env() call or remove it from environment if it did
+ * not exist.
+ * NSS_STRICT_NOFORK=DISABLED is needed only during NSS initialization to
+ * disable activation of atfork handler in NSS which is invalidating
+ * initialization in child process after fork.
+ */
+static int
+reset_nss_strict_fork_env(char *enval)
+{
+	if (enval != NULL) {
+		return (setenv("NSS_STRICT_NOFORK", enval, 1));
+	} else {
+		return (unsetenv("NSS_STRICT_NOFORK"));
+	}
+}
+#endif
+
+
 static char *
 buildDBName(const char *basename, const char *dbname)
 {
@@ -371,8 +418,11 @@
     const int needkeydb, const char *keydbpath, void *keydbhandle )
 
 {
-
     int	rc;
+#ifdef _SOLARIS_SDK
+    char *enval;
+    int rcenv = 0;
+#endif
      
     /*
      *     LDAPDebug(LDAP_DEBUG_TRACE, "ldapssl_clientauth_init\n",0 ,0 ,0);
@@ -386,9 +436,24 @@
 
     ldapssl_basic_init();
 
+#ifdef _SOLARIS_SDK
+    if ((rcenv = update_nss_strict_fork_env(&enval)) == -1) {
+	mutex_unlock(&inited_mutex);
+	return (-1);
+    }
+#endif
 
     /* Open the certificate database */
     rc = NSS_Init(certdbpath);
+#ifdef _SOLARIS_SDK
+    /* Error from NSS_Init() more important! */
+    if ((rcenv != 1) && (reset_nss_strict_fork_env(enval) != 0) && (rc == 0)) {
+	ldapssl_free(&enval);
+	mutex_unlock(&inited_mutex);
+	return (-1);
+    }
+    ldapssl_free(&enval);
+#endif
     if (rc != 0) {
 	if ((rc = PR_GetError()) >= 0)
 	    rc = -1;
@@ -470,6 +535,10 @@
     const int sslstrength )
 {
     int	rc;
+#ifdef _SOLARIS_SDK
+    char *enval;
+    int rcenv = 0;
+#endif
 
     mutex_lock(&inited_mutex);
     if ( inited ) {
@@ -483,7 +552,23 @@
 
     ldapssl_basic_init();
 
+#ifdef _SOLARIS_SDK
+    if ((rcenv = update_nss_strict_fork_env(&enval)) == -1) {
+	mutex_unlock(&inited_mutex);
+	return (-1);
+    }
+#endif
+
     rc = NSS_Init(certdbpath);
+#ifdef _SOLARIS_SDK
+    /* Error from NSS_Init() more important! */
+    if ((rcenv != 1) && (reset_nss_strict_fork_env(enval) != 0) && (rc == 0)) {
+	ldapssl_free(&enval);
+	mutex_unlock(&inited_mutex);
+	return (-1);
+    }
+    ldapssl_free(&enval);
+#endif
     if (rc != 0) {
 	if ((rc = PR_GetError()) >= 0)
 	    rc = -1;
@@ -535,6 +620,10 @@
     char		*confDir, *keydbName;
     static char         *secmodname =  "secmod.db";
     int			rc;
+#ifdef _SOLARIS_SDK
+    char *enval;
+    int rcenv = 0;
+#endif
     
     mutex_lock(&inited_mutex);
     if ( inited ) {
@@ -575,12 +664,29 @@
     ldapssl_free((void **)&keydbName);
     ldapssl_free((void **)&keydbpath);
 
+#ifdef _SOLARIS_SDK
+    if ((rcenv = update_nss_strict_fork_env(&enval)) == -1) {
+	mutex_unlock(&inited_mutex);
+	return (-1);
+    }
+#endif
+
     rc = NSS_Initialize(confDir,certdbPrefix,keydbPrefix,secmodname,
 		NSS_INIT_READONLY);
 
     ldapssl_free((void **)&certdbPrefix);
     ldapssl_free((void **)&keydbPrefix);
     ldapssl_free((void **)&confDir);
+
+#ifdef _SOLARIS_SDK
+    /* Error from NSS_Initialize() more important! */
+    if ((rcenv != 1) && (reset_nss_strict_fork_env(enval) != 0) && (rc == 0)) {
+	ldapssl_free(&enval);
+	mutex_unlock(&inited_mutex);
+	return (-1);
+    }
+    ldapssl_free(&enval);
+#endif
     
     if (rc != 0) {
 	if ((rc = PR_GetError()) >= 0)