From: Joseph Sutton Date: Wed, 14 Dec 2022 23:16:00 +0000 (+1300) Subject: tests/krb5: Move _test_samlogon() to base class X-Git-Tag: talloc-2.4.1~1648 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f44943b2bae99a1dde8b5d26baa6ed258b43c2e5;p=thirdparty%2Fsamba.git tests/krb5: Move _test_samlogon() to base class We'll want to make use of it in the group tests. Signed-off-by: Joseph Sutton Reviewed-by: Andrew Bartlett --- diff --git a/python/samba/tests/krb5/kdc_base_test.py b/python/samba/tests/krb5/kdc_base_test.py index e6e82503046..08c42d83aae 100644 --- a/python/samba/tests/krb5/kdc_base_test.py +++ b/python/samba/tests/krb5/kdc_base_test.py @@ -32,7 +32,7 @@ from enum import Enum from collections import namedtuple import ldb from ldb import SCOPE_BASE -from samba import common, generate_random_password +from samba import NTSTATUSError, common, generate_random_password, ntstatus from samba.auth import system_session from samba.credentials import ( Credentials, @@ -40,7 +40,17 @@ from samba.credentials import ( DONT_USE_KERBEROS, MUST_USE_KERBEROS, ) -from samba.dcerpc import drsblobs, drsuapi, misc, krb5pac, krb5ccache, security +from samba.dcerpc import ( + drsblobs, + drsuapi, + krb5ccache, + krb5pac, + misc, + netlogon, + ntlmssp, + samr, + security, +) from samba.drs_utils import drs_Replicate, drsuapi_connect from samba.dsdb import ( DSDB_SYNTAX_BINARY_DN, @@ -2328,3 +2338,91 @@ class KDCBaseTest(RawKerberosTest): return self.create_ccache_with_ticket(user_credentials, ticket, pac=pac) + + # Test SamLogon. Authentication should succeed for non-protected accounts, + # and fail for protected accounts. + def _test_samlogon(self, creds, logon_type, protected): + samdb = self.get_samdb() + + server = samdb.host_dns_name() + username, domain = creds.get_ntlm_username_domain() + workstation = 'Workstation' + + target_info = ntlmssp.AV_PAIR_LIST() + target_info.count = 3 + computername = ntlmssp.AV_PAIR() + computername.AvId = ntlmssp.MsvAvNbComputerName + computername.Value = workstation + + domainname = ntlmssp.AV_PAIR() + domainname.AvId = ntlmssp.MsvAvNbDomainName + domainname.Value = domain + + eol = ntlmssp.AV_PAIR() + eol.AvId = ntlmssp.MsvAvEOL + target_info.pair = [domainname, computername, eol] + + target_info_blob = ndr_pack(target_info) + + challenge = b'abcdefgh' + response = creds.get_ntlm_response(flags=0, + challenge=challenge, + target_info=target_info_blob) + + mach_creds = self.get_cached_creds( + account_type=self.AccountType.COMPUTER, + opts={'secure_channel_type': misc.SEC_CHAN_WKSTA}) + + conn = netlogon.netlogon(f'ncacn_ip_tcp:{server}[schannel,seal]', + self.get_lp(), + mach_creds) + + if logon_type == netlogon.NetlogonInteractiveInformation: + logon = netlogon.netr_PasswordInfo() + + lm_pass = samr.Password() + lm_pass.hash = [0] * 16 + + nt_pass = samr.Password() + nt_pass.hash = list(creds.get_nt_hash()) + mach_creds.encrypt_samr_password(nt_pass) + + logon.lmpassword = lm_pass + logon.ntpassword = nt_pass + + elif logon_type == netlogon.NetlogonNetworkInformation: + logon = netlogon.netr_NetworkInfo() + + logon.challenge = list(challenge) + logon.nt = netlogon.netr_ChallengeResponse() + logon.nt.length = len(response['nt_response']) + logon.nt.data = list(response['nt_response']) + + else: + self.fail(f'unknown logon type {logon_type}') + + identity_info = netlogon.netr_IdentityInfo() + identity_info.domain_name.string = domain + identity_info.account_name.string = username + identity_info.workstation.string = workstation + + logon.identity_info = identity_info + + validation_level = netlogon.NetlogonValidationSamInfo2 + netr_flags = 0 + + try: + conn.netr_LogonSamLogonEx(server, + mach_creds.get_workstation(), + logon_type, + logon, + validation_level, + netr_flags) + except NTSTATUSError as err: + self.assertTrue(protected, 'got unexpected error') + + num, _ = err.args + if num != ntstatus.NT_STATUS_ACCOUNT_RESTRICTION: + raise + else: + self.assertFalse(protected, 'expected error') diff --git a/python/samba/tests/krb5/protected_users_tests.py b/python/samba/tests/krb5/protected_users_tests.py index 929a90da2ef..ebda6381975 100755 --- a/python/samba/tests/krb5/protected_users_tests.py +++ b/python/samba/tests/krb5/protected_users_tests.py @@ -27,8 +27,8 @@ from functools import partial import ldb from samba import NTSTATUSError, generate_random_password, ntstatus -from samba.dcerpc import lsa, misc, netlogon, ntlmssp, samr, security -from samba.ndr import ndr_pack, ndr_unpack +from samba.dcerpc import lsa, netlogon, samr, security +from samba.ndr import ndr_unpack from samba.samdb import SamDB import samba.tests.krb5.kcrypto as kcrypto @@ -239,94 +239,6 @@ class ProtectedUsersTests(KDCBaseTest): self._test_samr_change_password(client_creds, protected=True) - # Test SamLogon. Authentication should succeed for non-protected accounts, - # and fail for protected accounts. - def _test_samlogon(self, creds, logon_type, protected): - samdb = self.get_samdb() - - server = samdb.host_dns_name() - username, domain = creds.get_ntlm_username_domain() - workstation = 'Workstation' - - target_info = ntlmssp.AV_PAIR_LIST() - target_info.count = 3 - computername = ntlmssp.AV_PAIR() - computername.AvId = ntlmssp.MsvAvNbComputerName - computername.Value = workstation - - domainname = ntlmssp.AV_PAIR() - domainname.AvId = ntlmssp.MsvAvNbDomainName - domainname.Value = domain - - eol = ntlmssp.AV_PAIR() - eol.AvId = ntlmssp.MsvAvEOL - target_info.pair = [domainname, computername, eol] - - target_info_blob = ndr_pack(target_info) - - challenge = b'abcdefgh' - response = creds.get_ntlm_response(flags=0, - challenge=challenge, - target_info=target_info_blob) - - mach_creds = self.get_cached_creds( - account_type=self.AccountType.COMPUTER, - opts={'secure_channel_type': misc.SEC_CHAN_WKSTA}) - - conn = netlogon.netlogon(f'ncacn_ip_tcp:{server}[schannel,seal]', - self.get_lp(), - mach_creds) - - if logon_type == netlogon.NetlogonInteractiveInformation: - logon = netlogon.netr_PasswordInfo() - - lm_pass = samr.Password() - lm_pass.hash = [0] * 16 - - nt_pass = samr.Password() - nt_pass.hash = list(creds.get_nt_hash()) - mach_creds.encrypt_samr_password(nt_pass) - - logon.lmpassword = lm_pass - logon.ntpassword = nt_pass - - elif logon_type == netlogon.NetlogonNetworkInformation: - logon = netlogon.netr_NetworkInfo() - - logon.challenge = list(challenge) - logon.nt = netlogon.netr_ChallengeResponse() - logon.nt.length = len(response['nt_response']) - logon.nt.data = list(response['nt_response']) - - else: - self.fail(f'unknown logon type {logon_type}') - - identity_info = netlogon.netr_IdentityInfo() - identity_info.domain_name.string = domain - identity_info.account_name.string = username - identity_info.workstation.string = workstation - - logon.identity_info = identity_info - - validation_level = netlogon.NetlogonValidationSamInfo2 - netr_flags = 0 - - try: - conn.netr_LogonSamLogonEx(server, - mach_creds.get_workstation(), - logon_type, - logon, - validation_level, - netr_flags) - except NTSTATUSError as err: - self.assertTrue(protected, 'got unexpected error') - - num, _ = err.args - if num != ntstatus.NT_STATUS_ACCOUNT_RESTRICTION: - raise - else: - self.assertFalse(protected, 'expected error') - # Test interactive SamLogon with an unprotected account. def test_samlogon_interactive_not_protected(self): client_creds = self._get_creds(protected=False,