]> git.sur5r.net Git - openldap/blobdiff - servers/slapd/back-ldap/search.c
provisions for configuring a desired chaining policy via the chaining behavior control
[openldap] / servers / slapd / back-ldap / search.c
index e60d6bfc5488eabab8e3ec359d38b6e3c251074e..8c610a57980b1c18b1006a4c2a060a51f58a5f17 100644 (file)
@@ -2,7 +2,7 @@
 /* $OpenLDAP$ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
- * Copyright 1999-2004 The OpenLDAP Foundation.
+ * Copyright 1999-2005 The OpenLDAP Foundation.
  * Portions Copyright 1999-2003 Howard Chu.
  * Portions Copyright 2000-2003 Pierangelo Masarati.
  * All rights reserved.
@@ -60,17 +60,17 @@ ldap_back_search(
        int             do_retry = 1;
        LDAPControl     **ctrls = NULL;
 
-       lc = ldap_back_getconn( op, rs );
+       lc = ldap_back_getconn( op, rs, LDAP_BACK_SENDERR );
        if ( !lc ) {
-               return -1;
+               return rs->sr_err;
        }
 
        /*
         * FIXME: in case of values return filter, we might want
         * to map attrs and maybe rewrite value
         */
-       if ( !ldap_back_dobind( lc, op, rs ) ) {
-               return -1;
+       if ( !ldap_back_dobind( lc, op, rs, LDAP_BACK_SENDERR ) ) {
+               return rs->sr_err;
        }
 
        /* should we check return values? */
@@ -105,13 +105,11 @@ ldap_back_search(
        }
 
        ctrls = op->o_ctrls;
-#ifdef LDAP_BACK_PROXY_AUTHZ
        rc = ldap_back_proxy_authz_ctrl( lc, op, rs, &ctrls );
        if ( rc != LDAP_SUCCESS ) {
                dontfreetext = 1;
                goto finish;
        }
-#endif /* LDAP_BACK_PROXY_AUTHZ */
        
 retry:
        rs->sr_err = ldap_search_ext( lc->lc_ld, op->o_req_ndn.bv_val,
@@ -122,7 +120,7 @@ retry:
 
        if ( rs->sr_err != LDAP_SUCCESS ) {
 fail:;
-               rc = ldap_back_op_result( lc, op, rs, msgid, 0 );
+               rc = ldap_back_op_result( lc, op, rs, msgid, LDAP_BACK_SENDERR );
                if ( freeconn ) {
                        ldap_back_freeconn( op, lc );
                        lc = NULL;
@@ -236,13 +234,34 @@ fail:;
                        }
 
                } else {
+                       char            **references = NULL;
+
                        rc = ldap_parse_result( lc->lc_ld, res, &rs->sr_err,
                                        &match.bv_val, (char **)&rs->sr_text,
-                                       NULL, &rs->sr_ctrls, 1 );
-                       if (rc != LDAP_SUCCESS ) {
+                                       &references, &rs->sr_ctrls, 1 );
+                       if ( rc != LDAP_SUCCESS ) {
                                rs->sr_err = rc;
                        }
                        rs->sr_err = slap_map_api2result( rs );
+
+                       if ( references ) {
+                               int     cnt;
+
+                               for ( cnt = 0; references[ cnt ]; cnt++ )
+                                       /* NO OP */ ;
+                               
+                               rs->sr_ref = ch_calloc( cnt + 1, sizeof( struct berval ) );
+
+                               for ( cnt = 0; references[ cnt ]; cnt++ ) {
+                                       ber_str2bv( references[ cnt ], 0, 0, &rs->sr_ref[ cnt ] );
+                               }
+
+                               /* cleanup */
+                               if ( references ) {
+                                       ldap_value_free( references );
+                               }
+                       }
+
                        rc = 0;
                        break;
                }
@@ -251,7 +270,7 @@ fail:;
        if ( rc == -1 ) {
                if ( do_retry ) {
                        do_retry = 0;
-                       if ( ldap_back_retry( lc, op, rs ) ) {
+                       if ( ldap_back_retry( lc, op, rs, LDAP_BACK_SENDERR ) ) {
                                goto retry;
                        }
                }
@@ -274,9 +293,7 @@ fail:;
 finish:;
        send_ldap_result( op, rs );
 
-#ifdef LDAP_BACK_PROXY_AUTHZ
        (void)ldap_back_proxy_authz_ctrl_free( op, &ctrls );
-#endif /* LDAP_BACK_PROXY_AUTHZ */
 
        if ( rs->sr_ctrls ) {
                ldap_controls_free( rs->sr_ctrls );
@@ -287,12 +304,19 @@ finish:;
                rs->sr_matched = NULL;
                LDAP_FREE( match.bv_val );
        }
+
        if ( rs->sr_text ) {
                if ( !dontfreetext ) {
                        LDAP_FREE( (char *)rs->sr_text );
                }
                rs->sr_text = NULL;
        }
+
+       if ( rs->sr_ref ) {
+               ber_bvarray_free( rs->sr_ref );
+               rs->sr_ref = NULL;
+       }
+
        if ( attrs ) {
                ch_free( attrs );
        }
@@ -462,7 +486,7 @@ ldap_build_entry(
                                        attr->a_desc->ad_type->sat_syntax,
                                        attr->a_desc->ad_type->sat_equality,
                                        &attr->a_vals[i], &attr->a_nvals[i],
-                                       NULL /* op->o_tmpmemctx */ );
+                                       NULL );
 
                                if ( rc != LDAP_SUCCESS ) {
                                        BER_BVZERO( &attr->a_nvals[i] );
@@ -498,34 +522,29 @@ ldap_back_entry_get(
 {
        struct ldapconn *lc;
        int             rc = 1,
-                       is_oc;
+                       do_not_cache;
        struct berval   bdn;
        LDAPMessage     *result = NULL,
                        *e = NULL;
        char            *gattr[3];
        char            *filter = NULL;
-       Connection      *oconn;
        SlapReply       rs;
        int             do_retry = 1;
+       LDAPControl     **ctrls = NULL;
 
        /* Tell getconn this is a privileged op */
-       is_oc = op->o_do_not_cache;
+       do_not_cache = op->o_do_not_cache;
        op->o_do_not_cache = 1;
-       lc = ldap_back_getconn( op, &rs );
-       oconn = op->o_conn;
-       op->o_conn = NULL;
-       if ( !lc || !ldap_back_dobind( lc, op, &rs ) ) {
-               op->o_do_not_cache = is_oc;
-               op->o_conn = oconn;
-               return 1;
+       lc = ldap_back_getconn( op, &rs, LDAP_BACK_DONTSEND );
+       if ( !lc || !ldap_back_dobind( lc, op, &rs, LDAP_BACK_DONTSEND ) ) {
+               op->o_do_not_cache = do_not_cache;
+               return rs.sr_err;
        }
-       op->o_do_not_cache = is_oc;
-       op->o_conn = oconn;
+       op->o_do_not_cache = do_not_cache;
 
        if ( at ) {
-               is_oc = ( strcasecmp( "objectclass", at->ad_cname.bv_val ) == 0 );
-               if ( oc && !is_oc ) {
-                       gattr[0] = "objectclass";
+               if ( oc && at != slap_schema.si_ad_objectClass ) {
+                       gattr[0] = slap_schema.si_ad_objectClass->ad_cname.bv_val;
                        gattr[1] = at->ad_cname.bv_val;
                        gattr[2] = NULL;
 
@@ -546,14 +565,20 @@ ldap_back_entry_get(
                *ptr++ = '\0';
        }
 
+       ctrls = op->o_ctrls;
+       rc = ldap_back_proxy_authz_ctrl( lc, op, &rs, &ctrls );
+       if ( rc != LDAP_SUCCESS ) {
+               goto cleanup;
+       }
+       
 retry:
        rc = ldap_search_ext_s( lc->lc_ld, ndn->bv_val, LDAP_SCOPE_BASE, filter,
-                               at ? gattr : NULL, 0, NULL, NULL, LDAP_NO_LIMIT,
-                               LDAP_NO_LIMIT, &result );
+                               at ? gattr : NULL, 0, ctrls, NULL,
+                               LDAP_NO_LIMIT, LDAP_NO_LIMIT, &result );
        if ( rc != LDAP_SUCCESS ) {
                if ( rc == LDAP_SERVER_DOWN && do_retry ) {
                        do_retry = 0;
-                       if ( ldap_back_retry( lc, op, &rs ) ) {
+                       if ( ldap_back_retry( lc, op, &rs, LDAP_BACK_DONTSEND ) ) {
                                goto retry;
                        }
                }
@@ -575,6 +600,8 @@ retry:
        }
 
 cleanup:
+       (void)ldap_back_proxy_authz_ctrl_free( op, &ctrls );
+
        if ( result ) {
                ldap_msgfree( result );
        }