The Samba-Bugzilla – Attachment 12655 Details for
Bug 12399
replmd_update_rpmd_rdn_attr doesn't normalize rdn attribute name
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
Work in progress patches including dbcheck support (untested!)
wip.diff.txt (text/plain), 33.32 KB, created by
Stefan Metzmacher
on 2016-11-11 15:02:40 UTC
(
hide
)
Description:
Work in progress patches including dbcheck support (untested!)
Filename:
MIME Type:
Creator:
Stefan Metzmacher
Created:
2016-11-11 15:02:40 UTC
Size:
33.32 KB
patch
obsolete
>From af7658d6dd4ba862ae62f0ed0dd12877617dc534 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Thu, 10 Nov 2016 14:01:21 +0100 >Subject: [PATCH 01/11] ldb:rdn_name: normalize rdn_name in > rdn_rename_callback() > >We already do that on 'add'. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=12399 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >--- > lib/ldb/modules/rdn_name.c | 10 ++++++++++ > 1 file changed, 10 insertions(+) > >diff --git a/lib/ldb/modules/rdn_name.c b/lib/ldb/modules/rdn_name.c >index f44ea71..e8d5d8a 100644 >--- a/lib/ldb/modules/rdn_name.c >+++ b/lib/ldb/modules/rdn_name.c >@@ -243,6 +243,7 @@ static int rdn_rename_callback(struct ldb_request *req, struct ldb_reply *ares) > struct rename_context *ac; > struct ldb_request *mod_req; > const char *rdn_name; >+ const struct ldb_schema_attribute *a = NULL; > const struct ldb_val *rdn_val_p; > struct ldb_val rdn_val; > struct ldb_message *msg; >@@ -286,6 +287,15 @@ static int rdn_rename_callback(struct ldb_request *req, struct ldb_reply *ares) > goto error; > } > >+ a = ldb_schema_attribute_by_name(ldb, rdn_name); >+ if (a == NULL) { >+ goto error; >+ } >+ >+ if (a->name != NULL) { >+ rdn_name = a->name; >+ } >+ > rdn_val_p = ldb_dn_get_rdn_val(msg->dn); > if (rdn_val_p == NULL) { > goto error; >-- >1.9.1 > > >From b11c59b6a8a9857ace9cc0f56d5ac84311f141bd Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Thu, 10 Nov 2016 18:01:47 +0100 >Subject: [PATCH 02/11] ldb:controls: add LDB_CONTROL_RECALCULATE_RDN_OID > >This will be used by 'samba-tool dbcheck' to fix the rdn attribute name. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=12399 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >--- > lib/ldb/common/ldb_controls.c | 22 ++++++++++++++++++++++ > lib/ldb/include/ldb.h | 8 ++++++++ > source4/setup/schema_samba4.ldif | 1 + > 3 files changed, 31 insertions(+) > >diff --git a/lib/ldb/common/ldb_controls.c b/lib/ldb/common/ldb_controls.c >index a83768a..3b474c2 100644 >--- a/lib/ldb/common/ldb_controls.c >+++ b/lib/ldb/common/ldb_controls.c >@@ -821,6 +821,28 @@ struct ldb_control *ldb_parse_control_from_string(struct ldb_context *ldb, TALLO > return ctrl; > } > >+ if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_RECALCULATE_RDN_NAME) == 0) { >+ const char *p; >+ int crit, ret; >+ >+ p = &(control_strings[sizeof(LDB_CONTROL_RECALCULATE_RDN_NAME)]); >+ ret = sscanf(p, "%d", &crit); >+ if ((ret != 1) || (crit < 0) || (crit > 1)) { >+ ldb_set_errstring(ldb, >+ "invalid recalculate_rdn control syntax\n" >+ " syntax: crit(b)\n" >+ " note: b = boolean"); >+ talloc_free(ctrl); >+ return NULL; >+ } >+ >+ ctrl->oid = LDB_CONTROL_RECALCULATE_RDN_OID; >+ ctrl->critical = crit; >+ ctrl->data = NULL; >+ >+ return ctrl; >+ } >+ > if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_DOMAIN_SCOPE_NAME) == 0) { > const char *p; > int crit, ret; >diff --git a/lib/ldb/include/ldb.h b/lib/ldb/include/ldb.h >index 7422d46..bddb1fb 100644 >--- a/lib/ldb/include/ldb.h >+++ b/lib/ldb/include/ldb.h >@@ -499,6 +499,14 @@ typedef int (*ldb_qsort_cmp_fn_t) (void *v1, void *v2, void *opaque); > #define LDB_CONTROL_BYPASS_OPERATIONAL_NAME "bypassoperational" > > /** >+ OID for recalculate RDN (rdn attribute and 'name') control. This control forces >+ the rdn_name module to the recalculate the rdn and name attributes as if the >+ object was just created. >+*/ >+#define LDB_CONTROL_RECALCULATE_RDN_OID "1.3.6.1.4.1.7165.4.3.30" >+#define LDB_CONTROL_RECALCULATE_RDN_NAME "recalculate_rdn" >+ >+/** > OID for recalculate SD control. This control force the > dsdb code to recalculate the SD of the object as if the > object was just created. >diff --git a/source4/setup/schema_samba4.ldif b/source4/setup/schema_samba4.ldif >index 04505de..b63bd30 100644 >--- a/source4/setup/schema_samba4.ldif >+++ b/source4/setup/schema_samba4.ldif >@@ -217,6 +217,7 @@ > #Allocated: DSDB_CONTROL_PASSWORD_USER_ACCOUNT_CONTROL_OID 1.3.6.1.4.1.7165.4.3.27 > #Allocated: DSDB_CONTROL_SKIP_DUPLICATES_CHECK_OID 1.3.6.1.4.1.7165.4.3.28 > #Allocated: DSDB_CONTROL_REPLMD_VANISH_LINKS 1.3.6.1.4.1.7165.4.3.29 >+#Allocated: LDB_CONTROL_RECALCULATE_RDN_OID 1.3.6.1.4.1.7165.4.3.30 > > # Extended 1.3.6.1.4.1.7165.4.4.x > #Allocated: DSDB_EXTENDED_REPLICATED_OBJECTS_OID 1.3.6.1.4.1.7165.4.4.1 >-- >1.9.1 > > >From 67f99d9e8bafc845cecaeb583fa376dd292794eb Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Thu, 10 Nov 2016 18:03:26 +0100 >Subject: [PATCH 03/11] ldb:rdn_name: add support for > LDB_CONTROL_RECALCULATE_RDN_OID on ldb_modify() > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=12399 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >--- > lib/ldb/modules/rdn_name.c | 141 +++++++++++++++++++++++++++++++++++++++++++++ > 1 file changed, 141 insertions(+) > >diff --git a/lib/ldb/modules/rdn_name.c b/lib/ldb/modules/rdn_name.c >index e8d5d8a..4697782 100644 >--- a/lib/ldb/modules/rdn_name.c >+++ b/lib/ldb/modules/rdn_name.c >@@ -377,11 +377,20 @@ static int rdn_name_rename(struct ldb_module *module, struct ldb_request *req) > return ldb_next_request(module, down_req); > } > >+static int rdn_recalculate_callback(struct ldb_request *req, struct ldb_reply *ares) >+{ >+ struct ldb_request *up_req = talloc_get_type(req->context, struct ldb_request); >+ >+ talloc_steal(up_req, req); >+ return up_req->callback(up_req, ares); >+} >+ > static int rdn_name_modify(struct ldb_module *module, struct ldb_request *req) > { > struct ldb_context *ldb; > const struct ldb_val *rdn_val_p; > struct ldb_message_element *e = NULL; >+ struct ldb_control *recalculate_rdn_control = NULL; > > ldb = ldb_module_get_ctx(module); > >@@ -390,6 +399,138 @@ static int rdn_name_modify(struct ldb_module *module, struct ldb_request *req) > return ldb_next_request(module, req); > } > >+ recalculate_rdn_control = ldb_request_get_control(req, >+ LDB_CONTROL_RECALCULATE_RDN_OID); >+ if (recalculate_rdn_control != NULL) { >+ struct ldb_message *msg = NULL; >+ const char *rdn_name = NULL; >+ struct ldb_val rdn_val; >+ const struct ldb_schema_attribute *a = NULL; >+ struct ldb_request *mod_req = NULL; >+ int ret; >+ struct ldb_message_element *rdn_del = NULL; >+ struct ldb_message_element *name_del = NULL; >+ >+ recalculate_rdn_control->critical = false; >+ >+ msg = ldb_msg_copy_shallow(req, req->op.mod.message); >+ if (msg == NULL) { >+ return ldb_module_oom(module); >+ } >+ >+ /* >+ * The caller must pass a dummy 'name' attribute >+ * in order to bypass some high level checks. >+ * >+ * We just remove it and check nothing is left. >+ */ >+ ldb_msg_remove_attr(msg, "name"); >+ >+ if (msg->num_elements != 0) { >+ return ldb_module_operr(module); >+ } >+ >+ rdn_name = ldb_dn_get_rdn_name(msg->dn); >+ if (rdn_name == NULL) { >+ return ldb_module_oom(module); >+ } >+ >+ a = ldb_schema_attribute_by_name(ldb, rdn_name); >+ if (a == NULL) { >+ return ldb_module_operr(module); >+ } >+ >+ if (a->name != NULL) { >+ rdn_name = a->name; >+ } >+ >+ rdn_val_p = ldb_dn_get_rdn_val(msg->dn); >+ if (rdn_val_p == NULL) { >+ return ldb_module_oom(module); >+ } >+ rdn_val = ldb_val_dup(msg, rdn_val_p); >+ if (rdn_val.length == 0) { >+ return ldb_module_oom(module); >+ } >+ >+ /* >+ * This is a bit tricky: >+ * >+ * We want _DELETE elements (as "rdn_del" and "name_del" without >+ * values) first, followed by _ADD (with the real names) >+ * elements (with values). Then we fix up the "rdn_del" and >+ * "name_del" attributes. >+ */ >+ >+ ret = ldb_msg_add_empty(msg, "rdn_del", LDB_FLAG_MOD_DELETE, NULL); >+ if (ret != 0) { >+ return ldb_module_oom(module); >+ } >+ ret = ldb_msg_add_empty(msg, rdn_name, LDB_FLAG_MOD_ADD, NULL); >+ if (ret != 0) { >+ return ldb_module_oom(module); >+ } >+ ret = ldb_msg_add_value(msg, rdn_name, &rdn_val, NULL); >+ if (ret != 0) { >+ return ldb_module_oom(module); >+ } >+ >+ ret = ldb_msg_add_empty(msg, "name_del", LDB_FLAG_MOD_DELETE, NULL); >+ if (ret != 0) { >+ return ldb_module_oom(module); >+ } >+ ret = ldb_msg_add_empty(msg, "name", LDB_FLAG_MOD_ADD, NULL); >+ if (ret != 0) { >+ return ldb_module_oom(module); >+ } >+ ret = ldb_msg_add_value(msg, "name", &rdn_val, NULL); >+ if (ret != 0) { >+ return ldb_module_oom(module); >+ } >+ >+ rdn_del = ldb_msg_find_element(msg, "rdn_del"); >+ if (rdn_del == NULL) { >+ return ldb_module_operr(module); >+ } >+ rdn_del->name = talloc_strdup(msg->elements, rdn_name); >+ if (rdn_del->name == NULL) { >+ return ldb_module_oom(module); >+ } >+ name_del = ldb_msg_find_element(msg, "name_del"); >+ if (name_del == NULL) { >+ return ldb_module_operr(module); >+ } >+ name_del->name = talloc_strdup(msg->elements, "name"); >+ if (name_del->name == NULL) { >+ return ldb_module_oom(module); >+ } >+ >+ ret = ldb_build_mod_req(&mod_req, ldb, >+ req, msg, NULL, >+ req, rdn_recalculate_callback, >+ req); >+ if (ret != LDB_SUCCESS) { >+ return ldb_module_done(req, NULL, NULL, ret); >+ } >+ talloc_steal(mod_req, msg); >+ >+ ret = ldb_request_add_control(mod_req, >+ LDB_CONTROL_RECALCULATE_RDN_OID, >+ false, NULL); >+ if (ret != LDB_SUCCESS) { >+ return ldb_module_done(req, NULL, NULL, ret); >+ } >+ ret = ldb_request_add_control(mod_req, >+ LDB_CONTROL_PERMISSIVE_MODIFY_OID, >+ false, NULL); >+ if (ret != LDB_SUCCESS) { >+ return ldb_module_done(req, NULL, NULL, ret); >+ } >+ >+ /* go on with the call chain */ >+ return ldb_next_request(module, mod_req); >+ } >+ > rdn_val_p = ldb_dn_get_rdn_val(req->op.mod.message->dn); > if (rdn_val_p == NULL) { > return LDB_ERR_OPERATIONS_ERROR; >-- >1.9.1 > > >From 120704c8738a01200687a94020f70b0dbf3bc558 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Sun, 30 Oct 2016 23:54:44 +0100 >Subject: [PATCH 04/11] s4:dsdb/repl_meta_data: normalize rdn attribute name > via the schema > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=12399 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >--- > source4/dsdb/samdb/ldb_modules/repl_meta_data.c | 10 ++++++++-- > 1 file changed, 8 insertions(+), 2 deletions(-) > >diff --git a/source4/dsdb/samdb/ldb_modules/repl_meta_data.c b/source4/dsdb/samdb/ldb_modules/repl_meta_data.c >index 4a66697..7d12c23 100644 >--- a/source4/dsdb/samdb/ldb_modules/repl_meta_data.c >+++ b/source4/dsdb/samdb/ldb_modules/repl_meta_data.c >@@ -1446,15 +1446,21 @@ static int replmd_update_rpmd_rdn_attr(struct ldb_context *ldb, > NTTIME now, > bool is_schema_nc) > { >+ const char *rdn_name = ldb_dn_get_rdn_name(msg->dn); >+ const struct dsdb_attribute *rdn_attr = >+ dsdb_attribute_by_lDAPDisplayName(ar->schema, rdn_name); >+ const char *attr_name = rdn_attr != NULL ? >+ rdn_attr->lDAPDisplayName : >+ rdn_name; > struct ldb_message_element new_el = { > .flags = LDB_FLAG_MOD_REPLACE, >- .name = ldb_dn_get_rdn_name(msg->dn), >+ .name = attr_name, > .num_values = 1, > .values = discard_const_p(struct ldb_val, rdn_new) > }; > struct ldb_message_element old_el = { > .flags = LDB_FLAG_MOD_REPLACE, >- .name = ldb_dn_get_rdn_name(msg->dn), >+ .name = attr_name, > .num_values = rdn_old ? 1 : 0, > .values = discard_const_p(struct ldb_val, rdn_old) > }; >-- >1.9.1 > > >From c4c1d9f83ee1380aa0e2ec90df1c1a1d6f8e9082 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Thu, 10 Nov 2016 19:01:04 +0100 >Subject: [PATCH 05/11] s4:dsdb/repl_meta_data: add more > DSDB_FLAG_INTERNAL_*_META_DATA flags > >These will be required in some cases, e.g. when fixing > >'CN: somename' into 'cn: somename' without changing the >replication meta data, as the rdn attribute is only >replicated implicitly. It's required to run samba-tool dbcheck >on each dc and we should avoid forcing a bulk replication >storm triggered by each dc. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=12399 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >--- > source4/dsdb/samdb/ldb_modules/repl_meta_data.c | 11 +++++++++++ > source4/dsdb/samdb/samdb.h | 5 +++++ > 2 files changed, 16 insertions(+) > >diff --git a/source4/dsdb/samdb/ldb_modules/repl_meta_data.c b/source4/dsdb/samdb/ldb_modules/repl_meta_data.c >index 7d12c23..e1c6518 100644 >--- a/source4/dsdb/samdb/ldb_modules/repl_meta_data.c >+++ b/source4/dsdb/samdb/ldb_modules/repl_meta_data.c >@@ -1306,6 +1306,12 @@ static int replmd_update_rpmd_element(struct ldb_context *ldb, > if (LDB_FLAG_MOD_TYPE(el->flags) == LDB_FLAG_MOD_REPLACE) { > may_skip = true; > } >+ if (LDB_FLAG_MOD_TYPE(el->flags) == LDB_FLAG_MOD_ADD) { >+ if (el->flags & DSDB_FLAG_INTERNAL_MAY_SKIP_META_DATA) { >+ el->flags &= ~DSDB_FLAG_INTERNAL_MAY_SKIP_META_DATA; >+ may_skip = true; >+ } >+ } > } else if (old_el == NULL && el->num_values == 0) { > if (LDB_FLAG_MOD_TYPE(el->flags) == LDB_FLAG_MOD_REPLACE) { > may_skip = true; >@@ -1326,6 +1332,11 @@ static int replmd_update_rpmd_element(struct ldb_context *ldb, > may_skip = true; > } > >+ if (el->flags & DSDB_FLAG_INTERNAL_SKIP_META_DATA) { >+ el->flags &= ~DSDB_FLAG_INTERNAL_SKIP_META_DATA; >+ may_skip = true; >+ } >+ > if (el->flags & DSDB_FLAG_INTERNAL_FORCE_META_DATA) { > may_skip = false; > el->flags &= ~DSDB_FLAG_INTERNAL_FORCE_META_DATA; >diff --git a/source4/dsdb/samdb/samdb.h b/source4/dsdb/samdb/samdb.h >index 176d065..2f5bca0 100644 >--- a/source4/dsdb/samdb/samdb.h >+++ b/source4/dsdb/samdb/samdb.h >@@ -312,6 +312,11 @@ struct dsdb_extended_sec_desc_propagation_op { > * must be in LDB_FLAG_INTERNAL_MASK > * see also the values in lib/ldb/include/ldb_module.h > */ >+/* Force a meta data update. */ > #define DSDB_FLAG_INTERNAL_FORCE_META_DATA 0x10000 >+/* Never update meta data */ >+#define DSDB_FLAG_INTERNAL_SKIP_META_DATA 0x20000 >+/* May skip an LDB_FLAG_MOD_ADD is the values did not change */ >+#define DSDB_FLAG_INTERNAL_MAY_SKIP_META_DATA 0x20000 > > #endif /* __SAMDB_H__ */ >-- >1.9.1 > > >From 729d729597cd5e3c20b1d2b6697b5510b9aa3e72 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Thu, 10 Nov 2016 19:01:04 +0100 >Subject: [PATCH 06/11] s4:dsdb/repl_meta_data: add support for > LDB_CONTROL_RECALCULATE_RDN_OID to replmd_modify() > >These will be required in some cases, e.g. when fixing >'CN: somename' into 'cn: somename' without changing the >replication meta data, as the rdn attribute is only >replicated implicitly. It's required to run samba-tool dbcheck >on each dc and we should avoid forcing a bulk replication >storm triggered by each dc. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=12399 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >--- > source4/dsdb/samdb/ldb_modules/repl_meta_data.c | 76 +++++++++++++++++++++++++ > 1 file changed, 76 insertions(+) > >diff --git a/source4/dsdb/samdb/ldb_modules/repl_meta_data.c b/source4/dsdb/samdb/ldb_modules/repl_meta_data.c >index e1c6518..7d9a6bf 100644 >--- a/source4/dsdb/samdb/ldb_modules/repl_meta_data.c >+++ b/source4/dsdb/samdb/ldb_modules/repl_meta_data.c >@@ -2747,6 +2747,7 @@ static int replmd_modify(struct ldb_module *module, struct ldb_request *req) > unsigned int functional_level; > const struct ldb_message_element *guid_el = NULL; > struct ldb_control *sd_propagation_control; >+ struct ldb_control *recalculate_rdn_control = NULL; > struct replmd_private *replmd_private = > talloc_get_type(ldb_module_get_private(module), struct replmd_private); > >@@ -2796,6 +2797,81 @@ static int replmd_modify(struct ldb_module *module, struct ldb_request *req) > return LDB_ERR_OPERATIONS_ERROR; > } > >+ recalculate_rdn_control = ldb_request_get_control(req, >+ LDB_CONTROL_RECALCULATE_RDN_OID); >+ if (recalculate_rdn_control != NULL) { >+ struct ldb_message_element *el = NULL; >+ const char *rdn_name = NULL; >+ const struct dsdb_attribute *rdn_attr = NULL; >+ int cmp; >+ >+ if (msg->num_elements != 4) { >+ return ldb_module_operr(module); >+ } >+ >+ rdn_name = ldb_dn_get_rdn_name(msg->dn); >+ if (rdn_name == NULL) { >+ return ldb_module_oom(module); >+ } >+ rdn_attr = dsdb_attribute_by_lDAPDisplayName(ac->schema, >+ rdn_name); >+ if (rdn_attr == NULL) { >+ return ldb_module_operr(module); >+ } >+ >+ el = &msg->elements[0]; >+ if (el->flags != LDB_FLAG_MOD_DELETE) { >+ return ldb_module_operr(module); >+ } >+ el->flags |= DSDB_FLAG_INTERNAL_SKIP_META_DATA; >+ cmp = strcmp(el->name, rdn_attr->lDAPDisplayName); >+ if (cmp != 0) { >+ /* >+ * This must be an exact match! >+ */ >+ return ldb_module_operr(module); >+ } >+ >+ el = &msg->elements[1]; >+ if (el->flags != LDB_FLAG_MOD_ADD) { >+ return ldb_module_operr(module); >+ } >+ el->flags |= DSDB_FLAG_INTERNAL_MAY_SKIP_META_DATA; >+ cmp = strcmp(el->name, rdn_attr->lDAPDisplayName); >+ if (cmp != 0) { >+ /* >+ * This must be an exact match! >+ */ >+ return ldb_module_operr(module); >+ } >+ >+ el = &msg->elements[2]; >+ if (el->flags != LDB_FLAG_MOD_DELETE) { >+ return ldb_module_operr(module); >+ } >+ el->flags |= DSDB_FLAG_INTERNAL_SKIP_META_DATA; >+ cmp = strcmp(el->name, "name"); >+ if (cmp != 0) { >+ /* >+ * This must be an exact match! >+ */ >+ return ldb_module_operr(module); >+ } >+ >+ el = &msg->elements[3]; >+ if (el->flags != LDB_FLAG_MOD_ADD) { >+ return ldb_module_operr(module); >+ } >+ el->flags |= DSDB_FLAG_INTERNAL_MAY_SKIP_META_DATA; >+ cmp = strcmp(el->name, "name"); >+ if (cmp != 0) { >+ /* >+ * This must be an exact match! >+ */ >+ return ldb_module_operr(module); >+ } >+ } >+ > ldb_msg_remove_attr(msg, "whenChanged"); > ldb_msg_remove_attr(msg, "uSNChanged"); > >-- >1.9.1 > > >From e97c690ea2a1a686435f50a304caf795424642f7 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Thu, 10 Nov 2016 11:32:33 +0100 >Subject: [PATCH 07/11] dbcheck: add more checks to validate the RDN attribute > names > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=12399 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >--- > python/samba/dbchecker.py | 45 ++++++++++++++++++++++++++++++++++++++------- > 1 file changed, 38 insertions(+), 7 deletions(-) > >diff --git a/python/samba/dbchecker.py b/python/samba/dbchecker.py >index 294c320..68ca6bc 100644 >--- a/python/samba/dbchecker.py >+++ b/python/samba/dbchecker.py >@@ -98,6 +98,7 @@ class dbcheck(object): > > self.dn_set = set() > self.link_id_cache = {} >+ self.lDAPDisplayName_cache = {} > self.name_map = {} > try: > res = samdb.search(base="CN=DnsAdmins,CN=Users,%s" % samdb.domain_dn(), scope=ldb.SCOPE_BASE, >@@ -399,6 +400,15 @@ newSuperior: %s""" % (str(from_dn), str(to_rdn), str(to_base))) > self.link_id_cache[attrname] = (linkID, revname) > return linkID, revname > >+ def normalize_lDAPDisplayName(self, attrname): >+ attrname = attrname.lower() >+ if attrname in self.lDAPDisplayName_cache: >+ return self.lDAPDisplayName_cache[attrname] >+ attid = self.samdb_schema.get_attid_from_lDAPDisplayName(attrname) >+ v = self.samdb_schema.get_lDAPDisplayName_by_attid(attid) >+ self.lDAPDisplayName_cache[attrname] = v >+ return v; >+ > def err_empty_attribute(self, dn, attrname): > '''fix empty attributes''' > self.report("ERROR: Empty attribute %s in %s" % (attrname, dn)) >@@ -1496,6 +1506,9 @@ newSuperior: %s""" % (str(from_dn), str(to_rdn), str(to_base))) > if self.verbose: > self.report("Checking object %s" % dn) > >+ dn_rdn_name = dn.get_rdn_name().upper() >+ rdn_lDAPDisplayName = self.normalize_lDAPDisplayName(dn_rdn_name) >+ > # If we modify the pass-by-reference attrs variable, then we get a > # replPropertyMetadata for every object that we check. > attrs = list(attrs) >@@ -1506,7 +1519,7 @@ newSuperior: %s""" % (str(from_dn), str(to_rdn), str(to_base))) > if str(dn.get_rdn_name()).lower() in map(str.lower, attrs): > attrs.append("name") > if 'name' in map(str.lower, attrs): >- attrs.append(dn.get_rdn_name()) >+ attrs.append(rdn_lDAPDisplayName) > attrs.append("isDeleted") > attrs.append("systemFlags") > if '*' in attrs: >@@ -1578,7 +1591,7 @@ newSuperior: %s""" % (str(from_dn), str(to_rdn), str(to_base))) > else: > name_val = obj[attrname][0] > >- if str(attrname).lower() == str(obj.dn.get_rdn_name()).lower(): >+ if str(attrname).lower() == str(rdn_lDAPDisplayName).lower(): > object_rdn_attr = attrname > if len(obj[attrname]) != 1: > error_count += 1 >@@ -1777,7 +1790,15 @@ newSuperior: %s""" % (str(from_dn), str(to_rdn), str(to_base))) > self.report("ERROR: Not fixing missing 'name' on '%s'" % (str(obj.dn))) > if object_rdn_attr is None: > error_count += 1 >- self.report("ERROR: Not fixing missing '%s' on '%s'" % (obj.dn.get_rdn_name(), str(obj.dn))) >+ self.report("ERROR: Not fixing missing '%s' on '%s'" % (rdn_lDAPDisplayName, str(obj.dn))) >+ elif object_rdn_attr != rdn_lDAPDisplayName: >+ error_count += 1 >+ self.report("ERROR: Not fixing attrname '%s' into '%s' on '%s'" % ( >+ object_rdn_attr, rdn_lDAPDisplayName, str(obj.dn))) >+ >+ if obj.dn.get_rdn_name() != dn_rdn_name: >+ if name_val is None: >+ name_val = obj.dn.get_rdn_value() > > if name_val is not None: > parent_dn = None >@@ -1787,7 +1808,7 @@ newSuperior: %s""" % (str(from_dn), str(to_rdn), str(to_base))) > if parent_dn is None: > parent_dn = obj.dn.parent() > expected_dn = ldb.Dn(self.samdb, "RDN=RDN,%s" % (parent_dn)) >- expected_dn.set_component(0, obj.dn.get_rdn_name(), name_val) >+ expected_dn.set_component(0, obj.dn.get_rdn_name().upper(), name_val) > > if obj.dn == deleted_objects_dn: > expected_dn = obj.dn >@@ -1795,9 +1816,19 @@ newSuperior: %s""" % (str(from_dn), str(to_rdn), str(to_base))) > if expected_dn != obj.dn: > error_count += 1 > self.err_wrong_dn(obj, expected_dn, object_rdn_attr, object_rdn_val, name_val) >- elif obj.dn.get_rdn_value() != object_rdn_val: >- error_count += 1 >- self.report("ERROR: Not fixing %s=%r on '%s'" % (object_rdn_attr, object_rdn_val, str(obj.dn))) >+ else: >+ if obj.dn.get_rdn_value() != object_rdn_val: >+ error_count += 1 >+ self.report("ERROR: Not fixing %s=%r on '%s'" % (object_rdn_attr, object_rdn_val, str(obj.dn))) >+ >+ if obj.dn.get_rdn_name() != dn_rdn_name: >+ error_count += 1 >+ self.report("ERROR: Not fixing RDN '%s' into '%s' on '%s'" % ( >+ obj.dn.get_rdn_name(), dn_rdn_name, str(obj.dn))) >+ elif str(obj.dn) != str(expected_dn): >+ error_count += 1 >+ self.report("ERROR: Not fixing DN '%s' into '%s'" % ( >+ str(obj.dn), str(expected_dn))) > > show_dn = True > if got_repl_property_meta_data: >-- >1.9.1 > > >From e905254de5597695ecc0e69e28f519defb2fca58 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Thu, 10 Nov 2016 12:21:38 +0100 >Subject: [PATCH 08/11] dbcheck: move search controls into a local variable > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >--- > python/samba/dbchecker.py | 27 ++++++++++++++------------- > 1 file changed, 14 insertions(+), 13 deletions(-) > >diff --git a/python/samba/dbchecker.py b/python/samba/dbchecker.py >index 68ca6bc..36a7da5 100644 >--- a/python/samba/dbchecker.py >+++ b/python/samba/dbchecker.py >@@ -1527,21 +1527,22 @@ newSuperior: %s""" % (str(from_dn), str(to_rdn), str(to_base))) > else: > attrs.append("objectGUID") > >- try: >- sd_flags = 0 >- sd_flags |= security.SECINFO_OWNER >- sd_flags |= security.SECINFO_GROUP >- sd_flags |= security.SECINFO_DACL >- sd_flags |= security.SECINFO_SACL >+ sd_flags = 0 >+ sd_flags |= security.SECINFO_OWNER >+ sd_flags |= security.SECINFO_GROUP >+ sd_flags |= security.SECINFO_DACL >+ sd_flags |= security.SECINFO_SACL >+ search_controls = [ >+ "extended_dn:1:1", >+ "show_recycled:1", >+ "show_deleted:1", >+ "sd_flags:1:%d" % sd_flags, >+ "reveal_internals:0", >+ ] > >+ try: > res = self.samdb.search(base=dn, scope=ldb.SCOPE_BASE, >- controls=[ >- "extended_dn:1:1", >- "show_recycled:1", >- "show_deleted:1", >- "sd_flags:1:%d" % sd_flags, >- "reveal_internals:0", >- ], >+ controls=search_controls, > attrs=attrs) > except ldb.LdbError, (enum, estr): > if enum == ldb.ERR_NO_SUCH_OBJECT: >-- >1.9.1 > > >From c13cde3f8b9f440325855d724e9ccd6bc6f0a703 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Thu, 10 Nov 2016 19:04:21 +0100 >Subject: [PATCH 09/11] TODO dbcheck: fixup 'CN: somename' into 'cn: somename' > >TODO: we should do this fix up after a possible rename > via self.err_wrong_dn(), that rename is more important > and may already fix the problem... > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=12399 >--- > python/samba/dbchecker.py | 36 +++++++++++++++++++++++++++++++++++- > 1 file changed, 35 insertions(+), 1 deletion(-) > >diff --git a/python/samba/dbchecker.py b/python/samba/dbchecker.py >index 36a7da5..8b3c875 100644 >--- a/python/samba/dbchecker.py >+++ b/python/samba/dbchecker.py >@@ -95,6 +95,7 @@ class dbcheck(object): > self.fix_missing_deleted_objects = False > self.fix_replica_locations = False > self.fix_missing_rid_set_master = False >+ self.fix_rdn_name = False > > self.dn_set = set() > self.link_id_cache = {} >@@ -409,6 +410,26 @@ newSuperior: %s""" % (str(from_dn), str(to_rdn), str(to_base))) > self.lDAPDisplayName_cache[attrname] = v > return v; > >+ def err_wrong_rdn_attribute_name(self, obj, wrong_rdn_name, correct_rdn_name, rdn_val): >+ '''handle a wrong rdn attribute name''' >+ msg = "RDN attribute '%s' should be '%s' on '%s'" % (wrong_rdn_name, correct_rdn_name, obj.dn) >+ >+ self.report("ERROR: wrong %s" % msg) >+ if not self.confirm_all('Change %s?' % msg, 'fix_rdn_name'): >+ self.report('Not changing %s' % msg) >+ return >+ >+ new_rdn = ldb.Dn(self.samdb, str(obj.dn)) >+ new_rdn.remove_base_components(len(obj.dn) - 1) >+ new_parent = obj.dn.parent() >+ >+ >+ m = ldb.Message() >+ m.dn = obj.dn >+ m['value'] = ldb.MessageElement('__ignore_recalculate_rdn__', ldb.FLAG_MOD_REPLACE, 'name') >+ if self.do_modify(m, ["recalculate_rdn:1"], 'Failed to correct %s' % msg): >+ self.report('Corrected %s' % msg) >+ > def err_empty_attribute(self, dn, attrname): > '''fix empty attributes''' > self.report("ERROR: Empty attribute %s in %s" % (attrname, dn)) >@@ -1794,9 +1815,22 @@ newSuperior: %s""" % (str(from_dn), str(to_rdn), str(to_base))) > self.report("ERROR: Not fixing missing '%s' on '%s'" % (rdn_lDAPDisplayName, str(obj.dn))) > elif object_rdn_attr != rdn_lDAPDisplayName: > error_count += 1 >- self.report("ERROR: Not fixing attrname '%s' into '%s' on '%s'" % ( >+ if name_val is not None: >+ self.err_wrong_rdn_attribute_name(obj, object_rdn_attr, >+ rdn_lDAPDisplayName, >+ name_val) >+ else: >+ self.report("ERROR: Not fixing attrname '%s' into '%s' on '%s'" % ( > object_rdn_attr, rdn_lDAPDisplayName, str(obj.dn))) > >+ res = self.samdb.search(base=obj.dn, scope=ldb.SCOPE_BASE, >+ controls=search_controls, >+ attrs=attrs) >+ obj = res[0] >+ object_rdn_attr = rdn_lDAPDisplayName >+ object_rdn_val = obj[object_rdn_attr][0] >+ name_val = obj["name"][0] >+ > if obj.dn.get_rdn_name() != dn_rdn_name: > if name_val is None: > name_val = obj.dn.get_rdn_value() >-- >1.9.1 > > >From f930cfb50265dca111afbf81a21cb560e507bbb9 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Fri, 11 Nov 2016 15:39:25 +0100 >Subject: [PATCH 10/11] python/samba/dbchecker.py TODO... > >--- > python/samba/dbchecker.py | 16 ++++++++++++---- > 1 file changed, 12 insertions(+), 4 deletions(-) > >diff --git a/python/samba/dbchecker.py b/python/samba/dbchecker.py >index 8b3c875..68c7cee 100644 >--- a/python/samba/dbchecker.py >+++ b/python/samba/dbchecker.py >@@ -1608,7 +1608,7 @@ newSuperior: %s""" % (str(from_dn), str(to_rdn), str(to_base))) > if str(attrname).lower() == "name": > if len(obj[attrname]) != 1: > error_count += 1 >- self.report("ERROR: Not fixing num_values(%d) for '%s' on '%s'" % >+ self.report("ERROR: num_values(%d) for '%s' on '%s'" % > (len(obj[attrname]), attrname, str(obj.dn))) > else: > name_val = obj[attrname][0] >@@ -1617,7 +1617,7 @@ newSuperior: %s""" % (str(from_dn), str(to_rdn), str(to_base))) > object_rdn_attr = attrname > if len(obj[attrname]) != 1: > error_count += 1 >- self.report("ERROR: Not fixing num_values(%d) for '%s' on '%s'" % >+ self.report("ERROR: num_values(%d) for '%s' on '%s'" % > (len(obj[attrname]), attrname, str(obj.dn))) > else: > object_rdn_val = obj[attrname][0] >@@ -1809,10 +1809,18 @@ newSuperior: %s""" % (str(from_dn), str(to_rdn), str(to_base))) > if ("*" in attrs or "name" in map(str.lower, attrs)): > if name_val is None: > error_count += 1 >- self.report("ERROR: Not fixing missing 'name' on '%s'" % (str(obj.dn))) >+ self.report("ERROR: missing 'name' on '%s'" % (str(obj.dn))) >+ name_val = obj.dn.get_rdn_value() > if object_rdn_attr is None: > error_count += 1 >- self.report("ERROR: Not fixing missing '%s' on '%s'" % (rdn_lDAPDisplayName, str(obj.dn))) >+ self.report("ERROR: missing '%s' on '%s'" % (rdn_lDAPDisplayName, str(obj.dn))) >+ if object_rdn_val is None: >+ object_rdn_val = name_val >+ if object_rdn_val != name_val: >+ error_count += 1 >+ self.report("ERROR: value difference %s=[%s] %s[%s] on '%s'" % ( >+ rdn_lDAPDisplayName, str(obj.dn))) >+ > elif object_rdn_attr != rdn_lDAPDisplayName: > error_count += 1 > if name_val is not None: >-- >1.9.1 > > >From a8ac7ade8e6285f97d9059835f3c9b53e7a66c5e Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Fri, 11 Nov 2016 15:39:34 +0100 >Subject: [PATCH 11/11] Revert "python/samba/dbchecker.py TODO..." > >This reverts commit 811d00ab9b7096b68c1c3c9f5740ef6438d5261c. >--- > python/samba/dbchecker.py | 16 ++++------------ > 1 file changed, 4 insertions(+), 12 deletions(-) > >diff --git a/python/samba/dbchecker.py b/python/samba/dbchecker.py >index 68c7cee..8b3c875 100644 >--- a/python/samba/dbchecker.py >+++ b/python/samba/dbchecker.py >@@ -1608,7 +1608,7 @@ newSuperior: %s""" % (str(from_dn), str(to_rdn), str(to_base))) > if str(attrname).lower() == "name": > if len(obj[attrname]) != 1: > error_count += 1 >- self.report("ERROR: num_values(%d) for '%s' on '%s'" % >+ self.report("ERROR: Not fixing num_values(%d) for '%s' on '%s'" % > (len(obj[attrname]), attrname, str(obj.dn))) > else: > name_val = obj[attrname][0] >@@ -1617,7 +1617,7 @@ newSuperior: %s""" % (str(from_dn), str(to_rdn), str(to_base))) > object_rdn_attr = attrname > if len(obj[attrname]) != 1: > error_count += 1 >- self.report("ERROR: num_values(%d) for '%s' on '%s'" % >+ self.report("ERROR: Not fixing num_values(%d) for '%s' on '%s'" % > (len(obj[attrname]), attrname, str(obj.dn))) > else: > object_rdn_val = obj[attrname][0] >@@ -1809,18 +1809,10 @@ newSuperior: %s""" % (str(from_dn), str(to_rdn), str(to_base))) > if ("*" in attrs or "name" in map(str.lower, attrs)): > if name_val is None: > error_count += 1 >- self.report("ERROR: missing 'name' on '%s'" % (str(obj.dn))) >- name_val = obj.dn.get_rdn_value() >+ self.report("ERROR: Not fixing missing 'name' on '%s'" % (str(obj.dn))) > if object_rdn_attr is None: > error_count += 1 >- self.report("ERROR: missing '%s' on '%s'" % (rdn_lDAPDisplayName, str(obj.dn))) >- if object_rdn_val is None: >- object_rdn_val = name_val >- if object_rdn_val != name_val: >- error_count += 1 >- self.report("ERROR: value difference %s=[%s] %s[%s] on '%s'" % ( >- rdn_lDAPDisplayName, str(obj.dn))) >- >+ self.report("ERROR: Not fixing missing '%s' on '%s'" % (rdn_lDAPDisplayName, str(obj.dn))) > elif object_rdn_attr != rdn_lDAPDisplayName: > error_count += 1 > if name_val is not None: >-- >1.9.1 >
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Raw
Actions:
View
Attachments on
bug 12399
:
12611
| 12655 |
12853