📄 search.c
字号:
} 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 + -