mirror of
https://github.com/samba-team/samba.git
synced 2025-01-26 10:04:02 +03:00
s4-upgradeprovision: introduce invocation id in lastprovisionUSNs
This commit is contained in:
parent
71ab462c81
commit
20233cdf53
@ -902,10 +902,22 @@ def checkKeepAttributeWithMetadata(delta, att, message, reference, current,
|
||||
|
||||
attrUSN = None
|
||||
if hash_attr_usn.get(att):
|
||||
attrUSN = hash_attr_usn.get(att)
|
||||
[attrUSN, attInvId] = hash_attr_usn.get(att)
|
||||
|
||||
if attrUSN is None:
|
||||
# If it's a replicated attribute and we don't have any USN
|
||||
# information about it. It means that we never saw it before
|
||||
# so let's add it !
|
||||
# If it is a replicated attribute but we are not master on it
|
||||
# (ie. not initially added in the provision we masterize).
|
||||
# attrUSN will be -1
|
||||
if isReplicated(att):
|
||||
continue
|
||||
elif att in hashAttrNotCopied.keys():
|
||||
delta.remove(att)
|
||||
else:
|
||||
continue
|
||||
|
||||
if att == "forceLogoff" and attrUSN is None:
|
||||
continue
|
||||
if attrUSN is None:
|
||||
delta.remove(att)
|
||||
continue
|
||||
@ -956,7 +968,7 @@ def checkKeepAttributeWithMetadata(delta, att, message, reference, current,
|
||||
|
||||
return delta
|
||||
|
||||
def update_present(ref_samdb, samdb, basedn, listPresent, usns, invocationid):
|
||||
def update_present(ref_samdb, samdb, basedn, listPresent, usns):
|
||||
""" This function updates the object that are already present in the
|
||||
provision
|
||||
|
||||
@ -966,8 +978,8 @@ def update_present(ref_samdb, samdb, basedn, listPresent, usns, invocationid):
|
||||
(ie. DC=foo, DC=bar)
|
||||
:param listPresent: A list of object that is present in the provision
|
||||
:param usns: A list of USN range modified by previous provision and
|
||||
upgradeprovision
|
||||
:param invocationid: The value of the invocationid for the current DC"""
|
||||
upgradeprovision grouped by invocation ID
|
||||
"""
|
||||
|
||||
# This hash is meant to speedup lookup of attribute name from an oid,
|
||||
# it's for the replPropertyMetaData handling
|
||||
@ -1026,10 +1038,10 @@ def update_present(ref_samdb, samdb, basedn, listPresent, usns, invocationid):
|
||||
# We put in this hash only modification
|
||||
# made on the current host
|
||||
att = hash_oid_name[samdb.get_oid_from_attid(o.attid)]
|
||||
if str(o.originating_invocation_id) == str(invocationid):
|
||||
# Note we could just use 1 here
|
||||
hash_attr_usn[att] = o.originating_usn
|
||||
if str(o.originating_invocation_id) in usns.keys():
|
||||
hash_attr_usn[att] = [o.originating_usn, str(o.originating_invocation_id)]
|
||||
else:
|
||||
hash_attr_usn[att] = [-1, None]
|
||||
|
||||
if usns is not None:
|
||||
delta = checkKeepAttributeWithMetadata(delta, att, message, reference,
|
||||
@ -1160,7 +1172,7 @@ def update_partition(ref_samdb, samdb, basedn, names, schema, provisionUSNs, pre
|
||||
message(SIMPLE, "Schema reloaded!")
|
||||
|
||||
changed = update_present(ref_samdb, samdb, basedn, listPresent,
|
||||
provisionUSNs, names.invocation)
|
||||
provisionUSNs)
|
||||
message(SIMPLE, "There are %d changed objects" % (changed))
|
||||
return 1
|
||||
|
||||
@ -1665,9 +1677,19 @@ if __name__ == '__main__':
|
||||
# 4)
|
||||
lastProvisionUSNs = get_last_provision_usn(ldbs.sam)
|
||||
if lastProvisionUSNs is not None:
|
||||
message(CHANGE,
|
||||
"Find a last provision USN, %d range(s)" % len(lastProvisionUSNs))
|
||||
v = 0
|
||||
for k in lastProvisionUSNs.keys():
|
||||
for r in lastProvisionUSNs[k]:
|
||||
v = v + 1
|
||||
|
||||
message(CHANGE,
|
||||
"Find last provision USN, %d invocation(s) for a total of %d ranges" % \
|
||||
(len(lastProvisionUSNs.keys()), v /2 ))
|
||||
|
||||
if lastProvisionUSNs.get("default") != None:
|
||||
message(CHANGE, "Old style for usn ranges used")
|
||||
lastProvisionUSNs[str(names.invocation)] = lastProvisionUSNs["default"]
|
||||
del lastProvisionUSNs["default"]
|
||||
# Objects will be created with the admin session
|
||||
# (not anymore system session)
|
||||
adm_session = admin_session(lp, str(names.domainsid))
|
||||
@ -1853,7 +1875,7 @@ if __name__ == '__main__':
|
||||
check_for_DNS(newpaths.private_dir, paths.private_dir)
|
||||
# 22)
|
||||
if lastProvisionUSNs is not None:
|
||||
update_provision_usn(ldbs.sam, minUSN, maxUSN)
|
||||
update_provision_usn(ldbs.sam, minUSN, maxUSN, names.invocation)
|
||||
if opts.full and (names.policyid is None or names.policyid_dc is None):
|
||||
update_policyids(names, ldbs.sam)
|
||||
if opts.full or opts.resetfileacl or opts.fixntacl:
|
||||
|
@ -322,7 +322,7 @@ def find_provision_key_parameters(samdb, secretsdb, idmapdb, paths, smbconf, lp)
|
||||
raise ProvisioningError("Unable to find uid/gid for Domain Admins rid")
|
||||
return names
|
||||
|
||||
def update_provision_usn(samdb, low, high, replace=False):
|
||||
def update_provision_usn(samdb, low, high, id, replace=False):
|
||||
"""Update the field provisionUSN in sam.ldb
|
||||
|
||||
This field is used to track range of USN modified by provision and
|
||||
@ -333,6 +333,7 @@ def update_provision_usn(samdb, low, high, replace=False):
|
||||
:param samdb: An LDB object connect to sam.ldb
|
||||
:param low: The lowest USN modified by this upgrade
|
||||
:param high: The highest USN modified by this upgrade
|
||||
:param id: The invocation id of the samba's dc
|
||||
:param replace: A boolean indicating if the range should replace any
|
||||
existing one or appended (default)
|
||||
"""
|
||||
@ -344,17 +345,24 @@ def update_provision_usn(samdb, low, high, replace=False):
|
||||
scope=ldb.SCOPE_SUBTREE,
|
||||
attrs=[LAST_PROVISION_USN_ATTRIBUTE, "dn"])
|
||||
for e in entry[0][LAST_PROVISION_USN_ATTRIBUTE]:
|
||||
if not re.search(';', e):
|
||||
e = "%s;%s" % (e, id)
|
||||
tab.append(str(e))
|
||||
|
||||
tab.append("%s-%s" % (low, high))
|
||||
tab.append("%s-%s;%s" % (low, high, id))
|
||||
delta = ldb.Message()
|
||||
delta.dn = ldb.Dn(samdb, "@PROVISION")
|
||||
delta[LAST_PROVISION_USN_ATTRIBUTE] = ldb.MessageElement(tab,
|
||||
ldb.FLAG_MOD_REPLACE, LAST_PROVISION_USN_ATTRIBUTE)
|
||||
entry = samdb.search(expression="(&(dn=@PROVISION)(provisionnerID=*))",
|
||||
base="", scope=ldb.SCOPE_SUBTREE,
|
||||
attrs=["provisionnerID"])
|
||||
if len(entry) == 0 or len(entry[0]) == 0:
|
||||
delta["provisionnerID"] = ldb.MessageElement(id, ldb.FLAG_MOD_ADD, "provisionnerID")
|
||||
samdb.modify(delta)
|
||||
|
||||
|
||||
def set_provision_usn(samdb, low, high):
|
||||
def set_provision_usn(samdb, low, high, id):
|
||||
"""Set the field provisionUSN in sam.ldb
|
||||
This field is used to track range of USN modified by provision and
|
||||
upgradeprovision.
|
||||
@ -363,9 +371,12 @@ def set_provision_usn(samdb, low, high):
|
||||
|
||||
:param samdb: An LDB object connect to sam.ldb
|
||||
:param low: The lowest USN modified by this upgrade
|
||||
:param high: The highest USN modified by this upgrade"""
|
||||
:param high: The highest USN modified by this upgrade
|
||||
:param id: The invocationId of the provision"""
|
||||
|
||||
tab = []
|
||||
tab.append("%s-%s" % (low, high))
|
||||
tab.append("%s-%s;%s" % (low, high, id))
|
||||
|
||||
delta = ldb.Message()
|
||||
delta.dn = ldb.Dn(samdb, "@PROVISION")
|
||||
delta[LAST_PROVISION_USN_ATTRIBUTE] = ldb.MessageElement(tab,
|
||||
@ -390,25 +401,36 @@ def get_max_usn(samdb,basedn):
|
||||
|
||||
|
||||
def get_last_provision_usn(sam):
|
||||
"""Get the lastest USN modified by a provision or an upgradeprovision
|
||||
"""Get USNs ranges modified by a provision or an upgradeprovision
|
||||
|
||||
:param sam: An LDB object pointing to the sam.ldb
|
||||
:return: an integer corresponding to the highest USN modified by
|
||||
(upgrade)provision, 0 is this value is unknown
|
||||
:return: a dictionnary which keys are invocation id and values are an array
|
||||
of integer representing the different ranges
|
||||
"""
|
||||
entry = sam.search(expression="(&(dn=@PROVISION)(%s=*))" %
|
||||
LAST_PROVISION_USN_ATTRIBUTE,
|
||||
base="", scope=ldb.SCOPE_SUBTREE,
|
||||
attrs=[LAST_PROVISION_USN_ATTRIBUTE])
|
||||
attrs=[LAST_PROVISION_USN_ATTRIBUTE, "provisionnerID"])
|
||||
if len(entry):
|
||||
range = []
|
||||
idx = 0
|
||||
myids = []
|
||||
range = {}
|
||||
p = re.compile(r'-')
|
||||
if entry[0].get("provisionnerID"):
|
||||
for e in entry[0]["provisionnerID"]:
|
||||
myids.append(str(e))
|
||||
for r in entry[0][LAST_PROVISION_USN_ATTRIBUTE]:
|
||||
tab = p.split(str(r))
|
||||
range.append(tab[0])
|
||||
range.append(tab[1])
|
||||
idx = idx + 1
|
||||
tab1 = str(r).split(';')
|
||||
if len(tab1) == 2:
|
||||
id = tab1[1]
|
||||
else:
|
||||
id = "default"
|
||||
if (len(myids) > 0 and id not in myids):
|
||||
continue
|
||||
tab2 = p.split(tab1[0])
|
||||
if range.get(id) == None:
|
||||
range[id] = []
|
||||
range[id].append(tab2[0])
|
||||
range[id].append(tab2[1])
|
||||
return range
|
||||
else:
|
||||
return None
|
||||
@ -1780,9 +1802,9 @@ def provision(logger, session_info, credentials, smbconf=None,
|
||||
lastProvisionUSNs = get_last_provision_usn(samdb)
|
||||
maxUSN = get_max_usn(samdb, str(names.rootdn))
|
||||
if lastProvisionUSNs is not None:
|
||||
update_provision_usn(samdb, 0, maxUSN, 1)
|
||||
update_provision_usn(samdb, 0, maxUSN, invocationid, 1)
|
||||
else:
|
||||
set_provision_usn(samdb, 0, maxUSN)
|
||||
set_provision_usn(samdb, 0, maxUSN, invocationid)
|
||||
|
||||
create_krb5_conf(paths.krb5conf,
|
||||
dnsdomain=names.dnsdomain, hostname=names.hostname,
|
||||
|
Loading…
x
Reference in New Issue
Block a user