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

📄 search.c

📁 OpenLdap是LDAP的开源项目
💻 C
📖 第 1 页 / 共 5 页
字号:
	} 	if ( !BER_BVISNULL( &f->f_sub_initial ) ) {		ber_len_t	start;#ifdef BACKSQL_TRACE		Debug( LDAP_DEBUG_TRACE, 			"==>backsql_process_sub_filter(%s): "			"sub_initial=\"%s\"\n", at->bam_ad->ad_cname.bv_val,			f->f_sub_initial.bv_val, 0 );#endif /* BACKSQL_TRACE */		start = bsi->bsi_flt_where.bb_val.bv_len;		backsql_strfcat_x( &bsi->bsi_flt_where,				bsi->bsi_op->o_tmpmemctx,				"b",				&f->f_sub_initial );		if ( casefold && BACKSQL_AT_CANUPPERCASE( at ) ) {			ldap_pvt_str2upper( &bsi->bsi_flt_where.bb_val.bv_val[ start ] );		}	}	backsql_strfcat_x( &bsi->bsi_flt_where,			bsi->bsi_op->o_tmpmemctx,			"c", '%' );	if ( f->f_sub_any != NULL ) {		for ( i = 0; !BER_BVISNULL( &f->f_sub_any[ i ] ); i++ ) {			ber_len_t	start;#ifdef BACKSQL_TRACE			Debug( LDAP_DEBUG_TRACE, 				"==>backsql_process_sub_filter(%s): "				"sub_any[%d]=\"%s\"\n", at->bam_ad->ad_cname.bv_val, 				i, f->f_sub_any[ i ].bv_val );#endif /* BACKSQL_TRACE */			start = bsi->bsi_flt_where.bb_val.bv_len;			backsql_strfcat_x( &bsi->bsi_flt_where,					bsi->bsi_op->o_tmpmemctx,					"bc",					&f->f_sub_any[ i ],					'%' );			if ( casefold && BACKSQL_AT_CANUPPERCASE( at ) ) {				/*				 * Note: toupper('%') = '%'				 */				ldap_pvt_str2upper( &bsi->bsi_flt_where.bb_val.bv_val[ start ] );			}		}	}	if ( !BER_BVISNULL( &f->f_sub_final ) ) {		ber_len_t	start;#ifdef BACKSQL_TRACE		Debug( LDAP_DEBUG_TRACE, 			"==>backsql_process_sub_filter(%s): "			"sub_final=\"%s\"\n", at->bam_ad->ad_cname.bv_val,			f->f_sub_final.bv_val, 0 );#endif /* BACKSQL_TRACE */		start = bsi->bsi_flt_where.bb_val.bv_len;    		backsql_strfcat_x( &bsi->bsi_flt_where,				bsi->bsi_op->o_tmpmemctx,				"b",				&f->f_sub_final );  		if ( casefold && BACKSQL_AT_CANUPPERCASE( at ) ) {			ldap_pvt_str2upper( &bsi->bsi_flt_where.bb_val.bv_val[ start ] );		}	}	backsql_strfcat_x( &bsi->bsi_flt_where,			bsi->bsi_op->o_tmpmemctx,			"l", 			(ber_len_t)STRLENOF( /* (' */ "')" ), /* (' */ "')" ); 	return 1;}static intbacksql_merge_from_tbls( backsql_srch_info *bsi, struct berval *from_tbls ){	if ( BER_BVISNULL( from_tbls ) ) {		return LDAP_SUCCESS;	}	if ( !BER_BVISNULL( &bsi->bsi_from.bb_val ) ) {		char		*start, *end;		struct berval	tmp;		ber_dupbv_x( &tmp, from_tbls, bsi->bsi_op->o_tmpmemctx );		for ( start = tmp.bv_val, end = strchr( start, ',' ); start; ) {			if ( end ) {				end[0] = '\0';			}			if ( strstr( bsi->bsi_from.bb_val.bv_val, start) == NULL )			{				backsql_strfcat_x( &bsi->bsi_from,						bsi->bsi_op->o_tmpmemctx,						"cs", ',', start );			}			if ( end ) {				/* in case there are spaces after the comma... */				for ( start = &end[1]; isspace( start[0] ); start++ );				if ( start[0] ) {					end = strchr( start, ',' );				} else {					start = NULL;				}			} else {				start = NULL;			}		}		bsi->bsi_op->o_tmpfree( tmp.bv_val, bsi->bsi_op->o_tmpmemctx );	} else {		backsql_strfcat_x( &bsi->bsi_from,				bsi->bsi_op->o_tmpmemctx,				"b", from_tbls );	}	return LDAP_SUCCESS;}static intbacksql_process_filter( backsql_srch_info *bsi, Filter *f ){	backsql_at_map_rec	**vat = NULL;	AttributeDescription	*ad = NULL;	unsigned		i;	int 			done = 0;	int			rc = 0;	Debug( LDAP_DEBUG_TRACE, "==>backsql_process_filter()\n", 0, 0, 0 );	if ( f->f_choice == SLAPD_FILTER_COMPUTED ) {		struct berval	flt;		char		*msg = NULL;		switch ( f->f_result ) {		case LDAP_COMPARE_TRUE:			BER_BVSTR( &flt, "10=10" );			msg = "TRUE";			break;		case LDAP_COMPARE_FALSE:			BER_BVSTR( &flt, "11=0" );			msg = "FALSE";			break;		case SLAPD_COMPARE_UNDEFINED:			BER_BVSTR( &flt, "12=0" );			msg = "UNDEFINED";			break;		default:			rc = -1;			goto done;		}		Debug( LDAP_DEBUG_TRACE, "backsql_process_filter(): "			"filter computed (%s)\n", msg, 0, 0 );		backsql_strfcat_x( &bsi->bsi_flt_where,				bsi->bsi_op->o_tmpmemctx, "b", &flt );		rc = 1;		goto done;	}	switch( f->f_choice ) {	case LDAP_FILTER_OR:		rc = backsql_process_filter_list( bsi, f->f_or, 				LDAP_FILTER_OR );		done = 1;		break;			case LDAP_FILTER_AND:		rc = backsql_process_filter_list( bsi, f->f_and,				LDAP_FILTER_AND );		done = 1;		break;	case LDAP_FILTER_NOT:		backsql_strfcat_x( &bsi->bsi_flt_where,				bsi->bsi_op->o_tmpmemctx,				"l",				(ber_len_t)STRLENOF( "NOT (" /* ) */ ),					"NOT (" /* ) */ );		rc = backsql_process_filter( bsi, f->f_not );		backsql_strfcat_x( &bsi->bsi_flt_where,				bsi->bsi_op->o_tmpmemctx,				"c", /* ( */ ')' );		done = 1;		break;	case LDAP_FILTER_PRESENT:		ad = f->f_desc;		break;			case LDAP_FILTER_EXT:		ad = f->f_mra->ma_desc;		if ( f->f_mr_dnattrs ) {			/*			 * if dn attrs filtering is requested, better return 			 * success and let test_filter() deal with candidate			 * selection; otherwise we'd need to set conditions			 * on the contents of the DN, e.g. "SELECT ... FROM			 * ldap_entries AS attributeName WHERE attributeName.dn			 * like '%attributeName=value%'"			 */			backsql_strfcat_x( &bsi->bsi_flt_where,					bsi->bsi_op->o_tmpmemctx,					"l",					(ber_len_t)STRLENOF( "1=1" ), "1=1" );			bsi->bsi_status = LDAP_SUCCESS;			rc = 1;			goto done;		}		break;			default:		ad = f->f_av_desc;		break;	}	if ( rc == -1 ) {		goto done;	} 	if ( done ) {		rc = 1;		goto done;	}	/*	 * Turn structuralObjectClass into objectClass	 */	if ( ad == slap_schema.si_ad_objectClass 			|| ad == slap_schema.si_ad_structuralObjectClass )	{		/*		 * If the filter is LDAP_FILTER_PRESENT, then it's done;		 * otherwise, let's see if we are lucky: filtering		 * for "structural" objectclass or ancestor...		 */		switch ( f->f_choice ) {		case LDAP_FILTER_EQUALITY:		{			ObjectClass	*oc = oc_bvfind( &f->f_av_value );			if ( oc == NULL ) {				Debug( LDAP_DEBUG_TRACE,						"backsql_process_filter(): "						"unknown objectClass \"%s\" "						"in filter\n",						f->f_av_value.bv_val, 0, 0 );				bsi->bsi_status = LDAP_OTHER;				rc = -1;				goto done;			}			/*			 * "structural" objectClass inheritance:			 * - a search for "person" will also return 			 *   "inetOrgPerson"			 * - a search for "top" will return everything			 */			if ( is_object_subclass( oc, bsi->bsi_oc->bom_oc ) ) {				static struct berval ldap_entry_objclasses = BER_BVC( "ldap_entry_objclasses" );				backsql_merge_from_tbls( bsi, &ldap_entry_objclasses );				backsql_strfcat_x( &bsi->bsi_flt_where,						bsi->bsi_op->o_tmpmemctx,						"lbl",						(ber_len_t)STRLENOF( "(2=2 OR (ldap_entries.id=ldap_entry_objclasses.entry_id AND ldap_entry_objclasses.oc_name='" /* ')) */ ),							"(2=2 OR (ldap_entries.id=ldap_entry_objclasses.entry_id AND ldap_entry_objclasses.oc_name='" /* ')) */,						&bsi->bsi_oc->bom_oc->soc_cname,						(ber_len_t)STRLENOF( /* ((' */ "'))" ),							/* ((' */ "'))" );				bsi->bsi_status = LDAP_SUCCESS;				rc = 1;				goto done;			}			break;		}		case LDAP_FILTER_PRESENT:			backsql_strfcat_x( &bsi->bsi_flt_where,					bsi->bsi_op->o_tmpmemctx,					"l",					(ber_len_t)STRLENOF( "3=3" ), "3=3" );			bsi->bsi_status = LDAP_SUCCESS;			rc = 1;			goto done;			/* FIXME: LDAP_FILTER_EXT? */					default:			Debug( LDAP_DEBUG_TRACE,					"backsql_process_filter(): "					"illegal/unhandled filter "					"on objectClass attribute",					0, 0, 0 );			bsi->bsi_status = LDAP_OTHER;			rc = -1;			goto done;		}	} else if ( ad == slap_schema.si_ad_entryUUID ) {		unsigned long	oc_id;#ifdef BACKSQL_ARBITRARY_KEY		struct berval	keyval;#else /* ! BACKSQL_ARBITRARY_KEY */		unsigned long	keyval;		char		keyvalbuf[] = "18446744073709551615";#endif /* ! BACKSQL_ARBITRARY_KEY */		switch ( f->f_choice ) {		case LDAP_FILTER_EQUALITY:			backsql_entryUUID_decode( &f->f_av_value, &oc_id, &keyval );			if ( oc_id != bsi->bsi_oc->bom_id ) {				bsi->bsi_status = LDAP_SUCCESS;				rc = -1;				goto done;			}#ifdef BACKSQL_ARBITRARY_KEY			backsql_strfcat_x( &bsi->bsi_flt_where,					bsi->bsi_op->o_tmpmemctx,					"bcblbc",					&bsi->bsi_oc->bom_keytbl, '.',					&bsi->bsi_oc->bom_keycol,					STRLENOF( " LIKE '" ), " LIKE '",					&keyval, '\'' );#else /* ! BACKSQL_ARBITRARY_KEY */			snprintf( keyvalbuf, sizeof( keyvalbuf ), "%lu", keyval );			backsql_strfcat_x( &bsi->bsi_flt_where,					bsi->bsi_op->o_tmpmemctx,					"bcbcs",					&bsi->bsi_oc->bom_keytbl, '.',					&bsi->bsi_oc->bom_keycol, '=', keyvalbuf );#endif /* ! BACKSQL_ARBITRARY_KEY */			break;		case LDAP_FILTER_PRESENT:			backsql_strfcat_x( &bsi->bsi_flt_where,					bsi->bsi_op->o_tmpmemctx,					"l",					(ber_len_t)STRLENOF( "4=4" ), "4=4" );			break;		default:			rc = -1;			goto done;		}		bsi->bsi_flags |= BSQL_SF_FILTER_ENTRYUUID;		rc = 1;		goto done;#ifdef BACKSQL_SYNCPROV	} else if ( ad == slap_schema.si_ad_entryCSN ) {		/*		 * support for syncrepl as producer...		 */#if 0		if ( !bsi->bsi_op->o_sync ) {			/* unsupported at present... */			bsi->bsi_status = LDAP_OTHER;			rc = -1;			goto done;		}#endif		bsi->bsi_flags |= ( BSQL_SF_FILTER_ENTRYCSN | BSQL_SF_RETURN_ENTRYUUID);		/* if doing a syncrepl, try to return as much as possible,		 * and always match the filter */		backsql_strfcat_x( &bsi->bsi_flt_where,				bsi->bsi_op->o_tmpmemctx,				"l",				(ber_len_t)STRLENOF( "5=5" ), "5=5" );		/* save for later use in operational attributes */		/* FIXME: saves only the first occurrence, because 		 * the filter during updates is written as		 * "(&(entryCSN<={contextCSN})(entryCSN>={oldContextCSN})({filter}))"		 * so we want our fake entryCSN to match the greatest		 * value		 */		if ( bsi->bsi_op->o_private == NULL ) {			bsi->bsi_op->o_private = &f->f_av_value;		}		bsi->bsi_status = LDAP_SUCCESS;		rc = 1;		goto done;#endif /* BACKSQL_SYNCPROV */	} else if ( ad == slap_schema.si_ad_hasSubordinates || ad == NULL ) {		/*		 * FIXME: this is not robust; e.g. a filter		 * '(!(hasSubordinates=TRUE))' fails because		 * in SQL it would read 'NOT (1=1)' instead 		 * of no condition.  		 * Note however that hasSubordinates is boolean, 		 * so a more appropriate filter would be 		 * '(hasSubordinates=FALSE)'		 *		 * A more robust search for hasSubordinates		 * would * require joining the ldap_entries table		 * selecting if there are descendants of the		 * candidate.		 */		backsql_strfcat_x( &bsi->bsi_flt_where,				bsi->bsi_op->o_tmpmemctx,				"l",				(ber_len_t)STRLENOF( "6=6" ), "6=6" );		if ( ad == slap_schema.si_ad_hasSubordinates ) {			/*			 * instruct candidate selection algorithm			 * and attribute list to try to detect			 * if an entry has subordinates			 */			bsi->bsi_flags |= BSQL_SF_FILTER_HASSUBORDINATE;		} else {			/*			 * clear attributes to fetch, to require ALL			 * and try extended match on all attributes			 */			backsql_attrlist_add( bsi, NULL );		}		rc = 1;		goto done;	}	/*	 * attribute inheritance:	 */	if ( backsql_supad2at( bsi->bsi_oc, ad, &vat ) ) {		bsi->bsi_status = LDAP_OTHER;		rc = -1;		goto done;	}	if ( vat == NULL ) {		/* search anyway; other parts of the filter		 * may succeeed */		backsql_strfcat_x( &bsi->bsi_flt_where,				bsi->bsi_op->o_tmpmemctx,				"l",				(ber_len_t)STRLENOF( "7=7" ), "7=7" );		bsi->bsi_status = LDAP_SUCCESS;		rc = 1;		goto done;	}	/* if required, open extra level of parens */	done = 0;	if ( vat[0]->bam_next || vat[1] ) {		backsql_strfcat_x( &bsi->bsi_flt_where,				bsi->bsi_op->o_tmpmemctx,				"c", '(' );		done = 1;	}	i = 0;next:;	/* apply attr */	if ( backsql_process_filter_attr( bsi, f, vat[i] ) == -1 ) {		return -1;	}	/* if more definitions of the same attr, apply */	if ( vat[i]->bam_next ) {		backsql_strfcat_x( &bsi->bsi_flt_where,				bsi->bsi_op->o_tmpmemctx,				"l",			STRLENOF( " OR " ), " OR " );		vat[i] = vat[i]->bam_next;		goto next;	}	/* if more descendants of the same attr, apply */	i++;	if ( vat[i] ) {		backsql_strfcat_x( &bsi->bsi_flt_where,				bsi->bsi_op->o_tmpmemctx,				"l",			STRLENOF( " OR " ), " OR " );		goto next;	}	/* if needed, close extra level of parens */	if ( done ) {		backsql_strfcat_x( &bsi->bsi_flt_where,				bsi->bsi_op->o_tmpmemctx,				"c", ')' );	}	rc = 1;done:;	if ( vat ) {		ch_free( vat );	}

⌨️ 快捷键说明

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