]> git.sur5r.net Git - openldap/blobdiff - servers/slapd/main.c
trim listed modules
[openldap] / servers / slapd / main.c
index 89e6a98d79a4b43b1638084805dcc96ecec82d88..994f9fcfa933c663d6f7dace9eeb927d7df48a6b 100644 (file)
@@ -1,7 +1,7 @@
 /* $OpenLDAP$ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
- * Copyright 1998-2005 The OpenLDAP Foundation.
+ * Copyright 1998-2007 The OpenLDAP Foundation.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -98,24 +98,23 @@ const char Versionstr[] =
        OPENLDAP_PACKAGE " " OPENLDAP_VERSION " Standalone LDAP Server (slapd)";
 #endif
 
-#define CHECK_NONE     0x00
-#define CHECK_CONFIG   0x01
+#define        CHECK_NONE      0x00
+#define        CHECK_CONFIG    0x01
+#define        CHECK_LOGLEVEL  0x02
 static int check = CHECK_NONE;
 static int version = 0;
 
 void *slap_tls_ctx;
-
-#ifdef LOG_LOCAL4
-#define DEFAULT_SYSLOG_USER    LOG_LOCAL4
-#endif /* LOG_LOCAL4 */
+LDAP *slap_tls_ld;
 
 static int
 slapd_opt_slp( const char *val, void *arg )
 {
 #ifdef HAVE_SLP
        /* NULL is default */
-       if ( val == NULL || strcasecmp( val, "on" ) == 0 ) {
+       if ( val == NULL || *val == '(' || strcasecmp( val, "on" ) == 0 ) {
                slapd_register_slp = 1;
+               slapd_slp_attrs = (val != NULL && *val == '(') ? val : NULL;
 
        } else if ( strcasecmp( val, "off" ) == 0 ) {
                slapd_register_slp = 0;
@@ -154,12 +153,13 @@ struct option_helper {
        void            *oh_arg;
        const char      *oh_usage;
 } option_helpers[] = {
-       { BER_BVC("slp"),       slapd_opt_slp,  NULL, "slp[={on|off}] enable/disable SLP" },
+       { BER_BVC("slp"),       slapd_opt_slp,  NULL, "slp[={on|off|(attrs)}] enable/disable SLP using (attrs)" },
        { BER_BVNULL, 0, NULL, NULL }
 };
 
+#if defined(LDAP_DEBUG) && defined(LDAP_SYSLOG)
 #ifdef LOG_LOCAL4
-static int
+int
 parse_syslog_user( const char *arg, int *syslogUser )
 {
        static slap_verbmasks syslogUsers[] = {
@@ -179,12 +179,12 @@ parse_syslog_user( const char *arg, int *syslogUser )
 #endif /* LOG_DAEMON */
                { BER_BVNULL, 0 }
        };
-       int i = verb_to_mask( optarg, syslogUsers );
+       int i = verb_to_mask( arg, syslogUsers );
 
        if ( BER_BVISNULL( &syslogUsers[ i ].word ) ) {
                Debug( LDAP_DEBUG_ANY,
                        "unrecognized syslog user \"%s\".\n",
-                       optarg, 0, 0 );
+                       arg, 0, 0 );
                return 1;
        }
 
@@ -194,7 +194,7 @@ parse_syslog_user( const char *arg, int *syslogUser )
 }
 #endif /* LOG_LOCAL4 */
 
-static int
+int
 parse_syslog_level( const char *arg, int *levelp )
 {
        static slap_verbmasks   str2syslog_level[] = {
@@ -220,15 +220,34 @@ parse_syslog_level( const char *arg, int *levelp )
 
        return 0;
 }
+#endif /* LDAP_DEBUG && LDAP_SYSLOG */
+
+int
+parse_debug_unknowns( char **unknowns, int *levelp )
+{
+       int i, level, rc = 0;
+
+       for ( i = 0; unknowns[ i ] != NULL; i++ ) {
+               level = 0;
+               if ( str2loglevel( unknowns[ i ], &level )) {
+                       fprintf( stderr,
+                               "unrecognized log level \"%s\"\n", unknowns[ i ] );
+                       rc = 1;
+               } else {
+                       *levelp |= level;
+               }
+       }
+       return rc;
+}
 
 int
-parse_debug_level( const char *arg, int *levelp )
+parse_debug_level( const char *arg, int *levelp, char ***unknowns )
 {
        int     level;
 
-       if ( arg != NULL && arg[ 0 ] != '-' && !isdigit( arg[ 0 ] ) )
+       if ( arg && arg[ 0 ] != '-' && !isdigit( (unsigned char) arg[ 0 ] ) )
        {
-               int     i, goterr = 0;
+               int     i;
                char    **levels;
 
                levels = ldap_str2charray( arg, "," );
@@ -237,12 +256,11 @@ parse_debug_level( const char *arg, int *levelp )
                        level = 0;
 
                        if ( str2loglevel( levels[ i ], &level ) ) {
+                               /* remember this for later */
+                               ldap_charray_add( unknowns, levels[ i ] );
                                fprintf( stderr,
-                                       "unrecognized log level "
-                                       "\"%s\"\n", levels[ i ] );
-                               goterr = 1;
-                               /* but keep parsing... */
-
+                                       "unrecognized log level \"%s\" (deferred)\n",
+                                       levels[ i ] );
                        } else {
                                *levelp |= level;
                        }
@@ -250,10 +268,6 @@ parse_debug_level( const char *arg, int *levelp )
 
                ldap_charray_free( levels );
 
-               if ( goterr ) {
-                       return 1;
-               }
-
        } else {
                if ( lutil_atoix( &level, arg, 0 ) != 0 ) {
                        fprintf( stderr,
@@ -335,7 +349,7 @@ int main( int argc, char **argv )
        char *sandbox = NULL;
 #endif
 #ifdef LOG_LOCAL4
-       int syslogUser = DEFAULT_SYSLOG_USER;
+       int syslogUser = SLAP_DEFAULT_SYSLOG_USER;
 #endif
        
        int g_argc = argc;
@@ -349,10 +363,14 @@ int main( int argc, char **argv )
        struct sync_cookie *scp = NULL;
        struct sync_cookie *scp_entry = NULL;
 
+       char **debug_unknowns = NULL;
+       char **syslog_unknowns = NULL;
+
        char *serverNamePrefix = "";
        size_t  l;
 
        int slapd_pid_file_unlink = 0, slapd_args_file_unlink = 0;
+       int firstopt = 1;
 
 #ifdef CSRIMALLOC
        FILE *leakfile;
@@ -429,12 +447,12 @@ int main( int argc, char **argv )
 #ifdef HAVE_CHROOT
                                "r:"
 #endif
-#ifdef LDAP_SYSLOG
+#if defined(LDAP_DEBUG) && defined(LDAP_SYSLOG)
                                "S:"
-#endif
 #ifdef LOG_LOCAL4
                                "l:"
 #endif
+#endif
 #if defined(HAVE_SETUID) && defined(HAVE_SETGID)
                                "u:g:"
 #endif
@@ -485,8 +503,13 @@ int main( int argc, char **argv )
                case 'd': {     /* set debug level and 'do not detach' flag */
                        int     level = 0;
 
+                       if ( strcmp( optarg, "?" ) == 0 ) {
+                               check |= CHECK_LOGLEVEL;
+                               break;
+                       }
+
                        no_detach = 1;
-                       if ( parse_debug_level( optarg, &level ) ) {
+                       if ( parse_debug_level( optarg, &level, &debug_unknowns ) ) {
                                goto destroy;
                        }
 #ifdef LDAP_DEBUG
@@ -541,7 +564,12 @@ int main( int argc, char **argv )
                }
 
                case 's':       /* set syslog level */
-                       if ( parse_debug_level( optarg, &ldap_syslog ) ) {
+                       if ( strcmp( optarg, "?" ) == 0 ) {
+                               check |= CHECK_LOGLEVEL;
+                               break;
+                       }
+
+                       if ( parse_debug_level( optarg, &ldap_syslog, &syslog_unknowns ) ) {
                                goto destroy;
                        }
                        break;
@@ -552,7 +580,6 @@ int main( int argc, char **argv )
                                goto destroy;
                        }
                        break;
-#endif /* LDAP_DEBUG && LDAP_SYSLOG */
 
 #ifdef LOG_LOCAL4
                case 'l':       /* set syslog local user */
@@ -561,6 +588,7 @@ int main( int argc, char **argv )
                        }
                        break;
 #endif
+#endif /* LDAP_DEBUG && LDAP_SYSLOG */
 
 #ifdef HAVE_CHROOT
                case 'r':
@@ -597,6 +625,12 @@ int main( int argc, char **argv )
                        break;
 
                case 'T':
+                       if ( firstopt == 0 ) {
+                               fprintf( stderr, "warning: \"-T %s\" "
+                                       "should be the first option.\n",
+                                       optarg );
+                       }
+
                        /* try full option string first */
                        for ( i = 0; tools[i].name; i++ ) {
                                if ( strcmp( optarg, &tools[i].name[4] ) == 0 ) {
@@ -627,6 +661,10 @@ unhandled_option:;
                        SERVICE_EXIT( ERROR_SERVICE_SPECIFIC_ERROR, 15 );
                        goto stop;
                }
+
+               if ( firstopt ) {
+                       firstopt = 0;
+               }
        }
 
        ber_set_option(NULL, LBER_OPT_DEBUG_LEVEL, &slap_debug);
@@ -690,6 +728,14 @@ unhandled_option:;
        lutil_passwd_init();
        slap_op_init();
 
+#ifdef HAVE_TLS
+       rc = ldap_create( &slap_tls_ld );
+       if ( rc ) {
+               SERVICE_EXIT( ERROR_SERVICE_SPECIFIC_ERROR, 20 );
+               goto destroy;
+       }
+#endif
+
        rc = slap_init( serverMode, serverName );
        if ( rc ) {
                SERVICE_EXIT( ERROR_SERVICE_SPECIFIC_ERROR, 18 );
@@ -707,6 +753,26 @@ unhandled_option:;
                goto destroy;
        }
 
+       if ( debug_unknowns ) {
+               rc = parse_debug_unknowns( debug_unknowns, &slap_debug );
+               ldap_charray_free( debug_unknowns );
+               debug_unknowns = NULL;
+               if ( rc )
+                       goto destroy;
+       }
+       if ( syslog_unknowns ) {
+               rc = parse_debug_unknowns( syslog_unknowns, &ldap_syslog );
+               ldap_charray_free( syslog_unknowns );
+               syslog_unknowns = NULL;
+               if ( rc )
+                       goto destroy;
+       }       
+
+       if ( check & CHECK_LOGLEVEL ) {
+               rc = 0;
+               goto destroy;
+       }
+
        if ( check & CHECK_CONFIG ) {
                fprintf( stderr, "config check succeeded\n" );
 
@@ -745,19 +811,13 @@ unhandled_option:;
        }
 
        {
-               void *def_ctx = NULL;
-
-               /* Save existing default ctx, if any */
-               ldap_pvt_tls_get_option( NULL, LDAP_OPT_X_TLS_CTX, &def_ctx );
+               int opt = 1;
 
                /* Force new ctx to be created */
-               ldap_pvt_tls_set_option( NULL, LDAP_OPT_X_TLS_CTX, NULL );
-
-               rc = ldap_pvt_tls_init_def_ctx( 1 );
+               rc = ldap_pvt_tls_set_option( slap_tls_ld, LDAP_OPT_X_TLS_NEWCTX, &opt );
                if( rc == 0 ) {
-                       ldap_pvt_tls_get_option( NULL, LDAP_OPT_X_TLS_CTX, &slap_tls_ctx );
-                       /* Restore previous ctx */
-                       ldap_pvt_tls_set_option( NULL, LDAP_OPT_X_TLS_CTX, def_ctx );
+                       /* The ctx's refcount is bumped up here */
+                       ldap_pvt_tls_get_option( slap_tls_ld, LDAP_OPT_X_TLS_CTX, &slap_tls_ctx );
                        load_extop( &slap_EXOP_START_TLS, 0, starttls_extop );
                } else if ( rc != LDAP_NOT_SUPPORTED ) {
                        Debug( LDAP_DEBUG_ANY,
@@ -881,6 +941,9 @@ shutdown:
        rc |= slap_shutdown( NULL );
 
 destroy:
+       if ( check & CHECK_LOGLEVEL ) {
+               (void)loglevel_print( stdout );
+       }
        /* remember an error during destroy */
        rc |= slap_destroy();
 
@@ -926,9 +989,15 @@ stop:
        lutil_passwd_destroy();
 
 #ifdef HAVE_TLS
+       if ( slap_tls_ld ) {
+               SSL_CTX_free( slap_tls_ctx );
+               ldap_unbind_ext( slap_tls_ld, NULL, NULL );
+       }
        ldap_pvt_tls_destroy();
 #endif
 
+       slap_sasl_regexp_destroy();
+
        if ( slapd_pid_file_unlink ) {
                unlink( slapd_pid_file );
        }
@@ -945,6 +1014,9 @@ stop:
        if ( urls )
                ch_free( urls );
 
+       /* kludge, get symbols referenced */
+       tavl_free( NULL, NULL );
+
 #ifdef CSRIMALLOC
        mal_dumpleaktrace( leakfile );
 #endif