2 # Unix SMB/CIFS implementation.
3 # Copyright (C) Stefan Metzmacher 2020
4 # Copyright (C) 2020 Catalyst.Net Ltd
6 # This program is free software; you can redistribute it and/or modify
7 # it under the terms of the GNU General Public License as published by
8 # the Free Software Foundation; either version 3 of the License, or
9 # (at your option) any later version.
11 # This program is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 # GNU General Public License for more details.
16 # You should have received a copy of the GNU General Public License
17 # along with this program. If not, see <http://www.gnu.org/licenses/>.
23 sys.path.insert(0, "bin/python")
24 os.environ["PYTHONUNBUFFERED"] = "1"
26 from samba.tests.krb5.kdc_base_test import KDCBaseTest
27 from samba.tests.krb5.rfc4120_constants import (
28 AES256_CTS_HMAC_SHA1_96,
36 global_asn1_print = False
37 global_hexdump = False
40 class KdcTgsTests(KDCBaseTest):
44 self.do_asn1_print = global_asn1_print
45 self.do_hexdump = global_hexdump
47 def test_tgs_req_cname_does_not_not_match_authenticator_cname(self):
48 ''' Try and obtain a ticket from the TGS, but supply a cname
49 that differs from that provided to the krbtgt
51 # Create the user account
52 samdb = self.get_samdb()
53 user_name = "tsttktusr"
54 (uc, _) = self.create_account(samdb, user_name)
55 realm = uc.get_realm().lower()
57 # Do the initial AS-REQ, should get a pre-authentication required
59 etype = (AES256_CTS_HMAC_SHA1_96,)
60 cname = self.PrincipalName_create(
61 name_type=NT_PRINCIPAL, names=[user_name])
62 sname = self.PrincipalName_create(
63 name_type=NT_SRV_INST, names=["krbtgt", realm])
65 rep = self.as_req(cname, sname, realm, etype)
66 self.check_pre_authentication(rep)
69 padata = self.get_enc_timestamp_pa_data(uc, rep)
70 key = self.get_as_rep_key(uc, rep)
71 rep = self.as_req(cname, sname, realm, etype, padata=[padata])
72 self.check_as_reply(rep)
74 # Request a service ticket, but use a cname that does not match
75 # that in the original AS-REQ
76 enc_part2 = self.get_as_rep_enc_data(key, rep)
77 key = self.EncryptionKey_import(enc_part2['key'])
78 ticket = rep['ticket']
80 cname = self.PrincipalName_create(
81 name_type=NT_PRINCIPAL,
82 names=["Administrator"])
83 sname = self.PrincipalName_create(
84 name_type=NT_PRINCIPAL,
85 names=["host", samdb.host_dns_name()])
87 (rep, enc_part) = self.tgs_req(cname, sname, realm, ticket, key, etype,
88 expected_error_mode=KDC_ERR_BADMATCH,
93 "rep = {%s}, enc_part = {%s}" % (rep, enc_part))
94 self.assertEqual(KRB_ERROR, rep['msg-type'], "rep = {%s}" % rep)
100 def test_ldap_service_ticket(self):
101 '''Get a ticket to the ldap service
103 # Create the user account
104 samdb = self.get_samdb()
105 user_name = "tsttktusr"
106 (uc, _) = self.create_account(samdb, user_name)
107 realm = uc.get_realm().lower()
109 # Do the initial AS-REQ, should get a pre-authentication required
111 etype = (AES256_CTS_HMAC_SHA1_96,)
112 cname = self.PrincipalName_create(
113 name_type=NT_PRINCIPAL, names=[user_name])
114 sname = self.PrincipalName_create(
115 name_type=NT_SRV_INST, names=["krbtgt", realm])
117 rep = self.as_req(cname, sname, realm, etype)
118 self.check_pre_authentication(rep)
121 padata = self.get_enc_timestamp_pa_data(uc, rep)
122 key = self.get_as_rep_key(uc, rep)
123 rep = self.as_req(cname, sname, realm, etype, padata=[padata])
124 self.check_as_reply(rep)
126 enc_part2 = self.get_as_rep_enc_data(key, rep)
127 key = self.EncryptionKey_import(enc_part2['key'])
128 ticket = rep['ticket']
130 # Request a ticket to the ldap service
131 sname = self.PrincipalName_create(
132 name_type=NT_SRV_INST,
133 names=["ldap", samdb.host_dns_name()])
135 (rep, _) = self.tgs_req(
136 cname, sname, uc.get_realm(), ticket, key, etype,
137 service_creds=self.get_dc_creds())
139 self.check_tgs_reply(rep)
141 def test_get_ticket_for_host_service_of_machine_account(self):
143 # Create a user and machine account for the test.
145 samdb = self.get_samdb()
146 user_name = "tsttktusr"
147 (uc, dn) = self.create_account(samdb, user_name)
148 (mc, _) = self.create_account(samdb, "tsttktmac", machine_account=True)
149 realm = uc.get_realm().lower()
151 # Do the initial AS-REQ, should get a pre-authentication required
153 etype = (AES256_CTS_HMAC_SHA1_96, ARCFOUR_HMAC_MD5)
154 cname = self.PrincipalName_create(
155 name_type=NT_PRINCIPAL, names=[user_name])
156 sname = self.PrincipalName_create(
157 name_type=NT_SRV_INST, names=["krbtgt", realm])
159 rep = self.as_req(cname, sname, realm, etype)
160 self.check_pre_authentication(rep)
163 padata = self.get_enc_timestamp_pa_data(uc, rep)
164 key = self.get_as_rep_key(uc, rep)
165 rep = self.as_req(cname, sname, realm, etype, padata=[padata])
166 self.check_as_reply(rep)
168 # Request a ticket to the host service on the machine account
169 ticket = rep['ticket']
170 enc_part2 = self.get_as_rep_enc_data(key, rep)
171 key = self.EncryptionKey_import(enc_part2['key'])
172 cname = self.PrincipalName_create(
173 name_type=NT_PRINCIPAL,
175 sname = self.PrincipalName_create(
176 name_type=NT_PRINCIPAL,
177 names=[mc.get_username()])
179 (rep, enc_part) = self.tgs_req(
180 cname, sname, uc.get_realm(), ticket, key, etype,
182 self.check_tgs_reply(rep)
184 # Check the contents of the service ticket
185 ticket = rep['ticket']
186 enc_part = self.decode_service_ticket(mc, ticket)
188 pac_data = self.get_pac_data(enc_part['authorization-data'])
189 sid = self.get_objectSid(samdb, dn)
190 upn = "%s@%s" % (uc.get_username(), realm)
193 str(pac_data.account_name),
194 "rep = {%s},%s" % (rep, pac_data))
198 "rep = {%s},%s" % (rep, pac_data))
201 pac_data.domain_name,
202 "rep = {%s},%s" % (rep, pac_data))
206 "rep = {%s},%s" % (rep, pac_data))
209 pac_data.account_sid,
210 "rep = {%s},%s" % (rep, pac_data))
213 if __name__ == "__main__":
214 global_asn1_print = False
215 global_hexdump = False