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

📄 search.c

📁 OpenLdap是LDAP的开源项目
💻 C
📖 第 1 页 / 共 5 页
字号:
 	bsi->bsi_op->o_tmpfree( bsi->bsi_sel.bb_val.bv_val, bsi->bsi_op->o_tmpmemctx );	BER_BVZERO( &bsi->bsi_sel.bb_val );	bsi->bsi_sel.bb_len = 0;	bsi->bsi_op->o_tmpfree( bsi->bsi_from.bb_val.bv_val, bsi->bsi_op->o_tmpmemctx );	BER_BVZERO( &bsi->bsi_from.bb_val );	bsi->bsi_from.bb_len = 0;	bsi->bsi_op->o_tmpfree( bsi->bsi_join_where.bb_val.bv_val, bsi->bsi_op->o_tmpmemctx );	BER_BVZERO( &bsi->bsi_join_where.bb_val );	bsi->bsi_join_where.bb_len = 0;	bsi->bsi_op->o_tmpfree( bsi->bsi_flt_where.bb_val.bv_val, bsi->bsi_op->o_tmpmemctx );	BER_BVZERO( &bsi->bsi_flt_where.bb_val );	bsi->bsi_flt_where.bb_len = 0;		Debug( LDAP_DEBUG_TRACE, "<==backsql_srch_query() returns %s\n",		query->bv_val ? query->bv_val : "NULL", 0, 0 );		return ( rc <= 0 ? 1 : 0 );}static intbacksql_oc_get_candidates( void *v_oc, void *v_bsi ){	backsql_oc_map_rec	*oc = v_oc;	backsql_srch_info	*bsi = v_bsi;	Operation		*op = bsi->bsi_op;	backsql_info		*bi = (backsql_info *)bsi->bsi_op->o_bd->be_private;	struct berval		query;	SQLHSTMT		sth = SQL_NULL_HSTMT;	RETCODE			rc;	int			res;	BACKSQL_ROW_NTS		row;	int			i;	int			j;	int			n_candidates = bsi->bsi_n_candidates;	/* 	 * + 1 because we need room for '%';	 * + 1 because we need room for ',' for LDAP_SCOPE_SUBORDINATE;	 * this makes a subtree	 * search for a DN BACKSQL_MAX_DN_LEN long legal 	 * if it returns that DN only	 */	char			tmp_base_ndn[ BACKSQL_MAX_DN_LEN + 1 + 1 ];	bsi->bsi_status = LDAP_SUCCESS; 	Debug( LDAP_DEBUG_TRACE, "==>backsql_oc_get_candidates(): oc=\"%s\"\n",			BACKSQL_OC_NAME( oc ), 0, 0 );	/* check for abandon */	if ( op->o_abandon ) {		bsi->bsi_status = SLAPD_ABANDON;		return BACKSQL_AVL_STOP;	}	if ( bsi->bsi_n_candidates == -1 ) {		Debug( LDAP_DEBUG_TRACE, "backsql_oc_get_candidates(): "			"unchecked limit has been overcome\n", 0, 0, 0 );		/* should never get here */		assert( 0 );		bsi->bsi_status = LDAP_ADMINLIMIT_EXCEEDED;		return BACKSQL_AVL_STOP;	}		bsi->bsi_oc = oc;	res = backsql_srch_query( bsi, &query );	if ( res ) {		Debug( LDAP_DEBUG_TRACE, "backsql_oc_get_candidates(): "			"error while constructing query for objectclass \"%s\"\n",			oc->bom_oc->soc_cname.bv_val, 0, 0 );		/*		 * FIXME: need to separate errors from legally		 * impossible filters		 */		switch ( bsi->bsi_status ) {		case LDAP_SUCCESS:		case LDAP_UNDEFINED_TYPE:		case LDAP_NO_SUCH_OBJECT:			/* we are conservative... */		default:			bsi->bsi_status = LDAP_SUCCESS;			/* try next */			return BACKSQL_AVL_CONTINUE;		case LDAP_ADMINLIMIT_EXCEEDED:		case LDAP_OTHER:			/* don't try any more */			return BACKSQL_AVL_STOP;		}	}	if ( BER_BVISNULL( &query ) ) {		Debug( LDAP_DEBUG_TRACE, "backsql_oc_get_candidates(): "			"could not construct query for objectclass \"%s\"\n",			oc->bom_oc->soc_cname.bv_val, 0, 0 );		bsi->bsi_status = LDAP_SUCCESS;		return BACKSQL_AVL_CONTINUE;	}	Debug( LDAP_DEBUG_TRACE, "Constructed query: %s\n", 			query.bv_val, 0, 0 );	rc = backsql_Prepare( bsi->bsi_dbh, &sth, query.bv_val, 0 );	bsi->bsi_op->o_tmpfree( query.bv_val, bsi->bsi_op->o_tmpmemctx );	BER_BVZERO( &query );	if ( rc != SQL_SUCCESS ) {		Debug( LDAP_DEBUG_TRACE, "backsql_oc_get_candidates(): "			"error preparing query\n", 0, 0, 0 );		backsql_PrintErrors( bi->sql_db_env, bsi->bsi_dbh, sth, rc );		bsi->bsi_status = LDAP_OTHER;		return BACKSQL_AVL_CONTINUE;	}		Debug( LDAP_DEBUG_TRACE, "id: '%ld'\n", bsi->bsi_oc->bom_id, 0, 0 );	rc = backsql_BindParamInt( sth, 1, SQL_PARAM_INPUT,			&bsi->bsi_oc->bom_id );	if ( rc != SQL_SUCCESS ) {		Debug( LDAP_DEBUG_TRACE, "backsql_oc_get_candidates(): "			"error binding objectclass id parameter\n", 0, 0, 0 );		bsi->bsi_status = LDAP_OTHER;		return BACKSQL_AVL_CONTINUE;	}	switch ( bsi->bsi_scope ) {	case LDAP_SCOPE_BASE:	case BACKSQL_SCOPE_BASE_LIKE:		/*		 * We do not accept DNs longer than BACKSQL_MAX_DN_LEN;		 * however this should be handled earlier		 */		if ( bsi->bsi_base_ndn->bv_len > BACKSQL_MAX_DN_LEN ) {			bsi->bsi_status = LDAP_OTHER;			return BACKSQL_AVL_CONTINUE;		}		AC_MEMCPY( tmp_base_ndn, bsi->bsi_base_ndn->bv_val,				bsi->bsi_base_ndn->bv_len + 1 );		/* uppercase DN only if the stored DN can be uppercased		 * for comparison */		if ( BACKSQL_CANUPPERCASE( bi ) ) {			ldap_pvt_str2upper( tmp_base_ndn );		}		Debug( LDAP_DEBUG_TRACE, "(base)dn: \"%s\"\n",				tmp_base_ndn, 0, 0 );		rc = backsql_BindParamStr( sth, 2, SQL_PARAM_INPUT,				tmp_base_ndn, BACKSQL_MAX_DN_LEN );		if ( rc != SQL_SUCCESS ) {         		Debug( LDAP_DEBUG_TRACE, "backsql_oc_get_candidates(): "				"error binding base_ndn parameter\n", 0, 0, 0 );			backsql_PrintErrors( bi->sql_db_env, bsi->bsi_dbh, 					sth, rc );			bsi->bsi_status = LDAP_OTHER;			return BACKSQL_AVL_CONTINUE;		}		break;	case LDAP_SCOPE_SUBORDINATE:	case LDAP_SCOPE_SUBTREE:	{		/* if short-cutting the search base,		 * don't bind any parameter */		if ( bsi->bsi_use_subtree_shortcut ) {			break;		}				/*		 * We do not accept DNs longer than BACKSQL_MAX_DN_LEN;		 * however this should be handled earlier		 */		if ( bsi->bsi_base_ndn->bv_len > BACKSQL_MAX_DN_LEN ) {			bsi->bsi_status = LDAP_OTHER;			return BACKSQL_AVL_CONTINUE;		}		/* 		 * Sets the parameters for the SQL built earlier		 * NOTE that all the databases could actually use 		 * the TimesTen version, which would be cleaner 		 * and would also eliminate the need for the		 * subtree_cond line in the configuration file.  		 * For now, I'm leaving it the way it is, 		 * so non-TimesTen databases use the original code.		 * But at some point this should get cleaned up.		 *		 * If "dn" is being used, do a suffix search.		 * If "dn_ru" is being used, do a prefix search.		 */		if ( BACKSQL_HAS_LDAPINFO_DN_RU( bi ) ) {			tmp_base_ndn[ 0 ] = '\0';			for ( i = 0, j = bsi->bsi_base_ndn->bv_len - 1;					j >= 0; i++, j--) {				tmp_base_ndn[ i ] = bsi->bsi_base_ndn->bv_val[ j ];			}			if ( bsi->bsi_scope == LDAP_SCOPE_SUBORDINATE ) {				tmp_base_ndn[ i++ ] = ',';			}			tmp_base_ndn[ i ] = '%';			tmp_base_ndn[ i + 1 ] = '\0';		} else {			i = 0;			tmp_base_ndn[ i++ ] = '%';			if ( bsi->bsi_scope == LDAP_SCOPE_SUBORDINATE ) {				tmp_base_ndn[ i++ ] = ',';			}			AC_MEMCPY( &tmp_base_ndn[ i ], bsi->bsi_base_ndn->bv_val,				bsi->bsi_base_ndn->bv_len + 1 );		}		/* uppercase DN only if the stored DN can be uppercased		 * for comparison */		if ( BACKSQL_CANUPPERCASE( bi ) ) {			ldap_pvt_str2upper( tmp_base_ndn );		}		if ( bsi->bsi_scope == LDAP_SCOPE_SUBORDINATE ) {			Debug( LDAP_DEBUG_TRACE, "(children)dn: \"%s\"\n",				tmp_base_ndn, 0, 0 );		} else {			Debug( LDAP_DEBUG_TRACE, "(sub)dn: \"%s\"\n",				tmp_base_ndn, 0, 0 );		}		rc = backsql_BindParamStr( sth, 2, SQL_PARAM_INPUT,				tmp_base_ndn, BACKSQL_MAX_DN_LEN );		if ( rc != SQL_SUCCESS ) {			Debug( LDAP_DEBUG_TRACE, "backsql_oc_get_candidates(): "				"error binding base_ndn parameter (2)\n",				0, 0, 0 );			backsql_PrintErrors( bi->sql_db_env, bsi->bsi_dbh, 					sth, rc );			bsi->bsi_status = LDAP_OTHER;			return BACKSQL_AVL_CONTINUE;		}		break;	} 	case LDAP_SCOPE_ONELEVEL:		assert( !BER_BVISNULL( &bsi->bsi_base_id.eid_ndn ) );#ifdef BACKSQL_ARBITRARY_KEY		Debug( LDAP_DEBUG_TRACE, "(one)id: \"%s\"\n",				bsi->bsi_base_id.eid_id.bv_val, 0, 0 );#else /* ! BACKSQL_ARBITRARY_KEY */		Debug( LDAP_DEBUG_TRACE, "(one)id: '%lu'\n",				bsi->bsi_base_id.eid_id, 0, 0 );#endif /* ! BACKSQL_ARBITRARY_KEY */		rc = backsql_BindParamID( sth, 2, SQL_PARAM_INPUT,				&bsi->bsi_base_id.eid_id );		if ( rc != SQL_SUCCESS ) {			Debug( LDAP_DEBUG_TRACE, "backsql_oc_get_candidates(): "				"error binding base id parameter\n", 0, 0, 0 );			bsi->bsi_status = LDAP_OTHER;			return BACKSQL_AVL_CONTINUE;		}		break;	}		rc = SQLExecute( sth );	if ( !BACKSQL_SUCCESS( rc ) ) {		Debug( LDAP_DEBUG_TRACE, "backsql_oc_get_candidates(): "			"error executing query\n", 0, 0, 0 );		backsql_PrintErrors( bi->sql_db_env, bsi->bsi_dbh, sth, rc );		SQLFreeStmt( sth, SQL_DROP );		bsi->bsi_status = LDAP_OTHER;		return BACKSQL_AVL_CONTINUE;	}	backsql_BindRowAsStrings_x( sth, &row, bsi->bsi_op->o_tmpmemctx );	rc = SQLFetch( sth );	for ( ; BACKSQL_SUCCESS( rc ); rc = SQLFetch( sth ) ) {		struct berval		dn, pdn, ndn;		backsql_entryID		*c_id = NULL;		int			ret;		ber_str2bv( row.cols[ 3 ], 0, 0, &dn );		if ( backsql_api_odbc2dn( bsi->bsi_op, bsi->bsi_rs, &dn ) ) {			continue;		}		ret = dnPrettyNormal( NULL, &dn, &pdn, &ndn, op->o_tmpmemctx );		if ( dn.bv_val != row.cols[ 3 ] ) {			free( dn.bv_val );		}		if ( ret != LDAP_SUCCESS ) {			continue;		}		if ( bi->sql_baseObject && dn_match( &ndn, &bi->sql_baseObject->e_nname ) ) {			goto cleanup;		}		c_id = (backsql_entryID *)op->o_tmpcalloc( 1, 				sizeof( backsql_entryID ), op->o_tmpmemctx );#ifdef BACKSQL_ARBITRARY_KEY		ber_str2bv_x( row.cols[ 0 ], 0, 1, &c_id->eid_id,				op->o_tmpmemctx );		ber_str2bv_x( row.cols[ 1 ], 0, 1, &c_id->eid_keyval,				op->o_tmpmemctx );#else /* ! BACKSQL_ARBITRARY_KEY */		if ( lutil_atoulx( &c_id->eid_id, row.cols[ 0 ], 0 ) != 0 ) {			goto cleanup;		}		if ( lutil_atoulx( &c_id->eid_keyval, row.cols[ 1 ], 0 ) != 0 ) {			goto cleanup;		}#endif /* ! BACKSQL_ARBITRARY_KEY */		c_id->eid_oc_id = bsi->bsi_oc->bom_id;		c_id->eid_dn = pdn;		c_id->eid_ndn = ndn;		/* append at end of list ... */		c_id->eid_next = NULL;		*bsi->bsi_id_listtail = c_id;		bsi->bsi_id_listtail = &c_id->eid_next;#ifdef BACKSQL_ARBITRARY_KEY		Debug( LDAP_DEBUG_TRACE, "backsql_oc_get_candidates(): "			"added entry id=%s, keyval=%s dn=\"%s\"\n",			c_id->eid_id.bv_val, c_id->eid_keyval.bv_val,			row.cols[ 3 ] );#else /* ! BACKSQL_ARBITRARY_KEY */		Debug( LDAP_DEBUG_TRACE, "backsql_oc_get_candidates(): "			"added entry id=%ld, keyval=%ld dn=\"%s\"\n",			c_id->eid_id, c_id->eid_keyval, row.cols[ 3 ] );#endif /* ! BACKSQL_ARBITRARY_KEY */		/* count candidates, for unchecked limit */		bsi->bsi_n_candidates--;		if ( bsi->bsi_n_candidates == -1 ) {			break;		}		continue;cleanup:;		if ( !BER_BVISNULL( &pdn ) ) {			op->o_tmpfree( pdn.bv_val, op->o_tmpmemctx );		}		if ( !BER_BVISNULL( &ndn ) ) {			op->o_tmpfree( ndn.bv_val, op->o_tmpmemctx );		}		if ( c_id != NULL ) {			ch_free( c_id );		}	}	backsql_FreeRow_x( &row, bsi->bsi_op->o_tmpmemctx );	SQLFreeStmt( sth, SQL_DROP );	Debug( LDAP_DEBUG_TRACE, "<==backsql_oc_get_candidates(): %d\n",			n_candidates - bsi->bsi_n_candidates, 0, 0 );	return ( bsi->bsi_n_candidates == -1 ? BACKSQL_AVL_STOP : BACKSQL_AVL_CONTINUE );}intbacksql_search( Operation *op, SlapReply *rs ){	backsql_info		*bi = (backsql_info *)op->o_bd->be_private;	SQLHDBC			dbh = SQL_NULL_HDBC;	int			sres;	Entry			user_entry = { 0 },				base_entry = { 0 };	int			manageDSAit = get_manageDSAit( op );	time_t			stoptime = 0;	backsql_srch_info	bsi = { 0 };	backsql_entryID		*eid = NULL;	struct berval		nbase = BER_BVNULL;	Debug( LDAP_DEBUG_TRACE, "==>backsql_search(): "		"base=\"%s\", filter=\"%s\", scope=%d,", 		op->o_req_ndn.bv_val,		op->ors_filterstr.bv_val,		op->ors_scope );	Debug( LDAP_DEBUG_TRACE, " deref=%d, attrsonly=%d, "		"attributes to load: %s\n",		op->ors_deref,		op->ors_attrsonly,		op->ors_attrs == NULL ? "all" : "custom list" );	if ( op->o_req_ndn.bv_len > BACKSQL_MAX_DN_LEN ) {		Debug( LDAP_DEBUG_TRACE, "backsql_search(): "			"search base length (%ld) exceeds max length (%d)\n", 			op->o_req_ndn.bv_len, BACKSQL_MAX_DN_LEN, 0 );		/*		 * FIXME: a LDAP_NO_SUCH_OBJECT could be appropriate		 * since it is impossible that such a long DN exists		 * in the backend		 */		rs->sr_err = LDAP_ADMINLIMIT_EXCEEDED;		send_ldap_result( op, rs );		return 1;	}	sres = backsql_get_db_conn( op, &dbh );	if ( sres != LDAP_SUCCESS ) {		Debug( LDAP_DEBUG_TRACE, "backsql_search(): "			"could not get connection handle - exiting\n", 			0, 0, 0 );		rs->sr_err = sres;		rs->sr_text = sres == LDAP_OTHER ?  "SQL-backend error" : NULL;		send_ldap_result( op, rs );		return 1;	}	/* compute it anyway; root does not use it */	stoptime = op->o_time + op->ors_tlimit;	/* init search */	bsi.bsi_e = &base_entry;	rs->sr_err = backsql_init_search( &bsi, &op->o_req_ndn,			op->ors_scope,			stoptime, op->ors_filter,			dbh, op, rs, op->ors_attrs,			( BACKSQL_ISF_MATCHED | BACKSQL_ISF_GET_ENTRY ) );	switch ( rs->sr_err ) {	case LDAP_SUCCESS:		break;	case LDAP_REFERRAL:		if ( manageDSAit && !BER_BVISNULL( &bsi.bsi_e->e_nname ) &&				dn_match( &op->o_req_ndn, &bsi.bsi_e->e_nname ) )		{			rs->sr_err = LDAP_SUCCESS;			rs->sr_text = NULL;			rs->sr_matched = NULL;			if ( rs->sr_ref ) {				ber_bvarray_free( rs->sr_ref );				rs->sr_ref = NULL;			}			break;		}		/* an entry was created; free it */		entry_clean( bsi.bsi_e );		/* fall thru */	default:#ifdef SLAP_ACL_HONOR_DISCLOSE		if ( !BER_BVISNULL( &base_entry.e_nname )				&& !access_allowed( op, &base_entry,					slap_schema.si_ad_entry, NULL,					ACL_DISCLOSE, NULL ) )		{			rs->sr_err = LDAP_NO_SUCH_OBJECT;			if ( rs->sr_ref ) {				ber_bvarray_free( rs->sr_ref );				rs->sr_ref = NULL;			}			rs->sr_matched = NULL;			rs->sr_text = NULL;		}#endif /* SLAP_ACL_HONOR_DISCLOSE */		send_ldap_result( op, rs );		if ( rs->sr_ref ) {			ber_bvarray_free( rs->sr_ref );			rs->sr_ref = NULL;		}		if ( !BER_BVISNULL( &base_entry.e_nname ) ) {			entry_clean( &base_entry );		}		goto done;	}#ifdef SLAP_ACL_HONOR_DISCLOSE	/* NOTE: __NEW__ "search" access is required	 * on searchBase object */	{		slap_mask_t	mask;				if ( get_assert( op ) &&				( test_filter( op, &base_entry, get_assertion( op ) )				  != LDAP_COMPARE_TRUE ) )		{			rs->sr_err = LDAP_ASSERTION_FAILED;					}		if ( ! access_allowed_mask( op, &base_entry,					slap_schema.si_ad_entry,					NULL, ACL_SEARCH, NULL, &mask ) )		{			if ( rs->sr_err == LDAP_SUCCESS ) {				rs->sr_err = LDAP_INSUFFICIENT_ACCESS;			}		}		if ( rs->sr_err != LDAP_SUCCESS ) {			if ( !ACL_GRANT( mask, ACL_DISCLOSE ) ) {				rs->sr_err = LDAP_NO_SUCH_OBJECT;				rs->sr_text = NULL;			}			send_ldap_result( op, rs );			goto done;		}	}#endif /* SLAP_ACL_HONOR_DISCLOSE */

⌨️ 快捷键说明

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