mirror of
https://git.openldap.org/openldap/openldap.git
synced 2025-02-05 13:40:08 +08:00
attribute & objectclass mapping rules
This commit is contained in:
parent
f9a76ce1ab
commit
6e6118c6cc
@ -58,8 +58,7 @@ ldap_back_add(
|
||||
int i;
|
||||
Attribute *a;
|
||||
LDAPMod **attrs;
|
||||
|
||||
char *mdn;
|
||||
char *mdn, *mapped;
|
||||
|
||||
lc = ldap_back_getconn(li, conn, op);
|
||||
if ( !lc || !ldap_back_dobind( lc, op ) ) {
|
||||
@ -77,14 +76,20 @@ ldap_back_add(
|
||||
|
||||
/* Create array of LDAPMods for ldap_add() */
|
||||
attrs = (LDAPMod **)ch_malloc(sizeof(LDAPMod *)*i);
|
||||
attrs[i-1] = 0;
|
||||
|
||||
for (i=0, a=e->e_attrs; a; i++, a=a->a_next) {
|
||||
attrs[i] = (LDAPMod *)ch_malloc(sizeof(LDAPMod));
|
||||
attrs[i]->mod_op = LDAP_MOD_BVALUES;
|
||||
attrs[i]->mod_type = a->a_desc->ad_cname->bv_val;
|
||||
attrs[i]->mod_vals.modv_bvals = a->a_vals;
|
||||
for (i=0, a=e->e_attrs; a; a=a->a_next) {
|
||||
mapped = ldap_back_map(&li->at_map, a->a_desc->ad_cname->bv_val, 0);
|
||||
if (mapped != NULL) {
|
||||
attrs[i] = (LDAPMod *)ch_malloc(sizeof(LDAPMod));
|
||||
if (attrs[i] != NULL) {
|
||||
attrs[i]->mod_op = LDAP_MOD_BVALUES;
|
||||
attrs[i]->mod_type = mapped;
|
||||
attrs[i]->mod_vals.modv_bvals = a->a_vals;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
attrs[i] = NULL;
|
||||
|
||||
ldap_add_s(lc->ld, mdn, attrs);
|
||||
for (--i; i>= 0; --i)
|
||||
|
@ -31,10 +31,10 @@ ldap_back_attribute(
|
||||
)
|
||||
{
|
||||
struct ldapinfo *li = (struct ldapinfo *) be->be_private;
|
||||
int rc = 1, i, j, count;
|
||||
int rc = 1, i, j, count, is_oc;
|
||||
Attribute *attr;
|
||||
struct berval **abv, **v;
|
||||
char **vs;
|
||||
char **vs, *mapped;
|
||||
LDAPMessage *result, *e;
|
||||
char *gattr[2];
|
||||
LDAP *ld;
|
||||
@ -42,6 +42,7 @@ ldap_back_attribute(
|
||||
*vals = NULL;
|
||||
if (target != NULL && strcmp(target->e_ndn, e_ndn) == 0) {
|
||||
/* we already have a copy of the entry */
|
||||
/* attribute and objectclass mapping has already been done */
|
||||
if ((attr = attr_find(target->e_attrs, entry_at)) == NULL)
|
||||
return(1);
|
||||
|
||||
@ -61,31 +62,49 @@ ldap_back_attribute(
|
||||
}
|
||||
|
||||
} else {
|
||||
mapped = ldap_back_map(&li->at_map, entry_at->ad_cname->bv_val, 0);
|
||||
if (mapped == NULL)
|
||||
return(1);
|
||||
|
||||
if (ldap_initialize(&ld, li->url) != LDAP_SUCCESS) {
|
||||
return(1);
|
||||
}
|
||||
|
||||
if (ldap_bind_s(ld, li->binddn, li->bindpw, LDAP_AUTH_SIMPLE) == LDAP_SUCCESS) {
|
||||
gattr[0] = entry_at->ad_cname->bv_val;
|
||||
gattr[0] = mapped;
|
||||
gattr[1] = NULL;
|
||||
if (ldap_search_ext_s(ld, e_ndn, LDAP_SCOPE_BASE, "(objectclass=*)",
|
||||
gattr, 0, NULL, NULL, LDAP_NO_LIMIT,
|
||||
LDAP_NO_LIMIT, &result) == LDAP_SUCCESS)
|
||||
{
|
||||
if ((e = ldap_first_entry(ld, result)) != NULL) {
|
||||
vs = ldap_get_values(ld, e, entry_at->ad_cname->bv_val);
|
||||
vs = ldap_get_values(ld, e, mapped);
|
||||
if (vs != NULL) {
|
||||
for ( count = 0; vs[count] != NULL; count++ ) { }
|
||||
v = (struct berval **) ch_calloc( (count + 1), sizeof(struct berval *) );
|
||||
if (v == NULL) {
|
||||
ldap_value_free(vs);
|
||||
} else {
|
||||
is_oc = (strcasecmp("objectclass", mapped) == 0);
|
||||
for ( i = 0, j = 0; i < count; i++) {
|
||||
v[j] = ber_bvstr( vs[i] );
|
||||
if( v[j] == NULL )
|
||||
if (!is_oc) {
|
||||
v[j] = ber_bvstr( vs[i] );
|
||||
if( v[j] == NULL )
|
||||
ch_free(vs[i]);
|
||||
else
|
||||
j++;
|
||||
} else {
|
||||
mapped = ldap_back_map(&li->oc_map, vs[i], 1);
|
||||
if (mapped) {
|
||||
mapped = ch_strdup( mapped );
|
||||
if (mapped) {
|
||||
v[j] = ber_bvstr( mapped );
|
||||
if (v[j])
|
||||
j++;
|
||||
}
|
||||
}
|
||||
ch_free(vs[i]);
|
||||
else
|
||||
j++;
|
||||
}
|
||||
}
|
||||
v[j] = NULL;
|
||||
*vals = v;
|
||||
|
@ -52,6 +52,18 @@ struct ldapconn {
|
||||
int bound;
|
||||
};
|
||||
|
||||
struct ldapmap {
|
||||
int drop_missing;
|
||||
|
||||
Avlnode *map;
|
||||
Avlnode *remap;
|
||||
};
|
||||
|
||||
struct ldapmapping {
|
||||
char *src;
|
||||
char *dst;
|
||||
};
|
||||
|
||||
struct ldapinfo {
|
||||
char *url;
|
||||
#if 0 /* unused! */
|
||||
@ -62,6 +74,9 @@ struct ldapinfo {
|
||||
char *bindpw;
|
||||
ldap_pvt_thread_mutex_t conn_mutex;
|
||||
Avlnode *conntree;
|
||||
|
||||
struct ldapmap oc_map;
|
||||
struct ldapmap at_map;
|
||||
};
|
||||
|
||||
struct ldapconn *ldap_back_getconn(struct ldapinfo *li, struct slap_conn *conn,
|
||||
@ -76,7 +91,14 @@ char *ldap_back_dn_restore(struct ldapinfo *li, char *dn, int normalized);
|
||||
|
||||
int conn_cmp(const void *, const void *);
|
||||
int conn_dup(void *, void *);
|
||||
|
||||
|
||||
int mapping_cmp (const void *, const void *);
|
||||
int mapping_dup (void *, void *);
|
||||
|
||||
char *ldap_back_map ( struct ldapmap *map, char *s, int remap );
|
||||
char *ldap_back_map_filter ( struct ldapinfo *li, char *f, int remap );
|
||||
char **ldap_back_map_attrs ( struct ldapinfo *li, char **a, int remap );
|
||||
|
||||
LDAP_END_DECL
|
||||
|
||||
#endif
|
||||
|
@ -199,7 +199,7 @@ ldap_back_getconn(struct ldapinfo *li, Connection *conn, Operation *op)
|
||||
err = avl_insert( &li->conntree, (caddr_t)lc,
|
||||
conn_cmp, conn_dup );
|
||||
|
||||
#if 1
|
||||
#if 0
|
||||
myprint( li->conntree );
|
||||
#endif
|
||||
|
||||
|
@ -57,7 +57,7 @@ ldap_back_compare(
|
||||
{
|
||||
struct ldapinfo *li = (struct ldapinfo *) be->be_private;
|
||||
struct ldapconn *lc;
|
||||
char *mdn;
|
||||
char *mdn, *mapped_oc, *mapped_at;
|
||||
|
||||
lc = ldap_back_getconn(li, conn, op);
|
||||
if (!lc || !ldap_back_dobind( lc, op ) ) {
|
||||
@ -69,7 +69,15 @@ ldap_back_compare(
|
||||
return -1;
|
||||
}
|
||||
|
||||
ldap_compare_s( lc->ld, mdn, ava->aa_desc->ad_cname->bv_val, ava->aa_value->bv_val );
|
||||
mapped_oc = ldap_back_map(&li->oc_map, ava->aa_desc->ad_cname->bv_val, 0);
|
||||
if (mapped_oc == NULL)
|
||||
return( -1 );
|
||||
|
||||
mapped_at = ldap_back_map(&li->at_map, ava->aa_value->bv_val, 0);
|
||||
if (mapped_oc == NULL)
|
||||
return( -1 );
|
||||
|
||||
ldap_compare_s( lc->ld, mdn, mapped_oc, mapped_at );
|
||||
|
||||
free( mdn );
|
||||
|
||||
|
@ -141,7 +141,7 @@ ldap_back_db_config(
|
||||
return( 1 );
|
||||
}
|
||||
|
||||
dn = ch_strdup( argv[1] );
|
||||
dn = ch_strdup( argv[1] );
|
||||
charray_add( &li->suffix_massage, dn );
|
||||
(void) dn_normalize( dn );
|
||||
charray_add( &li->suffix_massage, dn );
|
||||
@ -154,6 +154,92 @@ ldap_back_db_config(
|
||||
free( dn );
|
||||
free( massaged_dn );
|
||||
|
||||
/* 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} {<source> | *} [<dest> | *]\"\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} {<source> | *} [<dest> | *]\"\n",
|
||||
fname, lineno );
|
||||
return( 1 );
|
||||
}
|
||||
|
||||
if ( strcasecmp( argv[2], "*" ) != 0 ) {
|
||||
src = argv[2];
|
||||
if ( argc < 4 )
|
||||
dst = "";
|
||||
else if ( strcasecmp( argv[3], "*" ) == 0 )
|
||||
dst = src;
|
||||
else
|
||||
dst = argv[3];
|
||||
} else {
|
||||
if ( argc < 4 ) {
|
||||
map->drop_missing = 1;
|
||||
return 0;
|
||||
}
|
||||
if ( strcasecmp( argv[3], "*" ) == 0 ) {
|
||||
map->drop_missing = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
src = argv[3];
|
||||
dst = src;
|
||||
}
|
||||
|
||||
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 );
|
||||
}
|
||||
mapping->src = ch_strdup(src);
|
||||
mapping->dst = ch_strdup(dst);
|
||||
if ( *dst != 0 ) {
|
||||
mapping[1].src = mapping->dst;
|
||||
mapping[1].dst = mapping->src;
|
||||
} else {
|
||||
mapping[1].src = mapping->src;
|
||||
mapping[1].dst = mapping->dst;
|
||||
}
|
||||
|
||||
if ( 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;
|
||||
}
|
||||
|
||||
avl_insert( &map->map, (caddr_t)mapping,
|
||||
mapping_cmp, mapping_dup );
|
||||
avl_insert( &map->remap, (caddr_t)&mapping[1],
|
||||
mapping_cmp, mapping_dup );
|
||||
|
||||
/* anything else */
|
||||
} else {
|
||||
fprintf( stderr,
|
||||
@ -162,3 +248,160 @@ ldap_back_db_config(
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
mapping_cmp ( const void *c1, const void *c2 )
|
||||
{
|
||||
struct ldapmapping *map1 = (struct ldapmapping *)c1;
|
||||
struct ldapmapping *map2 = (struct ldapmapping *)c2;
|
||||
|
||||
return ( strcasecmp(map1->src, map2->src) );
|
||||
}
|
||||
|
||||
int
|
||||
mapping_dup ( void *c1, void *c2 )
|
||||
{
|
||||
struct ldapmapping *map1 = (struct ldapmapping *)c1;
|
||||
struct ldapmapping *map2 = (struct ldapmapping *)c2;
|
||||
|
||||
return( ( strcasecmp(map1->src, map2->src) == 0 ) ? -1 : 0 );
|
||||
}
|
||||
|
||||
char *
|
||||
ldap_back_map ( struct ldapmap *map, char *s, int remap )
|
||||
{
|
||||
Avlnode *tree;
|
||||
struct ldapmapping *mapping, fmapping;
|
||||
|
||||
if (remap)
|
||||
tree = map->remap;
|
||||
else
|
||||
tree = map->map;
|
||||
|
||||
fmapping.src = s;
|
||||
mapping = (struct ldapmapping *)avl_find( tree, (caddr_t)&fmapping, mapping_cmp );
|
||||
if (mapping != NULL) {
|
||||
if ( *mapping->dst == 0 )
|
||||
return(NULL);
|
||||
return(mapping->dst);
|
||||
}
|
||||
|
||||
if (map->drop_missing)
|
||||
return(NULL);
|
||||
|
||||
return(s);
|
||||
}
|
||||
|
||||
char *
|
||||
ldap_back_map_filter ( struct ldapinfo *li, char *f, int remap )
|
||||
{
|
||||
char *nf, *m, *p, *q, *s, c;
|
||||
int len, extra, plen, in_quote;
|
||||
|
||||
if (f == NULL)
|
||||
return(NULL);
|
||||
|
||||
len = strlen(f);
|
||||
extra = len;
|
||||
len *= 2;
|
||||
nf = ch_malloc( len + 1 );
|
||||
if (nf == NULL)
|
||||
return(NULL);
|
||||
|
||||
/* this loop assumes the filter ends with one
|
||||
* of the delimiter chars -- probably ')'.
|
||||
*/
|
||||
|
||||
s = nf;
|
||||
q = NULL;
|
||||
in_quote = 0;
|
||||
for (p = f; c = *p; p++) {
|
||||
if (c == '"') {
|
||||
in_quote = !in_quote;
|
||||
if (q != NULL) {
|
||||
plen = p - q;
|
||||
memcpy(s, q, plen);
|
||||
s += plen;
|
||||
q = NULL;
|
||||
}
|
||||
*s++ = c;
|
||||
} else if (in_quote) {
|
||||
/* ignore everything in quotes --
|
||||
* what about attrs in DNs?
|
||||
*/
|
||||
*s++ = c;
|
||||
} else if (c != '(' && c != ')'
|
||||
&& c != '=' && c != '>' && c != '<'
|
||||
&& c != '|' && c != '&')
|
||||
{
|
||||
if (q == NULL)
|
||||
q = p;
|
||||
} else {
|
||||
if (q != NULL) {
|
||||
*p = 0;
|
||||
m = ldap_back_map(&li->at_map, q, remap);
|
||||
if (m == NULL)
|
||||
m = ldap_back_map(&li->oc_map, q, remap);
|
||||
if (m == NULL) {
|
||||
m = q;
|
||||
}
|
||||
extra += p - q;
|
||||
plen = strlen(m);
|
||||
extra -= plen;
|
||||
if (extra < 0) {
|
||||
while (extra < 0) {
|
||||
extra += len;
|
||||
len *= 2;
|
||||
}
|
||||
s -= (long)nf;
|
||||
nf = ch_realloc(nf, len + 1);
|
||||
if (nf == NULL) {
|
||||
free(nf);
|
||||
return(NULL);
|
||||
}
|
||||
s += (long)nf;
|
||||
}
|
||||
memcpy(s, m, plen);
|
||||
s += plen;
|
||||
*p = c;
|
||||
q = NULL;
|
||||
}
|
||||
*s++ = c;
|
||||
}
|
||||
}
|
||||
*s = 0;
|
||||
return(nf);
|
||||
}
|
||||
|
||||
char **
|
||||
ldap_back_map_attrs ( struct ldapinfo *li, char **a, int remap )
|
||||
{
|
||||
int i, j, count;
|
||||
char **na, *mapped;
|
||||
|
||||
if (a == NULL)
|
||||
return(NULL);
|
||||
|
||||
for (count = 0; a[count] != NULL; count++) {
|
||||
/* */
|
||||
}
|
||||
|
||||
na = (char **)ch_calloc( count + 1, sizeof(char *) );
|
||||
if (na == NULL)
|
||||
return(NULL);
|
||||
|
||||
for (i = 0, j = 0; i < count; i++) {
|
||||
mapped = ldap_back_map(&li->at_map, a[i], remap);
|
||||
if (mapped != NULL) {
|
||||
mapped = ch_strdup(mapped);
|
||||
if (mapped == NULL) {
|
||||
charray_free(na);
|
||||
return(NULL);
|
||||
}
|
||||
na[j] = mapped;
|
||||
j++;
|
||||
}
|
||||
}
|
||||
return(na);
|
||||
}
|
||||
|
||||
|
@ -43,8 +43,8 @@ ldap_back_group(
|
||||
LDAP *ld;
|
||||
|
||||
AttributeDescription *ad_objectClass = slap_schema.si_ad_objectClass;
|
||||
const char *group_oc_name = NULL;
|
||||
const char *group_at_name = group_at->ad_cname->bv_val;
|
||||
char *group_oc_name = NULL;
|
||||
char *group_at_name = group_at->ad_cname->bv_val;
|
||||
|
||||
if( group_oc->soc_names && group_oc->soc_names[0] ) {
|
||||
group_oc_name = group_oc->soc_names[0];
|
||||
@ -54,6 +54,7 @@ ldap_back_group(
|
||||
|
||||
if (target != NULL && strcmp(target->e_ndn, gr_ndn) == 0) {
|
||||
/* we already have a copy of the entry */
|
||||
/* attribute and objectclass mapping has already been done */
|
||||
e = target;
|
||||
|
||||
if( is_entry_objectclass( e, group_oc ) ) {
|
||||
@ -69,6 +70,13 @@ ldap_back_group(
|
||||
return(1);
|
||||
|
||||
} else {
|
||||
group_oc_name = ldap_back_map(&li->oc_map, group_oc_name, 0);
|
||||
if (group_oc_name == NULL)
|
||||
return(1);
|
||||
group_at_name = ldap_back_map(&li->at_map, group_at_name, 0);
|
||||
if (group_at_name == NULL)
|
||||
return(1);
|
||||
|
||||
filter = ch_malloc(sizeof("(&(objectclass=)(=))")
|
||||
+ strlen(group_oc_name)
|
||||
+ strlen(group_at_name)
|
||||
|
@ -103,10 +103,24 @@ ldap_back_db_init(
|
||||
)
|
||||
{
|
||||
struct ldapinfo *li;
|
||||
struct ldapmapping *mapping;
|
||||
|
||||
li = (struct ldapinfo *) ch_calloc( 1, sizeof(struct ldapinfo) );
|
||||
ldap_pvt_thread_mutex_init( &li->conn_mutex );
|
||||
|
||||
mapping = (struct ldapmapping *)ch_calloc( 2, sizeof(struct ldapmapping) );
|
||||
if ( mapping != NULL ) {
|
||||
mapping->src = ch_strdup("objectclass");
|
||||
mapping->dst = ch_strdup("objectclass");
|
||||
mapping[1].src = mapping->src;
|
||||
mapping[1].dst = mapping->dst;
|
||||
|
||||
avl_insert( &li->at_map.map, (caddr_t)mapping,
|
||||
mapping_cmp, mapping_dup );
|
||||
avl_insert( &li->at_map.remap, (caddr_t)&mapping[1],
|
||||
mapping_cmp, mapping_dup );
|
||||
}
|
||||
|
||||
be->be_private = li;
|
||||
|
||||
return li == NULL;
|
||||
@ -122,6 +136,14 @@ conn_free(
|
||||
free( lc );
|
||||
}
|
||||
|
||||
static void
|
||||
mapping_free ( struct ldapmapping *mapping )
|
||||
{
|
||||
ch_free( mapping->src );
|
||||
ch_free( mapping->dst );
|
||||
ch_free( mapping );
|
||||
}
|
||||
|
||||
int
|
||||
ldap_back_db_destroy(
|
||||
Backend *be
|
||||
@ -153,6 +175,11 @@ ldap_back_db_destroy(
|
||||
if (li->conntree) {
|
||||
avl_free( li->conntree, (AVL_FREE) conn_free );
|
||||
}
|
||||
|
||||
avl_free( li->oc_map.remap, NULL );
|
||||
avl_free( li->oc_map.map, (AVL_FREE) mapping_free );
|
||||
avl_free( li->at_map.remap, NULL );
|
||||
avl_free( li->at_map.map, (AVL_FREE) mapping_free );
|
||||
|
||||
ldap_pvt_thread_mutex_unlock( &li->conn_mutex );
|
||||
ldap_pvt_thread_mutex_destroy( &li->conn_mutex );
|
||||
|
@ -61,8 +61,7 @@ ldap_back_modify(
|
||||
LDAPMod *mods;
|
||||
Modifications *ml;
|
||||
int i;
|
||||
|
||||
char *mdn;
|
||||
char *mdn, *mapped;
|
||||
|
||||
lc = ldap_back_getconn(li, conn, op);
|
||||
if ( !lc || !ldap_back_dobind( lc, op ) ) {
|
||||
@ -86,16 +85,17 @@ ldap_back_modify(
|
||||
return( -1 );
|
||||
}
|
||||
|
||||
modv[i] = 0;
|
||||
|
||||
for (i=0, ml=modlist; ml; i++, ml=ml->sml_next) {
|
||||
modv[i] = &mods[i];
|
||||
mods[i].mod_op = ml->sml_op | LDAP_MOD_BVALUES;
|
||||
mods[i].mod_type = ml->sml_desc->ad_cname->bv_val;
|
||||
mods[i].mod_bvalues = ml->sml_bvalues;
|
||||
for (i=0, ml=modlist; ml; ml=ml->sml_next) {
|
||||
mapped = ldap_back_map(&li->at_map, ml->sml_desc->ad_cname->bv_val, 0);
|
||||
if (mapped != NULL) {
|
||||
modv[i] = &mods[i];
|
||||
mods[i].mod_op = ml->sml_op | LDAP_MOD_BVALUES;
|
||||
mods[i].mod_type = mapped;
|
||||
mods[i].mod_bvalues = ml->sml_bvalues;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
modv[i] = 0;
|
||||
|
||||
ldap_modify_s( lc->ld, mdn, modv );
|
||||
free( mdn );
|
||||
|
@ -70,10 +70,9 @@ ldap_back_search(
|
||||
struct ldapconn *lc;
|
||||
struct timeval tv;
|
||||
LDAPMessage *res, *e;
|
||||
int i, rc, msgid, sres = LDAP_SUCCESS;
|
||||
int count, rc, msgid, sres = LDAP_SUCCESS;
|
||||
char *match = NULL, *err = NULL;
|
||||
|
||||
char *mbase;
|
||||
char *mbase, *mapped_filter, **mapped_attrs;
|
||||
|
||||
lc = ldap_back_getconn(li, conn, op);
|
||||
if ( !lc ) {
|
||||
@ -96,17 +95,41 @@ ldap_back_search(
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((msgid = ldap_search(lc->ld, mbase, scope, filterstr, attrs,
|
||||
mapped_filter = ldap_back_map_filter(li, (char *)filterstr, 0);
|
||||
if ( mapped_filter == NULL ) {
|
||||
mapped_filter = (char *)filterstr;
|
||||
}
|
||||
|
||||
mapped_attrs = ldap_back_map_attrs(li, attrs, 0);
|
||||
if ( mapped_attrs == NULL ) {
|
||||
mapped_attrs = attrs;
|
||||
}
|
||||
|
||||
if ((msgid = ldap_search(lc->ld, mbase, scope, mapped_filter, mapped_attrs,
|
||||
attrsonly)) == -1)
|
||||
fail: return( ldap_back_op_result(lc, op) );
|
||||
{
|
||||
fail:
|
||||
if (match)
|
||||
free(match);
|
||||
if (err)
|
||||
free(err);
|
||||
if (mapped_attrs != attrs)
|
||||
charray_free(mapped_attrs);
|
||||
if (mapped_filter != filterstr)
|
||||
free(mapped_filter);
|
||||
free(mbase);
|
||||
return( ldap_back_op_result(lc, op) );
|
||||
}
|
||||
|
||||
/* We pull apart the ber result, stuff it into a slapd entry, and
|
||||
* let send_search_entry stuff it back into ber format. Slow & ugly,
|
||||
* but this is necessary for version matching, and for ACL processing.
|
||||
*/
|
||||
|
||||
for (i=0, rc=0; rc != -1;
|
||||
rc = ldap_result(lc->ld, LDAP_RES_ANY, 0, &tv, &res)) {
|
||||
for ( count=0, rc=0;
|
||||
rc != -1;
|
||||
rc = ldap_result(lc->ld, LDAP_RES_ANY, 0, &tv, &res))
|
||||
{
|
||||
int ab;
|
||||
|
||||
/* check for abandon */
|
||||
@ -116,15 +139,16 @@ fail: return( ldap_back_op_result(lc, op) );
|
||||
|
||||
if (ab) {
|
||||
ldap_abandon(lc->ld, msgid);
|
||||
} else if (rc == 0) {
|
||||
goto finish;
|
||||
}
|
||||
if (rc == 0) {
|
||||
tv.tv_sec = 0;
|
||||
tv.tv_usec = 100000;
|
||||
ldap_pvt_thread_yield();
|
||||
continue;
|
||||
} else if (rc == LDAP_RES_SEARCH_ENTRY) {
|
||||
e = ldap_first_entry(lc->ld,res);
|
||||
ldap_send_entry(be, op, lc, e, attrs, attrsonly);
|
||||
i++;
|
||||
ldap_send_entry(be, op, lc, e, mapped_attrs, attrsonly);
|
||||
count++;
|
||||
ldap_msgfree(res);
|
||||
} else {
|
||||
sres = ldap_result2error(lc->ld, res, 1);
|
||||
@ -132,24 +156,26 @@ fail: return( ldap_back_op_result(lc, op) );
|
||||
ldap_get_option(lc->ld, LDAP_OPT_ERROR_STRING, &err);
|
||||
ldap_get_option(lc->ld, LDAP_OPT_MATCHED_DN, &match);
|
||||
rc = 0;
|
||||
}
|
||||
if (ab)
|
||||
return (0);
|
||||
else if (rc == 0)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (rc == -1)
|
||||
goto fail;
|
||||
|
||||
send_search_result( conn, op, sres,
|
||||
match, err, NULL, NULL, i );
|
||||
match, err, NULL, NULL, count );
|
||||
|
||||
finish:
|
||||
if (match)
|
||||
free(match);
|
||||
if (err)
|
||||
free(err);
|
||||
if (mbase)
|
||||
free(mbase);
|
||||
if (mapped_attrs != attrs)
|
||||
charray_free(mapped_attrs);
|
||||
if (mapped_filter != filterstr)
|
||||
free(mapped_filter);
|
||||
free(mbase);
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
@ -164,11 +190,12 @@ ldap_send_entry(
|
||||
)
|
||||
{
|
||||
struct ldapinfo *li = (struct ldapinfo *) be->be_private;
|
||||
char *a;
|
||||
char *a, *mapped;
|
||||
Entry ent;
|
||||
BerElement *ber = NULL;
|
||||
Attribute *attr, **attrp;
|
||||
struct berval *dummy = NULL;
|
||||
struct berval *bv;
|
||||
const char *text;
|
||||
|
||||
ent.e_dn = ldap_back_dn_restore( li, ldap_get_dn(lc->ld, e), 0 );
|
||||
@ -183,21 +210,47 @@ ldap_send_entry(
|
||||
a != NULL;
|
||||
a = ldap_next_attribute(lc->ld, e, ber))
|
||||
{
|
||||
mapped = ldap_back_map(&li->at_map, a, 1);
|
||||
if (mapped == NULL)
|
||||
continue;
|
||||
attr = (Attribute *)ch_malloc( sizeof(Attribute) );
|
||||
if (attr == NULL)
|
||||
continue;
|
||||
attr->a_next = 0;
|
||||
attr->a_desc = NULL;
|
||||
slap_str2ad(a, &attr->a_desc, &text);
|
||||
if (slap_str2ad(mapped, &attr->a_desc, &text) != LDAP_SUCCESS) {
|
||||
ch_free(attr);
|
||||
continue;
|
||||
}
|
||||
attr->a_vals = ldap_get_values_len(lc->ld, e, a);
|
||||
if (!attr->a_vals)
|
||||
if (!attr->a_vals) {
|
||||
attr->a_vals = &dummy;
|
||||
} else if ( strcasecmp( mapped, "objectclass" ) == 0 ) {
|
||||
int i, last;
|
||||
for ( last = 0; attr->a_vals[last]; last++ ) ;
|
||||
for ( i = 0; bv = attr->a_vals[i]; i++ ) {
|
||||
mapped = ldap_back_map(&li->oc_map, bv->bv_val, 1);
|
||||
if (mapped == NULL) {
|
||||
ber_bvfree(attr->a_vals[i]);
|
||||
attr->a_vals[i] = NULL;
|
||||
if (--last < 0)
|
||||
break;
|
||||
attr->a_vals[i] = attr->a_vals[last];
|
||||
attr->a_vals[last] = NULL;
|
||||
i--;
|
||||
} else if ( mapped != bv->bv_val ) {
|
||||
ch_free(bv->bv_val);
|
||||
bv->bv_val = ch_strdup( mapped );
|
||||
bv->bv_len = strlen( mapped );
|
||||
}
|
||||
}
|
||||
}
|
||||
*attrp = attr;
|
||||
attrp = &attr->a_next;
|
||||
}
|
||||
send_search_entry( be, lc->conn, op, &ent, attrs, attrsonly, NULL );
|
||||
for (;ent.e_attrs;) {
|
||||
attr=ent.e_attrs;
|
||||
while (ent.e_attrs) {
|
||||
attr = ent.e_attrs;
|
||||
ent.e_attrs = attr->a_next;
|
||||
ad_free(attr->a_desc, 1);
|
||||
if (attr->a_vals != &dummy)
|
||||
|
Loading…
Reference in New Issue
Block a user