From 373ded8d2475efd3f8e8b9ba37b3883b73511e9c Mon Sep 17 00:00:00 2001 From: Pierangelo Masarati Date: Sat, 6 May 2006 16:15:25 +0000 Subject: [PATCH] add URI list resorting feature (ITS#4524) --- include/ldap.h | 13 ++++ include/ldap_pvt.h | 21 +++++- libraries/libldap/ldap-int.h | 19 ++--- libraries/libldap/open.c | 8 ++- libraries/libldap/options.c | 34 ++++++++- libraries/libldap/request.c | 46 +++++-------- libraries/libldap/url.c | 95 +++++++++++++------------ servers/slapd/back-ldap/back-ldap.h | 40 +++++++---- servers/slapd/back-ldap/bind.c | 57 ++++++++++++--- servers/slapd/back-ldap/chain.c | 10 ++- servers/slapd/back-ldap/config.c | 2 +- servers/slapd/back-ldap/init.c | 6 ++ servers/slapd/back-ldap/proto-ldap.h | 3 +- servers/slapd/back-meta/add.c | 12 ++-- servers/slapd/back-meta/back-meta.h | 16 ++++- servers/slapd/back-meta/bind.c | 71 +++++++++++++------ servers/slapd/back-meta/candidates.c | 10 +-- servers/slapd/back-meta/compare.c | 6 +- servers/slapd/back-meta/config.c | 99 ++++++++++++++++----------- servers/slapd/back-meta/conn.c | 48 ++++++++----- servers/slapd/back-meta/delete.c | 6 +- servers/slapd/back-meta/init.c | 20 ++++-- servers/slapd/back-meta/modify.c | 12 ++-- servers/slapd/back-meta/modrdn.c | 10 +-- servers/slapd/back-meta/search.c | 14 ++-- servers/slapd/back-meta/unbind.c | 2 +- servers/slapd/back-monitor/database.c | 2 +- servers/slapd/referral.c | 4 +- 28 files changed, 446 insertions(+), 240 deletions(-) diff --git a/include/ldap.h b/include/ldap.h index c9d9d574de..c567d6adcc 100644 --- a/include/ldap.h +++ b/include/ldap.h @@ -784,6 +784,19 @@ ldap_set_nextref_proc LDAP_P(( 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: */ diff --git a/include/ldap_pvt.h b/include/ldap_pvt.h index 7463c9ea27..89fe20c6f0 100644 --- a/include/ldap_pvt.h +++ b/include/ldap_pvt.h @@ -41,10 +41,29 @@ ldap_pvt_url_scheme_port LDAP_P(( struct ldap_url_desc; /* avoid pulling in */ +#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(( diff --git a/libraries/libldap/ldap-int.h b/libraries/libldap/ldap-int.h index 99d7331122..9863b32b60 100644 --- a/libraries/libldap/ldap-int.h +++ b/libraries/libldap/ldap-int.h @@ -225,6 +225,8 @@ struct ldapoptions { 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 */ }; @@ -339,6 +341,8 @@ struct ldap { #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 @@ -525,8 +529,8 @@ LDAP_F (ber_int_t) ldap_send_initial_request( LDAP *ld, ber_tag_t msgtype, 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 ); @@ -589,11 +593,6 @@ LDAP_F (int) ldap_url_parselist LDAP_P(( 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, @@ -602,12 +601,6 @@ LDAP_F (int) ldap_url_parsehosts LDAP_P(( 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 */ diff --git a/libraries/libldap/open.c b/libraries/libldap/open.c index d1eaf04b2a..e01c5ea28e 100644 --- a/libraries/libldap/open.c +++ b/libraries/libldap/open.c @@ -37,8 +37,14 @@ 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; diff --git a/libraries/libldap/options.c b/libraries/libldap/options.c index cfc4711eb1..cca205a0d9 100644 --- a/libraries/libldap/options.c +++ b/libraries/libldap/options.c @@ -31,6 +31,9 @@ #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 */ @@ -475,7 +478,9 @@ ldap_set_option( * 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 { /* @@ -502,13 +507,17 @@ ldap_set_option( 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 { /* @@ -638,6 +647,14 @@ ldap_set_option( 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: @@ -733,3 +750,14 @@ ldap_set_nextref_proc( LDAP *ld, LDAP_NEXTREF_PROC *proc, void *params ) 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; +} diff --git a/libraries/libldap/request.c b/libraries/libldap/request.c index 5786816fd3..0847544b65 100644 --- a/libraries/libldap/request.c +++ b/libraries/libldap/request.c @@ -174,7 +174,7 @@ ldap_send_server_request( BerElement *ber, ber_int_t msgid, LDAPRequest *parentreq, - LDAPURLDesc *srvlist, + LDAPURLDesc **srvlist, LDAPConn *lc, LDAPreqinfo *bind ) { @@ -190,7 +190,7 @@ ldap_send_server_request( 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 */ @@ -300,11 +300,10 @@ ldap_send_server_request( } 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) ); @@ -332,9 +331,17 @@ ldap_new_connection( LDAP *ld, LDAPURLDesc *srvlist, int use_ldsb, } 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; } } @@ -361,11 +368,7 @@ ldap_new_connection( LDAP *ld, LDAPURLDesc *srvlist, int use_ldsb, 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; @@ -378,7 +381,7 @@ ldap_new_connection( LDAP *ld, LDAPURLDesc *srvlist, int use_ldsb, 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; @@ -885,7 +888,7 @@ ldap_chase_v3referrals( LDAP *ld, LDAPRequest *lr, char **refs, int sref, char * { /* 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 */ @@ -901,12 +904,6 @@ ldap_chase_v3referrals( LDAP *ld, LDAPRequest *lr, char **refs, int sref, char * 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 */ @@ -1020,7 +1017,7 @@ ldap_chase_v3referrals( LDAP *ld, LDAPRequest *lr, char **refs, int sref, char * 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 @@ -1152,7 +1149,7 @@ ldap_chase_referrals( LDAP *ld, *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", @@ -1162,11 +1159,6 @@ ldap_chase_referrals( LDAP *ld, 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 ); @@ -1212,7 +1204,7 @@ ldap_chase_referrals( LDAP *ld, 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 diff --git a/libraries/libldap/url.c b/libraries/libldap/url.c index 4c27ed33f2..e35be8f9f0 100644 --- a/libraries/libldap/url.c +++ b/libraries/libldap/url.c @@ -759,7 +759,7 @@ ldap_url_desc2str( LDAPURLDesc *u ) } 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. @@ -772,6 +772,8 @@ ldap_url_parse_ext( LDAP_CONST char *url_in, LDAPURLDesc **ludpp ) const char *url_tmp; char *url; + int check_dn = 1; + if( url_in == NULL || ludpp == NULL ) { return LDAP_URL_ERR_PARAM; } @@ -825,7 +827,7 @@ ldap_url_parse_ext( LDAP_CONST char *url_in, LDAPURLDesc **ludpp ) 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; @@ -879,6 +881,18 @@ ldap_url_parse_ext( LDAP_CONST char *url_in, LDAPURLDesc **ludpp ) } } + 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 [ */ @@ -890,6 +904,14 @@ ldap_url_parse_ext( LDAP_CONST char *url_in, LDAPURLDesc **ludpp ) 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 * @@ -908,11 +930,15 @@ ldap_url_parse_ext( LDAP_CONST char *url_in, LDAPURLDesc **ludpp ) /* 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; @@ -938,11 +964,15 @@ ldap_url_parse_ext( LDAP_CONST char *url_in, LDAPURLDesc **ludpp ) /* 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; @@ -1092,34 +1122,7 @@ ldap_url_parse_ext( LDAP_CONST char *url_in, LDAPURLDesc **ludpp ) 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 * @@ -1218,8 +1221,8 @@ ldap_url_duplist (LDAPURLDesc *ludlist) } 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; @@ -1230,7 +1233,11 @@ ldap_url_parselist_int (LDAPURLDesc **ludlist, const char *url, const char *sep, *ludlist = NULL; - urls = ldap_str2charray(url, sep); + if ( sep == NULL ) { + sep = ", "; + } + + urls = ldap_str2charray( url, sep ); if (urls == NULL) return LDAP_URL_ERR_MEM; @@ -1238,30 +1245,30 @@ ldap_url_parselist_int (LDAPURLDesc **ludlist, const char *url, const char *sep, 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 diff --git a/servers/slapd/back-ldap/back-ldap.h b/servers/slapd/back-ldap/back-ldap.h index 3fb58ba581..49017d2ed2 100644 --- a/servers/slapd/back-ldap/back-ldap.h +++ b/servers/slapd/back-ldap/back-ldap.h @@ -54,13 +54,15 @@ typedef struct ldapconn_t { } \ } 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) @@ -127,6 +129,11 @@ typedef struct ldapinfo_t { /* 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 @@ -169,21 +176,23 @@ typedef struct ldapinfo_t { #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 ) @@ -191,6 +200,7 @@ typedef struct ldapinfo_t { #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; diff --git a/servers/slapd/back-ldap/bind.c b/servers/slapd/back-ldap/bind.c index 1a13895369..2b0d39bd25 100644 --- a/servers/slapd/back-ldap/bind.c +++ b/servers/slapd/back-ldap/bind.c @@ -41,10 +41,6 @@ #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 ); @@ -103,7 +99,7 @@ ldap_back_bind( Operation *op, SlapReply *rs ) 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:; @@ -478,11 +474,17 @@ ldap_back_prepare_conn( ldapconn_t **lcp, Operation *op, SlapReply *rs, ldap_bac 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. */ @@ -511,8 +513,10 @@ ldap_back_prepare_conn( ldapconn_t **lcp, Operation *op, SlapReply *rs, ldap_bac } #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; @@ -898,8 +902,8 @@ retry_lock:; 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; } } @@ -1013,7 +1017,7 @@ ldap_back_dobind( ldapconn_t *lc, Operation *op, SlapReply *rs, ldap_back_send_t * 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 ) { @@ -1042,6 +1046,41 @@ ldap_back_default_rebind( LDAP *ld, LDAP_CONST char *url, ber_tag_t request, 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, @@ -1160,11 +1199,13 @@ ldap_back_retry( ldapconn_t **lcp, Operation *op, SlapReply *rs, ldap_back_send_ 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; diff --git a/servers/slapd/back-ldap/chain.c b/servers/slapd/back-ldap/chain.c index 6c04162075..ca6afdd2d6 100644 --- a/servers/slapd/back-ldap/chain.c +++ b/servers/slapd/back-ldap/chain.c @@ -381,7 +381,7 @@ Document: draft-ietf-ldapbis-protocol-27.txt /* 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; @@ -618,7 +618,7 @@ ldap_chain_response( Operation *op, SlapReply *rs ) /* 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; @@ -1550,6 +1550,7 @@ ldap_chain_db_init_common( BackendDB *be ) { BackendInfo *bi = be->bd_info; + ldapinfo_t *li; int t; be->bd_info = lback; @@ -1558,6 +1559,9 @@ ldap_chain_db_init_common( 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; @@ -1590,6 +1594,8 @@ ldap_chain_db_init_one( 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; diff --git a/servers/slapd/back-ldap/config.c b/servers/slapd/back-ldap/config.c index c0123fe8eb..2df70bcfa9 100644 --- a/servers/slapd/back-ldap/config.c +++ b/servers/slapd/back-ldap/config.c @@ -747,7 +747,7 @@ ldap_back_cf_gen( ConfigArgs *c ) } /* 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; diff --git a/servers/slapd/back-ldap/init.c b/servers/slapd/back-ldap/init.c index 77a10e78c8..765f201c21 100644 --- a/servers/slapd/back-ldap/init.c +++ b/servers/slapd/back-ldap/init.c @@ -103,6 +103,11 @@ ldap_back_db_init( Backend *be ) 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 ); @@ -304,6 +309,7 @@ ldap_back_db_destroy( 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 ); diff --git a/servers/slapd/back-ldap/proto-ldap.h b/servers/slapd/back-ldap/proto-ldap.h index 153a25978a..05d6883254 100644 --- a/servers/slapd/back-ldap/proto-ldap.h +++ b/servers/slapd/back-ldap/proto-ldap.h @@ -81,7 +81,8 @@ extern int chain_initialize( void ); 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 diff --git a/servers/slapd/back-meta/add.c b/servers/slapd/back-meta/add.c index 2b08958374..02a0093d5c 100644 --- a/servers/slapd/back-meta/add.c +++ b/servers/slapd/back-meta/add.c @@ -63,7 +63,7 @@ meta_back_add( Operation *op, SlapReply *rs ) /* * 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"; @@ -96,7 +96,7 @@ meta_back_add( Operation *op, SlapReply *rs ) 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; @@ -121,11 +121,11 @@ meta_back_add( Operation *op, SlapReply *rs ) 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 ]; @@ -180,8 +180,8 @@ retry:; 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; } diff --git a/servers/slapd/back-meta/back-meta.h b/servers/slapd/back-meta/back-meta.h index fe5766cbb9..0516f619f3 100644 --- a/servers/slapd/back-meta/back-meta.h +++ b/servers/slapd/back-meta/back-meta.h @@ -199,6 +199,14 @@ typedef struct metaconn_t { 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; @@ -247,9 +255,12 @@ typedef struct metainfo_t { #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; @@ -434,7 +445,8 @@ meta_dncache_delete_entry( 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 diff --git a/servers/slapd/back-meta/bind.c b/servers/slapd/back-meta/bind.c index 78ffc28ef6..fd0539d7ad 100644 --- a/servers/slapd/back-meta/bind.c +++ b/servers/slapd/back-meta/bind.c @@ -34,13 +34,6 @@ #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 ) { @@ -115,6 +108,7 @@ 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; @@ -144,7 +138,7 @@ meta_back_bind( Operation *op, SlapReply *rs ) } if ( isroot ) { - if ( BER_BVISNULL( &mi->mi_targets[ i ].mt_pseudorootdn ) ) + if ( BER_BVISNULL( &mt->mt_pseudorootdn ) ) { metasingleconn_t *msc = &mc->mc_conns[ i ]; @@ -167,9 +161,9 @@ meta_back_bind( Operation *op, SlapReply *rs ) 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; @@ -274,7 +268,7 @@ meta_back_single_bind( 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, @@ -418,7 +412,7 @@ retry:; 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 @@ -450,7 +444,7 @@ meta_back_single_dobind( 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; @@ -465,14 +459,14 @@ meta_back_single_dobind( * 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 ); @@ -665,7 +659,7 @@ meta_back_dobind( } 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; @@ -805,7 +799,7 @@ send_err:; * 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, @@ -820,6 +814,43 @@ meta_back_default_rebind( 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 ... */ diff --git a/servers/slapd/back-meta/candidates.c b/servers/slapd/back-meta/candidates.c index 794d1b3a47..27d3c2eaa1 100644 --- a/servers/slapd/back-meta/candidates.c +++ b/servers/slapd/back-meta/candidates.c @@ -136,10 +136,12 @@ meta_back_select_unique_candidate( { 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 ) { diff --git a/servers/slapd/back-meta/compare.c b/servers/slapd/back-meta/compare.c index 556984786c..cd6815bee7 100644 --- a/servers/slapd/back-meta/compare.c +++ b/servers/slapd/back-meta/compare.c @@ -83,7 +83,7 @@ meta_back_compare( Operation *op, SlapReply *rs ) /* * 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: @@ -98,7 +98,7 @@ meta_back_compare( Operation *op, SlapReply *rs ) * 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 ); @@ -109,7 +109,7 @@ meta_back_compare( Operation *op, SlapReply *rs ) * 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' ) { diff --git a/servers/slapd/back-meta/config.c b/servers/slapd/back-meta/config.c index 61434822cb..38a48ca88e 100644 --- a/servers/slapd/back-meta/config.c +++ b/servers/slapd/back-meta/config.c @@ -36,12 +36,15 @@ 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 ) { @@ -66,6 +69,10 @@ meta_back_new_target( ldap_back_map_init( &mt->mt_rwmap.rwm_at, &mapping ); + ldap_pvt_thread_mutex_init( &mt->mt_uri_mutex ); + + *mtp = mt; + return 0; } @@ -107,6 +114,8 @@ meta_back_db_config( struct berval dn; int rc; int c; + + metatarget_t *mt; switch ( argc ) { case 1: @@ -136,8 +145,8 @@ meta_back_db_config( ++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" @@ -154,19 +163,27 @@ meta_back_db_config( 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 ://[:port]/\" line\n", @@ -206,8 +223,8 @@ meta_back_db_config( * 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", @@ -219,12 +236,12 @@ meta_back_db_config( 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: @@ -246,9 +263,9 @@ meta_back_db_config( } } - 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 ); @@ -258,7 +275,7 @@ meta_back_db_config( * 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: of URI does not refer to current backend" " in \"uri ://[:port]/\" line\n", @@ -269,7 +286,7 @@ meta_back_db_config( /* * 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: of URI does not resolve to a backend" " in \"uri ://[:port]/\" line\n", @@ -317,7 +334,7 @@ meta_back_db_config( 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", @@ -326,12 +343,12 @@ meta_back_db_config( 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", @@ -341,7 +358,7 @@ meta_back_db_config( 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", @@ -352,7 +369,7 @@ meta_back_db_config( } } - 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 ) { @@ -423,7 +440,7 @@ meta_back_db_config( } 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 ) { @@ -505,7 +522,7 @@ meta_back_db_config( } 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 ) { @@ -564,7 +581,7 @@ meta_back_db_config( } 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: " @@ -601,7 +618,7 @@ meta_back_db_config( /* 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 ) { @@ -638,7 +655,7 @@ meta_back_db_config( } 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 ) { @@ -667,7 +684,7 @@ meta_back_db_config( } 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 ) { @@ -704,7 +721,7 @@ meta_back_db_config( } 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 ) { @@ -786,7 +803,7 @@ meta_back_db_config( } 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; @@ -870,7 +887,7 @@ meta_back_db_config( 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", @@ -895,7 +912,7 @@ meta_back_db_config( 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 ) { @@ -978,7 +995,7 @@ meta_back_db_config( * 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 ); @@ -999,7 +1016,7 @@ meta_back_db_config( 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 */ @@ -1013,8 +1030,8 @@ meta_back_db_config( 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 ) { @@ -1047,12 +1064,12 @@ meta_back_db_config( 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 ) { diff --git a/servers/slapd/back-meta/conn.c b/servers/slapd/back-meta/conn.c index a1ee87ccdf..59cd94962a 100644 --- a/servers/slapd/back-meta/conn.c +++ b/servers/slapd/back-meta/conn.c @@ -263,6 +263,9 @@ meta_back_init_one_conn( int version; dncookie dc; int isauthz = ( candidate == mc->mc_authz_target ); +#ifdef HAVE_TLS + int is_ldaps = 0; +#endif /* HAVE_TLS */ /* * Already init'ed @@ -276,7 +279,12 @@ meta_back_init_one_conn( /* * 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; } @@ -295,6 +303,7 @@ meta_back_init_one_conn( 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, @@ -303,7 +312,7 @@ meta_back_init_one_conn( #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 /* @@ -495,7 +504,7 @@ meta_back_retry( 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, @@ -505,16 +514,21 @@ meta_back_retry( 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 ); @@ -666,9 +680,9 @@ meta_back_get_candidate( * 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; @@ -915,7 +929,7 @@ retry_lock: } 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 @@ -1072,7 +1086,7 @@ retry_lock2:; */ ( void )meta_clear_unused_candidates( op, i ); - mt = &mi->mi_targets[ i ]; + mt = mi->mi_targets[ i ]; msc = &mc->mc_conns[ i ]; /* @@ -1124,7 +1138,7 @@ retry_lock2:; } 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 diff --git a/servers/slapd/back-meta/delete.c b/servers/slapd/back-meta/delete.c index d9461ac4e4..4d23793a83 100644 --- a/servers/slapd/back-meta/delete.c +++ b/servers/slapd/back-meta/delete.c @@ -53,7 +53,7 @@ meta_back_delete( Operation *op, SlapReply *rs ) /* * 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"; @@ -78,8 +78,8 @@ retry:; 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; } diff --git a/servers/slapd/back-meta/init.c b/servers/slapd/back-meta/init.c index a4962515d3..09f7007afc 100644 --- a/servers/slapd/back-meta/init.c +++ b/servers/slapd/back-meta/init.c @@ -104,6 +104,9 @@ meta_back_db_init( 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 ); @@ -125,15 +128,17 @@ meta_back_db_open( 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; } } } @@ -194,6 +199,7 @@ target_free( { 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 ); @@ -223,6 +229,8 @@ target_free( 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 @@ -251,7 +259,7 @@ meta_back_db_destroy( */ 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 ); diff --git a/servers/slapd/back-meta/modify.c b/servers/slapd/back-meta/modify.c index c17af5e928..2e11c5b696 100644 --- a/servers/slapd/back-meta/modify.c +++ b/servers/slapd/back-meta/modify.c @@ -59,7 +59,7 @@ meta_back_modify( Operation *op, SlapReply *rs ) /* * 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"; @@ -102,7 +102,7 @@ meta_back_modify( Operation *op, SlapReply *rs ) 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 ) ) { @@ -129,11 +129,11 @@ meta_back_modify( Operation *op, SlapReply *rs ) 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 ]; @@ -188,8 +188,8 @@ retry:; 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; } diff --git a/servers/slapd/back-meta/modrdn.c b/servers/slapd/back-meta/modrdn.c index a0f54f7b08..2c7d603b2b 100644 --- a/servers/slapd/back-meta/modrdn.c +++ b/servers/slapd/back-meta/modrdn.c @@ -76,7 +76,7 @@ meta_back_modrdn( Operation *op, SlapReply *rs ) */ /* needs LDAPv3 */ - switch ( mi->mi_targets[ candidate ].mt_version ) { + switch ( mi->mi_targets[ candidate ]->mt_version ) { case LDAP_VERSION3: break; @@ -97,7 +97,7 @@ meta_back_modrdn( Operation *op, SlapReply *rs ) /* * 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; @@ -109,7 +109,7 @@ meta_back_modrdn( Operation *op, SlapReply *rs ) /* * 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; @@ -134,8 +134,8 @@ retry:; 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; } diff --git a/servers/slapd/back-meta/search.c b/servers/slapd/back-meta/search.c index a2812a1d53..8e8699438d 100644 --- a/servers/slapd/back-meta/search.c +++ b/servers/slapd/back-meta/search.c @@ -73,7 +73,7 @@ meta_search_dobind_init( { 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 = ""; @@ -232,7 +232,7 @@ meta_back_search_start( 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; @@ -904,7 +904,7 @@ really_bad:; 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 ); @@ -1132,7 +1132,7 @@ really_bad:; * 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; @@ -1283,7 +1283,7 @@ meta_send_entry( /* * 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"; @@ -1327,7 +1327,7 @@ meta_send_entry( 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] */ ); @@ -1402,7 +1402,7 @@ meta_send_entry( 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 ); diff --git a/servers/slapd/back-meta/unbind.c b/servers/slapd/back-meta/unbind.c index 0b301a242c..7433c2613b 100644 --- a/servers/slapd/back-meta/unbind.c +++ b/servers/slapd/back-meta/unbind.c @@ -67,7 +67,7 @@ meta_back_conn_destroy( * 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; diff --git a/servers/slapd/back-monitor/database.c b/servers/slapd/back-monitor/database.c index 629248ec79..02644819b9 100644 --- a/servers/slapd/back-monitor/database.c +++ b/servers/slapd/back-monitor/database.c @@ -370,7 +370,7 @@ monitor_subsys_database_init( 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; diff --git a/servers/slapd/referral.c b/servers/slapd/referral.c index 064854c721..966651ef2a 100644 --- a/servers/slapd/referral.c +++ b/servers/slapd/referral.c @@ -140,7 +140,7 @@ int validate_global_referral( const char *url ) 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: @@ -219,7 +219,7 @@ BerVarray referral_rewrite( 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; -- 2.39.5