From: Ted C. Cheng Date: Fri, 6 Feb 2015 01:19:39 +0000 (-0800) Subject: ITS#7520 - back-ldap omit-unknown-schema changes X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;ds=sidebyside;h=e20ac6b5395e702d4089d97fac6d49972a403a4d;p=openldap ITS#7520 - back-ldap omit-unknown-schema changes --- diff --git a/doc/man/man5/slapd-ldap.5 b/doc/man/man5/slapd-ldap.5 index f64d26ceeb..a06ea9a053 100644 --- a/doc/man/man5/slapd-ldap.5 +++ b/doc/man/man5/slapd-ldap.5 @@ -458,6 +458,13 @@ If do not return search reference responses. By default, they are returned unless request is LDAPv2. +.TP +.B omit-unknown-schema +If +.BR yes , +do not return objectClasses or attributes that are not known to the local server. +The default is to return all schema elements. + .TP .B noundeffilter If diff --git a/servers/slapd/back-ldap/back-ldap.h b/servers/slapd/back-ldap/back-ldap.h index 5248000546..07d8e2fc23 100644 --- a/servers/slapd/back-ldap/back-ldap.h +++ b/servers/slapd/back-ldap/back-ldap.h @@ -333,6 +333,7 @@ typedef struct ldapinfo_t { #define LDAP_BACK_F_NOREFS (0x00080000U) #define LDAP_BACK_F_NOUNDEFFILTER (0x00100000U) +#define LDAP_BACK_F_OMIT_UNKNOWN_SCHEMA (0x00200000U) #define LDAP_BACK_F_ONERR_STOP (0x00200000U) @@ -376,7 +377,7 @@ typedef struct ldapinfo_t { #define LDAP_BACK_NOREFS(li) LDAP_BACK_ISSET( (li), LDAP_BACK_F_NOREFS) #define LDAP_BACK_NOUNDEFFILTER(li) LDAP_BACK_ISSET( (li), LDAP_BACK_F_NOUNDEFFILTER) - +#define LDAP_BACK_OMIT_UNKNOWN_SCHEMA(li) LDAP_BACK_ISSET( (li), LDAP_BACK_F_OMIT_UNKNOWN_SCHEMA) #define LDAP_BACK_ONERR_STOP(li) LDAP_BACK_ISSET( (li), LDAP_BACK_F_ONERR_STOP) int li_version; diff --git a/servers/slapd/back-ldap/config.c b/servers/slapd/back-ldap/config.c index db1721a50b..dda255174b 100644 --- a/servers/slapd/back-ldap/config.c +++ b/servers/slapd/back-ldap/config.c @@ -76,6 +76,8 @@ enum { LDAP_BACK_CFG_REWRITE, LDAP_BACK_CFG_KEEPALIVE, + LDAP_BACK_CFG_OMIT_UNKNOWN_SCHEMA, + LDAP_BACK_CFG_LAST }; @@ -354,6 +356,14 @@ static ConfigTable ldapcfg[] = { { "rewrite", "", 2, 4, STRLENOF( "rewrite" ), ARG_STRING|ARG_MAGIC|LDAP_BACK_CFG_REWRITE, ldap_back_cf_gen, NULL, NULL, NULL }, + { "omit-unknown-schema", "true|FALSE", 2, 2, 0, + ARG_MAGIC|ARG_ON_OFF|LDAP_BACK_CFG_OMIT_UNKNOWN_SCHEMA, + ldap_back_cf_gen, "( OLcfgDbAt:3.28 " + "NAME 'olcDbRemoveUnknownSchema' " + "DESC 'Omit unknown schema when returning search results' " + "SYNTAX OMsBoolean " + "SINGLE-VALUE )", + NULL, NULL }, { "keepalive", "keepalive", 2, 2, 0, ARG_MAGIC|LDAP_BACK_CFG_KEEPALIVE, ldap_back_cf_gen, "( OLcfgDbAt:3.29 " @@ -1405,6 +1415,10 @@ ldap_back_cf_gen( ConfigArgs *c ) c->value_int = LDAP_BACK_NOUNDEFFILTER( li ); break; + case LDAP_BACK_CFG_OMIT_UNKNOWN_SCHEMA: + c->value_int = LDAP_BACK_OMIT_UNKNOWN_SCHEMA( li ); + break; + case LDAP_BACK_CFG_ONERR: enum_to_verb( onerr_mode, li->li_flags & LDAP_BACK_F_ONERR_STOP, &bv ); if ( BER_BVISNULL( &bv )) { @@ -1587,6 +1601,10 @@ ldap_back_cf_gen( ConfigArgs *c ) li->li_flags &= ~LDAP_BACK_F_NOUNDEFFILTER; break; + case LDAP_BACK_CFG_OMIT_UNKNOWN_SCHEMA: + li->li_flags &= ~LDAP_BACK_F_OMIT_UNKNOWN_SCHEMA; + break; + case LDAP_BACK_CFG_ONERR: li->li_flags &= ~LDAP_BACK_F_ONERR_STOP; break; @@ -2286,6 +2304,15 @@ done_url:; Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg, 0 ); return 1; + case LDAP_BACK_CFG_OMIT_UNKNOWN_SCHEMA: + if ( c->value_int ) { + li->li_flags |= LDAP_BACK_F_OMIT_UNKNOWN_SCHEMA; + + } else { + li->li_flags &= ~LDAP_BACK_F_OMIT_UNKNOWN_SCHEMA; + } + break; + case LDAP_BACK_CFG_KEEPALIVE: slap_keepalive_parse( ber_bvstrdup(c->argv[1]), &li->li_tls.sb_keepalive, 0, 0, 0); diff --git a/servers/slapd/back-ldap/search.c b/servers/slapd/back-ldap/search.c index 69fb082565..6001566059 100644 --- a/servers/slapd/back-ldap/search.c +++ b/servers/slapd/back-ldap/search.c @@ -37,7 +37,22 @@ static int ldap_build_entry( Operation *op, LDAPMessage *e, Entry *ent, - struct berval *bdn ); + struct berval *bdn, int remove_unknown_schema ); + + +static ObjectClass * +oc_bvfind_undef_ex( struct berval *ocname, int flag ) +{ + ObjectClass *oc = oc_bvfind( ocname ); + + if ( oc || flag ) { + /* oc defined or remove-unknown-schema flag set */ + return oc; + } + + return oc_bvfind_undef( ocname ); +} + /* * replaces (&) with (objectClass=*) and (|) with (!(objectClass=*)) @@ -147,6 +162,8 @@ ldap_back_search( int do_retry = 1, dont_retry = 0; LDAPControl **ctrls = NULL; char **references = NULL; + int remove_unknown_schema = + LDAP_BACK_OMIT_UNKNOWN_SCHEMA (li); rs_assert_ready( rs ); rs->sr_flags &= ~REP_ENTRY_MASK; /* paranoia, we can set rs = non-entry */ @@ -354,7 +371,8 @@ retry: do_retry = 0; e = ldap_first_entry( lc->lc_ld, res ); - rc = ldap_build_entry( op, e, &ent, &bdn ); + rc = ldap_build_entry( op, e, &ent, &bdn, + remove_unknown_schema); if ( rc == LDAP_SUCCESS ) { ldap_get_entry_controls( lc->lc_ld, res, &rs->sr_ctrls ); rs->sr_entry = &ent; @@ -660,7 +678,8 @@ ldap_build_entry( Operation *op, LDAPMessage *e, Entry *ent, - struct berval *bdn ) + struct berval *bdn, + int remove_unknown_schema) { struct berval a; BerElement ber = *ldap_get_message_ber( e ); @@ -714,7 +733,7 @@ ldap_build_entry( != LDAP_SUCCESS ) { if ( slap_bv2undef_ad( &a, &attr->a_desc, &text, - SLAP_AD_PROXIED ) != LDAP_SUCCESS ) + (remove_unknown_schema ? SLAP_AD_NOINSERT : SLAP_AD_PROXIED )) != LDAP_SUCCESS ) { Debug( LDAP_DEBUG_ANY, "%s ldap_build_entry: " @@ -792,7 +811,8 @@ ldap_build_entry( /* check if, by chance, it's an undefined objectClass */ if ( attr->a_desc == slap_schema.si_ad_objectClass && - ( oc = oc_bvfind_undef( &attr->a_vals[i] ) ) != NULL ) + ( oc = oc_bvfind_undef_ex( &attr->a_vals[i], + remove_unknown_schema ) ) != NULL ) { ber_dupbv( &pval, &oc->soc_cname ); rc = LDAP_SUCCESS; @@ -918,6 +938,8 @@ ldap_back_entry_get( LDAPControl **ctrls = NULL; Operation op2 = *op; + int remove_unknown_schema = + LDAP_BACK_OMIT_UNKNOWN_SCHEMA (li); *ent = NULL; /* Tell getconn this is a privileged op */ @@ -993,7 +1015,7 @@ retry: goto cleanup; } - rc = ldap_build_entry( op, e, *ent, &bdn ); + rc = ldap_build_entry( op, e, *ent, &bdn, remove_unknown_schema ); if ( rc != LDAP_SUCCESS ) { entry_free( *ent );