]> git.sur5r.net Git - openldap/blobdiff - servers/slapd/back-ldap/search.c
Cleanup up LDAP_CLIENT_UPDATE code... including some bug fixing.
[openldap] / servers / slapd / back-ldap / search.c
index 45c5bd43df769e5a8e8009198d42e093eeabe27e..47f211c5da48b3c6908612d6ef1aa4d259bb98d5 100644 (file)
@@ -48,7 +48,7 @@
 #undef ldap_debug      /* silence a warning in ldap-int.h */
 #include "../../../libraries/libldap/ldap-int.h"
 
-static void ldap_send_entry( Backend *be, Operation *op, struct ldapconn *lc,
+static int ldap_send_entry( Backend *be, Operation *op, struct ldapconn *lc,
                              LDAPMessage *e, AttributeName *attrs, int attrsonly );
 
 int
@@ -82,12 +82,23 @@ ldap_back_search(
 #endif /* ENABLE_REWRITE */
        struct slap_limits_set *limit = NULL;
        int isroot = 0;
+       BerVarray v2refs = NULL;
 
        lc = ldap_back_getconn(li, conn, op);
        if ( !lc ) {
                return( -1 );
        }
 
+       /*
+        * controls are set in ldap_back_dobind()
+        * 
+        * FIXME: in case of values return filter, we might want
+        * to map attrs and maybe rewrite value
+        */
+       if ( !ldap_back_dobind( lc, op ) ) {
+               return( -1 );
+       }
+
        /* if not root, get appropriate limits */
        if ( be_isroot( be, &op->o_ndn ) ) {
                isroot = 1;
@@ -104,8 +115,8 @@ ldap_back_search(
                        
                /* positive hard limit means abort */
                } else if ( limit->lms_t_hard > 0 ) {
-                       send_search_result( conn, op, LDAP_UNWILLING_TO_PERFORM,
-                                       NULL, NULL, NULL, NULL, 0 );
+                       send_ldap_result( conn, op, LDAP_UNWILLING_TO_PERFORM,
+                                       NULL, NULL, NULL, NULL );
                        rc = 0;
                        goto finish;
                }
@@ -122,8 +133,8 @@ ldap_back_search(
                        
                /* positive hard limit means abort */
                } else if ( limit->lms_s_hard > 0 ) {
-                       send_search_result( conn, op, LDAP_UNWILLING_TO_PERFORM,
-                                       NULL, NULL, NULL, NULL, 0 );
+                       send_ldap_result( conn, op, LDAP_UNWILLING_TO_PERFORM,
+                                       NULL, NULL, NULL, NULL );
                        rc = 0;
                        goto finish;
                }
@@ -131,16 +142,13 @@ ldap_back_search(
                /* negative hard limit means no limit */
        }
 
+       /* should we check return values? */
        if (deref != -1)
                ldap_set_option( lc->ld, LDAP_OPT_DEREF, (void *)&deref);
        if (tlimit != -1)
                ldap_set_option( lc->ld, LDAP_OPT_TIMELIMIT, (void *)&tlimit);
        if (slimit != -1)
                ldap_set_option( lc->ld, LDAP_OPT_SIZELIMIT, (void *)&slimit);
-       
-       if ( !ldap_back_dobind( lc, op ) ) {
-               return( -1 );
-       }
 
        /*
         * Rewrite the search base, if required
@@ -266,15 +274,61 @@ fail:;
                        rc = 0;
                        goto finish;
                }
+
                if (rc == 0) {
                        tv.tv_sec = 0;
                        tv.tv_usec = 100000;
                        ldap_pvt_thread_yield();
+
                } else if (rc == LDAP_RES_SEARCH_ENTRY) {
                        e = ldap_first_entry(lc->ld,res);
-                       ldap_send_entry(be, op, lc, e, attrs, attrsonly);
-                       count++;
+                       if ( ldap_send_entry(be, op, lc, e, attrs, attrsonly) 
+                                       == LDAP_SUCCESS ) {
+                               count++;
+                       }
                        ldap_msgfree(res);
+
+               } else if ( rc == LDAP_RES_SEARCH_REFERENCE ) {
+                       char            **references = NULL;
+                       LDAPControl     **ctrls = NULL;
+                       BerVarray       refs;
+                       int             cnt;
+
+                       rc = ldap_parse_reference( lc->ld, res,
+                                       &references, &ctrls, 1 );
+
+                       if ( rc != LDAP_SUCCESS ) {
+                               continue;
+                       }
+
+                       if ( references == NULL ) {
+                               continue;
+                       }
+
+                       for ( cnt = 0; references[ cnt ]; cnt++ )
+                               /* NO OP */ ;
+                               
+                       refs = ch_calloc( cnt + 1, sizeof( struct berval ) );
+
+                       for ( cnt = 0; references[ cnt ]; cnt++ ) {
+                               refs[ cnt ].bv_val = references[ cnt ];
+                               refs[ cnt ].bv_len = strlen( references[ cnt ] );
+                       }
+
+                       /* ignore return value by now */
+                       ( void )send_search_reference( be, conn, op, 
+                                       NULL, refs, ctrls, &v2refs );
+
+                       /* cleanup */
+                       if ( references ) {
+                               ldap_value_free( references );
+                               ch_free( refs );
+                       }
+
+                       if ( ctrls ) {
+                               ldap_controls_free( ctrls );
+                       }
+
                } else {
                        sres = ldap_result2error(lc->ld, res, 1);
                        sres = ldap_back_map_result(sres);
@@ -320,12 +374,18 @@ fail:;
                }
        }
 
+       if ( v2refs ) {
+               sres = LDAP_REFERRAL;
+       }
        send_search_result( conn, op, sres,
-               mmatch, err, NULL, NULL, count );
+               mmatch, err, v2refs, NULL, count );
 
 #else /* !ENABLE_REWRITE */
+       if ( v2refs ) {
+               sres = LDAP_REFERRAL;
+       }
        send_search_result( conn, op, sres,
-               match, err, NULL, NULL, count );
+               match, err, v2refs, NULL, count );
 #endif /* !ENABLE_REWRITE */
 
 finish:;
@@ -353,7 +413,7 @@ finish:;
        return rc;
 }
 
-static void
+static int
 ldap_send_entry(
        Backend *be,
        Operation *op,
@@ -373,7 +433,7 @@ ldap_send_entry(
        const char *text;
 
        if ( ber_scanf( &ber, "{m{", &bdn ) == LBER_ERROR ) {
-               return;
+               return LDAP_DECODING_ERROR;
        }
 #ifdef ENABLE_REWRITE
 
@@ -400,7 +460,7 @@ ldap_send_entry(
                
        case REWRITE_REGEXEC_ERR:
        case REWRITE_REGEXEC_UNWILLING:
-               return;
+               return LDAP_OTHER;
        }
 #else /* !ENABLE_REWRITE */
        ldap_back_dn_massage( li, &bdn, &ent.e_name, 0, 0 );
@@ -414,7 +474,7 @@ ldap_send_entry(
         * FIXME: should we log anything, or delegate to dnNormalize2?
         */
        if ( dnNormalize2( NULL, &ent.e_name, &ent.e_nname ) != LDAP_SUCCESS ) {
-               return;
+               return LDAP_INVALID_DN_SYNTAX;
        }
        
        ent.e_id = 0;
@@ -454,12 +514,18 @@ ldap_send_entry(
                        continue;
                }
                
-               if (ber_scanf( &ber, "[W]", &attr->a_vals ) == LBER_ERROR ) {
+               if ( ber_scanf( &ber, "[W]", &attr->a_vals ) == LBER_ERROR
+                               || attr->a_vals == NULL ) {
+                       /*
+                        * Note: attr->a_vals can be null when using
+                        * values result filter
+                        */
                        attr->a_vals = &dummy;
+
                } else if ( attr->a_desc == slap_schema.si_ad_objectClass
                                || attr->a_desc == slap_schema.si_ad_structuralObjectClass ) {
                        int i, last;
-                       assert( attr->a_vals );
+
                        for ( last = 0; attr->a_vals[last].bv_val; last++ ) ;
                        for ( i = 0, bv = attr->a_vals; bv->bv_val; bv++, i++ ) {
                                ldap_back_map(&li->oc_map, bv, &mapped, 1);
@@ -496,7 +562,6 @@ ldap_send_entry(
                } else if ( strcmp( attr->a_desc->ad_type->sat_syntax->ssyn_oid,
                                        SLAPD_DN_SYNTAX ) == 0 ) {
                        int i;
-                       assert( attr->a_vals );
                        for ( i = 0, bv = attr->a_vals; bv->bv_val; bv++, i++ ) {
                                struct berval newval;
                                
@@ -560,4 +625,6 @@ ldap_send_entry(
                free( ent.e_dn );
        if ( ent.e_ndn )
                free( ent.e_ndn );
+
+       return LDAP_SUCCESS;
 }