xref: /freebsd/crypto/krb5/src/tests/t_referral.py (revision 7f2fe78b9dd5f51c821d771b63d2e096f6fd49e9)
1from k5test import *
2
3# Create a pair of realms, where KRBTEST1.COM can authenticate to
4# REFREALM and has a domain-realm mapping for 'd' pointing to it.
5drealm = {'domain_realm': {'d': 'REFREALM'}}
6realm, refrealm = cross_realms(2, xtgts=((0,1),),
7                               args=({'kdc_conf': drealm},
8                                     {'realm': 'REFREALM',
9                                      'create_user': False}),
10                               create_host=False)
11refrealm.addprinc('a/x.d')
12
13savefile = os.path.join(realm.testdir, 'ccache.copy')
14os.rename(realm.ccache, savefile)
15
16# Get credentials and check that we got a referral to REFREALM.
17def testref(realm, nametype):
18    shutil.copyfile(savefile, realm.ccache)
19    realm.run(['./gcred', nametype, 'a/x.d@'])
20    out = realm.run([klist]).split('\n')
21    if len(out) != 8:
22        fail('unexpected number of lines in klist output')
23    if out[5].split()[4] != 'a/x.d@' or out[6].split()[2] != 'a/x.d@REFREALM':
24        fail('unexpected service principals in klist output')
25
26# Get credentials and check that we get an error, not a referral.
27def testfail(realm, nametype):
28    shutil.copyfile(savefile, realm.ccache)
29    realm.run(['./gcred', nametype, 'a/x.d@'], expected_code=1,
30              expected_msg='not found in Kerberos database')
31
32# Create a modified KDC environment and restart the KDC.
33def restart_kdc(realm, kdc_conf):
34    env = realm.special_env('extravars', True, kdc_conf=kdc_conf)
35    realm.stop_kdc()
36    realm.start_kdc(env=env)
37
38# With no KDC configuration besides [domain_realm], we should get a
39# referral for a NT-SRV-HST or NT-SRV-INST server name, but not an
40# NT-UNKNOWN or NT-PRINCIPAL server name.
41mark('[domain-realm] only')
42testref(realm, 'srv-hst')
43testref(realm, 'srv-inst')
44testfail(realm, 'principal')
45testfail(realm, 'unknown')
46
47# With host_based_services matching the first server name component
48# ("a"), we should get a referral for an NT-UNKNOWN server name.
49# host_based_services can appear in either [kdcdefaults] or the realm
50# section, with the realm values supplementing the kdcdefaults values.
51# NT-SRV-HST server names should be unaffected by host_based_services,
52# and NT-PRINCIPAL server names shouldn't get a referral regardless.
53mark('host_based_services')
54restart_kdc(realm, {'kdcdefaults': {'host_based_services': '*'}})
55testref(realm, 'unknown')
56testfail(realm, 'principal')
57restart_kdc(realm, {'kdcdefaults': {'host_based_services': ['b', 'a,c']}})
58testref(realm, 'unknown')
59restart_kdc(realm, {'realms': {'$realm': {'host_based_services': 'a b c'}}})
60testref(realm, 'unknown')
61restart_kdc(realm, {'kdcdefaults': {'host_based_services': 'a'},
62                    'realms': {'$realm': {'host_based_services': 'b c'}}})
63testref(realm, 'unknown')
64restart_kdc(realm, {'kdcdefaults': {'host_based_services': 'b,c'},
65                    'realms': {'$realm': {'host_based_services': 'a,b'}}})
66testref(realm, 'unknown')
67restart_kdc(realm, {'kdcdefaults': {'host_based_services': 'b,c'}})
68testfail(realm, 'unknown')
69testref(realm, 'srv-hst')
70
71# With no_host_referrals matching the first server name component, we
72# should not get a referral even for NT-SRV-HOST server names
73mark('no_host_referral')
74restart_kdc(realm, {'kdcdefaults': {'no_host_referral': '*'}})
75testfail(realm, 'srv-hst')
76restart_kdc(realm, {'kdcdefaults': {'no_host_referral': ['b', 'a,c']}})
77testfail(realm, 'srv-hst')
78restart_kdc(realm, {'realms': {'$realm': {'no_host_referral': 'a b c'}}})
79testfail(realm, 'srv-hst')
80restart_kdc(realm, {'kdcdefaults': {'no_host_referral': 'a'},
81                    'realms': {'$realm': {'no_host_referral': 'b c'}}})
82testfail(realm, 'srv-hst')
83restart_kdc(realm, {'kdcdefaults': {'no_host_referral': 'b,c'},
84                    'realms': {'$realm': {'no_host_referral': 'a,b'}}})
85testfail(realm, 'srv-hst')
86restart_kdc(realm, {'kdcdefaults': {'no_host_referral': 'b,c'}})
87testref(realm, 'srv-hst')
88
89# no_host_referrals should override host_based_services for NT-UNKNWON
90# server names.
91restart_kdc(realm, {'kdcdefaults': {'no_host_referral': '*',
92                                    'host_based_services': '*'}})
93testfail(realm, 'unknown')
94
95realm.stop()
96refrealm.stop()
97
98# Regression test for #7483: a KDC should not return a host referral
99# to its own realm.
100mark('#7483 regression test')
101drealm = {'domain_realm': {'d': 'KRBTEST.COM'}}
102realm = K5Realm(kdc_conf=drealm, create_host=False)
103out, trace = realm.run(['./gcred', 'srv-hst', 'a/x.d@'], expected_code=1,
104                       return_trace=True)
105if 'back to same realm' in trace:
106    fail('KDC returned referral to service realm')
107realm.stop()
108
109# Test client referrals.  Use the test KDB module for KRBTEST1.COM to
110# simulate referrals since our built-in modules do not support them.
111# No cross-realm TGTs are necessary.
112mark('client referrals')
113kdcconf = {'realms': {'$realm': {'database_module': 'test'}},
114           'dbmodules': {'test': {'db_library': 'test',
115                                  'alias': {'user': '@KRBTEST2.COM',
116                                            'abc@XYZ': '@KRBTEST2.COM'}}}}
117r1, r2 = cross_realms(2, xtgts=(),
118                      args=({'kdc_conf': kdcconf, 'create_kdb': False}, None),
119                      create_host=False)
120r2.addprinc('abc\\@XYZ', 'pw')
121r1.start_kdc()
122r1.kinit('user', expected_code=1,
123         expected_msg='not found in Kerberos database')
124r1.kinit('user', password('user'), ['-C'])
125r1.klist('user@KRBTEST2.COM', 'krbtgt/KRBTEST2.COM')
126r1.kinit('abc@XYZ', 'pw', ['-E'])
127r1.klist('abc\\@XYZ@KRBTEST2.COM', 'krbtgt/KRBTEST2.COM')
128
129# Test that disable_encrypted_timestamp persists across client
130# referrals.  (This test relies on SPAKE not being enabled by default
131# on the KDC.)
132r2.run([kadminl, 'modprinc', '+preauth', 'user'])
133msgs = ('Encrypted timestamp (for ')
134r1.kinit('user', password('user'), ['-C'], expected_trace=msgs)
135dconf = {'realms': {'$realm': {'disable_encrypted_timestamp': 'true'}}}
136denv = r1.special_env('disable_encts', False, krb5_conf=dconf)
137msgs = ('Ignoring encrypted timestamp because it is disabled',
138        '/Encrypted timestamp is disabled')
139r1.kinit('user', None, ['-C'], env=denv, expected_code=1, expected_trace=msgs,
140         expected_msg='Encrypted timestamp is disabled')
141
142success('KDC host referral tests')
143