Author: rmeggins
Update of /cvs/dirsec/ldapserver/ldap/servers/plugins/chainingdb
In directory
cvs1.fedora.phx.redhat.com:/tmp/cvs-serv12377/ldapserver/ldap/servers/plugins/chainingdb
Modified Files:
cb.h cb_conn_stateless.c cb_instance.c
Log Message:
Resolves: bug 469261
Bug Description: Support server-to-server SASL - part 2
Reviewed by: nhosoi (Thanks!)
Fix Description: This part focuses on chaining backend - allowing the mux server to use
SASL to connect to the farm server, and allowing SASL authentication to chain. I had to
add two new config parameters for chaining:
nsUseStartTLS - on or off - tell connection to use startTLS - default is off
nsBindMechanism - if absent, will just use simple auth. If present, this must be one of
the supported mechanisms (EXTERNAL, GSSAPI, DIGEST-MD5) - default is absent (simple bind)
The chaining code uses a timeout, so I had to add a timeout to slapi_ldap_bind, and
correct the replication code to pass in a NULL for the timeout parameter.
Fixed a bug in the starttls code in slapi_ldap_init_ext.
The sasl code uses an internal search to find the entry corresponding to the sasl user id.
This search could not be chained due to the way it was coded. So I added a new chainable
component called cn=sasl and changed the sasl internal search code to use this component
ID. This allows the sasl code to work with a chained backend. In order to use chaining
with sasl, this component must be set in the chaining configuration
nsActiveChainingComponents. I also discovered that password policy must be configured
too, in order for the sasl code to determine if the account is locked out.
I fixed a bug in the sasl mapping debug trace code.
Still to come - sasl mappings to work with all of this new code - kerberos code
improvements - changes to pta and dna
Platforms tested: Fedora 8, Fedora 9
Flag Day: yes
Doc impact: yes
Index: cb.h
===================================================================
RCS file: /cvs/dirsec/ldapserver/ldap/servers/plugins/chainingdb/cb.h,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- cb.h 10 Nov 2006 23:44:50 -0000 1.5
+++ cb.h 5 Nov 2008 18:21:05 -0000 1.6
@@ -114,8 +114,10 @@
#define CB_CONFIG_SIZELIMIT "nsslapd-sizelimit"
#define CB_CONFIG_TIMELIMIT "nsslapd-timelimit"
#define CB_CONFIG_HOSTURL "nsFarmServerURL"
+#define CB_CONFIG_STARTTLS "nsUseStartTLS"
#define CB_CONFIG_BINDUSER "nsMultiplexorBindDn"
+#define CB_CONFIG_BINDMECH "nsBindMechanism"
#define CB_CONFIG_USERPASSWORD "nsMultiplexorCredentials"
#define CB_CONFIG_MAXBINDCONNECTIONS "nsBindConnectionsLimit"
#define CB_CONFIG_MAXCONNECTIONS "nsOperationConnectionsLimit"
@@ -163,6 +165,8 @@
#define CB_DEF_HOPLIMIT "10" /* CB_CONFIG_HOPLIMIT */
#define CB_DEF_MAX_IDLE_TIME "60" /* CB_CONFIG_MAX_IDLE_TIME */
#define CB_DEF_MAX_TEST_TIME "15" /* CB_CONFIG_MAX_TEST_TIME */
+#define CB_DEF_STARTTLS "off" /* CB_CONFIG_STARTTLS */
+#define CB_DEF_BINDMECH LDAP_SASL_SIMPLE /* CB_CONFIG_BINDMECH */
typedef void *cb_config_get_fn_t(void *arg);
typedef int cb_config_set_fn_t(void *arg, void *value, char *errorbuf, int phase, int
apply);
@@ -290,6 +294,8 @@
/* To protect the config set by LDAP */
PRRWLock * rwl_config_lock;
+ int starttls; /* use starttls with connection */
+ char *mech; /* plain, external, or a sasl mech */
} cb_conn_pool;
Index: cb_conn_stateless.c
===================================================================
RCS file: /cvs/dirsec/ldapserver/ldap/servers/plugins/chainingdb/cb_conn_stateless.c,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -r1.8 -r1.9
--- cb_conn_stateless.c 15 Oct 2008 06:29:54 -0000 1.8
+++ cb_conn_stateless.c 5 Nov 2008 18:21:05 -0000 1.9
@@ -164,6 +164,7 @@
char *password,*binddn,*hostname;
unsigned int port;
int secure;
+ char *mech = NULL;;
static char *error1="Can't contact remote server : %s";
static char *error2="Can't bind to remote server : %s";
int isMultiThread = ENABLE_MULTITHREAD_PER_CONN ; /* by default, we enable multiple
operations per connection */
@@ -199,6 +200,10 @@
hostname=pool->hostname;
port=pool->port;
secure=pool->secure;
+ if (pool->starttls) {
+ secure = 2;
+ }
+ mech=pool->mech;
PR_RWLock_Unlock(pool->rwl_config_lock);
@@ -348,12 +353,8 @@
/* For now, bind even if no user to detect error */
/* earlier */
if (pool->bindit) {
- int msgid;
- LDAPMessage *res=NULL;
- int parse_rc;
PRErrorCode prerr = 0;
LDAPControl **serverctrls=NULL;
- char **referrals=NULL;
char *plain = NULL;
int ret = -1;
@@ -381,14 +382,21 @@
}
/* Password-based client authentication */
+ rc = slapi_ldap_bind(ld, binddn, plain, mech, NULL, &serverctrls,
+ &bind_to, NULL);
- if (( msgid = ldap_simple_bind( ld, binddn, plain)) <0) {
- rc=ldap_get_lderrno( ld, NULL, NULL );
- prerr=PR_GetError();
- }
if ( ret == 0 ) slapi_ch_free_string(&plain); /* free plain only if it has been
duplicated */
- if ( rc != LDAP_SUCCESS ) {
+ if ( rc == LDAP_TIMEOUT ) {
+ if (cb_debug_on()) {
+ slapi_log_error( SLAPI_LOG_PLUGIN, CB_PLUGIN_SUBSYSTEM,
+ "Can't bind to server <%s> port
<%d>. (%s)\n",
+ hostname, port, "time-out expired");
+ }
+ rc = LDAP_CONNECT_ERROR;
+ goto unlock_and_return;
+ } else if ( rc != LDAP_SUCCESS ) {
+ prerr=PR_GetError();
if (cb_debug_on()) {
slapi_log_error( SLAPI_LOG_PLUGIN, CB_PLUGIN_SUBSYSTEM,
"Can't bind to server <%s> port <%d>. "
@@ -405,67 +413,11 @@
goto unlock_and_return;
}
- rc = ldap_result( ld, msgid, 0, &bind_to, &res );
- switch (rc) {
- case -1:
- rc = ldap_get_lderrno( ld, NULL, NULL );
- if (cb_debug_on()) {
- slapi_log_error( SLAPI_LOG_PLUGIN, CB_PLUGIN_SUBSYSTEM,
- "Can't bind to server <%s> port <%d>. "
- "(LDAP error %d - %s; "
- SLAPI_COMPONENT_NAME_NSPR " error %d - %s)\n",
- hostname, port, rc,
- ldap_err2string(rc),
- prerr, slapd_pr_strerror(prerr));
- }
- if ( errmsg ) {
- *errmsg = PR_smprintf(error2,ldap_err2string(rc));
- }
- rc = LDAP_CONNECT_ERROR;
- goto unlock_and_return;
- case 0:
- if (cb_debug_on()) {
- slapi_log_error( SLAPI_LOG_PLUGIN, CB_PLUGIN_SUBSYSTEM,
- "Can't bind to server <%s> port
<%d>. (%s)\n",
- hostname, port, "time-out expired");
- }
- rc = LDAP_CONNECT_ERROR;
- goto unlock_and_return;
- default:
-
- parse_rc = ldap_parse_result( ld, res, &rc, NULL,
- NULL, &referrals, &serverctrls, 1 );
-
- if ( parse_rc != LDAP_SUCCESS ) {
- if (cb_debug_on()) {
- slapi_log_error( SLAPI_LOG_PLUGIN,
CB_PLUGIN_SUBSYSTEM,
- "Can't bind to server <%s> port
<%d>. (%s)\n",
- hostname, port, ldap_err2string(parse_rc));
- }
- if ( errmsg ) {
- *errmsg = PR_smprintf(error2,ldap_err2string(parse_rc));
- }
- rc = parse_rc;
- goto unlock_and_return;
- }
-
- if ( rc != LDAP_SUCCESS ) {
- if (cb_debug_on()) {
- slapi_log_error( SLAPI_LOG_PLUGIN,
CB_PLUGIN_SUBSYSTEM,
- "Can't bind to server <%s> port
<%d>. (%s)\n",
- hostname, port, ldap_err2string(rc));
- }
- if ( errmsg ) {
- *errmsg = PR_smprintf(error2, ldap_err2string(rc));
- }
- goto unlock_and_return;
- }
-
- if ( serverctrls )
+ if ( serverctrls )
+ {
+ int i;
+ for( i = 0; serverctrls[ i ] != NULL; ++i )
{
- int i;
- for( i = 0; serverctrls[ i ] != NULL; ++i )
- {
if ( !(strcmp( serverctrls[ i ]->ldctl_oid, LDAP_CONTROL_PWEXPIRED)) )
{
/* Bind is successful but password has expired */
@@ -487,12 +439,8 @@
binddn, hostname, port, password_expiring);
}
}
- }
- ldap_controls_free(serverctrls);
- }
-
- if (referrals)
- charray_free(referrals);
+ }
+ ldap_controls_free(serverctrls);
}
}
@@ -896,6 +844,7 @@
LDAP *ld;
LDAPMessage *result;
time_t now;
+ int secure;
if (cb->max_idle_time <=0) /* Heart-beat disabled */
return LDAP_SUCCESS;
@@ -904,8 +853,12 @@
now = current_time();
if (end_time && ((now <= end_time) || (end_time <0))) return
LDAP_SUCCESS;
-
- ld=slapi_ldap_init(cb->pool->hostname,cb->pool->port,cb->pool->secure,0);
+
+ secure = cb->pool->secure;
+ if (cb->pool->starttls) {
+ secure = 2;
+ }
+ ld=slapi_ldap_init(cb->pool->hostname,cb->pool->port,secure,0);
if (NULL == ld) {
cb_update_failed_conn_cpt( cb );
return LDAP_SERVER_DOWN;
@@ -914,6 +867,8 @@
timeout.tv_sec=cb->max_test_time;
timeout.tv_usec=0;
+ /* NOTE: This will fail if we implement the ability to disable
+ anonymous bind */
rc=ldap_search_ext_s(ld ,NULL,LDAP_SCOPE_BASE,"objectclass=*",attrs,1,NULL,
NULL, &timeout, 1,&result);
if ( LDAP_SUCCESS != rc ) {
Index: cb_instance.c
===================================================================
RCS file: /cvs/dirsec/ldapserver/ldap/servers/plugins/chainingdb/cb_instance.c,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -r1.10 -r1.11
--- cb_instance.c 8 Oct 2008 17:29:01 -0000 1.10
+++ cb_instance.c 5 Nov 2008 18:21:05 -0000 1.11
@@ -53,7 +53,9 @@
/* Get functions */
static void *cb_instance_hosturl_get(void *arg);
+static void *cb_instance_starttls_get(void *arg);
static void *cb_instance_binduser_get(void *arg);
+static void *cb_instance_bindmech_get(void *arg);
static void *cb_instance_userpassword_get(void *arg);
static void *cb_instance_maxbconn_get(void *arg);
static void *cb_instance_maxconn_get(void *arg);
@@ -77,7 +79,9 @@
/* Set functions */
static int cb_instance_hosturl_set(void *arg, void *value, char *errorbuf, int phase, int
apply);
+static int cb_instance_starttls_set(void *arg, void *value, char *errorbuf, int phase,
int apply);
static int cb_instance_binduser_set(void *arg, void *value, char *errorbuf, int phase,
int apply);
+static int cb_instance_bindmech_set(void *arg, void *value, char *errorbuf, int phase,
int apply);
static int cb_instance_userpassword_set(void *arg, void *value, char *errorbuf, int
phase, int apply);
static int cb_instance_maxbconn_set(void *arg, void *value, char *errorbuf, int phase,
int apply);
static int cb_instance_maxconn_set(void *arg, void *value, char *errorbuf, int phase, int
apply);
@@ -120,6 +124,8 @@
{CB_CONFIG_HOPLIMIT,CB_CONFIG_TYPE_INT,CB_DEF_HOPLIMIT,&cb_instance_hoplimit_get,
&cb_instance_hoplimit_set,CB_ALWAYS_SHOW},
{CB_CONFIG_MAX_IDLE_TIME,CB_CONFIG_TYPE_INT,CB_DEF_MAX_IDLE_TIME,&cb_instance_max_idle_get,
&cb_instance_max_idle_set,CB_ALWAYS_SHOW},
{CB_CONFIG_MAX_TEST_TIME,CB_CONFIG_TYPE_INT,CB_DEF_MAX_TEST_TIME,&cb_instance_max_test_get,
&cb_instance_max_test_set,CB_ALWAYS_SHOW},
+{CB_CONFIG_STARTTLS,CB_CONFIG_TYPE_ONOFF,CB_DEF_STARTTLS,&cb_instance_starttls_get,
&cb_instance_starttls_set,CB_ALWAYS_SHOW},
+{CB_CONFIG_BINDMECH,CB_CONFIG_TYPE_STRING,CB_DEF_BINDMECH,&cb_instance_bindmech_get,
&cb_instance_bindmech_set,CB_ALWAYS_SHOW},
{NULL, 0, NULL, NULL, NULL, 0}
};
@@ -256,9 +262,9 @@
slapi_destroy_mutex(inst->pool->conn.conn_list_mutex);
slapi_destroy_mutex(inst->monitor_availability.cpt_lock);
slapi_destroy_mutex(inst->monitor_availability.lock_timeLimit);
- slapi_ch_free((void **) &inst->configDn);
- slapi_ch_free((void **) &inst->monitorDn);
- slapi_ch_free((void **) &inst->inst_name);
+ slapi_ch_free_string(&inst->configDn);
+ slapi_ch_free_string(&inst->monitorDn);
+ slapi_ch_free_string(&inst->inst_name);
charray_free(inst->every_attribute);
slapi_ch_free((void **) &inst->bind_pool);
@@ -1324,6 +1330,66 @@
}
+static void *cb_instance_starttls_get(void *arg)
+{
+ cb_backend_instance * inst=(cb_backend_instance *) arg;
+ uintptr_t data;
+
+ PR_RWLock_Rlock(inst->rwl_config_lock);
+ data=inst->pool->starttls;
+ PR_RWLock_Unlock(inst->rwl_config_lock);
+ return (void *) data;
+}
+
+static int cb_instance_starttls_set(void *arg, void *value, char *errorbuf, int phase,
int apply)
+{
+ cb_backend_instance * inst=(cb_backend_instance *) arg;
+ int rc = LDAP_SUCCESS;
+
+ if (apply) {
+ PR_RWLock_Wlock(inst->rwl_config_lock);
+ inst->pool->starttls=(int) ((uintptr_t)value);
+ PR_RWLock_Unlock(inst->rwl_config_lock);
+ if (( phase != CB_CONFIG_PHASE_INITIALIZATION ) &&
+ ( phase != CB_CONFIG_PHASE_STARTUP )) {
+ rc=CB_REOPEN_CONN; /* reconnect with the new starttls setting */
+ }
+ }
+ return rc;
+}
+
+static void *cb_instance_bindmech_get(void *arg)
+{
+ cb_backend_instance * inst=(cb_backend_instance *) arg;
+ char * data;
+
+ PR_RWLock_Rlock(inst->rwl_config_lock);
+ data = slapi_ch_strdup(inst->pool->mech);
+ PR_RWLock_Unlock(inst->rwl_config_lock);
+ return data;
+}
+
+static int cb_instance_bindmech_set(void *arg, void *value, char *errorbuf, int phase,
int apply)
+{
+ cb_backend_instance * inst=(cb_backend_instance *) arg;
+ int rc=LDAP_SUCCESS;
+
+ if (apply) {
+ PR_RWLock_Wlock(inst->rwl_config_lock);
+ if (( phase != CB_CONFIG_PHASE_INITIALIZATION ) &&
+ ( phase != CB_CONFIG_PHASE_STARTUP )) {
+
+ /* Dynamic modif */
+ charray_add(&inst->pool->waste_basket,inst->pool->mech);
+ rc=CB_REOPEN_CONN;
+ }
+
+ inst->pool->mech=slapi_ch_strdup((char *) value);
+ PR_RWLock_Unlock(inst->rwl_config_lock);
+ }
+ return rc;
+}
+
/* Finds an entry in a config_info array with the given name. Returns