mirror of
https://github.com/samba-team/samba.git
synced 2025-01-10 01:18:15 +03:00
domain_update: implement updates 82-89 in order to reach the latest w2016 level
I implemented them by looking at source4/setup/adprep/WindowsServerDocs/Domain-Wide-Updates.md.unused and looking at a network capture where a Windows 2022 joins an Windows 2008R2 domain. The strange thing is that Windows (tested with server 2022) uses c81fc9cc-0130-f4d1-b272-634d74818133 for update 83, while Domain-Wide-Updates.md and a fresh installation use c81fc9cc-0130-4fd1-b272-634d74818133. In order to match a fresh installation we use c81fc9cc-0130-4fd1-b272-634d74818133. Signed-off-by: Stefan Metzmacher <metze@samba.org> Reviewed-by: Andrew Bartlett <abartlet@samba.org>
This commit is contained in:
parent
c8f8efb31e
commit
1e024f6568
@ -35,7 +35,7 @@ from samba.dsdb import (
|
||||
)
|
||||
|
||||
MIN_UPDATE = 75
|
||||
MAX_UPDATE = 81
|
||||
MAX_UPDATE = 89
|
||||
|
||||
update_map = {
|
||||
# Missing updates from 2008 R2 - version 5
|
||||
@ -49,14 +49,30 @@ update_map = {
|
||||
81: "ff4f9d27-7157-4cb0-80a9-5d6f2b14c8ff",
|
||||
# Windows Server 2012 R2 - version 10
|
||||
# No updates
|
||||
# Windows Server 2016 - version 15
|
||||
82: "83c53da7-427e-47a4-a07a-a324598b88f7",
|
||||
# from the documentation and a fresh installtion
|
||||
# 83 is this:
|
||||
# c81fc9cc-0130-4fd1-b272-634d74818133
|
||||
# adprep will use this on the wire:
|
||||
# c81fc9cc-0130-f4d1-b272-634d74818133
|
||||
83: "c81fc9cc-0130-4fd1-b272-634d74818133",
|
||||
84: "e5f9e791-d96d-4fc9-93c9-d53e1dc439ba",
|
||||
85: "e6d5fd00-385d-4e65-b02d-9da3493ed850",
|
||||
86: "3a6b3fbf-3168-4312-a10d-dd5b3393952d",
|
||||
87: "7f950403-0ab3-47f9-9730-5d7b0269f9bd",
|
||||
88: "434bb40d-dbc9-4fe7-81d4-d57229f7b080",
|
||||
# Windows Server 2016 - version 16
|
||||
89: "a0c238ba-9e30-4ee6-80a6-43f731e9a5cd",
|
||||
}
|
||||
|
||||
|
||||
functional_level_to_max_update = {
|
||||
DS_DOMAIN_FUNCTION_2008: 74,
|
||||
DS_DOMAIN_FUNCTION_2008_R2: 77,
|
||||
DS_DOMAIN_FUNCTION_2012: 81,
|
||||
DS_DOMAIN_FUNCTION_2012_R2: 81,
|
||||
DS_DOMAIN_FUNCTION_2016: 88,
|
||||
DS_DOMAIN_FUNCTION_2016: 89,
|
||||
}
|
||||
|
||||
functional_level_to_version = {
|
||||
@ -64,7 +80,7 @@ functional_level_to_version = {
|
||||
DS_DOMAIN_FUNCTION_2008_R2: 5,
|
||||
DS_DOMAIN_FUNCTION_2012: 9,
|
||||
DS_DOMAIN_FUNCTION_2012_R2: 10,
|
||||
DS_DOMAIN_FUNCTION_2016: 15,
|
||||
DS_DOMAIN_FUNCTION_2016: 16,
|
||||
}
|
||||
|
||||
# No update numbers have been skipped over
|
||||
@ -329,3 +345,232 @@ objectClass: msImaging-PSPs
|
||||
|
||||
if self.add_update_container:
|
||||
self.update_add(op)
|
||||
|
||||
## ## Windows Server 2016: Domain-wide updates
|
||||
##
|
||||
## After the operations that are performed by domainprep in Windows
|
||||
## Server 2016 (operations 82-88) complete, the revision attribute for the
|
||||
## CN=ActiveDirectoryUpdate,CN=DomainUpdates,CN=System,DC=ForestRootDomain
|
||||
## object is set to 15.
|
||||
|
||||
## Operation 82: {83c53da7-427e-47a4-a07a-a324598b88f7}
|
||||
##
|
||||
## Create CN=Keys container at root of domain
|
||||
##
|
||||
## - objectClass: container
|
||||
## - description: Default container for key credential objects
|
||||
## - ShowInAdvancedViewOnly: TRUE
|
||||
##
|
||||
## (A;CI;RPWPCRLCLOCCDCRCWDWOSDDTSW;;;EA)
|
||||
## (A;CI;RPWPCRLCLOCCDCRCWDWOSDDTSW;;;DA)
|
||||
## (A;CI;RPWPCRLCLOCCDCRCWDWOSDDTSW;;;SY)
|
||||
## (A;CI;RPWPCRLCLOCCDCRCWDWOSDDTSW;;;DD)
|
||||
## (A;CI;RPWPCRLCLOCCDCRCWDWOSDDTSW;;;ED)
|
||||
##
|
||||
def operation_82(self, op):
|
||||
if self.update_exists(op):
|
||||
return
|
||||
self.raise_if_not_fix(op)
|
||||
|
||||
keys_dn = "CN=Keys,%s" % str(self.domain_dn)
|
||||
|
||||
sddl = "O:DA"
|
||||
sddl += "D:"
|
||||
sddl += "(A;CI;RPWPCRLCLOCCDCRCWDWOSDDTSW;;;EA)"
|
||||
sddl += "(A;CI;RPWPCRLCLOCCDCRCWDWOSDDTSW;;;DA)"
|
||||
sddl += "(A;CI;RPWPCRLCLOCCDCRCWDWOSDDTSW;;;SY)"
|
||||
sddl += "(A;CI;RPWPCRLCLOCCDCRCWDWOSDDTSW;;;DD)"
|
||||
sddl += "(A;CI;RPWPCRLCLOCCDCRCWDWOSDDTSW;;;ED)"
|
||||
|
||||
ldif = """
|
||||
dn: %s
|
||||
objectClass: container
|
||||
description: Default container for key credential objects
|
||||
ShowInAdvancedViewOnly: TRUE
|
||||
nTSecurityDescriptor: %s
|
||||
""" % (keys_dn, sddl)
|
||||
|
||||
self.samdb.add_ldif(ldif)
|
||||
|
||||
if self.add_update_container:
|
||||
self.update_add(op)
|
||||
|
||||
## Operation 83: {c81fc9cc-0130-4fd1-b272-634d74818133}
|
||||
##
|
||||
## Add Full Control allow aces to CN=Keys container for "domain\Key Admins"
|
||||
## and "rootdomain\Enterprise Key Admins".
|
||||
##
|
||||
## (A;CI;RPWPCRLCLOCCDCRCWDWOSDDTSW;;;Key Admins)
|
||||
## (A;CI;RPWPCRLCLOCCDCRCWDWOSDDTSW;;;Enterprise Key Admins)
|
||||
##
|
||||
def operation_83(self, op):
|
||||
if self.update_exists(op):
|
||||
return
|
||||
self.raise_if_not_fix(op)
|
||||
|
||||
keys_dn = "CN=Keys,%s" % str(self.domain_dn)
|
||||
|
||||
aces = ["(A;CI;RPWPCRLCLOCCDCRCWDWOSDDTSW;;;KA)"]
|
||||
aces += ["(A;CI;RPWPCRLCLOCCDCRCWDWOSDDTSW;;;EK)"]
|
||||
|
||||
self.sd_utils.update_aces_in_dacl(keys_dn, add_aces=aces)
|
||||
|
||||
if self.add_update_container:
|
||||
self.update_add(op)
|
||||
|
||||
|
||||
## Operation 84: {e5f9e791-d96d-4fc9-93c9-d53e1dc439ba}
|
||||
##
|
||||
## Modify otherWellKnownObjects attribute to point to the CN=Keys container.
|
||||
##
|
||||
## - otherWellKnownObjects: B:32:683A24E2E8164BD3AF86AC3C2CF3F981:CN=Keys,%ws
|
||||
def operation_84(self, op):
|
||||
if self.update_exists(op):
|
||||
return
|
||||
self.raise_if_not_fix(op)
|
||||
|
||||
keys_dn = "CN=Keys,%s" % str(self.domain_dn)
|
||||
|
||||
ldif = """
|
||||
dn: %s
|
||||
changetype: modify
|
||||
add: otherWellKnownObjects
|
||||
otherWellKnownObjects: B:32:683A24E2E8164BD3AF86AC3C2CF3F981:%s
|
||||
""" % (str(self.domain_dn), keys_dn)
|
||||
|
||||
self.samdb.modify_ldif(ldif)
|
||||
|
||||
if self.add_update_container:
|
||||
self.update_add(op)
|
||||
|
||||
|
||||
## Operation 85: {e6d5fd00-385d-4e65-b02d-9da3493ed850}
|
||||
##
|
||||
## Modify the domain NC to permit "domain\Key Admins" and
|
||||
## "rootdomain\Enterprise Key Admins"
|
||||
## to modify the msds-KeyCredentialLink attribute.
|
||||
##
|
||||
## (OA;CI;RPWP;5b47d60f-6090-40b2-9f37-2a4de88f3063;;Key Admins)
|
||||
## (OA;CI;RPWP;5b47d60f-6090-40b2-9f37-2a4de88f3063;;Enterprise Key Admins)
|
||||
## in root domain, but in non-root domains resulted in a bogus domain-relative
|
||||
## ACE with a non-resolvable -527 SID
|
||||
##
|
||||
def operation_85(self, op):
|
||||
if self.update_exists(op):
|
||||
return
|
||||
self.raise_if_not_fix(op)
|
||||
|
||||
aces = ["(OA;CI;RPWP;5b47d60f-6090-40b2-9f37-2a4de88f3063;;KA)"]
|
||||
# we use an explicit sid in order to replay the windows mistake
|
||||
aces += ["(OA;CI;RPWP;5b47d60f-6090-40b2-9f37-2a4de88f3063;;%s-527)" %
|
||||
str(self.domain_sid)]
|
||||
|
||||
self.sd_utils.update_aces_in_dacl(self.domain_dn, add_aces=aces)
|
||||
|
||||
if self.add_update_container:
|
||||
self.update_add(op)
|
||||
|
||||
|
||||
## Operation 86: {3a6b3fbf-3168-4312-a10d-dd5b3393952d}
|
||||
##
|
||||
## Grant the DS-Validated-Write-Computer CAR to creator owner and self
|
||||
##
|
||||
## (OA;CIIO;SW;9b026da6-0d3c-465c-8bee-5199d7165cba;bf967a86-0de6-11d0-a285-00aa003049e2;PS)
|
||||
## (OA;CIIO;SW;9b026da6-0d3c-465c-8bee-5199d7165cba;bf967a86-0de6-11d0-a285-00aa003049e2;CO)
|
||||
##
|
||||
def operation_86(self, op):
|
||||
if self.update_exists(op):
|
||||
return
|
||||
self.raise_if_not_fix(op)
|
||||
|
||||
aces = ["(OA;CIIO;SW;9b026da6-0d3c-465c-8bee-5199d7165cba;bf967a86-0de6-11d0-a285-00aa003049e2;PS)"]
|
||||
aces += ["(OA;CIIO;SW;9b026da6-0d3c-465c-8bee-5199d7165cba;bf967a86-0de6-11d0-a285-00aa003049e2;CO)"]
|
||||
|
||||
self.sd_utils.update_aces_in_dacl(self.domain_dn, add_aces=aces)
|
||||
|
||||
if self.add_update_container:
|
||||
self.update_add(op)
|
||||
|
||||
## Operation 87: {7f950403-0ab3-47f9-9730-5d7b0269f9bd}
|
||||
##
|
||||
## Delete the ACE granting Full Control to the incorrect
|
||||
## domain-relative Enterprise Key Admins group, and add
|
||||
## an ACE granting Full Control to Enterprise Key Admins group.
|
||||
##
|
||||
## Delete (A;CI;RPWPCRLCLOCCDCRCWDWOSDDTSW;;;Enterprise Key Admins)
|
||||
## Add (A;CI;RPWPCRLCLOCCDCRCWDWOSDDTSW;;;Enterprise Key Admins)
|
||||
##
|
||||
def operation_87(self, op):
|
||||
if self.update_exists(op):
|
||||
return
|
||||
self.raise_if_not_fix(op)
|
||||
|
||||
# we use an explicit sid in order to replay the windows mistake
|
||||
# note this is also strange for a 2nd reason because it doesn't
|
||||
# delete: ["(OA;CI;RPWP;5b47d60f-6090-40b2-9f37-2a4de88f3063;;%s-527)"
|
||||
# which was added in operation_85, so the del is basically a noop
|
||||
# and the result is one additional ace
|
||||
del_aces = ["(A;CI;RPWPCRLCLOCCDCRCWDWOSDDTSW;;;%s-527)" %
|
||||
str(self.domain_sid)]
|
||||
add_aces = ["(A;CI;RPWPCRLCLOCCDCRCWDWOSDDTSW;;;EK)"]
|
||||
|
||||
self.sd_utils.update_aces_in_dacl(self.domain_dn,
|
||||
del_aces=del_aces,
|
||||
add_aces=add_aces)
|
||||
|
||||
if self.add_update_container:
|
||||
self.update_add(op)
|
||||
|
||||
## Operation 88: {434bb40d-dbc9-4fe7-81d4-d57229f7b080}
|
||||
##
|
||||
## Add "msDS-ExpirePasswordsOnSmartCardOnlyAccounts" on the domain NC object
|
||||
## and set default value to FALSE
|
||||
##
|
||||
def operation_88(self, op):
|
||||
if self.update_exists(op):
|
||||
return
|
||||
self.raise_if_not_fix(op)
|
||||
|
||||
ldif = """
|
||||
dn: %s
|
||||
changetype: modify
|
||||
add: msDS-ExpirePasswordsOnSmartCardOnlyAccounts
|
||||
msDS-ExpirePasswordsOnSmartCardOnlyAccounts: FALSE
|
||||
""" % str(self.domain_dn)
|
||||
|
||||
self.samdb.modify_ldif(ldif)
|
||||
|
||||
if self.add_update_container:
|
||||
self.update_add(op)
|
||||
|
||||
## Windows Server 2016 (operation 89) complete, the **revision** attribute for the
|
||||
## CN=ActiveDirectoryUpdate,CN=DomainUpdates,CN=System,DC=ForestRootDomain object
|
||||
## is set to **16**.
|
||||
##
|
||||
|
||||
## Operation 89: {a0c238ba-9e30-4ee6-80a6-43f731e9a5cd}
|
||||
##
|
||||
## Delete the ACE granting Full Control to Enterprise Key Admins and
|
||||
## add an ACE granting Enterprise Key Admins Full Control over just
|
||||
## the msdsKeyCredentialLink attribute.
|
||||
##
|
||||
## Delete (A;CI;RPWPCRLCLOCCDCRCWDWOSDDTSW;;;Enterprise Key Admins)
|
||||
## Add (OA;CI;RPWP;5b47d60f-6090-40b2-9f37-2a4de88f3063;;Enterprise Key Admins)|
|
||||
##
|
||||
def operation_89(self, op):
|
||||
if self.update_exists(op):
|
||||
return
|
||||
self.raise_if_not_fix(op)
|
||||
|
||||
# Note this only fixes the mistake from operation_87
|
||||
# but leaves the mistake of operation_85 if we're
|
||||
# not in the root domain...
|
||||
del_aces = ["(A;CI;RPWPCRLCLOCCDCRCWDWOSDDTSW;;;EK)"]
|
||||
add_aces = ["(OA;CI;RPWP;5b47d60f-6090-40b2-9f37-2a4de88f3063;;EK)"]
|
||||
|
||||
self.sd_utils.update_aces_in_dacl(self.domain_dn,
|
||||
del_aces=del_aces,
|
||||
add_aces=add_aces)
|
||||
|
||||
if self.add_update_container:
|
||||
self.update_add(op)
|
||||
|
Loading…
Reference in New Issue
Block a user