]> git.sur5r.net Git - openldap/blobdiff - libraries/libldap/request.c
Renamed ppcontrol.c to ppolicy.c
[openldap] / libraries / libldap / request.c
index 847533261cf351884f0ca73e37dfe7ac3256817d..b289bfcb655506db9dfda03ead490632afe2384e 100644 (file)
@@ -1,14 +1,21 @@
 /* $OpenLDAP$ */
-/*
- * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
- * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
+/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
+ *
+ * Copyright 1998-2004 The OpenLDAP Foundation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted only as authorized by the OpenLDAP
+ * Public License.
+ *
+ * A copy of this license is available in the file LICENSE in the
+ * top-level directory of the distribution or, alternatively, at
+ * <http://www.OpenLDAP.org/license.html>.
  */
-/*  Portions
- *  Copyright (c) 1995 Regents of the University of Michigan.
- *  All rights reserved.
+/* Portions Copyright (c) 1995 Regents of the University of Michigan.
+ * All rights reserved.
  */
-/*---
- * This notice applies to changes, created by or for Novell, Inc.,
+/* This notice applies to changes, created by or for Novell, Inc.,
  * to preexisting works for which notices appear elsewhere in this file.
  *
  * Copyright (C) 1999, 2000 Novell, Inc. All Rights Reserved.
@@ -25,8 +32,8 @@
  * Modification to OpenLDAP source by Novell, Inc.
  * April 2000 sfs  Added code to chase V3 referrals
  *  request.c - sending of ldap requests; handling of referrals
- */
-/* Note: A verbatim copy of version 2.0.1 of the OpenLDAP Public License 
+ *---
+ * Note: A verbatim copy of version 2.0.1 of the OpenLDAP Public License 
  * can be found in the file "build/LICENSE-2.0.1" in this distribution
  * of OpenLDAP Software.
  */
@@ -371,10 +378,18 @@ ldap_new_connection( LDAP *ld, LDAPURLDesc *srvlist, int use_ldsb,
                                        0, 0, 0 );
 #else
                                Debug( LDAP_DEBUG_TRACE, "Call application rebind_proc\n", 0, 0, 0);
+#endif
+#ifdef LDAP_R_COMPILE
+               ldap_pvt_thread_mutex_unlock( &ld->ld_req_mutex );
+               ldap_pvt_thread_mutex_unlock( &ld->ld_res_mutex );
 #endif
                                err = (*ld->ld_rebind_proc)( ld,
                                        bind->ri_url, bind->ri_request, bind->ri_msgid,
                                        ld->ld_rebind_params );
+#ifdef LDAP_R_COMPILE
+               ldap_pvt_thread_mutex_lock( &ld->ld_res_mutex );
+               ldap_pvt_thread_mutex_lock( &ld->ld_req_mutex );
+#endif
 
                                ld->ld_defconn = savedefconn;
                                --lc->lconn_refcnt;
@@ -397,10 +412,18 @@ ldap_new_connection( LDAP *ld, LDAPURLDesc *srvlist, int use_ldsb,
                                0, 0, 0 );
 #else
                        Debug( LDAP_DEBUG_TRACE, "anonymous rebind via ldap_bind_s\n", 0, 0, 0);
+#endif
+#ifdef LDAP_R_COMPILE
+                       ldap_pvt_thread_mutex_unlock( &ld->ld_req_mutex );
+                       ldap_pvt_thread_mutex_unlock( &ld->ld_res_mutex );
 #endif
                        if ( ldap_bind_s( ld, "", "", LDAP_AUTH_SIMPLE ) != LDAP_SUCCESS ) {
                                err = -1;
                        }
+#ifdef LDAP_R_COMPILE
+                       ldap_pvt_thread_mutex_lock( &ld->ld_res_mutex );
+                       ldap_pvt_thread_mutex_lock( &ld->ld_req_mutex );
+#endif
                        ld->ld_defconn = savedefconn;
                        --lc->lconn_refcnt;
 
@@ -701,7 +724,8 @@ ldap_chase_v3referrals( LDAP *ld, LDAPRequest *lr, char **refs, int sref, char *
        BerElement      *ber;
        char            **refarray = NULL;
        LDAPConn        *lc;
-       int                      rc, count, i, j;
+       int                      rc, count, i, j, id;
+       int                      parent_was_reference;
        LDAPreqinfo  rinfo;
 
        ld->ld_errno = LDAP_SUCCESS;    /* optimistic */
@@ -737,6 +761,11 @@ ldap_chase_v3referrals( LDAP *ld, LDAPRequest *lr, char **refs, int sref, char *
                goto done;
        }
 
+       /* check if parent request was a search reference */
+       parent_was_reference = ( lr->lr_parent &&
+               lr->lr_parent->lr_res_msgtype == LDAP_RES_SEARCH_REFERENCE ) ?
+               1 : 0;
+               
        /* find original request */
        for ( origreq = lr;
                origreq->lr_parent != NULL;
@@ -840,8 +869,8 @@ ldap_chase_v3referrals( LDAP *ld, LDAPRequest *lr, char **refs, int sref, char *
                        srv->lud_dn = LDAP_STRDUP( "" );
                }
 
-               LDAP_NEXT_MSGID( ld, rc );
-               ber = re_encode_request( ld, origreq->lr_ber, rc,
+               LDAP_NEXT_MSGID( ld, id );
+               ber = re_encode_request( ld, origreq->lr_ber, id,
                        sref, srv, &rinfo.ri_request );
 
                if( ber == NULL ) {
@@ -866,8 +895,9 @@ ldap_chase_v3referrals( LDAP *ld, LDAPRequest *lr, char **refs, int sref, char *
 #ifdef LDAP_R_COMPILE
                ldap_pvt_thread_mutex_lock( &ld->ld_req_mutex );
 #endif
-               rc = ldap_send_server_request( ld, ber, ld->ld_msgid,
-                       origreq, srv, NULL, &rinfo );
+               rc = ldap_send_server_request( ld, ber, id,
+                       (sref && !parent_was_reference) ? origreq : lr,
+                       srv, NULL, &rinfo );
 #ifdef LDAP_R_COMPILE
                ldap_pvt_thread_mutex_unlock( &ld->ld_req_mutex );
 #endif
@@ -950,7 +980,7 @@ ldap_chase_referrals( LDAP *ld,
        int sref,
        int *hadrefp )
 {
-       int             rc, count;
+       int             rc, count, id;
        unsigned        len;
        char            *p, *ref, *unfollowed;
        LDAPRequest     *origreq;
@@ -1046,9 +1076,9 @@ ldap_chase_referrals( LDAP *ld,
 
                *hadrefp = 1;
 
-               LDAP_NEXT_MSGID( ld, rc );
+               LDAP_NEXT_MSGID( ld, id );
                ber = re_encode_request( ld, origreq->lr_ber,
-                   rc, sref, srv, &rinfo.ri_request );
+                   id, sref, srv, &rinfo.ri_request );
 
                if( ber == NULL ) {
                        return -1 ;
@@ -1062,7 +1092,7 @@ ldap_chase_referrals( LDAP *ld,
 #ifdef LDAP_R_COMPILE
        ldap_pvt_thread_mutex_lock( &ld->ld_req_mutex );
 #endif
-               rc = ldap_send_server_request( ld, ber, ld->ld_msgid,
+               rc = ldap_send_server_request( ld, ber, id,
                    lr, srv, NULL, &rinfo );
 #ifdef LDAP_R_COMPILE
        ldap_pvt_thread_mutex_unlock( &ld->ld_req_mutex );
@@ -1192,12 +1222,26 @@ re_encode_request( LDAP *ld,
                        /* 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 if ( sref ) {
+                       /* use scope implied by previous operation
+                        *   base -> base
+                        *   one -> base
+                        *   subtree -> subtree
+                        *   subordinate -> subtree
+                        */
+                       switch( scope ) {
+                       default:
+                       case LDAP_SCOPE_BASE:
+                       case LDAP_SCOPE_ONELEVEL:
+                               scope = LDAP_SCOPE_BASE;
+                               break;
+                       case LDAP_SCOPE_SUBTREE:
+#ifdef LDAP_FEATURE_SUBORDINATE_SCOPE
+                       case LDAP_SCOPE_SUBORDINATE:
+#endif
+                               scope = LDAP_SCOPE_SUBTREE;
+                               break;
+                       }
                }
 
        } else {