
from samba import dsdb

from os import path

SCOPE_BASE = ""

def binary_encode(s):
    return s

OUs = {}
GPOs = {}
accounts = {}

##############################
# OU=RnD,OU=IT Dept,DC=warthogs,DC=biz

#  /warthogs
#            -- Default Domain Policy    <- UserAtRoot
#  /warthogs/IT
##            -- IT GPO
#  /warthogs/IT/ITDep1                   <- hostname1
##            -- ITDep1 GPO
#  /warthogs/IT/ITDep2                   <- hostname2
##            -- ITDep2 User only GPO                                 <- machine flag disabled
#  /warthogs/RnD                         <- RnDUser
##            -- RnD GPO
#  /warthogs/RnD/RnDDep1                 <- RnDUserDep1
##            -- RnDDep1 GPO1
##            -- RnDDep1 GPO2
#  /warthogs/RnD/RnDDep2
##            -- RnDDep2 GPO
##            -- RnDDep2 Forced GPO                                   <- forced GPO
#  /warthogs/RnD/RnDDep2/SubDep2ForcedPolicy     <- RndUserSubDep2ForcedPolicy
##            -- SubDep2ForcedPolicy Forced GPO                       <- forced GPO
#  /warthogs/RnD/RnDDep2/SubDep2BlockInheritance                      <- block inheritance
##            -- SubDep2BlockInheritance GPO
#  /warthogs/RnD/RnDDep2/SubDep2BlockInheritance/SubBlocked   <- RnDUserWithBlockedInheritanceAndForcedPolicies
##            -- SubBlocked GPO
#  /warthogs/RnD/RnDDep3                 <- RnDUserDep3
##            -- RnDDep3 Disabled GPO                                 <- disabled gpo
##            -- RnDDep3 GPO
#  /warthogs/RnD/RnDDep4                 <- RnDUserDep4
##            -- RnDDep4 Security descriptor missing GPO              <- security descriptor missing
#  /warthogs/RnD/RnDDep5                 <- RnDUserDep5
##            -- RnDDep5 security access failed GPO                   <- security failed denied
#  /warthogs/RnD/RnDDep6                 <- RnDUserDep6
##            -- RnDDep6 security access denied GPO                   <- security access denied
#  /warthogs/RnD/RnDDep7                 <- RnDUserDep7
##            -- RnDDep7 machine only GPO                             <- user flag disabled
#  /warthogs/RnD/RnDDep8                 <- RnDUserDep8
##            -- RnDDep8 allow for one user only GPO  <- RnDUserDep8  <- nTSecurityDescriptor allowed for another user that our one
#  /warthogs/RnD/RnDDepBlockInheritance               <-RnDUserWithBlockedInheritance      <- block inheritance
##            -- RnDDepBlockInheritance GPO
#  /warthogs/NoGPO                       <- UserNoGPO
#  /warthogs/NogPOptions                 <- UserNogPOptions
##            -- NogPOptions GPO
#  /warthogs/InvalidGPOLink              <- UserInvalidLink

##############################

# Only called on user/machine, returns correct account object
def Dn(samdb, dn):
    return accounts[dn]


# OU themselves
class OU:
    def __init__(self, strdn):
        self.strdn = strdn
        self.gpos=[]

        self.gPLink = [b'']
        if path.basename(strdn) == "InvalidGPOLink":
            self.gPLink = [b'[invalidlink;0]']

        self.gPOptions = b'0'
        if path.basename(strdn) in ("SubDep2BlockInheritance", "RnDDepBlockInheritance"):
            self.gPOptions = [dsdb.GPO_BLOCK_INHERITANCE]
        if path.basename(strdn) == "NogPOptions":
            delattr(self, "gPOptions")

        OUs[strdn] = self

    def parent(self):
        ppath = path.dirname(self.strdn)
        if ppath == "":
            return None
        return OUs[ppath]

    def addGPO(self, gpo):
        self.gpos.append(gpo)
        gPLink = ""
        for gpo in self.gpos:
            global GPOs
            GPOs[gpo.name] = gpo
            state = 0
            if gpo.disabled:
                state = dsdb.GPLINK_OPT_DISABLE
            if gpo.enforced:
                state = dsdb.GPLINK_OPT_ENFORCE
            gPLink += "[LDAP://%s;%d]" % (gpo.name, state)
        self.gPLink = [gPLink]

    def addAccount(self, accountName):
        Account(accountName, self)


class GPO:
    def __init__(self, name):
        self.name = name.replace(" ", "_")
        self.display_name = name

        self.flags = [b'0']
        if name == "ITDep2 User only GPO":
            self.flags = [str.encode(str(dsdb.GPO_FLAG_MACHINE_DISABLE))]
        elif name == "RnDDep7 machine only GPO":
            self.flags = [str.encode(str(dsdb.GPO_FLAG_USER_DISABLE))]

        self.enforced = False
        if name == "RnDDep2 Forced GPO" or name == "SubDep2ForcedPolicy Forced GPO":
            self.enforced = True
        self.disabled = False
        if name == "RnDDep3 Disabled GPO":
            self.disabled = True

        self.nTSecurityDescriptor = ['O:S-1-5-21-16178157-162784614-155579044-512G:S-1-5-21-16178157-162784614-155579044-512D:PAI(D;;RPLCRC;;;S-1-5-21-16178157-162784614-155579044-1103)(OA;;CR;edacfd8f-ffb3-11d1-b41d-00a0c968f939;;S-1-5-21-16178157-162784614-155579044-1103)(A;;RPWPLCRC;;;S-1-5-21-16178157-162784614-155579044-1102)(A;CI;RPWPCCDCLCLORCWOWDSDDTSW;;;S-1-5-21-16178157-162784614-155579044-512)(A;CI;RPWPCCDCLCLORCWOWDSDDTSW;;;S-1-5-21-16178157-162784614-155579044-519)(A;CI;RPLCLORC;;;ED)(A;CI;RPLCLORC;;;AU)(A;CI;RPWPCCDCLCLORCWOWDSDDTSW;;;SY)(A;CIIO;RPWPCCDCLCLORCWOWDSDDTSW;;;CO)']

        if name == "RnDDep4 Security descriptor missing GPO":
            self.nTSecurityDescriptor = ["MISSING"]
        if name == "RnDDep5 security access failed GPO":
            self.nTSecurityDescriptor = ["FAILED"]
        if name == "RnDDep6 security access denied GPO":
            self.nTSecurityDescriptor = [self.nTSecurityDescriptor[0].replace("OA", "OD")]
        if name == "RnDDep8 allow for one user only GPO":
            self.nTSecurityDescriptor = [self.nTSecurityDescriptor[0].replace("S-1-5-21-16178157-162784614-155579044-1103", "OtherUserSid")]

        self.gPCFileSysPath = ['\\\\warthogs.biz\\SysVol\\warthogs.biz\\Policies\\%s' % self.name]


# Can be a User or a Computer
class Account:
    def __init__(self, name, dn):
        self.name = name
        self.parentDn = dn
        accounts[name] = self

    def parent(self):
        return self.parentDn


# Build Domains
o = OU("/warthogs")
o.addGPO(GPO("Default Domain Policy"))
o.addAccount("UserAtRoot")

o = OU("/warthogs/IT")
o.addGPO(GPO("IT GPO"))

o = OU("/warthogs/IT/ITDep1")
o.addGPO(GPO("ITDep1 GPO"))
o.addAccount("hostname1")

o = OU("/warthogs/IT/ITDep2")
o.addGPO(GPO("ITDep2 User only GPO"))
o.addAccount("hostname2")

o = OU("/warthogs/RnD")
o.addGPO(GPO("RnD GPO"))
o.addAccount("RnDUser")

o = OU("/warthogs/RnD/RnDDep1")
o.addGPO(GPO("RnDDep1 GPO1"))
o.addGPO(GPO("RnDDep1 GPO2"))
o.addAccount("RnDUserDep1")

o = OU("/warthogs/RnD/RnDDep2")
o.addGPO(GPO("RnDDep2 GPO"))
o.addGPO(GPO("RnDDep2 Forced GPO"))

o = OU("/warthogs/RnD/RnDDep2/SubDep2ForcedPolicy")
o.addGPO(GPO("SubDep2ForcedPolicy Forced GPO"))
o.addAccount("RndUserSubDep2ForcedPolicy")

o = OU("/warthogs/RnD/RnDDep2/SubDep2BlockInheritance")
o.addGPO(GPO("SubDep2BlockInheritance GPO"))

o = OU("/warthogs/RnD/RnDDep2/SubDep2BlockInheritance/SubBlocked")
o.addGPO(GPO("SubBlocked GPO"))
o.addAccount("RnDUserWithBlockedInheritanceAndForcedPolicies")

o = OU("/warthogs/RnD/RnDDep3")
o.addGPO(GPO("RnDDep3 Disabled GPO"))
o.addGPO(GPO("RnDDep3 GPO"))
o.addAccount("RnDUserDep3")

o = OU("/warthogs/RnD/RnDDep4")
o.addGPO(GPO("RnDDep4 Security descriptor missing GPO"))
o.addAccount("RnDUserDep4")

o = OU("/warthogs/RnD/RnDDep5")
o.addGPO(GPO("RnDDep5 security access failed GPO"))
o.addAccount("RnDUserDep5")

o = OU("/warthogs/RnD/RnDDep6")
o.addGPO(GPO("RnDDep6 security access denied GPO"))
o.addAccount("RnDUserDep6")

o = OU("/warthogs/RnD/RnDDep7")
o.addGPO(GPO("RnDDep7 machine only GPO"))
o.addAccount("RnDUserDep7")

o = OU("/warthogs/RnD/RnDDep8")
o.addGPO(GPO("RnDDep8 allow for one user only GPO"))
o.addAccount("RnDUserDep8")

o = OU("/warthogs/RnD/RnDDepBlockInheritance")
o.addGPO(GPO("RnDDepBlockInheritance GPO"))
o.addAccount("RnDUserWithBlockedInheritance")

o = OU("/warthogs/NoGPO")
o.addAccount("UserNoGPO")

o = OU("/warthogs/NogPOptions")
o.addGPO(GPO("NogPOptions GPO"))
o.addAccount("UserNogPOptions")

o = OU("/warthogs/InvalidGPOLink")
o.addAccount("UserInvalidLink")

# [b'[LDAP://cn={83A5BD5B-1D5D-472D-827F-DE0E6F714300},cn=policies,cn=system,DC=warthogs,DC=biz;0][LDAP://cn={5EC4DF8F-FF4E-41DE-846B-52AA6FFAF242},cn=policies,cn=system,DC=warthogs,DC=biz;0]'

# Message({'dn': Dn('OU=RnD,OU=IT Dept,DC=warthogs,DC=biz'),
# 'gPLink': MessageElement(
#   [b'[LDAP://cn={83A5BD5B-1D5D-472D-827F-DE0E6F714300},cn=policies,cn=system,DC=warthogs,DC=biz;0][LDAP://cn={5EC4DF8F-FF4E-41DE-846B-52AA6FFAF242},cn=policies,cn=system,DC=warthogs,DC=biz;0]']),
# 'gPOptions': MessageElement([b'0'])})


# 'AAAAAA'
# Message({'dn': Dn('OU=RnD,OU=IT Dept,DC=warthogs,DC=biz'), 'gPLink': MessageElement([b'[LDAP://cn={83A5BD5B-1D5D-472D-827F-DE0E6F714300},cn=policies,cn=system,DC=warthogs,DC=biz;0][LDAP://cn={5EC4DF8F-FF4E-41DE-846B-52AA6FFAF242},cn=policies,cn=system,DC=warthogs,DC=biz;0]']), 'gPOptions': MessageElement([b'0'])})
# 'XXXXXX'
# Message({'dn': Dn('cn={83A5BD5B-1D5D-472D-827F-DE0E6F714300},cn=policies,cn=system,DC=warthogs,DC=biz'), 'displayName': MessageElement([b'RnD Policy 2']), 'nTSecurityDescriptor': MessageElement([b'\x01\x00\x04\x9c\x00\x01\x00\x00\x1c\x01\x00\x00\x00\x00\x00\x00\x14\x00\x00\x00\x04\x00\xec\x00\x08\x00\x00\x00\x05\x02(\x00\x00\x01\x00\x00\x01\x00\x00\x00\x8f\xfd\xac\xed\xb3\xff\xd1\x11\xb4\x1d\x00\xa0\xc9h\xf99\x01\x01\x00\x00\x00\x00\x00\x05\x0b\x00\x00\x00\x00\x00$\x00\xff\x00\x0f\x00\x01\x05\x00\x00\x00\x00\x00\x05\x15\x00\x00\x00\xed\xdb\xf6\x00f\xe5\xb3\t\xa4\xf2E\t\x00\x02\x00\x00\x00\x02$\x00\xff\x00\x0f\x00\x01\x05\x00\x00\x00\x00\x00\x05\x15\x00\x00\x00\xed\xdb\xf6\x00f\xe5\xb3\t\xa4\xf2E\t\x00\x02\x00\x00\x00\x02$\x00\xff\x00\x0f\x00\x01\x05\x00\x00\x00\x00\x00\x05\x15\x00\x00\x00\xed\xdb\xf6\x00f\xe5\xb3\t\xa4\xf2E\t\x07\x02\x00\x00\x00\x02\x14\x00\x94\x00\x02\x00\x01\x01\x00\x00\x00\x00\x00\x05\t\x00\x00\x00\x00\x02\x14\x00\x94\x00\x02\x00\x01\x01\x00\x00\x00\x00\x00\x05\x0b\x00\x00\x00\x00\x02\x14\x00\xff\x00\x0f\x00\x01\x01\x00\x00\x00\x00\x00\x05\x12\x00\x00\x00\x00\n\x14\x00\xff\x00\x0f\x00\x01\x01\x00\x00\x00\x00\x00\x03\x00\x00\x00\x00\x01\x05\x00\x00\x00\x00\x00\x05\x15\x00\x00\x00\xed\xdb\xf6\x00f\xe5\xb3\t\xa4\xf2E\t\x00\x02\x00\x00\x01\x05\x00\x00\x00\x00\x00\x05\x15\x00\x00\x00\xed\xdb\xf6\x00f\xe5\xb3\t\xa4\xf2E\t\x00\x02\x00\x00']), 'name': MessageElement([b'{83A5BD5B-1D5D-472D-827F-DE0E6F714300}']), 'flags': MessageElement([b'0']), 'gPCFileSysPath': MessageElement([b'\\\\warthogs.biz\\SysVol\\warthogs.biz\\Policies\\{83A5BD5B-1D5D-472D-827F-DE0E6F714300}'])})
# 'XXXXXX'
# Message({'dn': Dn('cn={5EC4DF8F-FF4E-41DE-846B-52AA6FFAF242},cn=policies,cn=system,DC=warthogs,DC=biz'), 'displayName': MessageElement([b'RnD Policy']), 'nTSecurityDescriptor': MessageElement([b'\x01\x00\x04\x9c\x00\x01\x00\x00\x1c\x01\x00\x00\x00\x00\x00\x00\x14\x00\x00\x00\x04\x00\xec\x00\x08\x00\x00\x00\x05\x02(\x00\x00\x01\x00\x00\x01\x00\x00\x00\x8f\xfd\xac\xed\xb3\xff\xd1\x11\xb4\x1d\x00\xa0\xc9h\xf99\x01\x01\x00\x00\x00\x00\x00\x05\x0b\x00\x00\x00\x00\x00$\x00\xff\x00\x0f\x00\x01\x05\x00\x00\x00\x00\x00\x05\x15\x00\x00\x00\xed\xdb\xf6\x00f\xe5\xb3\t\xa4\xf2E\t\x00\x02\x00\x00\x00\x02$\x00\xff\x00\x0f\x00\x01\x05\x00\x00\x00\x00\x00\x05\x15\x00\x00\x00\xed\xdb\xf6\x00f\xe5\xb3\t\xa4\xf2E\t\x00\x02\x00\x00\x00\x02$\x00\xff\x00\x0f\x00\x01\x05\x00\x00\x00\x00\x00\x05\x15\x00\x00\x00\xed\xdb\xf6\x00f\xe5\xb3\t\xa4\xf2E\t\x07\x02\x00\x00\x00\x02\x14\x00\x94\x00\x02\x00\x01\x01\x00\x00\x00\x00\x00\x05\t\x00\x00\x00\x00\x02\x14\x00\x94\x00\x02\x00\x01\x01\x00\x00\x00\x00\x00\x05\x0b\x00\x00\x00\x00\x02\x14\x00\xff\x00\x0f\x00\x01\x01\x00\x00\x00\x00\x00\x05\x12\x00\x00\x00\x00\n\x14\x00\xff\x00\x0f\x00\x01\x01\x00\x00\x00\x00\x00\x03\x00\x00\x00\x00\x01\x05\x00\x00\x00\x00\x00\x05\x15\x00\x00\x00\xed\xdb\xf6\x00f\xe5\xb3\t\xa4\xf2E\t\x00\x02\x00\x00\x01\x05\x00\x00\x00\x00\x00\x05\x15\x00\x00\x00\xed\xdb\xf6\x00f\xe5\xb3\t\xa4\xf2E\t\x00\x02\x00\x00']), 'name': MessageElement([b'{5EC4DF8F-FF4E-41DE-846B-52AA6FFAF242}']), 'flags': MessageElement([b'0']), 'gPCFileSysPath': MessageElement([b'\\\\warthogs.biz\\SysVol\\warthogs.biz\\Policies\\{5EC4DF8F-FF4E-41DE-846B-52AA6FFAF242}'])})


# Message({'dn': Dn('OU=RnD,OU=IT Dept,DC=warthogs,DC=biz'), 'gPLink': MessageElement([b'[LDAP://cn={5EC4DF8F-FF4E-41DE-846B-52AA6FFAF242},cn=policies,cn=system,DC=warthogs,DC=biz;0]']), 'gPOptions': MessageElement([b'0'])})
# Message({'dn': Dn('OU=IT Dept,DC=warthogs,DC=biz'), 'gPLink': MessageElement([b'[LDAP://cn={75545F76-DEC2-4ADA-B7B8-D5209FD48727},cn=policies,cn=system,DC=warthogs,DC=biz;0]'])})
# Message({'dn': Dn('DC=warthogs,DC=biz'), 'gPLink': MessageElement([b'[LDAP://CN={31B2F340-016D-11D2-945F-00C04FB984F9},CN=Policies,CN=System,DC=warthogs,DC=biz;0]'])})


# GPO_APPLY_GUID = "edacfd8f-ffb3-11d1-b41d-00a0c968f939"
# secdesc = 'O:S-1-5-21-16178157-162784614-155579044-512G:S-1-5-21-16178157-162784614-155579044-512D:PAI(D;;RPLCRC;;;S-1-5-21-16178157-162784614-155579044-1103)(OA;;CR;edacfd8f-ffb3-11d1-b41d-00a0c968f939;;S-1-5-21-16178157-162784614-155579044-1103)(A;;RPWPLCRC;;;S-1-5-21-16178157-162784614-155579044-1102)(A;CI;RPWPCCDCLCLORCWOWDSDDTSW;;;S-1-5-21-16178157-162784614-155579044-512)(A;CI;RPWPCCDCLCLORCWOWDSDDTSW;;;S-1-5-21-16178157-162784614-155579044-519)(A;CI;RPLCLORC;;;ED)(A;CI;RPLCLORC;;;AU)(A;CI;RPWPCCDCLCLORCWOWDSDDTSW;;;SY)(A;CIIO;RPWPCCDCLCLORCWOWDSDDTSW;;;CO)'
# sids = ["S-1-5-21-16178157-162784614-155579044-1102", "AU"]
