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

📄 search.c

📁 ldap服务器源码
💻 C
📖 第 1 页 / 共 3 页
字号:
			} else#endif /* SLAP_ACL_HONOR_DISCLOSE */			{				ber_dupbv( &matched_dn, &matched->e_name );				erefs = is_entry_referral( matched )					? get_entry_referrals( op, matched )					: NULL;				if ( rs->sr_err == DB_NOTFOUND )					rs->sr_err = LDAP_REFERRAL;				rs->sr_matched = matched_dn.bv_val;			}#ifdef SLAP_ZONE_ALLOC			slap_zn_runlock(bdb->bi_cache.c_zctx, matched);#endif			bdb_cache_return_entry_r (bdb->bi_dbenv, &bdb->bi_cache,				matched, &lock);			matched = NULL;			if ( erefs ) {				rs->sr_ref = referral_rewrite( erefs, &matched_dn,					&op->o_req_dn, op->oq_search.rs_scope );				ber_bvarray_free( erefs );			}		} else {#ifdef SLAP_ZONE_ALLOC			slap_zn_runlock(bdb->bi_cache.c_zctx, matched);#endif			rs->sr_ref = referral_rewrite( default_referral,				NULL, &op->o_req_dn, op->oq_search.rs_scope );			rs->sr_err = rs->sr_ref != NULL ? LDAP_REFERRAL : LDAP_NO_SUCH_OBJECT;		}		send_ldap_result( op, rs );		if ( !opinfo )			LOCK_ID_FREE (bdb->bi_dbenv, locker );		if ( rs->sr_ref ) {			ber_bvarray_free( rs->sr_ref );			rs->sr_ref = NULL;		}		if ( !BER_BVISNULL( &matched_dn ) ) {			ber_memfree( matched_dn.bv_val );			rs->sr_matched = NULL;		}		return rs->sr_err;	}#ifdef SLAP_ACL_HONOR_DISCLOSE	/* NOTE: __NEW__ "search" access is required	 * on searchBase object */	if ( ! access_allowed_mask( op, e, slap_schema.si_ad_entry,				NULL, ACL_SEARCH, NULL, &mask ) )	{		if ( !ACL_GRANT( mask, ACL_DISCLOSE ) ) {			rs->sr_err = LDAP_NO_SUCH_OBJECT;		} else {			rs->sr_err = LDAP_INSUFFICIENT_ACCESS;		}#ifdef SLAP_ZONE_ALLOC		slap_zn_runlock(bdb->bi_cache.c_zctx, e);#endif		if ( e != &e_root ) {			bdb_cache_return_entry_r(bdb->bi_dbenv, &bdb->bi_cache, e, &lock);		}		send_ldap_result( op, rs );		return rs->sr_err;	}#endif /* SLAP_ACL_HONOR_DISCLOSE */	if ( !manageDSAit && e != &e_root && is_entry_referral( e ) ) {		/* entry is a referral, don't allow add */		struct berval matched_dn = BER_BVNULL;		BerVarray erefs = NULL;				ber_dupbv( &matched_dn, &e->e_name );		erefs = get_entry_referrals( op, e );		rs->sr_err = LDAP_REFERRAL;#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;		if ( erefs ) {			rs->sr_ref = referral_rewrite( erefs, &matched_dn,				&op->o_req_dn, op->oq_search.rs_scope );			ber_bvarray_free( erefs );			if ( !rs->sr_ref ) {				rs->sr_text = "bad_referral object";			}		}		Debug( LDAP_DEBUG_TRACE,			LDAP_XSTRING(bdb_search) ": entry is referral\n",			0, 0, 0 );		rs->sr_matched = matched_dn.bv_val;		send_ldap_result( op, rs );		if ( !opinfo ) {			LOCK_ID_FREE (bdb->bi_dbenv, locker );		}		ber_bvarray_free( rs->sr_ref );		rs->sr_ref = NULL;		ber_memfree( matched_dn.bv_val );		rs->sr_matched = NULL;		return 1;	}	if ( get_assert( op ) &&		( test_filter( op, e, get_assertion( op )) != LDAP_COMPARE_TRUE ))	{		rs->sr_err = LDAP_ASSERTION_FAILED;#ifdef SLAP_ZONE_ALLOC		slap_zn_runlock(bdb->bi_cache.c_zctx, e);#endif		if ( e != &e_root ) {			bdb_cache_return_entry_r(bdb->bi_dbenv, &bdb->bi_cache, e, &lock);		}		send_ldap_result( op, rs );		return 1;	}	/* compute it anyway; root does not use it */	stoptime = op->o_time + op->ors_tlimit;	/* need normalized dn below */	ber_dupbv( &realbase, &e->e_nname );	/* Copy info to base, must free entry before accessing the database	 * in search_candidates, to avoid deadlocks.	 */	base.e_private = e->e_private;	base.e_nname = realbase;	base.e_id = e->e_id;#ifdef SLAP_ZONE_ALLOC	slap_zn_runlock(bdb->bi_cache.c_zctx, e);#endif	if ( e != &e_root ) {		bdb_cache_return_entry_r(bdb->bi_dbenv, &bdb->bi_cache, e, &lock);	}	e = NULL;	/* select candidates */	if ( op->oq_search.rs_scope == LDAP_SCOPE_BASE ) {		rs->sr_err = base_candidate( op->o_bd, &base, candidates );	} else {		BDB_IDL_ZERO( candidates );		BDB_IDL_ZERO( scopes );		rs->sr_err = search_candidates( op, rs, &base,			locker, candidates, scopes );	}	/* start cursor at beginning of candidates.	 */	cursor = 0;	if ( candidates[0] == 0 ) {		Debug( LDAP_DEBUG_TRACE,			LDAP_XSTRING(bdb_search) ": no candidates\n",			0, 0, 0 );		goto nochange;	}	/* if not root and candidates exceed to-be-checked entries, abort */	if ( op->ors_limit	/* isroot == FALSE */ &&		op->ors_limit->lms_s_unchecked != -1 &&		BDB_IDL_N(candidates) > (unsigned) op->ors_limit->lms_s_unchecked )	{		rs->sr_err = LDAP_ADMINLIMIT_EXCEEDED;		send_ldap_result( op, rs );		rs->sr_err = LDAP_SUCCESS;		goto done;	}	if ( op->ors_limit == NULL	/* isroot == TRUE */ ||		!op->ors_limit->lms_s_pr_hide )	{		tentries = BDB_IDL_N(candidates);	}	if ( get_pagedresults( op ) > SLAP_CONTROL_IGNORED ) {		PagedResultsState *ps = op->o_pagedresults_state;		/* deferred cookie parsing */		rs->sr_err = parse_paged_cookie( op, rs );		if ( rs->sr_err != LDAP_SUCCESS ) {			send_ldap_result( op, rs );			goto done;		}		if ( (ID)( ps->ps_cookie ) == 0 ) {			id = bdb_idl_first( candidates, &cursor );		} else {			if ( ps->ps_size == 0 ) {				rs->sr_err = LDAP_SUCCESS;				rs->sr_text = "search abandoned by pagedResult size=0";				send_ldap_result( op, rs );				goto done;			}			for ( id = bdb_idl_first( candidates, &cursor );				id != NOID &&					id <= (ID)( ps->ps_cookie );				id = bdb_idl_next( candidates, &cursor ) )			{				/* empty */;			}		}		if ( cursor == NOID ) {			Debug( LDAP_DEBUG_TRACE, 				LDAP_XSTRING(bdb_search)				": no paged results candidates\n",				0, 0, 0 );			send_paged_response( op, rs, &lastid, 0 );			rs->sr_err = LDAP_OTHER;			goto done;		}		goto loop_begin;	}	for ( id = bdb_idl_first( candidates, &cursor );		  id != NOID ; id = bdb_idl_next( candidates, &cursor ) )	{		int scopeok;loop_begin:		/* check for abandon */		if ( op->o_abandon ) {			rs->sr_err = SLAPD_ABANDON;			goto done;		}		/* check time limit */		if ( op->ors_tlimit != SLAP_NO_LIMIT				&& slap_get_time() > stoptime )		{			rs->sr_err = LDAP_TIMELIMIT_EXCEEDED;			rs->sr_ref = rs->sr_v2ref;			send_ldap_result( op, rs );			rs->sr_err = LDAP_SUCCESS;			goto done;		}fetch_entry_retry:			/* get the entry with reader lock */			ei = NULL;			rs->sr_err = bdb_cache_find_id( op, ltid,				id, &ei, 0, locker, &lock );			if (rs->sr_err == LDAP_BUSY) {				rs->sr_text = "ldap server busy";				send_ldap_result( op, rs );				goto done;			} else if ( rs->sr_err == DB_LOCK_DEADLOCK				|| rs->sr_err == DB_LOCK_NOTGRANTED )			{				goto fetch_entry_retry;			}			if ( ei && rs->sr_err == LDAP_SUCCESS ) {				e = ei->bei_e;			} else {				e = NULL;			}			if ( e == NULL ) {				if( !BDB_IDL_IS_RANGE(candidates) ) {					/* only complain for non-range IDLs */					Debug( LDAP_DEBUG_TRACE,						LDAP_XSTRING(bdb_search)						": candidate %ld not found\n",						(long) id, 0, 0 );				}				goto loop_continue;			}		rs->sr_entry = e;		if ( is_entry_subentry( e ) ) {			if( op->oq_search.rs_scope != LDAP_SCOPE_BASE ) {				if(!get_subentries_visibility( op )) {					/* only subentries are visible */					goto loop_continue;				}			} else if ( get_subentries( op ) &&				!get_subentries_visibility( op ))			{				/* only subentries are visible */				goto loop_continue;			}		} else if ( get_subentries_visibility( op )) {			/* only subentries are visible */			goto loop_continue;		}		/* Does this candidate actually satisfy the search scope?		 *		 * Note that we don't lock access to the bei_parent pointer.		 * Since only leaf nodes can be deleted, the parent of any		 * node will always be a valid node. Also since we have		 * a Read lock on the data, it cannot be renamed out of the		 * scope while we are looking at it, and unless we're using		 * BDB_HIER, its parents cannot be moved either.		 */		scopeok = 0;		switch( op->ors_scope ) {		case LDAP_SCOPE_BASE:			/* This is always true, yes? */			if ( id == base.e_id ) scopeok = 1;			break;		case LDAP_SCOPE_ONELEVEL:			if ( ei->bei_parent->bei_id == base.e_id ) scopeok = 1;			break;#ifdef LDAP_SCOPE_CHILDREN		case LDAP_SCOPE_CHILDREN:			if ( id == base.e_id ) break;			/* Fall-thru */#endif		case LDAP_SCOPE_SUBTREE: {			EntryInfo *tmp;			for ( tmp = BEI(e); tmp; tmp = tmp->bei_parent ) {				if ( tmp->bei_id == base.e_id ) {					scopeok = 1;					break;				}			}			} break;		}		/* aliases were already dereferenced in candidate list */		if ( op->ors_deref & LDAP_DEREF_SEARCHING ) {			/* but if the search base is an alias, and we didn't			 * deref it when finding, return it.			 */			if ( is_entry_alias(e) &&				((op->ors_deref & LDAP_DEREF_FINDING) ||					!bvmatch(&e->e_nname, &op->o_req_ndn)))			{				goto loop_continue;			}			/* scopes is only non-empty for onelevel or subtree */			if ( !scopeok && BDB_IDL_N(scopes) ) {				unsigned x;				if ( op->ors_scope == LDAP_SCOPE_ONELEVEL ) {					x = bdb_idl_search( scopes, e->e_id );					if ( scopes[x] == e->e_id ) scopeok = 1;				} else {					/* subtree, walk up the tree */					EntryInfo *tmp = BEI(e);					for (;tmp->bei_parent; tmp=tmp->bei_parent) {						x = bdb_idl_search( scopes, tmp->bei_id );						if ( scopes[x] == tmp->bei_id ) {							scopeok = 1;							break;						}					}				}			}		}		/* Not in scope, ignore it */		if ( !scopeok )		{			Debug( LDAP_DEBUG_TRACE,				LDAP_XSTRING(bdb_search)				": %ld scope not okay\n",				(long) id, 0, 0 );			goto loop_continue;		}		/*		 * if it's a referral, add it to the list of referrals. only do		 * this for non-base searches, and don't check the filter		 * explicitly here since it's only a candidate anyway.		 */		if ( !manageDSAit && op->oq_search.rs_scope != LDAP_SCOPE_BASE			&& is_entry_referral( e ) )		{			BerVarray erefs = get_entry_referrals( op, e );			rs->sr_ref = referral_rewrite( erefs, &e->e_name, NULL,				op->oq_search.rs_scope == LDAP_SCOPE_ONELEVEL					? LDAP_SCOPE_BASE : LDAP_SCOPE_SUBTREE );			send_search_reference( op, rs );			ber_bvarray_free( rs->sr_ref );			ber_bvarray_free( erefs );			rs->sr_ref = NULL;			goto loop_continue;		}		if ( !manageDSAit && is_entry_glue( e )) {			goto loop_continue;		}		/* if it matches the filter and scope, send it */		rs->sr_err = test_filter( op, rs->sr_entry, op->oq_search.rs_filter );		if ( rs->sr_err == LDAP_COMPARE_TRUE ) {			/* check size limit */			if ( get_pagedresults(op) > SLAP_CONTROL_IGNORED ) {				if ( rs->sr_nentries >= ((PagedResultsState *)op->o_pagedresults_state)->ps_size ) {#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;					send_paged_response( op, rs, &lastid, tentries );					goto done;				}				lastid = id;

⌨️ 快捷键说明

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