mirror of
https://git.openldap.org/openldap/openldap.git
synced 2024-12-21 03:10:25 +08:00
ITS#7609 add per-target filter patterns
This commit is contained in:
parent
a3de7c29ae
commit
9649281f7b
@ -338,6 +338,19 @@ The optional number marks target <target> as the default one, starting
|
||||
from 1.
|
||||
Target <target> must be defined.
|
||||
|
||||
.TP
|
||||
.B filter <pattern>
|
||||
This directive allows specifying a
|
||||
.BR regex (5)
|
||||
pattern to indicate what search filter terms are actually served by a target.
|
||||
|
||||
In a search request, if the search filter matches the \fIpattern\fP
|
||||
the target is considered while fulfilling the request; otherwise
|
||||
the target is ignored. There may be multiple occurrences of
|
||||
the
|
||||
.B filter
|
||||
directive for each target.
|
||||
|
||||
.TP
|
||||
.B idassert\-authzFrom <authz-regexp>
|
||||
if defined, selects what
|
||||
|
@ -278,6 +278,12 @@ typedef struct metasubtree_t {
|
||||
struct metasubtree_t *ms_next;
|
||||
} metasubtree_t;
|
||||
|
||||
typedef struct metafilter_t {
|
||||
struct metafilter_t *mf_next;
|
||||
struct berval mf_regex_pattern;
|
||||
regex_t mf_regex;
|
||||
} metafilter_t;
|
||||
|
||||
typedef struct metacommon_t {
|
||||
int mc_version;
|
||||
int mc_nretries;
|
||||
@ -324,6 +330,7 @@ typedef struct metatarget_t {
|
||||
LDAP_URLLIST_PROC *mt_urllist_f;
|
||||
void *mt_urllist_p;
|
||||
|
||||
metafilter_t *mt_filter;
|
||||
metasubtree_t *mt_subtree;
|
||||
/* F: subtree-include; T: subtree-exclude */
|
||||
int mt_subtree_exclude;
|
||||
@ -681,6 +688,9 @@ meta_back_map_free( struct ldapmap *lm );
|
||||
extern int
|
||||
meta_subtree_destroy( metasubtree_t *ms );
|
||||
|
||||
extern void
|
||||
meta_filter_destroy( metafilter_t *mf );
|
||||
|
||||
extern int
|
||||
meta_target_finish( metainfo_t *mi, metatarget_t *mt,
|
||||
const char *log, char *msg, size_t msize
|
||||
|
@ -101,6 +101,7 @@ enum {
|
||||
LDAP_BACK_CFG_PSEUDOROOTDN,
|
||||
LDAP_BACK_CFG_PSEUDOROOTPW,
|
||||
LDAP_BACK_CFG_KEEPALIVE,
|
||||
LDAP_BACK_CFG_FILTER,
|
||||
|
||||
LDAP_BACK_CFG_LAST
|
||||
};
|
||||
@ -417,6 +418,15 @@ static ConfigTable metacfg[] = {
|
||||
"SINGLE-VALUE )",
|
||||
NULL, NULL },
|
||||
|
||||
{ "filter", "pattern", 2, 2, 0,
|
||||
ARG_MAGIC|LDAP_BACK_CFG_FILTER,
|
||||
meta_back_cf_gen, "( OLcfgDbAt:3.112 "
|
||||
"NAME 'olcDbFilter' "
|
||||
"DESC 'Filter regex pattern to include in target' "
|
||||
"EQUALITY caseExactMatch "
|
||||
"SYNTAX OMsDirectoryString )",
|
||||
NULL, NULL },
|
||||
|
||||
{ NULL, NULL, 0, 0, 0, ARG_IGNORED,
|
||||
NULL, NULL, NULL, NULL }
|
||||
};
|
||||
@ -477,6 +487,7 @@ static ConfigOCs metaocs[] = {
|
||||
"$ olcDbSubtreeInclude "
|
||||
"$ olcDbTimeout "
|
||||
"$ olcDbKeepalive "
|
||||
"$ olcDbFilter "
|
||||
|
||||
/* defaults may be inherited */
|
||||
COMMON_ATTRS
|
||||
@ -729,6 +740,22 @@ meta_subtree_destroy( metasubtree_t *ms )
|
||||
return meta_subtree_free( ms );
|
||||
}
|
||||
|
||||
static void
|
||||
meta_filter_free( metafilter_t *mf )
|
||||
{
|
||||
regfree( &mf->mf_regex );
|
||||
ber_memfree( mf->mf_regex_pattern.bv_val );
|
||||
ch_free( mf );
|
||||
}
|
||||
|
||||
void
|
||||
meta_filter_destroy( metafilter_t *mf )
|
||||
{
|
||||
if ( mf->mf_next )
|
||||
meta_filter_destroy( mf->mf_next );
|
||||
meta_filter_free( mf );
|
||||
}
|
||||
|
||||
static struct berval st_styles[] = {
|
||||
BER_BVC("subtree"),
|
||||
BER_BVC("children"),
|
||||
@ -1603,6 +1630,16 @@ meta_back_cf_gen( ConfigArgs *c )
|
||||
rc = meta_subtree_unparse( c, mt );
|
||||
break;
|
||||
|
||||
case LDAP_BACK_CFG_FILTER:
|
||||
if ( mt->mt_filter == NULL ) {
|
||||
rc = 1;
|
||||
} else {
|
||||
metafilter_t *mf;
|
||||
for ( mf = mt->mt_filter; mf; mf = mf->mf_next )
|
||||
value_add_one( &c->rvalue_vals, &mf->mf_regex_pattern );
|
||||
}
|
||||
break;
|
||||
|
||||
/* replaced by idassert */
|
||||
case LDAP_BACK_CFG_PSEUDOROOTDN:
|
||||
case LDAP_BACK_CFG_PSEUDOROOTPW:
|
||||
@ -1833,6 +1870,26 @@ meta_back_cf_gen( ConfigArgs *c )
|
||||
}
|
||||
break;
|
||||
|
||||
case LDAP_BACK_CFG_FILTER:
|
||||
if ( c->valx < 0 ) {
|
||||
meta_filter_destroy( mt->mt_filter );
|
||||
mt->mt_filter = NULL;
|
||||
} else {
|
||||
metafilter_t *mf, **mprev;
|
||||
for (i=0, mprev = &mt->mt_filter, mf = *mprev; mf; mf = *mprev) {
|
||||
if ( i == c->valx ) {
|
||||
*mprev = mf->mf_next;
|
||||
meta_filter_free( mf );
|
||||
break;
|
||||
}
|
||||
i++;
|
||||
mprev = &mf->mf_next;
|
||||
}
|
||||
if ( i != c->valx )
|
||||
rc = 1;
|
||||
}
|
||||
break;
|
||||
|
||||
case LDAP_BACK_CFG_KEEPALIVE:
|
||||
mt->mt_tls.sb_keepalive.sk_idle = 0;
|
||||
mt->mt_tls.sb_keepalive.sk_probes = 0;
|
||||
@ -2081,6 +2138,25 @@ meta_back_cf_gen( ConfigArgs *c )
|
||||
}
|
||||
break;
|
||||
|
||||
case LDAP_BACK_CFG_FILTER: {
|
||||
metafilter_t *mf, **m2;
|
||||
mf = ch_malloc( sizeof( metafilter_t ));
|
||||
rc = regcomp( &mf->mf_regex, c->argv[1], REG_EXTENDED );
|
||||
if ( rc ) {
|
||||
char regerr[ SLAP_TEXT_BUFLEN ];
|
||||
regerror( rc, &mf->mf_regex, regerr, sizeof(regerr) );
|
||||
snprintf( c->cr_msg, sizeof( c->cr_msg ),
|
||||
"regular expression \"%s\" bad because of %s",
|
||||
c->argv[1], regerr );
|
||||
ch_free( mf );
|
||||
return 1;
|
||||
}
|
||||
ber_str2bv( c->argv[1], 0, 1, &mf->mf_regex_pattern );
|
||||
for ( m2 = &mt->mt_filter; *m2; m2 = &(*m2)->mf_next )
|
||||
;
|
||||
*m2 = mf;
|
||||
} break;
|
||||
|
||||
case LDAP_BACK_CFG_DEFAULT_T:
|
||||
/* default target directive */
|
||||
i = mi->mi_ntargets - 1;
|
||||
|
@ -340,6 +340,10 @@ target_free(
|
||||
meta_subtree_destroy( mt->mt_subtree );
|
||||
mt->mt_subtree = NULL;
|
||||
}
|
||||
if ( mt->mt_filter ) {
|
||||
meta_filter_destroy( mt->mt_filter );
|
||||
mt->mt_filter = NULL;
|
||||
}
|
||||
if ( !BER_BVISNULL( &mt->mt_psuffix ) ) {
|
||||
free( mt->mt_psuffix.bv_val );
|
||||
}
|
||||
|
@ -548,6 +548,20 @@ meta_back_search_start(
|
||||
}
|
||||
}
|
||||
|
||||
/* check filter expression */
|
||||
if ( mt->mt_filter ) {
|
||||
metafilter_t *mf;
|
||||
for ( mf = mt->mt_filter; mf; mf = mf->mf_next ) {
|
||||
if ( regexec( &mf->mf_regex, op->ors_filterstr.bv_val, 0, NULL, 0 ) == 0 )
|
||||
break;
|
||||
}
|
||||
/* nothing matched, this target is no longer a candidate */
|
||||
if ( !mf ) {
|
||||
retcode = META_SEARCH_NOT_CANDIDATE;
|
||||
goto doreturn;
|
||||
}
|
||||
}
|
||||
|
||||
/* initiate dobind */
|
||||
retcode = meta_search_dobind_init( op, rs, mcp, candidate, candidates );
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user