X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=servers%2Fslapd%2Fmain.c;h=41d66907d9108d8f66d91b5a13a7b1c71e1fde50;hb=b508c611a6582fc9f23e0094b26a89b7c075131a;hp=4f6360f62693d5827a320adc98697094c6ac39ac;hpb=a99e5846b384ab8dbd5a33ca68312abdeb744573;p=openldap diff --git a/servers/slapd/main.c b/servers/slapd/main.c index 4f6360f626..41d66907d9 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-2005 The OpenLDAP Foundation. + * Copyright 1998-2011 The OpenLDAP Foundation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -65,7 +65,7 @@ static struct sockaddr_in bind_addr; typedef int (MainFunc) LDAP_P(( int argc, char *argv[] )); extern MainFunc slapadd, slapcat, slapdn, slapindex, slappasswd, - slaptest, slapauth, slapacl; + slaptest, slapauth, slapacl, slapschema, slapmodify; static struct { char *name; @@ -75,7 +75,9 @@ static struct { {"slapcat", slapcat}, {"slapdn", slapdn}, {"slapindex", slapindex}, + {"slapmodify", slapmodify}, {"slappasswd", slappasswd}, + {"slapschema", slapschema}, {"slaptest", slaptest}, {"slapauth", slapauth}, {"slapacl", slapacl}, @@ -98,51 +100,26 @@ const char Versionstr[] = OPENLDAP_PACKAGE " " OPENLDAP_VERSION " Standalone LDAP Server (slapd)"; #endif -#ifdef LOG_LOCAL4 -#define DEFAULT_SYSLOG_USER LOG_LOCAL4 - -typedef struct _str2intDispatch { - char *stringVal; - int abbr; - int intVal; -} STRDISP, *STRDISP_P; - -/* table to compute syslog-options to integer */ -static STRDISP syslog_types[] = { - { "LOCAL0", sizeof("LOCAL0"), LOG_LOCAL0 }, - { "LOCAL1", sizeof("LOCAL1"), LOG_LOCAL1 }, - { "LOCAL2", sizeof("LOCAL2"), LOG_LOCAL2 }, - { "LOCAL3", sizeof("LOCAL3"), LOG_LOCAL3 }, - { "LOCAL4", sizeof("LOCAL4"), LOG_LOCAL4 }, - { "LOCAL5", sizeof("LOCAL5"), LOG_LOCAL5 }, - { "LOCAL6", sizeof("LOCAL6"), LOG_LOCAL6 }, - { "LOCAL7", sizeof("LOCAL7"), LOG_LOCAL7 }, -#ifdef LOG_USER - { "USER", sizeof("USER"), LOG_USER }, -#endif -#ifdef LOG_DAEMON - { "DAEMON", sizeof("DAEMON"), LOG_DAEMON }, -#endif - { NULL, 0, 0 } -}; - -static int cnvt_str2int( char *, STRDISP_P, int ); -#endif /* LOG_LOCAL4 */ +extern OverlayInit slap_oinfo[]; +extern BackendInfo slap_binfo[]; -#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; +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; @@ -181,10 +158,151 @@ 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 +int +parse_syslog_user( const char *arg, int *syslogUser ) +{ + static slap_verbmasks syslogUsers[] = { + { BER_BVC( "LOCAL0" ), LOG_LOCAL0 }, + { BER_BVC( "LOCAL1" ), LOG_LOCAL1 }, + { BER_BVC( "LOCAL2" ), LOG_LOCAL2 }, + { BER_BVC( "LOCAL3" ), LOG_LOCAL3 }, + { BER_BVC( "LOCAL4" ), LOG_LOCAL4 }, + { BER_BVC( "LOCAL5" ), LOG_LOCAL5 }, + { BER_BVC( "LOCAL6" ), LOG_LOCAL6 }, + { BER_BVC( "LOCAL7" ), LOG_LOCAL7 }, +#ifdef LOG_USER + { BER_BVC( "USER" ), LOG_USER }, +#endif /* LOG_USER */ +#ifdef LOG_DAEMON + { BER_BVC( "DAEMON" ), LOG_DAEMON }, +#endif /* LOG_DAEMON */ + { BER_BVNULL, 0 } + }; + int i = verb_to_mask( arg, syslogUsers ); + + if ( BER_BVISNULL( &syslogUsers[ i ].word ) ) { + Debug( LDAP_DEBUG_ANY, + "unrecognized syslog user \"%s\".\n", + arg, 0, 0 ); + return 1; + } + + *syslogUser = syslogUsers[ i ].mask; + + return 0; +} +#endif /* LOG_LOCAL4 */ + +int +parse_syslog_level( const char *arg, int *levelp ) +{ + static slap_verbmasks str2syslog_level[] = { + { BER_BVC( "EMERG" ), LOG_EMERG }, + { BER_BVC( "ALERT" ), LOG_ALERT }, + { BER_BVC( "CRIT" ), LOG_CRIT }, + { BER_BVC( "ERR" ), LOG_ERR }, + { BER_BVC( "WARNING" ), LOG_WARNING }, + { BER_BVC( "NOTICE" ), LOG_NOTICE }, + { BER_BVC( "INFO" ), LOG_INFO }, + { BER_BVC( "DEBUG" ), LOG_DEBUG }, + { BER_BVNULL, 0 } + }; + int i = verb_to_mask( arg, str2syslog_level ); + if ( BER_BVISNULL( &str2syslog_level[ i ].word ) ) { + Debug( LDAP_DEBUG_ANY, + "unknown syslog level \"%s\".\n", + arg, 0, 0 ); + return 1; + } + + *levelp = str2syslog_level[ i ].mask; + + 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, char ***unknowns ) +{ + int level; + + if ( arg && arg[ 0 ] != '-' && !isdigit( (unsigned char) 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 { + int rc; + + if ( arg[0] == '-' ) { + rc = lutil_atoix( &level, arg, 0 ); + } else { + unsigned ulevel; + + rc = lutil_atoux( &ulevel, arg, 0 ); + level = (int)ulevel; + } + + if ( rc ) { + 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 ) { @@ -193,7 +311,7 @@ usage( char *name ) fprintf( stderr, "\t-4\t\tIPv4 only\n" "\t-6\t\tIPv6 only\n" - "\t-T {acl|add|auth|cat|dn|index|passwd|test}\n" + "\t-T {acl|add|auth|cat|dn|index|modify|passwd|test}\n" "\t\t\tRun in Tool mode\n" "\t-c cookie\tSync cookie of consumer\n" "\t-d level\tDebug level" "\n" @@ -203,7 +321,7 @@ usage( char *name ) "\t-g group\tGroup (id or name) to run as\n" #endif "\t-h URLs\t\tList of URLs to serve\n" -#ifdef LOG_LOCAL4 +#ifdef SLAP_DEFAULT_SYSLOG_USER "\t-l facility\tSyslog facility (default: LOCAL4)\n" #endif "\t-n serverName\tService name\n" @@ -226,7 +344,8 @@ usage( char *name ) #if defined(HAVE_SETUID) && defined(HAVE_SETGID) "\t-u user\t\tUser (id or name) to run as\n" #endif - "\t-V\t\tprint version info (-VV only)\n" + "\t-V\t\tprint version info (-VV exit afterwards, -VVV print\n" + "\t\t\tinfo about static overlays and backends)\n" ); } @@ -246,32 +365,41 @@ int main( int argc, char **argv ) #if defined(HAVE_CHROOT) char *sandbox = NULL; #endif -#ifdef LOG_LOCAL4 - int syslogUser = DEFAULT_SYSLOG_USER; +#ifdef SLAP_DEFAULT_SYSLOG_USER + int syslogUser = SLAP_DEFAULT_SYSLOG_USER; #endif int g_argc = argc; char **g_argv = argv; - char *configfile = NULL; - char *configdir = NULL; - char *serverName; - int serverMode = SLAP_SERVER_MODE; + char *configfile = NULL; + char *configdir = NULL; + char *serverName; + int serverMode = SLAP_SERVER_MODE; 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; 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" ) ) { @@ -285,7 +413,7 @@ int main( int argc, char **argv ) #ifdef HAVE_NT_SERVICE_MANAGER { - int *i; + int *ip; char *newConfigFile; char *newConfigDir; char *newUrls; @@ -297,9 +425,9 @@ int main( int argc, char **argv ) regService = serverName; } - i = (int*)lutil_getRegParam( regService, "DebugLevel" ); - if ( i != NULL ) { - slap_debug = *i; + ip = (int*)lutil_getRegParam( regService, "DebugLevel" ); + if ( ip != NULL ) { + slap_debug = *ip; Debug( LDAP_DEBUG_ANY, "new debug level from registry is: %d\n", slap_debug, 0, 0 ); } @@ -329,18 +457,21 @@ int main( int argc, char **argv ) #endif while ( (i = getopt( argc, argv, - "c:d:f:F:h:n:o:s:StT:V" -#if LDAP_PF_INET6 + "c:d:f:F:h:n:o:s:tT:V" +#ifdef LDAP_PF_INET6 "46" #endif #ifdef HAVE_CHROOT "r:" #endif +#if defined(LDAP_DEBUG) && defined(LDAP_SYSLOG) + "S:" #ifdef LOG_LOCAL4 - "l:" + "l:" +#endif #endif #if defined(HAVE_SETUID) && defined(HAVE_SETGID) - "u:g:" + "u:g:" #endif )) != EOF ) { switch ( i ) { @@ -362,8 +493,18 @@ int main( int argc, char **argv ) scp = (struct sync_cookie *) ch_calloc( 1, sizeof( struct sync_cookie )); 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 ) { Debug( LDAP_DEBUG_ANY, @@ -376,30 +517,26 @@ 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 */ - no_detach = 1; -#ifdef LDAP_DEBUG - if ( optarg != NULL && optarg[ 0 ] != '-' && !isdigit( optarg[ 0 ] ) ) - { - int level; - - if ( str2loglevel( optarg, &level ) ) { - fprintf( stderr, - "unrecognized log level " - "\"%s\"\n", optarg ); - goto destroy; - } + case 'd': { /* set debug level and 'do not detach' flag */ + int level = 0; - slap_debug |= level; - } else { - slap_debug |= atoi( optarg ); + if ( strcmp( optarg, "?" ) == 0 ) { + check |= CHECK_LOGLEVEL; + break; + } + + no_detach = 1; + if ( parse_debug_level( optarg, &level, &debug_unknowns ) ) { + goto destroy; } +#ifdef LDAP_DEBUG + 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 ); @@ -412,7 +549,6 @@ int main( int argc, char **argv ) case 'o': { char *val = strchr( optarg, '=' ); struct berval opt; - int i; opt.bv_val = optarg; @@ -444,15 +580,31 @@ int main( int argc, char **argv ) } case 's': /* set syslog level */ - ldap_syslog = atoi( optarg ); + if ( strcmp( optarg, "?" ) == 0 ) { + check |= CHECK_LOGLEVEL; + break; + } + + if ( parse_debug_level( optarg, &ldap_syslog, &syslog_unknowns ) ) { + goto destroy; + } + break; + +#if defined(LDAP_DEBUG) && defined(LDAP_SYSLOG) + case 'S': + if ( parse_syslog_level( optarg, &ldap_syslog_level ) ) { + goto destroy; + } break; #ifdef LOG_LOCAL4 case 'l': /* set syslog local user */ - syslogUser = cnvt_str2int( optarg, - syslog_types, DEFAULT_SYSLOG_USER ); + if ( parse_syslog_user( optarg, &syslogUser ) ) { + goto destroy; + } break; #endif +#endif /* LDAP_DEBUG && LDAP_SYSLOG */ #ifdef HAVE_CHROOT case 'r': @@ -489,6 +641,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 ) { @@ -519,9 +677,14 @@ unhandled_option:; SERVICE_EXIT( ERROR_SERVICE_SPECIFIC_ERROR, 15 ); goto stop; } + + if ( firstopt ) { + firstopt = 0; + } } - (void) ldap_pvt_thread_initialize(); + if ( optind != argc ) + goto unhandled_option; ber_set_option(NULL, LBER_OPT_DEBUG_LEVEL, &slap_debug); ldap_set_option(NULL, LDAP_OPT_DEBUG_LEVEL, &slap_debug); @@ -529,9 +692,25 @@ unhandled_option:; if ( version ) { fprintf( stderr, "%s\n", Versionstr ); + if ( version > 2 ) { + if ( slap_oinfo[0].ov_type ) { + fprintf( stderr, "Included static overlays:\n"); + for ( i= 0 ; slap_oinfo[i].ov_type; i++ ) { + fprintf( stderr, " %s\n", slap_oinfo[i].ov_type ); + } + } + if ( slap_binfo[0].bi_type ) { + fprintf( stderr, "Included static backends:\n"); + for ( i= 0 ; slap_binfo[i].bi_type; i++ ) { + fprintf( stderr, " %s\n", slap_binfo[i].bi_type ); + } + } + } + if ( version > 1 ) goto stop; } +#if defined(LDAP_DEBUG) && defined(LDAP_SYSLOG) { char *logName; #ifdef HAVE_EBCDIC @@ -543,16 +722,20 @@ unhandled_option:; #ifdef LOG_LOCAL4 openlog( logName, OPENLOG_OPTIONS, syslogUser ); -#elif LOG_DEBUG +#elif defined LOG_DEBUG openlog( logName, OPENLOG_OPTIONS ); #endif #ifdef HAVE_EBCDIC free( logName ); #endif } +#endif /* LDAP_DEBUG && LDAP_SYSLOG */ Debug( LDAP_DEBUG_ANY, "%s", Versionstr, 0, 0 ); + global_host = ldap_pvt_get_fqdn( NULL ); + ber_str2bv( global_host, 0, 0, &global_host_bv ); + if( check == CHECK_NONE && slapd_daemon_init( urls ) != 0 ) { rc = 1; SERVICE_EXIT( ERROR_SERVICE_SPECIFIC_ERROR, 16 ); @@ -582,61 +765,27 @@ unhandled_option:; extops_init(); 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 ) { - Debug( LDAP_DEBUG_ANY, - "schema initialization error\n", - 0, 0, 0 ); - - goto destroy; - } - - if ( slap_init( serverMode, serverName ) != 0 ) { - rc = 1; - SERVICE_EXIT( ERROR_SERVICE_SPECIFIC_ERROR, 18 ); - goto destroy; - } - - if ( slap_controls_init( ) != 0 ) { - Debug( LDAP_DEBUG_ANY, - "controls initialization error\n", - 0, 0, 0 ); +#ifdef HAVE_TLS + rc = ldap_create( &slap_tls_ld ); + if ( rc ) { + SERVICE_EXIT( ERROR_SERVICE_SPECIFIC_ERROR, 20 ); 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 ); + rc = LDAP_OPT_X_TLS_NEVER; + (void) ldap_pvt_tls_set_option( slap_tls_ld, LDAP_OPT_X_TLS_REQUIRE_CERT, &rc ); #endif - if ( frontend_init() ) { - goto destroy; - } - - if ( overlay_init() ) { - goto destroy; - } - -#ifdef SLAP_DYNACL - if ( acl_init() ) { + rc = slap_init( serverMode, serverName ); + if ( rc ) { + SERVICE_EXIT( ERROR_SERVICE_SPECIFIC_ERROR, 18 ); goto destroy; } -#endif /* SLAP_DYNACL */ if ( read_config( configfile, configdir ) != 0 ) { rc = 1; @@ -649,6 +798,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" ); @@ -659,6 +828,14 @@ unhandled_option:; } } + if ( glue_sub_attach( 0 ) != 0 ) { + Debug( LDAP_DEBUG_ANY, + "subordinate config error\n", + 0, 0, 0 ); + + goto destroy; + } + if ( slap_schema_check( ) != 0 ) { Debug( LDAP_DEBUG_ANY, "schema prep error\n", @@ -679,16 +856,15 @@ 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(); - if( rc != 0) { + rc = ldap_pvt_tls_set_option( slap_tls_ld, LDAP_OPT_X_TLS_NEWCTX, &opt ); + if( rc == 0 ) { + /* 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, "main: TLS init def ctx failed: %d\n", rc, 0, 0 ); @@ -696,10 +872,12 @@ unhandled_option:; 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 + +#ifdef HAVE_CYRUS_SASL + if( sasl_host == NULL ) { + sasl_host = ch_strdup( global_host ); } #endif @@ -733,49 +911,70 @@ 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; - } - - Debug( LDAP_DEBUG_ANY, "slapd starting\n", 0, 0, 0 ); - - 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 ); + + connections_init(); + + 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 ? @@ -795,6 +994,9 @@ shutdown: rc |= slap_shutdown( NULL ); destroy: + if ( check & CHECK_LOGLEVEL ) { + (void)loglevel_print( stdout ); + } /* remember an error during destroy */ rc |= slap_destroy(); @@ -808,10 +1010,11 @@ destroy: module_kill(); #endif - slap_op_destroy(); - extops_kill(); + supported_feature_destroy(); + entry_info_destroy(); + stop: #ifdef HAVE_NT_EVENT_LOG if (is_NT_Service) @@ -832,18 +1035,26 @@ stop: controls_destroy(); + filter_destroy(); + schema_destroy(); lutil_passwd_destroy(); #ifdef HAVE_TLS + if ( slap_tls_ld ) { + ldap_pvt_tls_ctx_free( slap_tls_ctx ); + ldap_unbind_ext( slap_tls_ld, NULL, NULL ); + } ldap_pvt_tls_destroy(); #endif - if ( slapd_pid_file != NULL ) { + slap_sasl_regexp_destroy(); + + if ( slapd_pid_file_unlink ) { unlink( slapd_pid_file ); } - if ( slapd_args_file != NULL ) { + if ( slapd_args_file_unlink ) { unlink( slapd_args_file ); } @@ -855,6 +1066,11 @@ stop: ch_free( configdir ); if ( urls ) ch_free( urls ); + if ( global_host ) + ch_free( global_host ); + + /* kludge, get symbols referenced */ + tavl_free( NULL, NULL ); #ifdef CSRIMALLOC mal_dumpleaktrace( leakfile ); @@ -876,13 +1092,12 @@ wait4child( int sig ) int save_errno = errno; #ifdef WNOHANG - errno = 0; + do + errno = 0; #ifdef HAVE_WAITPID - while ( waitpid( (pid_t)-1, NULL, WNOHANG ) > 0 || errno == EINTR ) - ; /* NULL */ + while ( waitpid( (pid_t)-1, NULL, WNOHANG ) > 0 || errno == EINTR ); #else - while ( wait3( NULL, WNOHANG, NULL ) > 0 || errno == EINTR ) - ; /* NULL */ + while ( wait3( NULL, WNOHANG, NULL ) > 0 || errno == EINTR ); #endif #else (void) wait( NULL ); @@ -892,32 +1107,3 @@ wait4child( int sig ) } #endif /* LDAP_SIGCHLD */ - - -#ifdef LOG_LOCAL4 - -/* - * Convert a string to an integer by means of a dispatcher table - * if the string is not in the table return the default - */ - -static int -cnvt_str2int( char *stringVal, STRDISP_P dispatcher, int defaultVal ) -{ - int retVal = defaultVal; - STRDISP_P disp; - - for (disp = dispatcher; disp->stringVal; disp++) { - - if (!strncasecmp (stringVal, disp->stringVal, disp->abbr)) { - - retVal = disp->intVal; - break; - - } - } - - return (retVal); -} - -#endif /* LOG_LOCAL4 */