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 <tri...@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 <abart...@samba.org> Autobuild-User: Andrew Tridgell <tri...@samba.org> Autobuild-Date: Thu Oct 6 07:08:35 CEST 2011 on sn-devel-104 commit d7f617e2e180eab6decb18e697f1e1294194a2cb Author: Andrew Tridgell <tri...@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 <abart...@samba.org> commit c2d70af1a7b0a67283837a9f823158fd7f8db574 Author: Andrew Tridgell <tri...@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 <abart...@samba.org> commit ea41860d32d38448e08cefd79d30ee1150317a9e Author: Andrew Tridgell <tri...@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 <abart...@samba.org> commit b3476f00a621cf2d5d547ed479acf91b5cc0679c Author: Andrew Tridgell <tri...@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 <abart...@samba.org> commit 2d63789e4869c147364d4e58c678a0c08b2e6859 Author: Andrew Tridgell <tri...@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 <abart...@samba.org> commit 8976e1d50d6dc6633af82e05afe51ef41b61c66c Author: Andrew Tridgell <tri...@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 <abart...@samba.org> commit 2a2deeb3b43dcb11f2b604bdd20c1183e87522bb Author: Andrew Tridgell <tri...@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 <abart...@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