[PATCH] samba-tool drs: new subcommand "conflicts"
Andrew Bartlett
abartlet at samba.org
Wed Feb 26 18:54:38 MST 2014
On Mon, 2014-02-24 at 14:06 +0100, Felix Botner wrote:
> http://technet.microsoft.com/en-us/library/bb727059.aspx explains how
> to deal with object name conflicts in a multimaster environment. One step is
> to delete conflicting objects.
>
> Since we have encountered conflicting objects in many s4 multimaster
> environments an easy way to list (and delete) them would be very helpful.
>
> Here a patch to add a new subcommand "conflicts" to samba-tool drs to list all
> conflicts with the option to delete them (or to delete a specific conflict).
Thanks for the patch! With real-world deployment of Samba as an AD DC,
these kind of tools are becoming really important. See below for my
further comments.
> Signed-off-by: Felix Botner <botner at univention.de>
> ---
> python/samba/netcmd/drs.py | 48 ++++++++++++++++++++++++++++++++++++++++++++
> 1 file changed, 48 insertions(+)
>
> diff --git a/python/samba/netcmd/drs.py b/python/samba/netcmd/drs.py
> index 36dc48e..b783e54 100644
> --- a/python/samba/netcmd/drs.py
> +++ b/python/samba/netcmd/drs.py
> @@ -32,6 +32,7 @@ from samba.samdb import SamDB
> from samba import drs_utils, nttime2string, dsdb
> from samba.dcerpc import drsuapi, misc
> import common
> +import samba.common
>
> def drsuapi_connect(ctx):
> '''make a DRSUAPI connection to the server'''
> @@ -234,7 +235,53 @@ class cmd_drs_kcc(Command):
> raise CommandError("DsExecuteKCC failed", e)
> self.message("Consistency check on %s successful." % DC)
>
> +class cmd_drs_conflicts(Command):
> + '''list/remove conflicts in local db'''
>
> + synopsis = "%prog [options]"
> +
> + takes_optiongroups = {
> + "sambaopts": options.SambaOptions,
> + "versionopts": options.VersionOptions,
> + "credopts": options.CredentialsOptions,
> + }
> +
> + takes_options = [
> + Option("--verbose", help="print ldif of conflict objects", action="store_true", default=False),
> + Option("--delete", help="delete all conflict objects", action="store_true", default=False),
> + Option("--dn", help="delete only given dn/conflict (if found)", type=str),
> + Option("--non-interactive", help="do not ask for deletion", action="store_true", default=False)
> + ]
> +
> + def run(self, delete, verbose, dn, non_interactive,
> + credopts=None, sambaopts=None, versionopts=None):
> + lp = sambaopts.get_loadparm()
> + creds = credopts.get_credentials(lp, fallback_machine=True)
> + samdb = SamDB(session_info=system_session(), url=None,
> + credentials=creds, lp=lp)
> +
> + domain_dn = samdb.domain_dn()
> + scope = ldb.SCOPE_SUBTREE
> + if dn:
> + domain_dn = dn
> + scope = ldb.SCOPE_BASE
> + controls = []
> + for msg in samdb.search(base=domain_dn, scope=scope, controls=controls):
> + if "\\0ACNF" in str(msg.dn):
> + print "Conflict: " + str(msg.dn)
> + if verbose:
> + print samdb.write_ldif(msg, ldb.CHANGETYPE_NONE)
> + if delete:
> + if not non_interactive == True:
> + answer = samba.common.confirm("Delete object with dn %s?" % msg.dn, allow_all=True)
> + if answer == "ALL":
> + non_interactive = True
> + elif answer == "NONE":
> + return
> + elif answer == False:
> + continue
> + samdb.delete(msg.dn)
> + print "%s deleted" % str(msg.dn)
>
> def drs_local_replicate(self, SOURCE_DC, NC):
> '''replicate from a source DC to the local SAM'''
> @@ -519,3 +566,4 @@ class cmd_drs(SuperCommand):
> subcommands["replicate"] = cmd_drs_replicate()
> subcommands["showrepl"] = cmd_drs_showrepl()
> subcommands["options"] = cmd_drs_options()
> + subcommands["conflicts"] = cmd_drs_conflicts()
This looks reasonable, but wouldn't be a better that this be put in
dbcheck, a bit like the reset-well-known-acls? That would avoid
reimplemting the all/none checks.
My feeling is while triggered by DRS, these are not really DRS
operations.
Andrew Bartlett
--
Andrew Bartlett
http://samba.org/~abartlet/
Authentication Developer, Samba Team http://samba.org
Samba Developer, Catalyst IT http://catalyst.net.nz/services/samba
More information about the samba-technical
mailing list