[SCM] Samba Shared Repository - branch master updated

Andrew Bartlett abartlet at samba.org
Sun Mar 16 23:45:05 MDT 2014


The branch, master has been updated
       via  9c9df40 dsdb: Further assert that we always have an objectClass and an rDN
      from  d783697 wintest: Try harder to make wintest force the telnet server to start

http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit 9c9df40220234cba973e84b4985d90da1334a1d1
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Fri Feb 28 17:49:12 2014 +1300

    dsdb: Further assert that we always have an objectClass and an rDN
    
    We must have these two elements in a replPropertyMetaData for it to be
    valid.
    
    We may have to relax this for new partition creation, but for now we
    want to find and isolate the database corruption.
    
    The printing of the LDIF is moved above the checks to make it easier
    to diagnoise the failures when further reproduced.
    
    Based initially on a patch originally by Arvid Requate <requate at univention.de>
    
    Andrew Bartlett
    
    Signed-off-by: Andrew Bartlett <abartlet at samba.org>
    Change-Id: I5f583d89e6d4c5e8e2d9667f336a0e8fd8347b25
    Reviewed-on: https://gerrit.samba.org/164
    Reviewed-by: Kamen Mazdrashki <kamenim at samba.org>
    
    Autobuild-User(master): Andrew Bartlett <abartlet at samba.org>
    Autobuild-Date(master): Mon Mar 17 06:44:17 CET 2014 on sn-devel-104

-----------------------------------------------------------------------

Summary of changes:
 source4/dsdb/samdb/ldb_modules/repl_meta_data.c |  150 ++++++++++++++++++-----
 1 files changed, 118 insertions(+), 32 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source4/dsdb/samdb/ldb_modules/repl_meta_data.c b/source4/dsdb/samdb/ldb_modules/repl_meta_data.c
index e96bdf1..05ef176 100644
--- a/source4/dsdb/samdb/ldb_modules/repl_meta_data.c
+++ b/source4/dsdb/samdb/ldb_modules/repl_meta_data.c
@@ -699,31 +699,65 @@ static int replmd_replPropertyMetaData1_attid_sort(const struct replPropertyMeta
 	return attid_1 > attid_2 ? 1 : -1;
 }
 
-static int replmd_replPropertyMetaDataCtr1_sort(struct replPropertyMetaDataCtr1 *ctr1,
-						const struct dsdb_schema *schema,
-						struct ldb_dn *dn)
+static int replmd_replPropertyMetaDataCtr1_verify(struct ldb_context *ldb,
+						  struct replPropertyMetaDataCtr1 *ctr1,
+						  const struct dsdb_attribute *rdn_sa,
+						  struct ldb_dn *dn)
+{
+	if (ctr1->count == 0) {
+		ldb_debug_set(ldb, LDB_DEBUG_FATAL,
+			      "No elements found in replPropertyMetaData for %s!\n",
+			      ldb_dn_get_linearized(dn));
+		return LDB_ERR_CONSTRAINT_VIOLATION;
+	}
+	if (ctr1->array[ctr1->count - 1].attid != rdn_sa->attributeID_id) {
+		ldb_debug_set(ldb, LDB_DEBUG_FATAL,
+			      "No rDN found in replPropertyMetaData for %s!\n",
+			      ldb_dn_get_linearized(dn));
+		return LDB_ERR_CONSTRAINT_VIOLATION;
+	}
+
+	/* the objectClass attribute is value 0x00000000, so must be first */
+	if (ctr1->array[0].attid != DRSUAPI_ATTID_objectClass) {
+		ldb_debug_set(ldb, LDB_DEBUG_FATAL,
+			      "No objectClass found in replPropertyMetaData for %s!\n",
+			      ldb_dn_get_linearized(dn));
+		return LDB_ERR_OBJECT_CLASS_VIOLATION;
+	}
+
+	return LDB_SUCCESS;
+}
+
+static int replmd_replPropertyMetaDataCtr1_sort_and_verify(struct ldb_context *ldb,
+							   struct replPropertyMetaDataCtr1 *ctr1,
+							   const struct dsdb_schema *schema,
+							   struct ldb_dn *dn)
 {
 	const char *rdn_name;
 	const struct dsdb_attribute *rdn_sa;
 
 	rdn_name = ldb_dn_get_rdn_name(dn);
 	if (!rdn_name) {
-		DEBUG(0,(__location__ ": No rDN for %s?\n", ldb_dn_get_linearized(dn)));
-		return LDB_ERR_OPERATIONS_ERROR;
+		ldb_debug_set(ldb, LDB_DEBUG_FATAL,
+			      __location__ ": No rDN for %s?\n",
+			      ldb_dn_get_linearized(dn));
+		return LDB_ERR_INVALID_DN_SYNTAX;
 	}
 
 	rdn_sa = dsdb_attribute_by_lDAPDisplayName(schema, rdn_name);
 	if (rdn_sa == NULL) {
-		DEBUG(0,(__location__ ": No sa found for rDN %s for %s\n", rdn_name, ldb_dn_get_linearized(dn)));
-		return LDB_ERR_OPERATIONS_ERROR;
+		ldb_debug_set(ldb, LDB_DEBUG_FATAL,
+			      __location__ ": No sa found for rDN %s for %s\n",
+			      rdn_name, ldb_dn_get_linearized(dn));
+		return LDB_ERR_UNDEFINED_ATTRIBUTE_TYPE;
 	}
 
 	DEBUG(6,("Sorting rpmd with attid exception %u rDN=%s DN=%s\n",
 		 rdn_sa->attributeID_id, rdn_name, ldb_dn_get_linearized(dn)));
 
-	LDB_TYPESAFE_QSORT(ctr1->array, ctr1->count, &rdn_sa->attributeID_id, replmd_replPropertyMetaData1_attid_sort);
-
-	return LDB_SUCCESS;
+	LDB_TYPESAFE_QSORT(ctr1->array, ctr1->count, &rdn_sa->attributeID_id,
+			   replmd_replPropertyMetaData1_attid_sort);
+	return replmd_replPropertyMetaDataCtr1_verify(ldb, ctr1, rdn_sa, dn);
 }
 
 static int replmd_ldb_message_element_attid_sort(const struct ldb_message_element *e1,
@@ -1039,8 +1073,9 @@ static int replmd_add(struct ldb_module *module, struct ldb_request *req)
 	/*
 	 * sort meta data array, and move the rdn attribute entry to the end
 	 */
-	ret = replmd_replPropertyMetaDataCtr1_sort(&nmd.ctr.ctr1, ac->schema, msg->dn);
+	ret = replmd_replPropertyMetaDataCtr1_sort_and_verify(ldb, &nmd.ctr.ctr1, ac->schema, msg->dn);
 	if (ret != LDB_SUCCESS) {
+		ldb_asprintf_errstring(ldb, "%s: error during direct ADD: %s", __func__, ldb_errstring(ldb));
 		talloc_free(ac);
 		return ret;
 	}
@@ -1094,7 +1129,17 @@ static int replmd_add(struct ldb_module *module, struct ldb_request *req)
 	 */
 	replmd_ldb_message_sort(msg, ac->schema);
 
+	/*
+	 * Assert that we do have an objectClass
+	 */
 	objectclass_el = ldb_msg_find_element(msg, "objectClass");
+	if (objectclass_el == NULL) {
+		ldb_asprintf_errstring(ldb, __location__
+				       ": objectClass missing on %s\n",
+				       ldb_dn_get_linearized(msg->dn));
+		talloc_free(ac);
+		return LDB_ERR_OPERATIONS_ERROR;
+	}
 	is_urgent = replmd_check_urgent_objectclass(objectclass_el,
 							REPL_URGENT_ON_CREATE);
 
@@ -1412,12 +1457,6 @@ static int replmd_update_rpmd(struct ldb_module *module,
 			return ret;
 		}
 
-		objectclass_el = ldb_msg_find_element(res->msgs[0], "objectClass");
-		if (is_urgent && replmd_check_urgent_objectclass(objectclass_el,
-								situation)) {
-			*is_urgent = true;
-		}
-
 		db_seq = ldb_msg_find_attr_as_uint64(res->msgs[0], "uSNChanged", 0);
 		if (*seq_num <= db_seq) {
 			DEBUG(0,(__location__ ": changereplmetada control provided but max(local_usn)"\
@@ -1442,12 +1481,6 @@ static int replmd_update_rpmd(struct ldb_module *module,
 			return ret;
 		}
 
-		objectclass_el = ldb_msg_find_element(res->msgs[0], "objectClass");
-		if (is_urgent && replmd_check_urgent_objectclass(objectclass_el,
-								situation)) {
-			*is_urgent = true;
-		}
-
 		omd_value = ldb_msg_find_ldb_val(res->msgs[0], "replPropertyMetaData");
 		if (!omd_value) {
 			DEBUG(0,(__location__ ": Object %s does not have a replPropertyMetaData attribute\n",
@@ -1478,12 +1511,33 @@ static int replmd_update_rpmd(struct ldb_module *module,
 				return ret;
 			}
 
-			if (is_urgent && !*is_urgent && (situation == REPL_URGENT_ON_UPDATE)) {
+			if (!*is_urgent && (situation == REPL_URGENT_ON_UPDATE)) {
 				*is_urgent = replmd_check_urgent_attribute(&msg->elements[i]);
 			}
 
 		}
 	}
+
+	/*
+	 * Assert that we have an objectClass attribute - this is major
+	 * corruption if we don't have this!
+	 */
+	objectclass_el = ldb_msg_find_element(res->msgs[0], "objectClass");
+	if (objectclass_el == NULL) {
+		ldb_debug_set(ldb, LDB_DEBUG_FATAL,
+			      __location__ ": objectClass missing on %s\n",
+			      ldb_dn_get_linearized(msg->dn));
+		return LDB_ERR_OPERATIONS_ERROR;
+	}
+
+	/*
+	 * Now check if this objectClass means we need to do urgent replication
+	 */
+	if (!*is_urgent && replmd_check_urgent_objectclass(objectclass_el,
+							   situation)) {
+		*is_urgent = true;
+	}
+
 	/*
 	 * replmd_update_rpmd_element has done an update if the
 	 * seq_num is set
@@ -1518,8 +1572,9 @@ static int replmd_update_rpmd(struct ldb_module *module,
 			return LDB_ERR_OPERATIONS_ERROR;
 		}
 
-		ret = replmd_replPropertyMetaDataCtr1_sort(&omd.ctr.ctr1, schema, msg->dn);
+		ret = replmd_replPropertyMetaDataCtr1_sort_and_verify(ldb, &omd.ctr.ctr1, schema, msg->dn);
 		if (ret != LDB_SUCCESS) {
+			ldb_asprintf_errstring(ldb, "%s: %s", __func__, ldb_errstring(ldb));
 			return ret;
 		}
 
@@ -3845,6 +3900,8 @@ static int replmd_replicated_apply_add(struct replmd_replicated_request *ar)
 	unsigned int i;
 	int ret;
 	bool remote_isDeleted = false;
+	const struct dsdb_attribute *rdn_sa;
+	const char *rdn_name;
 
 	ldb = ldb_module_get_ctx(ar->module);
 	msg = ar->objs->objects[ar->index_current].msg;
@@ -3889,12 +3946,38 @@ static int replmd_replicated_apply_add(struct replmd_replicated_request *ar)
 		}
 	}
 
+	if (DEBUGLVL(4)) {
+		char *s = ldb_ldif_message_string(ldb, ar, LDB_CHANGETYPE_ADD, msg);
+		DEBUG(4, ("DRS replication add message:\n%s\n", s));
+		talloc_free(s);
+	}
+
 	remote_isDeleted = ldb_msg_find_attr_as_bool(msg,
 						     "isDeleted", false);
 
 	/*
 	 * the meta data array is already sorted by the caller
 	 */
+
+	rdn_name = ldb_dn_get_rdn_name(msg->dn);
+	if (rdn_name == NULL) {
+		ldb_asprintf_errstring(ldb, __location__ ": No rDN for %s?\n", ldb_dn_get_linearized(msg->dn));
+		return replmd_replicated_request_error(ar, LDB_ERR_INVALID_DN_SYNTAX);
+	}
+
+	rdn_sa = dsdb_attribute_by_lDAPDisplayName(ar->schema, rdn_name);
+	if (rdn_sa == NULL) {
+		ldb_asprintf_errstring(ldb, ": No schema attribute found for rDN %s for %s\n",
+				       rdn_name, ldb_dn_get_linearized(msg->dn));
+		return replmd_replicated_request_error(ar, LDB_ERR_UNDEFINED_ATTRIBUTE_TYPE);
+	}
+
+	ret = replmd_replPropertyMetaDataCtr1_verify(ldb, &md->ctr.ctr1, rdn_sa, msg->dn);
+	if (ret != LDB_SUCCESS) {
+		ldb_asprintf_errstring(ldb, "%s: error during DRS repl ADD: %s", __func__, ldb_errstring(ldb));
+		return replmd_replicated_request_error(ar, ret);
+	}
+
 	for (i=0; i < md->ctr.ctr1.count; i++) {
 		md->ctr.ctr1.array[i].local_usn = ar->seq_num;
 	}
@@ -3922,12 +4005,6 @@ static int replmd_replicated_apply_add(struct replmd_replicated_request *ar)
 
 	ar->isDeleted = remote_isDeleted;
 
-	if (DEBUGLVL(4)) {
-		char *s = ldb_ldif_message_string(ldb, ar, LDB_CHANGETYPE_ADD, msg);
-		DEBUG(4, ("DRS replication add message:\n%s\n", s));
-		talloc_free(s);
-	}
-
 	ret = ldb_build_add_req(&change_req,
 				ldb,
 				ar,
@@ -4404,8 +4481,9 @@ static int replmd_replicated_apply_merge(struct replmd_replicated_request *ar)
 	 *
 	 * sort the new meta data array
 	 */
-	ret = replmd_replPropertyMetaDataCtr1_sort(&nmd.ctr.ctr1, ar->schema, msg->dn);
+	ret = replmd_replPropertyMetaDataCtr1_sort_and_verify(ldb, &nmd.ctr.ctr1, ar->schema, msg->dn);
 	if (ret != LDB_SUCCESS) {
+		ldb_asprintf_errstring(ldb, "%s: error during DRS repl merge: %s", __func__, ldb_errstring(ldb));
 		return ret;
 	}
 
@@ -4479,6 +4557,14 @@ 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) {
+				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_OPERATIONS_ERROR);
+			}
+		}
 	}
 
 	if (DEBUGLVL(4)) {


-- 
Samba Shared Repository


More information about the samba-cvs mailing list