diff options
author | Felix Botner <botner@univention.de> | 2014-02-24 14:08:25 +0100 |
---|---|---|
committer | Andrew Bartlett <abartlet@samba.org> | 2014-03-27 00:36:31 +0100 |
commit | 5b1d6e722e254522165ec512537a2efa2b979e6f (patch) | |
tree | 864d944c871873a1e55169767158f2d67b4507e2 /python | |
parent | 74a83be540c8fa0dd0f91da25b1f9d7ccc4ec568 (diff) | |
download | samba-5b1d6e722e254522165ec512537a2efa2b979e6f.tar.gz samba-5b1d6e722e254522165ec512537a2efa2b979e6f.tar.xz samba-5b1d6e722e254522165ec512537a2efa2b979e6f.zip |
samba-tool dbcheck: handle missing objectClass
In several cases we have seen objects without the objectClass attribute.
Here the suggestion for a patch to find such objects in "samba-tool dbcheck"
with the option to delete them.
(patch improved by Andrew Bartlett to suggest DRS re-replication)
Signed-off-by: Felix Botner <botner@univention.de>
Change-Id: I8eb0d191a2089271a9af5884d6bfbf173a5c85c6
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
Reviewed-by: Stefan Metzmacher <metze@samba.org>
Diffstat (limited to 'python')
-rw-r--r-- | python/samba/dbchecker.py | 31 |
1 files changed, 31 insertions, 0 deletions
diff --git a/python/samba/dbchecker.py b/python/samba/dbchecker.py index e6f26c3753f..f276cc56430 100644 --- a/python/samba/dbchecker.py +++ b/python/samba/dbchecker.py @@ -73,6 +73,7 @@ class dbcheck(object): self.ntds_dsa = ldb.Dn(samdb, samdb.get_dsServiceName()) self.class_schemaIDGUID = {} self.wellknown_sds = get_wellknown_sds(self.samdb) + self.fix_all_missing_objectclass = False self.name_map = {} try: @@ -174,6 +175,18 @@ class dbcheck(object): return False return c + def do_delete(self, dn, controls, msg): + '''delete dn with optional verbose output''' + if self.verbose: + self.report("delete DN %s" % dn) + try: + controls = controls + ["local_oid:%s:0" % dsdb.DSDB_CONTROL_DBCHECK] + self.samdb.delete(dn, controls=controls) + except Exception, err: + self.report("%s : %s" % (msg, err)) + return False + return True + def do_modify(self, m, controls, msg, validate=True): '''perform a modify with optional verbose output''' if self.verbose: @@ -272,6 +285,16 @@ newSuperior: %s""" % (str(from_dn), str(to_rdn), str(to_base))) '''see if a dsdb_Dn is the special Deleted Objects DN''' return dsdb_dn.prefix == "B:32:%s:" % dsdb.DS_GUID_DELETED_OBJECTS_CONTAINER + def err_missing_objectclass(self, dn): + """handle object without objectclass""" + self.report("ERROR: missing objectclass in object %s. If you have another working DC, please run 'samba-tool drs replicate --full-sync --local <destinationDC> <sourceDC> %s'" % (dn, self.samdb.get_nc_root(dn))) + if not self.confirm_all("If you cannot re-sync from another DC, do you wish to delete object '%s'?" % dn, 'fix_all_missing_objectclass'): + self.report("Not deleting object with missing objectclass '%s'" % dn) + return + if self.do_delete(dn, ["relax:0"], + "Failed to remove DN %s" % dn): + self.report("Removed DN %s" % dn) + def err_deleted_dn(self, dn, attrname, val, dsdb_dn, correct_dn): """handle a DN pointing to a deleted object""" self.report("ERROR: target DN is deleted for %s in object %s - %s" % (attrname, dn, val)) @@ -1018,11 +1041,15 @@ newSuperior: %s""" % (str(from_dn), str(to_rdn), str(to_base))) list_attrs_from_md = [] list_attrs_seen = [] got_repl_property_meta_data = False + got_objectclass = False for attrname in obj: if attrname == 'dn': continue + if str(attrname).lower() == 'objectclass': + got_objectclass = True + if str(attrname).lower() == 'replpropertymetadata': if self.has_replmetadata_zero_invocationid(dn, obj[attrname]): error_count += 1 @@ -1110,6 +1137,10 @@ newSuperior: %s""" % (str(from_dn), str(to_rdn), str(to_base))) error_count += 1 self.err_wrong_instancetype(obj, calculated_instancetype) + if not got_objectclass and ("*" in attrs or "objectclass" in map(str.lower, attrs)): + error_count += 1 + self.err_missing_objectclass(dn) + show_dn = True if got_repl_property_meta_data: rdn = (str(dn).split(","))[0] |