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

📄 search.c

📁 OpenLdap是LDAP的开源项目
💻 C
📖 第 1 页 / 共 5 页
字号:
	bsi.bsi_e = NULL;	bsi.bsi_n_candidates =		( op->ors_limit == NULL	/* isroot == TRUE */ ? -2 : 		( op->ors_limit->lms_s_unchecked == -1 ? -2 :		( op->ors_limit->lms_s_unchecked ) ) );	switch ( bsi.bsi_scope ) {	case LDAP_SCOPE_BASE:	case BACKSQL_SCOPE_BASE_LIKE:		/*		 * probably already found...		 */		bsi.bsi_id_list = &bsi.bsi_base_id;		bsi.bsi_id_listtail = &bsi.bsi_base_id.eid_next;		break;	case LDAP_SCOPE_SUBTREE:		/*		 * if baseObject is defined, and if it is the root 		 * of the search, add it to the candidate list		 */		if ( bi->sql_baseObject && BACKSQL_IS_BASEOBJECT_ID( &bsi.bsi_base_id.eid_id ) )		{			bsi.bsi_id_list = &bsi.bsi_base_id;			bsi.bsi_id_listtail = &bsi.bsi_base_id.eid_next;		}		/* FALLTHRU */	default:		/*		 * for each objectclass we try to construct query which gets IDs		 * of entries matching LDAP query filter and scope (or at least 		 * candidates), and get the IDs		 */		avl_apply( bi->sql_oc_by_oc, backsql_oc_get_candidates,				&bsi, BACKSQL_AVL_STOP, AVL_INORDER );		/* check for abandon */		if ( op->o_abandon ) {			eid = bsi.bsi_id_list;			rs->sr_err = SLAPD_ABANDON;			goto send_results;		}	}	if ( op->ors_limit != NULL	/* isroot == FALSE */			&& op->ors_limit->lms_s_unchecked != -1			&& bsi.bsi_n_candidates == -1 )	{		rs->sr_err = LDAP_ADMINLIMIT_EXCEEDED;		send_ldap_result( op, rs );		goto done;	}	/*	 * now we load candidate entries (only those attributes 	 * mentioned in attrs and filter), test it against full filter 	 * and then send to client; don't free entry_id if baseObject...	 */	for ( eid = bsi.bsi_id_list;			eid != NULL; 			eid = backsql_free_entryID( op,				eid, eid == &bsi.bsi_base_id ? 0 : 1 ) )	{		int		rc;		Attribute	*a_hasSubordinate = NULL,				*a_entryUUID = NULL,				*a_entryCSN = NULL,				**ap = NULL;		Entry		*e = NULL;		/* check for abandon */		if ( op->o_abandon ) {			rs->sr_err = SLAPD_ABANDON;			goto send_results;		}		/* check time limit */		if ( op->ors_tlimit != SLAP_NO_LIMIT				&& slap_get_time() > stoptime )		{			rs->sr_err = LDAP_TIMELIMIT_EXCEEDED;			rs->sr_ctrls = NULL;			rs->sr_ref = rs->sr_v2ref;			goto send_results;		}#ifdef BACKSQL_ARBITRARY_KEY		Debug(LDAP_DEBUG_TRACE, "backsql_search(): loading data "			"for entry id=%s, oc_id=%ld, keyval=%s\n",			eid->eid_id.bv_val, eid->eid_oc_id,			eid->eid_keyval.bv_val );#else /* ! BACKSQL_ARBITRARY_KEY */		Debug(LDAP_DEBUG_TRACE, "backsql_search(): loading data "			"for entry id=%ld, oc_id=%ld, keyval=%ld\n",			eid->eid_id, eid->eid_oc_id, eid->eid_keyval );#endif /* ! BACKSQL_ARBITRARY_KEY */		/* check scope */		switch ( op->ors_scope ) {		case LDAP_SCOPE_BASE:		case BACKSQL_SCOPE_BASE_LIKE:			if ( !dn_match( &eid->eid_ndn, &op->o_req_ndn ) ) {				goto next_entry2;			}			break;		case LDAP_SCOPE_ONE:		{			struct berval	rdn = eid->eid_ndn;			rdn.bv_len -= op->o_req_ndn.bv_len + STRLENOF( "," );			if ( !dnIsOneLevelRDN( &rdn ) ) {				goto next_entry2;			}			/* fall thru */		}		case LDAP_SCOPE_SUBORDINATE:			/* discard the baseObject entry */			if ( dn_match( &eid->eid_ndn, &op->o_req_ndn ) ) {				goto next_entry2;			}			/* FALLTHRU */		case LDAP_SCOPE_SUBTREE:			/* FIXME: this should never fail... */			if ( !dnIsSuffix( &eid->eid_ndn, &op->o_req_ndn ) ) {				goto next_entry2;			}			break;		}		if ( BACKSQL_IS_BASEOBJECT_ID( &eid->eid_id ) ) {			/* don't recollect baseObject... */			e = bi->sql_baseObject;		} else if ( eid == &bsi.bsi_base_id ) {			/* don't recollect searchBase object... */			e = &base_entry;		} else {			bsi.bsi_e = &user_entry;			rc = backsql_id2entry( &bsi, eid );			if ( rc != LDAP_SUCCESS ) {				Debug( LDAP_DEBUG_TRACE, "backsql_search(): "					"error %d in backsql_id2entry() "					"- skipping\n", rc, 0, 0 );				continue;			}			e = &user_entry;		}		if ( !manageDSAit &&				op->ors_scope != LDAP_SCOPE_BASE &&				op->ors_scope != BACKSQL_SCOPE_BASE_LIKE &&				is_entry_referral( e ) )		{			BerVarray refs;			refs = get_entry_referrals( op, e );			if ( !refs ) {				backsql_srch_info	bsi2 = { 0 };				Entry			user_entry2 = { 0 };				/* retry with the full entry... */				bsi2.bsi_e = &user_entry2;				rc = backsql_init_search( &bsi2,						&e->e_nname,						LDAP_SCOPE_BASE, 						(time_t)(-1), NULL,						dbh, op, rs, NULL,						BACKSQL_ISF_GET_ENTRY );				if ( rc == LDAP_SUCCESS ) {					if ( is_entry_referral( &user_entry2 ) )					{						refs = get_entry_referrals( op,								&user_entry2 );					} else {						rs->sr_err = LDAP_OTHER;					}					backsql_entry_clean( op, &user_entry2 );				}				if ( bsi2.bsi_attrs != NULL ) {					op->o_tmpfree( bsi2.bsi_attrs,							op->o_tmpmemctx );				}			}			if ( refs ) {				rs->sr_ref = referral_rewrite( refs,						&e->e_name,						&op->o_req_dn,						op->ors_scope );				ber_bvarray_free( refs );			}			if ( rs->sr_ref ) {				rs->sr_err = LDAP_REFERRAL;			} else {				rs->sr_text = "bad referral object";			}			rs->sr_entry = e;			rs->sr_matched = user_entry.e_name.bv_val;			send_search_reference( op, rs );			ber_bvarray_free( rs->sr_ref );			rs->sr_ref = NULL;			rs->sr_matched = NULL;			rs->sr_entry = NULL;			goto next_entry;		}		/*		 * We use this flag since we need to parse the filter		 * anyway; we should have used the frontend API function		 * filter_has_subordinates()		 */		if ( bsi.bsi_flags & BSQL_SF_FILTER_HASSUBORDINATE ) {			rc = backsql_has_children( op, dbh, &e->e_nname );			switch ( rc ) {			case LDAP_COMPARE_TRUE:			case LDAP_COMPARE_FALSE:				a_hasSubordinate = slap_operational_hasSubordinate( rc == LDAP_COMPARE_TRUE );				if ( a_hasSubordinate != NULL ) {					for ( ap = &user_entry.e_attrs; 							*ap; 							ap = &(*ap)->a_next );					*ap = a_hasSubordinate;				}				rc = 0;				break;			default:				Debug(LDAP_DEBUG_TRACE, 					"backsql_search(): "					"has_children failed( %d)\n", 					rc, 0, 0 );				rc = 1;				goto next_entry;			}		}		if ( bsi.bsi_flags & BSQL_SF_FILTER_ENTRYUUID ) {			a_entryUUID = backsql_operational_entryUUID( bi, eid );			if ( a_entryUUID != NULL ) {				if ( ap == NULL ) {					ap = &user_entry.e_attrs;				}				for ( ; *ap; ap = &(*ap)->a_next );				*ap = a_entryUUID;			}		}#ifdef BACKSQL_SYNCPROV		if ( bsi.bsi_flags & BSQL_SF_FILTER_ENTRYCSN ) {			a_entryCSN = backsql_operational_entryCSN( op );			if ( a_entryCSN != NULL ) {				if ( ap == NULL ) {					ap = &user_entry.e_attrs;				}				for ( ; *ap; ap = &(*ap)->a_next );				*ap = a_entryCSN;			}		}#endif /* BACKSQL_SYNCPROV */		if ( test_filter( op, e, op->ors_filter ) == LDAP_COMPARE_TRUE )		{			rs->sr_attrs = op->ors_attrs;			rs->sr_operational_attrs = NULL;			rs->sr_entry = e;			rs->sr_flags = ( e == &user_entry ) ? REP_ENTRY_MODIFIABLE : 0;			/* FIXME: need the whole entry (ITS#3480) */			rs->sr_err = send_search_entry( op, rs );			rs->sr_entry = NULL;			rs->sr_attrs = NULL;			rs->sr_operational_attrs = NULL;			switch ( rs->sr_err ) {			case LDAP_UNAVAILABLE:				/*				 * FIXME: send_search_entry failed;				 * better stop				 */				Debug( LDAP_DEBUG_TRACE, "backsql_search(): "					"connection lost\n", 0, 0, 0 );				goto end_of_search;			case LDAP_SIZELIMIT_EXCEEDED:				goto send_results;			}		}next_entry:;		if ( e == &user_entry ) {			backsql_entry_clean( op, &user_entry );		}next_entry2:;	}end_of_search:;	if ( rs->sr_nentries > 0 ) {		rs->sr_ref = rs->sr_v2ref;		rs->sr_err = (rs->sr_v2ref == NULL) ? LDAP_SUCCESS			: LDAP_REFERRAL;	} else {		rs->sr_err = bsi.bsi_status;	}send_results:;	if ( rs->sr_err != SLAPD_ABANDON ) {		send_ldap_result( op, rs );	}	/* cleanup in case of abandon */	for ( ; eid != NULL; 			eid = backsql_free_entryID( op,				eid, eid == &bsi.bsi_base_id ? 0 : 1 ) )		;	backsql_entry_clean( op, &base_entry );	/* in case we got here accidentally */	backsql_entry_clean( op, &user_entry );	if ( rs->sr_v2ref ) {		ber_bvarray_free( rs->sr_v2ref );		rs->sr_v2ref = NULL;	}#ifdef BACKSQL_SYNCPROV	if ( op->o_sync ) {		Operation	op2 = *op;		SlapReply	rs2 = { 0 };		Entry		e = { 0 };		slap_callback	cb = { 0 };		op2.o_tag = LDAP_REQ_ADD;		op2.o_bd = select_backend( &op->o_bd->be_nsuffix[0], 0, 0 );		op2.ora_e = &e;		op2.o_callback = &cb;		e.e_name = op->o_bd->be_suffix[0];		e.e_nname = op->o_bd->be_nsuffix[0];		cb.sc_response = slap_null_cb;		op2.o_bd->be_add( &op2, &rs2 );	}#endif /* BACKSQL_SYNCPROV */done:;	(void)backsql_free_entryID( op, &bsi.bsi_base_id, 0 );	if ( bsi.bsi_attrs != NULL ) {		op->o_tmpfree( bsi.bsi_attrs, op->o_tmpmemctx );	}	if ( !BER_BVISNULL( &nbase )			&& nbase.bv_val != op->o_req_ndn.bv_val )	{		ch_free( nbase.bv_val );	}	/* restore scope ... FIXME: this should be done before ANY	 * frontend call that uses op */	if ( op->ors_scope == BACKSQL_SCOPE_BASE_LIKE ) {		op->ors_scope = LDAP_SCOPE_BASE;	}	Debug( LDAP_DEBUG_TRACE, "<==backsql_search()\n", 0, 0, 0 );	return rs->sr_err;}/* return LDAP_SUCCESS IFF we can retrieve the specified entry. */intbacksql_entry_get(		Operation		*op,		struct berval		*ndn,		ObjectClass		*oc,		AttributeDescription	*at,		int			rw,		Entry			**ent ){	backsql_srch_info	bsi = { 0 };	SQLHDBC			dbh = SQL_NULL_HDBC;	int			rc;	SlapReply		rs = { 0 };	AttributeName		anlist[ 2 ];	*ent = NULL;	rc = backsql_get_db_conn( op, &dbh );	if ( !dbh ) {		return LDAP_OTHER;	}	if ( at ) {		anlist[ 0 ].an_name = at->ad_cname;		anlist[ 0 ].an_desc = at;		BER_BVZERO( &anlist[ 1 ].an_name );	}	bsi.bsi_e = ch_malloc( sizeof( Entry ) );	rc = backsql_init_search( &bsi,			ndn,			LDAP_SCOPE_BASE, 			(time_t)(-1), NULL,			dbh, op, &rs, at ? anlist : NULL,			BACKSQL_ISF_GET_ENTRY );	if ( !BER_BVISNULL( &bsi.bsi_base_id.eid_ndn ) ) {		(void)backsql_free_entryID( op, &bsi.bsi_base_id, 0 );	}	if ( rc == LDAP_SUCCESS ) {#if 0 /* not supported at present */		/* find attribute values */		if ( is_entry_alias( bsi.bsi_e ) ) {			Debug( LDAP_DEBUG_ACL,				"<= backsql_entry_get: entry is an alias\n",				0, 0, 0 );			rc = LDAP_ALIAS_PROBLEM;			goto return_results;		}#endif		if ( is_entry_referral( bsi.bsi_e ) ) {			Debug( LDAP_DEBUG_ACL,				"<= backsql_entry_get: entry is a referral\n",				0, 0, 0 );			rc = LDAP_REFERRAL;			goto return_results;		}		if ( oc && !is_entry_objectclass( bsi.bsi_e, oc, 0 ) ) {			Debug( LDAP_DEBUG_ACL,					"<= backsql_entry_get: "					"failed to find objectClass\n",					0, 0, 0 ); 			rc = LDAP_NO_SUCH_ATTRIBUTE;			goto return_results;		}		*ent = bsi.bsi_e;	}return_results:;	if ( bsi.bsi_attrs != NULL ) {		op->o_tmpfree( bsi.bsi_attrs, op->o_tmpmemctx );	}	if ( rc != LDAP_SUCCESS ) {		if ( bsi.bsi_e ) {			entry_free( bsi.bsi_e );		}	}	return rc;}voidbacksql_entry_clean(		Operation	*op,		Entry		*e ){	void *ctx;	ctx = ldap_pvt_thread_pool_context();	if ( ctx == NULL || ctx != op->o_tmpmemctx ) {		if ( !BER_BVISNULL( &e->e_name ) ) {			op->o_tmpfree( e->e_name.bv_val, op->o_tmpmemctx );			BER_BVZERO( &e->e_name );		}		if ( !BER_BVISNULL( &e->e_nname ) ) {			op->o_tmpfree( e->e_nname.bv_val, op->o_tmpmemctx );			BER_BVZERO( &e->e_nname );		}	}	entry_clean( e );}intbacksql_entry_release(		Operation	*op,		Entry		*e,		int		rw ){	backsql_entry_clean( op, e );	ch_free( e );	return 0;}

⌨️ 快捷键说明

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