]> git.sur5r.net Git - openldap/commitdiff
add URI list resorting feature (ITS#4524)
authorPierangelo Masarati <ando@openldap.org>
Sat, 6 May 2006 16:15:25 +0000 (16:15 +0000)
committerPierangelo Masarati <ando@openldap.org>
Sat, 6 May 2006 16:15:25 +0000 (16:15 +0000)
28 files changed:
include/ldap.h
include/ldap_pvt.h
libraries/libldap/ldap-int.h
libraries/libldap/open.c
libraries/libldap/options.c
libraries/libldap/request.c
libraries/libldap/url.c
servers/slapd/back-ldap/back-ldap.h
servers/slapd/back-ldap/bind.c
servers/slapd/back-ldap/chain.c
servers/slapd/back-ldap/config.c
servers/slapd/back-ldap/init.c
servers/slapd/back-ldap/proto-ldap.h
servers/slapd/back-meta/add.c
servers/slapd/back-meta/back-meta.h
servers/slapd/back-meta/bind.c
servers/slapd/back-meta/candidates.c
servers/slapd/back-meta/compare.c
servers/slapd/back-meta/config.c
servers/slapd/back-meta/conn.c
servers/slapd/back-meta/delete.c
servers/slapd/back-meta/init.c
servers/slapd/back-meta/modify.c
servers/slapd/back-meta/modrdn.c
servers/slapd/back-meta/search.c
servers/slapd/back-meta/unbind.c
servers/slapd/back-monitor/database.c
servers/slapd/referral.c

index c9d9d574de8248163ecdcebd0a18b44e4a327524..c567d6adcc0389b41f205d4b6d12286f1bf4dc33 100644 (file)
@@ -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:
  */
index 7463c9ea273e6b3d0c74c470a79812c5a287837b..89fe20c6f0e1e434e075bc1a2ea80b15a2c2fdea 100644 (file)
@@ -41,10 +41,29 @@ ldap_pvt_url_scheme_port LDAP_P((
 
 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((
index 99d7331122515804692c2d55de39e673749b1b39..9863b32b60c49a32cd054749ecec886a2012b061 100644 (file)
@@ -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
  */
index d1eaf04b2ac6dd8b4696792ad2e8bb3cfe11c718..e01c5ea28e4781d2dcb97b4731e9789a105852b3 100644 (file)
 
 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;
index cfc4711eb10a51b407efb9be394c54c7e931bf17..cca205a0d97b11f52dfeebc73b683fd71602b199 100644 (file)
@@ -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;
+}
index 5786816fd3fc79cf13ae0a2467eae13be21f7ef3..0847544b65b9ebe540ef271e422bc69749728689 100644 (file)
@@ -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
index 4c27ed33f23c3dcdd40f701a2fa5d9db3c709c52..e35be8f9f0e4fd42097bbfc061d111028cc916fc 100644 (file)
@@ -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
index 3fb58ba581184bbee1de890951388d1762c49cb5..49017d2ed20fb6816dee30883eee03ea4fb40341 100644 (file)
@@ -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;
 
index 1a13895369417663e7844949fd1d28910c7835aa..2b0d39bd2557912e64a3553025987cc3c4ee5e91 100644 (file)
 
 #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;
index 6c041620757a5bd803cda79a3ee8377fff2ef9a6..ca6afdd2d6f9797f194031158da891d7594eb6a9 100644 (file)
@@ -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;
index c0123fe8ebc20e915492f5a9b614d5c6b521ba42..2df70bcfa91a795f4ef15786367754e9fddf8b83 100644 (file)
@@ -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;
 
index 77a10e78c8984185d400f530de9bf05128b48e62..765f201c21e1a0f8ce97667b23a0297dbb37570b 100644 (file)
@@ -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 );
index 153a25978a78214059d44bcea86cbc9a257cf43b..05d68832549e6ff20bc9cbae843202be0340bb5d 100644 (file)
@@ -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
 
index 2b089583742fc88de2ad7b87d6acd7c4e9588099..02a0093d5c9d65ec4a329ba58c1626e3076498f5 100644 (file)
@@ -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;
                }
index fe5766cbb9b71ba8b8b3a88b3d263a9aeecaae39..0516f619f3ba3d27546664dd73d574f80b4f159d 100644 (file)
@@ -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
 
index 78ffc28ef60ecc226429be497cb4c7014be26328..fd0539d7ad1b01fc682ffe34158bf9891afecc54 100644 (file)
 #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 ...
  */
index 794d1b3a471a80289ee7da64b0f055482d216210..27d3c2eaa16f4a6b0b5f280df29ce98ff92bad6b 100644 (file)
@@ -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 ) {
index 556984786c5b816ee10b31135be1b080f861aa06..cd6815bee7e3e5418fc2d54278f8bed1918f3d60 100644 (file)
@@ -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' ) {
index 61434822cbfb93d33fd371e9bd742b69dc6d93f5..38a48ca88e08dde7b9c5328abeb855e3900248ed 100644 (file)
 
 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 <protocol>://<server>[:port]/<naming context>\" 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: <naming context> of URI does not refer to current backend"
        " in \"uri <protocol>://<server>[:port]/<naming context>\" 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: <naming context> of URI does not resolve to a backend"
        " in \"uri <protocol>://<server>[:port]/<naming context>\" 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 ) {
index a1ee87ccdf097863f33f359a1ea99aa3f4db4287..59cd94962a213af5f38187e592737e69d3a116f6 100644 (file)
@@ -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 
index d9461ac4e4d16aea618571e337c77235e5e42b2b..4d23793a8378a7d98df17b5ef20d05ef9f4f5106 100644 (file)
@@ -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;
                }
index a4962515d32293af52dce399cfa4bcb03b84bde4..09f7007afc493f9a7a57fe351db58ae2205d21fd 100644 (file)
@@ -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 );
index c17af5e928c675583d8805229255a9a499371025..2e11c5b696663bf169326f52606fc857c183974f 100644 (file)
@@ -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;
                }
index a0f54f7b0883fc04f65fee940a58e5884791a2bb..2c7d603b2bb4717afdfff4acad681f92de5c81a5 100644 (file)
@@ -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;
                }
index a2812a1d535b0dedf04f0116f2de0123648ad942..8e8699438de0e0731bc51333b92d3341edc7a852 100644 (file)
@@ -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 );
index 0b301a242c5b6994a35869193793fdfaffa2d43c..7433c2613bc36d16cfdc59f833cc097301c9fb66 100644 (file)
@@ -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;
index 629248ec79698cca959f9ace7d5fde6b838f51b1..02644819b9e459dde629a846d8ebdd32b14981f9 100644 (file)
@@ -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;
index 064854c721911b4b3d08af7e58fff6270097780f..966651ef2ab59f22f42de3f7a703f22d728f9323 100644 (file)
@@ -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;