]> git.sur5r.net Git - openldap/blobdiff - libraries/libldap/request.c
Fix off by one bug
[openldap] / libraries / libldap / request.c
index 5b6622365d7f759d79203bfdbfb353bb906355fa..6a707ec466ac947973f351eb8a9d546af82e34a0 100644 (file)
@@ -49,6 +49,7 @@ static BerElement *
 re_encode_request( LDAP *ld,
        BerElement *origber,
        ber_int_t msgid,
+       int sref,
        LDAPURLDesc *srv,
        int *type );
 
@@ -617,8 +618,11 @@ ldap_chase_v3referrals( LDAP *ld, LDAPRequest *lr, char **refs, int sref, char *
        }
 
        /* find original request */
-       for ( origreq = lr; origreq->lr_parent != NULL; origreq = origreq->lr_parent ) {
-               ;
+       for ( origreq = lr;
+               origreq->lr_parent != NULL;
+               origreq = origreq->lr_parent )
+       {
+               /* empty */ ;
        }
 
        refarray = refs;
@@ -626,7 +630,7 @@ ldap_chase_v3referrals( LDAP *ld, LDAPRequest *lr, char **refs, int sref, char *
        /* parse out & follow referrals */
        for( i=0; refarray[i] != NULL; i++) {
                /* Parse the referral URL */
-               if (( rc = ldap_url_parse( refarray[i], &srv)) != LDAP_SUCCESS) {
+               if (( rc = ldap_url_parse_ext( refarray[i], &srv)) != LDAP_SUCCESS) {
                        ld->ld_errno = rc;
                        rc = -1;
                        goto done;
@@ -655,26 +659,35 @@ ldap_chase_v3referrals( LDAP *ld, LDAPRequest *lr, char **refs, int sref, char *
                                 * if two search references come in one behind the other
                                 * for the same server with different contexts.
                                 */
-                               Debug( LDAP_DEBUG_TRACE, "ldap_chase_v3referrals: queue referral \"%s\"\n",
+                               Debug( LDAP_DEBUG_TRACE,
+                                       "ldap_chase_v3referrals: queue referral \"%s\"\n",
                                        refarray[i], 0, 0);
                                if( lc->lconn_rebind_queue == NULL ) {
                                        /* Create a referral list */
-                                       if( (lc->lconn_rebind_queue = (char ***)LDAP_MALLOC( sizeof(void *) * 2)) == NULL) {
+                                       lc->lconn_rebind_queue =
+                                               (char ***) LDAP_MALLOC( sizeof(void *) * 2);
+
+                                       if( lc->lconn_rebind_queue == NULL) {
                                                ld->ld_errno = LDAP_NO_MEMORY;
                                                rc = -1;
                                                goto done;
                                        }
+
                                        lc->lconn_rebind_queue[0] = refarray;
                                        lc->lconn_rebind_queue[1] = NULL;
                                        refarray = NULL;
+
                                } else {
                                        /* Count how many referral arrays we already have */
                                        for( j = 0; lc->lconn_rebind_queue[j] != NULL; j++) {
-                                               ;
+                                               /* empty */;
                                        }
+
                                        /* Add the new referral to the list */
-                                       if( (lc->lconn_rebind_queue = (char ***)LDAP_REALLOC(
-                                                       lc->lconn_rebind_queue, sizeof(void *) * (j + 2))) == NULL) {
+                                       lc->lconn_rebind_queue = (char ***) LDAP_REALLOC(
+                                               lc->lconn_rebind_queue, sizeof(void *) * (j + 2));
+
+                                       if( lc->lconn_rebind_queue == NULL ) {
                                                ld->ld_errno = LDAP_NO_MEMORY;
                                                rc = -1;
                                                goto done;
@@ -683,6 +696,7 @@ ldap_chase_v3referrals( LDAP *ld, LDAPRequest *lr, char **refs, int sref, char *
                                        lc->lconn_rebind_queue[j+1] = NULL;
                                        refarray = NULL;
                                }
+
                                /* We have queued the referral/reference, now just return */
                                rc = 0;
                                *hadrefp = 1;
@@ -700,14 +714,17 @@ ldap_chase_v3referrals( LDAP *ld, LDAPRequest *lr, char **refs, int sref, char *
                        srv->lud_dn = LDAP_STRDUP( "" );
                }
 
-               if (( ber = re_encode_request( ld, origreq->lr_ber,
-                           ++ld->ld_msgid, srv, &rinfo.ri_request )) == NULL ) {
+               ber = re_encode_request( ld, origreq->lr_ber, ++ld->ld_msgid,
+                       sref, srv, &rinfo.ri_request );
+
+               if( ber == NULL ) {
                        ld->ld_errno = LDAP_ENCODING_ERROR;
                        rc = -1;
                        goto done;
                }
 
-               Debug( LDAP_DEBUG_TRACE, "ldap_chase_v3referral: msgid %d, url \"%s\"\n",
+               Debug( LDAP_DEBUG_TRACE,
+                       "ldap_chase_v3referral: msgid %d, url \"%s\"\n",
                        lr->lr_msgid, refarray[i], 0);
 
                /* Send the new request to the server - may require a bind */
@@ -781,7 +798,11 @@ done:
  * XXX merging of errors in this routine needs to be improved
  */
 int
-ldap_chase_referrals( LDAP *ld, LDAPRequest *lr, char **errstrp, int *hadrefp )
+ldap_chase_referrals( LDAP *ld,
+       LDAPRequest *lr,
+       char **errstrp,
+       int sref,
+       int *hadrefp )
 {
        int             rc, count, len;
        char            *p, *ref, *unfollowed;
@@ -858,7 +879,7 @@ ldap_chase_referrals( LDAP *ld, LDAPRequest *lr, char **errstrp, int *hadrefp )
                *hadrefp = 1;
 
                ber = re_encode_request( ld, origreq->lr_ber,
-                   ++ld->ld_msgid, srv, &rinfo.ri_request );
+                   ++ld->ld_msgid, sref, srv, &rinfo.ri_request );
 
                if( ber == NULL ) {
                        return -1 ;
@@ -929,6 +950,7 @@ static BerElement *
 re_encode_request( LDAP *ld,
        BerElement *origber,
        ber_int_t msgid,
+       int sref,
        LDAPURLDesc *srv,
        int *type )
 {
@@ -977,11 +999,17 @@ re_encode_request( LDAP *ld,
                /* search requests need to be re-scope-ed */
                rc = ber_scanf( &tmpber, "{ae" /*"}"*/, &orig_dn, &scope );
 
-               if( srv->lud_scope == LDAP_SCOPE_DEFAULT &&
-                       scope != LDAP_SCOPE_SUBTREE )
-               {
+               if( srv->lud_scope != LDAP_SCOPE_DEFAULT ) {
+                       /* use the scope provided in reference */
+                       scope = srv->lud_scope;
+
+               } else if ( sref && scope != LDAP_SCOPE_SUBTREE ) {
+                       /* use scope implied by previous operation */
+                       /*   base -> base */
+                       /*   one -> base */
+                       /*   subtree -> subtree */
                        scope = LDAP_SCOPE_BASE;
-               } 
+               }
 
        } else {
                rc = ber_scanf( &tmpber, "{a" /*}*/, &orig_dn );