-/*
- * Copyright (c) 1996 Regents of the University of Michigan.
+/* $OpenLDAP$ */
+/* 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>.
+ */
+/* 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/socket.h>
#include <ac/ctype.h>
-#include <lber.h>
#include <ldap.h>
+#include <lutil.h>
#include "slurp.h"
#include "globals.h"
-#define MAXARGS 100
+#define ARGS_STEP 512
/* Forward declarations */
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 *, int *, char ** ));
-static char *getline LDAP_P(( FILE * ));
+static void parse_line LDAP_P(( char * ));
+static char *slurpd_getline LDAP_P(( FILE * ));
static char *strtok_quote LDAP_P(( char *, char * ));
+int cargc = 0, cargv_size = 0;
+char **cargv;
/* current config file line # */
static int lineno;
-
+char *slurpd_pid_file = NULL;
+char *slurpd_args_file = NULL;
/*
* Read the slapd config file, looking only for config options we're
char *fname
)
{
- FILE *fp;
- char *line;
- int cargc;
- char *cargv[MAXARGS];
-
- Debug( LDAP_DEBUG_CONFIG, "Config: opening config file \"%s\"\n",
- fname, 0, 0 );
+ 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;
+ }
- if ( (fp = fopen( fname, "r" )) == NULL ) {
- perror( fname );
- exit( 1 );
- }
+ Debug( LDAP_DEBUG_CONFIG, "Config: opening config file \"%s\"\n",
+ fname, 0, 0 );
- 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 );
}
- Debug( LDAP_DEBUG_CONFIG, "Config: (%s)\n", line, 0, 0 );
+ lineno = 0;
+ while ( (line = slurpd_getline( fp )) != NULL ) {
+ /* skip comments and blank lines */
+ if ( line[0] == '#' || line[0] == '\0' ) {
+ continue;
+ }
- parse_line( line, &cargc, cargv );
+ 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( 1 );
- } 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;
+ }
+
+ /* 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 ) {
+ Debug( LDAP_DEBUG_ANY,
+ "%s: line %d: missing filename in \"include <filename>\" line\n",
+ fname, lineno, 0 );
+
+ return( 1 );
+ }
+ LUTIL_SLASHPATH( cargv[1] );
+ savefname = strdup( cargv[1] );
+ savelineno = lineno;
+
+ if ( slurpd_read_config( savefname ) != 0 ) {
+ 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;
+ }
}
- sprintf( sglob->slapd_replogfile, cargv[1] );
- }
- } else if ( strcasecmp( cargv[0], "replica" ) == 0 ) {
- add_replica( cargv, cargc );
}
- }
- fclose( fp );
- Debug( LDAP_DEBUG_CONFIG,
- "Config: ** configuration file successfully read and parsed\n",
- 0, 0, 0 );
- return 0;
+
+ fclose( fp );
+ Debug( LDAP_DEBUG_CONFIG,
+ "Config: ** configuration file successfully read and parsed\n",
+ 0, 0, 0 );
+ return 0;
}
*/
static void
parse_line(
- char *line,
- int *argcp,
- char **argv
+ char *line
)
{
char * token;
- *argcp = 0;
+ cargc = 0;
for ( token = strtok_quote( line, " \t" ); token != NULL;
- token = strtok_quote( NULL, " \t" ) ) {
- argv[(*argcp)++] = token;
+ token = strtok_quote( NULL, " \t" ) )
+ {
+ if ( cargc == cargv_size - 1 ) {
+ char **tmp;
+ tmp = ch_realloc( cargv, (cargv_size + ARGS_STEP) *
+ sizeof(*cargv) );
+ if (tmp == NULL) {
+ cargc = 0;
+ return;
+ }
+ cargv = tmp;
+ cargv_size += ARGS_STEP;
+ }
+
+ cargv[cargc++] = token;
}
- argv[*argcp] = NULL;
+ cargv[cargc] = NULL;
}
} else {
inquote = 1;
}
- SAFEMEMCPY( next, next + 1, strlen( next + 1 ) + 1 );
+ AC_MEMCPY( next, next + 1, strlen( next + 1 ) + 1 );
break;
case '\\':
if ( next[1] )
- SAFEMEMCPY( next, next + 1, strlen( next + 1 ) + 1 );
+ AC_MEMCPY( next, next + 1, strlen( next + 1 ) + 1 );
next++; /* dont parse the escaped character */
break;
* Get a line of input.
*/
static char *
-getline(
+slurpd_getline(
FILE *fp
)
{
CATLINE( buf );
while ( fgets( buf, sizeof(buf), fp ) != NULL ) {
if ( (p = strchr( buf, '\n' )) != NULL ) {
- *p = '\0';
+ if( p > buf && p[-1] == '\r' ) --p;
+ *p = '\0';
}
lineno++;
if ( ! isspace( (unsigned char) buf[0] ) ) {
return( line );
}
+ /* change leading whitespace to space */
+ buf[0] = ' ';
+
CATLINE( buf );
}
buf[0] = '\0';
( nr + 1 ) * sizeof( Re * ));
if ( sglob->replicas == NULL ) {
fprintf( stderr, "out of memory, add_replica\n" );
- exit( 1 );
+ exit( EXIT_FAILURE );
}
sglob->replicas[ nr ] = NULL;
if ( Ri_init( &(sglob->replicas[ nr - 1 ])) < 0 ) {
fprintf( stderr, "out of memory, Ri_init\n" );
- exit( 1 );
+ exit( EXIT_FAILURE );
}
if ( parse_replica_line( cargv, cargc,
sglob->replicas[ nr - 1] ) < 0 ) {
sglob->replicas[ nr - 1 ] );
if ( sglob->replicas[ nr - 1]->ri_stel == NULL ) {
fprintf( stderr, "Failed to add status element structure\n" );
- exit( 1 );
+ exit( EXIT_FAILURE );
}
}
}
* Parse a "replica" line from the config file. replica lines should be
* in the following format:
* replica host=<hostname:portnumber> binddn=<binddn>
- * bindmethod="simple|kerberos" credentials=<creds>
+ * bindmethod="simple" credentials=<creds>
*
* where:
* <hostname:portnumber> describes the host name and port number where the
*
* <binddn> is the DN to bind to the replica slapd as,
*
- * bindmethod is either "simple" or "kerberos", and
+ * bindmethod is "simple", and
*
* <creds> are the credentials (e.g. password) for binddn. <creds> are
- * only used for bindmethod=simple. For bindmethod=kerberos, the
- * credentials= option should be omitted. Credentials for kerberos
- * authentication are in the system srvtab file.
+ * only used for bindmethod=simple.
*
* The "replica" config file line may be split across multiple lines. If
* a line begins with whitespace, it is considered a continuation of the
#define GOT_DN 2
#define GOT_METHOD 4
#define GOT_ALL ( GOT_HOST | GOT_DN | GOT_METHOD )
+#define GOT_MECH 8
+
static int
parse_replica_line(
char **cargv,
int gots = 0;
int i;
char *hp, *val;
+ LDAPURLDesc *ludp;
for ( i = 1; i < cargc; i++ ) {
- if ( !strncasecmp( cargv[ i ], HOSTSTR, strlen( HOSTSTR ))) {
- val = cargv[ i ] + strlen( HOSTSTR ) + 1;
+ if ( !strncasecmp( cargv[ i ], HOSTSTR, sizeof( HOSTSTR ) - 1 ) ) {
+ if ( gots & GOT_HOST ) {
+ fprintf( stderr, "Error: Malformed \"replica\" line in slapd config " );
+ fprintf( stderr, "file, too many host or uri names specified, line %d\n",
+ lineno );
+ return -1;
+ }
+ val = cargv[ i ] + sizeof( HOSTSTR ); /* '\0' string terminator accounts for '=' */
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;
+ } else if ( !strncasecmp( cargv[ i ], URISTR, sizeof( URISTR ) - 1 ) ) {
+ if ( gots & GOT_HOST ) {
+ fprintf( stderr, "Error: Malformed \"replica\" line in slapd config " );
+ fprintf( stderr, "file, too many host or uri names specified, line %d\n",
+ lineno );
+ return -1;
+ }
+ if ( ldap_url_parse( cargv[ i ] + sizeof( URISTR ), &ludp ) != LDAP_SUCCESS ) {
+ fprintf( stderr, "Error: Malformed \"replica\" line in slapd config " );
+ fprintf( stderr, "file, bad uri format specified, line %d\n",
+ lineno );
+ return -1;
+ }
+ if (ludp->lud_host == NULL) {
+ fprintf( stderr, "Error: Malformed \"replica\" line in slapd config " );
+ fprintf( stderr, "file, missing uri hostname, line %d\n",
+ lineno );
+ return -1;
+ }
+ ri->ri_hostname = strdup ( ludp->lud_host );
+ ri->ri_port = ludp->lud_port;
+ ri->ri_uri = strdup ( cargv[ i ] + sizeof( URISTR ) );
+ ldap_free_urldesc( ludp );
+ gots |= GOT_HOST;
+ } else if ( !strncasecmp( cargv[ i ],
+ ATTRSTR, sizeof( ATTRSTR ) - 1 ) ) {
+ /* ignore it */ ;
+ } else if ( !strncasecmp( cargv[ i ],
+ SUFFIXSTR, sizeof( SUFFIXSTR ) - 1 ) ) {
+ /* ignore it */ ;
+ } else if ( !strncasecmp( cargv[i], STARTTLSSTR, sizeof(STARTTLSSTR)-1 )) {
+ val = cargv[ i ] + sizeof( STARTTLSSTR );
+ if( !strcasecmp( val, CRITICALSTR ) ) {
+ ri->ri_tls = TLS_CRITICAL;
+ } else {
+ ri->ri_tls = TLS_ON;
+ }
+ } else if ( !strncasecmp( cargv[ i ], TLSSTR, sizeof( TLSSTR ) - 1 ) ) {
+ val = cargv[ i ] + sizeof( TLSSTR );
+ if( !strcasecmp( val, CRITICALSTR ) ) {
+ ri->ri_tls = TLS_CRITICAL;
+ } else {
+ ri->ri_tls = TLS_ON;
+ }
} else if ( !strncasecmp( cargv[ i ],
- BINDDNSTR, strlen( BINDDNSTR ))) {
- val = cargv[ i ] + strlen( BINDDNSTR ) + 1;
+ BINDDNSTR, sizeof( BINDDNSTR ) - 1 ) ) {
+ val = cargv[ i ] + sizeof( BINDDNSTR );
ri->ri_bind_dn = strdup( val );
gots |= GOT_DN;
} else if ( !strncasecmp( cargv[ i ], BINDMETHSTR,
- strlen( BINDMETHSTR ))) {
- val = cargv[ i ] + strlen( BINDMETHSTR ) + 1;
+ sizeof( BINDMETHSTR ) - 1 ) ) {
+ val = cargv[ i ] + sizeof( BINDMETHSTR );
if ( !strcasecmp( val, KERBEROSSTR )) {
-#ifdef HAVE_KERBEROS
- ri->ri_bind_method = AUTH_KERBEROS;
- if ( ri->ri_srvtab == NULL ) {
- ri->ri_srvtab = strdup( sglob->default_srvtab );
- }
- gots |= GOT_METHOD;
-#else /* HAVE_KERBEROS */
fprintf( stderr, "Error: a bind method of \"kerberos\" was\n" );
- fprintf( stderr, "specified in the slapd configuration file,\n" );
- fprintf( stderr, "but slurpd was not built with kerberos.\n" );
- fprintf( stderr, "You must rebuild the LDAP release with\n" );
- fprintf( stderr, "kerberos support if you wish to use\n" );
- fprintf( stderr, "bindmethod=kerberos\n" );
- exit( 1 );
-#endif /* HAVE_KERBEROS */
+ fprintf( stderr, "specified in the slapd configuration file.\n" );
+ 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 = LDAP_AUTH_SASL;
gots |= GOT_METHOD;
} else {
ri->ri_bind_method = -1;
}
- } else if ( !strncasecmp( cargv[ i ], CREDSTR, strlen( CREDSTR ))) {
- val = cargv[ i ] + strlen( CREDSTR ) + 1;
+ } else if ( !strncasecmp( cargv[ i ],
+ SASLMECHSTR, sizeof( SASLMECHSTR ) - 1 ) ) {
+ val = cargv[ i ] + sizeof( SASLMECHSTR );
+ gots |= GOT_MECH;
+ ri->ri_saslmech = strdup( val );
+ } else if ( !strncasecmp( cargv[ i ],
+ CREDSTR, sizeof( CREDSTR ) - 1 ) ) {
+ val = cargv[ i ] + sizeof( CREDSTR );
ri->ri_password = strdup( val );
- } else if ( !strncasecmp( cargv[ i ], BINDPSTR, strlen( BINDPSTR ))) {
- val = cargv[ i ] + strlen( BINDPSTR ) + 1;
- ri->ri_principal = strdup( val );
- } else if ( !strncasecmp( cargv[ i ], SRVTABSTR, strlen( SRVTABSTR ))) {
- val = cargv[ i ] + strlen( SRVTABSTR ) + 1;
+ } else if ( !strncasecmp( cargv[ i ],
+ SECPROPSSTR, sizeof( SECPROPSSTR ) - 1 ) ) {
+ val = cargv[ i ] + sizeof( SECPROPSSTR );
+ ri->ri_secprops = strdup( val );
+ } else if ( !strncasecmp( cargv[ i ],
+ REALMSTR, sizeof( REALMSTR ) - 1 ) ) {
+ val = cargv[ i ] + sizeof( REALMSTR );
+ ri->ri_realm = strdup( val );
+ } else if ( !strncasecmp( cargv[ i ],
+ AUTHCSTR, sizeof( AUTHCSTR ) - 1 ) ) {
+ val = cargv[ i ] + sizeof( AUTHCSTR );
+ ri->ri_authcId = strdup( val );
+ } else if ( !strncasecmp( cargv[ i ],
+ OLDAUTHCSTR, sizeof( OLDAUTHCSTR ) - 1 ) ) {
+ /* Old authcID is provided for some backwards compatibility */
+ val = cargv[ i ] + sizeof( OLDAUTHCSTR );
+ ri->ri_authcId = strdup( val );
+ } else if ( !strncasecmp( cargv[ i ],
+ AUTHZSTR, sizeof( AUTHZSTR ) - 1 ) ) {
+ val = cargv[ i ] + sizeof( AUTHZSTR );
+ ri->ri_authzId = strdup( val );
+ } else if ( !strncasecmp( cargv[ i ],
+ SRVTABSTR, sizeof( SRVTABSTR ) - 1 ) ) {
+ val = cargv[ i ] + sizeof( SRVTABSTR );
if ( ri->ri_srvtab != NULL ) {
free( ri->ri_srvtab );
}
cargv[ i ] );
}
}
- if ( gots != GOT_ALL ) {
- fprintf( stderr, "Error: Malformed \"replica\" line in slapd " );
- fprintf( stderr, "config file, line %d\n", lineno );
- return -1;
- }
+
+ 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 ) {
+ fprintf( stderr, "Error: Malformed \"replica\" line in slapd " );
+ fprintf( stderr, "config file, line %d\n", lineno );
+ return -1;
+ }
return 0;
}