]> git.sur5r.net Git - openldap/commitdiff
ITS#7520 - back-ldap omit-unknown-schema changes
authorTed C. Cheng <tedcheng@symas.com>
Fri, 6 Feb 2015 01:19:39 +0000 (17:19 -0800)
committerQuanah Gibson-Mount <quanah@ub16.quanah.org>
Fri, 6 Oct 2017 17:44:31 +0000 (10:44 -0700)
doc/man/man5/slapd-ldap.5
servers/slapd/back-ldap/back-ldap.h
servers/slapd/back-ldap/config.c
servers/slapd/back-ldap/search.c

index f64d26ceeb413b4923a8ed23e2186aae58ee4646..a06ea9a0533291a3cf5a40f91cc9775596b42a49 100644 (file)
@@ -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 <NO|yes>
+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 <NO|yes>
 If
index 5248000546a622b75d7e7f170ba3b92f300f2921..07d8e2fc23e865924f10fbf6da7116bb591ea3af 100644 (file)
@@ -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;
index db1721a50b4b370ba74f7411ac0eeaf858ec4ebc..dda255174b3de6b77e0858087b5144cfb56b848f 100644 (file)
@@ -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", "<arglist>", 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);
index 69fb082565866021fb2f2828c9f56c876cfd6a9c..6001566059a9d4349e5f9df6945236fdb3ae9c61 100644 (file)
 
 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 );