s4-dsdb: allow removal of unknown attributes if RELAX set
authorAndrew Tridgell <tridge@samba.org>
Tue, 5 Jul 2011 02:36:16 +0000 (12:36 +1000)
committerAndrew Tridgell <tridge@samba.org>
Tue, 5 Jul 2011 05:10:03 +0000 (07:10 +0200)
this allows attributes not known in the schema to be removed if the
caller has set the RELAX control. This will be used by dbcheck to
allow cleaning of bad attributes from the database

source4/dsdb/samdb/ldb_modules/objectclass_attrs.c
source4/dsdb/samdb/ldb_modules/repl_meta_data.c

index 5639a7a3e3e3f4ba9ec6b37af9d20c44e1c9404e..302904ab971fc6bf2159fbaa1be7582ad93b055a 100644 (file)
@@ -121,6 +121,12 @@ static int attr_handler(struct oc_context *ac)
                attr = dsdb_attribute_by_lDAPDisplayName(ac->schema,
                                                         msg->elements[i].name);
                if (attr == NULL) {
+                       if (ldb_request_get_control(ac->req, LDB_CONTROL_RELAX_OID) &&
+                           ac->req->operation != LDB_ADD) {
+                               /* we allow this for dbcheck to fix
+                                  broken attributes */
+                               goto no_attribute;
+                       }
                        ldb_asprintf_errstring(ldb, "objectclass_attrs: attribute '%s' on entry '%s' was not found in the schema!",
                                               msg->elements[i].name,
                                               ldb_dn_get_linearized(msg->dn));
@@ -172,6 +178,7 @@ static int attr_handler(struct oc_context *ac)
                msg->elements[i].name = attr->lDAPDisplayName;
        }
 
+no_attribute:
        if (ac->req->operation == LDB_ADD) {
                ret = ldb_build_add_req(&child_req, ldb, ac,
                                        msg, ac->req->controls,
@@ -297,6 +304,11 @@ static int attr_handler2(struct oc_context *ac)
                attr = dsdb_attribute_by_lDAPDisplayName(ac->schema,
                                                         msg->elements[i].name);
                if (attr == NULL) {
+                       if (ldb_request_get_control(ac->req, LDB_CONTROL_RELAX_OID)) {
+                               /* allow this to make it possible for dbcheck
+                                  to remove bad attributes */
+                               continue;
+                       }
                        return ldb_operr(ldb);
                }
 
index 9d2e5e2ac3bbcf2d0599d8671ba707825c09c403..830c118945fb0d13758bc7dd017959a63dc17e52 100644 (file)
@@ -1042,7 +1042,8 @@ static int replmd_update_rpmd_element(struct ldb_context *ldb,
                                      const struct dsdb_schema *schema,
                                      uint64_t *seq_num,
                                      const struct GUID *our_invocation_id,
-                                     NTTIME now)
+                                     NTTIME now,
+                                     struct ldb_request *req)
 {
        uint32_t i;
        const struct dsdb_attribute *a;
@@ -1050,6 +1051,12 @@ static int replmd_update_rpmd_element(struct ldb_context *ldb,
 
        a = dsdb_attribute_by_lDAPDisplayName(schema, el->name);
        if (a == NULL) {
+               if (ldb_request_get_control(req, LDB_CONTROL_RELAX_OID)) {
+                       /* allow this to make it possible for dbcheck
+                          to remove bad attributes */
+                       return LDB_SUCCESS;
+               }
+
                DEBUG(0,(__location__ ": Unable to find attribute %s in schema\n",
                         el->name));
                return LDB_ERR_OPERATIONS_ERROR;
@@ -1299,7 +1306,7 @@ static int replmd_update_rpmd(struct ldb_module *module,
                        struct ldb_message_element *old_el;
                        old_el = ldb_msg_find_element(res->msgs[0], msg->elements[i].name);
                        ret = replmd_update_rpmd_element(ldb, msg, &msg->elements[i], old_el, &omd, schema, seq_num,
-                                                        our_invocation_id, now);
+                                                        our_invocation_id, now, req);
                        if (ret != LDB_SUCCESS) {
                                return ret;
                        }