dsdb: Assert that incoming DRS objects are valid in the local schema
authorAndrew Bartlett <abartlet@samba.org>
Tue, 4 Jun 2013 23:22:45 +0000 (09:22 +1000)
committerStefan Metzmacher <metze@samba.org>
Sun, 29 Jun 2014 21:45:25 +0000 (23:45 +0200)
This should change some of the random segfaults seen in autobuild into
errors we can further debug.

Andrew Bartlett

Reviewed-by: Stefan Metzmacher <metze@samba.org>
source4/dsdb/samdb/ldb_modules/repl_meta_data.c

index 30b3012682941870431c8bf19935ca5b501313ef..0b7d440b254632821aa11616f1f10dd440577875 100644 (file)
@@ -3964,6 +3964,7 @@ static int replmd_replicated_apply_add(struct replmd_replicated_request *ar)
        /* remove any message elements that have zero values */
        for (i=0; i<msg->num_elements; i++) {
                struct ldb_message_element *el = &msg->elements[i];
+               const struct dsdb_attribute *sa;
 
                if (el->num_values == 0) {
                        if (ldb_attr_cmp(msg->elements[i].name, "objectClass") == 0) {
@@ -3980,6 +3981,14 @@ static int replmd_replicated_apply_add(struct replmd_replicated_request *ar)
                        i--;
                        continue;
                }
+               sa = dsdb_attribute_by_lDAPDisplayName(ar->schema, el->name);
+               if (!sa) {
+                       ldb_asprintf_errstring(ldb,
+                                              "replmd_apply_add: attribute '%s' on '%s' not defined in schema, "
+                                              "despite being in the schema during the inbound replication!",
+                                              el->name, ldb_dn_get_linearized(msg->dn));
+                       return replmd_replicated_request_error(ar, LDB_ERR_NO_SUCH_ATTRIBUTE);
+               }
        }
 
        if (DEBUGLVL(4)) {
@@ -4600,15 +4609,28 @@ static int replmd_replicated_apply_merge(struct replmd_replicated_request *ar)
 
        /* we want to replace the old values */
        for (i=0; i < msg->num_elements; i++) {
-               msg->elements[i].flags = LDB_FLAG_MOD_REPLACE;
-               if (ldb_attr_cmp(msg->elements[i].name, "objectClass") == 0) {
-                       if (msg->elements[i].num_values == 0) {
+               struct ldb_message_element *el = &msg->elements[i];
+               const struct dsdb_attribute *sa;
+
+               el->flags = LDB_FLAG_MOD_REPLACE;
+
+               if (ldb_attr_cmp(el->name, "objectClass") == 0) {
+                       if (el->num_values == 0) {
                                ldb_asprintf_errstring(ldb, __location__
                                                       ": objectClass removed on %s, aborting replication\n",
                                                       ldb_dn_get_linearized(msg->dn));
                                return replmd_replicated_request_error(ar, LDB_ERR_OBJECT_CLASS_VIOLATION);
                        }
                }
+
+               sa = dsdb_attribute_by_lDAPDisplayName(ar->schema, el->name);
+               if (!sa) {
+                       ldb_asprintf_errstring(ldb,
+                                              "replmd_apply_merge: attribute '%s' on '%s' not defined in schema, "
+                                              "despite being in the schema during the inbound replication!",
+                                              el->name, ldb_dn_get_linearized(msg->dn));
+                       return replmd_replicated_request_error(ar, LDB_ERR_NO_SUCH_ATTRIBUTE);
+               }
        }
 
        if (DEBUGLVL(4)) {