uptodateness: migrate more methods from visualize
[amitay/samba.git] / python / samba / uptodateness.py
1 # Uptodateness utils
2 #
3 # Copyright (C) Andrew Bartlett 2015, 2018
4 # Copyright (C) Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
5 # Copyright (C) Joe Guo <joeg@catalyst.net.nz>
6 #
7 # This program is free software; you can redistribute it and/or modify
8 # it under the terms of the GNU General Public License as published by
9 # the Free Software Foundation; either version 3 of the License, or
10 # (at your option) any later version.
11 #
12 # This program is distributed in the hope that it will be useful,
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 # GNU General Public License for more details.
16 #
17 # You should have received a copy of the GNU General Public License
18 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
19 import time
20
21 from ldb import SCOPE_BASE
22
23 from samba import nttime2unix, dsdb
24 from samba.netcmd import CommandError
25
26
27 def get_partition_maps(samdb):
28     """Generate dictionaries mapping short partition names to the
29     appropriate DNs."""
30     base_dn = samdb.domain_dn()
31     short_to_long = {
32         "DOMAIN": base_dn,
33         "CONFIGURATION": str(samdb.get_config_basedn()),
34         "SCHEMA": "CN=Schema,%s" % samdb.get_config_basedn(),
35         "DNSDOMAIN": "DC=DomainDnsZones,%s" % base_dn,
36         "DNSFOREST": "DC=ForestDnsZones,%s" % base_dn
37     }
38
39     long_to_short = {}
40     for s, l in short_to_long.items():
41         long_to_short[l] = s
42
43     return short_to_long, long_to_short
44
45
46 def get_partition(samdb, part):
47     # Allow people to say "--partition=DOMAIN" rather than
48     # "--partition=DC=blah,DC=..."
49     if part is not None:
50         short_partitions, long_partitions = get_partition_maps(samdb)
51         part = short_partitions.get(part.upper(), part)
52         if part not in long_partitions:
53             raise CommandError("unknown partition %s" % part)
54     return part
55
56
57 def get_utdv(samdb, dn):
58     """This finds the uptodateness vector in the database."""
59     cursors = []
60     config_dn = samdb.get_config_basedn()
61     for c in dsdb._dsdb_load_udv_v2(samdb, dn):
62         inv_id = str(c.source_dsa_invocation_id)
63         res = samdb.search(base=config_dn,
64                            expression=("(&(invocationId=%s)"
65                                        "(objectClass=nTDSDSA))" % inv_id),
66                            attrs=["distinguishedName", "invocationId"])
67         settings_dn = str(res[0]["distinguishedName"][0])
68         prefix, dsa_dn = settings_dn.split(',', 1)
69         if prefix != 'CN=NTDS Settings':
70             raise CommandError("Expected NTDS Settings DN, got %s" %
71                                settings_dn)
72
73         cursors.append((dsa_dn,
74                         inv_id,
75                         int(c.highest_usn),
76                         nttime2unix(c.last_sync_success)))
77     return cursors
78
79
80 def get_own_cursor(samdb):
81     res = samdb.search(base="",
82                        scope=SCOPE_BASE,
83                        attrs=["highestCommittedUSN"])
84     usn = int(res[0]["highestCommittedUSN"][0])
85     now = int(time.time())
86     return (usn, now)