mirror of
https://git.openldap.org/openldap/openldap.git
synced 2025-12-24 16:49:39 -05:00
improved filter mapping/rewrite; improved result rewriting; improved attribute/objectclass mapping configuration
This commit is contained in:
parent
009a9640d4
commit
bf35f8e37f
8 changed files with 661 additions and 238 deletions
|
|
@ -106,6 +106,7 @@ extern int ldap_back_conn_cmp( const void *c1, const void *c2);
|
|||
extern int ldap_back_conn_dup( void *c1, void *c2 );
|
||||
extern void ldap_back_conn_free( void *c );
|
||||
|
||||
/* attributeType/objectClass mapping */
|
||||
int mapping_cmp (const void *, const void *);
|
||||
int mapping_dup (void *, void *);
|
||||
|
||||
|
|
@ -130,6 +131,27 @@ ldap_back_map_attrs(
|
|||
|
||||
extern void mapping_free ( void *mapping );
|
||||
|
||||
extern int ldap_back_map_config(
|
||||
struct ldapmap *oc_map,
|
||||
struct ldapmap *at_map,
|
||||
const char *fname,
|
||||
int lineno,
|
||||
int argc,
|
||||
char **argv );
|
||||
|
||||
extern int
|
||||
ldap_back_filter_map_rewrite_(
|
||||
#ifdef ENABLE_REWRITE
|
||||
struct rewrite_info *info,
|
||||
void *cookie,
|
||||
#endif /* ENABLE_REWRITE */
|
||||
struct ldapmap *at_map,
|
||||
struct ldapmap *oc_map,
|
||||
Filter *f,
|
||||
struct berval *fstr,
|
||||
int remap );
|
||||
|
||||
/* suffix massaging by means of librewrite */
|
||||
#ifdef ENABLE_REWRITE
|
||||
extern int suffix_massage_config( struct rewrite_info *info,
|
||||
struct berval *pvnc, struct berval *nvnc,
|
||||
|
|
|
|||
|
|
@ -239,80 +239,8 @@ ldap_back_db_config(
|
|||
|
||||
/* objectclass/attribute mapping */
|
||||
} else if ( strcasecmp( argv[0], "map" ) == 0 ) {
|
||||
struct ldapmap *map;
|
||||
struct ldapmapping *mapping;
|
||||
char *src, *dst;
|
||||
|
||||
if ( argc < 3 || argc > 4 ) {
|
||||
fprintf( stderr,
|
||||
"%s: line %d: syntax is \"map {objectclass | attribute} [<local> | *] {<foreign> | *}\"\n",
|
||||
fname, lineno );
|
||||
return( 1 );
|
||||
}
|
||||
|
||||
if ( strcasecmp( argv[1], "objectclass" ) == 0 ) {
|
||||
map = &li->oc_map;
|
||||
} else if ( strcasecmp( argv[1], "attribute" ) == 0 ) {
|
||||
map = &li->at_map;
|
||||
} else {
|
||||
fprintf( stderr, "%s: line %d: syntax is "
|
||||
"\"map {objectclass | attribute} [<local> | *] "
|
||||
"{<foreign> | *}\"\n",
|
||||
fname, lineno );
|
||||
return( 1 );
|
||||
}
|
||||
|
||||
if ( strcmp( argv[2], "*" ) == 0 ) {
|
||||
if ( argc < 4 || strcmp( argv[3], "*" ) == 0 ) {
|
||||
map->drop_missing = ( argc < 4 );
|
||||
return 0;
|
||||
}
|
||||
src = dst = argv[3];
|
||||
} else if ( argc < 4 ) {
|
||||
src = "";
|
||||
dst = argv[2];
|
||||
} else {
|
||||
src = argv[2];
|
||||
dst = ( strcmp( argv[3], "*" ) == 0 ? src : argv[3] );
|
||||
}
|
||||
|
||||
if ( ( map == &li->at_map )
|
||||
&& ( strcasecmp( src, "objectclass" ) == 0
|
||||
|| strcasecmp( dst, "objectclass" ) == 0 ) )
|
||||
{
|
||||
fprintf( stderr,
|
||||
"%s: line %d: objectclass attribute cannot be mapped\n",
|
||||
fname, lineno );
|
||||
}
|
||||
|
||||
mapping = (struct ldapmapping *)ch_calloc( 2,
|
||||
sizeof(struct ldapmapping) );
|
||||
if ( mapping == NULL ) {
|
||||
fprintf( stderr,
|
||||
"%s: line %d: out of memory\n",
|
||||
fname, lineno );
|
||||
return( 1 );
|
||||
}
|
||||
ber_str2bv( src, 0, 1, &mapping->src );
|
||||
ber_str2bv( dst, 0, 1, &mapping->dst );
|
||||
mapping[1].src = mapping->dst;
|
||||
mapping[1].dst = mapping->src;
|
||||
|
||||
if ( (*src != '\0' &&
|
||||
avl_find( map->map, (caddr_t)mapping, mapping_cmp ) != NULL) ||
|
||||
avl_find( map->remap, (caddr_t)&mapping[1], mapping_cmp ) != NULL)
|
||||
{
|
||||
fprintf( stderr,
|
||||
"%s: line %d: duplicate mapping found (ignored)\n",
|
||||
fname, lineno );
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ( *src != '\0' )
|
||||
avl_insert( &map->map, (caddr_t)mapping,
|
||||
mapping_cmp, mapping_dup );
|
||||
avl_insert( &map->remap, (caddr_t)&mapping[1],
|
||||
mapping_cmp, mapping_dup );
|
||||
return ldap_back_map_config( &li->oc_map, &li->at_map,
|
||||
fname, lineno, argc, argv );
|
||||
|
||||
/* anything else */
|
||||
} else {
|
||||
|
|
@ -323,6 +251,162 @@ ldap_back_db_config(
|
|||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
ldap_back_map_config(
|
||||
struct ldapmap *oc_map,
|
||||
struct ldapmap *at_map,
|
||||
const char *fname,
|
||||
int lineno,
|
||||
int argc,
|
||||
char **argv )
|
||||
{
|
||||
struct ldapmap *map;
|
||||
struct ldapmapping *mapping;
|
||||
char *src, *dst;
|
||||
int is_oc = 0;
|
||||
|
||||
if ( argc < 3 || argc > 4 ) {
|
||||
fprintf( stderr,
|
||||
"%s: line %d: syntax is \"map {objectclass | attribute} [<local> | *] {<foreign> | *}\"\n",
|
||||
fname, lineno );
|
||||
return 1;
|
||||
}
|
||||
|
||||
if ( strcasecmp( argv[1], "objectclass" ) == 0 ) {
|
||||
map = oc_map;
|
||||
is_oc = 1;
|
||||
|
||||
} else if ( strcasecmp( argv[1], "attribute" ) == 0 ) {
|
||||
map = at_map;
|
||||
|
||||
} else {
|
||||
fprintf( stderr, "%s: line %d: syntax is "
|
||||
"\"map {objectclass | attribute} [<local> | *] "
|
||||
"{<foreign> | *}\"\n",
|
||||
fname, lineno );
|
||||
return 1;
|
||||
}
|
||||
|
||||
if ( strcmp( argv[2], "*" ) == 0 ) {
|
||||
if ( argc < 4 || strcmp( argv[3], "*" ) == 0 ) {
|
||||
map->drop_missing = ( argc < 4 );
|
||||
return 0;
|
||||
}
|
||||
src = dst = argv[3];
|
||||
|
||||
} else if ( argc < 4 ) {
|
||||
src = "";
|
||||
dst = argv[2];
|
||||
|
||||
} else {
|
||||
src = argv[2];
|
||||
dst = ( strcmp( argv[3], "*" ) == 0 ? src : argv[3] );
|
||||
}
|
||||
|
||||
if ( ( map == at_map )
|
||||
&& ( strcasecmp( src, "objectclass" ) == 0
|
||||
|| strcasecmp( dst, "objectclass" ) == 0 ) )
|
||||
{
|
||||
fprintf( stderr,
|
||||
"%s: line %d: objectclass attribute cannot be mapped\n",
|
||||
fname, lineno );
|
||||
}
|
||||
|
||||
mapping = (struct ldapmapping *)ch_calloc( 2,
|
||||
sizeof(struct ldapmapping) );
|
||||
if ( mapping == NULL ) {
|
||||
fprintf( stderr,
|
||||
"%s: line %d: out of memory\n",
|
||||
fname, lineno );
|
||||
return 1;
|
||||
}
|
||||
ber_str2bv( src, 0, 1, &mapping->src );
|
||||
ber_str2bv( dst, 0, 1, &mapping->dst );
|
||||
mapping[1].src = mapping->dst;
|
||||
mapping[1].dst = mapping->src;
|
||||
|
||||
/*
|
||||
* schema check
|
||||
*/
|
||||
if ( is_oc ) {
|
||||
if ( src[0] != '\0' ) {
|
||||
if ( oc_bvfind( &mapping->src ) == NULL ) {
|
||||
fprintf( stderr,
|
||||
"%s: line %d: warning, source objectClass '%s' "
|
||||
"should be defined in schema\n",
|
||||
fname, lineno, src );
|
||||
|
||||
/*
|
||||
* FIXME: this should become an err
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
if ( oc_bvfind( &mapping->dst ) == NULL ) {
|
||||
fprintf( stderr,
|
||||
"%s: line %d: warning, destination objectClass '%s' "
|
||||
"is not defined in schema\n",
|
||||
fname, lineno, dst );
|
||||
}
|
||||
} else {
|
||||
int rc;
|
||||
const char *text = NULL;
|
||||
AttributeDescription *ad = NULL;
|
||||
|
||||
if ( src[0] != '\0' ) {
|
||||
rc = slap_bv2ad( &mapping->src, &ad, &text );
|
||||
if ( rc != LDAP_SUCCESS ) {
|
||||
fprintf( stderr,
|
||||
"%s: line %d: warning, source attributeType '%s' "
|
||||
"should be defined in schema\n",
|
||||
fname, lineno, src );
|
||||
|
||||
/*
|
||||
* FIXME: this should become an err
|
||||
*/
|
||||
}
|
||||
|
||||
ad = NULL;
|
||||
}
|
||||
|
||||
rc = slap_bv2ad( &mapping->dst, &ad, &text );
|
||||
if ( rc != LDAP_SUCCESS ) {
|
||||
fprintf( stderr,
|
||||
"%s: line %d: warning, destination attributeType '%s' "
|
||||
"is not defined in schema\n",
|
||||
fname, lineno, dst );
|
||||
}
|
||||
}
|
||||
|
||||
if ( (src[0] != '\0' && avl_find( map->map, (caddr_t)mapping, mapping_cmp ) != NULL)
|
||||
|| avl_find( map->remap, (caddr_t)&mapping[1], mapping_cmp ) != NULL)
|
||||
{
|
||||
fprintf( stderr,
|
||||
"%s: line %d: duplicate mapping found (ignored)\n",
|
||||
fname, lineno );
|
||||
/* FIXME: free stuff */
|
||||
goto error_return;
|
||||
}
|
||||
|
||||
if ( src[0] != '\0' ) {
|
||||
avl_insert( &map->map, (caddr_t)mapping,
|
||||
mapping_cmp, mapping_dup );
|
||||
}
|
||||
avl_insert( &map->remap, (caddr_t)&mapping[1],
|
||||
mapping_cmp, mapping_dup );
|
||||
|
||||
return 0;
|
||||
|
||||
error_return:;
|
||||
if ( mapping ) {
|
||||
ch_free( mapping->src.bv_val );
|
||||
ch_free( mapping->dst.bv_val );
|
||||
ch_free( mapping );
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
ldap_back_exop_whoami(
|
||||
Connection *conn,
|
||||
|
|
@ -504,6 +588,15 @@ suffix_massage_config(
|
|||
ch_free( rargv[ 1 ] );
|
||||
ch_free( rargv[ 2 ] );
|
||||
|
||||
#if 0
|
||||
/*
|
||||
* FIXME: this is no longer required since now we map filters
|
||||
* based on the parsed filter structure, so we can deal directly
|
||||
* with attribute types and values. The rewriteContext
|
||||
* "searchFilter" now refers to the value of attrbutes
|
||||
* with DN syntax.
|
||||
*/
|
||||
|
||||
/*
|
||||
* the filter should be rewritten as
|
||||
*
|
||||
|
|
@ -580,6 +673,7 @@ suffix_massage_config(
|
|||
}
|
||||
}
|
||||
#endif /* rewrite filters */
|
||||
#endif
|
||||
|
||||
#if 0 /* "matched" is not normalized */
|
||||
rargv[ 0 ] = "rewriteContext";
|
||||
|
|
|
|||
|
|
@ -175,6 +175,10 @@ ldap_back_map_filter(
|
|||
tmp.bv_val = q;
|
||||
ldap_back_map(at_map, &tmp, &m, remap);
|
||||
if (m.bv_val == NULL || m.bv_val[0] == '\0') {
|
||||
/*
|
||||
* FIXME: are we sure we need to search
|
||||
* oc_map if at_map fails?
|
||||
*/
|
||||
ldap_back_map(oc_map, &tmp, &m, remap);
|
||||
if (m.bv_val == NULL || m.bv_val[0] == '\0') {
|
||||
m = tmp;
|
||||
|
|
@ -244,3 +248,392 @@ ldap_back_map_attrs(
|
|||
return(na);
|
||||
}
|
||||
|
||||
#ifdef ENABLE_REWRITE
|
||||
|
||||
static int
|
||||
map_attr_value_(
|
||||
struct rewrite_info *info,
|
||||
void *cookie,
|
||||
struct ldapmap *at_map,
|
||||
struct ldapmap *oc_map,
|
||||
AttributeDescription *ad,
|
||||
struct berval *mapped_attr,
|
||||
struct berval *value,
|
||||
struct berval *mapped_value,
|
||||
int remap )
|
||||
{
|
||||
struct berval vtmp;
|
||||
int freeval = 0;
|
||||
|
||||
ldap_back_map( at_map, &ad->ad_cname, mapped_attr, remap );
|
||||
if ( mapped_attr->bv_val == NULL || mapped_attr->bv_val[0] == '\0') {
|
||||
/*
|
||||
* FIXME: are we sure we need to search oc_map if at_map fails?
|
||||
*/
|
||||
ldap_back_map( oc_map, &ad->ad_cname, mapped_attr, remap );
|
||||
if ( mapped_attr->bv_val == NULL || mapped_attr->bv_val[0] == '\0' ) {
|
||||
*mapped_attr = ad->ad_cname;
|
||||
}
|
||||
}
|
||||
|
||||
if ( value == NULL ) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ( strcmp( ad->ad_type->sat_syntax->ssyn_oid, SLAPD_DN_SYNTAX ) == 0 )
|
||||
{
|
||||
switch ( rewrite_session( info, "searchFilter",
|
||||
value->bv_val, cookie, &vtmp.bv_val ) ) {
|
||||
case REWRITE_REGEXEC_OK:
|
||||
if ( vtmp.bv_val == NULL ) {
|
||||
vtmp = *value;
|
||||
} else {
|
||||
vtmp.bv_len = strlen( vtmp.bv_val );
|
||||
freeval = 1;
|
||||
}
|
||||
#ifdef NEW_LOGGING
|
||||
LDAP_LOG( BACK_LDAP, DETAIL1,
|
||||
"[rw] searchFilter: \"%s\" -> \"%s\"\n",
|
||||
value->bv_val, vtmp.bv_val, 0 );
|
||||
#else /* !NEW_LOGGING */
|
||||
Debug( LDAP_DEBUG_ARGS, "rw> searchFilter: \"%s\" -> \"%s\"\n%s",
|
||||
value->bv_val, vtmp.bv_val, "" );
|
||||
#endif /* !NEW_LOGGING */
|
||||
break;
|
||||
|
||||
|
||||
case REWRITE_REGEXEC_UNWILLING:
|
||||
return -1;
|
||||
|
||||
case REWRITE_REGEXEC_ERR:
|
||||
return -1;
|
||||
}
|
||||
|
||||
} else if ( ad == slap_schema.si_ad_objectClass || ad == slap_schema.si_ad_structuralObjectClass ) {
|
||||
ldap_back_map( oc_map, value, &vtmp, remap );
|
||||
if ( vtmp.bv_val == NULL || vtmp.bv_val[0] == '\0' ) {
|
||||
vtmp = *value;
|
||||
}
|
||||
|
||||
} else {
|
||||
vtmp = *value;
|
||||
}
|
||||
|
||||
filter_escape_value( &vtmp, mapped_value );
|
||||
|
||||
if ( freeval ) {
|
||||
ber_memfree( vtmp.bv_val );
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define map_attr_value(at_map, oc_map, ad, mapped_attr, value, mapped_value, remap) \
|
||||
map_attr_value_(info, cookie, (at_map), (oc_map), (ad), (mapped_attr), (value), (mapped_value), (remap))
|
||||
#define ldap_back_filter_map_rewrite(at_map, oc_map, f, fstr, remap) \
|
||||
ldap_back_filter_map_rewrite_(info, cookie, (at_map), (oc_map), (f), (fstr), (remap))
|
||||
|
||||
#else /* ! ENABLE_REWRITE */
|
||||
|
||||
static int
|
||||
map_attr_value_(
|
||||
struct ldapmap *at_map,
|
||||
struct ldapmap *oc_map,
|
||||
AttributeDescription *ad,
|
||||
struct berval *mapped_attr,
|
||||
struct berval *value,
|
||||
struct berval *mapped_value,
|
||||
int remap )
|
||||
{
|
||||
struct berval vtmp;
|
||||
|
||||
ldap_back_map( at_map, &ad->ad_cname, mapped_attr, remap );
|
||||
if ( mapped_attr->bv_val == NULL || mapped_attr->bv_val[0] == '\0') {
|
||||
/*
|
||||
* FIXME: are we sure we need to search oc_map if at_map fails?
|
||||
*/
|
||||
ldap_back_map( oc_map, &ad->ad_cname, mapped_attr, remap );
|
||||
if ( mapped_attr->bv_val == NULL || mapped_attr->bv_val[0] == '\0' ) {
|
||||
*mapped_attr = ad->ad_cname;
|
||||
}
|
||||
}
|
||||
|
||||
if ( value == NULL ) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ( strcmp( ad->ad_type->sat_syntax->ssyn_oid, SLAPD_DN_SYNTAX ) == 0 )
|
||||
{
|
||||
/* FIXME: use suffix massage capabilities */
|
||||
vtmp = *value;
|
||||
|
||||
} else if ( ad == slap_schema.si_ad_objectClass || ad == slap_schema.si_ad_structuralObjectClass ) {
|
||||
ldap_back_map( oc_map, value, &vtmp, remap );
|
||||
if ( vtmp.bv_val == NULL || vtmp.bv_val[0] == '\0' ) {
|
||||
vtmp = *value;
|
||||
}
|
||||
|
||||
} else {
|
||||
vtmp = *value;
|
||||
}
|
||||
|
||||
filter_escape_value( &vtmp, mapped_value );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define map_attr_value(at_map, oc_map, ad, mapped_attr, value, mapped_value, remap) \
|
||||
map_attr_value_((at_map), (oc_map), (ad), (mapped_attr), (value), (mapped_value), (remap))
|
||||
#define ldap_back_filter_map_rewrite(at_map, oc_map, f, fstr, remap) \
|
||||
ldap_back_filter_map_rewrite_((at_map), (oc_map), (f), (fstr), (remap))
|
||||
|
||||
#endif /* ! ENABLE_REWRITE */
|
||||
|
||||
int
|
||||
ldap_back_filter_map_rewrite_(
|
||||
#ifdef ENABLE_REWRITE
|
||||
struct rewrite_info *info,
|
||||
void *cookie,
|
||||
#endif /* ENABLE_REWRITE */
|
||||
struct ldapmap *at_map,
|
||||
struct ldapmap *oc_map,
|
||||
Filter *f,
|
||||
struct berval *fstr,
|
||||
int remap )
|
||||
{
|
||||
int i;
|
||||
Filter *p;
|
||||
struct berval atmp;
|
||||
struct berval vtmp;
|
||||
ber_len_t len;
|
||||
|
||||
if ( f == NULL ) {
|
||||
ber_str2bv( "No filter!", sizeof("No filter!")-1, 1, fstr );
|
||||
return -1;
|
||||
}
|
||||
|
||||
switch ( f->f_choice ) {
|
||||
case LDAP_FILTER_EQUALITY:
|
||||
if ( map_attr_value( at_map, oc_map, f->f_av_desc, &atmp,
|
||||
&f->f_av_value, &vtmp, remap ) )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
fstr->bv_len = atmp.bv_len + vtmp.bv_len
|
||||
+ ( sizeof("(=)") - 1 );
|
||||
fstr->bv_val = malloc( fstr->bv_len + 1 );
|
||||
|
||||
snprintf( fstr->bv_val, fstr->bv_len + 1, "(%s=%s)",
|
||||
atmp.bv_val, vtmp.bv_val );
|
||||
|
||||
ber_memfree( vtmp.bv_val );
|
||||
break;
|
||||
|
||||
case LDAP_FILTER_GE:
|
||||
if ( map_attr_value( at_map, oc_map, f->f_av_desc, &atmp,
|
||||
&f->f_av_value, &vtmp, remap ) )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
fstr->bv_len = atmp.bv_len + vtmp.bv_len
|
||||
+ ( sizeof("(>=)") - 1 );
|
||||
fstr->bv_val = malloc( fstr->bv_len + 1 );
|
||||
|
||||
snprintf( fstr->bv_val, fstr->bv_len + 1, "(%s>=%s)",
|
||||
atmp.bv_val, vtmp.bv_val );
|
||||
|
||||
ber_memfree( vtmp.bv_val );
|
||||
break;
|
||||
|
||||
case LDAP_FILTER_LE:
|
||||
if ( map_attr_value( at_map, oc_map, f->f_av_desc, &atmp,
|
||||
&f->f_av_value, &vtmp, remap ) )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
fstr->bv_len = atmp.bv_len + vtmp.bv_len
|
||||
+ ( sizeof("(<=)") - 1 );
|
||||
fstr->bv_val = malloc( fstr->bv_len + 1 );
|
||||
|
||||
snprintf( fstr->bv_val, fstr->bv_len + 1, "(%s<=%s)",
|
||||
atmp.bv_val, vtmp.bv_val );
|
||||
|
||||
ber_memfree( vtmp.bv_val );
|
||||
break;
|
||||
|
||||
case LDAP_FILTER_APPROX:
|
||||
if ( map_attr_value( at_map, oc_map, f->f_av_desc, &atmp,
|
||||
&f->f_av_value, &vtmp, remap ) )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
fstr->bv_len = atmp.bv_len + vtmp.bv_len
|
||||
+ ( sizeof("(~=)") - 1 );
|
||||
fstr->bv_val = malloc( fstr->bv_len + 1 );
|
||||
|
||||
snprintf( fstr->bv_val, fstr->bv_len + 1, "(%s~=%s)",
|
||||
atmp.bv_val, vtmp.bv_val );
|
||||
|
||||
ber_memfree( vtmp.bv_val );
|
||||
break;
|
||||
|
||||
case LDAP_FILTER_SUBSTRINGS:
|
||||
if ( map_attr_value( at_map, oc_map, f->f_sub_desc, &atmp,
|
||||
NULL, NULL, remap ) )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* cannot be a DN ... */
|
||||
|
||||
fstr->bv_len = atmp.bv_len + ( sizeof("(=*)") - 1 );
|
||||
fstr->bv_val = malloc( fstr->bv_len + 128 );
|
||||
|
||||
snprintf( fstr->bv_val, fstr->bv_len + 1, "(%s=*)",
|
||||
atmp.bv_val );
|
||||
|
||||
if ( f->f_sub_initial.bv_val != NULL ) {
|
||||
len = fstr->bv_len;
|
||||
|
||||
filter_escape_value( &f->f_sub_initial, &vtmp );
|
||||
|
||||
fstr->bv_len += vtmp.bv_len;
|
||||
fstr->bv_val = ch_realloc( fstr->bv_val, fstr->bv_len + 1 );
|
||||
|
||||
snprintf( &fstr->bv_val[len - 2], vtmp.bv_len + 3,
|
||||
/* "(attr=" */ "%s*)",
|
||||
vtmp.bv_val );
|
||||
|
||||
ber_memfree( vtmp.bv_val );
|
||||
}
|
||||
|
||||
if ( f->f_sub_any != NULL ) {
|
||||
for ( i = 0; f->f_sub_any[i].bv_val != NULL; i++ ) {
|
||||
len = fstr->bv_len;
|
||||
filter_escape_value( &f->f_sub_any[i], &vtmp );
|
||||
|
||||
fstr->bv_len += vtmp.bv_len + 1;
|
||||
fstr->bv_val = ch_realloc( fstr->bv_val, fstr->bv_len + 1 );
|
||||
|
||||
snprintf( &fstr->bv_val[len - 1], vtmp.bv_len + 3,
|
||||
/* "(attr=[init]*[any*]" */ "%s*)",
|
||||
vtmp.bv_val );
|
||||
ber_memfree( vtmp.bv_val );
|
||||
}
|
||||
}
|
||||
|
||||
if ( f->f_sub_final.bv_val != NULL ) {
|
||||
len = fstr->bv_len;
|
||||
|
||||
filter_escape_value( &f->f_sub_final, &vtmp );
|
||||
|
||||
fstr->bv_len += vtmp.bv_len;
|
||||
fstr->bv_val = ch_realloc( fstr->bv_val, fstr->bv_len + 1 );
|
||||
|
||||
snprintf( &fstr->bv_val[len - 1], vtmp.bv_len + 3,
|
||||
/* "(attr=[init*][any*]" */ "%s)",
|
||||
vtmp.bv_val );
|
||||
|
||||
ber_memfree( vtmp.bv_val );
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case LDAP_FILTER_PRESENT:
|
||||
if ( map_attr_value( at_map, oc_map, f->f_desc, &atmp,
|
||||
NULL, NULL, remap ) )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
fstr->bv_len = atmp.bv_len + ( sizeof("(=*)") - 1 );
|
||||
fstr->bv_val = malloc( fstr->bv_len + 1 );
|
||||
|
||||
snprintf( fstr->bv_val, fstr->bv_len + 1, "(%s=*)",
|
||||
atmp.bv_val );
|
||||
break;
|
||||
|
||||
case LDAP_FILTER_AND:
|
||||
case LDAP_FILTER_OR:
|
||||
case LDAP_FILTER_NOT:
|
||||
fstr->bv_len = sizeof("(%)") - 1;
|
||||
fstr->bv_val = malloc( fstr->bv_len + 128 );
|
||||
|
||||
snprintf( fstr->bv_val, fstr->bv_len + 1, "(%c)",
|
||||
f->f_choice == LDAP_FILTER_AND ? '&' :
|
||||
f->f_choice == LDAP_FILTER_OR ? '|' : '!' );
|
||||
|
||||
for ( p = f->f_list; p != NULL; p = p->f_next ) {
|
||||
len = fstr->bv_len;
|
||||
|
||||
if ( ldap_back_filter_map_rewrite( at_map, oc_map, p, &vtmp, remap ) )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
fstr->bv_len += vtmp.bv_len;
|
||||
fstr->bv_val = ch_realloc( fstr->bv_val, fstr->bv_len + 1 );
|
||||
|
||||
snprintf( &fstr->bv_val[len-1], vtmp.bv_len + 2,
|
||||
/*"("*/ "%s)", vtmp.bv_val );
|
||||
|
||||
ch_free( vtmp.bv_val );
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case LDAP_FILTER_EXT: {
|
||||
if ( f->f_mr_desc ) {
|
||||
if ( map_attr_value( at_map, oc_map, f->f_mr_desc, &atmp,
|
||||
&f->f_mr_value, &vtmp, remap ) )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
} else {
|
||||
atmp.bv_len = 0;
|
||||
atmp.bv_val = "";
|
||||
|
||||
filter_escape_value( &f->f_mr_value, &vtmp );
|
||||
}
|
||||
|
||||
|
||||
fstr->bv_len = atmp.bv_len +
|
||||
( f->f_mr_dnattrs ? sizeof(":dn")-1 : 0 ) +
|
||||
( f->f_mr_rule_text.bv_len ? f->f_mr_rule_text.bv_len+1 : 0 ) +
|
||||
vtmp.bv_len + ( sizeof("(:=)") - 1 );
|
||||
fstr->bv_val = malloc( fstr->bv_len + 1 );
|
||||
|
||||
snprintf( fstr->bv_val, fstr->bv_len + 1, "(%s%s%s%s:=%s)",
|
||||
atmp.bv_val,
|
||||
f->f_mr_dnattrs ? ":dn" : "",
|
||||
f->f_mr_rule_text.bv_len ? ":" : "",
|
||||
f->f_mr_rule_text.bv_len ? f->f_mr_rule_text.bv_val : "",
|
||||
vtmp.bv_val );
|
||||
ber_memfree( vtmp.bv_val );
|
||||
} break;
|
||||
|
||||
case SLAPD_FILTER_COMPUTED:
|
||||
ber_str2bv(
|
||||
f->f_result == LDAP_COMPARE_FALSE ? "(?=false)" :
|
||||
f->f_result == LDAP_COMPARE_TRUE ? "(?=true)" :
|
||||
f->f_result == SLAPD_COMPARE_UNDEFINED ? "(?=undefined)" :
|
||||
"(?=error)",
|
||||
f->f_result == LDAP_COMPARE_FALSE ? sizeof("(?=false)")-1 :
|
||||
f->f_result == LDAP_COMPARE_TRUE ? sizeof("(?=true)")-1 :
|
||||
f->f_result == SLAPD_COMPARE_UNDEFINED ? sizeof("(?=undefined)")-1 :
|
||||
sizeof("(?=error)")-1,
|
||||
1, fstr );
|
||||
break;
|
||||
|
||||
default:
|
||||
ber_str2bv( "(?=unknown)", sizeof("(?=unknown)")-1, 1, fstr );
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -74,12 +74,12 @@ ldap_back_search(
|
|||
LDAPMessage *res, *e;
|
||||
int count, rc = 0, msgid, sres = LDAP_SUCCESS;
|
||||
char *match = NULL, *err = NULL;
|
||||
char *mapped_filter = NULL, **mapped_attrs = NULL;
|
||||
char **mapped_attrs = NULL;
|
||||
struct berval mbase;
|
||||
#ifdef ENABLE_REWRITE
|
||||
char *mmatch = NULL;
|
||||
struct berval mfilter = { 0, NULL };
|
||||
#endif /* ENABLE_REWRITE */
|
||||
struct berval mfilter = { 0, NULL };
|
||||
struct slap_limits_set *limit = NULL;
|
||||
int isroot = 0;
|
||||
BerVarray v2refs = NULL;
|
||||
|
|
@ -186,69 +186,24 @@ ldap_back_search(
|
|||
rc = -1;
|
||||
goto finish;
|
||||
}
|
||||
|
||||
/*
|
||||
* Rewrite the search filter, if required
|
||||
*/
|
||||
switch ( rewrite_session( li->rwinfo, "searchFilter",
|
||||
filterstr->bv_val, conn, &mfilter.bv_val ) ) {
|
||||
case REWRITE_REGEXEC_OK:
|
||||
if ( mfilter.bv_val == NULL || mfilter.bv_val[0] == '\0') {
|
||||
if ( mfilter.bv_val != NULL ) {
|
||||
free( mfilter.bv_val );
|
||||
}
|
||||
mfilter = *filterstr;
|
||||
} else {
|
||||
mfilter.bv_len = strlen( mfilter.bv_val );
|
||||
}
|
||||
|
||||
#ifdef NEW_LOGGING
|
||||
LDAP_LOG( BACK_LDAP, DETAIL1,
|
||||
"[rw] searchFilter: \"%s\" -> \"%s\"\n",
|
||||
filterstr->bv_val, mfilter.bv_val, 0 );
|
||||
#else /* !NEW_LOGGING */
|
||||
Debug( LDAP_DEBUG_ARGS,
|
||||
"rw> searchFilter: \"%s\" -> \"%s\"\n%s",
|
||||
filterstr->bv_val, mfilter.bv_val, "" );
|
||||
#endif /* !NEW_LOGGING */
|
||||
break;
|
||||
|
||||
case REWRITE_REGEXEC_UNWILLING:
|
||||
send_ldap_result( conn, op, LDAP_UNWILLING_TO_PERFORM,
|
||||
NULL, "Operation not allowed", NULL, NULL );
|
||||
rc = -1;
|
||||
goto finish;
|
||||
|
||||
case REWRITE_REGEXEC_ERR:
|
||||
send_ldap_result( conn, op, LDAP_OTHER,
|
||||
NULL, "Rewrite error", NULL, NULL );
|
||||
rc = -1;
|
||||
goto finish;
|
||||
}
|
||||
#else /* !ENABLE_REWRITE */
|
||||
ldap_back_dn_massage( li, base, &mbase, 0, 1 );
|
||||
#endif /* !ENABLE_REWRITE */
|
||||
|
||||
mapped_filter = ldap_back_map_filter(&li->at_map, &li->oc_map,
|
||||
#ifdef ENABLE_REWRITE
|
||||
&mfilter,
|
||||
#else /* !ENABLE_REWRITE */
|
||||
filterstr,
|
||||
#endif /* !ENABLE_REWRITE */
|
||||
BACKLDAP_MAP);
|
||||
if ( mapped_filter == NULL ) {
|
||||
#ifdef ENABLE_REWRITE
|
||||
mapped_filter = mfilter.bv_val;
|
||||
#else /* !ENABLE_REWRITE */
|
||||
mapped_filter = filterstr->bv_val;
|
||||
#endif /* !ENABLE_REWRITE */
|
||||
}
|
||||
rc = ldap_back_filter_map_rewrite_( li->rwinfo, conn,
|
||||
&li->at_map, &li->oc_map, filter, &mfilter,
|
||||
BACKLDAP_MAP );
|
||||
#else /* ! ENABLE_REWRITE */
|
||||
rc = ldap_back_filter_map_rewrite_( &li->at_map, &li->oc_map,
|
||||
filter, &mfilter, BACKLDAP_MAP );
|
||||
#endif /* ! ENABLE_REWRITE */
|
||||
|
||||
#ifdef ENABLE_REWRITE
|
||||
if ( mfilter.bv_val != filterstr->bv_val ) {
|
||||
free( mfilter.bv_val );
|
||||
if ( rc ) {
|
||||
rc = -1;
|
||||
goto finish;
|
||||
}
|
||||
#endif /* ENABLE_REWRITE */
|
||||
|
||||
mapped_attrs = ldap_back_map_attrs(&li->at_map, attrs, BACKLDAP_MAP);
|
||||
if ( mapped_attrs == NULL && attrs) {
|
||||
|
|
@ -260,7 +215,7 @@ ldap_back_search(
|
|||
mapped_attrs[count] = NULL;
|
||||
}
|
||||
|
||||
rc = ldap_search_ext(lc->ld, mbase.bv_val, scope, mapped_filter,
|
||||
rc = ldap_search_ext(lc->ld, mbase.bv_val, scope, mfilter.bv_val,
|
||||
mapped_attrs, attrsonly, op->o_ctrls, NULL, tv.tv_sec ? &tv
|
||||
: NULL, slimit, &msgid);
|
||||
if ( rc != LDAP_SUCCESS ) {
|
||||
|
|
@ -412,8 +367,8 @@ finish:;
|
|||
if ( mapped_attrs ) {
|
||||
ch_free( mapped_attrs );
|
||||
}
|
||||
if ( mapped_filter != filterstr->bv_val ) {
|
||||
ch_free( mapped_filter );
|
||||
if ( mfilter.bv_val != filterstr->bv_val ) {
|
||||
ch_free( mfilter.bv_val );
|
||||
}
|
||||
if ( mbase.bv_val != base->bv_val ) {
|
||||
free( mbase.bv_val );
|
||||
|
|
@ -533,10 +488,11 @@ ldap_send_entry(
|
|||
|
||||
} else if ( attr->a_desc == slap_schema.si_ad_objectClass
|
||||
|| attr->a_desc == slap_schema.si_ad_structuralObjectClass ) {
|
||||
int i, last;
|
||||
int last;
|
||||
|
||||
for ( last = 0; attr->a_vals[last].bv_val; last++ ) ;
|
||||
for ( i = 0, bv = attr->a_vals; bv->bv_val; bv++, i++ ) {
|
||||
for ( last = 0; attr->a_vals[last].bv_val; last++ );
|
||||
|
||||
for ( bv = attr->a_vals; bv->bv_val; bv++ ) {
|
||||
ldap_back_map(&li->oc_map, bv, &mapped,
|
||||
BACKLDAP_REMAP);
|
||||
if (mapped.bv_val == NULL || mapped.bv_val[0] == '\0') {
|
||||
|
|
@ -546,7 +502,8 @@ ldap_send_entry(
|
|||
break;
|
||||
*bv = attr->a_vals[last];
|
||||
attr->a_vals[last].bv_val = NULL;
|
||||
i--;
|
||||
bv--;
|
||||
|
||||
} else if ( mapped.bv_val != bv->bv_val ) {
|
||||
/*
|
||||
* FIXME: after LBER_FREEing
|
||||
|
|
@ -571,9 +528,12 @@ ldap_send_entry(
|
|||
*/
|
||||
} else if ( strcmp( attr->a_desc->ad_type->sat_syntax->ssyn_oid,
|
||||
SLAPD_DN_SYNTAX ) == 0 ) {
|
||||
int i;
|
||||
for ( i = 0, bv = attr->a_vals; bv->bv_val; bv++, i++ ) {
|
||||
struct berval newval;
|
||||
int last;
|
||||
|
||||
for ( last = 0; attr->a_vals[last].bv_val; last++ );
|
||||
|
||||
for ( bv = attr->a_vals; bv->bv_val; bv++ ) {
|
||||
struct berval newval;
|
||||
|
||||
#ifdef ENABLE_REWRITE
|
||||
switch ( rewrite_session( li->rwinfo,
|
||||
|
|
@ -603,7 +563,15 @@ ldap_send_entry(
|
|||
break;
|
||||
|
||||
case REWRITE_REGEXEC_UNWILLING:
|
||||
|
||||
LBER_FREE(bv->bv_val);
|
||||
bv->bv_val = NULL;
|
||||
if (--last < 0)
|
||||
goto next_attr;
|
||||
*bv = attr->a_vals[last];
|
||||
attr->a_vals[last].bv_val = NULL;
|
||||
bv--;
|
||||
break;
|
||||
|
||||
case REWRITE_REGEXEC_ERR:
|
||||
/*
|
||||
* FIXME: better give up,
|
||||
|
|
@ -619,6 +587,8 @@ ldap_send_entry(
|
|||
}
|
||||
}
|
||||
|
||||
next_attr:;
|
||||
|
||||
*attrp = attr;
|
||||
attrp = &attr->a_next;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -512,87 +512,11 @@ meta_back_db_config(
|
|||
|
||||
/* objectclass/attribute mapping */
|
||||
} else if ( strcasecmp( argv[ 0 ], "map" ) == 0 ) {
|
||||
struct ldapmap *map;
|
||||
struct ldapmapping *mapping;
|
||||
char *src, *dst;
|
||||
int i = li->ntargets-1;
|
||||
|
||||
if ( i < 0 ) {
|
||||
fprintf( stderr,
|
||||
"%s: line %d: need \"uri\" directive first\n",
|
||||
fname, lineno );
|
||||
}
|
||||
|
||||
|
||||
if ( argc < 3 || argc > 4 ) {
|
||||
fprintf( stderr,
|
||||
"%s: line %d: syntax is \"map {objectclass | attribute} [<local> | *] {<foreign> | *}\"\n",
|
||||
fname, lineno );
|
||||
return 1;
|
||||
}
|
||||
|
||||
if ( strcasecmp( argv[ 1 ], "objectClass" ) == 0 ) {
|
||||
map = &li->targets[ i ]->oc_map;
|
||||
} else if ( strcasecmp( argv[ 1 ], "attribute" ) == 0 ) {
|
||||
map = &li->targets[ i ]->at_map;
|
||||
} else {
|
||||
fprintf( stderr,
|
||||
"%s: line %d: syntax is \"map {objectclass | attribute} [<local> | *] {<foreign> | *}\"\n",
|
||||
fname, lineno );
|
||||
return 1;
|
||||
}
|
||||
|
||||
if ( strcmp( argv[ 2 ], "*" ) == 0 ) {
|
||||
if ( argc < 4 || strcmp( argv[ 3 ], "*" ) == 0 ) {
|
||||
map->drop_missing = ( argc < 4 );
|
||||
return 0;
|
||||
}
|
||||
src = dst = argv[ 3 ];
|
||||
} else if ( argc < 4 ) {
|
||||
src = "";
|
||||
dst = argv[ 2 ];
|
||||
} else {
|
||||
src = argv[ 2 ];
|
||||
dst = ( strcmp( argv[ 3 ], "*" ) == 0 ? src : argv[ 3 ] );
|
||||
}
|
||||
|
||||
if ( ( map == &li->targets[ i ]->at_map )
|
||||
&& ( strcasecmp( src, "objectclass" ) == 0
|
||||
|| strcasecmp( dst, "objectclass" ) == 0 ) ) {
|
||||
fprintf( stderr,
|
||||
"%s: line %d: objectclass attribute cannot be mapped\n",
|
||||
fname, lineno );
|
||||
}
|
||||
|
||||
mapping = ch_calloc( 2, sizeof( struct ldapmapping ) );
|
||||
if ( mapping == NULL ) {
|
||||
fprintf( stderr,
|
||||
"%s: line %d: out of memory\n",
|
||||
fname, lineno );
|
||||
return 1;
|
||||
}
|
||||
ber_str2bv( src, 0, 1, &mapping->src );
|
||||
ber_str2bv( dst, 0, 1, &mapping->dst );
|
||||
mapping[ 1 ].src = mapping->dst;
|
||||
mapping[ 1 ].dst = mapping->src;
|
||||
|
||||
if ( (*src != '\0' &&
|
||||
avl_find( map->map, ( caddr_t )mapping,
|
||||
mapping_cmp ) != NULL)
|
||||
|| avl_find( map->remap, ( caddr_t )&mapping[ 1 ],
|
||||
mapping_cmp ) != NULL) {
|
||||
fprintf( stderr,
|
||||
"%s: line %d: duplicate mapping found (ignored)\n",
|
||||
fname, lineno );
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ( *src != '\0' )
|
||||
avl_insert( &map->map, ( caddr_t )mapping,
|
||||
mapping_cmp, mapping_dup );
|
||||
avl_insert( &map->remap, ( caddr_t )&mapping[ 1 ],
|
||||
mapping_cmp, mapping_dup );
|
||||
|
||||
return ldap_back_map_config( &li->targets[ i ]->oc_map,
|
||||
&li->targets[ i ]->at_map,
|
||||
fname, lineno, argc, argv );
|
||||
/* anything else */
|
||||
} else {
|
||||
fprintf( stderr,
|
||||
|
|
|
|||
|
|
@ -207,7 +207,7 @@ meta_back_search(
|
|||
char *realbase = ( char * )base->bv_val;
|
||||
int realscope = scope;
|
||||
ber_len_t suffixlen;
|
||||
char *mapped_filter, **mapped_attrs;
|
||||
char **mapped_attrs;
|
||||
|
||||
if ( lsc->candidate != META_CANDIDATE ) {
|
||||
msgid[ i ] = -1;
|
||||
|
|
@ -311,7 +311,8 @@ meta_back_search(
|
|||
rc = -1;
|
||||
goto finish;
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
/*
|
||||
* Rewrite the search filter, if required
|
||||
*/
|
||||
|
|
@ -367,7 +368,12 @@ meta_back_search(
|
|||
}
|
||||
mfilter.bv_val = NULL;
|
||||
mfilter.bv_len = 0;
|
||||
#endif
|
||||
|
||||
rc = ldap_back_filter_map_rewrite_( li->targets[ i ]->rwinfo, conn,
|
||||
&li->targets[ i ]->at_map, &li->targets[ i ]->oc_map,
|
||||
filter, &mfilter, BACKLDAP_MAP );
|
||||
|
||||
/*
|
||||
* Maps required attributes
|
||||
*/
|
||||
|
|
@ -386,14 +392,14 @@ meta_back_search(
|
|||
* Starts the search
|
||||
*/
|
||||
msgid[ i ] = ldap_search( lsc->ld, mbase, realscope,
|
||||
mapped_filter, mapped_attrs, attrsonly );
|
||||
mfilter.bv_val, mapped_attrs, attrsonly );
|
||||
if ( mapped_attrs ) {
|
||||
free( mapped_attrs );
|
||||
mapped_attrs = NULL;
|
||||
}
|
||||
if ( mapped_filter != filterstr->bv_val ) {
|
||||
free( mapped_filter );
|
||||
mapped_filter = NULL;
|
||||
if ( mfilter.bv_val != filterstr->bv_val ) {
|
||||
free( mfilter.bv_val );
|
||||
mfilter.bv_val = NULL;
|
||||
}
|
||||
if ( mbase != realbase ) {
|
||||
free( mbase );
|
||||
|
|
@ -782,9 +788,11 @@ meta_send_entry(
|
|||
|
||||
} else if ( attr->a_desc == slap_schema.si_ad_objectClass
|
||||
|| attr->a_desc == slap_schema.si_ad_structuralObjectClass ) {
|
||||
int i, last;
|
||||
int last;
|
||||
|
||||
for ( last = 0; attr->a_vals[ last ].bv_val; ++last );
|
||||
for ( i = 0, bv = attr->a_vals; bv->bv_val; bv++, i++ ) {
|
||||
|
||||
for ( bv = attr->a_vals; bv->bv_val; bv++ ) {
|
||||
ldap_back_map( &li->targets[ target]->oc_map,
|
||||
bv, &mapped, BACKLDAP_REMAP );
|
||||
if ( mapped.bv_val == NULL || mapped.bv_val[0] == '\0') {
|
||||
|
|
@ -795,7 +803,7 @@ meta_send_entry(
|
|||
}
|
||||
*bv = attr->a_vals[ last ];
|
||||
attr->a_vals[ last ].bv_val = NULL;
|
||||
i--;
|
||||
bv--;
|
||||
|
||||
} else if ( mapped.bv_val != bv->bv_val ) {
|
||||
free( bv->bv_val );
|
||||
|
|
@ -815,8 +823,11 @@ meta_send_entry(
|
|||
*/
|
||||
} else if ( strcmp( attr->a_desc->ad_type->sat_syntax->ssyn_oid,
|
||||
SLAPD_DN_SYNTAX ) == 0 ) {
|
||||
int i;
|
||||
for ( i = 0, bv = attr->a_vals; bv->bv_val; bv++, i++ ) {
|
||||
int last;
|
||||
|
||||
for ( last = 0; attr->a_vals[ last ].bv_val; ++last );
|
||||
|
||||
for ( bv = attr->a_vals; bv->bv_val; bv++ ) {
|
||||
char *newval;
|
||||
|
||||
switch ( rewrite_session( li->targets[ target ]->rwinfo,
|
||||
|
|
@ -847,7 +858,15 @@ meta_send_entry(
|
|||
break;
|
||||
|
||||
case REWRITE_REGEXEC_UNWILLING:
|
||||
|
||||
LBER_FREE(bv->bv_val);
|
||||
bv->bv_val = NULL;
|
||||
if (--last < 0)
|
||||
goto next_attr;
|
||||
*bv = attr->a_vals[last];
|
||||
attr->a_vals[last].bv_val = NULL;
|
||||
bv--;
|
||||
break;
|
||||
|
||||
case REWRITE_REGEXEC_ERR:
|
||||
/*
|
||||
* FIXME: better give up,
|
||||
|
|
@ -858,6 +877,8 @@ meta_send_entry(
|
|||
}
|
||||
}
|
||||
}
|
||||
next_attr:;
|
||||
|
||||
*attrp = attr;
|
||||
attrp = &attr->a_next;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,10 +26,6 @@ static int get_substring_filter(
|
|||
Filter *f,
|
||||
const char **text );
|
||||
|
||||
static int filter_escape_value(
|
||||
struct berval *in,
|
||||
struct berval *out );
|
||||
|
||||
static void simple_vrFilter2bv(
|
||||
ValuesReturnFilter *f,
|
||||
struct berval *fstr );
|
||||
|
|
@ -797,7 +793,8 @@ filter2bv( Filter *f, struct berval *fstr )
|
|||
}
|
||||
}
|
||||
|
||||
static int filter_escape_value(
|
||||
int
|
||||
filter_escape_value(
|
||||
struct berval *in,
|
||||
struct berval *out )
|
||||
{
|
||||
|
|
|
|||
|
|
@ -537,6 +537,8 @@ LDAP_SLAPD_F (void) vrFilter_free LDAP_P(( ValuesReturnFilter *f ));
|
|||
LDAP_SLAPD_F (void) vrFilter2bv LDAP_P(( ValuesReturnFilter *f, struct berval *fstr ));
|
||||
|
||||
LDAP_SLAPD_F (int) filter_has_subordinates LDAP_P(( Filter *filter ));
|
||||
LDAP_SLAPD_F (int) filter_escape_value LDAP_P(( struct berval *in,
|
||||
struct berval *out ));
|
||||
|
||||
/*
|
||||
* filterentry.c
|
||||
|
|
|
|||
Loading…
Reference in a new issue