⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 search.c

📁 OpenLdap是LDAP的开源项目
💻 C
📖 第 1 页 / 共 4 页
字号:
							candidates[ i ].sr_msgid = META_MSGID_IGNORE;							assert( ncandidates > 0 );							--ncandidates;							candidates[ i ].sr_err = rs->sr_err;							if ( META_BACK_ONERR_STOP( mi ) ) {								savepriv = op->o_private;								op->o_private = (void *)i;								send_ldap_result( op, rs );								op->o_private = savepriv;								goto finish;							}							/* fall thru */						case META_SEARCH_CANDIDATE:							/* get back into business... */							continue;						case META_SEARCH_BINDING:						case META_SEARCH_NEED_BIND:						case META_SEARCH_UNDEFINED:							assert( 0 );						default:							/* unrecoverable error */							candidates[ i ].sr_msgid = META_MSGID_IGNORE;							rc = rs->sr_err = LDAP_OTHER;							goto finish;						}					}					candidates[ i ].sr_err = rs->sr_err;					if ( META_BACK_ONERR_STOP( mi ) ) {						savepriv = op->o_private;						op->o_private = (void *)i;						send_ldap_result( op, rs );						op->o_private = savepriv;						goto finish;					}				}				/*				 * When no candidates are left,				 * the outer cycle finishes				 */				candidates[ i ].sr_msgid = META_MSGID_IGNORE;				assert( ncandidates > 0 );				--ncandidates;				rs->sr_err = candidates[ i ].sr_err;				continue;			default:				lastres_time = slap_get_time();				/* only touch when activity actually took place... */				if ( mi->mi_idle_timeout != 0 && msc->msc_time < lastres_time ) {					msc->msc_time = lastres_time;				}				break;			}			for ( msg = ldap_first_message( msc->msc_ld, res );				msg != NULL;				msg = ldap_next_message( msc->msc_ld, msg ) )			{				rc = ldap_msgtype( msg );				if ( rc == LDAP_RES_SEARCH_ENTRY ) {					LDAPMessage	*e;					if ( candidates[ i ].sr_type == REP_INTERMEDIATE ) {						/* don't retry any more... */						candidates[ i ].sr_type = REP_RESULT;					}					is_ok++;					e = ldap_first_entry( msc->msc_ld, msg );					savepriv = op->o_private;					op->o_private = (void *)i;					rs->sr_err = meta_send_entry( op, rs, mc, i, e );					switch ( rs->sr_err ) {					case LDAP_SIZELIMIT_EXCEEDED:						savepriv = op->o_private;						op->o_private = (void *)i;						send_ldap_result( op, rs );						op->o_private = savepriv;						rs->sr_err = LDAP_SUCCESS;						ldap_msgfree( res );						res = NULL;						goto finish;					case LDAP_UNAVAILABLE:						rs->sr_err = LDAP_OTHER;						ldap_msgfree( res );						res = NULL;						goto finish;					}					op->o_private = savepriv;					/* don't wait any longer... */					gotit = 1;					save_tv.tv_sec = 0;					save_tv.tv_usec = 0;				} else if ( rc == LDAP_RES_SEARCH_REFERENCE ) {					char		**references = NULL;					int		cnt;					if ( candidates[ i ].sr_type == REP_INTERMEDIATE ) {						/* don't retry any more... */						candidates[ i ].sr_type = REP_RESULT;					}						is_ok++;						rc = ldap_parse_reference( msc->msc_ld, msg,							&references, &rs->sr_ctrls, 0 );						if ( rc != LDAP_SUCCESS ) {						continue;					}						if ( references == NULL ) {						continue;					}#ifdef ENABLE_REWRITE					dc.ctx = "referralDN";#else /* ! ENABLE_REWRITE */					dc.tofrom = 0;					dc.normalized = 0;#endif /* ! ENABLE_REWRITE */					/* FIXME: merge all and return at the end */						for ( cnt = 0; references[ cnt ]; cnt++ )						;						rs->sr_ref = ch_calloc( sizeof( struct berval ), cnt + 1 );						for ( cnt = 0; references[ cnt ]; cnt++ ) {						ber_str2bv( references[ cnt ], 0, 1, &rs->sr_ref[ cnt ] );					}					BER_BVZERO( &rs->sr_ref[ cnt ] );						( void )ldap_back_referral_result_rewrite( &dc, rs->sr_ref );					if ( rs->sr_ref != NULL && !BER_BVISNULL( &rs->sr_ref[ 0 ] ) ) {						/* ignore return value by now */						savepriv = op->o_private;						op->o_private = (void *)i;						( void )send_search_reference( op, rs );						op->o_private = savepriv;							ber_bvarray_free( rs->sr_ref );						rs->sr_ref = NULL;					}					/* cleanup */					if ( references ) {						ber_memvfree( (void **)references );					}					if ( rs->sr_ctrls ) {						ldap_controls_free( rs->sr_ctrls );						rs->sr_ctrls = NULL;					}				} else if ( rc == LDAP_RES_SEARCH_RESULT ) {					char		buf[ SLAP_TEXT_BUFLEN ];					char		**references = NULL;					if ( candidates[ i ].sr_type == REP_INTERMEDIATE ) {						/* don't retry any more... */						candidates[ i ].sr_type = REP_RESULT;					}						/* NOTE: ignores response controls					 * (and intermediate response controls					 * as well, except for those with search					 * references); this may not be correct,					 * but if they're not ignored then					 * back-meta would need to merge them					 * consistently (think of pagedResults...)					 */					/* FIXME: response controls? */					rs->sr_err = ldap_parse_result( msc->msc_ld,						msg,						&candidates[ i ].sr_err,						(char **)&candidates[ i ].sr_matched,						NULL /* (char **)&candidates[ i ].sr_text */ ,						&references,						NULL /* &candidates[ i ].sr_ctrls (unused) */ ,						0 );					if ( rs->sr_err != LDAP_SUCCESS ) {						sres = slap_map_api2result( &candidates[ i ] );						candidates[ i ].sr_type = REP_RESULT;						ldap_msgfree( res );						res = NULL;						goto really_bad;					}					rs->sr_err = candidates[ i ].sr_err;					/* massage matchedDN if need be */					if ( candidates[ i ].sr_matched != NULL ) {						struct berval	match, mmatch;						ber_str2bv( candidates[ i ].sr_matched,							0, 0, &match );						candidates[ i ].sr_matched = NULL;						dc.ctx = "matchedDN";						dc.target = mi->mi_targets[ i ];						if ( !ldap_back_dn_massage( &dc, &match, &mmatch ) ) {							if ( mmatch.bv_val == match.bv_val ) {								candidates[ i ].sr_matched									= ch_strdup( mmatch.bv_val );							} else {								candidates[ i ].sr_matched = mmatch.bv_val;							}							candidate_match++;						} 						ldap_memfree( match.bv_val );					}					/* add references to array */					/* RFC 4511: referrals can only appear					 * if result code is LDAP_REFERRAL */					if ( references != NULL						&& references[ 0 ] != NULL						&& references[ 0 ][ 0 ] != '\0' )					{						if ( rs->sr_err != LDAP_REFERRAL ) {							Debug( LDAP_DEBUG_ANY,								"%s meta_back_search[%ld]: "								"got referrals with err=%d\n",								op->o_log_prefix,								i, rs->sr_err );						} else {							BerVarray	sr_ref;							int		cnt;								for ( cnt = 0; references[ cnt ]; cnt++ )								;								sr_ref = ch_calloc( sizeof( struct berval ), cnt + 1 );								for ( cnt = 0; references[ cnt ]; cnt++ ) {								ber_str2bv( references[ cnt ], 0, 1, &sr_ref[ cnt ] );							}							BER_BVZERO( &sr_ref[ cnt ] );								( void )ldap_back_referral_result_rewrite( &dc, sr_ref );												if ( rs->sr_v2ref == NULL ) {								rs->sr_v2ref = sr_ref;							} else {								for ( cnt = 0; !BER_BVISNULL( &sr_ref[ cnt ] ); cnt++ ) {									ber_bvarray_add( &rs->sr_v2ref, &sr_ref[ cnt ] );								}								ber_memfree( sr_ref );							}						}					} else if ( rs->sr_err == LDAP_REFERRAL ) {						Debug( LDAP_DEBUG_ANY,							"%s meta_back_search[%ld]: "							"got err=%d with null "							"or empty referrals\n",							op->o_log_prefix,							i, rs->sr_err );						rs->sr_err = LDAP_NO_SUCH_OBJECT;					}					/* cleanup */					ber_memvfree( (void **)references );						sres = slap_map_api2result( rs );						if ( StatslogTest( LDAP_DEBUG_TRACE | LDAP_DEBUG_ANY ) ) {						snprintf( buf, sizeof( buf ),							"%s meta_back_search[%ld] "							"match=\"%s\" err=%ld",							op->o_log_prefix, i,							candidates[ i ].sr_matched ? candidates[ i ].sr_matched : "",							(long) candidates[ i ].sr_err );						if ( candidates[ i ].sr_err == LDAP_SUCCESS ) {							Debug( LDAP_DEBUG_TRACE, "%s.\n", buf, 0, 0 );							} else {							Debug( LDAP_DEBUG_ANY, "%s (%s).\n",								buf, ldap_err2string( candidates[ i ].sr_err ), 0 );						}					}						switch ( sres ) {					case LDAP_NO_SUCH_OBJECT:						/* is_ok is touched any time a valid						 * (even intermediate) result is						 * returned; as a consequence, if						 * a candidate returns noSuchObject						 * it is ignored and the candidate						 * is simply demoted. */						if ( is_ok ) {							sres = LDAP_SUCCESS;						}						break;						case LDAP_SUCCESS:					case LDAP_REFERRAL:						is_ok++;						break;						case LDAP_SIZELIMIT_EXCEEDED:						/* if a target returned sizelimitExceeded						 * and the entry count is equal to the						 * proxy's limit, the target would have						 * returned more, and the error must be						 * propagated to the client; otherwise,						 * the target enforced a limit lower						 * than what requested by the proxy;						 * ignore it */						candidates[ i ].sr_err = rs->sr_err;						if ( rs->sr_nentries == op->ors_slimit							|| META_BACK_ONERR_STOP( mi ) )						{							savepriv = op->o_private;							op->o_private = (void *)i;							send_ldap_result( op, rs );							op->o_private = savepriv;							ldap_msgfree( res );							res = NULL;							goto finish;						}						break;						default:						candidates[ i ].sr_err = rs->sr_err;						if ( META_BACK_ONERR_STOP( mi ) ) {							savepriv = op->o_private;							op->o_private = (void *)i;							send_ldap_result( op, rs );							op->o_private = savepriv;							ldap_msgfree( res );							res = NULL;							goto finish;						}						break;					}						last = i;					rc = 0;						/*					 * When no candidates are left,					 * the outer cycle finishes					 */					candidates[ i ].sr_msgid = META_MSGID_IGNORE;					assert( ncandidates > 0 );					--ncandidates;					} else if ( rc == LDAP_RES_BIND ) {					meta_search_candidate_t	retcode;						retcode = meta_search_dobind_result( op, rs, &mc, i, candidates, msg );					if ( retcode == META_SEARCH_CANDIDATE ) {						candidates[ i ].sr_msgid = META_MSGID_IGNORE;						retcode = meta_back_search_start( op, rs, &dc, &mc, i, candidates );					}						switch ( retcode ) {					case META_SEARCH_CANDIDATE:						break;							/* means that failed but onerr == continue */					case META_SEARCH_NOT_CANDIDATE:					case META_SEARCH_ERR:						candidates[ i ].sr_msgid = META_MSGID_IGNORE;						assert( ncandidates > 0 );						--ncandidates;							candidates[ i ].sr_err = rs->sr_err;						if ( META_BACK_ONERR_STOP( mi ) ) {							savepriv = op->o_private;							op->o_private = (void *)i;							send_ldap_result( op, rs );							op->o_private = savepriv;							ldap_msgfree( res );							res = NULL;							goto finish;						}						goto free_message;						default:						assert( 0 );						break;					}					} else {					assert( 0 );					ldap_msgfree( res );					res = NULL;					goto really_bad;				}			}free_message:;			ldap_msgfree( res );			res = NULL;		}		/* check for abandon */		if ( op->o_abandon || LDAP_BACK_CONN_ABANDON( mc ) ) {			for ( i = 0; i < mi->mi_ntargets; i++ ) {				if ( candidates[ i ].sr_msgid >= 0 ) {					if ( META_IS_BINDING( &candidates[ i ] ) ) {						ldap_pvt_thread_mutex_lock( &mi->mi_conninfo.lai_mutex );						if ( LDAP_BACK_CONN_BINDING( &mc->mc_conns[ i ] ) ) {							/* if still binding, destroy */#ifdef DEBUG_205							char buf[ SLAP_TEXT_BUFLEN ];							snprintf( buf, sizeof( buf), "%s meta_back_search(abandon) "								"ldap_unbind_ext[%ld] mc=%p ld=%p",								op->o_log_prefix, i, (void *)mc,								(void *)mc->mc_conns[i].msc_ld );							Debug( LDAP_DEBUG_ANY, "### %s\n", buf, 0, 0 );#endif /* DEBUG_205 */							meta_clear_one_candidate( op, mc, i );						}						ldap_pvt_thread_mutex_unlock( &mi->mi_conninfo.lai_mutex );						META_BINDING_CLEAR( &candidates[ i ] );											} else {						(void)meta_back_cancel( mc, op, rs,							candidates[ i ].sr_msgid, i,							LDAP_BACK_DONTSEND );					}					candidates[ i ].sr_msgid = META_MSGID_IGNORE;					assert( ncandidates > 0 );					--ncandidates;				}			}			if ( op->o_abandon ) {				rc = SLAPD_ABANDON;			}			/* let send_ldap_result play cleanup handlers (ITS#4645) */			break;		}		/* if no entry was found during this loop,		 * set a minimal timeout */		if ( ncandidates > 0 && gotit == 0 ) {			if ( save_tv.tv_sec == 0 && save_tv.tv_usec == 0 ) {				save_tv.tv_usec = LDAP_BACK_RESULT_UTIMEOUT/initial_candidates;				/* arbitrarily limit to something between 1 and 2 minutes */			} else if ( ( stoptime == -1 && save_tv.tv_sec < 60 )				|| save_tv.tv_sec < ( stoptime - slap_get_time() ) / ( 2 * ncandidates ) )			{				/* double the timeout */				lutil_timermul( &save_tv, 2, &save_tv );			}			if ( alreadybound == 0 ) {				tv = save_tv;				(void)select( 0, NULL, NULL, NULL, &tv );			} else {				ldap_pvt_thread_yield();			}		}	}	if ( rc == -1 ) {		/*		 * FIXME: need a better strategy to handle errors		 */		if ( mc ) {			rc = meta_back_op_result( mc, op, rs, META_TARGET_NONE,				-1, stoptime != -1 ? (stoptime - slap_get_time()) : 0,				LDAP_BACK_SENDERR );		} else {			rc = rs->sr_err;		}		goto finish;	}	/*	 * Rewrite the matched portion of the search base, if required	 * 	 * FIXME: only the last one gets caught!	 */	savepriv = op->o_private;	op->o_private = (void *)(long)mi->mi_ntargets;	if ( candidate_match > 0 ) {		struct berval	pmatched = BER_BVNULL;		/* we use the first one */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -