def setUp(self): super(AuthLogTestsNetLogon, self).setUp() self.lp = samba.tests.env_loadparm() self.creds = Credentials() self.session = system_session() self.ldb = SamDB(session_info=self.session, credentials=self.creds, lp=self.lp) self.domain = os.environ["DOMAIN"] self.netbios_name = "NetLogonGood" self.machinepass = "******" self.remoteAddress = AS_SYSTEM_MAGIC_PATH_TOKEN self.base_dn = self.ldb.domain_dn() self.dn = ("cn=%s,cn=users,%s" % (self.netbios_name, self.base_dn)) utf16pw = text_type('"' + self.machinepass + '"').encode('utf-16-le') self.ldb.add({ "dn": self.dn, "objectclass": "computer", "sAMAccountName": "%s$" % self.netbios_name, "userAccountControl": str(UF_WORKSTATION_TRUST_ACCOUNT | UF_PASSWD_NOTREQD), "unicodePwd": utf16pw })
def get_supplemental_creds_drs(self): binding_str = "ncacn_ip_tcp:%s[seal]" % os.environ["SERVER"] dn = "cn=" + USER_NAME + ",cn=users," + self.base_dn drs = drsuapi.drsuapi(binding_str, self.get_loadparm(), self.creds) (drs_handle, supported_extensions) = drs_utils.drs_DsBind(drs) req8 = drsuapi.DsGetNCChangesRequest8() null_guid = misc.GUID() req8.destination_dsa_guid = null_guid req8.source_dsa_invocation_id = null_guid req8.naming_context = drsuapi.DsReplicaObjectIdentifier() req8.naming_context.dn = text_type(dn) req8.highwatermark = drsuapi.DsReplicaHighWaterMark() req8.highwatermark.tmp_highest_usn = 0 req8.highwatermark.reserved_usn = 0 req8.highwatermark.highest_usn = 0 req8.uptodateness_vector = None req8.replica_flags = (drsuapi.DRSUAPI_DRS_INIT_SYNC | drsuapi.DRSUAPI_DRS_PER_SYNC | drsuapi.DRSUAPI_DRS_GET_ANC | drsuapi.DRSUAPI_DRS_NEVER_SYNCED | drsuapi.DRSUAPI_DRS_WRIT_REP) req8.max_object_count = 402 req8.max_ndr_size = 402116 req8.extended_op = drsuapi.DRSUAPI_EXOP_REPL_OBJ req8.fsmo_info = 0 req8.partial_attribute_set = None req8.partial_attribute_set_ex = None req8.mapping_ctr.num_mappings = 0 req8.mapping_ctr.mappings = None (level, ctr) = drs.DsGetNCChanges(drs_handle, 8, req8) obj_item = ctr.first_object obj = obj_item.object sc_blob = None for i in range(0, obj.attribute_ctr.num_attributes): attr = obj.attribute_ctr.attributes[i] if attid_equal(attr.attid, drsuapi.DRSUAPI_ATTID_supplementalCredentials): net_ctx = net.Net(self.creds) net_ctx.replicate_decrypt(drs, attr, 0) sc_blob = attr.value_ctr.values[0].blob sc = ndr_unpack(drsblobs.supplementalCredentialsBlob, sc_blob) return sc
def setpassword(self, search_filter, password, force_change_at_next_login=False, username=None): """Sets the password for a user :param search_filter: LDAP filter to find the user (eg samccountname=name) :param password: Password for the user :param force_change_at_next_login: Force password change """ self.transaction_start() try: res = self.search(base=self.domain_dn(), scope=ldb.SCOPE_SUBTREE, expression=search_filter, attrs=[]) if len(res) == 0: raise Exception('Unable to find user "%s"' % (username or search_filter)) if len(res) > 1: raise Exception('Matched %u multiple users with filter "%s"' % (len(res), search_filter)) user_dn = res[0].dn pw = text_type(b'"' + password.encode('utf-8') + b'"', 'utf-8').encode('utf-16-le') setpw = """ dn: %s changetype: modify replace: unicodePwd unicodePwd:: %s """ % (user_dn, base64.b64encode(pw).decode('utf-8')) self.modify_ldif(setpw) if force_change_at_next_login: self.force_password_change_at_next_login( "(distinguishedName=" + str(user_dn) + ")") # modify the userAccountControl to remove the disabled bit self.enable_account(search_filter) except: self.transaction_cancel() raise else: self.transaction_commit()
def _drs_fetch_pfm(server, samdb, creds, lp): """Fetch prefixMap using DRS interface""" binding_str = "ncacn_ip_tcp:%s[print,seal]" % server drs = drsuapi.drsuapi(binding_str, lp, creds) (drs_handle, supported_extensions) = drs_DsBind(drs) print("DRS Handle: %s" % drs_handle) req8 = drsuapi.DsGetNCChangesRequest8() dest_dsa = misc.GUID("9c637462-5b8c-4467-aef2-bdb1f57bc4ef") replica_flags = 0 req8.destination_dsa_guid = dest_dsa req8.source_dsa_invocation_id = misc.GUID(samdb.get_invocation_id()) req8.naming_context = drsuapi.DsReplicaObjectIdentifier() req8.naming_context.dn = text_type(samdb.get_schema_basedn()) req8.highwatermark = drsuapi.DsReplicaHighWaterMark() req8.highwatermark.tmp_highest_usn = 0 req8.highwatermark.reserved_usn = 0 req8.highwatermark.highest_usn = 0 req8.uptodateness_vector = None req8.replica_flags = replica_flags req8.max_object_count = 0 req8.max_ndr_size = 402116 req8.extended_op = 0 req8.fsmo_info = 0 req8.partial_attribute_set = None req8.partial_attribute_set_ex = None req8.mapping_ctr.num_mappings = 0 req8.mapping_ctr.mappings = None (level, ctr) = drs.DsGetNCChanges(drs_handle, 8, req8) pfm = ctr.mapping_ctr # check for schemaInfo element pfm_it = pfm.mappings[-1] assert pfm_it.id_prefix == 0 assert pfm_it.oid.length == 21 s = '' for x in pfm_it.oid.binary_oid: s += chr(x) pfm_schi = ndr_unpack(drsblobs.schemaInfoBlob, s) assert pfm_schi.marker == 0xFF # remove schemaInfo element pfm.num_mappings -= 1 return (pfm, pfm_schi)
def _test_samlogon(self, binding, creds, checkFunction): def isLastExpectedMessage(msg): return ( msg["type"] == "Authentication" and msg["Authentication"]["serviceDescription"] == "SamLogon" and msg["Authentication"]["authDescription"] == "network" and msg["Authentication"]["passwordType"] == "NTLMv2" and (msg["Authentication"]["eventId"] == EVT_ID_SUCCESSFUL_LOGON) and (msg["Authentication"]["logonType"] == EVT_LOGON_NETWORK)) if binding: binding = "[schannel,%s]" % binding else: binding = "[schannel]" utf16pw = text_type('"' + self.machinepass + '"').encode('utf-16-le') self.ldb.add({ "dn": self.samlogon_dn, "objectclass": "computer", "sAMAccountName": "%s$" % self.netbios_name, "userAccountControl": str(UF_WORKSTATION_TRUST_ACCOUNT | UF_PASSWD_NOTREQD), "unicodePwd": utf16pw}) machine_creds = Credentials() machine_creds.guess(self.get_loadparm()) machine_creds.set_secure_channel_type(SEC_CHAN_WKSTA) machine_creds.set_password(self.machinepass) machine_creds.set_username(self.netbios_name + "$") netlogon_conn = netlogon.netlogon("ncalrpc:%s" % binding, self.get_loadparm(), machine_creds) challenge = b"abcdefgh" target_info = ntlmssp.AV_PAIR_LIST() target_info.count = 3 domainname = ntlmssp.AV_PAIR() domainname.AvId = ntlmssp.MsvAvNbDomainName domainname.Value = self.domain computername = ntlmssp.AV_PAIR() computername.AvId = ntlmssp.MsvAvNbComputerName computername.Value = self.netbios_name eol = ntlmssp.AV_PAIR() eol.AvId = ntlmssp.MsvAvEOL target_info.pair = [domainname, computername, eol] target_info_blob = ndr_pack(target_info) response = creds.get_ntlm_response(flags=CLI_CRED_NTLMv2_AUTH, challenge=challenge, target_info=target_info_blob) netr_flags = 0 logon_level = netlogon.NetlogonNetworkTransitiveInformation logon = samba.dcerpc.netlogon.netr_NetworkInfo() logon.challenge = [x if isinstance(x,int) else ord(x) for x in challenge] logon.nt = netlogon.netr_ChallengeResponse() logon.nt.length = len(response["nt_response"]) logon.nt.data = [x if isinstance(x,int) else ord(x) for x in response["nt_response"]] logon.identity_info = samba.dcerpc.netlogon.netr_IdentityInfo() (username, domain) = creds.get_ntlm_username_domain() logon.identity_info.domain_name.string = domain logon.identity_info.account_name.string = username logon.identity_info.workstation.string = creds.get_workstation() validation_level = samba.dcerpc.netlogon.NetlogonValidationSamInfo4 result = netlogon_conn.netr_LogonSamLogonEx( os.environ["SERVER"], machine_creds.get_workstation(), logon_level, logon, validation_level, netr_flags) (validation, authoritative, netr_flags_out) = result messages = self.waitForMessages(isLastExpectedMessage, netlogon_conn) checkFunction(messages)