[SCM] Samba Shared Repository - branch master updated

Andrew Tridgell tridge at samba.org
Wed Oct 5 23:09:03 MDT 2011


The branch, master has been updated
       via  3fca66e samba-tool: add support for fixing broken backlinks in dbcheck
       via  d7f617e s4-dsdb: allow deletion of backlinks if DSDB_CONTROL_DBCHECK given
       via  c2d70af s4-dsdb: added DSDB_CONTROL_DBCHECK
       via  ea41860 ldb: support raw OIDs in control string parsing
       via  b3476f0 ldb: fixed memory leak in control string parsing
       via  2d63789 s4-dsdb: allow groupType update on deleted objects
       via  8976e1d s4-rodc: use the rodc_replica flag on the partition
       via  2a2deeb s4-rodc: ensure we load replicated partitions for RODCs
      from  e717af0 s4-dsdb: Do not assume that all deleted objects have an objectCategory and sAMAccountType

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


- Log -----------------------------------------------------------------
commit 3fca66e2b343c6386476a52832591ae4e435d6b2
Author: Andrew Tridgell <tridge at samba.org>
Date:   Thu Oct 6 14:21:41 2011 +1100

    samba-tool: add support for fixing broken backlinks in dbcheck
    
    this allows dangling backlinks to be removed
    
    Pair-Programmed-With: Andrew Bartlett <abartlet at samba.org>
    
    Autobuild-User: Andrew Tridgell <tridge at samba.org>
    Autobuild-Date: Thu Oct  6 07:08:35 CEST 2011 on sn-devel-104

commit d7f617e2e180eab6decb18e697f1e1294194a2cb
Author: Andrew Tridgell <tridge at samba.org>
Date:   Thu Oct 6 14:21:02 2011 +1100

    s4-dsdb: allow deletion of backlinks if DSDB_CONTROL_DBCHECK given
    
    Pair-Programmed-With: Andrew Bartlett <abartlet at samba.org>

commit c2d70af1a7b0a67283837a9f823158fd7f8db574
Author: Andrew Tridgell <tridge at samba.org>
Date:   Thu Oct 6 14:20:25 2011 +1100

    s4-dsdb: added DSDB_CONTROL_DBCHECK
    
    this will be used for overrides by the dbcheck validator
    
    Pair-Programmed-With: Andrew Bartlett <abartlet at samba.org>

commit ea41860d32d38448e08cefd79d30ee1150317a9e
Author: Andrew Tridgell <tridge at samba.org>
Date:   Thu Oct 6 14:19:24 2011 +1100

    ldb: support raw OIDs in control string parsing
    
    this makes it possible to use a raw OID string on the command line or
    in python scripts
    
    Pair-Programmed-With: Andrew Bartlett <abartlet at samba.org>

commit b3476f00a621cf2d5d547ed479acf91b5cc0679c
Author: Andrew Tridgell <tridge at samba.org>
Date:   Thu Oct 6 14:18:49 2011 +1100

    ldb: fixed memory leak in control string parsing
    
    if parsing fails, free ctrl
    
    Pair-Programmed-With: Andrew Bartlett <abartlet at samba.org>

commit 2d63789e4869c147364d4e58c678a0c08b2e6859
Author: Andrew Tridgell <tridge at samba.org>
Date:   Thu Oct 6 12:31:21 2011 +1100

    s4-dsdb: allow groupType update on deleted objects
    
    this allows dbcheck to fix groupType on objects that have been deleted
    
    Pair-Programmed-With: Andrew Bartlett <abartlet at samba.org>

commit 8976e1d50d6dc6633af82e05afe51ef41b61c66c
Author: Andrew Tridgell <tridge at samba.org>
Date:   Thu Oct 6 11:24:28 2011 +1100

    s4-rodc: use the rodc_replica flag on the partition
    
    this sets DSDB_REPL_FLAG_PARTIAL_REPLICA when replicating a RODC
    partition, which tells the replication code to map instanceType to
    remove the INSTANCE_TYPE_WRITE bit
    
    Pair-Programmed-With: Andrew Bartlett <abartlet at samba.org>

commit 2a2deeb3b43dcb11f2b604bdd20c1183e87522bb
Author: Andrew Tridgell <tridge at samba.org>
Date:   Thu Oct 6 11:14:13 2011 +1100

    s4-rodc: ensure we load replicated partitions for RODCs
    
    Pair-Programmed-With: Andrew Bartlett <abartlet at samba.org>

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

Summary of changes:
 lib/ldb/common/ldb_controls.c                      |   42 +++++++++
 lib/ldb/include/ldb_private.h                      |    1 +
 source4/dsdb/pydsdb.c                              |    1 +
 source4/dsdb/repl/drepl_out_helpers.c              |    4 +-
 source4/dsdb/repl/drepl_partitions.c               |   89 +++++++++-----------
 source4/dsdb/repl/drepl_service.h                  |    2 +-
 source4/dsdb/samdb/ldb_modules/objectclass_attrs.c |    3 +-
 source4/dsdb/samdb/ldb_modules/repl_meta_data.c    |    3 +
 source4/dsdb/samdb/ldb_modules/samldb.c            |    3 +-
 source4/dsdb/samdb/samdb.h                         |    3 +
 source4/scripting/python/samba/dbchecker.py        |   52 +++++++-----
 source4/setup/schema_samba4.ldif                   |    1 +
 12 files changed, 129 insertions(+), 75 deletions(-)


Changeset truncated at 500 lines:

diff --git a/lib/ldb/common/ldb_controls.c b/lib/ldb/common/ldb_controls.c
index 3856167..42fabfc 100644
--- a/lib/ldb/common/ldb_controls.c
+++ b/lib/ldb/common/ldb_controls.c
@@ -428,6 +428,7 @@ struct ldb_control *ldb_parse_control_from_string(struct ldb_context *ldb, TALLO
 			error_string = talloc_asprintf_append(error_string, "   note: b = boolean, n = number, s = string, o = b64 binary blob");
 			ldb_set_errstring(ldb, error_string);
 			talloc_free(error_string);
+			talloc_free(ctrl);
 			return NULL;
 		}
 		ctrl->oid = LDB_CONTROL_VLV_REQ_OID;
@@ -435,6 +436,7 @@ struct ldb_control *ldb_parse_control_from_string(struct ldb_context *ldb, TALLO
 		if (!(control = talloc(ctrl,
 					struct ldb_vlv_req_control))) {
 			ldb_oom(ldb);
+			talloc_free(ctrl);
 			return NULL;
 		}
 		control->beforeCount = bc;
@@ -477,6 +479,7 @@ struct ldb_control *ldb_parse_control_from_string(struct ldb_context *ldb, TALLO
 			error_string = talloc_asprintf_append(error_string, "   note: b = boolean, n = number, o = b64 binary blob");
 			ldb_set_errstring(ldb, error_string);
 			talloc_free(error_string);
+			talloc_free(ctrl);
 			return NULL;
 		}
 
@@ -519,6 +522,7 @@ struct ldb_control *ldb_parse_control_from_string(struct ldb_context *ldb, TALLO
 			error_string = talloc_asprintf_append(error_string, "   note: b = boolean, s = string");
 			ldb_set_errstring(ldb, error_string);
 			talloc_free(error_string);
+			talloc_free(ctrl);
 			return NULL;
 		}
 
@@ -551,6 +555,7 @@ struct ldb_control *ldb_parse_control_from_string(struct ldb_context *ldb, TALLO
 				error_string = talloc_asprintf_append(error_string, "                     1 - normal string representation");
 				ldb_set_errstring(ldb, error_string);
 				talloc_free(error_string);
+				talloc_free(ctrl);
 				return NULL;
 			}
 			control = NULL;
@@ -580,6 +585,7 @@ struct ldb_control *ldb_parse_control_from_string(struct ldb_context *ldb, TALLO
 			error_string = talloc_asprintf_append(error_string, "   note: b = boolean, n = number");
 			ldb_set_errstring(ldb, error_string);
 			talloc_free(error_string);
+			talloc_free(ctrl);
 			return NULL;
 		}
 
@@ -606,6 +612,7 @@ struct ldb_control *ldb_parse_control_from_string(struct ldb_context *ldb, TALLO
 			error_string = talloc_asprintf_append(error_string, "   note: b = boolean, n = number");
 			ldb_set_errstring(ldb, error_string);
 			talloc_free(error_string);
+			talloc_free(ctrl);
 			return NULL;
 		}
 
@@ -630,6 +637,7 @@ struct ldb_control *ldb_parse_control_from_string(struct ldb_context *ldb, TALLO
 			error_string = talloc_asprintf_append(error_string, "   note: b = boolean");
 			ldb_set_errstring(ldb, error_string);
 			talloc_free(error_string);
+			talloc_free(ctrl);
 			return NULL;
 		}
 
@@ -652,6 +660,7 @@ struct ldb_control *ldb_parse_control_from_string(struct ldb_context *ldb, TALLO
 			error_string = talloc_asprintf_append(error_string, "   note: b = boolean");
 			ldb_set_errstring(ldb, error_string);
 			talloc_free(error_string);
+			talloc_free(ctrl);
 			return NULL;
 		}
 
@@ -674,6 +683,7 @@ struct ldb_control *ldb_parse_control_from_string(struct ldb_context *ldb, TALLO
 			error_string = talloc_asprintf_append(error_string, "   note: b = boolean");
 			ldb_set_errstring(ldb, error_string);
 			talloc_free(error_string);
+			talloc_free(ctrl);
 			return NULL;
 		}
 
@@ -696,6 +706,7 @@ struct ldb_control *ldb_parse_control_from_string(struct ldb_context *ldb, TALLO
 			error_string = talloc_asprintf_append(error_string, "   note: b = boolean");
 			ldb_set_errstring(ldb, error_string);
 			talloc_free(error_string);
+			talloc_free(ctrl);
 			return NULL;
 		}
 
@@ -719,6 +730,7 @@ struct ldb_control *ldb_parse_control_from_string(struct ldb_context *ldb, TALLO
 			error_string = talloc_asprintf_append(error_string, "   note: b = boolean, n = number");
 			ldb_set_errstring(ldb, error_string);
 			talloc_free(error_string);
+			talloc_free(ctrl);
 			return NULL;
 		}
 
@@ -750,6 +762,7 @@ struct ldb_control *ldb_parse_control_from_string(struct ldb_context *ldb, TALLO
 			error_string = talloc_asprintf_append(error_string, "   note: b = boolean, s = string");
 			ldb_set_errstring(ldb, error_string);
 			talloc_free(error_string);
+			talloc_free(ctrl);
 			return NULL;
 		}
 		ctrl->oid = LDB_CONTROL_SERVER_SORT_OID;
@@ -780,6 +793,7 @@ struct ldb_control *ldb_parse_control_from_string(struct ldb_context *ldb, TALLO
 			error_string = talloc_asprintf_append(error_string, "   note: b = boolean");
 			ldb_set_errstring(ldb, error_string);
 			talloc_free(error_string);
+			talloc_free(ctrl);
 			return NULL;
 		}
 
@@ -802,6 +816,7 @@ struct ldb_control *ldb_parse_control_from_string(struct ldb_context *ldb, TALLO
 			error_string = talloc_asprintf_append(error_string, "   note: b = boolean");
 			ldb_set_errstring(ldb, error_string);
 			talloc_free(error_string);
+			talloc_free(ctrl);
 			return NULL;
 		}
 
@@ -824,6 +839,7 @@ struct ldb_control *ldb_parse_control_from_string(struct ldb_context *ldb, TALLO
 			error_string = talloc_asprintf_append(error_string, "   note: b = boolean");
 			ldb_set_errstring(ldb, error_string);
 			talloc_free(error_string);
+			talloc_free(ctrl);
 			return NULL;
 		}
 
@@ -846,6 +862,7 @@ struct ldb_control *ldb_parse_control_from_string(struct ldb_context *ldb, TALLO
 			error_string = talloc_asprintf_append(error_string, "   note: b = boolean");
 			ldb_set_errstring(ldb, error_string);
 			talloc_free(error_string);
+			talloc_free(ctrl);
 			return NULL;
 		}
 
@@ -868,6 +885,7 @@ struct ldb_control *ldb_parse_control_from_string(struct ldb_context *ldb, TALLO
 			error_string = talloc_asprintf_append(error_string, "   note: b = boolean");
 			ldb_set_errstring(ldb, error_string);
 			talloc_free(error_string);
+			talloc_free(ctrl);
 			return NULL;
 		}
 
@@ -890,6 +908,7 @@ struct ldb_control *ldb_parse_control_from_string(struct ldb_context *ldb, TALLO
 			error_string = talloc_asprintf_append(error_string, "   note: b = boolean");
 			ldb_set_errstring(ldb, error_string);
 			talloc_free(error_string);
+			talloc_free(ctrl);
 			return NULL;
 		}
 
@@ -912,6 +931,7 @@ struct ldb_control *ldb_parse_control_from_string(struct ldb_context *ldb, TALLO
 			error_string = talloc_asprintf_append(error_string, "   note: b = boolean");
 			ldb_set_errstring(ldb, error_string);
 			talloc_free(error_string);
+			talloc_free(ctrl);
 			return NULL;
 		}
 
@@ -937,12 +957,14 @@ struct ldb_control *ldb_parse_control_from_string(struct ldb_context *ldb, TALLO
 			error_string = talloc_asprintf_append(error_string, "   note: b = boolean, s = string");
 			ldb_set_errstring(ldb, error_string);
 			talloc_free(error_string);
+			talloc_free(ctrl);
 			return NULL;
 		}
 
 		ctrl->oid = talloc_strdup(ctrl, oid);
 		if (!ctrl->oid) {
 			ldb_oom(ldb);
+			talloc_free(ctrl);
 			return NULL;
 		}
 		ctrl->critical = crit;
@@ -963,6 +985,7 @@ struct ldb_control *ldb_parse_control_from_string(struct ldb_context *ldb, TALLO
 			error_string = talloc_asprintf_append(error_string, "   note: b = boolean");
 			ldb_set_errstring(ldb, error_string);
 			talloc_free(error_string);
+			talloc_free(ctrl);
 			return NULL;
 		}
 
@@ -985,6 +1008,7 @@ struct ldb_control *ldb_parse_control_from_string(struct ldb_context *ldb, TALLO
 			error_string = talloc_asprintf_append(error_string, "   note: b = boolean");
 			ldb_set_errstring(ldb, error_string);
 			talloc_free(error_string);
+			talloc_free(ctrl);
 			return NULL;
 		}
 
@@ -994,9 +1018,27 @@ struct ldb_control *ldb_parse_control_from_string(struct ldb_context *ldb, TALLO
 
 		return ctrl;
 	}
+
+	/* support a raw OID */
+	if (isdigit(control_strings[0])) {
+		const char *p = strchr(control_strings, ':');
+		if (p == NULL) {
+			goto failed;
+		}
+		if (strspn(control_strings, "0123456789.") != (p-control_strings)) {
+			goto failed;
+		}
+		ctrl->oid = talloc_strndup(ctrl, control_strings, p-control_strings);
+		ctrl->critical = (p[1]=='1'?1:0);
+		ctrl->data = NULL;
+		return ctrl;
+	}
+
 	/*
 	 * When no matching control has been found.
 	 */
+failed:
+	talloc_free(ctrl);
 	return NULL;
 }
 
diff --git a/lib/ldb/include/ldb_private.h b/lib/ldb/include/ldb_private.h
index cafc020..db2457d 100644
--- a/lib/ldb/include/ldb_private.h
+++ b/lib/ldb/include/ldb_private.h
@@ -40,6 +40,7 @@
 #include "replace.h"
 #include "system/filesys.h"
 #include "system/time.h"
+#include "system/locale.h"
 #include "ldb.h"
 #include "ldb_module.h"
 
diff --git a/source4/dsdb/pydsdb.c b/source4/dsdb/pydsdb.c
index 18c2f7b..2ff6b82 100644
--- a/source4/dsdb/pydsdb.c
+++ b/source4/dsdb/pydsdb.c
@@ -1151,4 +1151,5 @@ void initdsdb(void)
 	ADD_DSDB_STRING(DSDB_SYNTAX_BINARY_DN);
 	ADD_DSDB_STRING(DSDB_SYNTAX_STRING_DN);
 	ADD_DSDB_STRING(DSDB_SYNTAX_OR_NAME);
+	ADD_DSDB_STRING(DSDB_CONTROL_DBCHECK);
 }
diff --git a/source4/dsdb/repl/drepl_out_helpers.c b/source4/dsdb/repl/drepl_out_helpers.c
index 7cb642a..71d2c3b 100644
--- a/source4/dsdb/repl/drepl_out_helpers.c
+++ b/source4/dsdb/repl/drepl_out_helpers.c
@@ -424,7 +424,7 @@ static void dreplsrv_op_pull_source_get_changes_trigger(struct tevent_req *req)
 			return;
 		}
 		replica_flags &= ~DRSUAPI_DRS_WRIT_REP;
-	} else if (service->am_rodc) {
+	} else if (partition->rodc_replica) {
 		bool for_schema = false;
 		if (ldb_dn_compare_base(ldb_get_schema_basedn(service->samdb), partition->dn) == 0) {
 			for_schema = true;
@@ -675,7 +675,7 @@ static void dreplsrv_op_pull_source_apply_changes_trigger(struct tevent_req *req
 		}
 	}
 
-	if (partition->partial_replica) {
+	if (partition->partial_replica || partition->rodc_replica) {
 		dsdb_repl_flags |= DSDB_REPL_FLAG_PARTIAL_REPLICA;
 	}
 	if (state->op->options & DRSUAPI_DRS_FULL_SYNC_IN_PROGRESS) {
diff --git a/source4/dsdb/repl/drepl_partitions.c b/source4/dsdb/repl/drepl_partitions.c
index 7c54245..f2d4b13 100644
--- a/source4/dsdb/repl/drepl_partitions.c
+++ b/source4/dsdb/repl/drepl_partitions.c
@@ -34,11 +34,15 @@
 #include "param/param.h"
 #include "dsdb/common/util.h"
 
+/*
+  load the partitions list based on replicated NC attributes in our
+  NTDSDSA object
+ */
 WERROR dreplsrv_load_partitions(struct dreplsrv_service *s)
 {
 	WERROR status;
-	static const char *attrs[] = { "hasMasterNCs", "hasPartialReplicaNCs", NULL };
-	unsigned int i;
+	static const char *attrs[] = { "hasMasterNCs", "hasPartialReplicaNCs", "msDS-HasFullReplicaNCs", NULL };
+	unsigned int a;
 	int ret;
 	TALLOC_CTX *tmp_ctx;
 	struct ldb_result *res;
@@ -62,57 +66,42 @@ WERROR dreplsrv_load_partitions(struct dreplsrv_service *s)
 		return WERR_DS_DRA_INTERNAL_ERROR;
 	}
 
-	el = ldb_msg_find_element(res->msgs[0], "hasMasterNCs");
-
-	for (i=0; el && i<el->num_values; i++) {
-		struct ldb_dn *pdn;
-		struct dreplsrv_partition *p;
+	for (a=0; attrs[a]; a++) {
+		int i;
 
-		pdn = ldb_dn_from_ldb_val(tmp_ctx, s->samdb, &el->values[i]);
-		if (pdn == NULL) {
-			talloc_free(tmp_ctx);
-			return WERR_DS_DRA_INTERNAL_ERROR;
+		el = ldb_msg_find_element(res->msgs[0], attrs[a]);
+		if (el == NULL) {
+			continue;
 		}
-		if (!ldb_dn_validate(pdn)) {
-			return WERR_DS_DRA_INTERNAL_ERROR;
-		}
-
-		p = talloc_zero(s, struct dreplsrv_partition);
-		W_ERROR_HAVE_NO_MEMORY(p);
-
-		p->dn = talloc_steal(p, pdn);
-		p->service = s;
+		for (i=0; i<el->num_values; i++) {
+			struct ldb_dn *pdn;
+			struct dreplsrv_partition *p;
+
+			pdn = ldb_dn_from_ldb_val(tmp_ctx, s->samdb, &el->values[i]);
+			if (pdn == NULL) {
+				talloc_free(tmp_ctx);
+				return WERR_DS_DRA_INTERNAL_ERROR;
+			}
+			if (!ldb_dn_validate(pdn)) {
+				return WERR_DS_DRA_INTERNAL_ERROR;
+			}
 
-		DLIST_ADD(s->partitions, p);
+			p = talloc_zero(s, struct dreplsrv_partition);
+			W_ERROR_HAVE_NO_MEMORY(p);
 
-		DEBUG(2, ("dreplsrv_partition[%s] loaded\n", ldb_dn_get_linearized(p->dn)));
-	}
+			p->dn = talloc_steal(p, pdn);
+			p->service = s;
 
-	el = ldb_msg_find_element(res->msgs[0], "hasPartialReplicaNCs");
+			if (strcasecmp(attrs[a], "hasPartialReplicaNCs") == 0) {
+				p->partial_replica = true;
+			} else if (strcasecmp(attrs[a], "msDS-HasFullReplicaNCs") == 0) {
+				p->rodc_replica = true;
+			}
 
-	for (i=0; el && i<el->num_values; i++) {
-		struct ldb_dn *pdn;
-		struct dreplsrv_partition *p;
+			DLIST_ADD(s->partitions, p);
 
-		pdn = ldb_dn_from_ldb_val(tmp_ctx, s->samdb, &el->values[i]);
-		if (pdn == NULL) {
-			talloc_free(tmp_ctx);
-			return WERR_DS_DRA_INTERNAL_ERROR;
-		}
-		if (!ldb_dn_validate(pdn)) {
-			return WERR_DS_DRA_INTERNAL_ERROR;
+			DEBUG(2, ("dreplsrv_partition[%s] loaded\n", ldb_dn_get_linearized(p->dn)));
 		}
-
-		p = talloc_zero(s, struct dreplsrv_partition);
-		W_ERROR_HAVE_NO_MEMORY(p);
-
-		p->dn = talloc_steal(p, pdn);
-		p->partial_replica = true;
-		p->service = s;
-
-		DLIST_ADD(s->partitions, p);
-
-		DEBUG(2, ("dreplsrv_partition[%s] loaded (partial replica)\n", ldb_dn_get_linearized(p->dn)));
 	}
 
 	talloc_free(tmp_ctx);
diff --git a/source4/dsdb/repl/drepl_service.h b/source4/dsdb/repl/drepl_service.h
index 9856452..6daf82d 100644
--- a/source4/dsdb/repl/drepl_service.h
+++ b/source4/dsdb/repl/drepl_service.h
@@ -106,8 +106,8 @@ struct dreplsrv_partition {
 	 */
 	struct dreplsrv_partition_source_dsa *notifies;
 
-	bool incoming_only;
 	bool partial_replica;
+	bool rodc_replica;
 };
 
 typedef void (*dreplsrv_extended_callback_t)(struct dreplsrv_service *,
diff --git a/source4/dsdb/samdb/ldb_modules/objectclass_attrs.c b/source4/dsdb/samdb/ldb_modules/objectclass_attrs.c
index 9893ada..b6f9165 100644
--- a/source4/dsdb/samdb/ldb_modules/objectclass_attrs.c
+++ b/source4/dsdb/samdb/ldb_modules/objectclass_attrs.c
@@ -173,7 +173,8 @@ static int attr_handler(struct oc_context *ac)
 		}
 
 		if ((attr->linkID & 1) == 1 &&
-		    !ldb_request_get_control(ac->req, LDB_CONTROL_RELAX_OID)) {
+		    !ldb_request_get_control(ac->req, LDB_CONTROL_RELAX_OID) &&
+		    !ldb_request_get_control(ac->req, DSDB_CONTROL_DBCHECK)) {
 			/* Odd is for the target.  Illegal to modify */
 			ldb_asprintf_errstring(ldb, 
 					       "objectclass_attrs: attribute '%s' on entry '%s' must not be modified directly, it is a linked attribute", 
diff --git a/source4/dsdb/samdb/ldb_modules/repl_meta_data.c b/source4/dsdb/samdb/ldb_modules/repl_meta_data.c
index fff542a..2be0760 100644
--- a/source4/dsdb/samdb/ldb_modules/repl_meta_data.c
+++ b/source4/dsdb/samdb/ldb_modules/repl_meta_data.c
@@ -2179,6 +2179,9 @@ static int replmd_modify_handle_linked_attribs(struct ldb_module *module,
 			continue;
 		}
 		if ((schema_attr->linkID & 1) == 1) {
+			if (parent && ldb_request_get_control(parent, DSDB_CONTROL_DBCHECK)) {
+				continue;
+			}
 			/* Odd is for the target.  Illegal to modify */
 			ldb_asprintf_errstring(ldb,
 					       "attribute %s must not be modified directly, it is a linked attribute", el->name);
diff --git a/source4/dsdb/samdb/ldb_modules/samldb.c b/source4/dsdb/samdb/ldb_modules/samldb.c
index b1f6b72..e0400fa 100644
--- a/source4/dsdb/samdb/ldb_modules/samldb.c
+++ b/source4/dsdb/samdb/ldb_modules/samldb.c
@@ -1458,7 +1458,8 @@ static int samldb_group_type_change(struct samldb_ctx *ac)
 	talloc_free(tmp_msg);
 
 	ret = dsdb_module_search_dn(ac->module, ac, &res, ac->msg->dn, attrs,
-				    DSDB_FLAG_NEXT_MODULE, ac->req);
+				    DSDB_FLAG_NEXT_MODULE |
+				    DSDB_SEARCH_SHOW_DELETED, ac->req);
 	if (ret != LDB_SUCCESS) {
 		return ret;
 	}
diff --git a/source4/dsdb/samdb/samdb.h b/source4/dsdb/samdb/samdb.h
index 4c89f24..aedd3db 100644
--- a/source4/dsdb/samdb/samdb.h
+++ b/source4/dsdb/samdb/samdb.h
@@ -99,6 +99,9 @@ struct dsdb_control_password_change_status {
 /* passed when we want special behaviour for partial replicas */
 #define DSDB_CONTROL_PARTIAL_REPLICA "1.3.6.1.4.1.7165.4.3.18"
 
+/* passed when we want special behaviour for dbcheck */
+#define DSDB_CONTROL_DBCHECK "1.3.6.1.4.1.7165.4.3.19"
+
 struct dsdb_control_password_change {
 	const struct samr_Password *old_nt_pwd_hash;
 	const struct samr_Password *old_lm_pwd_hash;
diff --git a/source4/scripting/python/samba/dbchecker.py b/source4/scripting/python/samba/dbchecker.py
index ea5a903..f19891a 100644
--- a/source4/scripting/python/samba/dbchecker.py
+++ b/source4/scripting/python/samba/dbchecker.py
@@ -201,6 +201,32 @@ class dbcheck(object):
 
 
     ################################################################
+    # handle a DN pointing to a deleted object
+    def err_deleted_dn(self, dn, attrname, val, dsdb_dn, correct_dn):
+        self.report("ERROR: target DN is deleted for %s in object %s - %s" % (attrname, dn, val))
+        self.report("Target GUID points at deleted DN %s" % correct_dn)
+        if not self.confirm_all('Remove DN link?', 'remove_all_deleted_DN_links'):
+            self.report("Not removing")
+            return
+        m = ldb.Message()
+        m.dn = dn
+        m['old_value'] = ldb.MessageElement(val, ldb.FLAG_MOD_DELETE, attrname)
+        if self.do_modify(m, ["show_recycled:1", "%s:0" % dsdb.DSDB_CONTROL_DBCHECK],
+                          "Failed to remove deleted DN attribute %s" % attrname):
+            self.report("Removed deleted DN on attribute %s" % attrname)
+
+    ################################################################
+    # handle a missing target DN (both GUID and DN string form are missing)
+    def err_missing_dn_GUID(self, dn, attrname, val, dsdb_dn):
+        # check if its a backlink
+        linkID = self.samdb_schema.get_linkId_from_lDAPDisplayName(attrname)
+        if (linkID & 1 == 0) and str(dsdb_dn).find('DEL\\0A') == -1:
+            self.report("Not removing dangling forward link")
+            return
+        self.err_deleted_dn(dn, attrname, val, dsdb_dn, dsdb_dn)
+
+
+    ################################################################
     # handle a missing GUID extended DN component
     def err_incorrect_dn_GUID(self, dn, attrname, val, dsdb_dn, errstr):
         self.report("ERROR: %s component for %s in object %s - %s" % (errstr, attrname, dn, val))
@@ -209,10 +235,12 @@ class dbcheck(object):
             res = self.samdb.search(base=str(dsdb_dn.dn), scope=ldb.SCOPE_BASE,
                                     attrs=[], controls=controls)
         except ldb.LdbError, (enum, estr):
-            self.report("unable to find object for DN %s - cannot fix (%s)" % (dsdb_dn.dn, estr))
+            self.report("unable to find object for DN %s - (%s)" % (dsdb_dn.dn, estr))
+            self.err_missing_dn_GUID(dn, attrname, val, dsdb_dn)
             return
         if len(res) == 0:
-            self.report("unable to find object for DN %s - cannot fix" % dsdb_dn.dn)
+            self.report("unable to find object for DN %s" % dsdb_dn.dn)
+            self.err_missing_dn_GUID(dn, attrname, val, dsdb_dn)
             return
         dsdb_dn.dn = res[0].dn
 
@@ -230,22 +258,6 @@ class dbcheck(object):
 
 


-- 
Samba Shared Repository


More information about the samba-cvs mailing list