X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=servers%2Fslapd%2Fslapcommon.c;h=a5d4b4f5c954e5d5afc41385f90b6c041e7b2d63;hb=72e319bd02256465a0e8c8a2bc304ec11de97378;hp=596cbc3182f60a34ed567f90a4511dd8ffb94c64;hpb=ae8a333bc8cae5af14a70a1f388ca64a0b6190cb;p=openldap diff --git a/servers/slapd/slapcommon.c b/servers/slapd/slapcommon.c index 596cbc3182..a5d4b4f5c9 100644 --- a/servers/slapd/slapcommon.c +++ b/servers/slapd/slapcommon.c @@ -2,7 +2,7 @@ /* $OpenLDAP$ */ /* This work is part of OpenLDAP Software . * - * Copyright 1998-2005 The OpenLDAP Foundation. + * Copyright 1998-2009 The OpenLDAP Foundation. * Portions Copyright 1998-2003 Kurt D. Zeilenga. * Portions Copyright 2003 IBM Corporation. * All rights reserved. @@ -47,23 +47,31 @@ static FILE *leakfile; static LDIFFP dummy; +#if defined(LDAP_SYSLOG) && defined(LDAP_DEBUG) +int start_syslog; +static char **syslog_unknowns; +#ifdef LOG_LOCAL4 +static int syslogUser = SLAP_DEFAULT_SYSLOG_USER; +#endif /* LOG_LOCAL4 */ +#endif /* LDAP_DEBUG && LDAP_SYSLOG */ + static void usage( int tool, const char *progname ) { char *options = NULL; fprintf( stderr, - "usage: %s [-v] [-d debuglevel] [-f configfile] [-F configdir]", + "usage: %s [-v] [-d debuglevel] [-f configfile] [-F configdir] [-o [=]]", progname ); switch( tool ) { case SLAPACL: options = "\n\t[-U authcID | -D authcDN] [-X authzID | -o authzDN=]" - "\n\t-b DN -o [=] [-u] [attr[/access][:value]] [...]\n"; + "\n\t-b DN [-u] [attr[/access][:value]] [...]\n"; break; case SLAPADD: - options = " [-c]\n\t[-n databasenumber | -b suffix]\n" - "\t[-l ldiffile] [-q] [-u] [-w]\n"; + options = " [-c]\n\t[-g] [-n databasenumber | -b suffix]\n" + "\t[-l ldiffile] [-j linenumber] [-q] [-u] [-s] [-w]\n"; break; case SLAPAUTH: @@ -71,8 +79,8 @@ usage( int tool, const char *progname ) break; case SLAPCAT: - options = " [-c]\n\t[-n databasenumber | -b suffix]" - " [-l ldiffile] [-a filter]\n"; + options = " [-c]\n\t[-g] [-n databasenumber | -b suffix]" + " [-l ldiffile] [-a filter] [-s subtree]\n"; break; case SLAPDN: @@ -80,12 +88,17 @@ usage( int tool, const char *progname ) break; case SLAPINDEX: - options = " [-c]\n\t[-n databasenumber | -b suffix] [-q]\n"; + options = " [-c]\n\t[-g] [-n databasenumber | -b suffix] [attr ...] [-q] [-t]\n"; break; case SLAPTEST: options = " [-u]\n"; break; + + case SLAPSCHEMA: + options = " [-c]\n\t[-g] [-n databasenumber | -b suffix]" + " [-l errorfile] [-a filter] [-s subtree]\n"; + break; } if ( options != NULL ) { @@ -95,19 +108,17 @@ usage( int tool, const char *progname ) } static int -parse_slapacl( void ) +parse_slapopt( void ) { - size_t len; + size_t len = 0; char *p; p = strchr( optarg, '=' ); - if ( p == NULL ) { - return -1; + if ( p != NULL ) { + len = p - optarg; + p++; } - len = p - optarg; - p++; - if ( strncasecmp( optarg, "sockurl", len ) == 0 ) { if ( !BER_BVISNULL( &listener_url ) ) { ber_memfree( listener_url.bv_val ); @@ -133,20 +144,54 @@ parse_slapacl( void ) ber_str2bv( p, 0, 1, &sock_name ); } else if ( strncasecmp( optarg, "ssf", len ) == 0 ) { - ssf = atoi( p ); + if ( lutil_atou( &ssf, p ) ) { + Debug( LDAP_DEBUG_ANY, "unable to parse ssf=\"%s\".\n", p, 0, 0 ); + return -1; + } } else if ( strncasecmp( optarg, "transport_ssf", len ) == 0 ) { - transport_ssf = atoi( p ); + if ( lutil_atou( &transport_ssf, p ) ) { + Debug( LDAP_DEBUG_ANY, "unable to parse transport_ssf=\"%s\".\n", p, 0, 0 ); + return -1; + } } else if ( strncasecmp( optarg, "tls_ssf", len ) == 0 ) { - tls_ssf = atoi( p ); + if ( lutil_atou( &tls_ssf, p ) ) { + Debug( LDAP_DEBUG_ANY, "unable to parse tls_ssf=\"%s\".\n", p, 0, 0 ); + return -1; + } } else if ( strncasecmp( optarg, "sasl_ssf", len ) == 0 ) { - sasl_ssf = atoi( p ); + if ( lutil_atou( &sasl_ssf, p ) ) { + Debug( LDAP_DEBUG_ANY, "unable to parse sasl_ssf=\"%s\".\n", p, 0, 0 ); + return -1; + } } else if ( strncasecmp( optarg, "authzDN", len ) == 0 ) { ber_str2bv( p, 0, 1, &authzDN ); +#if defined(LDAP_SYSLOG) && defined(LDAP_DEBUG) + } else if ( strncasecmp( optarg, "syslog", len ) == 0 ) { + if ( parse_debug_level( p, &ldap_syslog, &syslog_unknowns ) ) { + return -1; + } + start_syslog = 1; + + } else if ( strncasecmp( optarg, "syslog-level", len ) == 0 ) { + if ( parse_syslog_level( p, &ldap_syslog_level ) ) { + return -1; + } + start_syslog = 1; + +#ifdef LOG_LOCAL4 + } else if ( strncasecmp( optarg, "syslog-user", len ) == 0 ) { + if ( parse_syslog_user( p, &syslogUser ) ) { + return -1; + } + start_syslog = 1; +#endif /* LOG_LOCAL4 */ +#endif /* LDAP_DEBUG && LDAP_SYSLOG */ + } else { return -1; } @@ -162,6 +207,8 @@ parse_slapacl( void ) * argc, argv command line arguments */ +static int need_shutdown; + void slap_tool_init( const char* progname, @@ -175,9 +222,20 @@ slap_tool_init( char *filterstr = NULL; char *subtree = NULL; char *ldiffile = NULL; - int rc, i, dbnum; + char **debug_unknowns = NULL; + int rc, i; int mode = SLAP_TOOL_MODE; int truncatemode = 0; + int use_glue = 1; + int writer; + +#ifdef LDAP_DEBUG + /* tools default to "none", so that at least LDAP_DEBUG_ANY + * messages show up; use -d 0 to reset */ + slap_debug = LDAP_DEBUG_NONE; + ldif_debug = slap_debug; +#endif + ldap_syslog = 0; #ifdef CSRIMALLOC leakfilename = malloc( strlen( progname ) + STRLENOF( ".leak" ) + 1 ); @@ -186,35 +244,41 @@ slap_tool_init( leakfile = stderr; } free( leakfilename ); + leakfilename = NULL; #endif switch( tool ) { case SLAPADD: - options = "b:cd:f:F:l:n:qtuvw"; + options = "b:cd:f:F:gj:l:n:o:qsS:uvw"; break; case SLAPCAT: - options = "a:b:cd:f:F:l:n:s:v"; + options = "a:b:cd:f:F:gl:n:o:s:v"; mode |= SLAP_TOOL_READMAIN | SLAP_TOOL_READONLY; break; case SLAPDN: - options = "d:f:F:NPv"; + options = "d:f:F:No:Pv"; + mode |= SLAP_TOOL_READMAIN | SLAP_TOOL_READONLY; + break; + + case SLAPSCHEMA: + options = "a:b:cd:f:F:gl:n:o:s:v"; mode |= SLAP_TOOL_READMAIN | SLAP_TOOL_READONLY; break; case SLAPTEST: - options = "d:f:F:uv"; + options = "d:f:F:o:Quv"; mode |= SLAP_TOOL_READMAIN | SLAP_TOOL_READONLY; break; case SLAPAUTH: - options = "d:f:F:M:R:U:vX:"; + options = "d:f:F:M:o:R:U:vX:"; mode |= SLAP_TOOL_READMAIN | SLAP_TOOL_READONLY; break; case SLAPINDEX: - options = "b:cd:f:F:n:qv"; + options = "b:cd:f:F:gn:o:qtv"; mode |= SLAP_TOOL_READMAIN; break; @@ -232,7 +296,7 @@ slap_tool_init( while ( (i = getopt( argc, argv, options )) != EOF ) { switch ( i ) { case 'a': - filterstr = strdup( optarg ); + filterstr = ch_strdup( optarg ); break; case 'b': @@ -243,24 +307,51 @@ slap_tool_init( continuemode++; break; - case 'd': /* turn on debugging */ - ldap_debug += atoi( optarg ); - break; + case 'd': { /* turn on debugging */ + int level = 0; + + if ( parse_debug_level( optarg, &level, &debug_unknowns ) ) { + usage( tool, progname ); + } +#ifdef LDAP_DEBUG + if ( level == 0 ) { + /* allow to reset log level */ + slap_debug = 0; + + } else { + slap_debug |= level; + } +#else + if ( level != 0 ) + fputs( "must compile with LDAP_DEBUG for debugging\n", + stderr ); +#endif + } break; case 'D': ber_str2bv( optarg, 0, 1, &authcDN ); break; case 'f': /* specify a conf file */ - conffile = strdup( optarg ); + conffile = ch_strdup( optarg ); break; case 'F': /* specify a conf dir */ - confdir = strdup( optarg ); + confdir = ch_strdup( optarg ); + break; + + case 'g': /* disable subordinate glue */ + use_glue = 0; + break; + + case 'j': /* jump to linenumber */ + if ( lutil_atoi( &jumpline, optarg ) ) { + usage( tool, progname ); + } break; case 'l': /* LDIF file */ - ldiffile = strdup( optarg ); + ldiffile = ch_strdup( optarg ); break; case 'M': @@ -275,11 +366,13 @@ slap_tool_init( break; case 'n': /* which config file db to index */ - dbnum = atoi( optarg ); + if ( lutil_atoi( &dbnum, optarg ) || dbnum < 0 ) { + usage( tool, progname ); + } break; case 'o': - if ( parse_slapacl() ) { + if ( parse_slapopt() ) { usage( tool, progname ); } break; @@ -291,6 +384,11 @@ slap_tool_init( dn_mode = SLAP_TOOL_LDAPDN_PRETTY; break; + case 'Q': + quiet++; + slap_debug = 0; + break; + case 'q': /* turn on quick */ mode |= SLAP_TOOL_QUICK; break; @@ -299,8 +397,19 @@ slap_tool_init( realm = optarg; break; + case 'S': + if ( lutil_atou( &csnsid, optarg ) + || csnsid > SLAP_SYNC_SID_MAX ) + { + usage( tool, progname ); + } + break; + case 's': /* dump subtree */ - subtree = strdup( optarg ); + if ( tool == SLAPADD ) + mode |= SLAP_TOOL_NO_SCHEMA_CHECK; + else if ( tool == SLAPCAT || tool == SLAPSCHEMA ) + subtree = ch_strdup( optarg ); break; case 't': /* turn on truncate */ @@ -334,16 +443,56 @@ slap_tool_init( } } +#if defined(LDAP_SYSLOG) && defined(LDAP_DEBUG) + if ( start_syslog ) { + char *logName; +#ifdef HAVE_EBCDIC + logName = ch_strdup( progname ); + __atoe( logName ); +#else + logName = (char *)progname; +#endif + +#ifdef LOG_LOCAL4 + openlog( logName, OPENLOG_OPTIONS, syslogUser ); +#elif defined LOG_DEBUG + openlog( logName, OPENLOG_OPTIONS ); +#endif +#ifdef HAVE_EBCDIC + free( logName ); + logName = NULL; +#endif + } +#endif /* LDAP_DEBUG && LDAP_SYSLOG */ + + switch ( tool ) { + case SLAPCAT: + case SLAPSCHEMA: + writer = 1; + break; + + default: + writer = 0; + break; + } + switch ( tool ) { case SLAPADD: case SLAPCAT: - case SLAPINDEX: + case SLAPSCHEMA: if ( ( argc != optind ) || (dbnum >= 0 && base.bv_val != NULL ) ) { usage( tool, progname ); } break; + case SLAPINDEX: + if ( dbnum >= 0 && base.bv_val != NULL ) { + usage( tool, progname ); + } + + break; + case SLAPDN: if ( argc == optind ) { usage( tool, progname ); @@ -376,13 +525,11 @@ slap_tool_init( break; } - ldap_syslog = 0; - if ( ldiffile == NULL ) { - dummy.fp = tool == SLAPCAT ? stdout : stdin; + dummy.fp = writer ? stdout : stdin; ldiffp = &dummy; - } else if ((ldiffp = ldif_open( ldiffile, tool == SLAPCAT ? "w" : "r" )) + } else if ((ldiffp = ldif_open( ldiffile, writer ? "w" : "r" )) == NULL ) { perror( ldiffile ); @@ -393,36 +540,37 @@ slap_tool_init( * initialize stuff and figure out which backend we're dealing with */ -#ifdef SLAPD_MODULES - if ( module_init() != 0 ) { - fprintf( stderr, "%s: module_init failed!\n", progname ); - exit( EXIT_FAILURE ); - } -#endif - rc = slap_init( mode, progname ); - if ( rc != 0 ) { fprintf( stderr, "%s: slap_init failed!\n", progname ); exit( EXIT_FAILURE ); } - if ( frontend_init() ) { - fprintf( stderr, "%s: frontend_init failed!\n", progname ); - exit( EXIT_FAILURE ); - } + rc = read_config( conffile, confdir ); - if ( overlay_init() ) { - fprintf( stderr, "%s: overlay_init failed!\n", progname ); + if ( rc != 0 ) { + fprintf( stderr, "%s: bad configuration %s!\n", + progname, confdir ? "directory" : "file" ); exit( EXIT_FAILURE ); } - rc = read_config( conffile, confdir ); + if ( debug_unknowns ) { + rc = parse_debug_unknowns( debug_unknowns, &slap_debug ); + ldap_charray_free( debug_unknowns ); + debug_unknowns = NULL; + if ( rc ) + exit( EXIT_FAILURE ); + } - if ( rc != 0 ) { - fprintf( stderr, "%s: bad configuration file!\n", progname ); - exit( EXIT_FAILURE ); +#if defined(LDAP_SYSLOG) && defined(LDAP_DEBUG) + if ( syslog_unknowns ) { + rc = parse_debug_unknowns( syslog_unknowns, &ldap_syslog ); + ldap_charray_free( syslog_unknowns ); + syslog_unknowns = NULL; + if ( rc ) + exit( EXIT_FAILURE ); } +#endif at_oc_cache = 1; @@ -430,6 +578,7 @@ slap_tool_init( case SLAPADD: case SLAPCAT: case SLAPINDEX: + case SLAPSCHEMA: if ( !nbackends ) { fprintf( stderr, "No databases found " "in config file\n" ); @@ -441,6 +590,16 @@ slap_tool_init( break; } + if ( use_glue ) { + rc = glue_sub_attach( 0 ); + + if ( rc != 0 ) { + fprintf( stderr, + "%s: subordinate configuration error\n", progname ); + exit( EXIT_FAILURE ); + } + } + rc = slap_schema_check(); if ( rc != 0 ) { @@ -466,6 +625,9 @@ slap_tool_init( fprintf( stderr, "Invalid filter '%s'\n", filterstr ); exit( EXIT_FAILURE ); } + + ch_free( filterstr ); + filterstr = NULL; } if( subtree ) { @@ -481,6 +643,7 @@ slap_tool_init( base = val; } else { free( subtree ); + subtree = NULL; } } @@ -494,8 +657,9 @@ slap_tool_init( exit( EXIT_FAILURE ); } - be = select_backend( &nbase, 0, 0 ); + be = select_backend( &nbase, 0 ); ber_memfree( nbase.bv_val ); + BER_BVZERO( &nbase ); switch ( tool ) { case SLAPACL: @@ -517,13 +681,21 @@ slap_tool_init( nosubordinates = 1; } + ch_free( base.bv_val ); + BER_BVZERO( &base ); + } else if ( dbnum == -1 ) { + /* no suffix and no dbnum specified, just default to + * the first available database + */ if ( nbackends <= 0 ) { fprintf( stderr, "No available databases\n" ); exit( EXIT_FAILURE ); } LDAP_STAILQ_FOREACH( be, &backendDB, be_next ) { dbnum++; + + /* db #0 is cn=config, don't select it as a default */ if ( dbnum < 1 ) continue; if ( SLAP_MONITOR(be)) @@ -545,19 +717,19 @@ slap_tool_init( exit( EXIT_FAILURE ); } - if ( nosubordinates == 0 && dbnum > 0 ) { + if ( nosubordinates == 0 && dbnum > 1 ) { Debug( LDAP_DEBUG_ANY, "The first database does not allow %s;" " using the first available one (%d)\n", - progname, dbnum + 1, 0 ); + progname, dbnum, 0 ); } - } else if ( dbnum < 0 || dbnum > (nbackends-1) ) { + } else if ( dbnum >= nbackends ) { fprintf( stderr, "Database number selected via -n is out of range\n" - "Must be in the range 1 to %d" - " (number of databases in the config file)\n", - nbackends ); + "Must be in the range 0 to %d" + " (the number of configured databases)\n", + nbackends - 1 ); exit( EXIT_FAILURE ); } else { @@ -568,34 +740,62 @@ slap_tool_init( } startup:; + if ( be ) { + BackendDB *bdtmp; + + dbnum = 0; + LDAP_STAILQ_FOREACH( bdtmp, &backendDB, be_next ) { + if ( bdtmp == be ) break; + dbnum++; + } + } #ifdef CSRIMALLOC mal_leaktrace(1); #endif + if ( conffile != NULL ) { + ch_free( conffile ); + conffile = NULL; + } + + if ( ldiffile != NULL ) { + ch_free( ldiffile ); + ldiffile = NULL; + } + /* slapdn doesn't specify a backend to startup */ - if ( !dryrun && tool != SLAPDN && slap_startup( be ) ) { - switch ( tool ) { - case SLAPTEST: - fprintf( stderr, "slap_startup failed " - "(test would succeed using " - "the -u switch)\n" ); - break; + if ( !dryrun && tool != SLAPDN ) { + need_shutdown = 1; + + if ( slap_startup( be ) ) { + switch ( tool ) { + case SLAPTEST: + fprintf( stderr, "slap_startup failed " + "(test would succeed using " + "the -u switch)\n" ); + break; + + default: + fprintf( stderr, "slap_startup failed\n" ); + break; + } - default: - fprintf( stderr, "slap_startup failed\n" ); - break; + exit( EXIT_FAILURE ); } - - exit( EXIT_FAILURE ); } } -void slap_tool_destroy( void ) +int slap_tool_destroy( void ) { + int rc = 0; if ( !dryrun ) { - slap_shutdown( be ); - slap_destroy(); + if ( need_shutdown ) { + if ( slap_shutdown( be )) + rc = EXIT_FAILURE; + } + if ( slap_destroy()) + rc = EXIT_FAILURE; } #ifdef SLAPD_MODULES if ( slapMode == SLAP_SERVER_MODE ) { @@ -616,5 +816,11 @@ void slap_tool_destroy( void ) if ( !BER_BVISNULL( &authcDN ) ) { ch_free( authcDN.bv_val ); + BER_BVZERO( &authcDN ); + } + + if ( ldiffp && ldiffp != &dummy ) { + ldif_close( ldiffp ); } + return rc; }