/* $OpenLDAP$ */
-/*
- * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
- * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
+/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
+ *
+ * Copyright 1998-2005 The OpenLDAP Foundation.
+ * Portions Copyright 2003 Mark Benson.
+ * Portions Copyright 2002 John Morrissey.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted only as authorized by the OpenLDAP
+ * Public License.
+ *
+ * A copy of this license is available in file LICENSE in the
+ * top-level directory of the distribution or, alternatively, at
+ * <http://www.OpenLDAP.org/license.html>.
*/
-/*
- * Copyright (c) 1996 Regents of the University of Michigan.
+/* Portions Copyright (c) 1996 Regents of the University of Michigan.
* All rights reserved.
*
* Redistribution and use in source and binary forms are permitted
* software without specific prior written permission. This software
* is provided ``as is'' without express or implied warranty.
*/
+/* ACKNOWLEDGEMENTS:
+ * This work was originally developed by the University of Michigan
+ * (as part of U-MICH LDAP). Additional signficant contributors
+ * include:
+ * John Morrissey
+ * Mark Benson
+ */
/*
#include <ac/ctype.h>
#include <ldap.h>
+#include <lutil.h>
#include "slurp.h"
#include "globals.h"
static void add_replica LDAP_P(( char **, int ));
static int parse_replica_line LDAP_P(( char **, int, Ri *));
static void parse_line LDAP_P(( char * ));
-static char *getline LDAP_P(( FILE * ));
+static char *slurpd_getline LDAP_P(( FILE * ));
static char *strtok_quote LDAP_P(( char *, char * ));
int cargc = 0, cargv_size = 0;
char *fname
)
{
- FILE *fp;
- char *line;
-
- cargv = ch_calloc( ARGS_STEP + 1, sizeof(*cargv) );
- cargv_size = ARGS_STEP + 1;
+ FILE *fp;
+ char *line;
+
+#define GOT_REPLOG_NO (0)
+#define GOT_REPLOG_ONE (1)
+#define GOT_REPLOG_YES (2)
+#define GOT_REPLOG_DONE (3)
+#define GOT_REPLOG_MASK (0xF)
+#define GOT_REPLOG(i) ((i) & GOT_REPLOG_MASK)
+#define GOT_REPLOG_SET(i,v) ((i) = ((i) & ~GOT_REPLOG_MASK) | ((v) & GOT_REPLOG_MASK))
+
+#define GOT_REPLOG_PID (0x10)
+#define GOT_REPLOG_ARGS (0x20)
+#define GOT_REPLOG_INTERVAL (0x40)
+ int got_replog = GOT_REPLOG_NO;
+
+ /*
+ * replica-pidfile and replica-argsfile can appear before any replog;
+ * in this case they're global (legacy behavior); otherwise, since
+ * each replog needs a slurpd, they can appear after a replogfile line;
+ * in that case, the replog specific values are used.
+ */
+
+ if ( cargv == NULL ) {
+ cargv = ch_calloc( ARGS_STEP + 1, sizeof(*cargv) );
+ cargv_size = ARGS_STEP + 1;
+ }
-#ifdef NEW_LOGGING
- LDAP_LOG ( CONFIG, ARGS,
- "slurpd_read_config: Config: opening config file \"%s\"\n",
+ Debug( LDAP_DEBUG_CONFIG, "Config: opening config file \"%s\"\n",
fname, 0, 0 );
-#else
- Debug( LDAP_DEBUG_CONFIG, "Config: opening config file \"%s\"\n",
- fname, 0, 0 );
-#endif
-
- if ( (fp = fopen( fname, "r" )) == NULL ) {
- perror( fname );
- exit( EXIT_FAILURE );
- }
- lineno = 0;
- while ( (line = getline( fp )) != NULL ) {
- /* skip comments and blank lines */
- if ( line[0] == '#' || line[0] == '\0' ) {
- continue;
+ if ( (fp = fopen( fname, "r" )) == NULL ) {
+ perror( fname );
+ exit( EXIT_FAILURE );
}
-#ifdef NEW_LOGGING
- LDAP_LOG ( CONFIG, DETAIL1,
- "slurpd_read_config: Config: (%s)\n", line, 0, 0 );
-#else
- Debug( LDAP_DEBUG_CONFIG, "Config: (%s)\n", line, 0, 0 );
-#endif
+ lineno = 0;
+ while ( (line = slurpd_getline( fp )) != NULL ) {
+ /* skip comments and blank lines */
+ if ( line[0] == '#' || line[0] == '\0' ) {
+ continue;
+ }
- parse_line( line );
+ Debug( LDAP_DEBUG_CONFIG, "Config: (%s)\n", line, 0, 0 );
- if ( cargc < 1 ) {
- fprintf( stderr, "line %d: bad config line (ignored)\n", lineno );
- continue;
- }
+ parse_line( line );
- /* replication log file to which changes are appended */
- if ( strcasecmp( cargv[0], "replogfile" ) == 0 ) {
- /*
- * if slapd_replogfile has a value, the -r option was given,
- * so use that value. If slapd_replogfile has length == 0,
- * then we should use the value in the config file we're reading.
- */
- if ( sglob->slapd_replogfile[ 0 ] == '\0' ) {
- if ( cargc < 2 ) {
- fprintf( stderr,
- "line %d: missing filename in \"replogfile ",
- lineno );
- fprintf( stderr, "<filename>\" line\n" );
- exit( EXIT_FAILURE );
- } else if ( cargc > 2 && *cargv[2] != '#' ) {
- fprintf( stderr,
- "line %d: extra cruft at the end of \"replogfile %s\"",
- lineno, cargv[1] );
- fprintf( stderr, "line (ignored)\n" );
+ if ( cargc < 1 ) {
+ fprintf( stderr, "line %d: bad config line (ignored)\n", lineno );
+ continue;
}
- strcpy( sglob->slapd_replogfile, cargv[1] );
- }
- } else if ( strcasecmp( cargv[0], "replica" ) == 0 ) {
- add_replica( cargv, cargc );
+
+ /* replication log file to which changes are appended */
+ if ( strcasecmp( cargv[0], "replogfile" ) == 0 ) {
+ /*
+ * if slapd_replogfile has a value, the -r option was given,
+ * so use that value. If slapd_replogfile has length == 0,
+ * then we should use the value in the config file we're reading.
+ */
+ if ( cargc < 2 ) {
+ fprintf( stderr,
+ "line %d: missing filename in \"replogfile ",
+ lineno );
+ fprintf( stderr, "<filename>\" line\n" );
+ exit( EXIT_FAILURE );
+
+ } else if ( cargc > 2 && *cargv[2] != '#' ) {
+ fprintf( stderr,
+ "line %d: extra cruft at the end of \"replogfile %s\"",
+ lineno, cargv[1] );
+ fprintf( stderr, "line (ignored)\n" );
+ }
+
+ LUTIL_SLASHPATH( cargv[1] );
+ if ( sglob->slapd_replogfile[0] == '\0' ) {
+ strcpy( sglob->slapd_replogfile, cargv[1] );
+ GOT_REPLOG_SET(got_replog, GOT_REPLOG_YES);
+
+ } else {
+ if ( strcmp( sglob->slapd_replogfile, cargv[1] ) == 0 ) {
+ GOT_REPLOG_SET(got_replog, GOT_REPLOG_YES);
+
+ } else if ( GOT_REPLOG(got_replog) == GOT_REPLOG_YES ) {
+ GOT_REPLOG_SET(got_replog, GOT_REPLOG_DONE);
+
+ } else {
+ GOT_REPLOG_SET(got_replog, GOT_REPLOG_ONE);
+ }
+ }
+
+ } else if ( strcasecmp( cargv[0], "replica" ) == 0 ) {
+ add_replica( cargv, cargc );
- /* include another config file */
- } else if ( strcasecmp( cargv[0], "include" ) == 0 ) {
- char *savefname;
- int savelineno;
-
- if ( cargc < 2 ) {
-#ifdef NEW_LOGGING
- LDAP_LOG( CONFIG, CRIT,
- "%s: line %d: missing filename in \"include "
- "<filename>\" line.\n", fname, lineno , 0 );
-#else
- Debug( LDAP_DEBUG_ANY,
- "%s: line %d: missing filename in \"include <filename>\" line\n",
- fname, lineno, 0 );
-#endif
+ /* include another config file */
+ } else if ( strcasecmp( cargv[0], "include" ) == 0 ) {
+ char *savefname;
+ int savelineno;
+
+ if ( cargc < 2 ) {
+ Debug( LDAP_DEBUG_ANY,
+ "%s: line %d: missing filename in \"include <filename>\" line\n",
+ fname, lineno, 0 );
- return( 1 );
- }
- savefname = strdup( cargv[1] );
- savelineno = lineno;
+ return( 1 );
+ }
+ LUTIL_SLASHPATH( cargv[1] );
+ savefname = strdup( cargv[1] );
+ savelineno = lineno;
- if ( slurpd_read_config( savefname ) != 0 ) {
- return( 1 );
- }
+ if ( slurpd_read_config( savefname ) != 0 ) {
+ return( 1 );
+ }
- free( savefname );
- lineno = savelineno - 1;
-
- } else if ( strcasecmp( cargv[0], "replica-pidfile" ) == 0 ) {
- if ( cargc < 2 ) {
-#ifdef NEW_LOGGING
- LDAP_LOG( CONFIG, CRIT,
- "%s: line %d missing file name in \"replica-pidfile <file>\" "
- "line.\n", fname, lineno, 0 );
-#else
- Debug( LDAP_DEBUG_ANY,
- "%s: line %d: missing file name in \"replica-pidfile <file>\" line\n",
- fname, lineno, 0 );
-#endif
-
- return( 1 );
- }
-
- slurpd_pid_file = ch_strdup( cargv[1] );
-
- } else if ( strcasecmp( cargv[0], "replica-argsfile" ) == 0 ) {
- if ( cargc < 2 ) {
-#ifdef NEW_LOGGING
- LDAP_LOG( CONFIG, CRIT,
- "%s: %d: missing file name in "
- "\"argsfile <file>\" line.\n",
- fname, lineno, 0 );
-#else
- Debug( LDAP_DEBUG_ANY,
- "%s: line %d: missing file name in \"argsfile <file>\" line\n",
- fname, lineno, 0 );
-#endif
-
- return( 1 );
+ free( savefname );
+ lineno = savelineno - 1;
+
+ } else if ( strcasecmp( cargv[0], "replica-pidfile" ) == 0 ) {
+ if ( cargc < 2 ) {
+ Debug( LDAP_DEBUG_ANY,
+ "%s: line %d: missing file name in \"replica-pidfile <file>\" line\n",
+ fname, lineno, 0 );
+
+ return( 1 );
+ }
+
+ switch ( GOT_REPLOG(got_replog) ) {
+ case GOT_REPLOG_YES:
+ Debug( LDAP_DEBUG_CONFIG, "%s: line %d: "
+ "got replog specific replica-pidfile \"%s\".\n",
+ fname, lineno, cargv[1] );
+ case GOT_REPLOG_NO:
+ LUTIL_SLASHPATH( cargv[1] );
+ if ( slurpd_pid_file != NULL ) {
+ ch_free( slurpd_pid_file );
+ }
+ slurpd_pid_file = ch_strdup( cargv[1] );
+ got_replog |= GOT_REPLOG_PID;
+ break;
+
+ default:
+ Debug( LDAP_DEBUG_CONFIG, "%s: line %d: "
+ "replica-pidfile \"%s\" not mine.\n",
+ fname, lineno, cargv[1] );
+ break;
+ }
+
+ } else if ( strcasecmp( cargv[0], "replica-argsfile" ) == 0 ) {
+ if ( cargc < 2 ) {
+ Debug( LDAP_DEBUG_ANY,
+ "%s: line %d: missing file name in \"argsfile <file>\" line\n",
+ fname, lineno, 0 );
+
+ return( 1 );
+ }
+
+ switch ( GOT_REPLOG(got_replog) ) {
+ case GOT_REPLOG_YES:
+ Debug( LDAP_DEBUG_CONFIG, "%s: line %d: "
+ "got replog specific replica-argsfile \"%s\".\n",
+ fname, lineno, cargv[1] );
+ case GOT_REPLOG_NO:
+ LUTIL_SLASHPATH( cargv[1] );
+ if ( slurpd_args_file != NULL ) {
+ ch_free( slurpd_args_file );
+ }
+ slurpd_args_file = ch_strdup( cargv[1] );
+ got_replog |= GOT_REPLOG_ARGS;
+ break;
+
+ default:
+ Debug( LDAP_DEBUG_CONFIG, "%s: line %d: "
+ "replica-argsfile \"%s\" not mine.\n",
+ fname, lineno, cargv[1] );
+ break;
+ }
+
+ } else if ( strcasecmp( cargv[0], "replicationinterval" ) == 0 ) {
+ int c;
+
+ if ( cargc < 2 ) {
+ Debug( LDAP_DEBUG_ANY, "%s: line %d: missing interval in "
+ "\"replicationinterval <seconds>\" line\n",
+ fname, lineno, 0 );
+ return( 1 );
+ }
+
+ if ( lutil_atoi( &c, cargv[1] ) != 0 || c < 1 ) {
+ Debug( LDAP_DEBUG_ANY, "%s: line %d: invalid interval "
+ "(%d) in \"replicationinterval <seconds>\" line\n",
+ fname, lineno, c );
+
+ return( 1 );
+ }
+
+ switch ( GOT_REPLOG(got_replog) ) {
+ case GOT_REPLOG_YES:
+ Debug( LDAP_DEBUG_CONFIG, "%s: line %d: "
+ "got replog specific replicationinterval \"%s\".\n",
+ fname, lineno, cargv[1] );
+ case GOT_REPLOG_NO:
+ sglob->no_work_interval = c;
+ got_replog |= GOT_REPLOG_INTERVAL;
+ break;
+
+ default:
+ Debug( LDAP_DEBUG_CONFIG, "%s: line %d: "
+ "replicationinterval \"%s\" not mine.\n",
+ fname, lineno, cargv[1] );
+ break;
+ }
}
-
- slurpd_args_file = ch_strdup( cargv[1] );
}
- }
- fclose( fp );
-#ifdef NEW_LOGGING
- LDAP_LOG ( CONFIG, RESULTS,
- "slurpd_read_config: Config: "
- "** configuration file successfully read and parsed\n", 0, 0, 0 );
-#else
- Debug( LDAP_DEBUG_CONFIG,
- "Config: ** configuration file successfully read and parsed\n",
- 0, 0, 0 );
-#endif
- return 0;
+
+ fclose( fp );
+ Debug( LDAP_DEBUG_CONFIG,
+ "Config: ** configuration file successfully read and parsed\n",
+ 0, 0, 0 );
+ return 0;
}
* Get a line of input.
*/
static char *
-getline(
+slurpd_getline(
FILE *fp
)
{
sglob->replicas[ nr - 1] = NULL;
sglob->num_replicas--;
} else {
-#ifdef NEW_LOGGING
- LDAP_LOG ( CONFIG, RESULTS,
- "add_replica: Config: ** successfully added replica \"%s%d\"\n",
- sglob->replicas[ nr - 1 ]->ri_hostname == NULL ?
- "(null)" : sglob->replicas[ nr - 1 ]->ri_hostname,
- sglob->replicas[ nr - 1 ]->ri_port, 0 );
-#else
Debug( LDAP_DEBUG_CONFIG,
"Config: ** successfully added replica \"%s:%d\"\n",
sglob->replicas[ nr - 1 ]->ri_hostname == NULL ?
"(null)" : sglob->replicas[ nr - 1 ]->ri_hostname,
sglob->replicas[ nr - 1 ]->ri_port, 0 );
-#endif
sglob->replicas[ nr - 1]->ri_stel =
sglob->st->st_add( sglob->st,
sglob->replicas[ nr - 1 ] );
if (( hp = strchr( val, ':' )) != NULL ) {
*hp = '\0';
hp++;
- ri->ri_port = atoi( hp );
+ if ( lutil_atoi( &ri->ri_port, hp ) != 0 ) {
+ fprintf( stderr, "unable to parse port \"%s\", line %d\n",
+ hp, lineno );
+ return -1;
+ }
}
if ( ri->ri_port <= 0 ) {
- ri->ri_port = 0;
+ ri->ri_port = LDAP_PORT;
}
ri->ri_hostname = strdup( val );
gots |= GOT_HOST;
fprintf( stderr, "slurpd no longer supports Kerberos.\n" );
exit( EXIT_FAILURE );
} else if ( !strcasecmp( val, SIMPLESTR )) {
- ri->ri_bind_method = AUTH_SIMPLE;
+ ri->ri_bind_method = LDAP_AUTH_SIMPLE;
gots |= GOT_METHOD;
} else if ( !strcasecmp( val, SASLSTR )) {
- ri->ri_bind_method = AUTH_SASL;
+ ri->ri_bind_method = LDAP_AUTH_SASL;
gots |= GOT_METHOD;
} else {
ri->ri_bind_method = -1;
}
}
- if ( ri->ri_bind_method == AUTH_SASL) {
+ if ( ri->ri_bind_method == LDAP_AUTH_SASL) {
if ((gots & GOT_MECH) == 0) {
fprintf( stderr, "Error: \"replica\" line needs SASLmech flag in " );
fprintf( stderr, "slapd config file, line %d\n", lineno );
return -1;
}
- }
- else if ( gots != GOT_ALL ) {
+ } else if ( gots != GOT_ALL ) {
fprintf( stderr, "Error: Malformed \"replica\" line in slapd " );
fprintf( stderr, "config file, line %d\n", lineno );
return -1;