2 Unix SMB/CIFS implementation.
4 Validate the krb5 pac generation routines
6 Copyright (C) Andrew Bartlett <abartlet@samba.org> 2005-2015
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program. If not, see <http://www.gnu.org/licenses/>.
24 #include "system/kerberos.h"
25 #include "torture/smbtorture.h"
26 #include "torture/krb5/proto.h"
27 #include "auth/credentials/credentials.h"
28 #include "lib/cmdline/popt_common.h"
29 #include "source4/auth/kerberos/kerberos.h"
30 #include "source4/auth/kerberos/kerberos_util.h"
31 #include "lib/util/util_net.h"
33 #define TEST_CANONICALIZE 0x0000001
34 #define TEST_ENTERPRISE 0x0000002
35 #define TEST_UPPER_REALM 0x0000004
36 #define TEST_UPPER_USERNAME 0x0000008
37 #define TEST_NETBIOS_REALM 0x0000010
38 #define TEST_WIN2K 0x0000020
39 #define TEST_UPN 0x0000040
40 #define TEST_ALL 0x000007F
43 const char *test_name
;
45 const char *real_realm
;
46 const char *real_domain
;
48 const char *real_username
;
56 bool other_upn_suffix
;
57 const char *krb5_service
;
58 const char *krb5_hostname
;
63 TEST_TGS_REQ_KRBTGT_CANON
,
65 TEST_SELF_TRUST_TGS_REQ
,
73 struct torture_krb5_context
{
74 struct smb_krb5_context
*smb_krb5_context
;
75 struct torture_context
*tctx
;
76 struct addrinfo
*server
;
77 struct test_data
*test_data
;
79 enum test_stage test_stage
;
88 * TEST_AS_REQ and TEST_AS_REQ_SELF - SEND
90 * Confirm that the outgoing packet meets certain expectations. This
91 * should be extended to further assert the correct and expected
92 * behaviour of the krb5 libs, so we know what we are sending to the
95 * Additionally, this CHANGES the request to remove the canonicalize
96 * flag automatically added by the krb5 libs when an enterprise
97 * principal is used, so we can test what the server does in this
102 static bool torture_krb5_pre_send_as_req_test(struct torture_krb5_context
*test_context
,
103 const krb5_data
*send_buf
,
104 krb5_data
*modified_send_buf
)
107 krb5_error_code k5ret
;
109 torture_assert_int_equal(test_context
->tctx
, decode_AS_REQ(send_buf
->data
, send_buf
->length
,
110 &test_context
->as_req
, &used
),
111 0, "decode_AS_REQ for TEST_AS_REQ failed");
112 mod_as_req
= test_context
->as_req
;
113 torture_assert_int_equal(test_context
->tctx
, used
, send_buf
->length
, "length mismatch");
114 torture_assert_int_equal(test_context
->tctx
, test_context
->as_req
.pvno
,
115 5, "Got wrong as_req->pvno");
116 if (test_context
->test_data
->canonicalize
|| test_context
->test_data
->enterprise
) {
117 torture_assert(test_context
->tctx
,
118 test_context
->as_req
.req_body
.kdc_options
.canonicalize
,
119 "krb5 libs did not set canonicalize!");
121 torture_assert_int_equal(test_context
->tctx
,
122 test_context
->as_req
.req_body
.kdc_options
.canonicalize
,
124 "krb5 libs unexpectedly set canonicalize!");
127 if (test_context
->test_data
->enterprise
) {
128 torture_assert_int_equal(test_context
->tctx
,
129 test_context
->as_req
.req_body
.cname
->name_type
,
130 KRB5_NT_ENTERPRISE_PRINCIPAL
,
131 "krb5 libs did not pass principal as enterprise!");
133 torture_assert_int_equal(test_context
->tctx
,
134 test_context
->as_req
.req_body
.cname
->name_type
,
136 "krb5 libs unexpectedly set principal as enterprise!");
139 /* Force off canonicalize that was forced on by the krb5 libs */
140 if (test_context
->test_data
->canonicalize
== false && test_context
->test_data
->enterprise
) {
141 mod_as_req
.req_body
.kdc_options
.canonicalize
= false;
144 if (test_context
->test_stage
== TEST_AS_REQ_SELF
) {
146 * Force the server name to match the client name,
147 * including the name type. This isn't possible with
148 * the krb5 client libs alone
150 mod_as_req
.req_body
.sname
= test_context
->as_req
.req_body
.cname
;
153 ASN1_MALLOC_ENCODE(AS_REQ
, modified_send_buf
->data
, modified_send_buf
->length
,
154 &mod_as_req
, &used
, k5ret
);
155 torture_assert_int_equal(test_context
->tctx
,
157 "encode_AS_REQ failed");
159 if (test_context
->test_stage
!= TEST_AS_REQ_SELF
) {
160 torture_assert_int_equal(test_context
->tctx
, used
, send_buf
->length
,
161 "re-encode length mismatch");
169 * Confirm that the reply packet from the KDC meets certain
170 * expectations as part of TEST_AS_REQ. This uses a packet count to
171 * work out what packet we are up to in the multiple exchanged
172 * triggerd by krb5_get_init_creds_password().
176 static bool torture_krb5_post_recv_as_req_test(struct torture_krb5_context
*test_context
,
177 const krb5_data
*recv_buf
)
181 if (test_context
->packet_count
== 0) {
182 krb5_error_code k5ret
;
184 * The client libs obtain the salt by attempting to
185 * authenticate without pre-authentication and getting
186 * the correct salt with the
187 * KRB5KDC_ERR_PREAUTH_REQUIRED error. If we are in
188 * the test (netbios_realm && upn) that deliberatly
189 * has an incorrect principal, we check we get the
192 k5ret
= decode_KRB_ERROR(recv_buf
->data
, recv_buf
->length
,
196 k5ret
= decode_AS_REP(recv_buf
->data
, recv_buf
->length
,
199 if (test_context
->test_data
->netbios_realm
&& test_context
->test_data
->upn
) {
200 torture_assert(test_context
->tctx
, false,
201 "expected to get a KRB_ERROR packet with "
202 "KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN, got valid AS-REP");
204 torture_assert(test_context
->tctx
, false,
205 "expected to get a KRB_ERROR packet with "
206 "KRB5KDC_ERR_PREAUTH_REQUIRED, got valid AS-REP");
209 if (test_context
->test_data
->netbios_realm
&& test_context
->test_data
->upn
) {
210 torture_assert(test_context
->tctx
, false,
211 "unable to decode as KRB-ERROR or AS-REP, "
212 "expected to get a KRB_ERROR packet with KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN");
214 torture_assert(test_context
->tctx
, false,
215 "unable to decode as KRB-ERROR or AS-REP, "
216 "expected to get a KRB_ERROR packet with KRB5KDC_ERR_PREAUTH_REQUIRED");
220 torture_assert_int_equal(test_context
->tctx
, used
, recv_buf
->length
,
222 torture_assert_int_equal(test_context
->tctx
, error
.pvno
, 5,
223 "Got wrong error.pvno");
224 if (test_context
->test_data
->netbios_realm
&& test_context
->test_data
->upn
) {
225 torture_assert_int_equal(test_context
->tctx
,
227 KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN
- KRB5KDC_ERR_NONE
,
228 "Got wrong error.error_code");
230 torture_assert_int_equal(test_context
->tctx
,
232 KRB5KDC_ERR_PREAUTH_REQUIRED
- KRB5KDC_ERR_NONE
,
233 "Got wrong error.error_code");
236 free_KRB_ERROR(&error
);
237 } else if ((decode_KRB_ERROR(recv_buf
->data
, recv_buf
->length
, &error
, &used
) == 0)
238 && (test_context
->packet_count
== 1)) {
240 * The Windows 2012R2 KDC will always respond with
241 * KRB5KRB_ERR_RESPONSE_TOO_BIG over UDP as the ticket
242 * won't fit, because of the PAC. (It appears to do
243 * this always, even if it will). This triggers the
244 * client to try again over TCP.
246 torture_assert_int_equal(test_context
->tctx
,
247 used
, recv_buf
->length
,
249 torture_assert_int_equal(test_context
->tctx
,
251 "Got wrong error.pvno");
252 torture_assert_int_equal(test_context
->tctx
,
254 KRB5KRB_ERR_RESPONSE_TOO_BIG
- KRB5KDC_ERR_NONE
,
255 "Got wrong error.error_code");
256 free_KRB_ERROR(&error
);
259 * Finally the successful packet.
261 torture_assert_int_equal(test_context
->tctx
,
262 decode_AS_REP(recv_buf
->data
, recv_buf
->length
,
263 &test_context
->as_rep
, &used
), 0,
264 "decode_AS_REP failed");
265 torture_assert_int_equal(test_context
->tctx
, used
, recv_buf
->length
,
267 torture_assert_int_equal(test_context
->tctx
,
268 test_context
->as_rep
.pvno
, 5,
269 "Got wrong as_rep->pvno");
270 torture_assert_int_equal(test_context
->tctx
,
271 test_context
->as_rep
.ticket
.tkt_vno
, 5,
272 "Got wrong as_rep->ticket.tkt_vno");
273 torture_assert(test_context
->tctx
,
274 test_context
->as_rep
.ticket
.enc_part
.kvno
,
275 "Did not get a KVNO in test_context->as_rep.ticket.enc_part.kvno");
278 * We can confirm that the correct proxy behaviour is
279 * in use on the KDC by checking the KVNO of the
280 * krbtgt account returned in the reply.
282 * A packet passed to the full RW DC will not have a
283 * KVNO in the upper bits, while a packet processed
284 * locally on the RODC will have these bits filled in
285 * the msDS-SecondaryKrbTgtNumber
287 if (torture_setting_bool(test_context
->tctx
, "expect_cached_at_rodc", false)) {
288 torture_assert_int_not_equal(test_context
->tctx
,
289 *test_context
->as_rep
.ticket
.enc_part
.kvno
& 0xFFFF0000,
290 0, "Did not get a RODC number in the KVNO");
292 torture_assert_int_equal(test_context
->tctx
,
293 *test_context
->as_rep
.ticket
.enc_part
.kvno
& 0xFFFF0000,
294 0, "Unexpecedly got a RODC number in the KVNO");
296 free_AS_REP(&test_context
->as_rep
);
298 torture_assert(test_context
->tctx
, test_context
->packet_count
< 3, "too many packets");
299 free_AS_REQ(&test_context
->as_req
);
304 * TEST_TGS_REQ_KRBTGT_CANON
307 * Confirm that the outgoing TGS-REQ packet from krb5_get_creds()
308 * for the krbtgt/realm principal meets certain expectations, like
309 * that the canonicalize bit is not set
313 static bool torture_krb5_pre_send_tgs_req_krbtgt_canon_test(struct torture_krb5_context
*test_context
, const krb5_data
*send_buf
, krb5_data
*modified_send_buf
)
316 torture_assert_int_equal(test_context
->tctx
,
317 decode_TGS_REQ(send_buf
->data
, send_buf
->length
,
318 &test_context
->tgs_req
, &used
),
319 0, "decode_TGS_REQ for TEST_TGS_REQ test failed");
320 torture_assert_int_equal(test_context
->tctx
,
321 used
, send_buf
->length
,
323 torture_assert_int_equal(test_context
->tctx
,
324 test_context
->tgs_req
.pvno
, 5,
325 "Got wrong as_req->pvno");
326 torture_assert_int_equal(test_context
->tctx
,
327 test_context
->tgs_req
.req_body
.kdc_options
.canonicalize
,
329 "krb5 libs unexpectedly did not set canonicalize!");
331 torture_assert_int_equal(test_context
->tctx
,
332 test_context
->tgs_req
.req_body
.sname
->name_type
,
334 "Mismatch in name_type between request and expected request");
336 torture_assert_str_equal(test_context
->tctx
,
337 test_context
->tgs_req
.req_body
.realm
,
338 test_context
->test_data
->real_realm
,
339 "Mismatch in realm between request and expected request");
341 *modified_send_buf
= *send_buf
;
346 * TEST_TGS_REQ_KRBTGT_CANON
348 * Confirm that the reply TGS-REP packet for krb5_get_creds()
349 * where the client is behaving as if this is a cross-realm trust due
350 * to case or netbios vs dns name differences meets certain
351 * expectations, while canonicalize is set
355 static bool torture_krb5_post_recv_tgs_req_krbtgt_canon_test(struct torture_krb5_context
*test_context
, const krb5_data
*recv_buf
)
358 torture_assert_int_equal(test_context
->tctx
,
359 decode_TGS_REP(recv_buf
->data
, recv_buf
->length
,
360 &test_context
->tgs_rep
, &used
),
362 "decode_TGS_REP failed");
363 torture_assert_int_equal(test_context
->tctx
, used
, recv_buf
->length
, "length mismatch");
364 torture_assert_int_equal(test_context
->tctx
,
365 test_context
->tgs_rep
.pvno
, 5,
366 "Got wrong as_rep->pvno");
367 torture_assert_int_equal(test_context
->tctx
,
368 test_context
->tgs_rep
.ticket
.tkt_vno
, 5,
369 "Got wrong as_rep->ticket.tkt_vno");
370 torture_assert(test_context
->tctx
,
371 test_context
->tgs_rep
.ticket
.enc_part
.kvno
,
372 "Did not get a KVNO in test_context->as_rep.ticket.enc_part.kvno");
373 torture_assert_str_equal(test_context
->tctx
,
374 test_context
->tgs_req
.req_body
.realm
,
375 test_context
->tgs_rep
.ticket
.realm
,
376 "Mismatch in realm between request and ticket response");
377 torture_assert_str_equal(test_context
->tctx
,
378 test_context
->tgs_rep
.ticket
.realm
,
379 test_context
->test_data
->real_realm
,
380 "Mismatch in realm between ticket response and expected ticket response");
381 torture_assert_int_equal(test_context
->tctx
,
382 test_context
->tgs_rep
.ticket
.sname
.name_type
,
384 "Mismatch in name_type between ticket response and expected value of KRB5_NT_SRV_INST");
386 torture_assert_int_equal(test_context
->tctx
,
387 test_context
->tgs_rep
.ticket
.sname
.name_string
.len
,
389 "Mismatch in name_type between ticket response and expected value, expected krbtgt/REALM@REALM");
391 torture_assert_str_equal(test_context
->tctx
,
392 test_context
->tgs_rep
.ticket
.sname
.name_string
.val
[0], "krbtgt",
393 "Mismatch in name between reponse and expected response, expected krbtgt");
394 torture_assert_str_equal(test_context
->tctx
,
395 test_context
->tgs_rep
.ticket
.sname
.name_string
.val
[1], test_context
->test_data
->real_realm
,
396 "Mismatch in realm part of krbtgt/ in expected response, expected krbtgt/REALM@REALM");
399 * We can confirm that the correct proxy behaviour is
400 * in use on the KDC by checking the KVNO of the
401 * krbtgt account returned in the reply.
403 * A packet passed to the full RW DC will not have a
404 * KVNO in the upper bits, while a packet processed
405 * locally on the RODC will have these bits filled in
406 * the msDS-SecondaryKrbTgtNumber
408 if (torture_setting_bool(test_context
->tctx
, "expect_cached_at_rodc", false)) {
409 torture_assert_int_not_equal(test_context
->tctx
,
410 *test_context
->tgs_rep
.ticket
.enc_part
.kvno
& 0xFFFF0000,
411 0, "Did not get a RODC number in the KVNO");
413 torture_assert_int_equal(test_context
->tctx
,
414 *test_context
->tgs_rep
.ticket
.enc_part
.kvno
& 0xFFFF0000,
415 0, "Unexpecedly got a RODC number in the KVNO");
417 free_TGS_REP(&test_context
->tgs_rep
);
418 torture_assert(test_context
->tctx
,
419 test_context
->packet_count
< 2,
421 free_TGS_REQ(&test_context
->tgs_req
);
428 * Confirm that the outgoing TGS-REQ packet from krb5_get_creds
429 * certain expectations, like that the canonicalize bit is set (this
430 * test is to force that handling) and that if an enterprise name was
431 * requested, that it was sent.
435 static bool torture_krb5_pre_send_tgs_req_canon_test(struct torture_krb5_context
*test_context
,
436 const krb5_data
*send_buf
,
437 krb5_data
*modified_send_buf
)
440 torture_assert_int_equal(test_context
->tctx
,
441 decode_TGS_REQ(send_buf
->data
, send_buf
->length
,
442 &test_context
->tgs_req
, &used
),
443 0, "decode_TGS_REQ for TEST_TGS_REQ_CANON test failed");
444 torture_assert_int_equal(test_context
->tctx
, used
, send_buf
->length
, "length mismatch");
445 torture_assert_int_equal(test_context
->tctx
, test_context
->tgs_req
.pvno
, 5, "Got wrong as_req->pvno");
446 torture_assert_int_equal(test_context
->tctx
,
447 test_context
->tgs_req
.req_body
.kdc_options
.canonicalize
,
448 true, "krb5 libs unexpectedly did not set canonicalize!");
450 if (test_context
->test_data
->enterprise
) {
451 torture_assert_int_equal(test_context
->tctx
,
452 test_context
->tgs_req
.req_body
.sname
->name_type
, KRB5_NT_ENTERPRISE_PRINCIPAL
,
453 "Mismatch in name type between request and expected request, expected KRB5_NT_ENTERPRISE_PRINCIPAL");
454 torture_assert_str_equal(test_context
->tctx
,
455 test_context
->tgs_req
.req_body
.realm
, test_context
->test_data
->real_realm
,
456 "Mismatch in realm between request and expected request");
458 } else if (test_context
->test_data
->canonicalize
) {
459 torture_assert_int_equal(test_context
->tctx
,
460 test_context
->tgs_req
.req_body
.sname
->name_type
, KRB5_NT_PRINCIPAL
,
461 "Mismatch in name type between request and expected request, expected KRB5_NT_PRINCIPAL");
462 torture_assert_str_equal(test_context
->tctx
,
463 test_context
->tgs_req
.req_body
.realm
, test_context
->test_data
->real_realm
,
464 "Mismatch in realm between request and expected request");
467 torture_assert_int_equal(test_context
->tctx
,
468 test_context
->tgs_req
.req_body
.sname
->name_type
, KRB5_NT_PRINCIPAL
,
469 "Mismatch in name type between request and expected request, expected KRB5_NT_PRINCIPAL");
470 torture_assert_str_equal(test_context
->tctx
,
471 test_context
->tgs_req
.req_body
.realm
, test_context
->test_data
->realm
,
472 "Mismatch in realm between request and expected request");
476 *modified_send_buf
= *send_buf
;
482 * TEST_TGS_REQ_CANON - RECV
484 * Confirm that the reply TGS-REP or error packet from the KDC meets
485 * certain expectations as part of TEST_TGS_REQ_CANON.
487 * This is triggered by krb5_get_creds()
491 static bool torture_krb5_post_recv_tgs_req_canon_test(struct torture_krb5_context
*test_context
, const krb5_data
*recv_buf
)
497 * If this account did not have a servicePrincipalName, then
498 * we expect a errro packet, not a TGS-REQ
500 if (decode_KRB_ERROR(recv_buf
->data
, recv_buf
->length
, &error
, &used
) == 0) {
501 torture_assert_int_equal(test_context
->tctx
, used
, recv_buf
->length
, "length mismatch");
502 torture_assert_int_equal(test_context
->tctx
,
504 "Got wrong error.pvno");
505 torture_assert_int_equal(test_context
->tctx
,
507 KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN
- KRB5KDC_ERR_NONE
,
508 "Got wrong error.error_code");
510 torture_assert_int_equal(test_context
->tctx
,
511 decode_TGS_REP(recv_buf
->data
, recv_buf
->length
,
512 &test_context
->tgs_rep
,
515 "decode_TGS_REP failed");
516 torture_assert_int_equal(test_context
->tctx
,
517 used
, recv_buf
->length
,
519 torture_assert_int_equal(test_context
->tctx
,
520 test_context
->tgs_rep
.pvno
, 5,
521 "Got wrong as_rep->pvno");
522 torture_assert_int_equal(test_context
->tctx
,
523 test_context
->tgs_rep
.ticket
.tkt_vno
, 5,
524 "Got wrong as_rep->ticket.tkt_vno");
525 torture_assert(test_context
->tctx
,
526 test_context
->tgs_rep
.ticket
.enc_part
.kvno
,
527 "Did not get a KVNO in test_context->as_rep.ticket.enc_part.kvno");
528 torture_assert_str_equal(test_context
->tctx
,
529 test_context
->tgs_rep
.ticket
.realm
,
530 test_context
->test_data
->real_realm
,
531 "Mismatch in realm between ticket response and expected upper case REALM");
532 torture_assert_int_equal(test_context
->tctx
,
533 test_context
->tgs_rep
.ticket
.sname
.name_type
,
534 test_context
->tgs_req
.req_body
.sname
->name_type
,
535 "Mismatch in name_type between request and ticket response");
536 torture_assert_int_equal(test_context
->tctx
,
537 test_context
->tgs_rep
.ticket
.sname
.name_string
.len
,
538 test_context
->tgs_req
.req_body
.sname
->name_string
.len
,
539 "Mismatch in name_string.len between request and ticket response");
540 torture_assert(test_context
->tctx
,
541 test_context
->tgs_rep
.ticket
.sname
.name_string
.len
>= 1,
542 "name_string.len should be >=1 in ticket response");
543 torture_assert_str_equal(test_context
->tctx
,
544 test_context
->tgs_rep
.ticket
.sname
.name_string
.val
[0],
545 test_context
->tgs_req
.req_body
.sname
->name_string
.val
[0],
546 "Mismatch in name between request and expected request");
547 torture_assert_int_equal(test_context
->tctx
,
548 *test_context
->tgs_rep
.ticket
.enc_part
.kvno
& 0xFFFF0000,
549 0, "Unexpecedly got a RODC number in the KVNO, should just be principal KVNO");
550 free_TGS_REP(&test_context
->tgs_rep
);
552 torture_assert(test_context
->tctx
, test_context
->packet_count
== 0, "too many packets");
553 free_TGS_REQ(&test_context
->tgs_req
);
559 * TEST_SELF_TRUST_TGS_REQ
561 * Confirm that the outgoing TGS-REQ packet from krb5_mk_req_exact()
562 * certain expectations, like that the canonicalize bit is set (this
563 * test is to force that handling).
565 * This test is for the case where the name we ask for, while a valid
566 * alternate name for our own realm is used. The client acts as if
567 * this is cross-realm trust.
571 static bool torture_krb5_pre_send_self_trust_tgs_req_test(struct torture_krb5_context
*test_context
,
572 const krb5_data
*send_buf
,
573 krb5_data
*modified_send_buf
)
576 torture_assert_int_equal(test_context
->tctx
,
577 decode_TGS_REQ(send_buf
->data
, send_buf
->length
,
578 &test_context
->tgs_req
, &used
),
579 0, "decode_TGS_REQ for TEST_SELF_TRUST_TGS_REQ test failed");
580 torture_assert_int_equal(test_context
->tctx
, used
, send_buf
->length
, "length mismatch");
581 torture_assert_int_equal(test_context
->tctx
, test_context
->tgs_req
.pvno
, 5, "Got wrong as_req->pvno");
582 torture_assert_int_equal(test_context
->tctx
, test_context
->tgs_req
.req_body
.kdc_options
.canonicalize
, false, "krb5 libs unexpectedly set canonicalize!");
584 if (test_context
->test_data
->canonicalize
) {
585 torture_assert_str_equal(test_context
->tctx
,
586 test_context
->tgs_req
.req_body
.realm
,
587 test_context
->test_data
->real_realm
,
588 "Mismatch in realm between request and expected request");
590 torture_assert_str_equal(test_context
->tctx
,
591 test_context
->tgs_req
.req_body
.realm
,
592 test_context
->test_data
->realm
,
593 "Mismatch in realm between request and expected request");
595 torture_assert_int_equal(test_context
->tctx
,
596 test_context
->tgs_req
.req_body
.sname
->name_type
, KRB5_NT_PRINCIPAL
,
597 "Mismatch in name type between request and expected request, expected KRB5_NT_PRINCIPAL");
598 torture_assert_int_equal(test_context
->tctx
,
599 test_context
->tgs_req
.req_body
.sname
->name_string
.len
, 2,
600 "Mismatch in name between request and expected request, expected krbtgt/realm");
601 torture_assert_str_equal(test_context
->tctx
,
602 test_context
->tgs_req
.req_body
.sname
->name_string
.val
[0], "krbtgt",
603 "Mismatch in name between request and expected request, expected krbtgt");
604 torture_assert_str_equal(test_context
->tctx
,
605 test_context
->tgs_req
.req_body
.sname
->name_string
.val
[1], test_context
->test_data
->realm
,
606 "Mismatch in realm part of cross-realm request principal between request and expected request");
607 *modified_send_buf
= *send_buf
;
613 * TEST_SELF_TRUST_TGS_REQ and TEST_TGS_REQ_KRBTGT - RECV
615 * Confirm that the reply TGS-REP packet for krb5_mk_req_exact(),
616 * where the client is behaving as if this is a cross-realm trust due
617 * to case or netbios vs dns name differences meets certain
622 static bool torture_krb5_post_recv_self_trust_tgs_req_test(struct torture_krb5_context
*test_context
, const krb5_data
*recv_buf
)
625 torture_assert_int_equal(test_context
->tctx
,
626 decode_TGS_REP(recv_buf
->data
, recv_buf
->length
,
627 &test_context
->tgs_rep
, &used
),
629 "decode_TGS_REP failed");
630 torture_assert_int_equal(test_context
->tctx
, used
, recv_buf
->length
, "length mismatch");
631 torture_assert_int_equal(test_context
->tctx
,
632 test_context
->tgs_rep
.pvno
, 5,
633 "Got wrong as_rep->pvno");
634 torture_assert_int_equal(test_context
->tctx
,
635 test_context
->tgs_rep
.ticket
.tkt_vno
, 5,
636 "Got wrong as_rep->ticket.tkt_vno");
637 torture_assert(test_context
->tctx
,
638 test_context
->tgs_rep
.ticket
.enc_part
.kvno
,
639 "Did not get a KVNO in test_context->as_rep.ticket.enc_part.kvno");
640 torture_assert_str_equal(test_context
->tctx
,
641 test_context
->tgs_req
.req_body
.realm
,
642 test_context
->tgs_rep
.ticket
.realm
,
643 "Mismatch in realm between request and ticket response");
644 torture_assert_int_equal(test_context
->tctx
,
645 test_context
->tgs_rep
.ticket
.sname
.name_type
,
646 test_context
->tgs_req
.req_body
.sname
->name_type
,
647 "Mismatch in name_type between request and ticket response");
649 torture_assert_int_equal(test_context
->tctx
,
650 test_context
->tgs_rep
.ticket
.sname
.name_string
.len
, 2,
651 "Mismatch in name between request and expected request, expected krbtgt/realm");
652 torture_assert_str_equal(test_context
->tctx
,
653 test_context
->tgs_rep
.ticket
.sname
.name_string
.val
[0], "krbtgt",
654 "Mismatch in name between request and expected request, expected krbtgt");
655 torture_assert_str_equal(test_context
->tctx
,
656 test_context
->tgs_rep
.ticket
.sname
.name_string
.val
[1], test_context
->test_data
->realm
,
657 "Mismatch in realm part of cross-realm request principal between response and expected request");
659 * We can confirm that the correct proxy behaviour is
660 * in use on the KDC by checking the KVNO of the
661 * krbtgt account returned in the reply.
663 * A packet passed to the full RW DC will not have a
664 * KVNO in the upper bits, while a packet processed
665 * locally on the RODC will have these bits filled in
666 * the msDS-SecondaryKrbTgtNumber
668 if (torture_setting_bool(test_context
->tctx
, "expect_cached_at_rodc", false)) {
669 torture_assert_int_not_equal(test_context
->tctx
,
670 *test_context
->tgs_rep
.ticket
.enc_part
.kvno
& 0xFFFF0000,
671 0, "Did not get a RODC number in the KVNO");
673 torture_assert_int_equal(test_context
->tctx
,
674 *test_context
->tgs_rep
.ticket
.enc_part
.kvno
& 0xFFFF0000,
675 0, "Unexpecedly got a RODC number in the KVNO");
677 free_TGS_REP(&test_context
->tgs_rep
);
678 torture_assert_int_equal(test_context
->tctx
,
679 test_context
->packet_count
, 0,
681 test_context
->packet_count
= 0;
682 test_context
->test_stage
= TEST_TGS_REQ
;
683 free_TGS_REQ(&test_context
->tgs_req
);
690 * Confirm that the outgoing TGS-REQ packet from krb5_mk_req_exact()
691 * certain expectations, like that the canonicalize bit is set (this
692 * test is to force that handling) and that if an enterprise name was
693 * requested, that it was sent.
697 static bool torture_krb5_pre_send_tgs_req_test(struct torture_krb5_context
*test_context
, const krb5_data
*send_buf
, krb5_data
*modified_send_buf
)
700 torture_assert_int_equal(test_context
->tctx
,
701 decode_TGS_REQ(send_buf
->data
, send_buf
->length
,
702 &test_context
->tgs_req
, &used
),
703 0, "decode_TGS_REQ for TEST_TGS_REQ test failed");
704 torture_assert_int_equal(test_context
->tctx
, used
, send_buf
->length
, "length mismatch");
705 torture_assert_int_equal(test_context
->tctx
, test_context
->tgs_req
.pvno
, 5,
706 "Got wrong as_req->pvno");
707 torture_assert_int_equal(test_context
->tctx
,
708 test_context
->tgs_req
.req_body
.kdc_options
.canonicalize
,
710 "krb5 libs unexpectedly set canonicalize!");
712 if (test_context
->test_data
->enterprise
) {
713 torture_assert_int_equal(test_context
->tctx
,
714 test_context
->tgs_req
.req_body
.sname
->name_type
,
715 KRB5_NT_ENTERPRISE_PRINCIPAL
,
716 "Mismatch in name type between request and expected request, expected KRB5_NT_ENTERPRISE_PRINCIPAL");
717 torture_assert_str_equal(test_context
->tctx
,
718 test_context
->tgs_req
.req_body
.realm
,
719 test_context
->test_data
->real_realm
,
720 "Mismatch in realm between request and expected request");
723 torture_assert_int_equal(test_context
->tctx
,
724 test_context
->tgs_req
.req_body
.sname
->name_type
,
726 "Mismatch in name type between request and expected request, expected KRB5_NT_PRINCIPAL");
727 torture_assert_str_equal(test_context
->tctx
,
728 test_context
->tgs_req
.req_body
.realm
,
729 test_context
->test_data
->realm
,
730 "Mismatch in realm between request and expected request");
734 *modified_send_buf
= *send_buf
;
740 * TEST_TGS_REQ - RECV
742 * Confirm that the reply TGS-REP packet for krb5_mk_req_exact(), for
743 * the actual target service.
747 static bool torture_krb5_post_recv_tgs_req_test(struct torture_krb5_context
*test_context
, const krb5_data
*recv_buf
)
752 * If this account did not have a servicePrincipalName, then
753 * we expect a errro packet, not a TGS-REQ
755 if (decode_KRB_ERROR(recv_buf
->data
, recv_buf
->length
, &error
, &used
) == 0) {
756 torture_assert_int_equal(test_context
->tctx
,
757 used
, recv_buf
->length
,
759 torture_assert_int_equal(test_context
->tctx
,
761 "Got wrong error.pvno");
762 torture_assert_int_equal(test_context
->tctx
,
764 KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN
- KRB5KDC_ERR_NONE
,
765 "Got wrong error.error_code");
767 torture_assert_int_equal(test_context
->tctx
,
768 decode_TGS_REP(recv_buf
->data
, recv_buf
->length
,
769 &test_context
->tgs_rep
, &used
),
771 "decode_TGS_REP failed");
772 torture_assert_int_equal(test_context
->tctx
, used
, recv_buf
->length
,
774 torture_assert_int_equal(test_context
->tctx
,
775 test_context
->tgs_rep
.pvno
, 5,
776 "Got wrong as_rep->pvno");
777 torture_assert_int_equal(test_context
->tctx
,
778 test_context
->tgs_rep
.ticket
.tkt_vno
, 5,
779 "Got wrong as_rep->ticket.tkt_vno");
780 torture_assert(test_context
->tctx
,
781 test_context
->tgs_rep
.ticket
.enc_part
.kvno
,
782 "Did not get a KVNO in test_context->as_rep.ticket.enc_part.kvno");
783 torture_assert_str_equal(test_context
->tctx
,
784 test_context
->tgs_rep
.ticket
.realm
,
785 test_context
->test_data
->real_realm
,
786 "Mismatch in realm between ticket response and expected upper case REALM");
787 torture_assert_int_equal(test_context
->tctx
,
788 test_context
->tgs_req
.req_body
.sname
->name_type
,
789 test_context
->tgs_rep
.ticket
.sname
.name_type
, "Mismatch in name_type between request and ticket response");
790 torture_assert_int_equal(test_context
->tctx
,
791 *test_context
->tgs_rep
.ticket
.enc_part
.kvno
& 0xFFFF0000,
792 0, "Unexpecedly got a RODC number in the KVNO, should just be principal KVNO");
793 free_TGS_REP(&test_context
->tgs_rep
);
795 torture_assert(test_context
->tctx
, test_context
->packet_count
< 3, "too many packets");
796 free_TGS_REQ(&test_context
->tgs_req
);
797 test_context
->test_stage
= TEST_DONE
;
802 * TEST_TGS_REQ_KRBTGT
805 * Confirm that the outgoing TGS-REQ packet from krb5_mk_req_exact()
806 * for the krbtgt/realm principal meets certain expectations, like
807 * that the canonicalize bit is not set
811 static bool torture_krb5_pre_send_tgs_req_krbtgt_test(struct torture_krb5_context
*test_context
, const krb5_data
*send_buf
, krb5_data
*modified_send_buf
)
814 torture_assert_int_equal(test_context
->tctx
,
815 decode_TGS_REQ(send_buf
->data
, send_buf
->length
,
816 &test_context
->tgs_req
, &used
),
817 0, "decode_TGS_REQ for TEST_TGS_REQ test failed");
818 torture_assert_int_equal(test_context
->tctx
,
819 used
, send_buf
->length
,
821 torture_assert_int_equal(test_context
->tctx
,
822 test_context
->tgs_req
.pvno
, 5,
823 "Got wrong as_req->pvno");
824 torture_assert_int_equal(test_context
->tctx
,
825 test_context
->tgs_req
.req_body
.kdc_options
.canonicalize
,
827 "krb5 libs unexpectedly set canonicalize!");
829 torture_assert_str_equal(test_context
->tctx
,
830 test_context
->tgs_req
.req_body
.realm
,
831 test_context
->test_data
->realm
,
832 "Mismatch in realm between request and expected request");
834 *modified_send_buf
= *send_buf
;
835 test_context
->test_stage
= TEST_DONE
;
843 * Confirm that the outgoing TGS-REQ packet from krb5_mk_req_exact()
844 * for the krbtgt/realm principal meets certain expectations, like
845 * that the canonicalize bit is not set
849 static bool torture_krb5_pre_send_tgs_req_host_test(struct torture_krb5_context
*test_context
, const krb5_data
*send_buf
, krb5_data
*modified_send_buf
)
852 torture_assert_int_equal(test_context
->tctx
,
853 decode_TGS_REQ(send_buf
->data
, send_buf
->length
,
854 &test_context
->tgs_req
, &used
),
855 0, "decode_TGS_REQ for TEST_TGS_REQ test failed");
856 torture_assert_int_equal(test_context
->tctx
,
857 used
, send_buf
->length
,
859 torture_assert_int_equal(test_context
->tctx
,
860 test_context
->tgs_req
.pvno
, 5,
861 "Got wrong as_req->pvno");
862 torture_assert_int_equal(test_context
->tctx
,
863 test_context
->tgs_req
.req_body
.kdc_options
.canonicalize
,
865 "krb5 libs unexpectedly did not set canonicalize!");
867 torture_assert_int_equal(test_context
->tctx
,
868 test_context
->tgs_req
.req_body
.sname
->name_type
, KRB5_NT_PRINCIPAL
,
869 "Mismatch in name type between request and expected request, expected KRB5_NT_PRINCIPAL");
870 torture_assert_int_equal(test_context
->tctx
,
871 test_context
->tgs_req
.req_body
.sname
->name_string
.len
, 2,
872 "Mismatch in name between request and expected request, expected krbtgt/realm");
873 torture_assert_str_equal(test_context
->tctx
,
874 test_context
->tgs_req
.req_body
.sname
->name_string
.val
[0],
875 test_context
->test_data
->krb5_service
,
876 "Mismatch in name between request and expected request, expected krbtgt");
877 torture_assert_str_equal(test_context
->tctx
,
878 test_context
->tgs_req
.req_body
.sname
->name_string
.val
[1],
879 test_context
->test_data
->krb5_hostname
,
880 "Mismatch in realm part of cross-realm request principal between request and expected request");
882 torture_assert_str_equal(test_context
->tctx
,
883 test_context
->tgs_req
.req_body
.realm
,
884 test_context
->test_data
->real_realm
,
885 "Mismatch in realm between request and expected request");
887 *modified_send_buf
= *send_buf
;
892 * TEST_TGS_REQ_HOST - RECV
894 * Confirm that the reply TGS-REP packet for krb5_mk_req(), for
895 * the actual target service, as a SPN, not a any other name type.
899 static bool torture_krb5_post_recv_tgs_req_host_test(struct torture_krb5_context
*test_context
, const krb5_data
*recv_buf
)
902 torture_assert_int_equal(test_context
->tctx
,
903 decode_TGS_REP(recv_buf
->data
, recv_buf
->length
,
904 &test_context
->tgs_rep
, &used
),
906 "decode_TGS_REP failed");
907 torture_assert_int_equal(test_context
->tctx
, used
, recv_buf
->length
,
909 torture_assert_int_equal(test_context
->tctx
,
910 test_context
->tgs_rep
.pvno
, 5,
911 "Got wrong as_rep->pvno");
912 torture_assert_int_equal(test_context
->tctx
,
913 test_context
->tgs_rep
.ticket
.tkt_vno
, 5,
914 "Got wrong as_rep->ticket.tkt_vno");
915 torture_assert(test_context
->tctx
,
916 test_context
->tgs_rep
.ticket
.enc_part
.kvno
,
917 "Did not get a KVNO in test_context->as_rep.ticket.enc_part.kvno");
918 torture_assert_str_equal(test_context
->tctx
,
919 test_context
->tgs_rep
.ticket
.realm
,
920 test_context
->test_data
->real_realm
,
921 "Mismatch in realm between ticket response and expected upper case REALM");
922 torture_assert_int_equal(test_context
->tctx
,
923 test_context
->tgs_req
.req_body
.sname
->name_type
,
924 test_context
->tgs_rep
.ticket
.sname
.name_type
, "Mismatch in name_type between request and ticket response");
925 torture_assert_int_equal(test_context
->tctx
,
926 test_context
->tgs_rep
.ticket
.sname
.name_string
.len
, 2,
927 "Mismatch in name between request and expected request, expected service/hostname");
928 torture_assert_str_equal(test_context
->tctx
,
929 test_context
->tgs_rep
.ticket
.sname
.name_string
.val
[0],
930 test_context
->test_data
->krb5_service
,
931 "Mismatch in name between request and expected request, expected service/hostname");
932 torture_assert_str_equal(test_context
->tctx
,
933 test_context
->tgs_rep
.ticket
.sname
.name_string
.val
[1],
934 test_context
->test_data
->krb5_hostname
,
935 "Mismatch in name between request and expected request, expected service/hostname");
937 torture_assert_int_equal(test_context
->tctx
,
938 *test_context
->tgs_rep
.ticket
.enc_part
.kvno
& 0xFFFF0000,
939 0, "Unexpecedly got a RODC number in the KVNO, should just be principal KVNO");
940 free_TGS_REP(&test_context
->tgs_rep
);
942 torture_assert(test_context
->tctx
, test_context
->packet_count
< 2, "too many packets");
947 * TEST_AS_REQ_SELF - RECV
949 * Confirm that the reply packet from the KDC meets certain
950 * expectations as part of TEST_AS_REQ. This uses a packet count to
951 * work out what packet we are up to in the multiple exchanged
952 * triggerd by krb5_get_init_creds_password().
956 static bool torture_krb5_post_recv_as_req_self_test(struct torture_krb5_context
*test_context
,
957 const krb5_data
*recv_buf
)
961 if (test_context
->packet_count
== 0) {
962 krb5_error_code k5ret
;
964 * The client libs obtain the salt by attempting to
965 * authenticate without pre-authentication and getting
966 * the correct salt with the
967 * KRB5KDC_ERR_PREAUTH_REQUIRED error. If we are in
968 * the test (netbios_realm && upn) that deliberatly
969 * has an incorrect principal, we check we get the
972 k5ret
= decode_KRB_ERROR(recv_buf
->data
, recv_buf
->length
,
976 k5ret
= decode_AS_REP(recv_buf
->data
, recv_buf
->length
,
979 if (torture_setting_bool(test_context
->tctx
, "expect_machine_account", false) == false
980 || (test_context
->test_data
->upn
== true)) {
981 torture_assert(test_context
->tctx
, false,
982 "expected to get a KRB_ERROR packet with "
983 "KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN or KRB5KDC_ERR_PREAUTH_REQUIRED, got valid AS-REP");
985 torture_assert(test_context
->tctx
, false,
986 "expected to get a KRB_ERROR packet with "
987 "KRB5KDC_ERR_PREAUTH_REQUIRED, got valid AS-REP");
990 if (torture_setting_bool(test_context
->tctx
, "expect_machine_account", false) == false
991 || (test_context
->test_data
->upn
== true)) {
992 torture_assert(test_context
->tctx
, false,
993 "unable to decode as KRB-ERROR or AS-REP, "
994 "expected to get a KRB_ERROR packet with KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN or KRB5KDC_ERR_PREAUTH_REQUIRED");
996 torture_assert(test_context
->tctx
, false,
997 "unable to decode as KRB-ERROR or AS-REP, "
998 "expected to get a KRB_ERROR packet with KRB5KDC_ERR_PREAUTH_REQUIRED");
1002 torture_assert_int_equal(test_context
->tctx
, used
, recv_buf
->length
,
1004 torture_assert_int_equal(test_context
->tctx
, error
.pvno
, 5,
1005 "Got wrong error.pvno");
1006 if ((torture_setting_bool(test_context
->tctx
, "expect_machine_account", false) == false
1007 || (test_context
->test_data
->upn
== true))
1008 && error
.error_code
== KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN
- KRB5KDC_ERR_NONE
) {
1012 * This case is because Samba's Heimdal KDC
1013 * checks server and client accounts before
1014 * checking for pre-authentication.
1017 torture_assert_int_equal(test_context
->tctx
,
1019 KRB5KDC_ERR_PREAUTH_REQUIRED
- KRB5KDC_ERR_NONE
,
1020 "Got wrong error.error_code");
1023 free_KRB_ERROR(&error
);
1024 } else if ((decode_KRB_ERROR(recv_buf
->data
, recv_buf
->length
, &error
, &used
) == 0)
1025 && (test_context
->packet_count
== 1)) {
1027 * The Windows 2012R2 KDC will always respond with
1028 * KRB5KRB_ERR_RESPONSE_TOO_BIG over UDP as the ticket
1029 * won't fit, because of the PAC. (It appears to do
1030 * this always, even if it will). This triggers the
1031 * client to try again over TCP.
1033 torture_assert_int_equal(test_context
->tctx
,
1034 used
, recv_buf
->length
,
1036 torture_assert_int_equal(test_context
->tctx
,
1038 "Got wrong error.pvno");
1039 if ((torture_setting_bool(test_context
->tctx
, "expect_machine_account", false)
1040 && (test_context
->test_data
->upn
== false))) {
1041 torture_assert_int_equal(test_context
->tctx
,
1043 KRB5KRB_ERR_RESPONSE_TOO_BIG
- KRB5KDC_ERR_NONE
,
1044 "Got wrong error.error_code");
1046 torture_assert_int_equal(test_context
->tctx
,
1048 KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN
- KRB5KDC_ERR_NONE
,
1049 "Got wrong error.error_code");
1051 free_KRB_ERROR(&error
);
1054 * Finally the successful packet.
1056 torture_assert_int_equal(test_context
->tctx
,
1057 decode_AS_REP(recv_buf
->data
, recv_buf
->length
,
1058 &test_context
->as_rep
, &used
), 0,
1059 "decode_AS_REP failed");
1060 torture_assert_int_equal(test_context
->tctx
, used
, recv_buf
->length
,
1062 torture_assert_int_equal(test_context
->tctx
,
1063 test_context
->as_rep
.pvno
, 5,
1064 "Got wrong as_rep->pvno");
1065 torture_assert_int_equal(test_context
->tctx
,
1066 test_context
->as_rep
.ticket
.tkt_vno
, 5,
1067 "Got wrong as_rep->ticket.tkt_vno");
1068 torture_assert(test_context
->tctx
,
1069 test_context
->as_rep
.ticket
.enc_part
.kvno
,
1070 "Did not get a KVNO in test_context->as_rep.ticket.enc_part.kvno");
1073 * We do not expect an RODC number here in the KVNO,
1074 * as this is a ticket to the user's own account.
1076 torture_assert_int_equal(test_context
->tctx
,
1077 *test_context
->as_rep
.ticket
.enc_part
.kvno
& 0xFFFF0000,
1078 0, "Unexpecedly got a RODC number in the KVNO");
1079 free_AS_REP(&test_context
->as_rep
);
1081 torture_assert(test_context
->tctx
, test_context
->packet_count
< 3, "too many packets");
1082 free_AS_REQ(&test_context
->as_req
);
1087 * This function is set in torture_krb5_init_context_canon as krb5
1088 * send_and_recv function. This allows us to override what server the
1089 * test is aimed at, and to inspect the packets just before they are
1090 * sent to the network, and before they are processed on the recv
1093 * The torture_krb5_pre_send_test() and torture_krb5_post_recv_test()
1094 * functions are implement the actual tests.
1096 * When this asserts, the caller will get a spurious 'cannot contact
1100 static krb5_error_code
smb_krb5_send_and_recv_func_canon_override(krb5_context context
,
1101 void *data
, /* struct torture_krb5_context */
1102 krb5_krbhst_info
*hi
,
1104 const krb5_data
*send_buf
,
1105 krb5_data
*recv_buf
)
1107 krb5_error_code k5ret
;
1109 krb5_data modified_send_buf
;
1111 struct torture_krb5_context
*test_context
1112 = talloc_get_type_abort(data
, struct torture_krb5_context
);
1114 switch (test_context
->test_stage
) {
1116 torture_warning(test_context
->tctx
, "Unexpected outgoing packet from krb5 libs");
1119 ok
= torture_krb5_pre_send_as_req_test(test_context
, send_buf
,
1120 &modified_send_buf
);
1122 case TEST_TGS_REQ_KRBTGT_CANON
:
1123 ok
= torture_krb5_pre_send_tgs_req_krbtgt_canon_test(test_context
, send_buf
,
1124 &modified_send_buf
);
1126 case TEST_TGS_REQ_CANON
:
1127 ok
= torture_krb5_pre_send_tgs_req_canon_test(test_context
, send_buf
,
1128 &modified_send_buf
);
1130 case TEST_SELF_TRUST_TGS_REQ
:
1131 ok
= torture_krb5_pre_send_self_trust_tgs_req_test(test_context
, send_buf
,
1132 &modified_send_buf
);
1135 ok
= torture_krb5_pre_send_tgs_req_test(test_context
, send_buf
,
1136 &modified_send_buf
);
1138 case TEST_TGS_REQ_KRBTGT
:
1139 ok
= torture_krb5_pre_send_tgs_req_krbtgt_test(test_context
, send_buf
,
1140 &modified_send_buf
);
1142 case TEST_TGS_REQ_HOST
:
1143 ok
= torture_krb5_pre_send_tgs_req_host_test(test_context
, send_buf
,
1144 &modified_send_buf
);
1146 case TEST_AS_REQ_SELF
:
1147 ok
= torture_krb5_pre_send_as_req_test(test_context
, send_buf
,
1148 &modified_send_buf
);
1155 k5ret
= smb_krb5_send_and_recv_func_forced(context
, test_context
->server
,
1156 hi
, timeout
, &modified_send_buf
,
1162 switch (test_context
->test_stage
) {
1164 torture_warning(test_context
->tctx
, "Unexpected outgoing packet from krb5 libs");
1167 ok
= torture_krb5_post_recv_as_req_test(test_context
, recv_buf
);
1169 case TEST_TGS_REQ_KRBTGT_CANON
:
1170 ok
= torture_krb5_post_recv_tgs_req_krbtgt_canon_test(test_context
, recv_buf
);
1172 case TEST_TGS_REQ_CANON
:
1173 ok
= torture_krb5_post_recv_tgs_req_canon_test(test_context
, recv_buf
);
1175 case TEST_SELF_TRUST_TGS_REQ
:
1176 ok
= torture_krb5_post_recv_self_trust_tgs_req_test(test_context
, recv_buf
);
1179 ok
= torture_krb5_post_recv_tgs_req_test(test_context
, recv_buf
);
1181 case TEST_TGS_REQ_KRBTGT
:
1182 ok
= torture_krb5_post_recv_self_trust_tgs_req_test(test_context
, recv_buf
);
1184 case TEST_TGS_REQ_HOST
:
1185 ok
= torture_krb5_post_recv_tgs_req_host_test(test_context
, recv_buf
);
1187 case TEST_AS_REQ_SELF
:
1188 ok
= torture_krb5_post_recv_as_req_self_test(test_context
, recv_buf
);
1195 test_context
->packet_count
++;
1200 static int test_context_destructor(struct torture_krb5_context
*test_context
)
1202 freeaddrinfo(test_context
->server
);
1207 static bool torture_krb5_init_context_canon(struct torture_context
*tctx
,
1208 struct test_data
*test_data
,
1209 struct torture_krb5_context
**torture_krb5_context
)
1211 const char *host
= torture_setting_string(tctx
, "host", NULL
);
1212 krb5_error_code k5ret
;
1215 struct torture_krb5_context
*test_context
= talloc_zero(tctx
, struct torture_krb5_context
);
1216 torture_assert(tctx
, test_context
!= NULL
, "Failed to allocate");
1218 test_context
->test_data
= test_data
;
1219 test_context
->tctx
= tctx
;
1221 k5ret
= smb_krb5_init_context(test_context
, tctx
->lp_ctx
, &test_context
->smb_krb5_context
);
1222 torture_assert_int_equal(tctx
, k5ret
, 0, "smb_krb5_init_context failed");
1224 ok
= interpret_string_addr_internal(&test_context
->server
, host
, AI_NUMERICHOST
);
1225 torture_assert(tctx
, ok
, "Failed to parse target server");
1227 talloc_set_destructor(test_context
, test_context_destructor
);
1229 set_sockaddr_port(test_context
->server
->ai_addr
, 88);
1231 k5ret
= krb5_set_send_to_kdc_func(test_context
->smb_krb5_context
->krb5_context
,
1232 smb_krb5_send_and_recv_func_canon_override
,
1234 torture_assert_int_equal(tctx
, k5ret
, 0, "krb5_set_send_to_kdc_func failed");
1235 *torture_krb5_context
= test_context
;
1240 static bool torture_krb5_as_req_canon(struct torture_context
*tctx
, const void *tcase_data
)
1242 krb5_error_code k5ret
;
1243 krb5_get_init_creds_opt
*krb_options
= NULL
;
1244 struct test_data
*test_data
= talloc_get_type_abort(tcase_data
, struct test_data
);
1245 krb5_principal principal
;
1246 krb5_principal krbtgt_other
;
1247 krb5_principal expected_principal
;
1248 char *principal_string
;
1249 char *krbtgt_other_string
;
1250 int principal_flags
;
1251 char *expected_principal_string
;
1252 int expected_principal_flags
;
1253 char *got_principal_string
;
1254 char *assertion_message
;
1255 const char *password
= cli_credentials_get_password(cmdline_credentials
);
1256 krb5_context k5_context
;
1257 struct torture_krb5_context
*test_context
;
1259 krb5_creds my_creds
;
1260 krb5_creds
*server_creds
;
1262 krb5_auth_context auth_context
;
1264 krb5_data in_data
, enc_ticket
;
1265 krb5_get_creds_opt opt
;
1267 const char *upn
= torture_setting_string(tctx
, "krb5-upn", "");
1268 test_data
->krb5_service
= torture_setting_string(tctx
, "krb5-service", "host");
1269 test_data
->krb5_hostname
= torture_setting_string(tctx
, "krb5-hostname", "");
1272 * If we have not passed a UPN on the command line,
1273 * then skip the UPN tests.
1275 if (test_data
->upn
&& upn
[0] == '\0') {
1276 torture_skip(tctx
, "This test needs a UPN specified as --option=torture:krb5-upn=user@example.com to run");
1279 if (test_data
->netbios_realm
) {
1280 test_data
->realm
= test_data
->real_domain
;
1282 test_data
->realm
= test_data
->real_realm
;
1285 if (test_data
->upn
) {
1287 test_data
->username
= talloc_strdup(test_data
, upn
);
1288 p
= strchr(test_data
->username
, '@');
1294 * Test the UPN behaviour carefully. We can
1295 * test in two different modes, depending on
1296 * what UPN has been set up for us.
1298 * If the UPN is in our realm, then we do all the tests with this name also.
1300 * If the UPN is not in our realm, then we
1301 * expect the tests that replace the realm to
1302 * fail (as it won't match)
1304 if (strcasecmp(p
, test_data
->real_realm
) != 0) {
1305 test_data
->other_upn_suffix
= true;
1307 test_data
->other_upn_suffix
= false;
1311 * This lets us test the combination of the UPN prefix
1312 * with a valid domain, without adding even more
1315 if (test_data
->netbios_realm
== false) {
1316 test_data
->realm
= p
;
1320 ok
= torture_krb5_init_context_canon(tctx
, test_data
, &test_context
);
1321 torture_assert(tctx
, ok
, "torture_krb5_init_context failed");
1322 k5_context
= test_context
->smb_krb5_context
->krb5_context
;
1324 if (test_data
->upper_realm
) {
1325 test_data
->realm
= strupper_talloc(test_data
, test_data
->realm
);
1327 test_data
->realm
= strlower_talloc(test_data
, test_data
->realm
);
1329 if (test_data
->upper_username
) {
1330 test_data
->username
= strupper_talloc(test_data
, test_data
->username
);
1332 test_data
->username
= talloc_strdup(test_data
, test_data
->username
);
1335 principal_string
= talloc_asprintf(test_data
, "%s@%s", test_data
->username
, test_data
->realm
);
1338 * If we are set to canonicalize, we get back the fixed UPPER
1339 * case realm, and the real username (ie matching LDAP
1342 * Otherwise, if we are set to enterprise, we
1343 * get back the whole principal as-sent
1345 * Finally, if we are not set to canonicalize, we get back the
1346 * fixed UPPER case realm, but the as-sent username
1348 if (test_data
->canonicalize
) {
1349 expected_principal_string
= talloc_asprintf(test_data
,
1351 test_data
->real_username
,
1352 test_data
->real_realm
);
1353 } else if (test_data
->enterprise
) {
1354 expected_principal_string
= principal_string
;
1356 expected_principal_string
= talloc_asprintf(test_data
,
1358 test_data
->username
,
1359 test_data
->real_realm
);
1362 if (test_data
->enterprise
) {
1363 principal_flags
= KRB5_PRINCIPAL_PARSE_ENTERPRISE
;
1365 if (test_data
->upn
&& test_data
->other_upn_suffix
) {
1366 torture_skip(tctx
, "UPN test for UPN with other UPN suffix only runs with enterprise principals");
1368 principal_flags
= 0;
1371 if (test_data
->canonicalize
) {
1372 expected_principal_flags
= 0;
1374 expected_principal_flags
= principal_flags
;
1377 torture_assert_int_equal(tctx
,
1378 krb5_parse_name_flags(k5_context
,
1382 0, "krb5_parse_name_flags failed");
1383 torture_assert_int_equal(tctx
,
1384 krb5_parse_name_flags(k5_context
,
1385 expected_principal_string
,
1386 expected_principal_flags
,
1387 &expected_principal
),
1388 0, "krb5_parse_name_flags failed");
1391 * Prepare a AS-REQ and run the TEST_AS_REQ tests
1395 test_context
->test_stage
= TEST_AS_REQ
;
1396 test_context
->packet_count
= 0;
1399 * Set the canonicalize flag if this test requires it
1401 torture_assert_int_equal(tctx
,
1402 krb5_get_init_creds_opt_alloc(k5_context
, &krb_options
),
1403 0, "krb5_get_init_creds_opt_alloc failed");
1405 torture_assert_int_equal(tctx
,
1406 krb5_get_init_creds_opt_set_canonicalize(k5_context
,
1408 test_data
->canonicalize
),
1409 0, "krb5_get_init_creds_opt_set_canonicalize failed");
1411 torture_assert_int_equal(tctx
,
1412 krb5_get_init_creds_opt_set_win2k(k5_context
,
1415 0, "krb5_get_init_creds_opt_set_win2k failed");
1417 k5ret
= krb5_get_init_creds_password(k5_context
, &my_creds
, principal
,
1418 password
, NULL
, NULL
, 0,
1421 if (test_data
->netbios_realm
&& test_data
->upn
) {
1422 torture_assert_int_equal(tctx
, k5ret
,
1423 KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN
,
1424 "Got wrong error_code from krb5_get_init_creds_password");
1425 /* We can't proceed with more checks */
1428 assertion_message
= talloc_asprintf(tctx
,
1429 "krb5_get_init_creds_password for %s failed: %s",
1431 smb_get_krb5_error_message(k5_context
, k5ret
, tctx
));
1432 torture_assert_int_equal(tctx
, k5ret
, 0, assertion_message
);
1435 torture_assert(tctx
,
1436 test_context
->packet_count
> 1,
1437 "Expected krb5_get_init_creds_password to send more packets");
1440 * Assert that the reply was with the correct type of
1441 * principal, depending on the flags we set
1443 if (test_data
->canonicalize
== false && test_data
->enterprise
) {
1444 torture_assert_int_equal(tctx
,
1445 krb5_principal_get_type(k5_context
,
1447 KRB5_NT_ENTERPRISE_PRINCIPAL
,
1448 "smb_krb5_init_context gave incorrect client->name.name_type");
1450 torture_assert_int_equal(tctx
,
1451 krb5_principal_get_type(k5_context
,
1454 "smb_krb5_init_context gave incorrect client->name.name_type");
1457 torture_assert_int_equal(tctx
,
1458 krb5_unparse_name(k5_context
,
1459 my_creds
.client
, &got_principal_string
), 0,
1460 "krb5_unparse_name failed");
1462 assertion_message
= talloc_asprintf(tctx
,
1463 "krb5_get_init_creds_password returned a different principal %s to what was expected %s",
1464 got_principal_string
, expected_principal_string
);
1465 krb5_free_unparsed_name(k5_context
, got_principal_string
);
1467 torture_assert(tctx
, krb5_principal_compare(k5_context
,
1468 my_creds
.client
, expected_principal
),
1472 torture_assert_int_equal(tctx
,
1473 krb5_principal_get_type(k5_context
,
1474 my_creds
.server
), KRB5_NT_SRV_INST
,
1475 "smb_krb5_init_context gave incorrect server->name.name_type");
1477 torture_assert_int_equal(tctx
,
1478 krb5_principal_get_num_comp(k5_context
,
1479 my_creds
.server
), 2,
1480 "smb_krb5_init_context gave incorrect number of components in my_creds.server->name");
1482 torture_assert_str_equal(tctx
,
1483 krb5_principal_get_comp_string(k5_context
,
1484 my_creds
.server
, 0),
1486 "smb_krb5_init_context gave incorrect my_creds.server->name.name_string[0]");
1488 if (test_data
->canonicalize
|| test_data
->enterprise
) {
1489 torture_assert_str_equal(tctx
,
1490 krb5_principal_get_comp_string(k5_context
,
1491 my_creds
.server
, 1),
1492 test_data
->real_realm
,
1494 "smb_krb5_init_context gave incorrect my_creds.server->name.name_string[1]");
1496 torture_assert_str_equal(tctx
,
1497 krb5_principal_get_comp_string(k5_context
,
1498 my_creds
.server
, 1),
1501 "smb_krb5_init_context gave incorrect my_creds.server->name.name_string[1]");
1503 torture_assert_str_equal(tctx
,
1504 krb5_principal_get_realm(k5_context
,
1506 test_data
->real_realm
,
1507 "smb_krb5_init_context gave incorrect my_creds.server->realm");
1509 /* Store the result of the 'kinit' above into a memory ccache */
1510 cc_name
= talloc_asprintf(tctx
, "MEMORY:%s", test_data
->test_name
);
1511 torture_assert_int_equal(tctx
, krb5_cc_resolve(k5_context
, cc_name
,
1513 0, "krb5_cc_resolve failed");
1515 torture_assert_int_equal(tctx
, krb5_cc_initialize(k5_context
,
1516 ccache
, my_creds
.client
),
1517 0, "krb5_cc_initialize failed");
1519 torture_assert_int_equal(tctx
, krb5_cc_store_cred(k5_context
,
1521 0, "krb5_cc_store_cred failed");
1524 * Prepare a TGS-REQ and run the TEST_TGS_REQ_KRBTGT_CANON tests
1526 * This tests krb5_get_creds behaviour, which allows us to set
1527 * the KRB5_GC_CANONICALIZE option against the krbtgt/ principal
1530 krbtgt_other_string
= talloc_asprintf(test_data
, "krbtgt/%s@%s", test_data
->real_domain
, test_data
->real_realm
);
1531 torture_assert_int_equal(tctx
,
1532 krb5_make_principal(k5_context
, &krbtgt_other
,
1533 test_data
->real_realm
, "krbtgt",
1534 test_data
->real_domain
, NULL
),
1535 0, "krb5_make_principal failed");
1537 test_context
->test_stage
= TEST_TGS_REQ_KRBTGT_CANON
;
1538 test_context
->packet_count
= 0;
1540 torture_assert_int_equal(tctx
,
1541 krb5_get_creds_opt_alloc(k5_context
, &opt
),
1542 0, "krb5_get_creds_opt_alloc");
1544 krb5_get_creds_opt_add_options(k5_context
,
1546 KRB5_GC_CANONICALIZE
);
1548 krb5_get_creds_opt_add_options(k5_context
,
1552 /* Confirm if we can get a ticket krbtgt/realm that we got back with the initial kinit */
1553 k5ret
= krb5_get_creds(k5_context
, opt
, ccache
, krbtgt_other
, &server_creds
);
1555 if (test_data
->canonicalize
== false && test_data
->enterprise
== false
1556 && test_data
->netbios_realm
&& test_data
->upper_realm
) {
1558 * In these situations, the code above does store a
1559 * principal in the credentials cache matching what
1560 * krb5_get_creds() needs, so the test succeds, with no packets.
1563 assertion_message
= talloc_asprintf(tctx
,
1564 "krb5_get_creds for %s failed with: %s",
1565 krbtgt_other_string
,
1566 smb_get_krb5_error_message(k5_context
, k5ret
,
1569 torture_assert_int_equal(tctx
, k5ret
, 0, assertion_message
);
1570 torture_assert_int_equal(tctx
,
1571 test_context
->packet_count
,
1572 0, "Expected krb5_get_creds not to send packets");
1573 } else if (test_data
->canonicalize
== false && test_data
->enterprise
== false
1574 && (test_data
->upper_realm
== false || test_data
->netbios_realm
== true)) {
1575 torture_assert_int_equal(tctx
, k5ret
, KRB5_CC_NOTFOUND
,
1576 "krb5_get_creds should have failed with KRB5_CC_NOTFOUND");
1580 * In these situations, the code above does not store a
1581 * principal in the credentials cache matching what
1582 * krb5_get_creds() needs without talking to the KDC, so the
1583 * test fails with looping detected because when we set
1584 * canonicalize we confuse the client libs.
1587 assertion_message
= talloc_asprintf(tctx
,
1588 "krb5_get_creds for %s should have failed with looping detected: %s",
1589 krbtgt_other_string
,
1590 smb_get_krb5_error_message(k5_context
, k5ret
,
1593 torture_assert_int_equal(tctx
, k5ret
, KRB5_GET_IN_TKT_LOOP
, assertion_message
);
1594 torture_assert_int_equal(tctx
,
1595 test_context
->packet_count
,
1596 2, "Expected krb5_get_creds to send packets");
1600 * Prepare a TGS-REQ and run the TEST_TGS_REQ_CANON tests
1602 * This tests krb5_get_creds behaviour, which allows us to set
1603 * the KRB5_GC_CANONICALIZE option
1606 test_context
->test_stage
= TEST_TGS_REQ_CANON
;
1607 test_context
->packet_count
= 0;
1609 torture_assert_int_equal(tctx
,
1610 krb5_get_creds_opt_alloc(k5_context
, &opt
),
1611 0, "krb5_get_creds_opt_alloc");
1613 krb5_get_creds_opt_add_options(k5_context
,
1615 KRB5_GC_CANONICALIZE
);
1617 krb5_get_creds_opt_add_options(k5_context
,
1621 /* Confirm if we can get a ticket to our own name */
1622 k5ret
= krb5_get_creds(k5_context
, opt
, ccache
, principal
, &server_creds
);
1625 * In these situations, the code above does not store a
1626 * principal in the credentials cache matching what
1627 * krb5_get_creds() needs, so the test fails.
1630 if (test_data
->canonicalize
== false && test_data
->enterprise
== false
1631 && (test_data
->upper_realm
== false || test_data
->netbios_realm
== true)) {
1632 torture_assert_int_equal(tctx
, k5ret
, KRB5_CC_NOTFOUND
,
1633 "krb5_get_creds should have failed with KRB5_CC_NOTFOUND");
1635 assertion_message
= talloc_asprintf(tctx
,
1636 "krb5_get_creds for %s failed: %s",
1638 smb_get_krb5_error_message(k5_context
, k5ret
,
1642 * Only machine accounts (strictly, accounts with a
1643 * servicePrincipalName) can expect this test to succeed
1645 if (torture_setting_bool(tctx
, "expect_machine_account", false)
1646 && (test_data
->enterprise
|| test_data
->upn
== false)) {
1647 torture_assert_int_equal(tctx
, k5ret
, 0, assertion_message
);
1648 torture_assert_int_equal(tctx
, krb5_cc_store_cred(k5_context
,
1649 ccache
, server_creds
),
1650 0, "krb5_cc_store_cred failed");
1652 torture_assert_int_equal(tctx
,
1653 krb5_free_creds(k5_context
,
1655 0, "krb5_free_cred_contents failed");
1658 torture_assert_int_equal(tctx
, k5ret
, KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN
,
1662 torture_assert_int_equal(tctx
,
1663 test_context
->packet_count
,
1664 1, "Expected krb5_get_creds to send packets");
1668 * Confirm gettting a ticket to pass to the server, running
1669 * either the TEST_TGS_REQ or TEST_SELF_TRUST_TGS_REQ stage.
1671 * This triggers the client to attempt to get a
1672 * cross-realm ticket between the alternate names of
1673 * the server, and we need to confirm that behaviour.
1678 * This tries to guess when the krb5 libs will ask for a
1679 * cross-realm ticket, and when they will just ask the KDC
1682 if (test_context
->test_data
->canonicalize
== false
1683 || test_context
->test_data
->enterprise
1684 || (test_context
->test_data
->upper_realm
1685 && test_context
->test_data
->netbios_realm
== false)) {
1686 test_context
->test_stage
= TEST_TGS_REQ
;
1688 test_context
->test_stage
= TEST_SELF_TRUST_TGS_REQ
;
1691 test_context
->packet_count
= 0;
1692 torture_assert_int_equal(tctx
, krb5_auth_con_init(k5_context
, &auth_context
),
1693 0, "krb5_auth_con_init failed");
1696 k5ret
= krb5_mk_req_exact(k5_context
,
1702 assertion_message
= talloc_asprintf(tctx
,
1703 "krb5_mk_req_exact for %s failed: %s",
1705 smb_get_krb5_error_message(k5_context
, k5ret
, tctx
));
1708 * Only machine accounts (strictly, accounts with a
1709 * servicePrincipalName) can expect this test to succeed
1711 if (torture_setting_bool(tctx
, "expect_machine_account", false) && (test_data
->enterprise
|| test_data
->upn
== false)) {
1712 torture_assert_int_equal(tctx
, k5ret
, 0, assertion_message
);
1714 torture_assert_int_equal(tctx
, k5ret
, KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN
,
1719 * Only in these cases would the above code have needed to
1720 * send packets to the network
1722 if (test_data
->canonicalize
== false && test_data
->enterprise
== false
1723 && (test_data
->upper_realm
== false || test_data
->netbios_realm
== true)) {
1724 torture_assert(tctx
,
1725 test_context
->packet_count
> 0,
1726 "Expected krb5_mk_req_exact to send packets");
1730 * Confirm gettting a ticket to pass to the server, running
1731 * the TEST_TGS_REQ_HOST stage
1733 * This triggers the client to attempt to get a
1734 * cross-realm ticket between the alternate names of
1735 * the server, and we need to confirm that behaviour.
1739 if (*test_data
->krb5_service
&& *test_data
->krb5_hostname
) {
1741 * This tries to guess when the krb5 libs will ask for a
1742 * cross-realm ticket, and when they will just ask the KDC
1745 test_context
->test_stage
= TEST_TGS_REQ_HOST
;
1747 test_context
->packet_count
= 0;
1748 torture_assert_int_equal(tctx
, krb5_auth_con_init(k5_context
, &auth_context
),
1749 0, "krb5_auth_con_init failed");
1752 k5ret
= krb5_mk_req(k5_context
,
1755 test_data
->krb5_service
,
1756 test_data
->krb5_hostname
,
1760 if (test_data
->canonicalize
== false && test_data
->enterprise
== false
1761 && (test_data
->upper_realm
== false || test_data
->netbios_realm
== true)) {
1762 torture_assert_int_equal(tctx
, k5ret
, KRB5_CC_NOTFOUND
,
1763 "krb5_get_creds should have failed with KRB5_CC_NOTFOUND");
1765 assertion_message
= talloc_asprintf(tctx
,
1766 "krb5_mk_req for %s failed: %s",
1768 smb_get_krb5_error_message(k5_context
, k5ret
, tctx
));
1770 torture_assert_int_equal(tctx
, k5ret
, 0, assertion_message
);
1772 * Only in these cases would the above code have needed to
1773 * send packets to the network
1775 torture_assert(tctx
,
1776 test_context
->packet_count
> 0,
1777 "Expected krb5_get_creds to send packets");
1782 * Confirm gettting a ticket for the same krbtgt/realm that we
1783 * got back with the initial ticket, running the
1784 * TEST_TGS_REQ_KRBTGT stage.
1788 test_context
->test_stage
= TEST_TGS_REQ_KRBTGT
;
1789 test_context
->packet_count
= 0;
1792 k5ret
= krb5_mk_req_exact(k5_context
,
1799 assertion_message
= talloc_asprintf(tctx
,
1800 "krb5_mk_req_exact for %s failed: %s",
1802 smb_get_krb5_error_message(k5_context
, k5ret
, tctx
));
1803 torture_assert_int_equal(tctx
, k5ret
, 0, assertion_message
);
1806 * Confirm gettting a ticket for our own principal that we
1807 * got back with the initial ticket, running the
1808 * TEST_AS_REQ_SELF stage.
1811 test_context
->test_stage
= TEST_AS_REQ_SELF
;
1812 test_context
->packet_count
= 0;
1814 k5ret
= krb5_get_init_creds_password(k5_context
, &my_creds
, principal
,
1815 password
, NULL
, NULL
, 0,
1816 principal_string
, krb_options
);
1818 if (torture_setting_bool(test_context
->tctx
, "expect_machine_account", false) && (test_data
->upn
== false)) {
1819 assertion_message
= talloc_asprintf(tctx
,
1820 "krb5_get_init_creds_password for %s failed: %s",
1822 smb_get_krb5_error_message(k5_context
, k5ret
, tctx
));
1823 torture_assert_int_equal(tctx
, k5ret
, 0, assertion_message
);
1824 torture_assert(tctx
,
1825 test_context
->packet_count
>= 2,
1826 "Expected krb5_get_init_creds_password to send more packets");
1829 assertion_message
= talloc_asprintf(tctx
,
1830 "Got wrong error_code from krb5_get_init_creds_password, expected KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN trying to get a ticket to %s for %s", principal_string
, principal_string
);
1831 torture_assert_int_equal(tctx
, k5ret
,
1832 KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN
,
1834 torture_assert(tctx
,
1835 test_context
->packet_count
>= 1,
1836 "Expected krb5_get_init_creds_password to send more packets");
1838 /* We can't proceed with more checks */
1843 * Assert that the reply was with the correct type of
1844 * principal, depending on the flags we set
1846 if (test_data
->canonicalize
== false && test_data
->enterprise
) {
1847 torture_assert_int_equal(tctx
,
1848 krb5_principal_get_type(k5_context
,
1850 KRB5_NT_ENTERPRISE_PRINCIPAL
,
1851 "smb_krb5_init_context gave incorrect client->name.name_type");
1852 torture_assert_int_equal(tctx
,
1853 krb5_principal_get_type(k5_context
,
1855 KRB5_NT_ENTERPRISE_PRINCIPAL
,
1856 "smb_krb5_init_context gave incorrect server->name.name_type");
1858 torture_assert_int_equal(tctx
,
1859 krb5_principal_get_type(k5_context
,
1862 "smb_krb5_init_context gave incorrect client->name.name_type");
1863 torture_assert_int_equal(tctx
,
1864 krb5_principal_get_type(k5_context
,
1867 "smb_krb5_init_context gave incorrect server->name.name_type");
1870 torture_assert_int_equal(tctx
,
1871 krb5_unparse_name(k5_context
,
1872 my_creds
.client
, &got_principal_string
), 0,
1873 "krb5_unparse_name failed");
1875 assertion_message
= talloc_asprintf(tctx
,
1876 "krb5_get_init_creds_password returned a different principal %s to what was expected %s",
1877 got_principal_string
, expected_principal_string
);
1878 krb5_free_unparsed_name(k5_context
, got_principal_string
);
1880 torture_assert(tctx
, krb5_principal_compare(k5_context
,
1881 my_creds
.client
, expected_principal
),
1884 torture_assert_int_equal(tctx
,
1885 krb5_unparse_name(k5_context
,
1886 my_creds
.client
, &got_principal_string
), 0,
1887 "krb5_unparse_name failed");
1889 assertion_message
= talloc_asprintf(tctx
,
1890 "krb5_get_init_creds_password returned a different server principal %s to what was expected %s",
1891 got_principal_string
, expected_principal_string
);
1892 krb5_free_unparsed_name(k5_context
, got_principal_string
);
1894 torture_assert(tctx
, krb5_principal_compare(k5_context
,
1895 my_creds
.client
, expected_principal
),
1898 krb5_free_principal(k5_context
, principal
);
1899 krb5_get_init_creds_opt_free(k5_context
, krb_options
);
1901 torture_assert_int_equal(tctx
, krb5_free_cred_contents(k5_context
, &my_creds
),
1902 0, "krb5_free_cred_contents failed");
1907 struct torture_suite
*torture_krb5_canon(TALLOC_CTX
*mem_ctx
)
1910 struct torture_suite
*suite
= torture_suite_create(mem_ctx
, "canon");
1911 suite
->description
= talloc_strdup(suite
, "Kerberos Canonicalisation tests");
1913 for (i
= 0; i
< TEST_ALL
; i
++) {
1914 char *name
= talloc_asprintf(suite
, "%s.%s.%s.%s.%s.%s.%s",
1915 (i
& TEST_CANONICALIZE
) ? "canon" : "no-canon",
1916 (i
& TEST_ENTERPRISE
) ? "enterprise" : "no-enterprise",
1917 (i
& TEST_UPPER_REALM
) ? "uc-realm" : "lc-realm",
1918 (i
& TEST_UPPER_USERNAME
) ? "uc-user" : "lc-user",
1919 (i
& TEST_NETBIOS_REALM
) ? "netbios-realm" : "krb5-realm",
1920 (i
& TEST_WIN2K
) ? "win2k" : "no-win2k",
1921 (i
& TEST_UPN
) ? "upn" : "no-upn");
1923 struct test_data
*test_data
= talloc_zero(suite
, struct test_data
);
1925 test_data
->test_name
= name
;
1926 test_data
->real_realm
1927 = strupper_talloc(test_data
, cli_credentials_get_realm(cmdline_credentials
));
1928 test_data
->real_domain
= cli_credentials_get_domain(cmdline_credentials
);
1929 test_data
->username
= cli_credentials_get_username(cmdline_credentials
);
1930 test_data
->real_username
= cli_credentials_get_username(cmdline_credentials
);
1931 test_data
->canonicalize
= (i
& TEST_CANONICALIZE
) != 0;
1932 test_data
->enterprise
= (i
& TEST_ENTERPRISE
) != 0;
1933 test_data
->upper_realm
= (i
& TEST_UPPER_REALM
) != 0;
1934 test_data
->upper_username
= (i
& TEST_UPPER_USERNAME
) != 0;
1935 test_data
->netbios_realm
= (i
& TEST_NETBIOS_REALM
) != 0;
1936 test_data
->win2k
= (i
& TEST_WIN2K
) != 0;
1937 test_data
->upn
= (i
& TEST_UPN
) != 0;
1938 torture_suite_add_simple_tcase_const(suite
, name
, torture_krb5_as_req_canon
,