[SCM] Samba Shared Repository - branch master updated
Andrew Tridgell
tridge at samba.org
Wed Apr 18 01:20:02 MDT 2012
The branch, master has been updated
via c69c07e dbcheck: added fix for incorrect RMD_FLAGS
via 997a22e dsdb: added SHOW_DELETED to samldb_member_check()
via 2eb899d replace: added ENOATTR define if undefined
via 8c9c6f8 s4:dbchecker.py - integrate the "objectClass" fixing code
via a2a9c33 s4:dsdb/pydsdb.c - call the "objectClass" normalisation code from Python
via 27bcf7a LDB:ldb_tdb/ldb_tdb.c - allow LDB modify replaces with different value ordering
via 9deb650 ldb: added ldb_msg_element_equal_ordered()
from 010f2b8 Add docs for aio_linux vfs module.
http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master
- Log -----------------------------------------------------------------
commit c69c07efeccffec9848e6040b7934ee866b91e7e
Author: Andrew Tridgell <tridge at samba.org>
Date: Wed Apr 18 15:46:14 2012 +1000
dbcheck: added fix for incorrect RMD_FLAGS
this fixes the case where a DN link has RMD_FLAGS=0 for a link inside
a deleted object
Pair-Programmed-With: Andrew Bartlett <abartlet at samba.org>
Autobuild-User: Andrew Tridgell <tridge at samba.org>
Autobuild-Date: Wed Apr 18 09:19:41 CEST 2012 on sn-devel-104
commit 997a22e7bf0711ce209885c408c6dd26391d7e16
Author: Andrew Tridgell <tridge at samba.org>
Date: Wed Apr 18 15:45:31 2012 +1000
dsdb: added SHOW_DELETED to samldb_member_check()
when dbcheck is fixing DNs, it will sometimes operated on a deleted DN
link
Pair-Programmed-With: Andrew Bartlett <abartlet at samba.org>
commit 2eb899de6a2bdf1aac1c1f010a6d2b5b02f9de39
Author: Andrew Tridgell <tridge at samba.org>
Date: Wed Apr 18 14:35:17 2012 +1000
replace: added ENOATTR define if undefined
this fixes the build of the tdb xattr wrapper code on systems without
xattr headers
Pair-Programmed-With: Andrew Bartlett <abartlet at samba.org>
commit 8c9c6f869d7f6e991806be344f582191d701b77c
Author: Matthias Dieter Wallnöfer <mdw at samba.org>
Date: Wed Apr 11 17:18:37 2012 +0200
s4:dbchecker.py - integrate the "objectClass" fixing code
Signed-off-by: Andrew Tridgell <tridge at samba.org>
commit a2a9c334c10b259d070a984a61656ae76a95a643
Author: Matthias Dieter Wallnöfer <mdw at samba.org>
Date: Wed Apr 11 16:06:03 2012 +0200
s4:dsdb/pydsdb.c - call the "objectClass" normalisation code from Python
This allows the dbchecker to fix ordering/inconsistency problems with
the mentioned attribute.
Signed-off-by: Andrew Tridgell <tridge at samba.org>
commit 27bcf7a0b6ab3a4c74129e3952c1bf14b8017b86
Author: Matthias Dieter Wallnöfer <mdw at samba.org>
Date: Wed Apr 11 21:09:38 2012 +0200
LDB:ldb_tdb/ldb_tdb.c - allow LDB modify replaces with different value ordering
This is essential for fixing up wrong ordered "objectClass" attributes.
Signed-off-by: Andrew Tridgell <tridge at samba.org>
commit 9deb650fa2b93338ca91ccc96a940d670d29cbee
Author: Andrew Tridgell <tridge at samba.org>
Date: Tue Apr 17 14:01:08 2012 +1000
ldb: added ldb_msg_element_equal_ordered()
this gives us a order sensitive msg element comparison. We need this
to allow dbcheck to fix the order of objectClass attributes.
-----------------------------------------------------------------------
Summary of changes:
lib/ldb/ABI/{ldb-1.1.5.sigs => ldb-1.1.6.sigs} | 1 +
...pyldb-util-1.1.2.sigs => pyldb-util-1.1.6.sigs} | 0
lib/ldb/common/ldb_msg.c | 20 ++++++
lib/ldb/include/ldb_module.h | 5 ++
lib/ldb/ldb_tdb/ldb_tdb.c | 13 +++-
lib/ldb/wscript | 2 +-
lib/replace/system/filesys.h | 8 +++
source4/dsdb/pydsdb.c | 14 +++++
source4/dsdb/samdb/ldb_modules/samldb.c | 2 +-
source4/scripting/python/samba/dbchecker.py | 62 ++++++++++++++++++++
10 files changed, 122 insertions(+), 5 deletions(-)
copy lib/ldb/ABI/{ldb-1.1.5.sigs => ldb-1.1.6.sigs} (99%)
copy lib/ldb/ABI/{pyldb-util-1.1.2.sigs => pyldb-util-1.1.6.sigs} (100%)
Changeset truncated at 500 lines:
diff --git a/lib/ldb/ABI/ldb-1.1.5.sigs b/lib/ldb/ABI/ldb-1.1.6.sigs
similarity index 99%
copy from lib/ldb/ABI/ldb-1.1.5.sigs
copy to lib/ldb/ABI/ldb-1.1.6.sigs
index cc0f859..f90fa13 100644
--- a/lib/ldb/ABI/ldb-1.1.5.sigs
+++ b/lib/ldb/ABI/ldb-1.1.6.sigs
@@ -157,6 +157,7 @@ ldb_msg_diff: struct ldb_message *(struct ldb_context *, struct ldb_message *, s
ldb_msg_difference: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message *, struct ldb_message *, struct ldb_message **)
ldb_msg_element_compare: int (struct ldb_message_element *, struct ldb_message_element *)
ldb_msg_element_compare_name: int (struct ldb_message_element *, struct ldb_message_element *)
+ldb_msg_element_equal_ordered: bool (const struct ldb_message_element *, const struct ldb_message_element *)
ldb_msg_find_attr_as_bool: int (const struct ldb_message *, const char *, int)
ldb_msg_find_attr_as_dn: struct ldb_dn *(struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, const char *)
ldb_msg_find_attr_as_double: double (const struct ldb_message *, const char *, double)
diff --git a/lib/ldb/ABI/pyldb-util-1.1.2.sigs b/lib/ldb/ABI/pyldb-util-1.1.6.sigs
similarity index 100%
copy from lib/ldb/ABI/pyldb-util-1.1.2.sigs
copy to lib/ldb/ABI/pyldb-util-1.1.6.sigs
diff --git a/lib/ldb/common/ldb_msg.c b/lib/ldb/common/ldb_msg.c
index c17e5f3..35c568a 100644
--- a/lib/ldb/common/ldb_msg.c
+++ b/lib/ldb/common/ldb_msg.c
@@ -360,6 +360,26 @@ int ldb_msg_element_compare(struct ldb_message_element *el1,
}
/*
+ compare two ldb_message_element structures.
+ Different ordering is considered a mismatch
+*/
+bool ldb_msg_element_equal_ordered(const struct ldb_message_element *el1,
+ const struct ldb_message_element *el2)
+{
+ unsigned i;
+ if (el1->num_values != el2->num_values) {
+ return false;
+ }
+ for (i=0;i<el1->num_values;i++) {
+ if (ldb_val_equal_exact(&el1->values[i],
+ &el2->values[i]) != 1) {
+ return false;
+ }
+ }
+ return true;
+}
+
+/*
compare two ldb_message_element structures
comparing by element name
*/
diff --git a/lib/ldb/include/ldb_module.h b/lib/ldb/include/ldb_module.h
index 4ecddc4..389e8ce 100644
--- a/lib/ldb/include/ldb_module.h
+++ b/lib/ldb/include/ldb_module.h
@@ -359,4 +359,9 @@ int ldb_parse_tree_walk(struct ldb_parse_tree *tree,
int (*callback)(struct ldb_parse_tree *tree, void *),
void *private_context);
+/* compare two message elements with ordering - used by modify */
+bool ldb_msg_element_equal_ordered(const struct ldb_message_element *el1,
+ const struct ldb_message_element *el2);
+
+
#endif
diff --git a/lib/ldb/ldb_tdb/ldb_tdb.c b/lib/ldb/ldb_tdb/ldb_tdb.c
index ebde8a3..5324c9b 100644
--- a/lib/ldb/ldb_tdb/ldb_tdb.c
+++ b/lib/ldb/ldb_tdb/ldb_tdb.c
@@ -845,11 +845,18 @@ int ltdb_modify_internal(struct ldb_module *module,
if (idx != -1) {
j = (unsigned int) idx;
el2 = &(msg2->elements[j]);
- if (ldb_msg_element_compare(el, el2) == 0) {
- /* we are replacing with the same values */
+
+ /* we consider two elements to be
+ * equal only if the order
+ * matches. This allows dbcheck to
+ * fix the ordering on attributes
+ * where order matters, such as
+ * objectClass
+ */
+ if (ldb_msg_element_equal_ordered(el, el2)) {
continue;
}
-
+
/* Delete the attribute if it exists in the DB */
if (msg_delete_attribute(module, ldb, msg2,
el->name) != 0) {
diff --git a/lib/ldb/wscript b/lib/ldb/wscript
index 620d2cf..f62bdec 100755
--- a/lib/ldb/wscript
+++ b/lib/ldb/wscript
@@ -1,7 +1,7 @@
#!/usr/bin/env python
APPNAME = 'ldb'
-VERSION = '1.1.5'
+VERSION = '1.1.6'
blddir = 'bin'
diff --git a/lib/replace/system/filesys.h b/lib/replace/system/filesys.h
index e2c3c1d..2393068 100644
--- a/lib/replace/system/filesys.h
+++ b/lib/replace/system/filesys.h
@@ -200,4 +200,12 @@
# define uwrap_enabled() 0
#endif /* UID_WRAPPER */
+/*
+ this allows us to use a uniform error handling for our xattr
+ wrappers
+*/
+#ifndef ENOATTR
+#define ENOATTR ENODATA
+#endif
+
#endif
diff --git a/source4/dsdb/pydsdb.c b/source4/dsdb/pydsdb.c
index 762a03d..d3486a4 100644
--- a/source4/dsdb/pydsdb.c
+++ b/source4/dsdb/pydsdb.c
@@ -569,6 +569,7 @@ static PyObject *py_dsdb_DsReplicaAttribute(PyObject *self, PyObject *args)
PyObject *item = PyList_GetItem(el_list, i);
if (!PyString_Check(item)) {
PyErr_Format(PyExc_TypeError, "ldif_elements should be strings");
+ talloc_free(tmp_ctx);
return NULL;
}
el->values[i].data = (uint8_t *)PyString_AsString(item);
@@ -663,12 +664,25 @@ static PyObject *py_dsdb_normalise_attributes(PyObject *self, PyObject *args)
PyObject *item = PyList_GetItem(el_list, i);
if (!PyString_Check(item)) {
PyErr_Format(PyExc_TypeError, "ldif_elements should be strings");
+ talloc_free(tmp_ctx);
return NULL;
}
el->values[i].data = (uint8_t *)PyString_AsString(item);
el->values[i].length = PyString_Size(item);
}
+ /* Normalise "objectClass" attribute if needed */
+ if (ldb_attr_cmp(a->lDAPDisplayName, "objectClass") == 0) {
+ int iret;
+ iret = dsdb_sort_objectClass_attr(ldb, schema, tmp_ctx, el,
+ tmp_ctx, el);
+ if (iret != LDB_SUCCESS) {
+ PyErr_SetString(PyExc_RuntimeError, ldb_errstring(ldb));
+ talloc_free(tmp_ctx);
+ return NULL;
+ }
+ }
+
/* first run ldb_to_drsuapi, then convert back again. This has
* the effect of normalising the attributes
*/
diff --git a/source4/dsdb/samdb/ldb_modules/samldb.c b/source4/dsdb/samdb/ldb_modules/samldb.c
index 79ab1f8..390d921 100644
--- a/source4/dsdb/samdb/ldb_modules/samldb.c
+++ b/source4/dsdb/samdb/ldb_modules/samldb.c
@@ -1683,7 +1683,7 @@ static int samldb_member_check(struct samldb_ctx *ac)
/* Fetch information from the existing object */
ret = dsdb_module_search(ac->module, ac, &res, ac->msg->dn, LDB_SCOPE_BASE, attrs,
- DSDB_FLAG_NEXT_MODULE, ac->req, NULL);
+ DSDB_FLAG_NEXT_MODULE | DSDB_SEARCH_SHOW_DELETED, ac->req, NULL);
if (ret != LDB_SUCCESS) {
return ret;
}
diff --git a/source4/scripting/python/samba/dbchecker.py b/source4/scripting/python/samba/dbchecker.py
index d866b3c..7993b54 100644
--- a/source4/scripting/python/samba/dbchecker.py
+++ b/source4/scripting/python/samba/dbchecker.py
@@ -48,6 +48,7 @@ class dbcheck(object):
self.fix_time_metadata = False
self.fix_all_missing_backlinks = False
self.fix_all_orphaned_backlinks = False
+ self.fix_rmd_flags = False
self.in_transaction = in_transaction
def check_database(self, DN=None, scope=ldb.SCOPE_SUBTREE, controls=[], attrs=['*']):
@@ -163,6 +164,26 @@ class dbcheck(object):
validate=False):
self.report("Normalised attribute %s" % attrname)
+ def err_normalise_mismatch_replace(self, dn, attrname, values):
+ '''fix attribute normalisation errors'''
+ normalised = self.samdb.dsdb_normalise_attributes(self.samdb_schema, attrname, values)
+ self.report("ERROR: Normalisation error for attribute '%s' in '%s'" % (attrname, dn))
+ self.report("Values/Order of values do/does not match: %s/%s!" % (values, list(normalised)))
+ if list(normalised) == values:
+ return
+ if not self.confirm_all("Fix normalisation for '%s' from '%s'?" % (attrname, dn), 'fix_all_normalisation'):
+ self.report("Not fixing attribute '%s'" % attrname)
+ return
+
+ m = ldb.Message()
+ m.dn = dn
+ m[attrname] = ldb.MessageElement(normalised, ldb.FLAG_MOD_REPLACE, attrname)
+
+ if self.do_modify(m, ["relax:0", "show_recycled:1"],
+ "Failed to normalise attribute %s" % attrname,
+ validate=False):
+ self.report("Normalised attribute %s" % attrname)
+
def is_deleted_objects_dn(self, dsdb_dn):
'''see if a dsdb_Dn is the special Deleted Objects DN'''
return dsdb_dn.prefix == "B:32:18E2EA80684F11D2B9AA00C04F79F805:"
@@ -262,6 +283,20 @@ class dbcheck(object):
"Failed to fix missing backlink %s" % backlink_name):
self.report("Fixed missing backlink %s" % (backlink_name))
+ def err_incorrect_rmd_flags(self, obj, attrname, revealed_dn):
+ '''handle a incorrect RMD_FLAGS value'''
+ rmd_flags = int(revealed_dn.dn.get_extended_component("RMD_FLAGS"))
+ self.report("ERROR: incorrect RMD_FLAGS value %u for attribute '%s' in %s for link %s" % (rmd_flags, attrname, obj.dn, revealed_dn.dn.extended_str()))
+ if not self.confirm_all('Fix incorrect RMD_FLAGS %u' % rmd_flags, 'fix_rmd_flags'):
+ self.report("Not fixing incorrect RMD_FLAGS %u" % rmd_flags)
+ return
+ m = ldb.Message()
+ m.dn = obj.dn
+ m['old_value'] = ldb.MessageElement(str(revealed_dn), ldb.FLAG_MOD_DELETE, attrname)
+ if self.do_modify(m, ["show_recycled:1", "reveal_internals:0", "show_deleted:0"],
+ "Failed to fix incorrect RMD_FLAGS %u" % rmd_flags):
+ self.report("Fixed incorrect RMD_FLAGS %u" % (rmd_flags))
+
def err_orphaned_backlink(self, obj, attrname, val, link_name, target_dn):
'''handle a orphaned backlink value'''
self.report("ERROR: orphaned backlink attribute '%s' in %s for link %s in %s" % (attrname, obj.dn, link_name, target_dn))
@@ -275,6 +310,18 @@ class dbcheck(object):
"Failed to fix orphaned backlink %s" % link_name):
self.report("Fixed orphaned backlink %s" % (link_name))
+ def find_revealed_link(self, dn, attrname, guid):
+ '''return a revealed link in an object'''
+ res = self.samdb.search(base=dn, scope=ldb.SCOPE_BASE, attrs=[attrname],
+ controls=["show_deleted:0", "extended_dn:0", "reveal_internals:0"])
+ syntax_oid = self.samdb_schema.get_syntax_oid_from_lDAPDisplayName(attrname)
+ for val in res[0][attrname]:
+ dsdb_dn = dsdb_Dn(self.samdb, val, syntax_oid)
+ guid2 = dsdb_dn.dn.get_extended_component("GUID")
+ if guid == guid2:
+ return dsdb_dn
+ return None
+
def check_dn(self, obj, attrname, syntax_oid):
'''check a DN attribute for correctness'''
error_count = 0
@@ -324,6 +371,14 @@ class dbcheck(object):
res[0].dn, "incorrect string version of DN")
continue
+ if is_deleted and not target_is_deleted and reverse_link_name is not None:
+ revealed_dn = self.find_revealed_link(obj.dn, attrname, guid)
+ rmd_flags = revealed_dn.dn.get_extended_component("RMD_FLAGS")
+ if rmd_flags != None and (int(rmd_flags) & 1) == 0:
+ # the RMD_FLAGS for this link should be 1, as the target is deleted
+ self.err_incorrect_rmd_flags(obj, attrname, revealed_dn)
+ continue
+
# check the reverse_link is correct if there should be one
if reverse_link_name is not None:
match_count = 0
@@ -422,6 +477,13 @@ class dbcheck(object):
got_repl_property_meta_data = True
continue
+ if str(attrname).lower() == 'objectclass':
+ normalised = self.samdb.dsdb_normalise_attributes(self.samdb_schema, attrname, list(obj[attrname]))
+ if list(normalised) != list(obj[attrname]):
+ self.err_normalise_mismatch_replace(dn, attrname, list(obj[attrname]))
+ error_count += 1
+ continue
+
# check for empty attributes
for val in obj[attrname]:
if val == '':
--
Samba Shared Repository
More information about the samba-cvs
mailing list