X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;ds=sidebyside;f=servers%2Fslapd%2Fback-meta%2Fconn.c;h=f13352e7bbd654911bb9dd80a4b7683b52b6ef21;hb=5094d6abda4a30b1cb42b1242260d2748de6159a;hp=cf440dec0890aff16c67547f14c313660204d152;hpb=74fa239a201cd2d785fe34bdbaf6804161bdb231;p=openldap diff --git a/servers/slapd/back-meta/conn.c b/servers/slapd/back-meta/conn.c index cf440dec08..f13352e7bb 100644 --- a/servers/slapd/back-meta/conn.c +++ b/servers/slapd/back-meta/conn.c @@ -1,5 +1,5 @@ /* - * Copyright 1998-2001 The OpenLDAP Foundation, All Rights Reserved. + * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved. * COPYING RESTRICTIONS APPLY, see COPYRIGHT file * * Copyright 2001, Pierangelo Masarati, All rights reserved. @@ -170,7 +170,6 @@ static struct metaconn * metaconn_alloc( int ntargets ) { struct metaconn *lc; - int i; assert( ntargets > 0 ); @@ -182,24 +181,14 @@ metaconn_alloc( int ntargets ) /* * make it a null-terminated array ... */ - lc->conns = ch_calloc( sizeof( struct metasingleconn * ), ntargets+1 ); + lc->conns = ch_calloc( sizeof( struct metasingleconn ), ntargets+1 ); if ( lc->conns == NULL ) { free( lc ); return NULL; } + lc->conns[ ntargets ].candidate = META_LAST_CONN; - for ( i = 0; i < ntargets; i++ ) { - lc->conns[ i ] = - ch_calloc( sizeof( struct metasingleconn ), 1 ); - if ( lc->conns[ i ] == NULL ) { - charray_free( ( char ** )lc->conns ); - free( lc->conns ); - free( lc ); - return NULL; - } - } - - lc->bound_target = -1; + lc->bound_target = META_BOUND_NONE; return lc; } @@ -219,12 +208,7 @@ metaconn_free( } if ( lc->conns ) { - int i; - - for ( i = 0; lc->conns[ i ] != NULL; ++i ) { - free( lc->conns[ i ] ); - } - charray_free( ( char ** )lc->conns ); + ch_free( lc->conns ); } free( lc ); @@ -237,14 +221,14 @@ metaconn_free( */ static int init_one_conn( - Connection *conn, - Operation *op, - struct metatarget *lt, - int vers, - struct metasingleconn *lsc + Operation *op, + SlapReply *rs, + struct metatarget *lt, + struct metasingleconn *lsc ) { - int err; + int vers; + dncookie dc; /* * Already init'ed @@ -256,59 +240,46 @@ init_one_conn( /* * Attempts to initialize the connection to the target ds */ - err = ldap_initialize( &lsc->ld, lt->uri ); - - /* - * In case of failure, the error is mapped back from client - * to server error code - */ - if ( err != LDAP_SUCCESS ) { - return ldap_back_map_result( err ); + rs->sr_err = ldap_initialize( &lsc->ld, lt->uri ); + if ( rs->sr_err != LDAP_SUCCESS ) { + return ldap_back_map_result( rs ); } - + /* * Set LDAP version. This will always succeed: If the client * bound with a particular version, then so can we. */ + vers = op->o_conn->c_protocol; ldap_set_option( lsc->ld, LDAP_OPT_PROTOCOL_VERSION, &vers ); + /* FIXME: configurable? */ + ldap_set_option(lsc->ld, LDAP_OPT_REFERRALS, LDAP_OPT_ON); /* * Sets a cookie for the rewrite session */ - ( void )rewrite_session_init( lt->rwinfo, conn ); + ( void )rewrite_session_init( lt->rwmap.rwm_rw, op->o_conn ); /* * If the connection dn is not null, an attempt to rewrite it is made */ - if ( conn->c_cdn != NULL && conn->c_cdn[ 0 ] != '\0' ) { + if ( op->o_conn->c_dn.bv_len != 0 ) { + dc.rwmap = <->rwmap; + dc.conn = op->o_conn; + dc.rs = rs; + dc.ctx = "bindDn"; + /* * Rewrite the bind dn if needed */ - lsc->bound_dn = NULL; - switch ( rewrite_session( lt->rwinfo, "bindDn", - conn->c_cdn, conn, - &lsc->bound_dn ) ) { - case REWRITE_REGEXEC_OK: - if ( lsc->bound_dn == NULL ) { - lsc->bound_dn = ch_strdup( conn->c_cdn ); - } - Debug( LDAP_DEBUG_ARGS, - "rw> bindDn: \"%s\" -> \"%s\"\n%s", - conn->c_cdn, lsc->bound_dn, "" ); - break; - - case REWRITE_REGEXEC_UNWILLING: - send_ldap_result( conn, op, - LDAP_UNWILLING_TO_PERFORM, - NULL, "Unwilling to perform", - NULL, NULL ); - /* continues to the next case */ - - case REWRITE_REGEXEC_ERR: - return LDAP_OPERATIONS_ERROR; + if ( ldap_back_dn_massage( &dc, &op->o_conn->c_dn, &lsc->bound_dn) ) { + send_ldap_result( op, rs ); + return rs->sr_err; } + + assert( lsc->bound_dn.bv_val ); + } else { - lsc->bound_dn = NULL; + ber_str2bv( "", 0, 1, &lsc->bound_dn ); } lsc->bound = META_UNBOUND; @@ -334,20 +305,19 @@ init_one_conn( */ struct metaconn * meta_back_getconn( - struct metainfo *li, - Connection *conn, - Operation *op, - int op_type, - const char *ndn, - int *candidate - ) + Operation *op, + SlapReply *rs, + int op_type, + struct berval *ndn, + int *candidate ) { + struct metainfo *li = ( struct metainfo * )op->o_bd->be_private; struct metaconn *lc, lc_curr; - int vers, cached = -1, i = -1, err = LDAP_SUCCESS; + int cached = -1, i = -1, err = LDAP_SUCCESS; int new_conn = 0; /* Searches for a metaconn in the avl tree */ - lc_curr.conn = conn; + lc_curr.conn = op->o_conn; ldap_pvt_thread_mutex_lock( &li->conn_mutex ); lc = (struct metaconn *)avl_find( li->conntree, (caddr_t)&lc_curr, meta_back_conn_cmp ); @@ -356,12 +326,10 @@ meta_back_getconn( /* Looks like we didn't get a bind. Open a new session... */ if ( !lc ) { lc = metaconn_alloc( li->ntargets ); - lc->conn = conn; + lc->conn = op->o_conn; new_conn = 1; } - vers = conn->c_protocol; - /* * looks in cache, if any */ @@ -387,17 +355,20 @@ meta_back_getconn( metaconn_free( lc ); } - send_ldap_result( conn, op, LDAP_NO_SUCH_OBJECT, - NULL, "", NULL, NULL ); - + rs->sr_err = LDAP_NO_SUCH_OBJECT; return NULL; } - +#ifdef NEW_LOGGING + LDAP_LOG( BACK_META, INFO, + "meta_back_getconn: got target %d for ndn=\"%s\" from cache\n", + i, ndn->bv_val, 0 ); +#else /* !NEW_LOGGING */ Debug( LDAP_DEBUG_CACHE, "==>meta_back_getconn: got target %d for ndn=\"%s\" from cache\n%s", - i, ndn, "" ); - + i, ndn->bv_val, "" ); +#endif /* !NEW_LOGGING */ + /* * Clear all other candidates */ @@ -405,10 +376,11 @@ meta_back_getconn( /* * The target is activated; if needed, it is - * also init'd + * also init'd. In case of error, init_one_conn + * sends the appropriate result. */ - err = init_one_conn( conn, op, li->targets[ i ], - vers, lc->conns[ i ] ); + err = init_one_conn( op, rs, li->targets[ i ], + &lc->conns[ i ] ); if ( err != LDAP_SUCCESS ) { /* @@ -416,13 +388,10 @@ meta_back_getconn( * be init'd, should the other ones * be tried? */ - ( void )meta_clear_one_candidate( lc->conns[ i ], 1 ); + ( void )meta_clear_one_candidate( &lc->conns[ i ], 1 ); if ( new_conn ) { metaconn_free( lc ); } - - send_ldap_result( conn, op, LDAP_OPERATIONS_ERROR, NULL, "internal server error", NULL, NULL ); - return NULL; } @@ -430,23 +399,46 @@ meta_back_getconn( *candidate = i; } + /* + * require all connections ... + */ + } else if (op_type == META_OP_REQUIRE_ALL) { + for ( i = 0; i < li->ntargets; i++ ) { + + /* + * The target is activated; if needed, it is + * also init'd + */ + int lerr = init_one_conn( op, rs, li->targets[ i ], + &lc->conns[ i ] ); + if ( lerr != LDAP_SUCCESS ) { + + /* + * FIXME: in case one target cannot + * be init'd, should the other ones + * be tried? + */ + ( void )meta_clear_one_candidate( &lc->conns[ i ], 1 ); + err = lerr; + continue; + } + } + /* * if no unique candidate ... */ } else { - int ndnlen = strlen( ndn ); for ( i = 0; i < li->ntargets; i++ ) { if ( i == cached - || meta_back_is_candidate( li->targets[ i ]->suffix, - ndn, ndnlen ) ) { + || meta_back_is_candidate( &li->targets[ i ]->suffix, ndn ) ) { /* * The target is activated; if needed, it is * also init'd */ - int lerr = init_one_conn( conn, op, + int lerr = init_one_conn( op, rs, li->targets[ i ], - vers, lc->conns[ i ] ); + &lc->conns[ i ] ); if ( lerr != LDAP_SUCCESS ) { /* @@ -454,7 +446,7 @@ meta_back_getconn( * be init'd, should the other ones * be tried? */ - ( void )meta_clear_one_candidate( lc->conns[ i ], 1 ); + ( void )meta_clear_one_candidate( &lc->conns[ i ], 1 ); err = lerr; continue; } @@ -462,6 +454,10 @@ meta_back_getconn( } } + /* clear out init_one_conn non-fatal errors */ + rs->sr_err = LDAP_SUCCESS; + rs->sr_text = NULL; + if ( new_conn ) { /* @@ -477,23 +473,33 @@ meta_back_getconn( ldap_pvt_thread_mutex_unlock( &li->conn_mutex ); +#ifdef NEW_LOGGING + LDAP_LOG( BACK_META, INFO, + "meta_back_getconn: conn %ld inserted\n", lc->conn->c_connid, 0, 0); +#else /* !NEW_LOGGING */ Debug( LDAP_DEBUG_TRACE, "=>meta_back_getconn: conn %ld inserted\n%s%s", lc->conn->c_connid, "", "" ); +#endif /* !NEW_LOGGING */ /* * Err could be -1 in case a duplicate metaconn is inserted */ if ( err != 0 ) { - send_ldap_result( conn, op, LDAP_OPERATIONS_ERROR, - NULL, "internal server error", NULL, NULL ); + rs->sr_err = LDAP_OTHER; + rs->sr_text = "Internal server error"; metaconn_free( lc ); return NULL; } } else { +#ifdef NEW_LOGGING + LDAP_LOG( BACK_META, INFO, + "meta_back_getconn: conn %ld fetched\n", lc->conn->c_connid, 0, 0 ); +#else /* !NEW_LOGGING */ Debug( LDAP_DEBUG_TRACE, "=>meta_back_getconn: conn %ld fetched\n%s%s", lc->conn->c_connid, "", "" ); +#endif /* !NEW_LOGGING */ } return lc;