LDAP_NEXTREF_PROC *nextref_proc,
void *params ));
+/* V3 URLLIST Function Callback Prototype */
+typedef int (LDAP_URLLIST_PROC) LDAP_P((
+ LDAP *ld,
+ LDAPURLDesc **urllist,
+ LDAPURLDesc **url,
+ void *params ));
+
+LDAP_F( int )
+ldap_set_urllist_proc LDAP_P((
+ LDAP *ld,
+ LDAP_URLLIST_PROC *urllist_proc,
+ void *params ));
+
/*
* in controls.c:
*/
struct ldap_url_desc; /* avoid pulling in <ldap.h> */
+#define LDAP_PVT_URL_PARSE_NONE (0x00U)
+#define LDAP_PVT_URL_PARSE_NOEMPTY_HOST (0x01U)
+#define LDAP_PVT_URL_PARSE_DEF_PORT (0x02U)
+#define LDAP_PVT_URL_PARSE_NOEMPTY_DN (0x04U)
+#define LDAP_PVT_URL_PARSE_NODEF_SCOPE (0x08U)
+#define LDAP_PVT_URL_PARSE_HISTORIC (LDAP_PVT_URL_PARSE_NODEF_SCOPE | LDAP_PVT_URL_PARSE_NOEMPTY_HOST | LDAP_PVT_URL_PARSE_DEF_PORT)
LDAP_F( int )
ldap_url_parse_ext LDAP_P((
LDAP_CONST char *url,
- struct ldap_url_desc **ludpp ));
+ struct ldap_url_desc **ludpp,
+ unsigned flags ));
+
+LDAP_F (int) ldap_url_parselist_ext LDAP_P((
+ struct ldap_url_desc **ludlist,
+ const char *url,
+ const char *sep,
+ unsigned flags ));
+
+LDAP_F (char *) ldap_url_list2urls LDAP_P((
+ struct ldap_url_desc *ludlist ));
+
+LDAP_F (void) ldap_free_urllist LDAP_P((
+ struct ldap_url_desc *ludlist ));
LDAP_F( char * )
ldap_pvt_ctime LDAP_P((
void *ldo_rebind_params;
LDAP_NEXTREF_PROC *ldo_nextref_proc;
void *ldo_nextref_params;
+ LDAP_URLLIST_PROC *ldo_urllist_proc;
+ void *ldo_urllist_params;
LDAP_BOOLEANS ldo_booleans; /* boolean options */
};
#define ld_rebind_params ld_options.ldo_rebind_params
#define ld_nextref_proc ld_options.ldo_nextref_proc
#define ld_nextref_params ld_options.ldo_nextref_params
+#define ld_urllist_proc ld_options.ldo_urllist_proc
+#define ld_urllist_params ld_options.ldo_urllist_params
#define ld_version ld_options.ldo_version
LDAP_F (BerElement *) ldap_alloc_ber_with_options( LDAP *ld );
LDAP_F (void) ldap_set_ber_options( LDAP *ld, BerElement *ber );
-LDAP_F (int) ldap_send_server_request( LDAP *ld, BerElement *ber, ber_int_t msgid, LDAPRequest *parentreq, LDAPURLDesc *srvlist, LDAPConn *lc, LDAPreqinfo *bind );
-LDAP_F (LDAPConn *) ldap_new_connection( LDAP *ld, LDAPURLDesc *srvlist, int use_ldsb, int connect, LDAPreqinfo *bind );
+LDAP_F (int) ldap_send_server_request( LDAP *ld, BerElement *ber, ber_int_t msgid, LDAPRequest *parentreq, LDAPURLDesc **srvlist, LDAPConn *lc, LDAPreqinfo *bind );
+LDAP_F (LDAPConn *) ldap_new_connection( LDAP *ld, LDAPURLDesc **srvlist, int use_ldsb, int connect, LDAPreqinfo *bind );
LDAP_F (LDAPRequest *) ldap_find_request_by_msgid( LDAP *ld, ber_int_t msgid );
LDAP_F (void) ldap_free_request( LDAP *ld, LDAPRequest *lr );
LDAP_F (void) ldap_free_connection( LDAP *ld, LDAPConn *lc, int force, int unbind );
LDAPURLDesc **ludlist,
const char *url ));
-LDAP_F (int) ldap_url_parselist_ext LDAP_P((
- LDAPURLDesc **ludlist,
- const char *url,
- const char *sep ));
-
LDAP_F (int) ldap_url_parsehosts LDAP_P((
LDAPURLDesc **ludlist,
const char *hosts,
LDAP_F (char *) ldap_url_list2hosts LDAP_P((
LDAPURLDesc *ludlist ));
-LDAP_F (char *) ldap_url_list2urls LDAP_P((
- LDAPURLDesc *ludlist ));
-
-LDAP_F (void) ldap_free_urllist LDAP_P((
- LDAPURLDesc *ludlist ));
-
/*
* in cyrus.c
*/
int ldap_open_defconn( LDAP *ld )
{
+#ifdef LDAP_R_COMPILE
+ ldap_pvt_thread_mutex_lock( &ld->ld_req_mutex );
+#endif /* LDAP_R_COMPILE */
ld->ld_defconn = ldap_new_connection( ld,
- ld->ld_options.ldo_defludp, 1, 1, NULL );
+ &ld->ld_options.ldo_defludp, 1, 1, NULL );
+#ifdef LDAP_R_COMPILE
+ ldap_pvt_thread_mutex_unlock( &ld->ld_req_mutex );
+#endif /* LDAP_R_COMPILE */
if( ld->ld_defconn == NULL ) {
ld->ld_errno = LDAP_SERVER_DOWN;
#define LDAP_OPT_NEXTREF_PROC 0x4e815d
#define LDAP_OPT_NEXTREF_PARAMS 0x4e815e
+#define LDAP_OPT_URLLIST_PROC 0x4e816d
+#define LDAP_OPT_URLLIST_PARAMS 0x4e816e
+
static const LDAPAPIFeatureInfo features[] = {
#ifdef LDAP_API_FEATURE_X_OPENLDAP
{ /* OpenLDAP Extensions API Feature */
* must want global default returned
* to initial condition.
*/
- rc = ldap_url_parselist(&ludlist, "ldap://localhost/");
+ rc = ldap_url_parselist_ext(&ludlist, "ldap://localhost/", NULL,
+ LDAP_PVT_URL_PARSE_NOEMPTY_HOST
+ | LDAP_PVT_URL_PARSE_DEF_PORT );
} else {
/*
int rc = LDAP_OPT_SUCCESS;
if(urls != NULL) {
- rc = ldap_url_parselist(&ludlist, urls);
+ rc = ldap_url_parselist_ext(&ludlist, urls, NULL,
+ LDAP_PVT_URL_PARSE_NOEMPTY_HOST
+ | LDAP_PVT_URL_PARSE_DEF_PORT );
} else if(ld == NULL) {
/*
* must want global default returned
* to initial condition.
*/
- rc = ldap_url_parselist(&ludlist, "ldap://localhost/");
+ rc = ldap_url_parselist_ext(&ludlist, "ldap://localhost/", NULL,
+ LDAP_PVT_URL_PARSE_NOEMPTY_HOST
+ | LDAP_PVT_URL_PARSE_DEF_PORT );
} else {
/*
lo->ldo_nextref_params = (void *)invalue;
} return LDAP_OPT_SUCCESS;
+ /* Only accessed from inside this function by ldap_set_urllist_proc() */
+ case LDAP_OPT_URLLIST_PROC: {
+ lo->ldo_urllist_proc = (LDAP_URLLIST_PROC *)invalue;
+ } return LDAP_OPT_SUCCESS;
+ case LDAP_OPT_URLLIST_PARAMS: {
+ lo->ldo_urllist_params = (void *)invalue;
+ } return LDAP_OPT_SUCCESS;
+
/* read-only options */
case LDAP_OPT_API_INFO:
case LDAP_OPT_DESC:
rc = ldap_set_option( ld, LDAP_OPT_NEXTREF_PARAMS, (void *)params );
return rc;
}
+
+int
+ldap_set_urllist_proc( LDAP *ld, LDAP_URLLIST_PROC *proc, void *params )
+{
+ int rc;
+ rc = ldap_set_option( ld, LDAP_OPT_URLLIST_PROC, (void *)proc );
+ if( rc != LDAP_OPT_SUCCESS ) return rc;
+
+ rc = ldap_set_option( ld, LDAP_OPT_URLLIST_PARAMS, (void *)params );
+ return rc;
+}
BerElement *ber,
ber_int_t msgid,
LDAPRequest *parentreq,
- LDAPURLDesc *srvlist,
+ LDAPURLDesc **srvlist,
LDAPConn *lc,
LDAPreqinfo *bind )
{
if ( srvlist == NULL ) {
lc = ld->ld_defconn;
} else {
- lc = find_connection( ld, srvlist, 1 );
+ lc = find_connection( ld, *srvlist, 1 );
if ( lc == NULL ) {
if ( (bind != NULL) && (parentreq != NULL) ) {
/* Remember the bind in the parent */
}
LDAPConn *
-ldap_new_connection( LDAP *ld, LDAPURLDesc *srvlist, int use_ldsb,
+ldap_new_connection( LDAP *ld, LDAPURLDesc **srvlist, int use_ldsb,
int connect, LDAPreqinfo *bind )
{
LDAPConn *lc;
- LDAPURLDesc *srv;
Debug( LDAP_DEBUG_TRACE, "ldap_new_connection %d %d %d\n",
use_ldsb, connect, (bind != NULL) );
}
if ( connect ) {
- for ( srv = srvlist; srv != NULL; srv = srv->lud_next ) {
- if ( ldap_int_open_connection( ld, lc, srv, 0 ) != -1 )
+ LDAPURLDesc **srvp, *srv = NULL;
+
+ for ( srvp = srvlist; *srvp != NULL; srvp = &(*srvp)->lud_next ) {
+ if ( ldap_int_open_connection( ld, lc, *srvp, 0 ) != -1 )
{
+ srv = *srvp;
+
+ if ( ld->ld_urllist_proc ) {
+ ld->ld_urllist_proc( ld, srvlist, srvp, ld->ld_urllist_params );
+ }
+
break;
}
}
ldap_pvt_thread_mutex_unlock( &ld->ld_conn_mutex );
#endif
- /*
- * XXX for now, we always do a synchronous bind. This will have
- * to change in the long run...
- */
- if ( bind != NULL) {
+ if ( bind != NULL ) {
int err = 0;
LDAPConn *savedefconn;
if ( ld->ld_rebind_proc != NULL) {
LDAPURLDesc *srvfunc;
- srvfunc = ldap_url_dup( srvlist );
+ srvfunc = ldap_url_dup( *srvlist );
if ( srvfunc == NULL ) {
ld->ld_errno = LDAP_NO_MEMORY;
err = -1;
{
/* Parse the referral URL */
- rc = ldap_url_parse_ext( refarray[i], &srv );
+ rc = ldap_url_parse_ext( refarray[i], &srv, LDAP_PVT_URL_PARSE_NOEMPTY_DN );
if ( rc != LDAP_URL_SUCCESS ) {
/* ldap_url_parse_ext() returns LDAP_URL_* errors
* which do not map on API errors */
goto done;
}
- /* treat ldap://hostpart and ldap://hostpart/ the same */
- if ( srv->lud_dn && srv->lud_dn[0] == '\0' ) {
- LDAP_FREE( srv->lud_dn );
- srv->lud_dn = NULL;
- }
-
/* check connection for re-bind in progress */
if (( lc = find_connection( ld, srv, 1 )) != NULL ) {
/* See if we've already requested this DN with this conn */
ldap_pvt_thread_mutex_lock( &ld->ld_req_mutex );
#endif
rc = ldap_send_server_request( ld, ber, id,
- origreq, srv, NULL, &rinfo );
+ origreq, &srv, NULL, &rinfo );
#ifdef LDAP_R_COMPILE
ldap_pvt_thread_mutex_unlock( &ld->ld_req_mutex );
#endif
*p++ = '\0';
}
- rc = ldap_url_parse_ext( ref, &srv );
+ rc = ldap_url_parse_ext( ref, &srv, LDAP_PVT_URL_PARSE_NOEMPTY_DN );
if ( rc != LDAP_URL_SUCCESS ) {
Debug( LDAP_DEBUG_TRACE,
"ignoring %s referral <%s>\n",
continue;
}
- if ( srv->lud_dn != NULL && srv->lud_dn == '\0' ) {
- LDAP_FREE( srv->lud_dn );
- srv->lud_dn = NULL;
- }
-
Debug( LDAP_DEBUG_TRACE,
"chasing LDAP referral: <%s>\n", ref, 0, 0 );
ldap_pvt_thread_mutex_lock( &ld->ld_req_mutex );
#endif
rc = ldap_send_server_request( ld, ber, id,
- lr, srv, NULL, &rinfo );
+ lr, &srv, NULL, &rinfo );
#ifdef LDAP_R_COMPILE
ldap_pvt_thread_mutex_unlock( &ld->ld_req_mutex );
#endif
}
int
-ldap_url_parse_ext( LDAP_CONST char *url_in, LDAPURLDesc **ludpp )
+ldap_url_parse_ext( LDAP_CONST char *url_in, LDAPURLDesc **ludpp, unsigned flags )
{
/*
* Pick apart the pieces of an LDAP URL.
const char *url_tmp;
char *url;
+ int check_dn = 1;
+
if( url_in == NULL || ludpp == NULL ) {
return LDAP_URL_ERR_PARAM;
}
ludp->lud_port = 0;
ludp->lud_dn = NULL;
ludp->lud_attrs = NULL;
- ludp->lud_scope = LDAP_SCOPE_DEFAULT;
+ ludp->lud_scope = ( flags & LDAP_PVT_URL_PARSE_NODEF_SCOPE ) ? LDAP_SCOPE_BASE : LDAP_SCOPE_DEFAULT;
ludp->lud_filter = NULL;
ludp->lud_exts = NULL;
}
}
+ if ( ( flags & LDAP_PVT_URL_PARSE_DEF_PORT ) && ludp->lud_port == 0 ) {
+ if ( strcmp( ludp->lud_scheme, "ldap" ) == 0 ) {
+ ludp->lud_port = LDAP_PORT;
+#ifdef LDAP_CONNECTIONLESS
+ } else if ( strcmp( ludp->lud_scheme, "cldap" ) == 0 ) {
+ ludp->lud_port = LDAP_PORT;
+#endif
+ } else if ( strcmp( ludp->lud_scheme, "ldaps" ) == 0 ) {
+ ludp->lud_port = LDAPS_PORT;
+ }
+ }
+
ldap_pvt_hex_unescape( url );
/* If [ip address]:port syntax, url is [ip and we skip the [ */
return LDAP_URL_ERR_MEM;
}
+ if ( ( flags & LDAP_PVT_URL_PARSE_NOEMPTY_HOST )
+ && ludp->lud_host != NULL
+ && *ludp->lud_host == '\0' )
+ {
+ LDAP_FREE( ludp->lud_host );
+ ludp->lud_host = NULL;
+ }
+
/*
* Kludge. ldap://111.222.333.444:389??cn=abc,o=company
*
/* parse dn part */
ldap_pvt_hex_unescape( q );
ludp->lud_dn = LDAP_STRDUP( q );
- } else {
+
+ } else if ( !( flags & LDAP_PVT_URL_PARSE_NOEMPTY_DN ) ) {
ludp->lud_dn = LDAP_STRDUP( "" );
+
+ } else {
+ check_dn = 0;
}
- if( ludp->lud_dn == NULL ) {
+ if ( check_dn && ludp->lud_dn == NULL ) {
LDAP_FREE( url );
ldap_free_urldesc( ludp );
return LDAP_URL_ERR_MEM;
/* parse dn part */
ldap_pvt_hex_unescape( p );
ludp->lud_dn = LDAP_STRDUP( p );
- } else {
+
+ } else if ( !( flags & LDAP_PVT_URL_PARSE_NOEMPTY_DN ) ) {
ludp->lud_dn = LDAP_STRDUP( "" );
+
+ } else {
+ check_dn = 0;
}
- if( ludp->lud_dn == NULL ) {
+ if( check_dn && ludp->lud_dn == NULL ) {
LDAP_FREE( url );
ldap_free_urldesc( ludp );
return LDAP_URL_ERR_MEM;
int
ldap_url_parse( LDAP_CONST char *url_in, LDAPURLDesc **ludpp )
{
- int rc = ldap_url_parse_ext( url_in, ludpp );
-
- if( rc != LDAP_URL_SUCCESS ) {
- return rc;
- }
-
- if ((*ludpp)->lud_scope == LDAP_SCOPE_DEFAULT) {
- (*ludpp)->lud_scope = LDAP_SCOPE_BASE;
- }
-
- if ((*ludpp)->lud_host != NULL && *(*ludpp)->lud_host == '\0') {
- LDAP_FREE( (*ludpp)->lud_host );
- (*ludpp)->lud_host = NULL;
- }
-
- if ((*ludpp)->lud_port == 0) {
- if( strcmp((*ludpp)->lud_scheme, "ldap") == 0 ) {
- (*ludpp)->lud_port = LDAP_PORT;
-#ifdef LDAP_CONNECTIONLESS
- } else if( strcmp((*ludpp)->lud_scheme, "cldap") == 0 ) {
- (*ludpp)->lud_port = LDAP_PORT;
-#endif
- } else if( strcmp((*ludpp)->lud_scheme, "ldaps") == 0 ) {
- (*ludpp)->lud_port = LDAPS_PORT;
- }
- }
-
- return rc;
+ return ldap_url_parse_ext( url_in, ludpp, LDAP_PVT_URL_PARSE_HISTORIC );
}
LDAPURLDesc *
}
static int
-ldap_url_parselist_int (LDAPURLDesc **ludlist, const char *url, const char *sep,
- int (*url_parse)( const char *, LDAPURLDesc ** ) )
+ldap_url_parselist_int (LDAPURLDesc **ludlist, const char *url, const char *sep, unsigned flags )
+
{
int i, rc;
LDAPURLDesc *ludp;
*ludlist = NULL;
- urls = ldap_str2charray(url, sep);
+ if ( sep == NULL ) {
+ sep = ", ";
+ }
+
+ urls = ldap_str2charray( url, sep );
if (urls == NULL)
return LDAP_URL_ERR_MEM;
for (i = 0; urls[i] != NULL; i++) ;
/* ...and put them in the "stack" backward */
while (--i >= 0) {
- rc = url_parse( urls[i], &ludp );
+ rc = ldap_url_parse_ext( urls[i], &ludp, flags );
if ( rc != 0 ) {
- ldap_charray_free(urls);
- ldap_free_urllist(*ludlist);
+ ldap_charray_free( urls );
+ ldap_free_urllist( *ludlist );
*ludlist = NULL;
return rc;
}
ludp->lud_next = *ludlist;
*ludlist = ludp;
}
- ldap_charray_free(urls);
+ ldap_charray_free( urls );
return LDAP_URL_SUCCESS;
}
int
ldap_url_parselist (LDAPURLDesc **ludlist, const char *url )
{
- return ldap_url_parselist_int( ludlist, url, ", ", ldap_url_parse );
+ return ldap_url_parselist_int( ludlist, url, ", ", LDAP_PVT_URL_PARSE_HISTORIC );
}
int
-ldap_url_parselist_ext (LDAPURLDesc **ludlist, const char *url, const char *sep )
+ldap_url_parselist_ext (LDAPURLDesc **ludlist, const char *url, const char *sep, unsigned flags )
{
- return ldap_url_parselist_int( ludlist, url, sep, ldap_url_parse_ext );
+ return ldap_url_parselist_int( ludlist, url, sep, flags );
}
int
} \
} while ( 0 )
-#define LDAP_BACK_FCONN_ISBOUND (0x01)
-#define LDAP_BACK_FCONN_ISANON (0x02)
+#define LDAP_BACK_FCONN_ISBOUND (0x00000001U)
+#define LDAP_BACK_FCONN_ISANON (0x00000002U)
#define LDAP_BACK_FCONN_ISBMASK (LDAP_BACK_FCONN_ISBOUND|LDAP_BACK_FCONN_ISANON)
-#define LDAP_BACK_FCONN_ISPRIV (0x04)
-#define LDAP_BACK_FCONN_ISTLS (0x08)
-#define LDAP_BACK_FCONN_BINDING (0x10)
-#define LDAP_BACK_FCONN_TAINTED (0x20)
+#define LDAP_BACK_FCONN_ISPRIV (0x00000004U)
+#define LDAP_BACK_FCONN_ISTLS (0x00000008U)
+#define LDAP_BACK_FCONN_BINDING (0x00000010U)
+#define LDAP_BACK_FCONN_TAINTED (0x00000020U)
+
+/* 0x00FF0000 are reserved for back-meta */
#define LDAP_BACK_CONN_ISBOUND(lc) LDAP_BACK_CONN_ISSET((lc), LDAP_BACK_FCONN_ISBOUND)
#define LDAP_BACK_CONN_ISBOUND_SET(lc) LDAP_BACK_CONN_SET((lc), LDAP_BACK_FCONN_ISBOUND)
/* li_bvuri: an array of each single URI that is equivalent;
* to be checked for the presence of a certain item */
BerVarray li_bvuri;
+ ldap_pvt_thread_mutex_t li_uri_mutex;
+
+ LDAP_REBIND_PROC *li_rebind_f;
+ LDAP_URLLIST_PROC *li_urllist_f;
+ void *li_urllist_p;
slap_bindconf li_acl;
#define li_acl_authcID li_acl.sb_authcId
#define LDAP_BACK_RETRY_DEFAULT (3)
unsigned li_flags;
-#define LDAP_BACK_F_NONE 0x00U
-#define LDAP_BACK_F_SAVECRED 0x01U
-#define LDAP_BACK_F_USE_TLS 0x02U
-#define LDAP_BACK_F_PROPAGATE_TLS 0x04U
-#define LDAP_BACK_F_TLS_CRITICAL 0x08U
+#define LDAP_BACK_F_NONE 0x0000U
+#define LDAP_BACK_F_SAVECRED 0x0001U
+#define LDAP_BACK_F_USE_TLS 0x0002U
+#define LDAP_BACK_F_PROPAGATE_TLS 0x0004U
+#define LDAP_BACK_F_TLS_CRITICAL 0x0008U
#define LDAP_BACK_F_TLS_USE_MASK (LDAP_BACK_F_USE_TLS|LDAP_BACK_F_TLS_CRITICAL)
#define LDAP_BACK_F_TLS_PROPAGATE_MASK (LDAP_BACK_F_PROPAGATE_TLS|LDAP_BACK_F_TLS_CRITICAL)
#define LDAP_BACK_F_TLS_MASK (LDAP_BACK_F_TLS_USE_MASK|LDAP_BACK_F_TLS_PROPAGATE_MASK)
-#define LDAP_BACK_F_CHASE_REFERRALS 0x10U
-#define LDAP_BACK_F_PROXY_WHOAMI 0x20U
+#define LDAP_BACK_F_CHASE_REFERRALS 0x0010U
+#define LDAP_BACK_F_PROXY_WHOAMI 0x0020U
-#define LDAP_BACK_F_SUPPORT_T_F 0x80U
-#define LDAP_BACK_F_SUPPORT_T_F_DISCOVER 0x40U
+#define LDAP_BACK_F_SUPPORT_T_F_DISCOVER 0x0040U
+#define LDAP_BACK_F_SUPPORT_T_F 0x0080U
#define LDAP_BACK_F_SUPPORT_T_F_MASK (LDAP_BACK_F_SUPPORT_T_F|LDAP_BACK_F_SUPPORT_T_F_DISCOVER)
+#define LDAP_BACK_F_MONITOR 0x0100U
+
#define LDAP_BACK_ISSET(li,f) ( ( (li)->li_flags & (f) ) == (f) )
#define LDAP_BACK_SAVECRED(li) LDAP_BACK_ISSET( (li), LDAP_BACK_F_SAVECRED )
#define LDAP_BACK_USE_TLS(li) LDAP_BACK_ISSET( (li), LDAP_BACK_F_USE_TLS )
#define LDAP_BACK_TLS_CRITICAL(li) LDAP_BACK_ISSET( (li), LDAP_BACK_F_TLS_CRITICAL )
#define LDAP_BACK_CHASE_REFERRALS(li) LDAP_BACK_ISSET( (li), LDAP_BACK_F_CHASE_REFERRALS )
#define LDAP_BACK_PROXY_WHOAMI(li) LDAP_BACK_ISSET( (li), LDAP_BACK_F_PROXY_WHOAMI )
+#define LDAP_BACK_MONITOR(li) LDAP_BACK_ISSET( (li), LDAP_BACK_F_MONITOR )
int li_version;
#define LDAP_CONTROL_OBSOLETE_PROXY_AUTHZ "2.16.840.1.113730.3.4.12"
-static LDAP_REBIND_PROC ldap_back_default_rebind;
-
-LDAP_REBIND_PROC *ldap_back_rebind_f = ldap_back_default_rebind;
-
static int
ldap_back_proxy_authz_bind( ldapconn_t *lc, Operation *op, SlapReply *rs, ldap_back_send_t sendok );
lc->lc_cred.bv_len );
}
ber_bvreplace( &lc->lc_cred, &op->orb_cred );
- ldap_set_rebind_proc( lc->lc_ld, ldap_back_rebind_f, lc );
+ ldap_set_rebind_proc( lc->lc_ld, li->li_rebind_f, lc );
}
}
done:;
assert( lcp != NULL );
+ ldap_pvt_thread_mutex_lock( &li->li_uri_mutex );
rs->sr_err = ldap_initialize( &ld, li->li_uri );
+ ldap_pvt_thread_mutex_unlock( &li->li_uri_mutex );
if ( rs->sr_err != LDAP_SUCCESS ) {
goto error_return;
}
+ if ( li->li_urllist_f ) {
+ ldap_set_urllist_proc( ld, li->li_urllist_f, li->li_urllist_p );
+ }
+
/* Set LDAP version. This will always succeed: If the client
* bound with a particular version, then so can we.
*/
}
#ifdef HAVE_TLS
+ ldap_pvt_thread_mutex_lock( &li->li_uri_mutex );
rs->sr_err = ldap_back_start_tls( ld, op->o_protocol, &is_tls,
li->li_uri, li->li_flags, li->li_nretries, &rs->sr_text );
+ ldap_pvt_thread_mutex_unlock( &li->li_uri_mutex );
if ( rs->sr_err != LDAP_SUCCESS ) {
ldap_unbind_ext( ld, NULL, NULL );
goto error_return;
if ( rc != LDAP_OPT_SUCCESS ) {
Debug( LDAP_DEBUG_ANY, "Error: ldap_set_option "
- "(%s,SECPROPS,\"%s\") failed!\n",
- li->li_uri, li->li_acl_secprops, 0 );
+ "(SECPROPS,\"%s\") failed!\n",
+ li->li_acl_secprops, 0, 0 );
goto done;
}
}
* This is a callback used for chasing referrals using the same
* credentials as the original user on this session.
*/
-static int
+int
ldap_back_default_rebind( LDAP *ld, LDAP_CONST char *url, ber_tag_t request,
ber_int_t msgid, void *params )
{
LDAP_SASL_SIMPLE, &lc->lc_cred, NULL, NULL, NULL );
}
+/*
+ * ldap_back_default_urllist
+ */
+int
+ldap_back_default_urllist(
+ LDAP *ld,
+ LDAPURLDesc **urllist,
+ LDAPURLDesc **url,
+ void *params )
+{
+ ldapinfo_t *li = (ldapinfo_t *)params;
+ LDAPURLDesc **urltail;
+
+ if ( urllist == url ) {
+ return LDAP_SUCCESS;
+ }
+
+ for ( urltail = &(*url)->lud_next; *urltail; urltail = &(*urltail)->lud_next )
+ /* count */ ;
+
+ *urltail = *urllist;
+ *urllist = *url;
+ *url = NULL;
+
+ ldap_pvt_thread_mutex_lock( &li->li_uri_mutex );
+ if ( li->li_uri ) {
+ ch_free( li->li_uri );
+ }
+
+ ldap_get_option( ld, LDAP_OPT_URI, (void *)&li->li_uri );
+ ldap_pvt_thread_mutex_unlock( &li->li_uri_mutex );
+
+ return LDAP_SUCCESS;
+}
+
int
ldap_back_op_result(
ldapconn_t *lc,
ldap_pvt_thread_mutex_lock( &li->li_conninfo.lai_mutex );
if ( (*lcp)->lc_refcnt == 1 ) {
+ ldap_pvt_thread_mutex_lock( &li->li_uri_mutex );
Debug( LDAP_DEBUG_ANY,
"%s ldap_back_retry: retrying URI=\"%s\" DN=\"%s\"\n",
op->o_log_prefix, li->li_uri,
BER_BVISNULL( &(*lcp)->lc_bound_ndn ) ?
"" : (*lcp)->lc_bound_ndn.bv_val );
+ ldap_pvt_thread_mutex_unlock( &li->li_uri_mutex );
ldap_unbind_ext( (*lcp)->lc_ld, NULL, NULL );
(*lcp)->lc_ld = NULL;
/* parse reference and use
* proto://[host][:port]/ only */
- rc = ldap_url_parse_ext( ref->bv_val, &srv );
+ rc = ldap_url_parse_ext( ref->bv_val, &srv, LDAP_PVT_URL_PARSE_NONE );
if ( rc != LDAP_URL_SUCCESS ) {
/* try next */
rc = LDAP_OTHER;
/* parse reference and use
* proto://[host][:port]/ only */
- rc = ldap_url_parse_ext( curr[0].bv_val, &srv );
+ rc = ldap_url_parse_ext( curr[0].bv_val, &srv, LDAP_PVT_URL_PARSE_NONE );
if ( rc != LDAP_URL_SUCCESS ) {
/* try next */
rs->sr_err = LDAP_OTHER;
BackendDB *be )
{
BackendInfo *bi = be->bd_info;
+ ldapinfo_t *li;
int t;
be->bd_info = lback;
if ( t != 0 ) {
return t;
}
+ li = (ldapinfo_t *)be->be_private;
+ li->li_urllist_f = NULL;
+ li->li_urllist_p = NULL;
be->bd_info = bi;
return 0;
return t;
}
li = (ldapinfo_t *)be->be_private;
+ li->li_urllist_f = NULL;
+ li->li_urllist_p = NULL;
/* copy common data */
li->li_nretries = lc->lc_common_li->li_nretries;
}
/* PARANOID: DN and more are not required nor allowed */
- urlrc = ldap_url_parselist_ext( &lud, c->argv[ 1 ], ", \t" );
+ urlrc = ldap_url_parselist_ext( &lud, c->argv[ 1 ], ", \t", LDAP_PVT_URL_PARSE_NONE );
if ( urlrc != LDAP_URL_SUCCESS ) {
char *why;
return -1;
}
+ li->li_rebind_f = ldap_back_default_rebind;
+ li->li_urllist_f = ldap_back_default_urllist;
+ li->li_urllist_p = li;
+ ldap_pvt_thread_mutex_init( &li->li_uri_mutex );
+
BER_BVZERO( &li->li_acl_authcID );
BER_BVZERO( &li->li_acl_authcDN );
BER_BVZERO( &li->li_acl_passwd );
ldap_pvt_thread_mutex_unlock( &li->li_conninfo.lai_mutex );
ldap_pvt_thread_mutex_destroy( &li->li_conninfo.lai_mutex );
+ ldap_pvt_thread_mutex_destroy( &li->li_uri_mutex );
}
ch_free( be->be_private );
extern int distproc_initialize( void );
#endif
-extern LDAP_REBIND_PROC *ldap_back_rebind_f;
+extern LDAP_REBIND_PROC ldap_back_default_rebind;
+extern LDAP_URLLIST_PROC ldap_back_default_urllist;
LDAP_END_DECL
/*
* Rewrite the add dn, if needed
*/
- dc.target = &mi->mi_targets[ candidate ];
+ dc.target = mi->mi_targets[ candidate ];
dc.conn = op->o_conn;
dc.rs = rs;
dc.ctx = "addDN";
mapped = a->a_desc->ad_cname;
} else {
- ldap_back_map( &mi->mi_targets[ candidate ].mt_rwmap.rwm_at,
+ ldap_back_map( &mi->mi_targets[ candidate ]->mt_rwmap.rwm_at,
&a->a_desc->ad_cname, &mapped, BACKLDAP_MAP );
if ( BER_BVISNULL( &mapped ) || BER_BVISEMPTY( &mapped ) ) {
continue;
for ( j = 0; !BER_BVISNULL( &a->a_vals[ j ] ); ) {
struct ldapmapping *mapping;
- ldap_back_mapping( &mi->mi_targets[ candidate ].mt_rwmap.rwm_oc,
+ ldap_back_mapping( &mi->mi_targets[ candidate ]->mt_rwmap.rwm_oc,
&a->a_vals[ j ], &mapping, BACKLDAP_MAP );
if ( mapping == NULL ) {
- if ( mi->mi_targets[ candidate ].mt_rwmap.rwm_oc.drop_missing ) {
+ if ( mi->mi_targets[ candidate ]->mt_rwmap.rwm_oc.drop_missing ) {
continue;
}
attrs[ i ]->mod_bvalues[ j ] = &a->a_vals[ j ];
LDAPMessage *res = NULL;
int rc;
- if ( mi->mi_targets[ candidate ].mt_timeout[ LDAP_BACK_OP_ADD ] != 0 ) {
- tv.tv_sec = mi->mi_targets[ candidate ].mt_timeout[ LDAP_BACK_OP_ADD ];
+ if ( mi->mi_targets[ candidate ]->mt_timeout[ LDAP_BACK_OP_ADD ] != 0 ) {
+ tv.tv_sec = mi->mi_targets[ candidate ]->mt_timeout[ LDAP_BACK_OP_ADD ];
tv.tv_usec = 0;
tvp = &tv;
}
typedef struct metatarget_t {
char *mt_uri;
+ ldap_pvt_thread_mutex_t mt_uri_mutex;
+
+ /* TODO: we might want to enable different strategies
+ * for different targets */
+ LDAP_REBIND_PROC *mt_rebind_f;
+ LDAP_URLLIST_PROC *mt_urllist_f;
+ void *mt_urllist_p;
+
BerVarray mt_subtree_exclude;
int mt_scope;
#define META_DEFAULT_TARGET_NONE (-1)
int mi_nretries;
- metatarget_t *mi_targets;
+ metatarget_t **mi_targets;
metacandidates_t *mi_candidates;
+ LDAP_REBIND_PROC *mi_rebind_f;
+ LDAP_URLLIST_PROC *mi_urllist_f;
+
metadncache_t mi_cache;
ldap_avl_info_t mi_conninfo;
extern void
meta_dncache_free( void *entry );
-extern LDAP_REBIND_PROC *meta_back_rebind_f;
+extern LDAP_REBIND_PROC meta_back_default_rebind;
+extern LDAP_URLLIST_PROC meta_back_default_urllist;
LDAP_END_DECL
#include "../back-ldap/back-ldap.h"
#include "back-meta.h"
-static LDAP_REBIND_PROC meta_back_default_rebind;
-
-/*
- * a module could register a replacement for this function
- */
-LDAP_REBIND_PROC *meta_back_rebind_f = meta_back_default_rebind;
-
int
meta_back_bind( Operation *op, SlapReply *rs )
{
*/
mc->mc_authz_target = META_BOUND_NONE;
for ( i = 0; i < mi->mi_ntargets; i++ ) {
+ metatarget_t *mt = mi->mi_targets[ i ];
int lerr;
Operation op2 = *op;
int massage = 1;
}
if ( isroot ) {
- if ( BER_BVISNULL( &mi->mi_targets[ i ].mt_pseudorootdn ) )
+ if ( BER_BVISNULL( &mt->mt_pseudorootdn ) )
{
metasingleconn_t *msc = &mc->mc_conns[ i ];
continue;
}
- op2.o_req_dn = mi->mi_targets[ i ].mt_pseudorootdn;
- op2.o_req_ndn = mi->mi_targets[ i ].mt_pseudorootdn;
- op2.orb_cred = mi->mi_targets[ i ].mt_pseudorootpw;
+ op2.o_req_dn = mt->mt_pseudorootdn;
+ op2.o_req_ndn = mt->mt_pseudorootdn;
+ op2.orb_cred = mt->mt_pseudorootpw;
op2.orb_method = LDAP_AUTH_SIMPLE;
massage = 0;
int massage )
{
metainfo_t *mi = ( metainfo_t * )op->o_bd->be_private;
- metatarget_t *mt = &mi->mi_targets[ candidate ];
+ metatarget_t *mt = mi->mi_targets[ candidate ];
struct berval mdn = BER_BVNULL;
metasingleconn_t *msc = &mc->mc_conns[ candidate ];
int msgid,
if ( LDAP_BACK_SAVECRED( mi ) ) {
ber_bvreplace( &msc->msc_cred, &op->orb_cred );
- ldap_set_rebind_proc( msc->msc_ld, meta_back_rebind_f, msc );
+ ldap_set_rebind_proc( msc->msc_ld, mt->mt_rebind_f, msc );
}
if ( mi->mi_cache.ttl != META_DNCACHE_DISABLED
int dolock )
{
metainfo_t *mi = ( metainfo_t * )op->o_bd->be_private;
- metatarget_t *mt = &mi->mi_targets[ candidate ];
+ metatarget_t *mt = mi->mi_targets[ candidate ];
metaconn_t *mc = *mcp;
metasingleconn_t *msc = &mc->mc_conns[ candidate ];
int rc;
* meta_back_single_dobind() calls meta_back_single_bind()
* if required.
*/
- if ( be_isroot( op ) && !BER_BVISNULL( &mi->mi_targets[ candidate ].mt_pseudorootdn ) )
+ if ( be_isroot( op ) && !BER_BVISNULL( &mt->mt_pseudorootdn ) )
{
Operation op2 = *op;
op2.o_tag = LDAP_REQ_BIND;
- op2.o_req_dn = mi->mi_targets[ candidate ].mt_pseudorootdn;
- op2.o_req_ndn = mi->mi_targets[ candidate ].mt_pseudorootdn;
- op2.orb_cred = mi->mi_targets[ candidate ].mt_pseudorootpw;
+ op2.o_req_dn = mt->mt_pseudorootdn;
+ op2.o_req_ndn = mt->mt_pseudorootdn;
+ op2.orb_cred = mt->mt_pseudorootpw;
op2.orb_method = LDAP_AUTH_SIMPLE;
rc = meta_back_single_bind( &op2, rs, *mcp, candidate, 0 );
}
for ( i = 0; i < mi->mi_ntargets; i++ ) {
- metatarget_t *mt = &mi->mi_targets[ i ];
+ metatarget_t *mt = mi->mi_targets[ i ];
metasingleconn_t *msc = &mc->mc_conns[ i ];
int rc, do_retry = 1;
* This is a callback used for chasing referrals using the same
* credentials as the original user on this session.
*/
-static int
+int
meta_back_default_rebind(
LDAP *ld,
LDAP_CONST char *url,
NULL, NULL, NULL );
}
+/*
+ * meta_back_default_urllist
+ *
+ * This is a callback used for mucking with the urllist
+ */
+int
+meta_back_default_urllist(
+ LDAP *ld,
+ LDAPURLDesc **urllist,
+ LDAPURLDesc **url,
+ void *params )
+{
+ metatarget_t *mt = (metatarget_t *)params;
+ LDAPURLDesc **urltail;
+
+ if ( urllist == url ) {
+ return LDAP_SUCCESS;
+ }
+
+ for ( urltail = &(*url)->lud_next; *urltail; urltail = &(*urltail)->lud_next )
+ /* count */ ;
+
+ *urltail = *urllist;
+ *urllist = *url;
+ *url = NULL;
+
+ ldap_pvt_thread_mutex_lock( &mt->mt_uri_mutex );
+ if ( mt->mt_uri ) {
+ ch_free( mt->mt_uri );
+ }
+
+ ldap_get_option( ld, LDAP_OPT_URI, (void *)&mt->mt_uri );
+ ldap_pvt_thread_mutex_unlock( &mt->mt_uri_mutex );
+
+ return LDAP_SUCCESS;
+}
+
/*
* FIXME: error return must be handled in a cleaner way ...
*/
{
int i, candidate = META_TARGET_NONE;
- for ( i = 0; i < mi->mi_ntargets; ++i ) {
- if ( meta_back_is_candidate( &mi->mi_targets[ i ].mt_nsuffix,
- mi->mi_targets[ i ].mt_scope,
- mi->mi_targets[ i ].mt_subtree_exclude,
+ for ( i = 0; i < mi->mi_ntargets; i++ ) {
+ metatarget_t *mt = mi->mi_targets[ i ];
+
+ if ( meta_back_is_candidate( &mt->mt_nsuffix,
+ mt->mt_scope,
+ mt->mt_subtree_exclude,
ndn, LDAP_SCOPE_BASE ) )
{
if ( candidate == META_TARGET_NONE ) {
/*
* Rewrite the compare dn, if needed
*/
- dc.target = &mi->mi_targets[ i ];
+ dc.target = mi->mi_targets[ i ];
switch ( ldap_back_dn_massage( &dc, &op->o_req_dn, &mdn ) ) {
case LDAP_UNWILLING_TO_PERFORM:
* if attr is objectClass, try to remap the value
*/
if ( op->orc_ava->aa_desc == slap_schema.si_ad_objectClass ) {
- ldap_back_map( &mi->mi_targets[ i ].mt_rwmap.rwm_oc,
+ ldap_back_map( &mi->mi_targets[ i ]->mt_rwmap.rwm_oc,
&op->orc_ava->aa_value,
&mapped_value, BACKLDAP_MAP );
* else try to remap the attribute
*/
} else {
- ldap_back_map( &mi->mi_targets[ i ].mt_rwmap.rwm_at,
+ ldap_back_map( &mi->mi_targets[ i ]->mt_rwmap.rwm_at,
&op->orc_ava->aa_desc->ad_cname,
&mapped_attr, BACKLDAP_MAP );
if ( BER_BVISNULL( &mapped_attr ) || mapped_attr.bv_val[0] == '\0' ) {
static int
meta_back_new_target(
- metatarget_t *mt )
+ metatarget_t **mtp )
{
struct ldapmapping *mapping;
char *rargv[ 3 ];
+ metatarget_t *mt;
- memset( mt, 0, sizeof( metatarget_t ) );
+ *mtp = NULL;
+
+ mt = ch_calloc( sizeof( metatarget_t ), 1 );
mt->mt_rwmap.rwm_rw = rewrite_info_init( REWRITE_MODE_USE_DEFAULT );
if ( mt->mt_rwmap.rwm_rw == NULL ) {
ldap_back_map_init( &mt->mt_rwmap.rwm_at, &mapping );
+ ldap_pvt_thread_mutex_init( &mt->mt_uri_mutex );
+
+ *mtp = mt;
+
return 0;
}
struct berval dn;
int rc;
int c;
+
+ metatarget_t *mt;
switch ( argc ) {
case 1:
++mi->mi_ntargets;
- mi->mi_targets = ( metatarget_t * )ch_realloc( mi->mi_targets,
- sizeof( metatarget_t ) * mi->mi_ntargets );
+ mi->mi_targets = ( metatarget_t ** )ch_realloc( mi->mi_targets,
+ sizeof( metatarget_t * ) * mi->mi_ntargets );
if ( mi->mi_targets == NULL ) {
Debug( LDAP_DEBUG_ANY,
"%s: line %d: out of memory while storing server name"
return 1;
}
- mi->mi_targets[ i ].mt_nretries = mi->mi_nretries;
- mi->mi_targets[ i ].mt_flags = mi->mi_flags;
- mi->mi_targets[ i ].mt_version = mi->mi_version;
- mi->mi_targets[ i ].mt_network_timeout = mi->mi_network_timeout;
- mi->mi_targets[ i ].mt_bind_timeout = mi->mi_bind_timeout;
+ mt = mi->mi_targets[ i ];
+
+ mt->mt_rebind_f = mi->mi_rebind_f;
+ mt->mt_urllist_f = mi->mi_urllist_f;
+ mt->mt_urllist_p = mt;
+
+ mt->mt_nretries = mi->mi_nretries;
+ mt->mt_flags = mi->mi_flags;
+ mt->mt_version = mi->mi_version;
+ mt->mt_network_timeout = mi->mi_network_timeout;
+ mt->mt_bind_timeout = mi->mi_bind_timeout;
for ( c = 0; c < LDAP_BACK_OP_LAST; c++ ) {
- mi->mi_targets[ i ].mt_timeout[ c ] = mi->mi_timeout[ c ];
+ mt->mt_timeout[ c ] = mi->mi_timeout[ c ];
}
/*
* uri MUST be legal!
*/
- if ( ldap_url_parselist_ext( &ludp, argv[ 1 ], "\t" ) != LDAP_SUCCESS ) {
+ if ( ldap_url_parselist_ext( &ludp, argv[ 1 ], "\t",
+ LDAP_PVT_URL_PARSE_NONE ) != LDAP_SUCCESS )
+ {
Debug( LDAP_DEBUG_ANY,
"%s: line %d: unable to parse URI"
" in \"uri <protocol>://<server>[:port]/<naming context>\" line\n",
* copies and stores uri and suffix
*/
ber_str2bv( ludp->lud_dn, 0, 0, &dn );
- rc = dnPrettyNormal( NULL, &dn, &mi->mi_targets[ i ].mt_psuffix,
- &mi->mi_targets[ i ].mt_nsuffix, NULL );
+ rc = dnPrettyNormal( NULL, &dn, &mt->mt_psuffix,
+ &mt->mt_nsuffix, NULL );
if( rc != LDAP_SUCCESS ) {
Debug( LDAP_DEBUG_ANY, "%s: line %d: "
"target \"%s\" DN is invalid\n",
switch ( ludp->lud_scope ) {
case LDAP_SCOPE_DEFAULT:
- mi->mi_targets[ i ].mt_scope = LDAP_SCOPE_SUBTREE;
+ mt->mt_scope = LDAP_SCOPE_SUBTREE;
break;
case LDAP_SCOPE_SUBTREE:
case LDAP_SCOPE_SUBORDINATE:
- mi->mi_targets[ i ].mt_scope = ludp->lud_scope;
+ mt->mt_scope = ludp->lud_scope;
break;
default:
}
}
- mi->mi_targets[ i ].mt_uri = ldap_url_list2urls( ludp );
+ mt->mt_uri = ldap_url_list2urls( ludp );
ldap_free_urllist( ludp );
- if ( mi->mi_targets[ i ].mt_uri == NULL) {
+ if ( mt->mt_uri == NULL) {
Debug( LDAP_DEBUG_ANY, "%s: line %d: no memory?\n",
fname, lineno, 0 );
return( 1 );
* uri MUST be a branch of suffix!
*/
#if 0 /* too strict a constraint */
- if ( select_backend( &mi->mi_targets[ i ].suffix, 0, 0 ) != be ) {
+ if ( select_backend( &mt->mt_nsuffix, 0, 0 ) != be ) {
Debug( LDAP_DEBUG_ANY,
"%s: line %d: <naming context> of URI does not refer to current backend"
" in \"uri <protocol>://<server>[:port]/<naming context>\" line\n",
/*
* uri MUST be a branch of a suffix!
*/
- if ( select_backend( &mi->mi_targets[ i ].mt_nsuffix, 0, 0 ) == NULL ) {
+ if ( select_backend( &mt->mt_nsuffix, 0, 0 ) == NULL ) {
Debug( LDAP_DEBUG_ANY,
"%s: line %d: <naming context> of URI does not resolve to a backend"
" in \"uri <protocol>://<server>[:port]/<naming context>\" line\n",
return( 1 );
}
- if ( !dnIsSuffix( &ndn, &mi->mi_targets[ i ].mt_nsuffix ) ) {
+ if ( !dnIsSuffix( &ndn, &mi->mi_targets[ i ]->mt_nsuffix ) ) {
Debug( LDAP_DEBUG_ANY, "%s: line %d: "
"subtree-exclude DN=\"%s\" "
"must be subtree of target\n",
return( 1 );
}
- if ( mi->mi_targets[ i ].mt_subtree_exclude != NULL ) {
+ if ( mi->mi_targets[ i ]->mt_subtree_exclude != NULL ) {
int j;
- for ( j = 0; !BER_BVISNULL( &mi->mi_targets[ i ].mt_subtree_exclude[ j ] ); j++ )
+ for ( j = 0; !BER_BVISNULL( &mi->mi_targets[ i ]->mt_subtree_exclude[ j ] ); j++ )
{
- if ( dnIsSuffix( &mi->mi_targets[ i ].mt_subtree_exclude[ j ], &ndn ) ) {
+ if ( dnIsSuffix( &mi->mi_targets[ i ]->mt_subtree_exclude[ j ], &ndn ) ) {
Debug( LDAP_DEBUG_ANY, "%s: line %d: "
"subtree-exclude DN=\"%s\" "
"is suffix of another subtree-exclude\n",
ber_memfree( ndn.bv_val );
return( 1 );
- } else if ( dnIsSuffix( &ndn, &mi->mi_targets[ i ].mt_subtree_exclude[ j ] ) ) {
+ } else if ( dnIsSuffix( &ndn, &mi->mi_targets[ i ]->mt_subtree_exclude[ j ] ) ) {
Debug( LDAP_DEBUG_ANY, "%s: line %d: "
"another subtree-exclude is suffix of "
"subtree-exclude DN=\"%s\"\n",
}
}
- ber_bvarray_add( &mi->mi_targets[ i ].mt_subtree_exclude, &ndn );
+ ber_bvarray_add( &mi->mi_targets[ i ]->mt_subtree_exclude, &ndn );
/* default target directive */
} else if ( strcasecmp( argv[ 0 ], "default-target" ) == 0 ) {
} else if ( strcasecmp( argv[ 0 ], "network-timeout" ) == 0 ) {
unsigned long t;
time_t *tp = mi->mi_ntargets ?
- &mi->mi_targets[ mi->mi_ntargets - 1 ].mt_network_timeout
+ &mi->mi_targets[ mi->mi_ntargets - 1 ]->mt_network_timeout
: &mi->mi_network_timeout;
if ( argc != 2 ) {
} else if ( strcasecmp( argv[ 0 ], "bind-timeout" ) == 0 ) {
unsigned long t;
struct timeval *tp = mi->mi_ntargets ?
- &mi->mi_targets[ mi->mi_ntargets - 1 ].mt_bind_timeout
+ &mi->mi_targets[ mi->mi_ntargets - 1 ]->mt_bind_timeout
: &mi->mi_bind_timeout;
switch ( argc ) {
}
ber_str2bv( argv[ 1 ], 0, 0, &dn );
- if ( dnNormalize( 0, NULL, NULL, &dn, &mi->mi_targets[ i ].mt_binddn,
+ if ( dnNormalize( 0, NULL, NULL, &dn, &mi->mi_targets[ i ]->mt_binddn,
NULL ) != LDAP_SUCCESS )
{
Debug( LDAP_DEBUG_ANY, "%s: line %d: "
/* FIXME: some day we'll need to throw an error */
}
- ber_str2bv( argv[ 1 ], 0L, 1, &mi->mi_targets[ i ].mt_bindpw );
+ ber_str2bv( argv[ 1 ], 0L, 1, &mi->mi_targets[ i ]->mt_bindpw );
/* save bind creds for referral rebinds? */
} else if ( strcasecmp( argv[ 0 ], "rebind-as-user" ) == 0 ) {
} else if ( strcasecmp( argv[ 0 ], "chase-referrals" ) == 0 ) {
unsigned *flagsp = mi->mi_ntargets ?
- &mi->mi_targets[ mi->mi_ntargets - 1 ].mt_flags
+ &mi->mi_targets[ mi->mi_ntargets - 1 ]->mt_flags
: &mi->mi_flags;
if ( argc != 2 ) {
} else if ( strcasecmp( argv[ 0 ], "tls" ) == 0 ) {
unsigned *flagsp = mi->mi_ntargets ?
- &mi->mi_targets[ mi->mi_ntargets - 1 ].mt_flags
+ &mi->mi_targets[ mi->mi_ntargets - 1 ]->mt_flags
: &mi->mi_flags;
if ( argc != 2 ) {
} else if ( strcasecmp( argv[ 0 ], "t-f-support" ) == 0 ) {
unsigned *flagsp = mi->mi_ntargets ?
- &mi->mi_targets[ mi->mi_ntargets - 1 ].mt_flags
+ &mi->mi_targets[ mi->mi_ntargets - 1 ]->mt_flags
: &mi->mi_flags;
if ( argc != 2 ) {
} else if ( strcasecmp( argv[ 0 ], "timeout" ) == 0 ) {
char *sep;
time_t *tv = mi->mi_ntargets ?
- mi->mi_targets[ mi->mi_ntargets - 1 ].mt_timeout
+ mi->mi_targets[ mi->mi_ntargets - 1 ]->mt_timeout
: mi->mi_timeout;
int c;
dn.bv_val = argv[ 1 ];
dn.bv_len = strlen( argv[ 1 ] );
if ( dnNormalize( 0, NULL, NULL, &dn,
- &mi->mi_targets[ i ].mt_pseudorootdn, NULL ) != LDAP_SUCCESS )
+ &mi->mi_targets[ i ]->mt_pseudorootdn, NULL ) != LDAP_SUCCESS )
{
Debug( LDAP_DEBUG_ANY, "%s: line %d: "
"pseudoroot DN '%s' is invalid\n",
fname, lineno, 0 );
return 1;
}
- ber_str2bv( argv[ 1 ], 0L, 1, &mi->mi_targets[ i ].mt_pseudorootpw );
+ ber_str2bv( argv[ 1 ], 0L, 1, &mi->mi_targets[ i ]->mt_pseudorootpw );
/* dn massaging */
} else if ( strcasecmp( argv[ 0 ], "suffixmassage" ) == 0 ) {
* FIXME: no extra rewrite capabilities should be added
* to the database
*/
- rc = suffix_massage_config( mi->mi_targets[ i ].mt_rwmap.rwm_rw,
+ rc = suffix_massage_config( mi->mi_targets[ i ]->mt_rwmap.rwm_rw,
&pvnc, &nvnc, &prnc, &nrnc );
free( pvnc.bv_val );
return 1;
}
- return rewrite_parse( mi->mi_targets[ i ].mt_rwmap.rwm_rw,
+ return rewrite_parse( mi->mi_targets[ i ]->mt_rwmap.rwm_rw,
fname, lineno, argc, argv );
/* objectclass/attribute mapping */
return 1;
}
- return ldap_back_map_config( &mi->mi_targets[ i ].mt_rwmap.rwm_oc,
- &mi->mi_targets[ i ].mt_rwmap.rwm_at,
+ return ldap_back_map_config( &mi->mi_targets[ i ]->mt_rwmap.rwm_oc,
+ &mi->mi_targets[ i ]->mt_rwmap.rwm_at,
fname, lineno, argc, argv );
} else if ( strcasecmp( argv[ 0 ], "nretries" ) == 0 ) {
mi->mi_nretries = nretries;
} else {
- mi->mi_targets[ i ].mt_nretries = nretries;
+ mi->mi_targets[ i ]->mt_nretries = nretries;
}
} else if ( strcasecmp( argv[ 0 ], "protocol-version" ) == 0 ) {
int *version = mi->mi_ntargets ?
- &mi->mi_targets[ mi->mi_ntargets - 1 ].mt_version
+ &mi->mi_targets[ mi->mi_ntargets - 1 ]->mt_version
: &mi->mi_version;
if ( argc != 2 ) {
int version;
dncookie dc;
int isauthz = ( candidate == mc->mc_authz_target );
+#ifdef HAVE_TLS
+ int is_ldaps = 0;
+#endif /* HAVE_TLS */
/*
* Already init'ed
/*
* Attempts to initialize the connection to the target ds
*/
+ ldap_pvt_thread_mutex_lock( &mt->mt_uri_mutex );
rs->sr_err = ldap_initialize( &msc->msc_ld, mt->mt_uri );
+#ifdef HAVE_TLS
+ is_ldaps = ldap_is_ldaps_url( mt->mt_uri );
+#endif /* HAVE_TLS */
+ ldap_pvt_thread_mutex_unlock( &mt->mt_uri_mutex );
if ( rs->sr_err != LDAP_SUCCESS ) {
goto error_return;
}
version = LDAP_VERSION3;
}
ldap_set_option( msc->msc_ld, LDAP_OPT_PROTOCOL_VERSION, &version );
+ ldap_set_urllist_proc( msc->msc_ld, mt->mt_urllist_f, mt->mt_urllist_p );
/* automatically chase referrals ("chase-referrals [{yes|no}]" statement) */
ldap_set_option( msc->msc_ld, LDAP_OPT_REFERRALS,
#ifdef HAVE_TLS
/* start TLS ("tls [try-]{start|propagate}" statement) */
if ( ( LDAP_BACK_USE_TLS( mi ) || ( op->o_conn->c_is_tls && LDAP_BACK_PROPAGATE_TLS( mi ) ) )
- && !ldap_is_ldaps_url( mt->mt_uri ) )
+ && !is_ldaps )
{
#ifdef SLAP_STARTTLS_ASYNCHRONOUS
/*
ldap_back_send_t sendok )
{
metainfo_t *mi = ( metainfo_t * )op->o_bd->be_private;
- metatarget_t *mt = &mi->mi_targets[ candidate ];
+ metatarget_t *mt = mi->mi_targets[ candidate ];
metaconn_t *mc = *mcp;
metasingleconn_t *msc = &mc->mc_conns[ candidate ];
int rc = LDAP_UNAVAILABLE,
assert( mc->mc_refcnt > 0 );
if ( mc->mc_refcnt == 1 ) {
- char buf[ SLAP_TEXT_BUFLEN ];
+ if ( LogTest( LDAP_DEBUG_ANY ) ) {
+ char buf[ SLAP_TEXT_BUFLEN ];
- snprintf( buf, sizeof( buf ),
- "retrying URI=\"%s\" DN=\"%s\"",
- mt->mt_uri,
- BER_BVISNULL( &msc->msc_bound_ndn ) ?
- "" : msc->msc_bound_ndn.bv_val );
- Debug( LDAP_DEBUG_ANY,
- "%s meta_back_retry[%d]: %s.\n",
- op->o_log_prefix, candidate, buf );
+ ldap_pvt_thread_mutex_lock( &mt->mt_uri_mutex );
+ snprintf( buf, sizeof( buf ),
+ "retrying URI=\"%s\" DN=\"%s\"",
+ mt->mt_uri,
+ BER_BVISNULL( &msc->msc_bound_ndn ) ?
+ "" : msc->msc_bound_ndn.bv_val );
+ ldap_pvt_thread_mutex_unlock( &mt->mt_uri_mutex );
+
+ Debug( LDAP_DEBUG_ANY,
+ "%s meta_back_retry[%d]: %s.\n",
+ op->o_log_prefix, candidate, buf );
+ }
meta_clear_one_candidate( msc );
LDAP_BACK_CONN_ISBOUND_CLEAR( msc );
* and a default target is defined, and it is
* a candidate, try using it (FIXME: YMMV) */
if ( mi->mi_defaulttarget != META_DEFAULT_TARGET_NONE
- && meta_back_is_candidate( &mi->mi_targets[ mi->mi_defaulttarget ].mt_nsuffix,
- mi->mi_targets[ mi->mi_defaulttarget ].mt_scope,
- mi->mi_targets[ mi->mi_defaulttarget ].mt_subtree_exclude,
+ && meta_back_is_candidate( &mi->mi_targets[ mi->mi_defaulttarget ]->mt_nsuffix,
+ mi->mi_targets[ mi->mi_defaulttarget ]->mt_scope,
+ mi->mi_targets[ mi->mi_defaulttarget ]->mt_subtree_exclude,
ndn, op->o_tag == LDAP_REQ_SEARCH ? op->ors_scope : LDAP_SCOPE_BASE ) )
{
candidate = mi->mi_defaulttarget;
}
for ( i = 0; i < mi->mi_ntargets; i++ ) {
- metatarget_t *mt = &mi->mi_targets[ i ];
+ metatarget_t *mt = mi->mi_targets[ i ];
/*
* The target is activated; if needed, it is
*/
( void )meta_clear_unused_candidates( op, i );
- mt = &mi->mi_targets[ i ];
+ mt = mi->mi_targets[ i ];
msc = &mc->mc_conns[ i ];
/*
}
for ( i = 0; i < mi->mi_ntargets; i++ ) {
- metatarget_t *mt = &mi->mi_targets[ i ];
+ metatarget_t *mt = mi->mi_targets[ i ];
metasingleconn_t *msc = &mc->mc_conns[ i ];
if ( i == cached
/*
* Rewrite the compare dn, if needed
*/
- dc.target = &mi->mi_targets[ candidate ];
+ dc.target = mi->mi_targets[ candidate ];
dc.conn = op->o_conn;
dc.rs = rs;
dc.ctx = "deleteDN";
LDAPMessage *res = NULL;
int rc;
- if ( mi->mi_targets[ candidate ].mt_timeout[ LDAP_BACK_OP_DELETE ] != 0 ) {
- tv.tv_sec = mi->mi_targets[ candidate ].mt_timeout[ LDAP_BACK_OP_DELETE ];
+ if ( mi->mi_targets[ candidate ]->mt_timeout[ LDAP_BACK_OP_DELETE ] != 0 ) {
+ tv.tv_sec = mi->mi_targets[ candidate ]->mt_timeout[ LDAP_BACK_OP_DELETE ];
tv.tv_usec = 0;
tvp = &tv;
}
mi->mi_bind_timeout.tv_sec = 0;
mi->mi_bind_timeout.tv_usec = META_BIND_TIMEOUT;
+ mi->mi_rebind_f = meta_back_default_rebind;
+ mi->mi_urllist_f = meta_back_default_urllist;
+
ldap_pvt_thread_mutex_init( &mi->mi_conninfo.lai_mutex );
ldap_pvt_thread_mutex_init( &mi->mi_cache.mutex );
int i, rc;
for ( i = 0; i < mi->mi_ntargets; i++ ) {
- if ( mi->mi_targets[ i ].mt_flags & LDAP_BACK_F_SUPPORT_T_F_DISCOVER )
+ metatarget_t *mt = mi->mi_targets[ i ];
+
+ if ( mt->mt_flags & LDAP_BACK_F_SUPPORT_T_F_DISCOVER )
{
- mi->mi_targets[ i ].mt_flags &= ~LDAP_BACK_F_SUPPORT_T_F_DISCOVER;
- rc = slap_discover_feature( mi->mi_targets[ i ].mt_uri,
- mi->mi_targets[ i ].mt_version,
+ mt->mt_flags &= ~LDAP_BACK_F_SUPPORT_T_F_DISCOVER;
+ rc = slap_discover_feature( mt->mt_uri,
+ mt->mt_version,
slap_schema.si_ad_supportedFeatures->ad_cname.bv_val,
LDAP_FEATURE_ABSOLUTE_FILTERS );
if ( rc == LDAP_COMPARE_TRUE ) {
- mi->mi_targets[ i ].mt_flags |= LDAP_BACK_F_SUPPORT_T_F;
+ mt->mt_flags |= LDAP_BACK_F_SUPPORT_T_F;
}
}
}
{
if ( mt->mt_uri ) {
free( mt->mt_uri );
+ ldap_pvt_thread_mutex_destroy( &mt->mt_uri_mutex );
}
if ( mt->mt_subtree_exclude ) {
ber_bvarray_free( mt->mt_subtree_exclude );
avl_free( mt->mt_rwmap.rwm_oc.map, mapping_free );
avl_free( mt->mt_rwmap.rwm_at.remap, mapping_dst_free );
avl_free( mt->mt_rwmap.rwm_at.map, mapping_free );
+
+ free( mt );
}
int
*/
if ( mi->mi_targets != NULL ) {
for ( i = 0; i < mi->mi_ntargets; i++ ) {
- target_free( &mi->mi_targets[ i ] );
+ target_free( mi->mi_targets[ i ] );
}
free( mi->mi_targets );
/*
* Rewrite the modify dn, if needed
*/
- dc.target = &mi->mi_targets[ candidate ];
+ dc.target = mi->mi_targets[ candidate ];
dc.conn = op->o_conn;
dc.rs = rs;
dc.ctx = "modifyDN";
mapped = ml->sml_desc->ad_cname;
} else {
- ldap_back_map( &mi->mi_targets[ candidate ].mt_rwmap.rwm_at,
+ ldap_back_map( &mi->mi_targets[ candidate ]->mt_rwmap.rwm_at,
&ml->sml_desc->ad_cname, &mapped,
BACKLDAP_MAP );
if ( BER_BVISNULL( &mapped ) || BER_BVISEMPTY( &mapped ) ) {
for ( j = 0; !BER_BVISNULL( &ml->sml_values[ j ] ); ) {
struct ldapmapping *mapping;
- ldap_back_mapping( &mi->mi_targets[ candidate ].mt_rwmap.rwm_oc,
+ ldap_back_mapping( &mi->mi_targets[ candidate ]->mt_rwmap.rwm_oc,
&ml->sml_values[ j ], &mapping, BACKLDAP_MAP );
if ( mapping == NULL ) {
- if ( mi->mi_targets[ candidate ].mt_rwmap.rwm_oc.drop_missing ) {
+ if ( mi->mi_targets[ candidate ]->mt_rwmap.rwm_oc.drop_missing ) {
continue;
}
mods[ i ].mod_bvalues[ j ] = &ml->sml_values[ j ];
struct timeval tv, *tvp = NULL;
LDAPMessage *res = NULL;
- if ( mi->mi_targets[ candidate ].mt_timeout[ LDAP_BACK_OP_MODIFY ] != 0 ) {
- tv.tv_sec = mi->mi_targets[ candidate ].mt_timeout[ LDAP_BACK_OP_MODIFY ];
+ if ( mi->mi_targets[ candidate ]->mt_timeout[ LDAP_BACK_OP_MODIFY ] != 0 ) {
+ tv.tv_sec = mi->mi_targets[ candidate ]->mt_timeout[ LDAP_BACK_OP_MODIFY ];
tv.tv_usec = 0;
tvp = &tv;
}
*/
/* needs LDAPv3 */
- switch ( mi->mi_targets[ candidate ].mt_version ) {
+ switch ( mi->mi_targets[ candidate ]->mt_version ) {
case LDAP_VERSION3:
break;
/*
* Rewrite the new superior, if defined and required
*/
- dc.target = &mi->mi_targets[ candidate ];
+ dc.target = mi->mi_targets[ candidate ];
dc.ctx = "newSuperiorDN";
if ( ldap_back_dn_massage( &dc, op->orr_newSup, &mnewSuperior ) ) {
rs->sr_err = LDAP_OTHER;
/*
* Rewrite the modrdn dn, if required
*/
- dc.target = &mi->mi_targets[ candidate ];
+ dc.target = mi->mi_targets[ candidate ];
dc.ctx = "modrDN";
if ( ldap_back_dn_massage( &dc, &op->o_req_dn, &mdn ) ) {
rs->sr_err = LDAP_OTHER;
LDAPMessage *res = NULL;
int rc;
- if ( mi->mi_targets[ candidate ].mt_timeout[ LDAP_BACK_OP_MODRDN ] != 0 ) {
- tv.tv_sec = mi->mi_targets[ candidate ].mt_timeout[ LDAP_BACK_OP_MODRDN ];
+ if ( mi->mi_targets[ candidate ]->mt_timeout[ LDAP_BACK_OP_MODRDN ] != 0 ) {
+ tv.tv_sec = mi->mi_targets[ candidate ]->mt_timeout[ LDAP_BACK_OP_MODRDN ];
tv.tv_usec = 0;
tvp = &tv;
}
{
metaconn_t *mc = *mcp;
metainfo_t *mi = ( metainfo_t * )op->o_bd->be_private;
- metatarget_t *mt = &mi->mi_targets[ candidate ];
+ metatarget_t *mt = mi->mi_targets[ candidate ];
metasingleconn_t *msc = &mc->mc_conns[ candidate ];
char *binddn = "";
SlapReply *candidates )
{
metainfo_t *mi = ( metainfo_t * )op->o_bd->be_private;
- metatarget_t *mt = &mi->mi_targets[ candidate ];
+ metatarget_t *mt = mi->mi_targets[ candidate ];
metaconn_t *mc = *mcp;
metasingleconn_t *msc = &mc->mc_conns[ candidate ];
struct berval realbase = op->o_req_dn;
candidates[ i ].sr_matched = NULL;
dc.ctx = "matchedDN";
- dc.target = &mi->mi_targets[ i ];
+ dc.target = mi->mi_targets[ i ];
if ( !ldap_back_dn_massage( &dc, &match, &mmatch ) ) {
if ( mmatch.bv_val == match.bv_val ) {
candidates[ i ].sr_matched = ch_strdup( mmatch.bv_val );
* ignore the matchedDN */
if ( sres == LDAP_SUCCESS
&& candidates[ i ].sr_err == LDAP_NO_SUCH_OBJECT
- && op->o_req_ndn.bv_len > mi->mi_targets[ i ].mt_nsuffix.bv_len )
+ && op->o_req_ndn.bv_len > mi->mi_targets[ i ]->mt_nsuffix.bv_len )
{
free( (char *)candidates[ i ].sr_matched );
candidates[ i ].sr_matched = NULL;
/*
* Rewrite the dn of the result, if needed
*/
- dc.target = &mi->mi_targets[ target ];
+ dc.target = mi->mi_targets[ target ];
dc.conn = op->o_conn;
dc.rs = rs;
dc.ctx = "searchResult";
slap_syntax_validate_func *validate;
slap_syntax_transform_func *pretty;
- ldap_back_map( &mi->mi_targets[ target ].mt_rwmap.rwm_at,
+ ldap_back_map( &mi->mi_targets[ target ]->mt_rwmap.rwm_at,
&a, &mapped, BACKLDAP_REMAP );
if ( BER_BVISNULL( &mapped ) || mapped.bv_val[0] == '\0' ) {
( void )ber_scanf( &ber, "x" /* [W] */ );
struct berval *bv;
for ( bv = attr->a_vals; !BER_BVISNULL( bv ); bv++ ) {
- ldap_back_map( &mi->mi_targets[ target ].mt_rwmap.rwm_oc,
+ ldap_back_map( &mi->mi_targets[ target ]->mt_rwmap.rwm_oc,
bv, &mapped, BACKLDAP_REMAP );
if ( BER_BVISNULL( &mapped ) || mapped.bv_val[0] == '\0') {
free( bv->bv_val );
* Cleanup rewrite session
*/
for ( i = 0; i < mi->mi_ntargets; ++i ) {
- rewrite_session_delete( mi->mi_targets[ i ].mt_rwmap.rwm_rw, conn );
+ rewrite_session_delete( mi->mi_targets[ i ]->mt_rwmap.rwm_rw, conn );
}
return 0;
int t;
for ( t = 0; t < mi->mi_ntargets; t++ ) {
- char **urls = ldap_str2charray( mi->mi_targets[ t ].mt_uri, " " );
+ char **urls = ldap_str2charray( mi->mi_targets[ t ]->mt_uri, " " );
if ( urls != NULL ) {
int u;
int rc;
LDAPURLDesc *lurl;
- rc = ldap_url_parse_ext( url, &lurl );
+ rc = ldap_url_parse_ext( url, &lurl, LDAP_PVT_URL_PARSE_NONE );
switch( rc ) {
case LDAP_URL_SUCCESS:
char *dn;
int rc;
- rc = ldap_url_parse_ext( iv->bv_val, &url );
+ rc = ldap_url_parse_ext( iv->bv_val, &url, LDAP_PVT_URL_PARSE_NONE );
if ( rc == LDAP_URL_ERR_BADSCHEME ) {
ber_dupbv( jv++, iv );
continue;