From 6e128193873dde53926ece166ed8bc712b753eac Mon Sep 17 00:00:00 2001 From: Pierangelo Masarati Date: Wed, 1 Dec 2004 21:47:13 +0000 Subject: [PATCH] allow undefined schema items to be returned by back-ldap and remapped by the rwm overlay --- servers/slapd/back-ldap/search.c | 17 ++++++++--- servers/slapd/oc.c | 48 ++++++++++++++++++++++++++++++++ servers/slapd/overlays/rwm.c | 4 ++- servers/slapd/overlays/rwmconf.c | 9 ++++++ servers/slapd/schema_prep.c | 2 +- 5 files changed, 74 insertions(+), 6 deletions(-) diff --git a/servers/slapd/back-ldap/search.c b/servers/slapd/back-ldap/search.c index 408fb61a2d..e60d6bfc54 100644 --- a/servers/slapd/back-ldap/search.c +++ b/servers/slapd/back-ldap/search.c @@ -420,15 +420,24 @@ ldap_build_entry( if ( pretty ) { rc = pretty( attr->a_desc->ad_type->sat_syntax, &attr->a_vals[i], &pval, NULL ); + } else { rc = validate( attr->a_desc->ad_type->sat_syntax, &attr->a_vals[i] ); } if ( rc != LDAP_SUCCESS ) { - attr->a_nvals = NULL; - attr_free( attr ); - goto next_attr; + /* check if, by chance, it's an undefined objectClass */ + if ( attr->a_desc == slap_schema.si_ad_objectClass && + oc_bvfind_undef( &attr->a_vals[i] ) != NULL ) + { + ber_dupbv( &pval, &attr->a_vals[i] ); + + } else { + attr->a_nvals = NULL; + attr_free( attr ); + goto next_attr; + } } if ( pretty ) { @@ -539,7 +548,7 @@ ldap_back_entry_get( retry: rc = ldap_search_ext_s( lc->lc_ld, ndn->bv_val, LDAP_SCOPE_BASE, filter, - gattr, 0, NULL, NULL, LDAP_NO_LIMIT, + at ? gattr : NULL, 0, NULL, NULL, LDAP_NO_LIMIT, LDAP_NO_LIMIT, &result ); if ( rc != LDAP_SUCCESS ) { if ( rc == LDAP_SERVER_DOWN && do_retry ) { diff --git a/servers/slapd/oc.c b/servers/slapd/oc.c index fcefc34449..651041f934 100644 --- a/servers/slapd/oc.c +++ b/servers/slapd/oc.c @@ -170,6 +170,47 @@ oc_bvfind( struct berval *ocname ) return( NULL ); } +static LDAP_SLIST_HEAD(OCUList, slap_object_class) oc_undef_list + = LDAP_SLIST_HEAD_INITIALIZER(&oc_undef_list); + +ObjectClass * +oc_bvfind_undef( struct berval *ocname ) +{ + ObjectClass *oc = oc_bvfind( ocname ); + + if ( oc ) { + return oc; + } + + LDAP_SLIST_FOREACH( oc, &oc_undef_list, soc_next ) { + int d = oc->soc_cname.bv_len - ocname->bv_len; + + if ( d ) { + continue; + } + + if ( strcasecmp( oc->soc_cname.bv_val, ocname->bv_val ) == 0 ) { + break; + } + } + + if ( oc ) { + return oc; + } + + oc = ch_malloc( sizeof( ObjectClass ) + ocname->bv_len + 1 ); + memset( oc, 0, sizeof( ObjectClass ) ); + + oc->soc_cname.bv_len = ocname->bv_len; + oc->soc_cname.bv_val = (char *)&oc[ 1 ]; + AC_MEMCPY( oc->soc_cname.bv_val, ocname->bv_val, ocname->bv_len ); + + LDAP_SLIST_NEXT( oc, soc_next ) = NULL; + LDAP_SLIST_INSERT_HEAD( &oc_undef_list, oc, soc_next ); + + return oc; +} + static int oc_create_required( ObjectClass *soc, @@ -337,6 +378,13 @@ oc_destroy( void ) if (o->soc_allowed) ldap_memfree(o->soc_allowed); ldap_objectclass_free((LDAPObjectClass *)o); } + + while( !LDAP_SLIST_EMPTY(&oc_undef_list) ) { + o = LDAP_SLIST_FIRST(&oc_undef_list); + LDAP_SLIST_REMOVE_HEAD(&oc_undef_list, soc_next); + + ch_free( (ObjectClass *)o ); + } } static int diff --git a/servers/slapd/overlays/rwm.c b/servers/slapd/overlays/rwm.c index 11b4da6635..fc4634703d 100644 --- a/servers/slapd/overlays/rwm.c +++ b/servers/slapd/overlays/rwm.c @@ -771,7 +771,9 @@ rwm_attrs( Operation *op, SlapReply *rs, Attribute** a_first ) goto cleanup_attr; } - if ( (*ap)->a_desc->ad_type->sat_no_user_mod ) { + if ( (*ap)->a_desc->ad_type->sat_no_user_mod + && (*ap)->a_desc->ad_type != slap_schema.si_at_undefined ) + { goto next_attr; } diff --git a/servers/slapd/overlays/rwmconf.c b/servers/slapd/overlays/rwmconf.c index ba20bc35a7..8ec26196f0 100644 --- a/servers/slapd/overlays/rwmconf.c +++ b/servers/slapd/overlays/rwmconf.c @@ -142,10 +142,19 @@ rwm_map_config( "is not defined in schema\n", fname, lineno, dst ); + mapping[0].m_dst_oc = oc_bvfind_undef( &mapping[0].m_dst ); + if ( mapping[0].m_dst_oc == NULL ) { + fprintf( stderr, "%s: line %d: unable to mimic destination objectClass '%s'\n", + fname, lineno, dst ); + return 1; + } + +#if 0 mapping[0].m_dst_oc = ch_malloc( sizeof( ObjectClass ) ); memset( mapping[0].m_dst_oc, 0, sizeof( ObjectClass ) ); mapping[0].m_dst_oc->soc_cname = mapping[0].m_dst; mapping[0].m_flags |= RWMMAP_F_FREE_DST; +#endif } mapping[1].m_src_oc = mapping[0].m_dst_oc; diff --git a/servers/slapd/schema_prep.c b/servers/slapd/schema_prep.c index e81009a57b..ce794edc4a 100644 --- a/servers/slapd/schema_prep.c +++ b/servers/slapd/schema_prep.c @@ -1248,7 +1248,7 @@ slap_schema_load( void ) } } - slap_at_undefined.sat_syntax = slap_schema.si_syn_distinguishedName; + slap_at_undefined.sat_syntax = slap_schema.si_syn_octetString; slap_schema.si_at_undefined = &slap_at_undefined; return LDAP_SUCCESS; -- 2.39.5