Example #1
0
def import_sam_policy(samdb, policy, logger):
    """Import a Samba 3 policy.

    :param samdb: Samba4 SAM database
    :param policy: Samba3 account policy
    :param logger: Logger object
    """

    # Following entries are used -
    #    min password length, password history, minimum password age,
    #    maximum password age, lockout duration
    #
    # Following entries are not used -
    #    reset count minutes, user must logon to change password,
    #    bad lockout minutes, disconnect time

    m = ldb.Message()
    m.dn = samdb.get_default_basedn()
    m['a01'] = ldb.MessageElement(str(policy['min password length']),
        ldb.FLAG_MOD_REPLACE, 'minPwdLength')
    m['a02'] = ldb.MessageElement(str(policy['password history']),
        ldb.FLAG_MOD_REPLACE, 'pwdHistoryLength')

    min_pw_age_unix = policy['minimum password age']
    min_pw_age_nt = 0 - unix2nttime(min_pw_age_unix)
    m['a03'] = ldb.MessageElement(str(min_pw_age_nt), ldb.FLAG_MOD_REPLACE,
        'minPwdAge')

    max_pw_age_unix = policy['maximum password age']
    if (max_pw_age_unix == 0xFFFFFFFF):
        max_pw_age_nt = 0
    else:
        max_pw_age_nt = unix2nttime(max_pw_age_unix)

    m['a04'] = ldb.MessageElement(str(max_pw_age_nt), ldb.FLAG_MOD_REPLACE,
                                  'maxPwdAge')

    lockout_duration_mins = policy['lockout duration']
    lockout_duration_nt = unix2nttime(lockout_duration_mins * 60)

    m['a05'] = ldb.MessageElement(str(lockout_duration_nt),
        ldb.FLAG_MOD_REPLACE, 'lockoutDuration')

    try:
        samdb.modify(m)
    except ldb.LdbError, e:
        logger.warn("Could not set account policy, (%s)", str(e))
Example #2
0
    def set_attribute_replmetadata_version(self,
                                           dn,
                                           att,
                                           value,
                                           addifnotexist=False):
        res = self.search(expression="distinguishedName=%s" % dn,
                          scope=ldb.SCOPE_SUBTREE,
                          controls=["search_options:1:2"],
                          attrs=["replPropertyMetaData"])
        if len(res) == 0:
            return None

        repl = ndr_unpack(drsblobs.replPropertyMetaDataBlob,
                          res[0]["replPropertyMetaData"][0])
        ctr = repl.ctr
        now = samba.unix2nttime(int(time.time()))
        found = False
        if len(self.hash_oid_name.keys()) == 0:
            self._populate_oid_attid()
        for o in ctr.array:
            # Search for Description
            att_oid = self.get_oid_from_attid(o.attid)
            if att_oid in self.hash_oid_name and\
               att.lower() == self.hash_oid_name[att_oid].lower():
                found = True
                seq = self.sequence_number(ldb.SEQ_NEXT)
                o.version = value
                o.originating_change_time = now
                o.originating_invocation_id = misc.GUID(
                    self.get_invocation_id())
                o.originating_usn = seq
                o.local_usn = seq

        if not found and addifnotexist and len(ctr.array) > 0:
            o2 = drsblobs.replPropertyMetaData1()
            o2.attid = 589914
            att_oid = self.get_oid_from_attid(o2.attid)
            seq = self.sequence_number(ldb.SEQ_NEXT)
            o2.version = value
            o2.originating_change_time = now
            o2.originating_invocation_id = misc.GUID(self.get_invocation_id())
            o2.originating_usn = seq
            o2.local_usn = seq
            found = True
            tab = ctr.array
            tab.append(o2)
            ctr.count = ctr.count + 1
            ctr.array = tab

        if found:
            replBlob = ndr_pack(repl)
            msg = ldb.Message()
            msg.dn = res[0].dn
            msg["replPropertyMetaData"] = \
                ldb.MessageElement(replBlob,
                                   ldb.FLAG_MOD_REPLACE,
                                   "replPropertyMetaData")
            self.modify(msg, ["local_oid:1.3.6.1.4.1.7165.4.3.14:0"])
Example #3
0
    def generate_auth(self, trustdom_secret):
        def arcfour_encrypt(key, data):
            c = RC4.RC4(key)
            return c.update(data)

        def string_to_array(what):
            blob = [0] * len(what)

            for i in range(len(what)):
                blob[i] = ord(what[i])
            return blob

        password_blob = string_to_array(trustdom_secret.encode('utf-16-le'))

        clear_value = drsblobs.AuthInfoClear()
        clear_value.size = len(password_blob)
        clear_value.password = password_blob

        clear_authentication_information = drsblobs.AuthenticationInformation()
        clear_authentication_information.LastUpdateTime = samba.unix2nttime(
            int(time.time()))
        clear_authentication_information.AuthType = lsa.TRUST_AUTH_TYPE_CLEAR
        clear_authentication_information.AuthInfo = clear_value

        authentication_information_array = drsblobs.AuthenticationInformationArray(
        )
        authentication_information_array.count = 1
        authentication_information_array.array = [
            clear_authentication_information
        ]

        outgoing = drsblobs.trustAuthInOutBlob()
        outgoing.count = 1
        outgoing.current = authentication_information_array

        confounder = [3] * 512
        for i in range(512):
            confounder[i] = random.randint(0, 255)

        trustpass = drsblobs.trustDomainPasswords()
        trustpass.confounder = confounder

        trustpass.outgoing = outgoing
        trustpass.incoming = outgoing

        trustpass_blob = ndr_pack(trustpass)

        encrypted_trustpass = arcfour_encrypt(self._pipe.session_key,
                                              trustpass_blob)

        auth_blob = lsa.DATA_BUF2()
        auth_blob.size = len(encrypted_trustpass)
        auth_blob.data = string_to_array(encrypted_trustpass)

        auth_info = lsa.TrustDomainInfoAuthInfoInternal()
        auth_info.auth_blob = auth_blob
        self.auth_info = auth_info
Example #4
0
 def __init__(self, url, setup_dir=""):
     self.url = url
     self._connect_to_mysql()
     self.nttime = samba.unix2nttime(int(time.time()))
     self.ou_id = None  # initialized on add_server() method
     self.replica_id = 1
     self.global_count = 1  # folder_id for public folders
     self._change_number = None
     self.migration_app = 'openchangedb'
Example #5
0
 def __init__(self, url, setup_dir=""):
     self.url = url
     self.schema = os.path.join(setup_dir, self.OPENCHANGEDB_SCHEMA)
     self._connect_to_mysql()
     self.nttime = samba.unix2nttime(int(time.time()))
     self.ou_id = None  # initialized on add_server() method
     self.replica_id = 1
     self.global_count = 1  # folder_id for public folders
     self._change_number = None
Example #6
0
 def __init__(self, url, setup_dir=""):
     self.url = url
     self.schema = os.path.join(setup_dir, self.OPENCHANGEDB_SCHEMA)
     self._connect_to_mysql()
     self.nttime = samba.unix2nttime(int(time.time()))
     self.ou_id = None  # initialized on add_server() method
     self.replica_id = 1
     self.global_count = 1  # folder_id for public folders
     self._change_number = None
Example #7
0
 def __init__(self, url, setup_dir=""):
     self.url = url
     self._connect_to_mysql()
     self.nttime = samba.unix2nttime(int(time.time()))
     self.ou_id = None  # initialized on add_server() method
     self.replica_id = 1
     self.global_count = 1  # folder_id for public folders
     self._change_number = None
     self.migration_app = 'openchangedb'
Example #8
0
def import_sam_policy(samdb, policy, logger):
    """Import a Samba 3 policy.

    :param samdb: Samba4 SAM database
    :param policy: Samba3 account policy
    :param logger: Logger object
    """

    # Following entries are used -
    #    min password length, password history, minimum password age,
    #    maximum password age, lockout duration
    #
    # Following entries are not used -
    #    reset count minutes, user must logon to change password,
    #    bad lockout minutes, disconnect time

    m = ldb.Message()
    m.dn = samdb.get_default_basedn()

    if 'min password length' in policy:
        m['a01'] = ldb.MessageElement(str(policy['min password length']),
                                      ldb.FLAG_MOD_REPLACE, 'minPwdLength')

    if 'password history' in policy:
        m['a02'] = ldb.MessageElement(str(policy['password history']),
                                      ldb.FLAG_MOD_REPLACE, 'pwdHistoryLength')

    if 'minimum password age' in policy:
        min_pw_age_unix = policy['minimum password age']
        min_pw_age_nt = int(-min_pw_age_unix * (1e7))
        m['a03'] = ldb.MessageElement(str(min_pw_age_nt), ldb.FLAG_MOD_REPLACE,
                                      'minPwdAge')

    if 'maximum password age' in policy:
        max_pw_age_unix = policy['maximum password age']
        if max_pw_age_unix == -1 or max_pw_age_unix == 0:
            max_pw_age_nt = -0x8000000000000000
        else:
            max_pw_age_nt = int(-max_pw_age_unix * (1e7))

        m['a04'] = ldb.MessageElement(str(max_pw_age_nt), ldb.FLAG_MOD_REPLACE,
                                      'maxPwdAge')

    if 'lockout duration' in policy:
        lockout_duration_mins = policy['lockout duration']
        lockout_duration_nt = unix2nttime(lockout_duration_mins * 60)

        m['a05'] = ldb.MessageElement(str(lockout_duration_nt),
                                      ldb.FLAG_MOD_REPLACE, 'lockoutDuration')

    try:
        samdb.modify(m)
    except ldb.LdbError, e:
        logger.warn("Could not set account policy, (%s)", str(e))
Example #9
0
    def set_attribute_replmetadata_version(self, dn, att, value,
            addifnotexist=False):
        res = self.search(expression="distinguishedName=%s" % dn,
                            scope=ldb.SCOPE_SUBTREE,
                            controls=["search_options:1:2"],
                            attrs=["replPropertyMetaData"])
        if len(res) == 0:
            return None

        repl = ndr_unpack(drsblobs.replPropertyMetaDataBlob,
                            str(res[0]["replPropertyMetaData"]))
        ctr = repl.ctr
        now = samba.unix2nttime(int(time.time()))
        found = False
        if len(self.hash_oid_name.keys()) == 0:
            self._populate_oid_attid()
        for o in ctr.array:
            # Search for Description
            att_oid = self.get_oid_from_attid(o.attid)
            if self.hash_oid_name.has_key(att_oid) and\
               att.lower() == self.hash_oid_name[att_oid].lower():
                found = True
                seq = self.sequence_number(ldb.SEQ_NEXT)
                o.version = value
                o.originating_change_time = now
                o.originating_invocation_id = misc.GUID(self.get_invocation_id())
                o.originating_usn = seq
                o.local_usn = seq

        if not found and addifnotexist and len(ctr.array) >0:
            o2 = drsblobs.replPropertyMetaData1()
            o2.attid = 589914
            att_oid = self.get_oid_from_attid(o2.attid)
            seq = self.sequence_number(ldb.SEQ_NEXT)
            o2.version = value
            o2.originating_change_time = now
            o2.originating_invocation_id = misc.GUID(self.get_invocation_id())
            o2.originating_usn = seq
            o2.local_usn = seq
            found = True
            tab = ctr.array
            tab.append(o2)
            ctr.count = ctr.count + 1
            ctr.array = tab

        if found :
            replBlob = ndr_pack(repl)
            msg = ldb.Message()
            msg.dn = res[0].dn
            msg["replPropertyMetaData"] = ldb.MessageElement(replBlob,
                                                ldb.FLAG_MOD_REPLACE,
                                                "replPropertyMetaData")
            self.modify(msg, ["local_oid:1.3.6.1.4.1.7165.4.3.14:0"])
Example #10
0
    def setexpiry(self, search_filter, expiry_seconds, no_expiry_req=False):
        """Sets the account expiry for a user

        :param search_filter: LDAP filter to find the user (eg
            samaccountname=name)
        :param expiry_seconds: expiry time from now in seconds
        :param no_expiry_req: if set, then don't expire password
        """
        self.transaction_start()
        try:
            res = self.search(base=self.domain_dn(),
                              scope=ldb.SCOPE_SUBTREE,
                              expression=search_filter,
                              attrs=["userAccountControl", "accountExpires"])
            if len(res) == 0:
                raise Exception('Unable to find user "%s"' % search_filter)
            assert (len(res) == 1)
            user_dn = res[0].dn

            userAccountControl = int(res[0]["userAccountControl"][0])
            accountExpires = int(res[0]["accountExpires"][0])
            if no_expiry_req:
                userAccountControl = userAccountControl | 0x10000
                accountExpires = 0
            else:
                userAccountControl = userAccountControl & ~0x10000
                accountExpires = samba.unix2nttime(expiry_seconds +
                                                   int(time.time()))

            setexp = """
dn: %s
changetype: modify
replace: userAccountControl
userAccountControl: %u
replace: accountExpires
accountExpires: %u
""" % (user_dn, userAccountControl, accountExpires)

            self.modify_ldif(setexp)
        except:
            self.transaction_cancel()
            raise
        else:
            self.transaction_commit()
Example #11
0
 def __init__(self, url):
     self.url = url
     self.ldb = Ldb(self.url)
     self.nttime = samba.unix2nttime(int(time.time()))
Example #12
0
    def join_setup_trusts(ctx):
        '''provision the local SAM'''
        def arcfour_encrypt(key, data):
            from Crypto.Cipher import ARC4
            c = ARC4.new(key)
            return c.encrypt(data)

        def string_to_array(string):
            blob = [0] * len(string)

            for i in range(len(string)):
                blob[i] = ord(string[i])

            return blob

        print "Setup domain trusts with server %s" % ctx.server
        binding_options = ""  # why doesn't signing work here? w2k8r2 claims no session key
        lsaconn = lsa.lsarpc("ncacn_np:%s[%s]" % (ctx.server, binding_options),
                             ctx.lp, ctx.creds)

        objectAttr = lsa.ObjectAttribute()
        objectAttr.sec_qos = lsa.QosInfo()

        pol_handle = lsaconn.OpenPolicy2(''.decode('utf-8'), objectAttr,
                                         security.SEC_FLAG_MAXIMUM_ALLOWED)

        info = lsa.TrustDomainInfoInfoEx()
        info.domain_name.string = ctx.dnsdomain
        info.netbios_name.string = ctx.domain_name
        info.sid = security.dom_sid(ctx.domsid)
        info.trust_direction = lsa.LSA_TRUST_DIRECTION_INBOUND | lsa.LSA_TRUST_DIRECTION_OUTBOUND
        info.trust_type = lsa.LSA_TRUST_TYPE_UPLEVEL
        info.trust_attributes = lsa.LSA_TRUST_ATTRIBUTE_WITHIN_FOREST

        try:
            oldname = lsa.String()
            oldname.string = ctx.dnsdomain
            oldinfo = lsaconn.QueryTrustedDomainInfoByName(
                pol_handle, oldname, lsa.LSA_TRUSTED_DOMAIN_INFO_FULL_INFO)
            print("Removing old trust record for %s (SID %s)" %
                  (ctx.dnsdomain, oldinfo.info_ex.sid))
            lsaconn.DeleteTrustedDomain(pol_handle, oldinfo.info_ex.sid)
        except RuntimeError:
            pass

        password_blob = string_to_array(ctx.trustdom_pass.encode('utf-16-le'))

        clear_value = drsblobs.AuthInfoClear()
        clear_value.size = len(password_blob)
        clear_value.password = password_blob

        clear_authentication_information = drsblobs.AuthenticationInformation()
        clear_authentication_information.LastUpdateTime = samba.unix2nttime(
            int(time.time()))
        clear_authentication_information.AuthType = lsa.TRUST_AUTH_TYPE_CLEAR
        clear_authentication_information.AuthInfo = clear_value

        authentication_information_array = drsblobs.AuthenticationInformationArray(
        )
        authentication_information_array.count = 1
        authentication_information_array.array = [
            clear_authentication_information
        ]

        outgoing = drsblobs.trustAuthInOutBlob()
        outgoing.count = 1
        outgoing.current = authentication_information_array

        trustpass = drsblobs.trustDomainPasswords()
        confounder = [3] * 512

        for i in range(512):
            confounder[i] = random.randint(0, 255)

        trustpass.confounder = confounder

        trustpass.outgoing = outgoing
        trustpass.incoming = outgoing

        trustpass_blob = ndr_pack(trustpass)

        encrypted_trustpass = arcfour_encrypt(lsaconn.session_key,
                                              trustpass_blob)

        auth_blob = lsa.DATA_BUF2()
        auth_blob.size = len(encrypted_trustpass)
        auth_blob.data = string_to_array(encrypted_trustpass)

        auth_info = lsa.TrustDomainInfoAuthInfoInternal()
        auth_info.auth_blob = auth_blob

        trustdom_handle = lsaconn.CreateTrustedDomainEx2(
            pol_handle, info, auth_info, security.SEC_STD_DELETE)

        rec = {
            "dn": "cn=%s,cn=system,%s" % (ctx.dnsforest, ctx.base_dn),
            "objectclass": "trustedDomain",
            "trustType": str(info.trust_type),
            "trustAttributes": str(info.trust_attributes),
            "trustDirection": str(info.trust_direction),
            "flatname": ctx.forest_domain_name,
            "trustPartner": ctx.dnsforest,
            "trustAuthIncoming": ndr_pack(outgoing),
            "trustAuthOutgoing": ndr_pack(outgoing)
        }
        ctx.local_samdb.add(rec)

        rec = {
            "dn": "cn=%s$,cn=users,%s" % (ctx.forest_domain_name, ctx.base_dn),
            "objectclass": "user",
            "userAccountControl": str(samba.dsdb.UF_INTERDOMAIN_TRUST_ACCOUNT),
            "clearTextPassword": ctx.trustdom_pass.encode('utf-16-le')
        }
        ctx.local_samdb.add(rec)