version 1.64, 2002/01/17 22:30:05
|
version 1.64.2.13, 2004/03/26 22:34:27
|
Line 1
|
Line 1
|
/* $OpenLDAP: pkg/ldap/libraries/libldap/result.c,v 1.63 2002/01/06 01:18:38 kurt Exp $ */ |
/* $OpenLDAP: pkg/ldap/libraries/libldap/result.c,v 1.64.2.12 2003/02/28 17:07:14 kurt Exp $ */ |
/* |
/* |
* Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved. |
* Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved. |
* COPYING RESTRICTIONS APPLY, see COPYRIGHT file |
* COPYING RESTRICTIONS APPLY, see COPYRIGHT file |
*/ |
*/ |
/* Portions |
/* Portions |
Line 27
|
Line 27
|
* |
* |
* result.c - wait for an ldap result |
* result.c - wait for an ldap result |
*/ |
*/ |
|
/* 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. |
|
*/ |
|
|
/* |
/* |
* LDAPv3 (RFC2251) |
* LDAPv3 (RFC2251) |
Line 53
|
Line 57
|
#include <ac/unistd.h> |
#include <ac/unistd.h> |
|
|
#include "ldap-int.h" |
#include "ldap-int.h" |
|
#include "ldap_log.h" |
|
|
static int ldap_abandoned LDAP_P(( LDAP *ld, ber_int_t msgid )); |
static int ldap_abandoned LDAP_P(( LDAP *ld, ber_int_t msgid )); |
static int ldap_mark_abandoned LDAP_P(( LDAP *ld, ber_int_t msgid )); |
static int ldap_mark_abandoned LDAP_P(( LDAP *ld, ber_int_t msgid )); |
static int wait4msg LDAP_P(( LDAP *ld, ber_int_t msgid, int all, struct timeval *timeout, |
static int wait4msg LDAP_P(( LDAP *ld, ber_int_t msgid, int all, struct timeval *timeout, |
LDAPMessage **result )); |
LDAPMessage **result )); |
static ber_tag_t try_read1msg LDAP_P(( LDAP *ld, ber_int_t msgid, |
static ber_tag_t try_read1msg LDAP_P(( LDAP *ld, ber_int_t msgid, |
int all, Sockbuf *sb, LDAPConn *lc, LDAPMessage **result )); |
int all, Sockbuf *sb, LDAPConn **lc, LDAPMessage **result )); |
static ber_tag_t build_result_ber LDAP_P(( LDAP *ld, BerElement **bp, LDAPRequest *lr )); |
static ber_tag_t build_result_ber LDAP_P(( LDAP *ld, BerElement **bp, LDAPRequest *lr )); |
static void merge_error_info LDAP_P(( LDAP *ld, LDAPRequest *parentr, LDAPRequest *lr )); |
static void merge_error_info LDAP_P(( LDAP *ld, LDAPRequest *parentr, LDAPRequest *lr )); |
static LDAPMessage * chkResponseList LDAP_P(( LDAP *ld, int msgid, int all)); |
static LDAPMessage * chkResponseList LDAP_P(( LDAP *ld, int msgid, int all)); |
Line 97 ldap_result(
|
Line 101 ldap_result(
|
assert( ld != NULL ); |
assert( ld != NULL ); |
assert( result != NULL ); |
assert( result != NULL ); |
|
|
|
#ifdef NEW_LOGGING |
|
LDAP_LOG ( OPERATION, ARGS, "ldap_result msgid %d\n", msgid, 0, 0 ); |
|
#else |
Debug( LDAP_DEBUG_TRACE, "ldap_result msgid %d\n", msgid, 0, 0 ); |
Debug( LDAP_DEBUG_TRACE, "ldap_result msgid %d\n", msgid, 0, 0 ); |
|
#endif |
if( ld == NULL ) { |
|
return -1; |
|
} |
|
|
|
if( result == NULL ) { |
|
ld->ld_errno = LDAP_PARAM_ERROR; |
|
return -1; |
|
} |
|
|
|
lm = chkResponseList(ld, msgid, all); |
lm = chkResponseList(ld, msgid, all); |
|
|
Line 133 chkResponseList(
|
Line 132 chkResponseList(
|
* wait until it arrives or timeout occurs. |
* wait until it arrives or timeout occurs. |
*/ |
*/ |
|
|
|
#ifdef NEW_LOGGING |
|
LDAP_LOG ( OPERATION, ARGS, "ldap_chkResponseList for msgid=%d, all=%d\n", |
|
msgid, all, 0 ); |
|
#else |
Debug( LDAP_DEBUG_TRACE, |
Debug( LDAP_DEBUG_TRACE, |
"ldap_chkResponseList for msgid=%d, all=%d\n", |
"ldap_chkResponseList for msgid=%d, all=%d\n", |
msgid, all, 0 ); |
msgid, all, 0 ); |
|
#endif |
lastlm = NULL; |
lastlm = NULL; |
for ( lm = ld->ld_responses; lm != NULL; lm = nextlm ) { |
for ( lm = ld->ld_responses; lm != NULL; lm = nextlm ) { |
nextlm = lm->lm_next; |
nextlm = lm->lm_next; |
|
|
if ( ldap_abandoned( ld, lm->lm_msgid ) ) { |
if ( ldap_abandoned( ld, lm->lm_msgid ) ) { |
|
#ifdef NEW_LOGGING |
|
LDAP_LOG ( OPERATION, DETAIL1, |
|
"ldap_chkResponseList msg abandoned, msgid %d\n", msgid, 0, 0 ); |
|
#else |
Debug( LDAP_DEBUG_TRACE, |
Debug( LDAP_DEBUG_TRACE, |
"ldap_chkResponseList msg abandoned, msgid %d\n", |
"ldap_chkResponseList msg abandoned, msgid %d\n", |
msgid, 0, 0 ); |
msgid, 0, 0 ); |
|
#endif |
ldap_mark_abandoned( ld, lm->lm_msgid ); |
ldap_mark_abandoned( ld, lm->lm_msgid ); |
|
|
if ( lastlm == NULL ) { |
if ( lastlm == NULL ) { |
Line 201 chkResponseList(
|
Line 210 chkResponseList(
|
|
|
#ifdef LDAP_DEBUG |
#ifdef LDAP_DEBUG |
if( lm == NULL) { |
if( lm == NULL) { |
|
#ifdef NEW_LOGGING |
|
LDAP_LOG ( OPERATION, RESULTS, "ldap_chkResponseList returns NULL\n", |
|
0, 0, 0 ); |
|
#else |
Debug( LDAP_DEBUG_TRACE, |
Debug( LDAP_DEBUG_TRACE, |
"ldap_chkResponseList returns NULL\n", 0, 0, 0); |
"ldap_chkResponseList returns NULL\n", 0, 0, 0); |
|
#endif |
} else { |
} else { |
|
#ifdef NEW_LOGGING |
|
LDAP_LOG ( OPERATION, RESULTS, |
|
"ldap_chkResponseList returns msgid %d, type 0x%02lu\n", |
|
lm->lm_msgid, (unsigned long) lm->lm_msgtype, 0 ); |
|
#else |
Debug( LDAP_DEBUG_TRACE, |
Debug( LDAP_DEBUG_TRACE, |
"ldap_chkResponseList returns msgid %d, type 0x%02lu\n", |
"ldap_chkResponseList returns msgid %d, type 0x%02lu\n", |
lm->lm_msgid, (unsigned long) lm->lm_msgtype, 0); |
lm->lm_msgid, (unsigned long) lm->lm_msgtype, 0); |
|
#endif |
} |
} |
#endif |
#endif |
return lm; |
return lm; |
Line 231 wait4msg(
|
Line 251 wait4msg(
|
|
|
#ifdef LDAP_DEBUG |
#ifdef LDAP_DEBUG |
if ( timeout == NULL ) { |
if ( timeout == NULL ) { |
|
#ifdef NEW_LOGGING |
|
LDAP_LOG ( OPERATION, ARGS, |
|
"wait4msg (infinite timeout), msgid %d\n", msgid, 0, 0 ); |
|
#else |
Debug( LDAP_DEBUG_TRACE, "wait4msg (infinite timeout), msgid %d\n", |
Debug( LDAP_DEBUG_TRACE, "wait4msg (infinite timeout), msgid %d\n", |
msgid, 0, 0 ); |
msgid, 0, 0 ); |
|
#endif |
} else { |
} else { |
|
#ifdef NEW_LOGGING |
|
LDAP_LOG ( OPERATION, ARGS, |
|
"wait4msg (timeout %ld sec, %ld usec), msgid %d\n", |
|
(long) timeout->tv_sec, (long) timeout->tv_usec, msgid ); |
|
#else |
Debug( LDAP_DEBUG_TRACE, "wait4msg (timeout %ld sec, %ld usec), msgid %d\n", |
Debug( LDAP_DEBUG_TRACE, "wait4msg (timeout %ld sec, %ld usec), msgid %d\n", |
(long) timeout->tv_sec, (long) timeout->tv_usec, msgid ); |
(long) timeout->tv_sec, (long) timeout->tv_usec, msgid ); |
|
#endif |
} |
} |
#endif /* LDAP_DEBUG */ |
#endif /* LDAP_DEBUG */ |
|
|
Line 250 wait4msg(
|
Line 281 wait4msg(
|
rc = -2; |
rc = -2; |
while ( rc == -2 ) { |
while ( rc == -2 ) { |
#ifdef LDAP_DEBUG |
#ifdef LDAP_DEBUG |
|
#ifdef NEW_LOGGING |
|
LDAP_LOG ( OPERATION, ARGS, |
|
"wait4msg continue, msgid %d, all %d\n", msgid, all, 0 ); |
|
#else |
Debug( LDAP_DEBUG_TRACE, "wait4msg continue, msgid %d, all %d\n", |
Debug( LDAP_DEBUG_TRACE, "wait4msg continue, msgid %d, all %d\n", |
msgid, all, 0 ); |
msgid, all, 0 ); |
|
#endif |
if ( ldap_debug & LDAP_DEBUG_TRACE ) { |
if ( ldap_debug & LDAP_DEBUG_TRACE ) { |
ldap_dump_connection( ld, ld->ld_conns, 1 ); |
ldap_dump_connection( ld, ld->ld_conns, 1 ); |
ldap_dump_requests_and_responses( ld ); |
ldap_dump_requests_and_responses( ld ); |
Line 262 wait4msg(
|
Line 298 wait4msg(
|
rc = (*result)->lm_msgtype; |
rc = (*result)->lm_msgtype; |
} else { |
} else { |
|
|
for ( lc = ld->ld_conns; lc != NULL; lc = lc->lconn_next ) { |
for ( lc = ld->ld_conns; lc != NULL; lc = nextlc ) { |
|
nextlc = lc->lconn_next; |
if ( ber_sockbuf_ctrl( lc->lconn_sb, |
if ( ber_sockbuf_ctrl( lc->lconn_sb, |
LBER_SB_OPT_DATA_READY, NULL ) ) { |
LBER_SB_OPT_DATA_READY, NULL ) ) { |
rc = try_read1msg( ld, msgid, all, lc->lconn_sb, |
rc = try_read1msg( ld, msgid, all, lc->lconn_sb, |
lc, result ); |
&lc, result ); |
break; |
break; |
} |
} |
} |
} |
Line 277 wait4msg(
|
Line 314 wait4msg(
|
|
|
#ifdef LDAP_DEBUG |
#ifdef LDAP_DEBUG |
if ( rc == -1 ) { |
if ( rc == -1 ) { |
|
#ifdef NEW_LOGGING |
|
LDAP_LOG ( OPERATION, ARGS, |
|
"wait4msg: ldap_int_select returned -1: errno %d\n", |
|
errno, 0, 0 ); |
|
#else |
Debug( LDAP_DEBUG_TRACE, |
Debug( LDAP_DEBUG_TRACE, |
"ldap_int_select returned -1: errno %d\n", |
"ldap_int_select returned -1: errno %d\n", |
errno, 0, 0 ); |
errno, 0, 0 ); |
|
#endif |
} |
} |
#endif |
#endif |
|
|
Line 296 wait4msg(
|
Line 339 wait4msg(
|
rc = -2; /* select interrupted: loop */ |
rc = -2; /* select interrupted: loop */ |
} else { |
} else { |
rc = -2; |
rc = -2; |
|
if ( ld->ld_requests && |
|
ld->ld_requests->lr_status == LDAP_REQST_WRITING && |
|
ldap_is_write_ready( ld, |
|
ld->ld_requests->lr_conn->lconn_sb ) ) { |
|
ldap_int_flush_request( ld, ld->ld_requests ); |
|
} |
for ( lc = ld->ld_conns; rc == -2 && lc != NULL; |
for ( lc = ld->ld_conns; rc == -2 && lc != NULL; |
lc = nextlc ) { |
lc = nextlc ) { |
nextlc = lc->lconn_next; |
nextlc = lc->lconn_next; |
Line 304 wait4msg(
|
Line 353 wait4msg(
|
ldap_is_read_ready( ld, |
ldap_is_read_ready( ld, |
lc->lconn_sb )) { |
lc->lconn_sb )) { |
rc = try_read1msg( ld, msgid, all, |
rc = try_read1msg( ld, msgid, all, |
lc->lconn_sb, lc, result ); |
lc->lconn_sb, &lc, result ); |
|
if ( lc == NULL ) lc = nextlc; |
} |
} |
} |
} |
} |
} |
Line 319 wait4msg(
|
Line 369 wait4msg(
|
break; |
break; |
} |
} |
|
|
|
#ifdef NEW_LOGGING |
|
LDAP_LOG ( OPERATION, DETAIL1, |
|
"wait4msg: %ld secs to go\n", (long) tv.tv_sec, 0, 0 ); |
|
#else |
Debug( LDAP_DEBUG_TRACE, "wait4msg: %ld secs to go\n", |
Debug( LDAP_DEBUG_TRACE, "wait4msg: %ld secs to go\n", |
(long) tv.tv_sec, 0, 0 ); |
(long) tv.tv_sec, 0, 0 ); |
|
#endif |
start_time = tmp_time; |
start_time = tmp_time; |
} |
} |
} |
} |
Line 335 try_read1msg(
|
Line 390 try_read1msg(
|
ber_int_t msgid, |
ber_int_t msgid, |
int all, |
int all, |
Sockbuf *sb, |
Sockbuf *sb, |
LDAPConn *lc, |
LDAPConn **lcp, |
LDAPMessage **result ) |
LDAPMessage **result ) |
{ |
{ |
BerElement *ber; |
BerElement *ber; |
Line 345 try_read1msg(
|
Line 400 try_read1msg(
|
ber_len_t len; |
ber_len_t len; |
int foundit = 0; |
int foundit = 0; |
LDAPRequest *lr, *tmplr; |
LDAPRequest *lr, *tmplr; |
|
LDAPConn *lc; |
BerElement tmpber; |
BerElement tmpber; |
int rc, refer_cnt, hadref, simple_request; |
int rc, refer_cnt, hadref, simple_request; |
ber_int_t lderr; |
ber_int_t lderr; |
|
#ifdef LDAP_CONNECTIONLESS |
|
int firstmsg = 1, moremsgs = 0, isv2 = 0; |
|
#endif |
/* |
/* |
* v3ref = flag for V3 referral / search reference |
* v3ref = flag for V3 referral / search reference |
* 0 = not a ref, 1 = sucessfully chased ref, -1 = pass ref to application |
* 0 = not a ref, 1 = sucessfully chased ref, -1 = pass ref to application |
Line 355 try_read1msg(
|
Line 414 try_read1msg(
|
int v3ref; |
int v3ref; |
|
|
assert( ld != NULL ); |
assert( ld != NULL ); |
assert( lc != NULL ); |
assert( lcp != NULL ); |
|
assert( *lcp != NULL ); |
|
|
|
#ifdef NEW_LOGGING |
|
LDAP_LOG ( OPERATION, ARGS, "read1msg: msgid %d, all %d\n", msgid, all, 0 ); |
|
#else |
Debug( LDAP_DEBUG_TRACE, "read1msg: msgid %d, all %d\n", msgid, all, 0 ); |
Debug( LDAP_DEBUG_TRACE, "read1msg: msgid %d, all %d\n", msgid, all, 0 ); |
|
#endif |
|
|
|
lc = *lcp; |
|
|
|
retry: |
if ( lc->lconn_ber == NULL ) { |
if ( lc->lconn_ber == NULL ) { |
lc->lconn_ber = ldap_alloc_ber_with_options(ld); |
lc->lconn_ber = ldap_alloc_ber_with_options(ld); |
|
|
Line 370 try_read1msg(
|
Line 437 try_read1msg(
|
ber = lc->lconn_ber; |
ber = lc->lconn_ber; |
assert( LBER_VALID (ber) ); |
assert( LBER_VALID (ber) ); |
|
|
|
retry2: |
/* get the next message */ |
/* get the next message */ |
errno = 0; |
errno = 0; |
#ifdef LDAP_CONNECTIONLESS |
#ifdef LDAP_CONNECTIONLESS |
if ( LDAP_IS_UDP(ld) ) { |
if ( LDAP_IS_UDP(ld) ) { |
struct sockaddr from; |
struct sockaddr from; |
ber_int_sb_read(sb, &from, sizeof(struct sockaddr)); |
ber_int_sb_read(sb, &from, sizeof(struct sockaddr)); |
|
if (ld->ld_options.ldo_version == LDAP_VERSION2) isv2=1; |
} |
} |
|
nextresp3: |
#endif |
#endif |
if ( (tag = ber_get_next( sb, &len, ber )) |
if ( (tag = ber_get_next( sb, &len, ber )) |
!= LDAP_TAG_MESSAGE ) { |
!= LDAP_TAG_MESSAGE ) { |
if ( tag == LBER_DEFAULT) { |
if ( tag == LBER_DEFAULT) { |
#ifdef LDAP_DEBUG |
#ifdef LDAP_DEBUG |
|
#ifdef NEW_LOGGING |
|
LDAP_LOG ( OPERATION, DETAIL1, |
|
"read1msg: ber_get_next failed\n", 0, 0, 0 ); |
|
#else |
Debug( LDAP_DEBUG_CONNS, |
Debug( LDAP_DEBUG_CONNS, |
"ber_get_next failed.\n", 0, 0, 0 ); |
"ber_get_next failed.\n", 0, 0, 0 ); |
#endif |
#endif |
|
#endif |
#ifdef EWOULDBLOCK |
#ifdef EWOULDBLOCK |
if (errno==EWOULDBLOCK) return -2; |
if (errno==EWOULDBLOCK) return -2; |
#endif |
#endif |
Line 413 try_read1msg(
|
Line 488 try_read1msg(
|
|
|
/* if it's been abandoned, toss it */ |
/* if it's been abandoned, toss it */ |
if ( ldap_abandoned( ld, id ) ) { |
if ( ldap_abandoned( ld, id ) ) { |
ber_free( ber, 1 ); |
#ifdef NEW_LOGGING |
|
LDAP_LOG ( OPERATION, DETAIL1, "read1msg: abandoned\n", 0, 0, 0 ); |
|
#else |
Debug( LDAP_DEBUG_ANY, "abandoned\n", 0, 0, 0); |
Debug( LDAP_DEBUG_ANY, "abandoned\n", 0, 0, 0); |
|
#endif |
|
retry_ber: |
|
if ( ber_sockbuf_ctrl( sb, LBER_SB_OPT_DATA_READY, NULL ) ) { |
|
ber_free_buf( ber ); |
|
ber_init2( ber, NULL, ld->ld_lberoptions ); |
|
goto retry2; |
|
} |
|
ber_free( ber, 1 ); |
return( -2 ); /* continue looking */ |
return( -2 ); /* continue looking */ |
} |
} |
|
|
if (( lr = ldap_find_request_by_msgid( ld, id )) == NULL ) { |
if (( lr = ldap_find_request_by_msgid( ld, id )) == NULL ) { |
|
#ifdef NEW_LOGGING |
|
LDAP_LOG ( OPERATION, DETAIL1, |
|
"read1msg: no request for response with msgid %ld (tossing)\n", |
|
(long) id, 0, 0 ); |
|
#else |
Debug( LDAP_DEBUG_ANY, |
Debug( LDAP_DEBUG_ANY, |
"no request for response with msgid %ld (tossing)\n", |
"no request for response with msgid %ld (tossing)\n", |
(long) id, 0, 0 ); |
(long) id, 0, 0 ); |
ber_free( ber, 1 ); |
#endif |
return( -2 ); /* continue looking */ |
goto retry_ber; |
} |
} |
#ifdef LDAP_CONNECTIONLESS |
#ifdef LDAP_CONNECTIONLESS |
if (LDAP_IS_UDP(ld) && ld->ld_options.ldo_version == LDAP_VERSION2) { |
if (LDAP_IS_UDP(ld) && isv2) { |
struct berval blank; |
ber_scanf(ber, "x{"); |
ber_scanf(ber, "m{", &blank); |
|
} |
} |
|
nextresp2: |
#endif |
#endif |
/* the message type */ |
/* the message type */ |
if ( (tag = ber_peek_tag( ber, &len )) == LBER_ERROR ) { |
if ( (tag = ber_peek_tag( ber, &len )) == LBER_ERROR ) { |
Line 438 try_read1msg(
|
Line 528 try_read1msg(
|
return( -1 ); |
return( -1 ); |
} |
} |
|
|
|
#ifdef NEW_LOGGING |
|
LDAP_LOG ( OPERATION, DETAIL1, |
|
"read1msg: ldap_read: message type %s msgid %ld, original id %ld\n", |
|
ldap_int_msgtype2str( tag ), |
|
(long) lr->lr_msgid, (long) lr->lr_origid ); |
|
#else |
Debug( LDAP_DEBUG_TRACE, |
Debug( LDAP_DEBUG_TRACE, |
"ldap_read: message type %s msgid %ld, original id %ld\n", |
"ldap_read: message type %s msgid %ld, original id %ld\n", |
ldap_int_msgtype2str( tag ), |
ldap_int_msgtype2str( tag ), |
(long) lr->lr_msgid, (long) lr->lr_origid ); |
(long) lr->lr_msgid, (long) lr->lr_origid ); |
|
#endif |
|
|
id = lr->lr_origid; |
id = lr->lr_origid; |
refer_cnt = 0; |
refer_cnt = 0; |
Line 476 try_read1msg(
|
Line 573 try_read1msg(
|
/* If haven't got end search, set chasing referrals */ |
/* If haven't got end search, set chasing referrals */ |
if( lr->lr_status != LDAP_REQST_COMPLETED) { |
if( lr->lr_status != LDAP_REQST_COMPLETED) { |
lr->lr_status = LDAP_REQST_CHASINGREFS; |
lr->lr_status = LDAP_REQST_CHASINGREFS; |
|
#ifdef NEW_LOGGING |
|
LDAP_LOG ( OPERATION, DETAIL1, |
|
"read1msg: search ref chased," |
|
"mark request chasing refs, id = %d\n", |
|
lr->lr_msgid, 0, 0 ); |
|
#else |
Debug( LDAP_DEBUG_TRACE, |
Debug( LDAP_DEBUG_TRACE, |
"read1msg: search ref chased, mark request chasing refs, id = %d\n", |
"read1msg: search ref chased, mark request chasing refs, id = %d\n", |
lr->lr_msgid, 0, 0); |
lr->lr_msgid, 0, 0); |
|
#endif |
} |
} |
v3ref = 1; /* We sucessfully chased the reference */ |
v3ref = 1; /* We sucessfully chased the reference */ |
} |
} |
Line 502 try_read1msg(
|
Line 606 try_read1msg(
|
if( ber_scanf( &tmpber, "{v}", &refs) == LBER_ERROR) { |
if( ber_scanf( &tmpber, "{v}", &refs) == LBER_ERROR) { |
rc = LDAP_DECODING_ERROR; |
rc = LDAP_DECODING_ERROR; |
lr->lr_status = LDAP_REQST_COMPLETED; |
lr->lr_status = LDAP_REQST_COMPLETED; |
|
#ifdef NEW_LOGGING |
|
LDAP_LOG ( OPERATION, DETAIL1, |
|
"read1msg: referral decode error," |
|
"mark request completed, id = %d\n", |
|
lr->lr_msgid, 0, 0 ); |
|
#else |
Debug( LDAP_DEBUG_TRACE, |
Debug( LDAP_DEBUG_TRACE, |
"read1msg: referral decode error, mark request completed, id = %d\n", |
"read1msg: referral decode error, mark request completed, id = %d\n", |
lr->lr_msgid, 0, 0); |
lr->lr_msgid, 0, 0); |
|
#endif |
} else { |
} else { |
/* Chase the referral |
/* Chase the referral |
* Note: refs arrary is freed by ldap_chase_v3referrals |
* Note: refs arrary is freed by ldap_chase_v3referrals |
Line 512 try_read1msg(
|
Line 623 try_read1msg(
|
refer_cnt = ldap_chase_v3referrals( ld, lr, refs, |
refer_cnt = ldap_chase_v3referrals( ld, lr, refs, |
0, &lr->lr_res_error, &hadref ); |
0, &lr->lr_res_error, &hadref ); |
lr->lr_status = LDAP_REQST_COMPLETED; |
lr->lr_status = LDAP_REQST_COMPLETED; |
|
#ifdef NEW_LOGGING |
|
LDAP_LOG ( OPERATION, DETAIL1, |
|
"read1msg: referral chased," |
|
"mark request completed, id = %d\n", |
|
lr->lr_msgid, 0, 0 ); |
|
#else |
Debug( LDAP_DEBUG_TRACE, |
Debug( LDAP_DEBUG_TRACE, |
"read1msg: referral chased, mark request completed, id = %d\n", |
"read1msg: referral chased, mark request completed, id = %d\n", |
lr->lr_msgid, 0, 0); |
lr->lr_msgid, 0, 0); |
|
#endif |
if( refer_cnt > 0) { |
if( refer_cnt > 0) { |
v3ref = 1; /* Referral successfully chased */ |
v3ref = 1; /* Referral successfully chased */ |
} |
} |
Line 538 try_read1msg(
|
Line 656 try_read1msg(
|
* go through the following code. This code also chases V2 referrals |
* go through the following code. This code also chases V2 referrals |
* and checks if all referrals have been chased. |
* and checks if all referrals have been chased. |
*/ |
*/ |
if ( (tag != LDAP_RES_SEARCH_ENTRY) && (v3ref > -1) ) { |
if ( (tag != LDAP_RES_SEARCH_ENTRY) && (v3ref > -1) |
|
#ifdef LDAP_RES_INTERMEDIATE_RESP |
|
&& (tag != LDAP_RES_INTERMEDIATE_RESP ) |
|
#endif |
|
) { |
/* For a v3 search referral/reference, only come here if already chased it */ |
/* For a v3 search referral/reference, only come here if already chased it */ |
if ( ld->ld_version >= LDAP_VERSION2 && |
if ( ld->ld_version >= LDAP_VERSION2 && |
( lr->lr_parent != NULL || |
( lr->lr_parent != NULL || |
Line 546 try_read1msg(
|
Line 668 try_read1msg(
|
{ |
{ |
tmpber = *ber; /* struct copy */ |
tmpber = *ber; /* struct copy */ |
if ( v3ref == 1 ) { |
if ( v3ref == 1 ) { |
; /* V3 search reference or V3 referral sucessfully chased */ |
/* V3 search reference or V3 referral |
|
* sucessfully chased. If this message |
|
* is a search result, then it has no more |
|
* outstanding referrals. |
|
*/ |
|
if ( tag == LDAP_RES_SEARCH_RESULT ) |
|
refer_cnt = 0; |
} else if ( ber_scanf( &tmpber, "{iaa}", &lderr, |
} else if ( ber_scanf( &tmpber, "{iaa}", &lderr, |
&lr->lr_res_matched, &lr->lr_res_error ) |
&lr->lr_res_matched, &lr->lr_res_error ) |
!= LBER_ERROR ) { |
!= LBER_ERROR ) { |
Line 555 try_read1msg(
|
Line 683 try_read1msg(
|
refer_cnt = ldap_chase_referrals( ld, lr, |
refer_cnt = ldap_chase_referrals( ld, lr, |
&lr->lr_res_error, -1, &hadref ); |
&lr->lr_res_error, -1, &hadref ); |
lr->lr_status = LDAP_REQST_COMPLETED; |
lr->lr_status = LDAP_REQST_COMPLETED; |
|
#ifdef NEW_LOGGING |
|
LDAP_LOG ( OPERATION, DETAIL1, |
|
"read1msg: V2 referral chased," |
|
"mark request completed, id = %d\n", |
|
lr->lr_msgid, 0, 0 ); |
|
#else |
Debug( LDAP_DEBUG_TRACE, |
Debug( LDAP_DEBUG_TRACE, |
"read1msg: V2 referral chased, mark request completed, id = %d\n", lr->lr_msgid, 0, 0); |
"read1msg: V2 referral chased, mark request completed, id = %d\n", lr->lr_msgid, 0, 0); |
|
#endif |
} |
} |
|
|
/* save errno, message, and matched string */ |
/* save errno, message, and matched string */ |
Line 569 try_read1msg(
|
Line 704 try_read1msg(
|
} else { |
} else { |
lr->lr_res_errno = LDAP_PARTIAL_RESULTS; |
lr->lr_res_errno = LDAP_PARTIAL_RESULTS; |
} |
} |
|
#ifdef NEW_LOGGING |
|
LDAP_LOG ( OPERATION, DETAIL1, |
|
"read1msg: new result: res_errno: %d, res_error: <%s>, res_matched: <%s>\n", |
|
lr->lr_res_errno, lr->lr_res_error ? lr->lr_res_error : "", |
|
lr->lr_res_matched ? lr->lr_res_matched : "" ); |
|
#else |
Debug( LDAP_DEBUG_TRACE, |
Debug( LDAP_DEBUG_TRACE, |
"new result: res_errno: %d, res_error: <%s>, res_matched: <%s>\n", |
"new result: res_errno: %d, res_error: <%s>, res_matched: <%s>\n", |
lr->lr_res_errno, lr->lr_res_error ? lr->lr_res_error : "", |
lr->lr_res_errno, lr->lr_res_error ? lr->lr_res_error : "", |
lr->lr_res_matched ? lr->lr_res_matched : "" ); |
lr->lr_res_matched ? lr->lr_res_matched : "" ); |
|
#endif |
} |
} |
} |
} |
|
|
|
#ifdef NEW_LOGGING |
|
LDAP_LOG ( OPERATION, DETAIL1, "read1msg: %d new referrals\n", |
|
refer_cnt, 0, 0 ); |
|
#else |
Debug( LDAP_DEBUG_TRACE, |
Debug( LDAP_DEBUG_TRACE, |
"read1msg: %d new referrals\n", refer_cnt, 0, 0 ); |
"read1msg: %d new referrals\n", refer_cnt, 0, 0 ); |
|
#endif |
|
|
if ( refer_cnt != 0 ) { /* chasing referrals */ |
if ( refer_cnt != 0 ) { /* chasing referrals */ |
ber_free( ber, 1 ); |
ber_free( ber, 1 ); |
Line 597 Debug( LDAP_DEBUG_TRACE,
|
Line 744 Debug( LDAP_DEBUG_TRACE,
|
} |
} |
|
|
lr->lr_status = LDAP_REQST_COMPLETED; /* declare this request done */ |
lr->lr_status = LDAP_REQST_COMPLETED; /* declare this request done */ |
|
#ifdef NEW_LOGGING |
|
LDAP_LOG ( OPERATION, DETAIL1, |
|
"read1msg: mark request completed, id = %d\n", |
|
lr->lr_msgid, 0, 0 ); |
|
#else |
Debug( LDAP_DEBUG_TRACE, |
Debug( LDAP_DEBUG_TRACE, |
"read1msg: mark request completed, id = %d\n", lr->lr_msgid, 0, 0); |
"read1msg: mark request completed, id = %d\n", lr->lr_msgid, 0, 0); |
|
#endif |
while ( lr->lr_parent != NULL ) { |
while ( lr->lr_parent != NULL ) { |
merge_error_info( ld, lr->lr_parent, lr ); |
merge_error_info( ld, lr->lr_parent, lr ); |
|
|
Line 622 Debug( LDAP_DEBUG_TRACE,
|
Line 775 Debug( LDAP_DEBUG_TRACE,
|
if ( lr->lr_outrefcnt <= 0 && lr->lr_parent == NULL && tmplr == NULL ) { |
if ( lr->lr_outrefcnt <= 0 && lr->lr_parent == NULL && tmplr == NULL ) { |
id = lr->lr_msgid; |
id = lr->lr_msgid; |
tag = lr->lr_res_msgtype; |
tag = lr->lr_res_msgtype; |
|
#ifdef NEW_LOGGING |
|
LDAP_LOG ( OPERATION, DETAIL1, |
|
"read1msg: request %ld done\n", (long) id, 0, 0 ); |
|
LDAP_LOG ( OPERATION, DETAIL1, |
|
"read1msg: res_errno: %d,res_error: <%s>, res_matched: <%s>\n", |
|
lr->lr_res_errno, lr->lr_res_error ? lr->lr_res_error : "", |
|
lr->lr_res_matched ? lr->lr_res_matched : "" ); |
|
#else |
Debug( LDAP_DEBUG_ANY, "request %ld done\n", |
Debug( LDAP_DEBUG_ANY, "request %ld done\n", |
(long) id, 0, 0 ); |
(long) id, 0, 0 ); |
Debug( LDAP_DEBUG_TRACE, |
Debug( LDAP_DEBUG_TRACE, |
"res_errno: %d, res_error: <%s>, res_matched: <%s>\n", |
"res_errno: %d, res_error: <%s>, res_matched: <%s>\n", |
lr->lr_res_errno, lr->lr_res_error ? lr->lr_res_error : "", |
lr->lr_res_errno, lr->lr_res_error ? lr->lr_res_error : "", |
lr->lr_res_matched ? lr->lr_res_matched : "" ); |
lr->lr_res_matched ? lr->lr_res_matched : "" ); |
|
#endif |
if ( !simple_request ) { |
if ( !simple_request ) { |
ber_free( ber, 1 ); |
ber_free( ber, 1 ); |
ber = NULL; |
ber = NULL; |
Line 642 lr->lr_res_matched ? lr->lr_res_matched
|
Line 804 lr->lr_res_matched ? lr->lr_res_matched
|
|
|
if ( lc != NULL ) { |
if ( lc != NULL ) { |
ldap_free_connection( ld, lc, 0, 1 ); |
ldap_free_connection( ld, lc, 0, 1 ); |
|
*lcp = NULL; |
} |
} |
} |
} |
} |
} |
Line 660 lr->lr_res_matched ? lr->lr_res_matched
|
Line 823 lr->lr_res_matched ? lr->lr_res_matched
|
new->lm_msgtype = tag; |
new->lm_msgtype = tag; |
new->lm_ber = ber; |
new->lm_ber = ber; |
|
|
#ifndef LDAP_NOCACHE |
#ifdef LDAP_CONNECTIONLESS |
if ( ld->ld_cache != NULL ) { |
/* CLDAP replies all fit in a single datagram. In LDAPv2 RFC1798 |
ldap_add_result_to_cache( ld, new ); |
* the responses are all a sequence wrapped in one message. In |
|
* LDAPv3 each response is in its own message. The datagram must |
|
* end with a SearchResult. We can't just parse each response in |
|
* separate calls to try_read1msg because the header info is only |
|
* present at the beginning of the datagram, not at the beginning |
|
* of each response. So parse all the responses at once and queue |
|
* them up, then pull off the first response to return to the |
|
* caller when all parsing is complete. |
|
*/ |
|
if ( LDAP_IS_UDP(ld) ) { |
|
/* If not a result, look for more */ |
|
if ( tag != LDAP_RES_SEARCH_RESULT ) { |
|
int ok = 0; |
|
moremsgs = 1; |
|
if (isv2) { |
|
/* LDAPv2: dup the current ber, skip past the current |
|
* response, and see if there are any more after it. |
|
*/ |
|
ber = ber_dup( ber ); |
|
ber_scanf( ber, "x" ); |
|
if (ber_peek_tag(ber, &len) != LBER_DEFAULT) { |
|
/* There's more - dup the ber buffer so they can all be |
|
* individually freed by ldap_msgfree. |
|
*/ |
|
struct berval bv; |
|
ber_get_option(ber, LBER_OPT_BER_REMAINING_BYTES, &len); |
|
bv.bv_val = LDAP_MALLOC(len); |
|
if (bv.bv_val) { |
|
ok=1; |
|
ber_read(ber, bv.bv_val, len); |
|
bv.bv_len = len; |
|
ber_init2(ber, &bv, ld->ld_lberoptions ); |
|
} |
|
} |
|
} else { |
|
/* LDAPv3: Just allocate a new ber. Since this is a buffered |
|
* datagram, if the sockbuf is readable we still have data |
|
* to parse. |
|
*/ |
|
ber = ldap_alloc_ber_with_options(ld); |
|
if (ber_sockbuf_ctrl(sb, LBER_SB_OPT_DATA_READY, NULL)) ok=1; |
|
} |
|
/* set up response chain */ |
|
if ( firstmsg ) { |
|
firstmsg = 0; |
|
new->lm_next = ld->ld_responses; |
|
ld->ld_responses = new; |
|
} else { |
|
tmp->lm_chain = new; |
|
} |
|
tmp = new; |
|
/* "ok" means there's more to parse */ |
|
if (ok) { |
|
if (isv2) goto nextresp2; |
|
else goto nextresp3; |
|
} else { |
|
/* got to end of datagram without a SearchResult. Free |
|
* our dup'd ber, but leave any buffer alone. For v2 case, |
|
* the previous response is still using this buffer. For v3, |
|
* the new ber has no buffer to free yet. |
|
*/ |
|
ber_free(ber, 0); |
|
return -1; |
|
} |
|
} else if ( moremsgs ) { |
|
/* got search result, and we had multiple responses in 1 datagram. |
|
* stick the result onto the end of the chain, and then pull the |
|
* first response off the head of the chain. |
|
*/ |
|
tmp->lm_chain = new; |
|
*result = chkResponseList( ld, msgid, all ); |
|
ld->ld_errno = LDAP_SUCCESS; |
|
return( (*result)->lm_msgtype ); |
} |
} |
#endif /* LDAP_NOCACHE */ |
} |
|
#endif |
|
|
/* is this the one we're looking for? */ |
/* is this the one we're looking for? */ |
if ( msgid == LDAP_RES_ANY || id == msgid ) { |
if ( msgid == LDAP_RES_ANY || id == msgid ) { |
Line 703 lr->lr_res_matched ? lr->lr_res_matched
|
Line 939 lr->lr_res_matched ? lr->lr_res_matched
|
|
|
new->lm_next = ld->ld_responses; |
new->lm_next = ld->ld_responses; |
ld->ld_responses = new; |
ld->ld_responses = new; |
return( -2 ); /* continue looking */ |
goto exit; |
} |
} |
|
|
|
#ifdef NEW_LOGGING |
|
LDAP_LOG ( OPERATION, DETAIL1, |
|
"read1msg: adding response id %ld type %ld\n", |
|
(long) new->lm_msgid, (long) new->lm_msgtype, 0 ); |
|
#else |
Debug( LDAP_DEBUG_TRACE, "adding response id %ld type %ld:\n", |
Debug( LDAP_DEBUG_TRACE, "adding response id %ld type %ld:\n", |
(long) new->lm_msgid, (long) new->lm_msgtype, 0 ); |
(long) new->lm_msgid, (long) new->lm_msgtype, 0 ); |
|
#endif |
|
|
/* part of a search response - add to end of list of entries */ |
/* part of a search response - add to end of list of entries */ |
for ( tmp = l; (tmp->lm_chain != NULL) && |
for ( tmp = l; (tmp->lm_chain != NULL) && |
Line 726 lr->lr_res_matched ? lr->lr_res_matched
|
Line 968 lr->lr_res_matched ? lr->lr_res_matched
|
prev->lm_next = l->lm_next; |
prev->lm_next = l->lm_next; |
*result = l; |
*result = l; |
ld->ld_errno = LDAP_SUCCESS; |
ld->ld_errno = LDAP_SUCCESS; |
#ifdef LDAP_WORLD_P16 |
|
/* |
|
* XXX questionable fix; see text for [P16] on |
|
* http://www.critical-angle.com/ldapworld/patch/ |
|
* |
|
* inclusion of this patch causes searchs to hang on |
|
* multiple platforms |
|
*/ |
|
return( l->lm_msgtype ); |
|
#else /* LDAP_WORLD_P16 */ |
|
return( tag ); |
return( tag ); |
#endif /* !LDAP_WORLD_P16 */ |
|
} |
} |
|
|
|
exit: |
|
if ( ber_sockbuf_ctrl( sb, LBER_SB_OPT_DATA_READY, NULL ) ) { |
|
goto retry; |
|
} |
return( -2 ); /* continue looking */ |
return( -2 ); /* continue looking */ |
} |
} |
|
|
Line 748 static ber_tag_t
|
Line 983 static ber_tag_t
|
build_result_ber( LDAP *ld, BerElement **bp, LDAPRequest *lr ) |
build_result_ber( LDAP *ld, BerElement **bp, LDAPRequest *lr ) |
{ |
{ |
ber_len_t len; |
ber_len_t len; |
ber_int_t tag; |
ber_tag_t tag; |
ber_int_t along; |
ber_int_t along; |
BerElement *ber; |
BerElement *ber; |
|
|
Line 826 merge_error_info( LDAP *ld, LDAPRequest
|
Line 1061 merge_error_info( LDAP *ld, LDAPRequest
|
} |
} |
} |
} |
|
|
|
#ifdef NEW_LOGGING |
|
LDAP_LOG( OPERATION, DETAIL1, "merged parent (id %d) error info: ", |
|
parentr->lr_msgid, 0, 0 ); |
|
LDAP_LOG( OPERATION, DETAIL1, "result errno %d, error <%s>, matched <%s>\n", |
|
parentr->lr_res_errno, parentr->lr_res_error ? |
|
parentr->lr_res_error : "", parentr->lr_res_matched ? |
|
parentr->lr_res_matched : "" ); |
|
#else |
Debug( LDAP_DEBUG_TRACE, "merged parent (id %d) error info: ", |
Debug( LDAP_DEBUG_TRACE, "merged parent (id %d) error info: ", |
parentr->lr_msgid, 0, 0 ); |
parentr->lr_msgid, 0, 0 ); |
Debug( LDAP_DEBUG_TRACE, "result errno %d, error <%s>, matched <%s>\n", |
Debug( LDAP_DEBUG_TRACE, "result errno %d, error <%s>, matched <%s>\n", |
parentr->lr_res_errno, parentr->lr_res_error ? |
parentr->lr_res_errno, parentr->lr_res_error ? |
parentr->lr_res_error : "", parentr->lr_res_matched ? |
parentr->lr_res_error : "", parentr->lr_res_matched ? |
parentr->lr_res_matched : "" ); |
parentr->lr_res_matched : "" ); |
|
#endif |
} |
} |
|
|
|
|
Line 877 ldap_msgfree( LDAPMessage *lm )
|
Line 1121 ldap_msgfree( LDAPMessage *lm )
|
LDAPMessage *next; |
LDAPMessage *next; |
int type = 0; |
int type = 0; |
|
|
|
#ifdef NEW_LOGGING |
|
LDAP_LOG ( OPERATION, ENTRY, "ldap_msgfree\n", 0, 0, 0 ); |
|
#else |
Debug( LDAP_DEBUG_TRACE, "ldap_msgfree\n", 0, 0, 0 ); |
Debug( LDAP_DEBUG_TRACE, "ldap_msgfree\n", 0, 0, 0 ); |
|
#endif |
|
|
for ( ; lm != NULL; lm = next ) { |
for ( ; lm != NULL; lm = next ) { |
next = lm->lm_chain; |
next = lm->lm_chain; |
Line 901 ldap_msgdelete( LDAP *ld, int msgid )
|
Line 1149 ldap_msgdelete( LDAP *ld, int msgid )
|
|
|
assert( ld != NULL ); |
assert( ld != NULL ); |
|
|
|
#ifdef NEW_LOGGING |
|
LDAP_LOG ( OPERATION, ENTRY, "ldap_msgdelete\n", 0, 0, 0 ); |
|
#else |
Debug( LDAP_DEBUG_TRACE, "ldap_msgdelete\n", 0, 0, 0 ); |
Debug( LDAP_DEBUG_TRACE, "ldap_msgdelete\n", 0, 0, 0 ); |
|
#endif |
|
|
prev = NULL; |
prev = NULL; |
for ( lm = ld->ld_responses; lm != NULL; lm = lm->lm_next ) { |
for ( lm = ld->ld_responses; lm != NULL; lm = lm->lm_next ) { |