X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;ds=sidebyside;f=libraries%2Flibldap%2Frequest.c;h=b289bfcb655506db9dfda03ead490632afe2384e;hb=ef691ae8673a590fa48e201fe1f0c71764b58980;hp=dedb1ee2868f081471ef717238f1c0251d29b22a;hpb=6939c531700652491f4be4688c6a1f35a1ab8a18;p=openldap diff --git a/libraries/libldap/request.c b/libraries/libldap/request.c index dedb1ee286..b289bfcb65 100644 --- a/libraries/libldap/request.c +++ b/libraries/libldap/request.c @@ -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 . + * + * 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 + * . */ -/* 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. */ @@ -82,7 +89,8 @@ ldap_send_initial_request( LDAP *ld, ber_tag_t msgtype, const char *dn, - BerElement *ber ) + BerElement *ber, + ber_int_t msgid) { LDAPURLDesc *servers; int rc; @@ -133,8 +141,14 @@ ldap_send_initial_request( return LDAP_PARAM_ERROR; } #endif - rc = ldap_send_server_request( ld, ber, ld->ld_msgid, NULL, +#ifdef LDAP_R_COMPILE + ldap_pvt_thread_mutex_lock( &ld->ld_req_mutex ); +#endif + rc = ldap_send_server_request( ld, ber, msgid, NULL, servers, NULL, NULL ); +#ifdef LDAP_R_COMPILE + ldap_pvt_thread_mutex_unlock( &ld->ld_req_mutex ); +#endif if (servers) ldap_free_urllist(servers); return(rc); @@ -186,7 +200,7 @@ ldap_send_server_request( LDAPreqinfo *bind ) { LDAPRequest *lr; - int incparent; + int incparent, rc; #ifdef NEW_LOGGING LDAP_LOG ( OPERATION, ENTRY, "ldap_send_server_request\n", 0, 0, 0 ); @@ -232,11 +246,13 @@ ldap_send_server_request( * LDAP_BUSY and let the caller retry later. We only allow a single * request to be in WRITING state. */ + rc = 0; if ( ld->ld_requests && ld->ld_requests->lr_status == LDAP_REQST_WRITING && ldap_int_flush_request( ld, ld->ld_requests ) < 0 ) { - return -1; + rc = -1; } + if ( rc ) return rc; if (( lr = (LDAPRequest *)LDAP_CALLOC( 1, sizeof( LDAPRequest ))) == NULL ) { @@ -274,11 +290,11 @@ ldap_send_server_request( ld->ld_requests = lr; lr->lr_prev = NULL; + ld->ld_errno = LDAP_SUCCESS; if ( ldap_int_flush_request( ld, lr ) == -1 ) { - return -1; + msgid = -1; } - ld->ld_errno = LDAP_SUCCESS; return( msgid ); } @@ -362,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; @@ -388,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; @@ -572,6 +604,9 @@ ldap_dump_requests_and_responses( LDAP *ld ) LDAPRequest *lr; LDAPMessage *lm, *l; +#ifdef LDAP_R_COMPILE + ldap_pvt_thread_mutex_lock( &ld->ld_req_mutex ); +#endif fprintf( stderr, "** Outstanding Requests:\n" ); if (( lr = ld->ld_requests ) == NULL ) { fprintf( stderr, " Empty\n" ); @@ -587,7 +622,9 @@ ldap_dump_requests_and_responses( LDAP *ld ) fprintf( stderr, " outstanding referrals %d, parent count %d\n", lr->lr_outrefcnt, lr->lr_parentcnt ); } - +#ifdef LDAP_R_COMPILE + ldap_pvt_thread_mutex_unlock( &ld->ld_req_mutex ); +#endif fprintf( stderr, "** Response Queue:\n" ); if (( lm = ld->ld_responses ) == NULL ) { fprintf( stderr, " Empty\n" ); @@ -687,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 */ @@ -723,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; @@ -826,7 +869,8 @@ ldap_chase_v3referrals( LDAP *ld, LDAPRequest *lr, char **refs, int sref, char * srv->lud_dn = LDAP_STRDUP( "" ); } - ber = re_encode_request( ld, origreq->lr_ber, ++ld->ld_msgid, + LDAP_NEXT_MSGID( ld, id ); + ber = re_encode_request( ld, origreq->lr_ber, id, sref, srv, &rinfo.ri_request ); if( ber == NULL ) { @@ -848,8 +892,16 @@ ldap_chase_v3referrals( LDAP *ld, LDAPRequest *lr, char **refs, int sref, char * /* Send the new request to the server - may require a bind */ rinfo.ri_msgid = origreq->lr_origid; rinfo.ri_url = refarray[i]; - if ( (rc = ldap_send_server_request( ld, ber, ld->ld_msgid, - origreq, srv, NULL, &rinfo )) < 0 ) { +#ifdef LDAP_R_COMPILE + ldap_pvt_thread_mutex_lock( &ld->ld_req_mutex ); +#endif + 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 + if ( rc < 0 ) { /* Failure, try next referral in the list */ #ifdef NEW_LOGGING LDAP_LOG ( OPERATION, ERR, @@ -928,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; @@ -1024,8 +1076,9 @@ ldap_chase_referrals( LDAP *ld, *hadrefp = 1; + LDAP_NEXT_MSGID( ld, id ); ber = re_encode_request( ld, origreq->lr_ber, - ++ld->ld_msgid, sref, srv, &rinfo.ri_request ); + id, sref, srv, &rinfo.ri_request ); if( ber == NULL ) { return -1 ; @@ -1036,8 +1089,14 @@ ldap_chase_referrals( LDAP *ld, rinfo.ri_msgid = origreq->lr_origid; - rc = ldap_send_server_request( ld, ber, ld->ld_msgid, +#ifdef LDAP_R_COMPILE + ldap_pvt_thread_mutex_lock( &ld->ld_req_mutex ); +#endif + 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 ); +#endif LDAP_FREE( rinfo.ri_url ); @@ -1163,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 { @@ -1241,6 +1314,9 @@ ldap_find_request_by_msgid( LDAP *ld, ber_int_t msgid ) { LDAPRequest *lr; +#ifdef LDAP_R_COMPILE + ldap_pvt_thread_mutex_lock( &ld->ld_req_mutex ); +#endif for ( lr = ld->ld_requests; lr != NULL; lr = lr->lr_next ) { if( lr->lr_status == LDAP_REQST_COMPLETED ) { continue; /* Skip completed requests */ @@ -1249,6 +1325,9 @@ ldap_find_request_by_msgid( LDAP *ld, ber_int_t msgid ) break; } } +#ifdef LDAP_R_COMPILE + ldap_pvt_thread_mutex_unlock( &ld->ld_req_mutex ); +#endif return( lr ); }