summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRich Megginson <rmeggins@redhat.com>2008-04-03 21:07:55 +0000
committerRich Megginson <rmeggins@redhat.com>2008-04-03 21:07:55 +0000
commitcd83de12e4666fc18e458431159591b6ec92eef6 (patch)
tree0d800bdccf673472c9aabada85c9cee483301905
parentc1b2db5308dd275d16d96ae57e37aad73aa4bd2a (diff)
downloadds-cd83de12e4666fc18e458431159591b6ec92eef6.tar.gz
ds-cd83de12e4666fc18e458431159591b6ec92eef6.tar.xz
ds-cd83de12e4666fc18e458431159591b6ec92eef6.zip
Resolves: bug 439829
Bug Description: simple password auth fails using NSS 3.11.99 or later Reviewed by: nkinder (Thanks!) Fix Description: The new softokn in NSS 3.11.99 and later requires that the server calls NSS_Init() after forking, but before detaching from the controlling terminal. In fact, this was always a requirement, but the softokn in older NSS allow it. However, it's possible that some hardware crypto devices do not allow this and may not work with older directory servers. The fix is to move the nss/ssl initialization so that it can be called at the right point, or from other points in cases where the server does not fork (e.g. db2ldif). Platforms tested: Fedora 9 i386, RHEL5 x86_64 Flag Day: no Doc impact: no
-rw-r--r--ldap/servers/slapd/detach.c16
-rw-r--r--ldap/servers/slapd/main.c117
-rw-r--r--ldap/servers/slapd/proto-slap.h7
3 files changed, 93 insertions, 47 deletions
diff --git a/ldap/servers/slapd/detach.c b/ldap/servers/slapd/detach.c
index d9906263..a547b50c 100644
--- a/ldap/servers/slapd/detach.c
+++ b/ldap/servers/slapd/detach.c
@@ -76,7 +76,8 @@
#endif /* USE_SYSCONF */
void
-detach()
+detach( int slapd_exemode, int importexport_encrypt,
+ int s_port, daemon_ports_t *ports_info )
{
#ifndef _WIN32
int i, sd;
@@ -108,6 +109,12 @@ detach()
break;
}
+ /* call this right after the fork, but before closing stdin */
+ if (slapd_do_all_nss_ssl_init(slapd_exemode, importexport_encrypt,
+ s_port, ports_info)) {
+ exit(1);
+ }
+
workingdir = config_get_workingdir();
if ( NULL == workingdir ) {
errorlog = config_get_errorlog();
@@ -150,7 +157,12 @@ detach()
#endif /* USE_SETSID */
g_set_detached(1);
- }
+ } else { /* not detaching - call nss/ssl init */
+ if (slapd_do_all_nss_ssl_init(slapd_exemode, importexport_encrypt,
+ s_port, ports_info)) {
+ exit(1);
+ }
+ }
(void) SIGNAL( SIGPIPE, SIG_IGN );
#endif /* _WIN32 */
diff --git a/ldap/servers/slapd/main.c b/ldap/servers/slapd/main.c
index 1c1943a6..f4e44f48 100644
--- a/ldap/servers/slapd/main.c
+++ b/ldap/servers/slapd/main.c
@@ -901,48 +901,14 @@ main( int argc, char **argv)
}
#endif
- /*
- * Initialise NSS once for the whole slapd process, whether SSL
- * is enabled or not. We use NSS for random number generation and
- * other things even if we are not going to accept SSL connections.
- * We also need NSS for attribute encryption/decryption on import and export.
- */
- init_ssl = ( (slapd_exemode == SLAPD_EXEMODE_SLAPD) || importexport_encrypt)
- && config_get_security()
- && (0 != s_port) && (s_port <= LDAP_PORT_MAX);
- /* As of DS 6.1, always do a full initialization so that other
- * modules can assume NSS is available
- */
- if ( slapd_nss_init((slapd_exemode == SLAPD_EXEMODE_SLAPD),
- (slapd_exemode != SLAPD_EXEMODE_REFERRAL) /* have config? */ )) {
- LDAPDebug(LDAP_DEBUG_ANY,
- "ERROR: NSS Initialization Failed.\n", 0, 0, 0);
- exit (1);
- }
-
- if (slapd_exemode == SLAPD_EXEMODE_SLAPD) {
- client_auth_init();
- }
-
- if ( init_ssl && ( 0 != slapd_ssl_init())) {
- LDAPDebug(LDAP_DEBUG_ANY,
- "ERROR: SSL Initialization Failed.\n", 0, 0, 0 );
- exit( 1 );
- }
-
- if ((slapd_exemode == SLAPD_EXEMODE_SLAPD) ||
- (slapd_exemode == SLAPD_EXEMODE_REFERRAL)) {
- if ( init_ssl ) {
- PRFileDesc **sock;
- for (sock = ports_info.s_socket; sock && *sock; sock++) {
- if ( 0 != slapd_ssl_init2(sock, 0) ) {
- LDAPDebug(LDAP_DEBUG_ANY,
- "ERROR: SSL Initialization phase 2 Failed.\n", 0, 0, 0 );
- exit( 1 );
- }
- }
- }
- }
+ /* Do NSS and/or SSL init for those modes other than listening modes */
+ if ((slapd_exemode != SLAPD_EXEMODE_REFERRAL) &&
+ (slapd_exemode != SLAPD_EXEMODE_SLAPD)) {
+ if (slapd_do_all_nss_ssl_init(slapd_exemode, importexport_encrypt,
+ s_port, &ports_info)) {
+ return 1;
+ }
+ }
/*
* if we were called upon to do special database stuff, do it and be
@@ -1002,7 +968,8 @@ main( int argc, char **argv)
* Have to detach after ssl_init - the user may be prompted for the PIN
* on the terminal, so it must be open.
*/
- detach();
+ detach(slapd_exemode, importexport_encrypt,
+ s_port, &ports_info);
/*
* Now write our PID to the startup PID file.
@@ -2885,3 +2852,67 @@ slapd_debug_level_usage( void )
}
#endif /* LDAP_DEBUG */
+/*
+ This function does all NSS and SSL related initialization
+ required during startup. We use this function rather
+ than just call this code from main because we must perform
+ all of this initialization after the fork() but before
+ we detach from the controlling terminal. This is because
+ the NSS softokn requires that NSS_Init is called after the
+ fork - this was always the case, but it is a hard error in
+ NSS 3.11.99 and later. We also have to call NSS_Init before
+ doing the detach because NSS may prompt the user for the
+ token (h/w or softokn) password on stdin. So we use this
+ function that we can call from detach() if running in
+ regular slapd exemode or from main() if running in other
+ modes (or just not detaching).
+*/
+int
+slapd_do_all_nss_ssl_init(int slapd_exemode, int importexport_encrypt,
+ int s_port, daemon_ports_t *ports_info)
+{
+ /*
+ * Initialise NSS once for the whole slapd process, whether SSL
+ * is enabled or not. We use NSS for random number generation and
+ * other things even if we are not going to accept SSL connections.
+ * We also need NSS for attribute encryption/decryption on import and export.
+ */
+ int init_ssl = ( (slapd_exemode == SLAPD_EXEMODE_SLAPD) || importexport_encrypt)
+ && config_get_security()
+ && (0 != s_port) && (s_port <= LDAP_PORT_MAX);
+ /* As of DS 6.1, always do a full initialization so that other
+ * modules can assume NSS is available
+ */
+ if ( slapd_nss_init((slapd_exemode == SLAPD_EXEMODE_SLAPD),
+ (slapd_exemode != SLAPD_EXEMODE_REFERRAL) /* have config? */ )) {
+ LDAPDebug(LDAP_DEBUG_ANY,
+ "ERROR: NSS Initialization Failed.\n", 0, 0, 0);
+ exit (1);
+ }
+
+ if (slapd_exemode == SLAPD_EXEMODE_SLAPD) {
+ client_auth_init();
+ }
+
+ if ( init_ssl && ( 0 != slapd_ssl_init())) {
+ LDAPDebug(LDAP_DEBUG_ANY,
+ "ERROR: SSL Initialization Failed.\n", 0, 0, 0 );
+ exit( 1 );
+ }
+
+ if ((slapd_exemode == SLAPD_EXEMODE_SLAPD) ||
+ (slapd_exemode == SLAPD_EXEMODE_REFERRAL)) {
+ if ( init_ssl ) {
+ PRFileDesc **sock;
+ for (sock = ports_info->s_socket; sock && *sock; sock++) {
+ if ( 0 != slapd_ssl_init2(sock, 0) ) {
+ LDAPDebug(LDAP_DEBUG_ANY,
+ "ERROR: SSL Initialization phase 2 Failed.\n", 0, 0, 0 );
+ exit( 1 );
+ }
+ }
+ }
+ }
+
+ return 0;
+}
diff --git a/ldap/servers/slapd/proto-slap.h b/ldap/servers/slapd/proto-slap.h
index b27b74b4..f3f7131f 100644
--- a/ldap/servers/slapd/proto-slap.h
+++ b/ldap/servers/slapd/proto-slap.h
@@ -483,7 +483,8 @@ void do_delete( Slapi_PBlock *pb );
/*
* detach.c
*/
-void detach( void );
+void detach( int slapd_exemode, int importexport_encrypt,
+ int s_port, daemon_ports_t *ports_info );
#ifndef _WIN32
void close_all_files( void );
#endif
@@ -879,7 +880,6 @@ int slapd_security_library_is_initialized();
int slapd_ssl_listener_is_initialized();
int sasl_io_cleanup(Connection *c);
-
/*
* security_wrappers.c
*/
@@ -1277,4 +1277,7 @@ void *slapd_service_exit_wait();
#if ( defined( hpux ) || defined( irix ))
void signal2sigaction( int s, void *a );
#endif
+int slapd_do_all_nss_ssl_init(int slapd_exemode, int importexport_encrypt,
+ int s_port, daemon_ports_t *ports_info);
+
#endif /* _PROTO_SLAP */