The branch, master has been updated via e8a323c smbd: Fix compile warning in dmapi.c via 393348d dbcheck: Directly call dn.get_rdn_{val,name}() for clarity and consistency via 5b22222 s4:repl_meta_data: fix array assignment in replmd_process_linked_attribute() via 709ed04 dbchecker: verify and fix broken dn values via 821d7dc dbchecker: make the deleted objects container detection more generic via 7f03a94 ldb: change version to 1.1.17 via 771d7b8 ldb:pyldb: add some more helper functions for LdbDn via 094c391 ldb:pyldb: fix doc string for set_extended_component() via aae9da9 ldb:pyldb: add some const to PyObject_FromLdbValue() from 8dede57 ctdb: Fix a comment typo
http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master - Log ----------------------------------------------------------------- commit e8a323c73138bc132e95facfae011847e7c14aa0 Author: Christof Schmitt <c...@samba.org> Date: Thu May 1 13:50:19 2014 -0700 smbd: Fix compile warning in dmapi.c Signed-off-by: Christof Schmitt <c...@samba.org> Reviewed-by: Andrew Bartlett <abart...@samba.org> Change-Id: I69297d91ab8c857204e1f78cafb210b9a05f3b77 Autobuild-User(master): Andrew Bartlett <abart...@samba.org> Autobuild-Date(master): Fri May 2 03:41:31 CEST 2014 on sn-devel-104 commit 393348d11ed781d9f42049d5f996b0bab8b15d58 Author: Andrew Bartlett <abart...@samba.org> Date: Wed Apr 30 09:38:34 2014 +1200 dbcheck: Directly call dn.get_rdn_{val,name}() for clarity and consistency When looking for incorrect name values, this improves the previous code by avoiding one more manual parse step, and uses less cryptic variable names. Andrew Bartlett Change-Id: Iff8e571a6359a67bf173f729dc12b8787292b3cb Signed-off-by: Andrew Bartlett <abart...@samba.org> Reviewed-by: Jelmer Vernooij <jel...@samba.org> commit 5b22222421c77c8c379c828c5da7e6c8c38cfb88 Author: Stefan Metzmacher <me...@samba.org> Date: Thu Apr 3 16:03:19 2014 +0200 s4:repl_meta_data: fix array assignment in replmd_process_linked_attribute() Change-Id: I10357236108f68ab749ba0e1f07558302c573887 Signed-off-by: Stefan Metzmacher <me...@samba.org> Reviewed-by: Andrew Bartlett <abart...@samba.org> commit 709ed040ec161e99b3c1f7076eac4a631149f64a Author: Stefan Metzmacher <me...@samba.org> Date: Thu Mar 13 23:12:39 2014 +0100 dbchecker: verify and fix broken dn values With older Samba versions (4.0.x) the following could happen: - On account was created on DC1 - It was replicated to DC2 - The connection between the dcs is offline - The account gets modified on DC2 - The account gets deleted on DC1 - The connection becomes online again - DC1 replicates the modification from DC2, this resets the dn to the original value. 'name' and 'cn' are correct (with '\nDEL${GUID}'), but 'dn' is wrong. - DC2 replicates the deletion from DC1. this doesn't include a changed dn as DC1 had a bug. 'name' is correct (with '\nDEL${GUID}'), but 'cn' and 'dn' are wrong. Bug: https://bugzilla.samba.org/show_bug.cgi?id=10536 Change-Id: Ia70a6c12e0ff0d4c2c8100cb1d8f3c6422b65591 Signed-off-by: Stefan Metzmacher <me...@samba.org> Reviewed-by: Andrew Bartlett <abart...@samba.org> commit 821d7dc7b33598f72c4518f8975073b058df5960 Author: Stefan Metzmacher <me...@samba.org> Date: Thu Mar 13 23:12:39 2014 +0100 dbchecker: make the deleted objects container detection more generic Change-Id: I282ad887c41412e25fdf73476e405f4e88e0b239 Signed-off-by: Stefan Metzmacher <me...@samba.org> Reviewed-by: Andrew Bartlett <abart...@samba.org> commit 7f03a94ffa3752ccdb28cc50033b4e2a26e2b3f2 Author: Stefan Metzmacher <me...@samba.org> Date: Tue Apr 29 09:37:54 2014 +0200 ldb: change version to 1.1.17 This adds some pyldb methods for ldb.Dn. Signed-off-by: Stefan Metzmacher <me...@samba.org> Reviewed-by: Jelmer Vernooij <jel...@samba.org> Reviewed-by: Andrew Bartlett <abart...@samba.org> commit 771d7b8c0df9240a9638dbf06a9f04431767bbb8 Author: Stefan Metzmacher <me...@samba.org> Date: Tue Apr 29 09:35:31 2014 +0200 ldb:pyldb: add some more helper functions for LdbDn This adds [g|s]et_component[|_name|_value]() and get_rdn_[name|value](). Signed-off-by: Stefan Metzmacher <me...@samba.org> Reviewed-by: Jelmer Vernooij <jel...@samba.org> Reviewed-by: Andrew Bartlett <abart...@samba.org> commit 094c39107c0abf4951e6f7012ac06b08cae1ea04 Author: Stefan Metzmacher <me...@samba.org> Date: Tue Apr 29 09:34:48 2014 +0200 ldb:pyldb: fix doc string for set_extended_component() Signed-off-by: Stefan Metzmacher <me...@samba.org> Reviewed-by: Jelmer Vernooij <jel...@samba.org> Reviewed-by: Andrew Bartlett <abart...@samba.org> commit aae9da9803dd551364bc3c096e06601bb1c9ed50 Author: Stefan Metzmacher <me...@samba.org> Date: Tue Apr 29 09:32:45 2014 +0200 ldb:pyldb: add some const to PyObject_FromLdbValue() PyString_FromStringAndSize() makes a copy of the value... Signed-off-by: Stefan Metzmacher <me...@samba.org> Reviewed-by: Jelmer Vernooij <jel...@samba.org> Reviewed-by: Andrew Bartlett <abart...@samba.org> ----------------------------------------------------------------------- Summary of changes: lib/ldb/ABI/{ldb-1.1.14.sigs => ldb-1.1.17.sigs} | 0 ...ldb-util-1.1.10.sigs => pyldb-util-1.1.17.sigs} | 0 lib/ldb/pyldb.c | 116 +++++++++++++++++++- lib/ldb/wscript | 2 +- python/samba/dbchecker.py | 99 ++++++++++++++++- source3/smbd/dmapi.c | 2 +- source4/dsdb/samdb/ldb_modules/repl_meta_data.c | 4 +- 7 files changed, 215 insertions(+), 8 deletions(-) copy lib/ldb/ABI/{ldb-1.1.14.sigs => ldb-1.1.17.sigs} (100%) copy lib/ldb/ABI/{pyldb-util-1.1.10.sigs => pyldb-util-1.1.17.sigs} (100%) Changeset truncated at 500 lines: diff --git a/lib/ldb/ABI/ldb-1.1.14.sigs b/lib/ldb/ABI/ldb-1.1.17.sigs similarity index 100% copy from lib/ldb/ABI/ldb-1.1.14.sigs copy to lib/ldb/ABI/ldb-1.1.17.sigs diff --git a/lib/ldb/ABI/pyldb-util-1.1.10.sigs b/lib/ldb/ABI/pyldb-util-1.1.17.sigs similarity index 100% copy from lib/ldb/ABI/pyldb-util-1.1.10.sigs copy to lib/ldb/ABI/pyldb-util-1.1.17.sigs diff --git a/lib/ldb/pyldb.c b/lib/ldb/pyldb.c index 4360b31..78b8012 100644 --- a/lib/ldb/pyldb.c +++ b/lib/ldb/pyldb.c @@ -189,7 +189,7 @@ static void PyErr_SetLdbError(PyObject *error, int ret, struct ldb_context *ldb_ ldb_ctx == NULL?ldb_strerror(ret):ldb_errstring(ldb_ctx))); } -static PyObject *PyObject_FromLdbValue(struct ldb_val *val) +static PyObject *PyObject_FromLdbValue(const struct ldb_val *val) { return PyString_FromStringAndSize((const char *)val->data, val->length); } @@ -552,6 +552,103 @@ static PyObject *py_ldb_dn_is_child_of(PyLdbDnObject *self, PyObject *args) return PyBool_FromLong(ldb_dn_compare_base(base, dn) == 0); } +static PyObject *py_ldb_dn_get_component_name(PyLdbDnObject *self, PyObject *args) +{ + struct ldb_dn *dn; + const char *name; + unsigned int num = 0; + + if (!PyArg_ParseTuple(args, "I", &num)) + return NULL; + + dn = pyldb_Dn_AsDn((PyObject *)self); + + name = ldb_dn_get_component_name(dn, num); + if (name == NULL) { + Py_RETURN_NONE; + } + + return PyString_FromString(name); +} + +static PyObject *py_ldb_dn_get_component_value(PyLdbDnObject *self, PyObject *args) +{ + struct ldb_dn *dn; + const struct ldb_val *val; + unsigned int num = 0; + + if (!PyArg_ParseTuple(args, "I", &num)) + return NULL; + + dn = pyldb_Dn_AsDn((PyObject *)self); + + val = ldb_dn_get_component_val(dn, num); + if (val == NULL) { + Py_RETURN_NONE; + } + + return PyObject_FromLdbValue(val); +} + +static PyObject *py_ldb_dn_set_component(PyLdbDnObject *self, PyObject *args) +{ + unsigned int num = 0; + char *name = NULL; + PyObject *value = Py_None; + struct ldb_val val = { NULL, }; + int err; + + if (!PyArg_ParseTuple(args, "IsO", &num, &name, &value)) + return NULL; + + if (value != Py_None) { + if (!PyString_Check(value)) { + PyErr_SetString(PyExc_TypeError, "Expected a string argument"); + return NULL; + } + val.data = (uint8_t *)PyString_AsString(value); + val.length = PyString_Size(value); + } + + err = ldb_dn_set_component(self->dn, num, name, val); + if (err != LDB_SUCCESS) { + PyErr_SetString(PyExc_TypeError, "Failed to set component"); + return NULL; + } + + Py_RETURN_NONE; +} + +static PyObject *py_ldb_dn_get_rdn_name(PyLdbDnObject *self) +{ + struct ldb_dn *dn; + const char *name; + + dn = pyldb_Dn_AsDn((PyObject *)self); + + name = ldb_dn_get_rdn_name(dn); + if (name == NULL) { + Py_RETURN_NONE; + } + + return PyString_FromString(name); +} + +static PyObject *py_ldb_dn_get_rdn_value(PyLdbDnObject *self) +{ + struct ldb_dn *dn; + const struct ldb_val *val; + + dn = pyldb_Dn_AsDn((PyObject *)self); + + val = ldb_dn_get_rdn_val(dn); + if (val == NULL) { + Py_RETURN_NONE; + } + + return PyObject_FromLdbValue(val); +} + static PyMethodDef py_ldb_dn_methods[] = { { "validate", (PyCFunction)py_ldb_dn_validate, METH_NOARGS, "S.validate() -> bool\n" @@ -597,8 +694,23 @@ static PyMethodDef py_ldb_dn_methods[] = { "S.get_extended_component(name) -> string\n\n" "returns a DN extended component as a binary string"}, { "set_extended_component", (PyCFunction)py_ldb_dn_set_extended_component, METH_VARARGS, - "S.set_extended_component(name, value) -> string\n\n" + "S.set_extended_component(name, value) -> None\n\n" "set a DN extended component as a binary string"}, + { "get_component_name", (PyCFunction)py_ldb_dn_get_component_name, METH_VARARGS, + "S.get_component_name(num) -> string\n" + "get the attribute name of the specified component" }, + { "get_component_value", (PyCFunction)py_ldb_dn_get_component_value, METH_VARARGS, + "S.get_component_value(num) -> string\n" + "get the attribute value of the specified component as a binary string" }, + { "set_component", (PyCFunction)py_ldb_dn_set_component, METH_VARARGS, + "S.get_component_value(num, name, value) -> None\n" + "set the attribute name and value of the specified component" }, + { "get_rdn_name", (PyCFunction)py_ldb_dn_get_rdn_name, METH_NOARGS, + "S.get_rdn_name() -> string\n" + "get the RDN attribute name" }, + { "get_rdn_value", (PyCFunction)py_ldb_dn_get_rdn_value, METH_NOARGS, + "S.get_rdn_value() -> string\n" + "get the RDN attribute value as a binary string" }, { NULL } }; diff --git a/lib/ldb/wscript b/lib/ldb/wscript index 07c5d9a..5621b38 100755 --- a/lib/ldb/wscript +++ b/lib/ldb/wscript @@ -1,7 +1,7 @@ #!/usr/bin/env python APPNAME = 'ldb' -VERSION = '1.1.16' +VERSION = '1.1.17' blddir = 'bin' diff --git a/python/samba/dbchecker.py b/python/samba/dbchecker.py index f276cc5..c658610 100644 --- a/python/samba/dbchecker.py +++ b/python/samba/dbchecker.py @@ -63,6 +63,7 @@ class dbcheck(object): self.fix_instancetype = False self.fix_replmetadata_zero_invocationid = False self.fix_deleted_deleted_objects = False + self.fix_dn = False self.reset_well_known_acls = reset_well_known_acls self.reset_all_well_known_acls = False self.in_transaction = in_transaction @@ -486,6 +487,26 @@ newSuperior: %s""" % (str(from_dn), str(to_rdn), str(to_base))) else: self.samdb.transaction_cancel() + def err_wrong_dn(self, obj, new_dn, rdn_attr, rdn_val, name_val): + '''handle a wrong dn''' + + new_rdn = ldb.Dn(self.samdb, str(new_dn)) + new_rdn.remove_base_components(len(new_rdn) - 1) + new_parent = new_dn.parent() + + attributes = "" + if rdn_val != name_val: + attributes += "%s=%r " % (rdn_attr, rdn_val) + attributes += "name=%r" % (name_val) + + self.report("ERROR: wrong dn[%s] %s new_dn[%s]" % (obj.dn, attributes, new_dn)) + if not self.confirm_all("Rename %s to %s?" % (obj.dn, new_dn), 'fix_dn'): + self.report("Not renaming %s to %s" % (obj.dn, new_dn)) + return + + if self.do_rename(obj.dn, new_rdn, new_parent, ["show_recycled:1", "relax:0"], + "Failed to rename object %s into %s" % (obj.dn, new_dn)): + self.report("Renamed %s into %s" % (obj.dn, new_dn)) def err_wrong_instancetype(self, obj, calculated_instancetype): '''handle a wrong instanceType''' @@ -1008,6 +1029,16 @@ newSuperior: %s""" % (str(from_dn), str(to_rdn), str(to_base))) '''check one object''' if self.verbose: self.report("Checking object %s" % dn) + if "dn" in map(str.lower, attrs): + attrs.append("name") + if "distinguishedname" in map(str.lower, attrs): + attrs.append("name") + 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("isDeleted") + attrs.append("systemFlags") if '*' in attrs: attrs.append("replPropertyMetaData") @@ -1043,6 +1074,19 @@ newSuperior: %s""" % (str(from_dn), str(to_rdn), str(to_base))) got_repl_property_meta_data = False got_objectclass = False + nc_dn = self.samdb.get_nc_root(obj.dn) + try: + deleted_objects_dn = self.samdb.get_wellknown_dn(nc_dn, + samba.dsdb.DS_GUID_DELETED_OBJECTS_CONTAINER) + except KeyError, e: + deleted_objects_dn = ldb.Dn(self.samdb, "CN=Deleted Objects,%s" % nc_dn) + + object_rdn_attr = None + object_rdn_val = None + name_val = None + isDeleted = False + systemFlags = 0 + for attrname in obj: if attrname == 'dn': continue @@ -1050,6 +1094,30 @@ newSuperior: %s""" % (str(from_dn), str(to_rdn), str(to_base))) if str(attrname).lower() == 'objectclass': got_objectclass = True + 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'" % + (len(obj[attrname]), attrname, str(obj.dn))) + else: + name_val = obj[attrname][0] + + if str(attrname).lower() == str(obj.dn.get_rdn_name()).lower(): + object_rdn_attr = attrname + if len(obj[attrname]) != 1: + error_count += 1 + 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] + + if str(attrname).lower() == 'isdeleted': + if obj[attrname][0] != "FALSE": + isDeleted = True + + if str(attrname).lower() == 'systemflags': + systemFlags = int(obj[attrname][0]) + if str(attrname).lower() == 'replpropertymetadata': if self.has_replmetadata_zero_invocationid(dn, obj[attrname]): error_count += 1 @@ -1141,10 +1209,37 @@ newSuperior: %s""" % (str(from_dn), str(to_rdn), str(to_base))) error_count += 1 self.err_missing_objectclass(dn) + 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))) + 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))) + + if name_val is not None: + parent_dn = None + if isDeleted: + if not (systemFlags & samba.dsdb.SYSTEM_FLAG_DISALLOW_MOVE_ON_DELETE): + parent_dn = deleted_objects_dn + 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) + + if obj.dn == deleted_objects_dn: + expected_dn = obj.dn + + 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))) + show_dn = True if got_repl_property_meta_data: - rdn = (str(dn).split(","))[0] - if rdn == "CN=Deleted Objects": + if obj.dn == deleted_objects_dn: isDeletedAttId = 131120 # It's 29/12/9999 at 23:59:59 UTC as specified in MS-ADTS 7.1.1.4.2 Deleted Objects Container diff --git a/source3/smbd/dmapi.c b/source3/smbd/dmapi.c index 8e80a58..8c93873 100644 --- a/source3/smbd/dmapi.c +++ b/source3/smbd/dmapi.c @@ -277,7 +277,7 @@ uint32 dmapi_file_flags(const char * const path) return 0; } - dmapi_session = *(dm_sessid_t *)dmapi_session_ptr; + dmapi_session = *(const dm_sessid_t *)dmapi_session_ptr; if (dmapi_session == DM_NO_SESSION) { return 0; } diff --git a/source4/dsdb/samdb/ldb_modules/repl_meta_data.c b/source4/dsdb/samdb/ldb_modules/repl_meta_data.c index 4e5d8f0..b01c956 100644 --- a/source4/dsdb/samdb/ldb_modules/repl_meta_data.c +++ b/source4/dsdb/samdb/ldb_modules/repl_meta_data.c @@ -5397,8 +5397,8 @@ linked_attributes[0]: attrs[0] = attr->lDAPDisplayName; attrs[1] = "isDeleted"; - attrs[1] = "isRecycled"; - attrs[2] = NULL; + attrs[2] = "isRecycled"; + attrs[3] = NULL; /* get the existing message from the db for the object with this GUID, returning attribute being modified. We will then -- Samba Shared Repository