X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;ds=sidebyside;f=servers%2Fslapd%2Fmain.c;h=7c88dd93d0f04e976ef635a743039c6059926d75;hb=fbd3c1c5fe8560db51cedcb2f710d9cda3ff3cc8;hp=47012f76692ae368a3d8d259c8692089d052c4f5;hpb=cd9a9c628dd08435dff10b25eb9c6de5f7f4a604;p=openldap diff --git a/servers/slapd/main.c b/servers/slapd/main.c index 47012f7669..7c88dd93d0 100644 --- a/servers/slapd/main.c +++ b/servers/slapd/main.c @@ -1,7 +1,7 @@ /* $OpenLDAP$ */ /* This work is part of OpenLDAP Software . * - * Copyright 1998-2004 The OpenLDAP Foundation. + * Copyright 1998-2006 The OpenLDAP Foundation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -27,6 +27,7 @@ #include +#include #include #include #include @@ -34,8 +35,6 @@ #include #include -#include "ldap_pvt.h" - #include "slap.h" #include "lutil.h" #include "ldif.h" @@ -183,9 +182,74 @@ struct option_helper { const char *oh_usage; } option_helpers[] = { { BER_BVC("slp"), slapd_opt_slp, NULL, "slp[={on|off}] enable/disable SLP" }, - { BER_BVNULL } + { BER_BVNULL, 0, NULL, NULL } }; +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, char ***unknowns ) +{ + int level; + + if ( arg != NULL && arg[ 0 ] != '-' && !isdigit( arg[ 0 ] ) ) + { + int i; + char **levels; + + levels = ldap_str2charray( arg, "," ); + + for ( i = 0; levels[ i ] != NULL; i++ ) { + level = 0; + + if ( str2loglevel( levels[ i ], &level ) ) { + /* remember this for later */ + ldap_charray_add( unknowns, levels[ i ] ); + fprintf( stderr, + "unrecognized log level \"%s\" (deferred)\n", + levels[ i ] ); + } else { + *levelp |= level; + } + } + + ldap_charray_free( levels ); + + } else { + if ( lutil_atoix( &level, arg, 0 ) != 0 ) { + fprintf( stderr, + "unrecognized log level " + "\"%s\"\n", arg ); + return 1; + } + + if ( level == 0 ) { + *levelp = 0; + + } else { + *levelp |= level; + } + } + + return 0; +} + static void usage( char *name ) { @@ -194,11 +258,12 @@ usage( char *name ) fprintf( stderr, "\t-4\t\tIPv4 only\n" "\t-6\t\tIPv6 only\n" - "\t-T {add|auth|cat|dn|index|passwd|test}\n" + "\t-T {acl|add|auth|cat|dn|index|passwd|test}\n" "\t\t\tRun in Tool mode\n" "\t-c cookie\tSync cookie of consumer\n" "\t-d level\tDebug level" "\n" "\t-f filename\tConfiguration file\n" + "\t-F dir\tConfiguration directory\n" #if defined(HAVE_SETUID) && defined(HAVE_SETGID) "\t-g group\tGroup (id or name) to run as\n" #endif @@ -207,7 +272,7 @@ usage( char *name ) "\t-l facility\tSyslog facility (default: LOCAL4)\n" #endif "\t-n serverName\tService name\n" - "\t-o [=val] Generic means to specify options" ); + "\t-o [=val] generic means to specify options" ); if ( !BER_BVISNULL( &option_helpers[0].oh_name ) ) { int i; @@ -247,35 +312,39 @@ int main( int argc, char **argv ) char *sandbox = NULL; #endif #ifdef LOG_LOCAL4 - int syslogUser = DEFAULT_SYSLOG_USER; + int syslogUser = DEFAULT_SYSLOG_USER; #endif int g_argc = argc; char **g_argv = argv; -#ifdef HAVE_NT_SERVICE_MANAGER - char *configfile = ".\\slapd.conf"; -#else - char *configfile = SLAPD_DEFAULT_CONFIGFILE; -#endif - char *serverName; - int serverMode = SLAP_SERVER_MODE; + char *configfile = NULL; + char *configdir = NULL; + char *serverName; + int serverMode = SLAP_SERVER_MODE; - struct berval cookie = BER_BVNULL; 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; + #ifdef CSRIMALLOC FILE *leakfile; if( ( leakfile = fopen( "slapd.leak", "w" )) == NULL ) { leakfile = stderr; } #endif - char *serverNamePrefix = ""; - size_t l; slap_sl_mem_init(); + (void) ldap_pvt_thread_initialize(); + serverName = lutil_progname( "slapd", argc, argv ); if ( strcmp( serverName, "slapd" ) ) { @@ -291,6 +360,7 @@ int main( int argc, char **argv ) { int *i; char *newConfigFile; + char *newConfigDir; char *newUrls; char *regService = NULL; @@ -303,15 +373,8 @@ int main( int argc, char **argv ) i = (int*)lutil_getRegParam( regService, "DebugLevel" ); if ( i != NULL ) { slap_debug = *i; -#ifdef NEW_LOGGING - lutil_log_initialize( argc, argv ); - LDAP_LOG( SLAPD, INFO, - "main: new debug level from registry is: %d\n", - slap_debug, 0, 0 ); -#else Debug( LDAP_DEBUG_ANY, "new debug level from registry is: %d\n", slap_debug, 0, 0 ); -#endif } newUrls = (char *) lutil_getRegParam(regService, "Urls"); @@ -320,30 +383,26 @@ int main( int argc, char **argv ) ch_free(urls); urls = ch_strdup(newUrls); -#ifdef NEW_LOGGING - LDAP_LOG( SLAPD, INFO, - "main: new urls from registry: %s\n", urls, 0, 0 ); -#else Debug(LDAP_DEBUG_ANY, "new urls from registry: %s\n", urls, 0, 0); -#endif } newConfigFile = (char*)lutil_getRegParam( regService, "ConfigFile" ); if ( newConfigFile != NULL ) { configfile = newConfigFile; -#ifdef NEW_LOGGING - LDAP_LOG( SLAPD, INFO, - "main: new config file from registry is: %s\n", configfile, 0, 0 ); -#else Debug ( LDAP_DEBUG_ANY, "new config file from registry is: %s\n", configfile, 0, 0 ); -#endif + } + + newConfigDir = (char*)lutil_getRegParam( regService, "ConfigDir" ); + if ( newConfigDir != NULL ) { + configdir = newConfigDir; + Debug ( LDAP_DEBUG_ANY, "new config dir from registry is: %s\n", configdir, 0, 0 ); } } #endif while ( (i = getopt( argc, argv, - "c:d:f:h:n:o:s:StT:V" + "c:d:f:F:h:n:o:s:tT:V" #if LDAP_PF_INET6 "46" #endif @@ -375,21 +434,24 @@ int main( int argc, char **argv ) case 'c': /* provide sync cookie, override if exist in replica */ scp = (struct sync_cookie *) ch_calloc( 1, sizeof( struct sync_cookie )); - ber_str2bv( optarg, strlen( optarg ), 1, &cookie ); - ber_bvarray_add( &scp->octet_str, &cookie ); - slap_parse_sync_cookie( scp ); + ber_str2bv( optarg, 0, 1, &scp->octet_str ); + + /* This only parses out the rid at this point */ + slap_parse_sync_cookie( scp, NULL ); + + if ( scp->rid == -1 ) { + Debug( LDAP_DEBUG_ANY, + "main: invalid cookie \"%s\"\n", + optarg, 0, 0 ); + slap_sync_cookie_free( scp, 1 ); + goto destroy; + } LDAP_STAILQ_FOREACH( scp_entry, &slap_sync_cookie, sc_next ) { if ( scp->rid == scp_entry->rid ) { -#ifdef NEW_LOGGING - LDAP_LOG( OPERATION, CRIT, - "main: duplicated replica id in cookies\n", - 0, 0, 0 ); -#else Debug( LDAP_DEBUG_ANY, "main: duplicated replica id in cookies\n", 0, 0, 0 ); -#endif slap_sync_cookie_free( scp, 1 ); goto destroy; } @@ -397,21 +459,30 @@ int main( int argc, char **argv ) LDAP_STAILQ_INSERT_TAIL( &slap_sync_cookie, scp, sc_next ); break; - case 'd': /* set debug level and 'do not detach' flag */ + case 'd': { /* set debug level and 'do not detach' flag */ + int level = 0; + no_detach = 1; + if ( parse_debug_level( optarg, &level, &debug_unknowns ) ) { + goto destroy; + } #ifdef LDAP_DEBUG - slap_debug |= atoi( optarg ); + slap_debug |= level; #else - if ( atoi( optarg ) != 0 ) + if ( level != 0 ) fputs( "must compile with LDAP_DEBUG for debugging\n", stderr ); #endif - break; + } break; case 'f': /* read config file */ configfile = ch_strdup( optarg ); break; + case 'F': /* use config dir */ + configdir = ch_strdup( optarg ); + break; + case 'o': { char *val = strchr( optarg, '=' ); struct berval opt; @@ -447,7 +518,9 @@ int main( int argc, char **argv ) } case 's': /* set syslog level */ - ldap_syslog = atoi( optarg ); + if ( parse_debug_level( optarg, &ldap_syslog, &syslog_unknowns ) ) { + goto destroy; + } break; #ifdef LOG_LOCAL4 @@ -524,14 +597,9 @@ unhandled_option:; } } -#ifdef NEW_LOGGING - lutil_log_initialize( argc, argv ); -#else - lutil_set_debug_level( "slapd", slap_debug ); ber_set_option(NULL, LBER_OPT_DEBUG_LEVEL, &slap_debug); ldap_set_option(NULL, LDAP_OPT_DEBUG_LEVEL, &slap_debug); ldif_debug = slap_debug; -#endif if ( version ) { fprintf( stderr, "%s\n", Versionstr ); @@ -557,11 +625,7 @@ unhandled_option:; #endif } -#ifdef NEW_LOGGING - LDAP_LOG( SLAPD, INFO, "%s", Versionstr, 0, 0 ); -#else Debug( LDAP_DEBUG_ANY, "%s", Versionstr, 0, 0 ); -#endif if( check == CHECK_NONE && slapd_daemon_init( urls ) != 0 ) { rc = 1; @@ -594,77 +658,13 @@ unhandled_option:; lutil_passwd_init(); slap_op_init(); -#ifdef SLAPD_MODULES - if ( module_init() != 0 ) { - rc = 1; - SERVICE_EXIT( ERROR_SERVICE_SPECIFIC_ERROR, 17 ); - goto destroy; - } -#endif - - if ( slap_schema_init( ) != 0 ) { -#ifdef NEW_LOGGING - LDAP_LOG( OPERATION, CRIT, "main: schema initialization error\n", 0, 0, 0 ); -#else - Debug( LDAP_DEBUG_ANY, - "schema initialization error\n", - 0, 0, 0 ); -#endif - - goto destroy; - } - - if ( slap_init( serverMode, serverName ) != 0 ) { - rc = 1; + rc = slap_init( serverMode, serverName ); + if ( rc ) { SERVICE_EXIT( ERROR_SERVICE_SPECIFIC_ERROR, 18 ); goto destroy; } - if ( slap_controls_init( ) != 0 ) { -#ifdef NEW_LOGGING - LDAP_LOG( OPERATION, CRIT, "main: controls initialization error\n", 0, 0, 0 ); -#else - Debug( LDAP_DEBUG_ANY, - "controls initialization error\n", - 0, 0, 0 ); -#endif - - goto destroy; - } - -#ifdef HAVE_TLS - /* Library defaults to full certificate checking. This is correct when - * a client is verifying a server because all servers should have a - * valid cert. But few clients have valid certs, so we want our default - * to be no checking. The config file can override this as usual. - */ - rc = 0; - (void) ldap_pvt_tls_set_option( NULL, LDAP_OPT_X_TLS_REQUIRE_CERT, &rc ); -#endif - -#ifdef LDAP_SLAPI - if ( slapi_int_initialize() != 0 ) { -#ifdef NEW_LOGGING - LDAP_LOG( OPERATION, CRIT, "main: slapi initialization error\n", 0, 0, 0 ); -#else - Debug( LDAP_DEBUG_ANY, - "slapi initialization error\n", - 0, 0, 0 ); -#endif - - goto destroy; - } -#endif /* LDAP_SLAPI */ - - if ( frontend_init() ) { - goto destroy; - } - - if ( overlay_init() ) { - goto destroy; - } - - if ( read_config( configfile, 0 ) != 0 ) { + if ( read_config( configfile, configdir ) != 0 ) { rc = 1; SERVICE_EXIT( ERROR_SERVICE_SPECIFIC_ERROR, 19 ); @@ -675,6 +675,21 @@ 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_CONFIG ) { fprintf( stderr, "config check succeeded\n" ); @@ -685,25 +700,18 @@ unhandled_option:; } } - if ( glue_sub_init( ) != 0 ) { -#ifdef NEW_LOGGING - LDAP_LOG( SLAPD, CRIT, "main: subordinate config error\n", 0, 0, 0 ); -#else + if ( glue_sub_attach( ) != 0 ) { Debug( LDAP_DEBUG_ANY, "subordinate config error\n", 0, 0, 0 ); -#endif + goto destroy; } if ( slap_schema_check( ) != 0 ) { -#ifdef NEW_LOGGING - LDAP_LOG( SLAPD, CRIT, "main: schema prep error\n", 0, 0, 0 ); -#else Debug( LDAP_DEBUG_ANY, "schema prep error\n", 0, 0, 0 ); -#endif goto destroy; } @@ -711,13 +719,9 @@ unhandled_option:; #ifdef HAVE_TLS rc = ldap_pvt_tls_init(); if( rc != 0) { -#ifdef NEW_LOGGING - LDAP_LOG( SLAPD, CRIT, "main: tls init failed: %d\n", rc, 0, 0 ); -#else Debug( LDAP_DEBUG_ANY, "main: TLS init failed: %d\n", 0, 0, 0 ); -#endif rc = 1; SERVICE_EXIT( ERROR_SERVICE_SPECIFIC_ERROR, 20 ); goto destroy; @@ -732,23 +736,20 @@ unhandled_option:; /* 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(); - if( rc != 0) { -#ifdef NEW_LOGGING - LDAP_LOG( SLAPD, CRIT, "main: tls init def ctx failed: %d\n", rc, 0, 0 ); -#else + rc = ldap_pvt_tls_init_def_ctx( 1 ); + 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 ); + load_extop( &slap_EXOP_START_TLS, 0, starttls_extop ); + } else if ( rc != LDAP_NOT_SUPPORTED ) { Debug( LDAP_DEBUG_ANY, "main: TLS init def ctx failed: %d\n", rc, 0, 0 ); -#endif rc = 1; SERVICE_EXIT( ERROR_SERVICE_SPECIFIC_ERROR, 20 ); goto destroy; } - /* Retrieve slapd's own ctx */ - 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 ); } #endif @@ -763,6 +764,9 @@ unhandled_option:; #endif (void) SIGNAL( SIGINT, slap_sig_shutdown ); (void) SIGNAL( SIGTERM, slap_sig_shutdown ); +#ifdef SIGTRAP + (void) SIGNAL( SIGTRAP, slap_sig_shutdown ); +#endif #ifdef LDAP_SIGCHLD (void) SIGNAL( LDAP_SIGCHLD, wait4child ); #endif @@ -779,56 +783,72 @@ unhandled_option:; mal_leaktrace(1); #endif - /* - * FIXME: moved here from slapd_daemon_task() - * because back-monitor db_open() needs it - */ - time( &starttime ); - - if ( slap_startup( NULL ) != 0 ) { - rc = 1; - SERVICE_EXIT( ERROR_SERVICE_SPECIFIC_ERROR, 21 ); - goto shutdown; - } - -#ifdef NEW_LOGGING - LDAP_LOG( SLAPD, INFO, "main: slapd starting.\n", 0, 0, 0 ); -#else - Debug( LDAP_DEBUG_ANY, "slapd starting\n", 0, 0, 0 ); -#endif - - if ( slapd_pid_file != NULL ) { FILE *fp = fopen( slapd_pid_file, "w" ); - if( fp != NULL ) { - fprintf( fp, "%d\n", (int) getpid() ); - fclose( fp ); + if ( fp == NULL ) { + int save_errno = errno; - } else { - free(slapd_pid_file); + Debug( LDAP_DEBUG_ANY, "unable to open pid file " + "\"%s\": %d (%s)\n", + slapd_pid_file, + save_errno, strerror( save_errno ) ); + + free( slapd_pid_file ); slapd_pid_file = NULL; + + rc = 1; + goto destroy; } + fprintf( fp, "%d\n", (int) getpid() ); + fclose( fp ); + slapd_pid_file_unlink = 1; } if ( slapd_args_file != NULL ) { FILE *fp = fopen( slapd_args_file, "w" ); - if( fp != NULL ) { - for ( i = 0; i < g_argc; i++ ) { - fprintf( fp, "%s ", g_argv[i] ); - } - fprintf( fp, "\n" ); - fclose( fp ); - } else { - free(slapd_args_file); + if ( fp == NULL ) { + int save_errno = errno; + + Debug( LDAP_DEBUG_ANY, "unable to open args file " + "\"%s\": %d (%s)\n", + slapd_args_file, + save_errno, strerror( save_errno ) ); + + free( slapd_args_file ); slapd_args_file = NULL; + + rc = 1; + goto destroy; + } + + for ( i = 0; i < g_argc; i++ ) { + fprintf( fp, "%s ", g_argv[i] ); } + fprintf( fp, "\n" ); + fclose( fp ); + slapd_args_file_unlink = 1; } + /* + * FIXME: moved here from slapd_daemon_task() + * because back-monitor db_open() needs it + */ + time( &starttime ); + + if ( slap_startup( NULL ) != 0 ) { + rc = 1; + SERVICE_EXIT( ERROR_SERVICE_SPECIFIC_ERROR, 21 ); + goto shutdown; + } + + Debug( LDAP_DEBUG_ANY, "slapd starting\n", 0, 0, 0 ); + #ifdef HAVE_NT_EVENT_LOG if (is_NT_Service) - lutil_LogStartedEvent( serverName, slap_debug, configfile, urls ); + lutil_LogStartedEvent( serverName, slap_debug, configfile ? + configfile : SLAPD_DEFAULT_CONFIGFILE , urls ); #endif rc = slapd_daemon(); @@ -867,11 +887,7 @@ stop: lutil_LogStoppedEvent( serverName ); #endif -#ifdef NEW_LOGGING - LDAP_LOG( SLAPD, CRIT, "main: slapd stopped.\n", 0, 0, 0 ); -#else Debug( LDAP_DEBUG_ANY, "slapd stopped.\n", 0, 0, 0 ); -#endif #ifdef HAVE_NT_SERVICE_MANAGER @@ -893,15 +909,22 @@ stop: ldap_pvt_tls_destroy(); #endif - if ( slapd_pid_file != NULL ) { + if ( slapd_pid_file_unlink ) { unlink( slapd_pid_file ); } - if ( slapd_args_file != NULL ) { + if ( slapd_args_file_unlink ) { unlink( slapd_args_file ); } config_destroy(); + if ( configfile ) + ch_free( configfile ); + if ( configdir ) + ch_free( configdir ); + if ( urls ) + ch_free( urls ); + #ifdef CSRIMALLOC mal_dumpleaktrace( leakfile ); #endif