From: Joseph Sutton Date: Thu, 1 Dec 2022 02:35:56 +0000 (+1300) Subject: tests/krb5: Test that NT_STATUS_ACCOUNT_LOCKED_OUT is returned in KDC reply e-data X-Git-Tag: talloc-2.4.1~672 X-Git-Url: http://git.samba.org/?p=samba.git;a=commitdiff_plain;h=3424c6d20fe32f7821ccd61b385189ef271e68ab tests/krb5: Test that NT_STATUS_ACCOUNT_LOCKED_OUT is returned in KDC reply e-data Certain clients rely on this behaviour. Signed-off-by: Joseph Sutton Reviewed-by: Andrew Bartlett --- diff --git a/python/samba/tests/krb5/lockout_tests.py b/python/samba/tests/krb5/lockout_tests.py index 46e516a5366..4140e4f8825 100755 --- a/python/samba/tests/krb5/lockout_tests.py +++ b/python/samba/tests/krb5/lockout_tests.py @@ -89,7 +89,8 @@ def connect_kdc(pipe, realm, workstation, dn, - expect_error=True): + expect_error=True, + expect_status=None): AsReqBaseTest.setUpClass() as_req_base = AsReqBaseTest() as_req_base.setUp() @@ -131,45 +132,87 @@ def connect_kdc(pipe, etypes = as_req_base.get_default_enctypes(user_creds) + # Remove the LDAP connection. + del type(as_req_base)._ldb + if expect_error: expected_error_modes = (KDC_ERR_CLIENT_REVOKED, KDC_ERR_PREAUTH_FAILED) + + # Wrap generic_check_kdc_error() to expect an NTSTATUS code when the + # account is locked out. + def check_error_fn(kdc_exchange_dict, + callback_dict, + rep): + error_code = rep.get('error-code') + if error_code == KDC_ERR_CLIENT_REVOKED: + # The account was locked out. + if expect_status: + # Expect to get a LOCKED_OUT NTSTATUS code. + kdc_exchange_dict['expect_edata'] = True + kdc_exchange_dict['expect_status'] = True + kdc_exchange_dict['expected_status'] = ( + ntstatus.NT_STATUS_ACCOUNT_LOCKED_OUT) + + elif error_code == KDC_ERR_PREAUTH_FAILED: + # Just a wrong password: the account wasn’t locked out. Don’t + # expect an NTSTATUS code. + kdc_exchange_dict['expect_status'] = False + + # Continue with the generic error-checking logic. + return as_req_base.generic_check_kdc_error( + kdc_exchange_dict, + callback_dict, + rep) + + check_rep_fn = None else: expected_error_modes = 0 - # Remove the LDAP connection. - del type(as_req_base)._ldb + check_error_fn = None + check_rep_fn = as_req_base.generic_check_kdc_rep - # Indicate that we're ready. This ensures we hit the right transaction - # lock. - pipe.send_bytes(b'0') + def _generate_padata_copy(_kdc_exchange_dict, + _callback_dict, + req_body): + return padata, req_body - # Wait for the main process to take out a transaction lock. - if not pipe.poll(timeout=5): - raise AssertionError('main process failed to indicate readiness') - - # Try making a Kerberos AS-REQ to the KDC. This should fail, either due to - # the user's account being locked out or due to using the wrong password. - as_rep, kdc_exchange_dict = as_req_base._test_as_exchange( + kdc_exchange_dict = as_req_base.as_exchange_dict( creds=user_creds, - cname=cname, - realm=realm, - sname=sname, - till=till, - expected_error_mode=expected_error_modes, expected_crealm=realm, expected_cname=cname, expected_srealm=realm, expected_sname=sname, - expected_salt=expected_salt, - etypes=etypes, - padata=padata, - kdc_options=kdc_options, - expected_supported_etypes=krbtgt_supported_etypes, expected_account_name=user_name, - preauth_key=preauth_key, + expected_supported_etypes=krbtgt_supported_etypes, ticket_decryption_key=krbtgt_decryption_key, + generate_padata_fn=_generate_padata_copy, + check_error_fn=check_error_fn, + check_rep_fn=check_rep_fn, + check_kdc_private_fn=as_req_base.generic_check_kdc_private, + expected_error_mode=expected_error_modes, + expected_salt=expected_salt, + preauth_key=preauth_key, + kdc_options=str(kdc_options), pac_request=True) + + # Indicate that we're ready. This ensures we hit the right transaction + # lock. + pipe.send_bytes(b'0') + + # Wait for the main process to take out a transaction lock. + if not pipe.poll(timeout=5): + raise AssertionError('main process failed to indicate readiness') + + # Try making a Kerberos AS-REQ to the KDC. This might fail, either due to + # the user's account being locked out or due to using the wrong password. + as_rep = as_req_base._generic_kdc_exchange(kdc_exchange_dict, + cname=cname, + realm=realm, + sname=sname, + till_time=till, + etypes=etypes) + as_req_base.assertIsNotNone(as_rep) msg_type = as_rep['msg-type'] @@ -564,6 +607,9 @@ class LockoutTests(KDCBaseTest): def test_lockout_transaction_kdc(self): self.do_lockout_transaction(connect_kdc) + def test_lockout_transaction_kdc_ntstatus(self): + self.do_lockout_transaction(partial(connect_kdc, expect_status=True)) + def test_lockout_transaction_ntlm(self): self.do_lockout_transaction(connect_ntlm) @@ -588,6 +634,10 @@ class LockoutTests(KDCBaseTest): def test_lockout_transaction_rename_kdc(self): self.do_lockout_transaction(connect_kdc, rename=True) + def test_lockout_transaction_rename_kdc_ntstatus(self): + self.do_lockout_transaction(partial(connect_kdc, expect_status=True), + rename=True) + def test_lockout_transaction_rename_ntlm(self): self.do_lockout_transaction(connect_ntlm, rename=True) @@ -597,6 +647,10 @@ class LockoutTests(KDCBaseTest): def test_lockout_transaction_bad_pwd_kdc(self): self.do_lockout_transaction(connect_kdc, correct_pw=False) + def test_lockout_transaction_bad_pwd_kdc_ntstatus(self): + self.do_lockout_transaction(partial(connect_kdc, expect_status=True), + correct_pw=False) + def test_lockout_transaction_bad_pwd_ntlm(self): self.do_lockout_transaction(connect_ntlm, correct_pw=False) @@ -640,6 +694,9 @@ class LockoutTests(KDCBaseTest): def test_lockout_race_kdc(self): self.do_lockout_race(connect_kdc) + def test_lockout_race_kdc_ntstatus(self): + self.do_lockout_race(partial(connect_kdc, expect_status=True)) + def test_lockout_race_ntlm(self): self.do_lockout_race(connect_ntlm) diff --git a/selftest/knownfail_heimdal_kdc b/selftest/knownfail_heimdal_kdc index b998f234285..8174c267f6f 100644 --- a/selftest/knownfail_heimdal_kdc +++ b/selftest/knownfail_heimdal_kdc @@ -57,6 +57,13 @@ # ^samba.tests.krb5.protected_users_tests.samba.tests.krb5.protected_users_tests.ProtectedUsersTests.test_samr_change_password_protected.ad_dc # +# Lockout tests +# +^samba.tests.krb5.lockout_tests.samba.tests.krb5.lockout_tests.LockoutTests.test_lockout_race_kdc_ntstatus.ad_dc:local +^samba.tests.krb5.lockout_tests.samba.tests.krb5.lockout_tests.LockoutTests.test_lockout_transaction_bad_pwd_kdc_ntstatus.ad_dc:local +^samba.tests.krb5.lockout_tests.samba.tests.krb5.lockout_tests.LockoutTests.test_lockout_transaction_kdc_ntstatus.ad_dc:local +^samba.tests.krb5.lockout_tests.samba.tests.krb5.lockout_tests.LockoutTests.test_lockout_transaction_rename_kdc_ntstatus.ad_dc:local +# # Group tests # ^samba.tests.krb5.group_tests.samba.tests.krb5.group_tests.GroupTests.test_group_nested_group_addition_compression_tgs_req_to_service.ad_dc diff --git a/selftest/knownfail_mit_kdc b/selftest/knownfail_mit_kdc index 5daca97ef9f..35b4ea11c37 100644 --- a/selftest/knownfail_mit_kdc +++ b/selftest/knownfail_mit_kdc @@ -480,9 +480,13 @@ samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_ ^samba.tests.krb5.lockout_tests.samba.tests.krb5.lockout_tests.LockoutTests.test_bad_pwd_count_transaction_kdc.ad_dc:local ^samba.tests.krb5.lockout_tests.samba.tests.krb5.lockout_tests.LockoutTests.test_bad_pwd_count_transaction_rename_kdc.ad_dc:local ^samba.tests.krb5.lockout_tests.samba.tests.krb5.lockout_tests.LockoutTests.test_lockout_race_kdc.ad_dc:local +^samba.tests.krb5.lockout_tests.samba.tests.krb5.lockout_tests.LockoutTests.test_lockout_race_kdc_ntstatus.ad_dc:local ^samba.tests.krb5.lockout_tests.samba.tests.krb5.lockout_tests.LockoutTests.test_lockout_transaction_bad_pwd_kdc.ad_dc:local +^samba.tests.krb5.lockout_tests.samba.tests.krb5.lockout_tests.LockoutTests.test_lockout_transaction_bad_pwd_kdc_ntstatus.ad_dc:local ^samba.tests.krb5.lockout_tests.samba.tests.krb5.lockout_tests.LockoutTests.test_lockout_transaction_kdc.ad_dc:local +^samba.tests.krb5.lockout_tests.samba.tests.krb5.lockout_tests.LockoutTests.test_lockout_transaction_kdc_ntstatus.ad_dc:local ^samba.tests.krb5.lockout_tests.samba.tests.krb5.lockout_tests.LockoutTests.test_lockout_transaction_rename_kdc.ad_dc:local +^samba.tests.krb5.lockout_tests.samba.tests.krb5.lockout_tests.LockoutTests.test_lockout_transaction_rename_kdc_ntstatus.ad_dc:local # # Encryption type tests #