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))
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"])
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
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'
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
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))
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"])
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()
def __init__(self, url): self.url = url self.ldb = Ldb(self.url) self.nttime = samba.unix2nttime(int(time.time()))
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)