modify the database will return an "unwilling to perform" error. By
default, readonly is off.
.HP
-.B replica host=<hostname>[:port] bindmethod=simple|sasl
-.B [binddn=<simple DN>] [credentials=<simple password>]
-.B [saslmech=<SASL mech>] [authcId=<authentication ID>]
+.B replica host=<hostname>[:port] [tls=yes|critical]
+.B bindmethod=simple|sasl [binddn=<simple DN>] [credentials=<simple password>]
+.B [saslmech=<SASL mech>] [secopts=<options>] [realm=<realm>]
+.B [authcId=<authentication ID>] [authcId=<authentication ID>]
.RS
Specify a replication site for this database. Refer to the "OpenLDAP
Administrator's Guide" for detailed information on setting up a replicated
}
ri->ri_hostname = strdup( val );
gots |= GOT_HOST;
+ } else if ( !strncasecmp( cargv[ i ], TLSSTR, strlen( TLSSTR ))) {
+ val = cargv[ i ] + strlen( TLSSTR ) + 1;
+ if( !strcasecmp( val, TLSCRITICALSTR ) ) {
+ 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;
} else if ( !strncasecmp( cargv[ i ], CREDSTR, strlen( CREDSTR ))) {
val = cargv[ i ] + strlen( CREDSTR ) + 1;
ri->ri_password = strdup( val );
+ } else if ( !strncasecmp( cargv[ i ], SECPROPSSTR, strlen( SECPROPSSTR ))) {
+ val = cargv[ i ] + strlen( SECPROPSSTR ) + 1;
+ ri->ri_secprops = strdup( val );
+ } else if ( !strncasecmp( cargv[ i ], REALMSTR, strlen( REALMSTR ))) {
+ val = cargv[ i ] + strlen( REALMSTR ) + 1;
+ ri->ri_realm = strdup( val );
} else if ( !strncasecmp( cargv[ i ], AUTHCSTR, strlen( AUTHCSTR ))) {
val = cargv[ i ] + strlen( AUTHCSTR ) + 1;
ri->ri_authcId = strdup( val );
/* Old authcID is provided for some backwards compatibility */
val = cargv[ i ] + strlen( OLDAUTHCSTR ) + 1;
ri->ri_authcId = strdup( val );
+ } else if ( !strncasecmp( cargv[ i ], AUTHZSTR, strlen( AUTHZSTR ))) {
+ val = cargv[ i ] + strlen( AUTHZSTR ) + 1;
+ ri->ri_authzId = strdup( val );
} else if ( !strncasecmp( cargv[ i ], SRVTABSTR, strlen( SRVTABSTR ))) {
val = cargv[ i ] + strlen( SRVTABSTR ) + 1;
if ( ri->ri_srvtab != NULL ) {
}
ldap_set_option(ri->ri_ldp, LDAP_OPT_RESTART, LDAP_OPT_ON);
+ if( ri->ri_tls ) {
+ int err;
+ err = ldap_start_tls_s(ri->ri_ldp, NULL, NULL);
+
+ if( err != LDAP_SUCCESS ) {
+ Debug( LDAP_DEBUG_ANY,
+ "%s: ldap_start_tls failed: %s (%d)\n",
+ ri->ri_tls != TLS_CRITICAL ? "Warning" : "Error",
+ ldap_err2string( err ), err );
+
+ if( ri->ri_tls != TLS_CRITICAL ) {
+ ldap_unbind( ri->ri_ldp );
+ ri->ri_ldp = NULL;
+ return BIND_ERR_TLS_FAILED;
+ }
+ }
+ }
+
switch ( ri->ri_bind_method ) {
case AUTH_SIMPLE:
/*
ri->ri_hostname, ri->ri_authcId, ri->ri_saslmech );
#ifdef HAVE_CYRUS_SASL
+ if( ri->ri_secprops != NULL ) {
+ int err;
+ err = ldap_set_option(ri->ri_ldp, LDAP_OPT_X_SASL_SECPROPS,
+ ri->ri_secprops);
+
+ if( err != LDAP_OPT_SUCCESS ) {
+ Debug( LDAP_DEBUG_ANY,
+ "Error: ldap_set_option(%s,SECPROPS,\"%s\") failed!\n",
+ ri->ri_hostname, ri->ri_secprops, NULL );
+ ldap_unbind( ri->ri_ldp );
+ ri->ri_ldp = NULL;
+ return BIND_ERR_SASL_FAILED;
+ }
+ }
+
defaults = lutil_sasl_defaults( ri->ri_ldp, ri->ri_saslmech,
- NULL, ri->ri_authcId, NULL, NULL );
+ ri->ri_realm, ri->ri_authcId, ri->ri_password, ri->ri_authzId );
ldrc = ldap_sasl_interactive_bind_s( ri->ri_ldp, ri->ri_bind_dn,
ri->ri_saslmech, NULL, NULL,
LDAP_SASL_QUIET, lutil_sasl_interact, defaults );
/* Maximum line length we can read from replication log */
#define REPLBUFLEN 256
+/* TLS flags */
+#define TLS_OFF 0
+#define TLS_ON 1
+#define TLS_CRITICAL 2
+
/* We support simple (plaintext password) and SASL authentication */
#define AUTH_SIMPLE 1
#define AUTH_KERBEROS 2
#define SASLSTR "sasl"
#define CREDSTR "credentials"
#define OLDAUTHCSTR "bindprincipal"
-#define AUTHCSTR "authcID"
+#define AUTHCSTR "authcID"
+#define AUTHZSTR "authzID"
#define SRVTABSTR "srvtab"
#define SASLMECHSTR "saslmech"
+#define REALMSTR "realm"
+#define SECPROPSSTR "secprops"
+#define TLSSTR "tls"
+#define TLSCRITICALSTR "critical"
#define REPLICA_SLEEP_TIME ( 10 )
/* Enumeration of various types of bind failures */
-#define BIND_OK 0
-#define BIND_ERR_BADLDP 1
-#define BIND_ERR_OPEN 2
-#define BIND_ERR_BAD_ATYPE 3
+#define BIND_OK 0
+#define BIND_ERR_BADLDP 1
+#define BIND_ERR_OPEN 2
+#define BIND_ERR_BAD_ATYPE 3
#define BIND_ERR_SIMPLE_FAILED 4
#define BIND_ERR_KERBEROS_FAILED 5
-#define BIND_ERR_BADRI 6
-#define BIND_ERR_VERSION 7
-#define BIND_ERR_REFERRALS 8
-#define BIND_ERR_MANAGEDSAIT 9
-#define BIND_ERR_SASL_FAILED 10
+#define BIND_ERR_BADRI 6
+#define BIND_ERR_VERSION 7
+#define BIND_ERR_REFERRALS 8
+#define BIND_ERR_MANAGEDSAIT 9
+#define BIND_ERR_SASL_FAILED 10
+#define BIND_ERR_TLS_FAILED 11
/* Return codes for do_ldap() */
#define DO_LDAP_OK 0
*/
typedef struct ri Ri;
struct ri {
-
/* Private data */
char *ri_hostname; /* canonical hostname of replica */
int ri_port; /* port where slave slapd running */
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 */
char *ri_bind_dn; /* DN to bind as when replicating */
- char *ri_password; /* Password for AUTH_SIMPLE */
+ char *ri_password; /* Password for any method */
+ char *ri_secprops; /* SASL security properties */
+ char *ri_realm; /* realm for any mechanism */
char *ri_authcId; /* authentication ID for any mechanism */
+ char *ri_authzId; /* authorization ID for any mechanism */
char *ri_srvtab; /* srvtab file for kerberos bind */
char *ri_saslmech; /* SASL mechanism to use */
struct re *ri_curr; /* current repl entry being processed */