# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
+from __future__ import print_function
+
import samba.getopt as options
import ldb
import logging
from samba.dcerpc import drsblobs
from samba import colour
+from samba.uptodateness import (
+ get_partition_maps,
+ get_utdv_edges,
+ get_utdv_distances,
+ get_utdv_summary,
+ get_kcc_and_dsas,
+)
+
def drsuapi_connect(ctx):
'''make a DRSUAPI connection to the server'''
targetdir=targetdir, include_secrets=include_secrets)
+class cmd_drs_uptodateness(Command):
+ """Show uptodateness status"""
+
+ synopsis = "%prog [options]"
+
+ takes_optiongroups = {
+ "sambaopts": options.SambaOptions,
+ "versionopts": options.VersionOptions,
+ "credopts": options.CredentialsOptions,
+ }
+
+ takes_options = [
+ Option("-H", "--URL", metavar="URL", dest="H",
+ help="LDB URL for database or target server"),
+ Option("-p", "--partition",
+ help="restrict to this partition"),
+ Option("--json", action='store_true',
+ help="Print data in json format"),
+ Option("--maximum", action='store_true',
+ help="Print maximum out-of-date-ness only"),
+ Option("--median", action='store_true',
+ help="Print median out-of-date-ness only"),
+ Option("--full", action='store_true',
+ help="Print full out-of-date-ness data"),
+ ]
+
+ def format_as_json(self, partitions_summaries):
+ return json.dumps(partitions_summaries, indent=2)
+
+ def format_as_text(self, partitions_summaries):
+ lines = []
+ for part_name, summary in partitions_summaries.items():
+ items = ['%s: %s' % (k, v) for k, v in summary.items()]
+ line = '%-15s %s' % (part_name, ' '.join(items))
+ lines.append(line)
+ return '\n'.join(lines)
+
+ def run(self, H=None, partition=None,
+ json=False, maximum=False, median=False, full=False,
+ sambaopts=None, credopts=None, versionopts=None,
+ quiet=False, verbose=False):
+
+ lp = sambaopts.get_loadparm()
+ creds = credopts.get_credentials(lp, fallback_machine=True)
+ local_kcc, dsas = get_kcc_and_dsas(H, lp, creds)
+ samdb = local_kcc.samdb
+ short_partitions, _ = get_partition_maps(samdb)
+ if partition:
+ if partition in short_partitions:
+ part_dn = short_partitions[partition]
+ # narrow down to specified partition only
+ short_partitions = {partition: part_dn}
+ else:
+ raise CommandError("unknown partition %s" % partition)
+
+ filters = []
+ if maximum:
+ filters.append('maximum')
+ if median:
+ filters.append('median')
+
+ partitions_distances = {}
+ partitions_summaries = {}
+ for part_name, part_dn in short_partitions.items():
+ utdv_edges = get_utdv_edges(local_kcc, dsas, part_dn, lp, creds)
+ distances = get_utdv_distances(utdv_edges, dsas)
+ summary = get_utdv_summary(distances, filters=filters)
+ partitions_distances[part_name] = distances
+ partitions_summaries[part_name] = summary
+
+ if full:
+ # always print json format
+ output = self.format_as_json(partitions_distances)
+ else:
+ if json:
+ output = self.format_as_json(partitions_summaries)
+ else:
+ output = self.format_as_text(partitions_summaries)
+
+ print(output, file=self.outf)
+
+
class cmd_drs(SuperCommand):
"""Directory Replication Services (DRS) management."""
subcommands["showrepl"] = cmd_drs_showrepl()
subcommands["options"] = cmd_drs_options()
subcommands["clone-dc-database"] = cmd_drs_clone_dc_database()
+ subcommands["uptodateness"] = cmd_drs_uptodateness()