modify the database will return an "unwilling to perform" error. By
default, readonly is off.
.HP
-.B replica host=<hostname>[:port] [starttls=yes|critical]
+.B replica uri=ldap[s]://<hostname>[:port]|host=<hostname>[:port]
+.B [starttls=yes|critical]
.B [suffix=<suffix> [...]]
.B bindmethod=simple|sasl [binddn=<simple DN>] [credentials=<simple password>]
.B [saslmech=<SASL mech>] [secprops=<properties>] [realm=<realm>]
directory service. Zero or more
.B suffix
instances can be used to select the subtrees that will be replicated
-(defaults to all the database). A
+(defaults to all the database).
+.B host
+is deprecated in favor of the
+.B uri
+option.
+.B uri
+allows the replica LDAP server to be specified as an LDAP URI.
+A
.B bindmethod
of
.B simple
int lineno, i;
int rc;
struct berval vals[2];
-
+ char *replicahost;
+ LDAPURLDesc *ludp;
static int lastmod = 1;
static BackendInfo *bi = NULL;
static BackendDB *be = NULL;
if ( cargc < 2 ) {
#ifdef NEW_LOGGING
LDAP_LOG( CONFIG, CRIT,
- "%s: line %d: missing host in \"replica "
+ "%s: line %d: missing host or uri in \"replica "
" <host[:port]\" line\n", fname, lineno , 0 );
#else
Debug( LDAP_DEBUG_ANY,
- "%s: line %d: missing host in \"replica <host[:port]>\" line\n",
+ "%s: line %d: missing host or uri in \"replica <host[:port]>\" line\n",
fname, lineno, 0 );
#endif
nr = add_replica_info( be,
cargv[i] + 5 );
break;
+ } else if (strncasecmp( cargv[i], "uri=", 4 )
+ == 0 ) {
+ if ( ldap_url_parse( cargv[ i ] + 4, &ludp )
+ != LDAP_SUCCESS ) {
+#ifdef NEW_LOGGING
+ LDAP_LOG( CONFIG, INFO,
+ "%s: line %d: replica line contains invalid "
+ "uri definition.\n", fname, lineno, 0);
+#else
+ Debug( LDAP_DEBUG_ANY,
+ "%s: line %d: replica line contains invalid "
+ "uri definition.\n", fname, lineno, 0);
+#endif
+ return 1;
+ }
+ if (ludp->lud_host == NULL ) {
+#ifdef NEW_LOGGING
+ LDAP_LOG( CONFIG, INFO,
+ "%s: line %d: replica line contains invalid "
+ "uri definition - missing hostname.\n",
+ fname, lineno, 0);
+#else
+ Debug( LDAP_DEBUG_ANY,
+ "%s: line %d: replica line contains invalid "
+ "uri definition - missing hostname.\n", fname, lineno, 0);
+#endif
+ return 1;
+ }
+ replicahost = ch_malloc( strlen( cargv[ i ] ) );
+ if ( replicahost == NULL ) {
+#ifdef NEW_LOGGING
+ LDAP_LOG( CONFIG, ERR,
+ "out of memory in read_config\n", 0, 0,0 );
+#else
+ Debug( LDAP_DEBUG_ANY,
+ "out of memory in read_config\n", 0, 0, 0 );
+#endif
+ ldap_free_urldesc( ludp );
+ exit( EXIT_FAILURE );
+ }
+ sprintf(replicahost, "%s:%d",
+ ludp->lud_host, ludp->lud_port);
+ nr = add_replica_info( be, replicahost );
+ ldap_free_urldesc( ludp );
+ ch_free(replicahost);
+ break;
}
}
if ( i == cargc ) {
#ifdef NEW_LOGGING
LDAP_LOG( CONFIG, INFO,
- "%s: line %d: missing host in \"replica\" line\n",
+ "%s: line %d: missing host or uri in \"replica\" line\n",
fname, lineno , 0 );
#else
Debug( LDAP_DEBUG_ANY,
- "%s: line %d: missing host in \"replica\" line\n",
+ "%s: line %d: missing host or uri in \"replica\" line\n",
fname, lineno, 0 );
#endif
return 1;
int gots = 0;
int i;
char *hp, *val;
+ LDAPURLDesc *ludp;
for ( i = 1; i < cargc; i++ ) {
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';
}
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 */ ;
}
ri->ri_ldp = NULL;
}
+
+ if ( ri->ri_uri != NULL ) { /* new URI style */
+#ifdef NEW_LOGGING
+ LDAP_LOG ( OPERATION, ARGS,
+ "do_bind: Initializing session to %s\n",
+ ri->ri_uri, 0, 0);
+#else
+ Debug( LDAP_DEBUG_ARGS, "Initializing session to %s\n",
+ ri->ri_uri, 0, 0 );
+#endif
+ ldrc = ldap_initialize( &(ri->ri_ldp), ri->ri_uri);
+
+ if (ldrc != LDAP_SUCCESS) {
+#ifdef NEW_LOGGING
+ LDAP_LOG ( OPERATION, ERR,
+ "do_bind: ldap_initalize (0, %s) failed: %s\n",
+ ri->ri_uri, ldap_err2string(ldrc), 0 );
+#else
+ Debug( LDAP_DEBUG_ANY, "Error: ldap_initialize(0, %s) failed: %s\n",
+ ri->ri_uri, ldap_err2string(ldrc), 0 );
+#endif
+ return( BIND_ERR_OPEN );
+ }
+ } else { /* old HOST style */
#ifdef NEW_LOGGING
LDAP_LOG ( OPERATION, ARGS,
"do_bind: Initializing session to %s:%d\n",
ri->ri_hostname, ri->ri_port, sys_errlist[ errno ] );
#endif
return( BIND_ERR_OPEN );
+ }
}
{ /* set version 3 */
/* Initialize private data */
(*ri)->ri_hostname = NULL;
+ (*ri)->ri_uri = NULL;
(*ri)->ri_ldp = NULL;
(*ri)->ri_bind_dn = NULL;
(*ri)->ri_password = NULL;
/* Config file keywords */
#define HOSTSTR "host"
+#define URISTR "uri"
#define ATTRSTR "attr"
#define SUFFIXSTR "suffix"
#define BINDDNSTR "binddn"
/* Private data */
char *ri_hostname; /* canonical hostname of replica */
int ri_port; /* port where slave slapd running */
+ char *ri_uri; /* e.g. "ldaps://ldap-1.example.com:636" */
LDAP *ri_ldp; /* LDAP struct for this replica */
int ri_tls; /* TLS: 0=no, 1=yes, 2=critical */
int ri_bind_method; /* AUTH_SIMPLE or AUTH_KERBEROS */