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

📄 search.c

📁 ldap服务器源码
💻 C
📖 第 1 页 / 共 3 页
字号:
			}			if (e) {				/* safe default */				rs->sr_attrs = op->oq_search.rs_attrs;				rs->sr_operational_attrs = NULL;				rs->sr_ctrls = NULL;				rs->sr_flags = 0;				rs->sr_err = LDAP_SUCCESS;				rs->sr_err = send_search_entry( op, rs );				switch ( rs->sr_err ) {				case LDAP_SUCCESS:	/* entry sent ok */					break;				default:		/* entry not sent */					break;				case LDAP_UNAVAILABLE:				case LDAP_SIZELIMIT_EXCEEDED:#ifdef SLAP_ZONE_ALLOC					slap_zn_runlock(bdb->bi_cache.c_zctx, e);#endif					bdb_cache_return_entry_r(bdb->bi_dbenv,						&bdb->bi_cache, e, &lock);					e = NULL;					rs->sr_entry = NULL;					if ( rs->sr_err == LDAP_SIZELIMIT_EXCEEDED ) {						rs->sr_ref = rs->sr_v2ref;						send_ldap_result( op, rs );						rs->sr_err = LDAP_SUCCESS;					} else {						rs->sr_err = LDAP_OTHER;					}					goto done;				}			}		} else {			Debug( LDAP_DEBUG_TRACE,				LDAP_XSTRING(bdb_search)				": %ld does not match filter\n",				(long) id, 0, 0 );		}loop_continue:		if( e != NULL ) {			/* free reader lock */#ifdef SLAP_ZONE_ALLOC			slap_zn_runlock(bdb->bi_cache.c_zctx, e);#endif			bdb_cache_return_entry_r( bdb->bi_dbenv,				&bdb->bi_cache, e , &lock );			e = NULL;			rs->sr_entry = NULL;		}	}nochange:	rs->sr_ctrls = NULL;	rs->sr_ref = rs->sr_v2ref;	rs->sr_err = (rs->sr_v2ref == NULL) ? LDAP_SUCCESS : LDAP_REFERRAL;	rs->sr_rspoid = NULL;	if ( get_pagedresults(op) > SLAP_CONTROL_IGNORED ) {		send_paged_response( op, rs, NULL, 0 );	} else {		send_ldap_result( op, rs );	}	rs->sr_err = LDAP_SUCCESS;done:	if ( !opinfo )		LOCK_ID_FREE( bdb->bi_dbenv, locker );	if( rs->sr_v2ref ) {		ber_bvarray_free( rs->sr_v2ref );		rs->sr_v2ref = NULL;	}	if( realbase.bv_val ) ch_free( realbase.bv_val );	return rs->sr_err;}static int base_candidate(	BackendDB	*be,	Entry	*e,	ID		*ids ){	Debug(LDAP_DEBUG_ARGS, "base_candidates: base: \"%s\" (0x%08lx)\n",		e->e_nname.bv_val, (long) e->e_id, 0);	ids[0] = 1;	ids[1] = e->e_id;	return 0;}/* Look for "objectClass Present" in this filter. * Also count depth of filter tree while we're at it. */static int oc_filter(	Filter *f,	int cur,	int *max ){	int rc = 0;	assert( f != NULL );	if( cur > *max ) *max = cur;	switch( f->f_choice ) {	case LDAP_FILTER_PRESENT:		if (f->f_desc == slap_schema.si_ad_objectClass) {			rc = 1;		}		break;	case LDAP_FILTER_AND:	case LDAP_FILTER_OR:		cur++;		for ( f=f->f_and; f; f=f->f_next ) {			(void) oc_filter(f, cur, max);		}		break;	default:		break;	}	return rc;}static void search_stack_free( void *key, void *data ){	ber_memfree_x(data, NULL);}static void *search_stack( Operation *op ){	struct bdb_info *bdb = (struct bdb_info *) op->o_bd->be_private;	void *ret = NULL;	if ( op->o_threadctx ) {		ldap_pvt_thread_pool_getkey( op->o_threadctx, search_stack,			&ret, NULL );	} else {		ret = bdb->bi_search_stack;	}	if ( !ret ) {		ret = ch_malloc( bdb->bi_search_stack_depth * BDB_IDL_UM_SIZE			* sizeof( ID ) );		if ( op->o_threadctx ) {			ldap_pvt_thread_pool_setkey( op->o_threadctx, search_stack,				ret, search_stack_free );		} else {			bdb->bi_search_stack = ret;		}	}	return ret;}static int search_candidates(	Operation *op,	SlapReply *rs,	Entry *e,	u_int32_t locker,	ID	*ids,	ID	*scopes ){	struct bdb_info *bdb = (struct bdb_info *) op->o_bd->be_private;	int rc, depth = 1;	Filter		f, rf, xf, nf;	ID		*stack;#ifdef LDAP_COMP_MATCH	AttributeAssertion aa_ref = { NULL, BER_BVNULL, NULL };#else	AttributeAssertion aa_ref = { NULL, BER_BVNULL };#endif	Filter	sf;#ifdef LDAP_COMP_MATCH	AttributeAssertion aa_subentry = { NULL, BER_BVNULL, NULL };#else	AttributeAssertion aa_subentry = { NULL, BER_BVNULL };#endif	/*	 * This routine takes as input a filter (user-filter)	 * and rewrites it as follows:	 *	(&(scope=DN)[(objectClass=subentry)]	 *		(|[(objectClass=referral)(objectClass=alias)](user-filter))	 */	Debug(LDAP_DEBUG_TRACE,		"search_candidates: base=\"%s\" (0x%08lx) scope=%d\n",		e->e_nname.bv_val, (long) e->e_id, op->oq_search.rs_scope );	xf.f_or = op->oq_search.rs_filter;	xf.f_choice = LDAP_FILTER_OR;	xf.f_next = NULL;	/* If the user's filter uses objectClass=*,	 * these clauses are redundant.	 */	if (!oc_filter(op->oq_search.rs_filter, 1, &depth)		&& !get_subentries_visibility(op)) {		if( !get_manageDSAit(op) && !get_domainScope(op) ) {			/* match referral objects */			struct berval bv_ref = BER_BVC( "referral" );			rf.f_choice = LDAP_FILTER_EQUALITY;			rf.f_ava = &aa_ref;			rf.f_av_desc = slap_schema.si_ad_objectClass;			rf.f_av_value = bv_ref;			rf.f_next = xf.f_or;			xf.f_or = &rf;			depth++;		}	}	f.f_next = NULL;	f.f_choice = LDAP_FILTER_AND;	f.f_and = &nf;	/* Dummy; we compute scope separately now */	nf.f_choice = SLAPD_FILTER_COMPUTED;	nf.f_result = LDAP_SUCCESS;	nf.f_next = ( xf.f_or == op->oq_search.rs_filter )		? op->oq_search.rs_filter : &xf ;	/* Filter depth increased again, adding dummy clause */	depth++;	if( get_subentries_visibility( op ) ) {		struct berval bv_subentry = BER_BVC( "subentry" );		sf.f_choice = LDAP_FILTER_EQUALITY;		sf.f_ava = &aa_subentry;		sf.f_av_desc = slap_schema.si_ad_objectClass;		sf.f_av_value = bv_subentry;		sf.f_next = nf.f_next;		nf.f_next = &sf;	}	/* Allocate IDL stack, plus 1 more for former tmp */	if ( depth+1 > bdb->bi_search_stack_depth ) {		stack = ch_malloc( (depth + 1) * BDB_IDL_UM_SIZE * sizeof( ID ) );	} else {		stack = search_stack( op );	}	if( op->ors_deref & LDAP_DEREF_SEARCHING ) {		rc = search_aliases( op, rs, e, locker, ids, scopes, stack );	} else {		rc = bdb_dn2idl( op, e, ids, stack );	}	if ( rc == LDAP_SUCCESS ) {		rc = bdb_filter_candidates( op, &f, ids,			stack, stack+BDB_IDL_UM_SIZE );	}	if ( depth+1 > bdb->bi_search_stack_depth ) {		ch_free( stack );	}	if( rc ) {		Debug(LDAP_DEBUG_TRACE,			"bdb_search_candidates: failed (rc=%d)\n",			rc, NULL, NULL );	} else {		Debug(LDAP_DEBUG_TRACE,			"bdb_search_candidates: id=%ld first=%ld last=%ld\n",			(long) ids[0],			(long) BDB_IDL_FIRST(ids),			(long) BDB_IDL_LAST(ids) );	}	return rc;}static intparse_paged_cookie( Operation *op, SlapReply *rs ){	LDAPControl	**c;	int		rc = LDAP_SUCCESS;	ber_tag_t	tag;	ber_int_t	size;	BerElement	*ber;	struct berval	cookie = BER_BVNULL;	PagedResultsState *ps = op->o_pagedresults_state;	/* this function must be invoked only if the pagedResults	 * control has been detected, parsed and partially checked	 * by the frontend */	assert( get_pagedresults( op ) > SLAP_CONTROL_IGNORED );	/* look for the appropriate ctrl structure */	for ( c = op->o_ctrls; c[0] != NULL; c++ ) {		if ( strcmp( c[0]->ldctl_oid, LDAP_CONTROL_PAGEDRESULTS ) == 0 )		{			break;		}	}	if ( c[0] == NULL ) {		rs->sr_text = "missing pagedResults control";		return LDAP_PROTOCOL_ERROR;	}	/* Tested by frontend */	assert( c[0]->ldctl_value.bv_len > 0 );	/* Parse the control value	 *	realSearchControlValue ::= SEQUENCE {	 *		size	INTEGER (0..maxInt),	 *				-- requested page size from client	 *				-- result set size estimate from server	 *		cookie	OCTET STRING	 * }	 */	ber = ber_init( &c[0]->ldctl_value );	if ( ber == NULL ) {		rs->sr_text = "internal error";		return LDAP_OTHER;	}	tag = ber_scanf( ber, "{im}", &size, &cookie );	/* Tested by frontend */	assert( tag != LBER_ERROR );	assert( size >= 0 );	/* cookie decoding/checks deferred to backend... */	if ( cookie.bv_len ) {		PagedResultsCookie reqcookie;		if( cookie.bv_len != sizeof( reqcookie ) ) {			/* bad cookie */			rs->sr_text = "paged results cookie is invalid";			rc = LDAP_PROTOCOL_ERROR;			goto done;		}		AC_MEMCPY( &reqcookie, cookie.bv_val, sizeof( reqcookie ));		if ( reqcookie > ps->ps_cookie ) {			/* bad cookie */			rs->sr_text = "paged results cookie is invalid";			rc = LDAP_PROTOCOL_ERROR;			goto done;		} else if ( reqcookie < ps->ps_cookie ) {			rs->sr_text = "paged results cookie is invalid or old";			rc = LDAP_UNWILLING_TO_PERFORM;			goto done;		}	} else {		/* Initial request.  Initialize state. */#if 0		if ( op->o_conn->c_pagedresults_state.ps_cookie != 0 ) {			/* There's another pagedResults control on the			 * same connection; reject new pagedResults controls 			 * (allowed by RFC2696) */			rs->sr_text = "paged results cookie unavailable; try later";			rc = LDAP_UNWILLING_TO_PERFORM;			goto done;		}#endif		ps->ps_cookie = 0;		ps->ps_count = 0;	}done:;	(void)ber_free( ber, 1 );	return rc;}static voidsend_paged_response( 	Operation	*op,	SlapReply	*rs,	ID		*lastid,	int		tentries ){	LDAPControl	ctrl, *ctrls[2];	BerElementBuffer berbuf;	BerElement	*ber = (BerElement *)&berbuf;	PagedResultsCookie respcookie;	struct berval cookie;	Debug(LDAP_DEBUG_ARGS,		"send_paged_response: lastid=0x%08lx nentries=%d\n", 		lastid ? *lastid : 0, rs->sr_nentries, NULL );	BER_BVZERO( &ctrl.ldctl_value );	ctrls[0] = &ctrl;	ctrls[1] = NULL;	ber_init2( ber, NULL, LBER_USE_DER );	if ( lastid ) {		respcookie = ( PagedResultsCookie )(*lastid);		cookie.bv_len = sizeof( respcookie );		cookie.bv_val = (char *)&respcookie;	} else {		respcookie = ( PagedResultsCookie )0;		BER_BVSTR( &cookie, "" );	}	op->o_conn->c_pagedresults_state.ps_cookie = respcookie;	op->o_conn->c_pagedresults_state.ps_count =		((PagedResultsState *)op->o_pagedresults_state)->ps_count +		rs->sr_nentries;	/* return size of 0 -- no estimate */	ber_printf( ber, "{iO}", 0, &cookie ); 	if ( ber_flatten2( ber, &ctrls[0]->ldctl_value, 0 ) == -1 ) {		goto done;	}	ctrls[0]->ldctl_oid = LDAP_CONTROL_PAGEDRESULTS;	ctrls[0]->ldctl_iscritical = 0;	rs->sr_ctrls = ctrls;	rs->sr_err = LDAP_SUCCESS;	send_ldap_result( op, rs );	rs->sr_ctrls = NULL;done:	(void) ber_free_buf( ber );}

⌨️ 快捷键说明

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