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"
32 #include "auth/auth.h"
33 #include "auth/auth_sam_reply.h"
34 #include "auth/gensec/gensec.h"
35 #include "param/param.h"
37 #define TEST_CANONICALIZE 0x0000001
38 #define TEST_ENTERPRISE 0x0000002
39 #define TEST_UPPER_REALM 0x0000004
40 #define TEST_UPPER_USERNAME 0x0000008
41 #define TEST_NETBIOS_REALM 0x0000010
42 #define TEST_WIN2K 0x0000020
43 #define TEST_UPN 0x0000040
44 #define TEST_S4U2SELF 0x0000080
45 #define TEST_REMOVEDOLLAR 0x0000100
46 #define TEST_AS_REQ_SPN 0x0000200
47 #define TEST_ALL 0x00003FF
50 const char *test_name
;
52 const char *real_realm
;
53 const char *real_domain
;
55 const char *real_username
;
63 bool other_upn_suffix
;
68 const char *krb5_service
;
69 const char *krb5_hostname
;
74 TEST_TGS_REQ_KRBTGT_CANON
= 1,
75 TEST_TGS_REQ_CANON
= 2,
76 TEST_SELF_TRUST_TGS_REQ
= 3,
78 TEST_TGS_REQ_KRBTGT
= 5,
79 TEST_TGS_REQ_HOST
= 6,
80 TEST_TGS_REQ_HOST_SRV_INST
= 7,
81 TEST_TGS_REQ_HOST_SRV_HST
= 8,
86 struct torture_krb5_context
{
87 struct smb_krb5_context
*smb_krb5_context
;
88 struct torture_context
*tctx
;
89 struct addrinfo
*server
;
90 struct test_data
*test_data
;
92 enum test_stage test_stage
;
100 const char *principal_name
;
104 * A helper function which avoids touching the local databases to
105 * generate the session info, as we just want to verify the principal
106 * name that we found in the ticket not the full local token
108 static NTSTATUS
test_generate_session_info_pac(struct auth4_context
*auth_ctx
,
110 struct smb_krb5_context
*smb_krb5_context
,
112 const char *principal_name
,
113 const struct tsocket_address
*remote_address
,
114 uint32_t session_info_flags
,
115 struct auth_session_info
**session_info
)
118 struct auth_user_info_dc
*user_info_dc
;
120 struct pac_data
*pac_data
;
122 tmp_ctx
= talloc_named(mem_ctx
, 0, "gensec_gssapi_session_info context");
123 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx
);
125 auth_ctx
->private_data
= pac_data
= talloc_zero(auth_ctx
, struct pac_data
);
127 pac_data
->principal_name
= talloc_strdup(pac_data
, principal_name
);
128 if (!pac_data
->principal_name
) {
129 talloc_free(tmp_ctx
);
130 return NT_STATUS_NO_MEMORY
;
133 nt_status
= kerberos_pac_blob_to_user_info_dc(tmp_ctx
,
135 smb_krb5_context
->krb5_context
,
136 &user_info_dc
, NULL
, NULL
);
137 if (!NT_STATUS_IS_OK(nt_status
)) {
138 talloc_free(tmp_ctx
);
142 if (user_info_dc
->info
->authenticated
) {
143 session_info_flags
|= AUTH_SESSION_INFO_AUTHENTICATED
;
146 session_info_flags
|= AUTH_SESSION_INFO_SIMPLE_PRIVILEGES
;
147 nt_status
= auth_generate_session_info(mem_ctx
,
150 user_info_dc
, session_info_flags
,
152 if (!NT_STATUS_IS_OK(nt_status
)) {
153 talloc_free(tmp_ctx
);
157 talloc_free(tmp_ctx
);
161 /* Check to see if we can pass the PAC across to the NETLOGON server for validation */
163 /* Also happens to be a really good one-step verfication of our Kerberos stack */
165 static bool test_accept_ticket(struct torture_context
*tctx
,
166 struct cli_credentials
*credentials
,
167 const char *principal
,
168 DATA_BLOB client_to_server
)
171 struct gensec_security
*gensec_server_context
;
172 DATA_BLOB server_to_client
;
173 struct auth4_context
*auth_context
;
174 struct auth_session_info
*session_info
;
175 struct pac_data
*pac_data
;
176 TALLOC_CTX
*tmp_ctx
= talloc_new(tctx
);
178 torture_assert(tctx
, tmp_ctx
!= NULL
, "talloc_new() failed");
180 auth_context
= talloc_zero(tmp_ctx
, struct auth4_context
);
181 torture_assert(tctx
, auth_context
!= NULL
, "talloc_new() failed");
183 auth_context
->generate_session_info_pac
= test_generate_session_info_pac
;
185 status
= gensec_server_start(tctx
,
186 lpcfg_gensec_settings(tctx
, tctx
->lp_ctx
),
187 auth_context
, &gensec_server_context
);
188 torture_assert_ntstatus_ok(tctx
, status
, "gensec_server_start (server) failed");
190 status
= gensec_set_credentials(gensec_server_context
, credentials
);
191 torture_assert_ntstatus_ok(tctx
, status
, "gensec_set_credentials (server) failed");
193 status
= gensec_start_mech_by_name(gensec_server_context
, "krb5");
194 torture_assert_ntstatus_ok(tctx
, status
, "gensec_start_mech_by_name (server) failed");
196 server_to_client
= data_blob(NULL
, 0);
198 /* Do a client-server update dance */
199 status
= gensec_update(gensec_server_context
, tmp_ctx
, client_to_server
, &server_to_client
);
200 torture_assert_ntstatus_ok(tctx
, status
, "gensec_update (server) failed");
202 /* Extract the PAC using Samba's code */
204 status
= gensec_session_info(gensec_server_context
, gensec_server_context
, &session_info
);
205 torture_assert_ntstatus_ok(tctx
, status
, "gensec_session_info failed");
207 pac_data
= talloc_get_type(auth_context
->private_data
, struct pac_data
);
209 torture_assert(tctx
, pac_data
!= NULL
, "gensec_update failed to fill in pac_data in auth_context");
210 torture_assert(tctx
, pac_data
->principal_name
!= NULL
, "principal_name not present");
211 torture_assert_str_equal(tctx
, pac_data
->principal_name
, principal
, "wrong principal name");
216 * TEST_AS_REQ and TEST_AS_REQ_SELF - SEND
218 * Confirm that the outgoing packet meets certain expectations. This
219 * should be extended to further assert the correct and expected
220 * behaviour of the krb5 libs, so we know what we are sending to the
223 * Additionally, this CHANGES the request to remove the canonicalize
224 * flag automatically added by the krb5 libs when an enterprise
225 * principal is used, so we can test what the server does in this
230 static bool torture_krb5_pre_send_as_req_test(struct torture_krb5_context
*test_context
,
231 const krb5_data
*send_buf
,
232 krb5_data
*modified_send_buf
)
235 krb5_error_code k5ret
;
237 torture_assert_int_equal(test_context
->tctx
, decode_AS_REQ(send_buf
->data
, send_buf
->length
,
238 &test_context
->as_req
, &used
),
239 0, "decode_AS_REQ for TEST_AS_REQ failed");
240 mod_as_req
= test_context
->as_req
;
241 torture_assert_int_equal(test_context
->tctx
, used
, send_buf
->length
, "length mismatch");
242 torture_assert_int_equal(test_context
->tctx
, test_context
->as_req
.pvno
,
243 5, "Got wrong as_req->pvno");
244 if (test_context
->test_data
->canonicalize
245 || test_context
->test_data
->enterprise
) {
246 torture_assert(test_context
->tctx
,
247 test_context
->as_req
.req_body
.kdc_options
.canonicalize
,
248 "krb5 libs did not set canonicalize!");
250 torture_assert_int_equal(test_context
->tctx
,
251 test_context
->as_req
.req_body
.kdc_options
.canonicalize
,
253 "krb5 libs unexpectedly set canonicalize!");
256 if (test_context
->test_data
->as_req_spn
) {
257 if (test_context
->test_data
->upn
) {
258 torture_assert_int_equal(test_context
->tctx
,
259 test_context
->as_req
.req_body
.cname
->name_type
,
261 "krb5 libs unexpectedly "
262 "did not set principal "
265 torture_assert_int_equal(test_context
->tctx
,
266 test_context
->as_req
.req_body
.cname
->name_type
,
268 "krb5 libs unexpectedly "
269 "did not set principal "
272 } else if (test_context
->test_data
->enterprise
) {
273 torture_assert_int_equal(test_context
->tctx
,
274 test_context
->as_req
.req_body
.cname
->name_type
,
275 KRB5_NT_ENTERPRISE_PRINCIPAL
,
276 "krb5 libs did not pass principal as enterprise!");
278 torture_assert_int_equal(test_context
->tctx
,
279 test_context
->as_req
.req_body
.cname
->name_type
,
281 "krb5 libs unexpectedly set principal as enterprise!");
284 /* Force off canonicalize that was forced on by the krb5 libs */
285 if (test_context
->test_data
->canonicalize
== false && test_context
->test_data
->enterprise
) {
286 mod_as_req
.req_body
.kdc_options
.canonicalize
= false;
289 if (test_context
->test_stage
== TEST_AS_REQ_SELF
) {
291 * Force the server name to match the client name,
292 * including the name type. This isn't possible with
293 * the krb5 client libs alone
295 mod_as_req
.req_body
.sname
= test_context
->as_req
.req_body
.cname
;
298 ASN1_MALLOC_ENCODE(AS_REQ
, modified_send_buf
->data
, modified_send_buf
->length
,
299 &mod_as_req
, &used
, k5ret
);
300 torture_assert_int_equal(test_context
->tctx
,
302 "encode_AS_REQ failed");
304 if (test_context
->test_stage
!= TEST_AS_REQ_SELF
) {
305 torture_assert_int_equal(test_context
->tctx
, used
, send_buf
->length
,
306 "re-encode length mismatch");
314 * Confirm that the reply packet from the KDC meets certain
315 * expectations as part of TEST_AS_REQ. This uses a packet count to
316 * work out what packet we are up to in the multiple exchanged
317 * triggerd by krb5_get_init_creds_password().
321 static bool torture_krb5_post_recv_as_req_test(struct torture_krb5_context
*test_context
,
322 const krb5_data
*recv_buf
)
326 if (test_context
->packet_count
== 0) {
327 krb5_error_code k5ret
;
329 * The client libs obtain the salt by attempting to
330 * authenticate without pre-authentication and getting
331 * the correct salt with the
332 * KRB5KDC_ERR_PREAUTH_REQUIRED error. If we are in
333 * the test (netbios_realm && upn) that deliberatly
334 * has an incorrect principal, we check we get the
337 k5ret
= decode_KRB_ERROR(recv_buf
->data
, recv_buf
->length
,
341 k5ret
= decode_AS_REP(recv_buf
->data
, recv_buf
->length
,
344 if (test_context
->test_data
->netbios_realm
&& test_context
->test_data
->upn
) {
345 torture_assert(test_context
->tctx
, false,
346 "expected to get a KRB_ERROR packet with "
347 "KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN, got valid AS-REP");
349 torture_assert(test_context
->tctx
, false,
350 "expected to get a KRB_ERROR packet with "
351 "KRB5KDC_ERR_PREAUTH_REQUIRED, got valid AS-REP");
354 if (test_context
->test_data
->netbios_realm
&& test_context
->test_data
->upn
) {
355 torture_assert(test_context
->tctx
, false,
356 "unable to decode as KRB-ERROR or AS-REP, "
357 "expected to get a KRB_ERROR packet with KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN");
359 torture_assert(test_context
->tctx
, false,
360 "unable to decode as KRB-ERROR or AS-REP, "
361 "expected to get a KRB_ERROR packet with KRB5KDC_ERR_PREAUTH_REQUIRED");
365 torture_assert_int_equal(test_context
->tctx
, used
, recv_buf
->length
,
367 torture_assert_int_equal(test_context
->tctx
, error
.pvno
, 5,
368 "Got wrong error.pvno");
369 if (test_context
->test_data
->netbios_realm
&& test_context
->test_data
->upn
) {
370 torture_assert_int_equal(test_context
->tctx
,
372 KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN
- KRB5KDC_ERR_NONE
,
373 "Got wrong error.error_code");
374 } else if (test_context
->test_data
->as_req_spn
&& !test_context
->test_data
->spn_is_upn
) {
375 torture_assert_int_equal(test_context
->tctx
,
377 KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN
- KRB5KDC_ERR_NONE
,
378 "Got wrong error.error_code");
380 torture_assert_int_equal(test_context
->tctx
,
382 KRB5KDC_ERR_PREAUTH_REQUIRED
- KRB5KDC_ERR_NONE
,
383 "Got wrong error.error_code");
386 free_KRB_ERROR(&error
);
387 } else if ((decode_KRB_ERROR(recv_buf
->data
, recv_buf
->length
, &error
, &used
) == 0)
388 && (test_context
->packet_count
== 1)) {
390 * The Windows 2012R2 KDC will always respond with
391 * KRB5KRB_ERR_RESPONSE_TOO_BIG over UDP as the ticket
392 * won't fit, because of the PAC. (It appears to do
393 * this always, even if it will). This triggers the
394 * client to try again over TCP.
396 torture_assert_int_equal(test_context
->tctx
,
397 used
, recv_buf
->length
,
399 torture_assert_int_equal(test_context
->tctx
,
401 "Got wrong error.pvno");
402 torture_assert_int_equal(test_context
->tctx
,
404 KRB5KRB_ERR_RESPONSE_TOO_BIG
- KRB5KDC_ERR_NONE
,
405 "Got wrong error.error_code");
406 free_KRB_ERROR(&error
);
409 * Finally the successful packet.
411 torture_assert_int_equal(test_context
->tctx
,
412 decode_AS_REP(recv_buf
->data
, recv_buf
->length
,
413 &test_context
->as_rep
, &used
), 0,
414 "decode_AS_REP failed");
415 torture_assert_int_equal(test_context
->tctx
, used
, recv_buf
->length
,
417 torture_assert_int_equal(test_context
->tctx
,
418 test_context
->as_rep
.pvno
, 5,
419 "Got wrong as_rep->pvno");
420 torture_assert_int_equal(test_context
->tctx
,
421 test_context
->as_rep
.ticket
.tkt_vno
, 5,
422 "Got wrong as_rep->ticket.tkt_vno");
423 torture_assert(test_context
->tctx
,
424 test_context
->as_rep
.ticket
.enc_part
.kvno
,
425 "Did not get a KVNO in test_context->as_rep.ticket.enc_part.kvno");
428 * We can confirm that the correct proxy behaviour is
429 * in use on the KDC by checking the KVNO of the
430 * krbtgt account returned in the reply.
432 * A packet passed to the full RW DC will not have a
433 * KVNO in the upper bits, while a packet processed
434 * locally on the RODC will have these bits filled in
435 * the msDS-SecondaryKrbTgtNumber
437 if (torture_setting_bool(test_context
->tctx
, "expect_cached_at_rodc", false)) {
438 torture_assert_int_not_equal(test_context
->tctx
,
439 *test_context
->as_rep
.ticket
.enc_part
.kvno
& 0xFFFF0000,
440 0, "Did not get a RODC number in the KVNO");
442 torture_assert_int_equal(test_context
->tctx
,
443 *test_context
->as_rep
.ticket
.enc_part
.kvno
& 0xFFFF0000,
444 0, "Unexpecedly got a RODC number in the KVNO");
446 free_AS_REP(&test_context
->as_rep
);
448 torture_assert(test_context
->tctx
, test_context
->packet_count
< 3, "too many packets");
449 free_AS_REQ(&test_context
->as_req
);
454 * TEST_TGS_REQ_KRBTGT_CANON
457 * Confirm that the outgoing TGS-REQ packet from krb5_get_creds()
458 * for the krbtgt/realm principal meets certain expectations, like
459 * that the canonicalize bit is not set
463 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
)
466 torture_assert_int_equal(test_context
->tctx
,
467 decode_TGS_REQ(send_buf
->data
, send_buf
->length
,
468 &test_context
->tgs_req
, &used
),
469 0, "decode_TGS_REQ for TEST_TGS_REQ test failed");
470 torture_assert_int_equal(test_context
->tctx
,
471 used
, send_buf
->length
,
473 torture_assert_int_equal(test_context
->tctx
,
474 test_context
->tgs_req
.pvno
, 5,
475 "Got wrong as_req->pvno");
476 torture_assert_int_equal(test_context
->tctx
,
477 test_context
->tgs_req
.req_body
.kdc_options
.canonicalize
,
479 "krb5 libs unexpectedly did not set canonicalize!");
481 torture_assert_int_equal(test_context
->tctx
,
482 test_context
->tgs_req
.req_body
.sname
->name_type
,
484 "Mismatch in name_type between request and expected request");
486 torture_assert_str_equal(test_context
->tctx
,
487 test_context
->tgs_req
.req_body
.realm
,
488 test_context
->test_data
->real_realm
,
489 "Mismatch in realm between request and expected request");
491 *modified_send_buf
= *send_buf
;
496 * TEST_TGS_REQ_KRBTGT_CANON
498 * Confirm that the reply TGS-REP packet for krb5_get_creds()
499 * where the client is behaving as if this is a cross-realm trust due
500 * to case or netbios vs dns name differences meets certain
501 * expectations, while canonicalize is set
505 static bool torture_krb5_post_recv_tgs_req_krbtgt_canon_test(struct torture_krb5_context
*test_context
, const krb5_data
*recv_buf
)
508 torture_assert_int_equal(test_context
->tctx
,
509 decode_TGS_REP(recv_buf
->data
, recv_buf
->length
,
510 &test_context
->tgs_rep
, &used
),
512 "decode_TGS_REP failed");
513 torture_assert_int_equal(test_context
->tctx
, used
, recv_buf
->length
, "length mismatch");
514 torture_assert_int_equal(test_context
->tctx
,
515 test_context
->tgs_rep
.pvno
, 5,
516 "Got wrong as_rep->pvno");
517 torture_assert_int_equal(test_context
->tctx
,
518 test_context
->tgs_rep
.ticket
.tkt_vno
, 5,
519 "Got wrong as_rep->ticket.tkt_vno");
520 torture_assert(test_context
->tctx
,
521 test_context
->tgs_rep
.ticket
.enc_part
.kvno
,
522 "Did not get a KVNO in test_context->as_rep.ticket.enc_part.kvno");
523 torture_assert_str_equal(test_context
->tctx
,
524 test_context
->tgs_req
.req_body
.realm
,
525 test_context
->tgs_rep
.ticket
.realm
,
526 "Mismatch in realm between request and ticket response");
527 torture_assert_str_equal(test_context
->tctx
,
528 test_context
->tgs_rep
.ticket
.realm
,
529 test_context
->test_data
->real_realm
,
530 "Mismatch in realm between ticket response and expected ticket response");
531 torture_assert_int_equal(test_context
->tctx
,
532 test_context
->tgs_rep
.ticket
.sname
.name_type
,
534 "Mismatch in name_type between ticket response and expected value of KRB5_NT_SRV_INST");
536 torture_assert_int_equal(test_context
->tctx
,
537 test_context
->tgs_rep
.ticket
.sname
.name_string
.len
,
539 "Mismatch in name_type between ticket response and expected value, expected krbtgt/REALM@REALM");
541 torture_assert_str_equal(test_context
->tctx
,
542 test_context
->tgs_rep
.ticket
.sname
.name_string
.val
[0], "krbtgt",
543 "Mismatch in name between response and expected response, expected krbtgt");
544 torture_assert_str_equal(test_context
->tctx
,
545 test_context
->tgs_rep
.ticket
.sname
.name_string
.val
[1], test_context
->test_data
->real_realm
,
546 "Mismatch in realm part of krbtgt/ in expected response, expected krbtgt/REALM@REALM");
549 * We can confirm that the correct proxy behaviour is
550 * in use on the KDC by checking the KVNO of the
551 * krbtgt account returned in the reply.
553 * A packet passed to the full RW DC will not have a
554 * KVNO in the upper bits, while a packet processed
555 * locally on the RODC will have these bits filled in
556 * the msDS-SecondaryKrbTgtNumber
558 if (torture_setting_bool(test_context
->tctx
, "expect_cached_at_rodc", false)) {
559 torture_assert_int_not_equal(test_context
->tctx
,
560 *test_context
->tgs_rep
.ticket
.enc_part
.kvno
& 0xFFFF0000,
561 0, "Did not get a RODC number in the KVNO");
563 torture_assert_int_equal(test_context
->tctx
,
564 *test_context
->tgs_rep
.ticket
.enc_part
.kvno
& 0xFFFF0000,
565 0, "Unexpecedly got a RODC number in the KVNO");
567 free_TGS_REP(&test_context
->tgs_rep
);
568 torture_assert(test_context
->tctx
,
569 test_context
->packet_count
< 2,
571 free_TGS_REQ(&test_context
->tgs_req
);
578 * Confirm that the outgoing TGS-REQ packet from krb5_get_creds
579 * certain expectations, like that the canonicalize bit is set (this
580 * test is to force that handling) and that if an enterprise name was
581 * requested, that it was sent.
585 static bool torture_krb5_pre_send_tgs_req_canon_test(struct torture_krb5_context
*test_context
,
586 const krb5_data
*send_buf
,
587 krb5_data
*modified_send_buf
)
590 torture_assert_int_equal(test_context
->tctx
,
591 decode_TGS_REQ(send_buf
->data
, send_buf
->length
,
592 &test_context
->tgs_req
, &used
),
593 0, "decode_TGS_REQ for TEST_TGS_REQ_CANON test failed");
594 torture_assert_int_equal(test_context
->tctx
, used
, send_buf
->length
, "length mismatch");
595 torture_assert_int_equal(test_context
->tctx
, test_context
->tgs_req
.pvno
, 5, "Got wrong as_req->pvno");
596 torture_assert_int_equal(test_context
->tctx
,
597 test_context
->tgs_req
.req_body
.kdc_options
.canonicalize
,
598 true, "krb5 libs unexpectedly did not set canonicalize!");
600 if (test_context
->test_data
->enterprise
) {
601 torture_assert_int_equal(test_context
->tctx
,
602 test_context
->tgs_req
.req_body
.sname
->name_type
, KRB5_NT_ENTERPRISE_PRINCIPAL
,
603 "Mismatch in name type between request and expected request, expected KRB5_NT_ENTERPRISE_PRINCIPAL");
604 torture_assert_str_equal(test_context
->tctx
,
605 test_context
->tgs_req
.req_body
.realm
, test_context
->test_data
->real_realm
,
606 "Mismatch in realm between request and expected request");
608 } else if (test_context
->test_data
->as_req_spn
) {
609 torture_assert_int_equal(test_context
->tctx
,
610 test_context
->tgs_req
.req_body
.sname
->name_type
, KRB5_NT_SRV_HST
,
611 "Mismatch in name type between request and expected request, expected KRB5_NT_SRV_HST");
612 torture_assert_str_equal(test_context
->tctx
,
613 test_context
->tgs_req
.req_body
.realm
, test_context
->test_data
->real_realm
,
614 "Mismatch in realm between request and expected request");
616 } else if (test_context
->test_data
->canonicalize
) {
617 torture_assert_int_equal(test_context
->tctx
,
618 test_context
->tgs_req
.req_body
.sname
->name_type
, KRB5_NT_PRINCIPAL
,
619 "Mismatch in name type between request and expected request, expected KRB5_NT_PRINCIPAL");
620 torture_assert_str_equal(test_context
->tctx
,
621 test_context
->tgs_req
.req_body
.realm
, test_context
->test_data
->real_realm
,
622 "Mismatch in realm between request and expected request");
625 torture_assert_int_equal(test_context
->tctx
,
626 test_context
->tgs_req
.req_body
.sname
->name_type
, KRB5_NT_PRINCIPAL
,
627 "Mismatch in name type between request and expected request, expected KRB5_NT_PRINCIPAL");
628 torture_assert_str_equal(test_context
->tctx
,
629 test_context
->tgs_req
.req_body
.realm
, test_context
->test_data
->realm
,
630 "Mismatch in realm between request and expected request");
634 *modified_send_buf
= *send_buf
;
640 * TEST_TGS_REQ_CANON - RECV
642 * Confirm that the reply TGS-REP or error packet from the KDC meets
643 * certain expectations as part of TEST_TGS_REQ_CANON.
645 * This is triggered by krb5_get_creds()
649 static bool torture_krb5_post_recv_tgs_req_canon_test(struct torture_krb5_context
*test_context
, const krb5_data
*recv_buf
)
655 * If this account did not have a servicePrincipalName, then
656 * we expect a errro packet, not a TGS-REQ
658 if (decode_KRB_ERROR(recv_buf
->data
, recv_buf
->length
, &error
, &used
) == 0) {
659 torture_assert_int_equal(test_context
->tctx
, used
, recv_buf
->length
, "length mismatch");
660 torture_assert_int_equal(test_context
->tctx
,
662 "Got wrong error.pvno");
663 torture_assert_int_equal(test_context
->tctx
,
665 KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN
- KRB5KDC_ERR_NONE
,
666 "Got wrong error.error_code");
668 torture_assert_int_equal(test_context
->tctx
,
669 decode_TGS_REP(recv_buf
->data
, recv_buf
->length
,
670 &test_context
->tgs_rep
,
673 "decode_TGS_REP failed");
674 torture_assert_int_equal(test_context
->tctx
,
675 used
, recv_buf
->length
,
677 torture_assert_int_equal(test_context
->tctx
,
678 test_context
->tgs_rep
.pvno
, 5,
679 "Got wrong as_rep->pvno");
680 torture_assert_int_equal(test_context
->tctx
,
681 test_context
->tgs_rep
.ticket
.tkt_vno
, 5,
682 "Got wrong as_rep->ticket.tkt_vno");
683 torture_assert(test_context
->tctx
,
684 test_context
->tgs_rep
.ticket
.enc_part
.kvno
,
685 "Did not get a KVNO in test_context->as_rep.ticket.enc_part.kvno");
686 torture_assert_str_equal(test_context
->tctx
,
687 test_context
->tgs_rep
.ticket
.realm
,
688 test_context
->test_data
->real_realm
,
689 "Mismatch in realm between ticket response and expected upper case REALM");
690 torture_assert_int_equal(test_context
->tctx
,
691 test_context
->tgs_rep
.ticket
.sname
.name_type
,
692 test_context
->tgs_req
.req_body
.sname
->name_type
,
693 "Mismatch in name_type between request and ticket response");
694 torture_assert_int_equal(test_context
->tctx
,
695 test_context
->tgs_rep
.ticket
.sname
.name_string
.len
,
696 test_context
->tgs_req
.req_body
.sname
->name_string
.len
,
697 "Mismatch in name_string.len between request and ticket response");
698 torture_assert(test_context
->tctx
,
699 test_context
->tgs_rep
.ticket
.sname
.name_string
.len
>= 1,
700 "name_string.len should be >=1 in ticket response");
701 torture_assert_str_equal(test_context
->tctx
,
702 test_context
->tgs_rep
.ticket
.sname
.name_string
.val
[0],
703 test_context
->tgs_req
.req_body
.sname
->name_string
.val
[0],
704 "Mismatch in name between request and expected request");
705 torture_assert_int_equal(test_context
->tctx
,
706 *test_context
->tgs_rep
.ticket
.enc_part
.kvno
& 0xFFFF0000,
707 0, "Unexpecedly got a RODC number in the KVNO, should just be principal KVNO");
708 free_TGS_REP(&test_context
->tgs_rep
);
710 torture_assert(test_context
->tctx
, test_context
->packet_count
== 0, "too many packets");
711 free_TGS_REQ(&test_context
->tgs_req
);
717 * TEST_SELF_TRUST_TGS_REQ
719 * Confirm that the outgoing TGS-REQ packet from krb5_mk_req_exact()
720 * certain expectations, like that the canonicalize bit is set (this
721 * test is to force that handling).
723 * This test is for the case where the name we ask for, while a valid
724 * alternate name for our own realm is used. The client acts as if
725 * this is cross-realm trust.
729 static bool torture_krb5_pre_send_self_trust_tgs_req_test(struct torture_krb5_context
*test_context
,
730 const krb5_data
*send_buf
,
731 krb5_data
*modified_send_buf
)
734 torture_assert_int_equal(test_context
->tctx
,
735 decode_TGS_REQ(send_buf
->data
, send_buf
->length
,
736 &test_context
->tgs_req
, &used
),
737 0, "decode_TGS_REQ for TEST_SELF_TRUST_TGS_REQ test failed");
738 torture_assert_int_equal(test_context
->tctx
, used
, send_buf
->length
, "length mismatch");
739 torture_assert_int_equal(test_context
->tctx
, test_context
->tgs_req
.pvno
, 5, "Got wrong as_req->pvno");
741 if (test_context
->test_data
->enterprise
742 || (test_context
->test_data
->spn_is_upn
&& test_context
->test_data
->upn
)) {
743 torture_assert_int_equal(test_context
->tctx
,
744 test_context
->tgs_req
.req_body
.kdc_options
.canonicalize
,
746 "krb5 libs unexpectedly"
747 " did not set canonicalize!");
749 torture_assert_int_equal(test_context
->tctx
,
750 test_context
->tgs_req
.req_body
.kdc_options
.canonicalize
,
752 "krb5 libs unexpectedly"
753 " set canonicalize!");
757 if (test_context
->test_data
->canonicalize
) {
758 torture_assert_str_equal(test_context
->tctx
,
759 test_context
->tgs_req
.req_body
.realm
,
760 test_context
->test_data
->real_realm
,
761 "Mismatch in realm between request and expected request");
763 torture_assert_str_equal(test_context
->tctx
,
764 test_context
->tgs_req
.req_body
.realm
,
765 test_context
->test_data
->realm
,
766 "Mismatch in realm between request and expected request");
768 torture_assert_int_equal(test_context
->tctx
,
769 test_context
->tgs_req
.req_body
.sname
->name_type
, KRB5_NT_PRINCIPAL
,
770 "Mismatch in name type between request and expected request, expected KRB5_NT_PRINCIPAL");
771 torture_assert_int_equal(test_context
->tctx
,
772 test_context
->tgs_req
.req_body
.sname
->name_string
.len
, 2,
773 "Mismatch in name between request and expected request, expected krbtgt/realm");
774 torture_assert_str_equal(test_context
->tctx
,
775 test_context
->tgs_req
.req_body
.sname
->name_string
.val
[0], "krbtgt",
776 "Mismatch in name between request and expected request, expected krbtgt");
777 torture_assert_str_equal(test_context
->tctx
,
778 test_context
->tgs_req
.req_body
.sname
->name_string
.val
[1], test_context
->test_data
->realm
,
779 "Mismatch in realm part of cross-realm request principal between request and expected request");
780 *modified_send_buf
= *send_buf
;
786 * TEST_SELF_TRUST_TGS_REQ and TEST_TGS_REQ_KRBTGT - RECV
788 * Confirm that the reply TGS-REP packet for krb5_mk_req_exact(),
789 * where the client is behaving as if this is a cross-realm trust due
790 * to case or netbios vs dns name differences meets certain
795 static bool torture_krb5_post_recv_self_trust_tgs_req_test(struct torture_krb5_context
*test_context
, const krb5_data
*recv_buf
)
798 torture_assert_int_equal(test_context
->tctx
,
799 decode_TGS_REP(recv_buf
->data
, recv_buf
->length
,
800 &test_context
->tgs_rep
, &used
),
802 "decode_TGS_REP failed");
803 torture_assert_int_equal(test_context
->tctx
, used
, recv_buf
->length
, "length mismatch");
804 torture_assert_int_equal(test_context
->tctx
,
805 test_context
->tgs_rep
.pvno
, 5,
806 "Got wrong as_rep->pvno");
807 torture_assert_int_equal(test_context
->tctx
,
808 test_context
->tgs_rep
.ticket
.tkt_vno
, 5,
809 "Got wrong as_rep->ticket.tkt_vno");
810 torture_assert(test_context
->tctx
,
811 test_context
->tgs_rep
.ticket
.enc_part
.kvno
,
812 "Did not get a KVNO in test_context->as_rep.ticket.enc_part.kvno");
813 torture_assert_str_equal(test_context
->tctx
,
814 test_context
->tgs_req
.req_body
.realm
,
815 test_context
->tgs_rep
.ticket
.realm
,
816 "Mismatch in realm between request and ticket response");
817 torture_assert_int_equal(test_context
->tctx
,
818 test_context
->tgs_rep
.ticket
.sname
.name_type
,
819 test_context
->tgs_req
.req_body
.sname
->name_type
,
820 "Mismatch in name_type between request and ticket response");
822 torture_assert_int_equal(test_context
->tctx
,
823 test_context
->tgs_rep
.ticket
.sname
.name_string
.len
, 2,
824 "Mismatch in name between request and expected request, expected krbtgt/realm");
825 torture_assert_str_equal(test_context
->tctx
,
826 test_context
->tgs_rep
.ticket
.sname
.name_string
.val
[0], "krbtgt",
827 "Mismatch in name between request and expected request, expected krbtgt");
828 torture_assert_str_equal(test_context
->tctx
,
829 test_context
->tgs_rep
.ticket
.sname
.name_string
.val
[1], test_context
->test_data
->realm
,
830 "Mismatch in realm part of cross-realm request principal between response and expected request");
832 * We can confirm that the correct proxy behaviour is
833 * in use on the KDC by checking the KVNO of the
834 * krbtgt account returned in the reply.
836 * A packet passed to the full RW DC will not have a
837 * KVNO in the upper bits, while a packet processed
838 * locally on the RODC will have these bits filled in
839 * the msDS-SecondaryKrbTgtNumber
841 if (torture_setting_bool(test_context
->tctx
, "expect_cached_at_rodc", false)) {
842 torture_assert_int_not_equal(test_context
->tctx
,
843 *test_context
->tgs_rep
.ticket
.enc_part
.kvno
& 0xFFFF0000,
844 0, "Did not get a RODC number in the KVNO");
846 torture_assert_int_equal(test_context
->tctx
,
847 *test_context
->tgs_rep
.ticket
.enc_part
.kvno
& 0xFFFF0000,
848 0, "Unexpecedly got a RODC number in the KVNO");
850 free_TGS_REP(&test_context
->tgs_rep
);
851 torture_assert_int_equal(test_context
->tctx
,
852 test_context
->packet_count
, 0,
854 test_context
->packet_count
= 0;
855 test_context
->test_stage
= TEST_TGS_REQ
;
856 free_TGS_REQ(&test_context
->tgs_req
);
863 * Confirm that the outgoing TGS-REQ packet from krb5_mk_req_exact()
864 * certain expectations, like that the canonicalize bit is set (this
865 * test is to force that handling) and that if an enterprise name was
866 * requested, that it was sent.
870 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
)
873 torture_assert_int_equal(test_context
->tctx
,
874 decode_TGS_REQ(send_buf
->data
, send_buf
->length
,
875 &test_context
->tgs_req
, &used
),
876 0, "decode_TGS_REQ for TEST_TGS_REQ test failed");
877 torture_assert_int_equal(test_context
->tctx
, used
, send_buf
->length
, "length mismatch");
878 torture_assert_int_equal(test_context
->tctx
, test_context
->tgs_req
.pvno
, 5,
879 "Got wrong as_req->pvno");
881 if (test_context
->test_data
->enterprise
882 && test_context
->test_data
->s4u2self
== false
883 && test_context
->test_data
->spn_is_upn
) {
884 torture_assert_int_equal(test_context
->tctx
,
885 test_context
->tgs_req
.req_body
.kdc_options
.canonicalize
,
887 "krb5 libs unexpectedly"
888 " did not set canonicalize!");
890 torture_assert_int_equal(test_context
->tctx
,
891 test_context
->tgs_req
.req_body
.kdc_options
.canonicalize
,
893 "krb5 libs unexpectedly"
894 " set canonicalize!");
897 if (test_context
->test_data
->enterprise
) {
898 torture_assert_int_equal(test_context
->tctx
,
899 test_context
->tgs_req
.req_body
.sname
->name_type
,
900 KRB5_NT_ENTERPRISE_PRINCIPAL
,
901 "Mismatch in name type between request and expected request, expected KRB5_NT_ENTERPRISE_PRINCIPAL");
902 torture_assert_str_equal(test_context
->tctx
,
903 test_context
->tgs_req
.req_body
.realm
,
904 test_context
->test_data
->real_realm
,
905 "Mismatch in realm between request and expected request");
907 } else if (test_context
->test_data
->spn_is_upn
&& test_context
->test_data
->upn
&& test_context
->test_data
->canonicalize
) {
908 torture_assert_int_equal(test_context
->tctx
,
909 test_context
->tgs_req
.req_body
.sname
->name_type
,
911 "Mismatch in name type between request and expected request, expected KRB5_NT_PRINCIPAL");
912 torture_assert_str_equal(test_context
->tctx
,
913 test_context
->tgs_req
.req_body
.realm
,
914 test_context
->test_data
->real_realm
,
915 "Mismatch in realm between request and expected request");
917 } else if (test_context
->test_data
->spn_is_upn
918 && test_context
->test_data
->as_req_spn
919 && test_context
->test_data
->canonicalize
== false) {
920 torture_assert_int_equal(test_context
->tctx
,
921 test_context
->tgs_req
.req_body
.sname
->name_type
,
923 "Mismatch in name type between request and expected request, expected KRB5_NT_SRV_HST");
924 torture_assert_str_equal(test_context
->tctx
,
925 test_context
->tgs_req
.req_body
.realm
,
926 test_context
->test_data
->realm
,
927 "Mismatch in realm between request and expected request");
930 torture_assert_int_equal(test_context
->tctx
,
931 test_context
->tgs_req
.req_body
.sname
->name_type
,
933 "Mismatch in name type between request and expected request, expected KRB5_NT_PRINCIPAL");
934 torture_assert_str_equal(test_context
->tctx
,
935 test_context
->tgs_req
.req_body
.realm
,
936 test_context
->test_data
->realm
,
937 "Mismatch in realm between request and expected request");
941 *modified_send_buf
= *send_buf
;
947 * TEST_TGS_REQ - RECV
949 * Confirm that the reply TGS-REP packet for krb5_mk_req_exact(), for
950 * the actual target service.
954 static bool torture_krb5_post_recv_tgs_req_test(struct torture_krb5_context
*test_context
, const krb5_data
*recv_buf
)
959 * If this account did not have a servicePrincipalName, then
960 * we expect a errro packet, not a TGS-REQ
962 if (decode_KRB_ERROR(recv_buf
->data
, recv_buf
->length
, &error
, &used
) == 0) {
963 torture_assert_int_equal(test_context
->tctx
,
964 used
, recv_buf
->length
,
966 torture_assert_int_equal(test_context
->tctx
,
968 "Got wrong error.pvno");
969 torture_assert_int_equal(test_context
->tctx
,
971 KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN
- KRB5KDC_ERR_NONE
,
972 "Got wrong error.error_code");
974 torture_assert_int_equal(test_context
->tctx
,
975 decode_TGS_REP(recv_buf
->data
, recv_buf
->length
,
976 &test_context
->tgs_rep
, &used
),
978 "decode_TGS_REP failed");
979 torture_assert_int_equal(test_context
->tctx
, used
, recv_buf
->length
,
981 torture_assert_int_equal(test_context
->tctx
,
982 test_context
->tgs_rep
.pvno
, 5,
983 "Got wrong as_rep->pvno");
984 torture_assert_int_equal(test_context
->tctx
,
985 test_context
->tgs_rep
.ticket
.tkt_vno
, 5,
986 "Got wrong as_rep->ticket.tkt_vno");
987 torture_assert(test_context
->tctx
,
988 test_context
->tgs_rep
.ticket
.enc_part
.kvno
,
989 "Did not get a KVNO in test_context->as_rep.ticket.enc_part.kvno");
990 torture_assert_str_equal(test_context
->tctx
,
991 test_context
->tgs_rep
.ticket
.realm
,
992 test_context
->test_data
->real_realm
,
993 "Mismatch in realm between ticket response and expected upper case REALM");
994 torture_assert_int_equal(test_context
->tctx
,
995 test_context
->tgs_req
.req_body
.sname
->name_type
,
996 test_context
->tgs_rep
.ticket
.sname
.name_type
, "Mismatch in name_type between request and ticket response");
997 torture_assert_int_equal(test_context
->tctx
,
998 *test_context
->tgs_rep
.ticket
.enc_part
.kvno
& 0xFFFF0000,
999 0, "Unexpecedly got a RODC number in the KVNO, should just be principal KVNO");
1000 free_TGS_REP(&test_context
->tgs_rep
);
1002 torture_assert(test_context
->tctx
, test_context
->packet_count
< 3, "too many packets");
1003 free_TGS_REQ(&test_context
->tgs_req
);
1004 test_context
->test_stage
= TEST_DONE
;
1009 * TEST_TGS_REQ_KRBTGT
1012 * Confirm that the outgoing TGS-REQ packet from krb5_mk_req_exact()
1013 * for the krbtgt/realm principal meets certain expectations, like
1014 * that the canonicalize bit is not set
1018 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
)
1021 torture_assert_int_equal(test_context
->tctx
,
1022 decode_TGS_REQ(send_buf
->data
, send_buf
->length
,
1023 &test_context
->tgs_req
, &used
),
1024 0, "decode_TGS_REQ for TEST_TGS_REQ test failed");
1025 torture_assert_int_equal(test_context
->tctx
,
1026 used
, send_buf
->length
,
1028 torture_assert_int_equal(test_context
->tctx
,
1029 test_context
->tgs_req
.pvno
, 5,
1030 "Got wrong as_req->pvno");
1031 torture_assert_int_equal(test_context
->tctx
,
1032 test_context
->tgs_req
.req_body
.kdc_options
.canonicalize
,
1034 "krb5 libs unexpectedly set canonicalize!");
1036 torture_assert_str_equal(test_context
->tctx
,
1037 test_context
->tgs_req
.req_body
.realm
,
1038 test_context
->test_data
->realm
,
1039 "Mismatch in realm between request and expected request");
1041 *modified_send_buf
= *send_buf
;
1042 test_context
->test_stage
= TEST_DONE
;
1047 * TEST_TGS_REQ_HOST, TEST_TGS_REQ_HOST_SRV_INST and TEST_TGS_REQ_HOST_SRV_HST
1050 * Confirm that the outgoing TGS-REQ packet from krb5_mk_req_exact()
1051 * for the krbtgt/realm principal meets certain expectations, like
1052 * that the canonicalize bit is not set
1056 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
)
1059 torture_assert_int_equal(test_context
->tctx
,
1060 decode_TGS_REQ(send_buf
->data
, send_buf
->length
,
1061 &test_context
->tgs_req
, &used
),
1062 0, "decode_TGS_REQ for TEST_TGS_REQ test failed");
1063 torture_assert_int_equal(test_context
->tctx
,
1064 used
, send_buf
->length
,
1066 torture_assert_int_equal(test_context
->tctx
,
1067 test_context
->tgs_req
.pvno
, 5,
1068 "Got wrong as_req->pvno");
1069 torture_assert_int_equal(test_context
->tctx
,
1070 test_context
->tgs_req
.req_body
.sname
->name_string
.len
, 2,
1071 "Mismatch in name between request and expected request, expected krbtgt/realm");
1072 torture_assert_int_equal(test_context
->tctx
,
1073 test_context
->tgs_req
.req_body
.kdc_options
.canonicalize
,
1075 "krb5 libs unexpectedly did not set canonicalize!");
1077 if (test_context
->test_stage
== TEST_TGS_REQ_HOST_SRV_INST
) {
1078 torture_assert_int_equal(test_context
->tctx
,
1079 test_context
->tgs_req
.req_body
.sname
->name_type
, KRB5_NT_SRV_INST
,
1080 "Mismatch in name type between request and expected request, expected KRB5_NT_SRV_INST");
1081 torture_assert_str_equal(test_context
->tctx
,
1082 test_context
->tgs_req
.req_body
.sname
->name_string
.val
[0],
1083 strupper_talloc(test_context
, test_context
->test_data
->krb5_service
),
1084 "Mismatch in name between request and expected request, expected service");
1085 torture_assert_str_equal(test_context
->tctx
,
1086 test_context
->tgs_req
.req_body
.sname
->name_string
.val
[1],
1087 test_context
->test_data
->krb5_hostname
,
1088 "Mismatch in hostname part between request and expected request");
1090 } else if (test_context
->test_stage
== TEST_TGS_REQ_HOST_SRV_HST
) {
1092 torture_assert_int_equal(test_context
->tctx
,
1093 test_context
->tgs_req
.req_body
.sname
->name_type
, KRB5_NT_SRV_HST
,
1094 "Mismatch in name type between request and expected request, expected KRB5_NT_SRV_HST");
1095 torture_assert_str_equal(test_context
->tctx
,
1096 test_context
->tgs_req
.req_body
.sname
->name_string
.val
[0],
1097 test_context
->test_data
->krb5_service
,
1098 "Mismatch in name between request and expected request, expected service");
1099 torture_assert_str_equal(test_context
->tctx
,
1100 test_context
->tgs_req
.req_body
.sname
->name_string
.val
[1],
1101 strupper_talloc(test_context
, test_context
->test_data
->krb5_hostname
),
1102 "Mismatch in hostname part between request and expected request");
1105 torture_assert_int_equal(test_context
->tctx
,
1106 test_context
->tgs_req
.req_body
.sname
->name_type
, KRB5_NT_PRINCIPAL
,
1107 "Mismatch in name type between request and expected request, expected KRB5_NT_PRINCIPAL");
1108 torture_assert_str_equal(test_context
->tctx
,
1109 test_context
->tgs_req
.req_body
.sname
->name_string
.val
[0],
1110 test_context
->test_data
->krb5_service
,
1111 "Mismatch in name between request and expected request, expected service");
1112 torture_assert_str_equal(test_context
->tctx
,
1113 test_context
->tgs_req
.req_body
.sname
->name_string
.val
[1],
1114 test_context
->test_data
->krb5_hostname
,
1115 "Mismatch in hostname part between request and expected request");
1118 torture_assert_str_equal(test_context
->tctx
,
1119 test_context
->tgs_req
.req_body
.realm
,
1120 test_context
->test_data
->real_realm
,
1121 "Mismatch in realm between request and expected request");
1123 *modified_send_buf
= *send_buf
;
1128 * TEST_TGS_REQ_HOST, TEST_TGS_REQ_HOST_SRV_INST, TEST_TGS_REQ_HOST_SRV_HST - RECV
1130 * Confirm that the reply TGS-REP packet for krb5_mk_req(), for
1131 * the actual target service, as a SPN, not a any other name type.
1135 static bool torture_krb5_post_recv_tgs_req_host_test(struct torture_krb5_context
*test_context
, const krb5_data
*recv_buf
)
1138 torture_assert_int_equal(test_context
->tctx
,
1139 decode_TGS_REP(recv_buf
->data
, recv_buf
->length
,
1140 &test_context
->tgs_rep
, &used
),
1142 "decode_TGS_REP failed");
1143 torture_assert_int_equal(test_context
->tctx
, used
, recv_buf
->length
,
1145 torture_assert_int_equal(test_context
->tctx
,
1146 test_context
->tgs_rep
.pvno
, 5,
1147 "Got wrong as_rep->pvno");
1148 torture_assert_int_equal(test_context
->tctx
,
1149 test_context
->tgs_rep
.ticket
.tkt_vno
, 5,
1150 "Got wrong as_rep->ticket.tkt_vno");
1151 torture_assert(test_context
->tctx
,
1152 test_context
->tgs_rep
.ticket
.enc_part
.kvno
,
1153 "Did not get a KVNO in test_context->as_rep.ticket.enc_part.kvno");
1154 torture_assert_str_equal(test_context
->tctx
,
1155 test_context
->tgs_rep
.ticket
.realm
,
1156 test_context
->test_data
->real_realm
,
1157 "Mismatch in realm between ticket response and expected upper case REALM");
1158 torture_assert_int_equal(test_context
->tctx
,
1159 test_context
->tgs_req
.req_body
.sname
->name_type
,
1160 test_context
->tgs_rep
.ticket
.sname
.name_type
, "Mismatch in name_type between request and ticket response");
1161 torture_assert_int_equal(test_context
->tctx
,
1162 test_context
->tgs_rep
.ticket
.sname
.name_string
.len
, 2,
1163 "Mismatch in name between request and expected request, expected service/hostname");
1164 torture_assert_str_equal(test_context
->tctx
,
1165 test_context
->tgs_rep
.ticket
.sname
.name_string
.val
[0],
1166 test_context
->tgs_req
.req_body
.sname
->name_string
.val
[0],
1167 "Mismatch in name between request and expected request, expected service/hostname");
1168 torture_assert_str_equal(test_context
->tctx
,
1169 test_context
->tgs_rep
.ticket
.sname
.name_string
.val
[1],
1170 test_context
->tgs_req
.req_body
.sname
->name_string
.val
[1],
1171 "Mismatch in name between request and expected request, expected service/hostname");
1173 torture_assert_int_equal(test_context
->tctx
,
1174 *test_context
->tgs_rep
.ticket
.enc_part
.kvno
& 0xFFFF0000,
1175 0, "Unexpecedly got a RODC number in the KVNO, should just be principal KVNO");
1176 free_TGS_REP(&test_context
->tgs_rep
);
1178 torture_assert(test_context
->tctx
, test_context
->packet_count
< 2, "too many packets");
1183 * TEST_AS_REQ_SELF - RECV
1185 * Confirm that the reply packet from the KDC meets certain
1186 * expectations as part of TEST_AS_REQ. This uses a packet count to
1187 * work out what packet we are up to in the multiple exchanged
1188 * triggerd by krb5_get_init_creds_password().
1192 static bool torture_krb5_post_recv_as_req_self_test(struct torture_krb5_context
*test_context
,
1193 const krb5_data
*recv_buf
)
1197 if (test_context
->packet_count
== 0) {
1198 krb5_error_code k5ret
;
1200 * The client libs obtain the salt by attempting to
1201 * authenticate without pre-authentication and getting
1202 * the correct salt with the
1203 * KRB5KDC_ERR_PREAUTH_REQUIRED error. If we are in
1204 * the test (netbios_realm && upn) that deliberatly
1205 * has an incorrect principal, we check we get the
1208 k5ret
= decode_KRB_ERROR(recv_buf
->data
, recv_buf
->length
,
1212 k5ret
= decode_AS_REP(recv_buf
->data
, recv_buf
->length
,
1215 if (torture_setting_bool(test_context
->tctx
, "expect_machine_account", false) == false
1216 || (test_context
->test_data
->upn
== true)) {
1217 torture_assert(test_context
->tctx
, false,
1218 "expected to get a KRB_ERROR packet with "
1219 "KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN or KRB5KDC_ERR_PREAUTH_REQUIRED, got valid AS-REP");
1221 torture_assert(test_context
->tctx
, false,
1222 "expected to get a KRB_ERROR packet with "
1223 "KRB5KDC_ERR_PREAUTH_REQUIRED, got valid AS-REP");
1226 if (torture_setting_bool(test_context
->tctx
, "expect_machine_account", false) == false
1227 || (test_context
->test_data
->upn
== true)) {
1228 torture_assert(test_context
->tctx
, false,
1229 "unable to decode as KRB-ERROR or AS-REP, "
1230 "expected to get a KRB_ERROR packet with KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN or KRB5KDC_ERR_PREAUTH_REQUIRED");
1232 torture_assert(test_context
->tctx
, false,
1233 "unable to decode as KRB-ERROR or AS-REP, "
1234 "expected to get a KRB_ERROR packet with KRB5KDC_ERR_PREAUTH_REQUIRED");
1238 torture_assert_int_equal(test_context
->tctx
, used
, recv_buf
->length
,
1240 torture_assert_int_equal(test_context
->tctx
, error
.pvno
, 5,
1241 "Got wrong error.pvno");
1242 if ((torture_setting_bool(test_context
->tctx
, "expect_machine_account", false) == false
1243 || (test_context
->test_data
->upn
== true))
1244 && error
.error_code
== KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN
- KRB5KDC_ERR_NONE
) {
1248 * This case is because Samba's Heimdal KDC
1249 * checks server and client accounts before
1250 * checking for pre-authentication.
1253 torture_assert_int_equal(test_context
->tctx
,
1255 KRB5KDC_ERR_PREAUTH_REQUIRED
- KRB5KDC_ERR_NONE
,
1256 "Got wrong error.error_code");
1259 free_KRB_ERROR(&error
);
1260 } else if ((decode_KRB_ERROR(recv_buf
->data
, recv_buf
->length
, &error
, &used
) == 0)
1261 && (test_context
->packet_count
== 1)) {
1263 * The Windows 2012R2 KDC will always respond with
1264 * KRB5KRB_ERR_RESPONSE_TOO_BIG over UDP as the ticket
1265 * won't fit, because of the PAC. (It appears to do
1266 * this always, even if it will). This triggers the
1267 * client to try again over TCP.
1269 torture_assert_int_equal(test_context
->tctx
,
1270 used
, recv_buf
->length
,
1272 torture_assert_int_equal(test_context
->tctx
,
1274 "Got wrong error.pvno");
1275 if ((torture_setting_bool(test_context
->tctx
, "expect_machine_account", false)
1276 && ((test_context
->test_data
->upn
== false)
1277 || (test_context
->test_data
->as_req_spn
&&
1278 test_context
->test_data
->spn_is_upn
)
1279 || (test_context
->test_data
->enterprise
== false &&
1280 test_context
->test_data
->upn
&&
1281 test_context
->test_data
->spn_is_upn
)))) {
1282 torture_assert_int_equal(test_context
->tctx
,
1284 KRB5KRB_ERR_RESPONSE_TOO_BIG
- KRB5KDC_ERR_NONE
,
1285 "Got wrong error.error_code");
1287 torture_assert_int_equal(test_context
->tctx
,
1289 KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN
- KRB5KDC_ERR_NONE
,
1290 "Got wrong error.error_code");
1292 free_KRB_ERROR(&error
);
1295 * Finally the successful packet.
1297 torture_assert_int_equal(test_context
->tctx
,
1298 decode_AS_REP(recv_buf
->data
, recv_buf
->length
,
1299 &test_context
->as_rep
, &used
), 0,
1300 "decode_AS_REP failed");
1301 torture_assert_int_equal(test_context
->tctx
, used
, recv_buf
->length
,
1303 torture_assert_int_equal(test_context
->tctx
,
1304 test_context
->as_rep
.pvno
, 5,
1305 "Got wrong as_rep->pvno");
1306 torture_assert_int_equal(test_context
->tctx
,
1307 test_context
->as_rep
.ticket
.tkt_vno
, 5,
1308 "Got wrong as_rep->ticket.tkt_vno");
1309 torture_assert(test_context
->tctx
,
1310 test_context
->as_rep
.ticket
.enc_part
.kvno
,
1311 "Did not get a KVNO in test_context->as_rep.ticket.enc_part.kvno");
1314 * We do not expect an RODC number here in the KVNO,
1315 * as this is a ticket to the user's own account.
1317 torture_assert_int_equal(test_context
->tctx
,
1318 *test_context
->as_rep
.ticket
.enc_part
.kvno
& 0xFFFF0000,
1319 0, "Unexpecedly got a RODC number in the KVNO");
1320 free_AS_REP(&test_context
->as_rep
);
1322 torture_assert(test_context
->tctx
, test_context
->packet_count
< 3, "too many packets");
1323 free_AS_REQ(&test_context
->as_req
);
1328 * This function is set in torture_krb5_init_context_canon as krb5
1329 * send_and_recv function. This allows us to override what server the
1330 * test is aimed at, and to inspect the packets just before they are
1331 * sent to the network, and before they are processed on the recv
1334 * The torture_krb5_pre_send_test() and torture_krb5_post_recv_test()
1335 * functions are implement the actual tests.
1337 * When this asserts, the caller will get a spurious 'cannot contact
1341 static krb5_error_code
smb_krb5_send_and_recv_func_canon_override(krb5_context context
,
1342 void *data
, /* struct torture_krb5_context */
1343 krb5_krbhst_info
*hi
,
1345 const krb5_data
*send_buf
,
1346 krb5_data
*recv_buf
)
1348 krb5_error_code k5ret
;
1350 krb5_data modified_send_buf
;
1352 struct torture_krb5_context
*test_context
1353 = talloc_get_type_abort(data
, struct torture_krb5_context
);
1355 switch (test_context
->test_stage
) {
1357 torture_warning(test_context
->tctx
, "Unexpected outgoing packet from krb5 libs");
1360 ok
= torture_krb5_pre_send_as_req_test(test_context
, send_buf
,
1361 &modified_send_buf
);
1363 case TEST_TGS_REQ_KRBTGT_CANON
:
1364 ok
= torture_krb5_pre_send_tgs_req_krbtgt_canon_test(test_context
, send_buf
,
1365 &modified_send_buf
);
1367 case TEST_TGS_REQ_CANON
:
1368 ok
= torture_krb5_pre_send_tgs_req_canon_test(test_context
, send_buf
,
1369 &modified_send_buf
);
1371 case TEST_SELF_TRUST_TGS_REQ
:
1372 ok
= torture_krb5_pre_send_self_trust_tgs_req_test(test_context
, send_buf
,
1373 &modified_send_buf
);
1376 ok
= torture_krb5_pre_send_tgs_req_test(test_context
, send_buf
,
1377 &modified_send_buf
);
1379 case TEST_TGS_REQ_KRBTGT
:
1380 ok
= torture_krb5_pre_send_tgs_req_krbtgt_test(test_context
, send_buf
,
1381 &modified_send_buf
);
1383 case TEST_TGS_REQ_HOST
:
1384 case TEST_TGS_REQ_HOST_SRV_INST
:
1385 case TEST_TGS_REQ_HOST_SRV_HST
:
1386 ok
= torture_krb5_pre_send_tgs_req_host_test(test_context
, send_buf
,
1387 &modified_send_buf
);
1389 case TEST_AS_REQ_SELF
:
1390 ok
= torture_krb5_pre_send_as_req_test(test_context
, send_buf
,
1391 &modified_send_buf
);
1398 k5ret
= smb_krb5_send_and_recv_func_forced(context
, test_context
->server
,
1399 hi
, timeout
, &modified_send_buf
,
1405 switch (test_context
->test_stage
) {
1407 torture_warning(test_context
->tctx
, "Unexpected outgoing packet from krb5 libs");
1410 ok
= torture_krb5_post_recv_as_req_test(test_context
, recv_buf
);
1412 case TEST_TGS_REQ_KRBTGT_CANON
:
1413 ok
= torture_krb5_post_recv_tgs_req_krbtgt_canon_test(test_context
, recv_buf
);
1415 case TEST_TGS_REQ_CANON
:
1416 ok
= torture_krb5_post_recv_tgs_req_canon_test(test_context
, recv_buf
);
1418 case TEST_SELF_TRUST_TGS_REQ
:
1419 ok
= torture_krb5_post_recv_self_trust_tgs_req_test(test_context
, recv_buf
);
1422 ok
= torture_krb5_post_recv_tgs_req_test(test_context
, recv_buf
);
1424 case TEST_TGS_REQ_KRBTGT
:
1425 ok
= torture_krb5_post_recv_self_trust_tgs_req_test(test_context
, recv_buf
);
1427 case TEST_TGS_REQ_HOST
:
1428 case TEST_TGS_REQ_HOST_SRV_INST
:
1429 case TEST_TGS_REQ_HOST_SRV_HST
:
1430 ok
= torture_krb5_post_recv_tgs_req_host_test(test_context
, recv_buf
);
1432 case TEST_AS_REQ_SELF
:
1433 ok
= torture_krb5_post_recv_as_req_self_test(test_context
, recv_buf
);
1439 torture_warning(test_context
->tctx
, "Packet of length %llu failed post-recv checks in test stage %d", (unsigned long long)recv_buf
->length
, test_context
->test_stage
);
1440 if (decode_KRB_ERROR(recv_buf
->data
, recv_buf
->length
, &error
, &used
) == 0) {
1441 torture_warning(test_context
->tctx
,
1442 "STAGE: %d Unexpectedly got a KRB-ERROR packet "
1443 "with error code %d (%s)",
1444 test_context
->test_stage
,
1446 error_message(error
.error_code
+ KRB5KDC_ERR_NONE
));
1447 free_KRB_ERROR(&error
);
1452 test_context
->packet_count
++;
1457 static int test_context_destructor(struct torture_krb5_context
*test_context
)
1459 freeaddrinfo(test_context
->server
);
1464 static bool torture_krb5_init_context_canon(struct torture_context
*tctx
,
1465 struct test_data
*test_data
,
1466 struct torture_krb5_context
**torture_krb5_context
)
1468 const char *host
= torture_setting_string(tctx
, "host", NULL
);
1469 krb5_error_code k5ret
;
1472 struct torture_krb5_context
*test_context
= talloc_zero(tctx
, struct torture_krb5_context
);
1473 torture_assert(tctx
, test_context
!= NULL
, "Failed to allocate");
1475 test_context
->test_data
= test_data
;
1476 test_context
->tctx
= tctx
;
1478 k5ret
= smb_krb5_init_context(test_context
, tctx
->lp_ctx
, &test_context
->smb_krb5_context
);
1479 torture_assert_int_equal(tctx
, k5ret
, 0, "smb_krb5_init_context failed");
1481 ok
= interpret_string_addr_internal(&test_context
->server
, host
, AI_NUMERICHOST
);
1482 torture_assert(tctx
, ok
, "Failed to parse target server");
1484 talloc_set_destructor(test_context
, test_context_destructor
);
1486 set_sockaddr_port(test_context
->server
->ai_addr
, 88);
1488 k5ret
= krb5_set_send_to_kdc_func(test_context
->smb_krb5_context
->krb5_context
,
1489 smb_krb5_send_and_recv_func_canon_override
,
1491 torture_assert_int_equal(tctx
, k5ret
, 0, "krb5_set_send_to_kdc_func failed");
1492 *torture_krb5_context
= test_context
;
1497 static bool torture_krb5_as_req_canon(struct torture_context
*tctx
, const void *tcase_data
)
1499 krb5_error_code k5ret
;
1500 krb5_get_init_creds_opt
*krb_options
= NULL
;
1501 struct test_data
*test_data
= talloc_get_type_abort(tcase_data
, struct test_data
);
1502 krb5_principal principal
;
1503 krb5_principal krbtgt_other
;
1504 krb5_principal expected_principal
;
1505 const char *principal_string
= NULL
;
1506 char *krbtgt_other_string
;
1507 int principal_flags
;
1508 const char *expected_principal_string
= NULL
;
1509 char *expected_unparse_principal_string
;
1510 int expected_principal_flags
;
1511 char *got_principal_string
;
1512 char *assertion_message
;
1513 const char *password
= cli_credentials_get_password(
1514 popt_get_cmdline_credentials());
1515 krb5_context k5_context
;
1516 struct torture_krb5_context
*test_context
;
1518 krb5_creds my_creds
;
1519 krb5_creds
*server_creds
;
1521 krb5_auth_context auth_context
;
1523 krb5_data in_data
, enc_ticket
;
1524 krb5_get_creds_opt opt
;
1526 const char *spn
= NULL
;
1527 const char *spn_real_realm
= NULL
;
1528 const char *upn
= torture_setting_string(tctx
, "krb5-upn", "");
1529 test_data
->krb5_service
= torture_setting_string(tctx
, "krb5-service", "host");
1530 test_data
->krb5_hostname
= torture_setting_string(tctx
, "krb5-hostname", "");
1533 * If we have not passed a UPN on the command line,
1534 * then skip the UPN tests.
1536 if (test_data
->upn
&& upn
[0] == '\0') {
1537 torture_skip(tctx
, "This test needs a UPN specified as --option=torture:krb5-upn=user@example.com to run");
1541 * If we have not passed a SPN on the command line,
1542 * then skip the SPN tests.
1544 if (test_data
->as_req_spn
&& test_data
->krb5_hostname
[0] == '\0') {
1545 torture_skip(tctx
, "This test needs a hostname specified as --option=torture:krb5-hostname=hostname.example.com and optinally --option=torture:krb5-service=service (defaults to host) to run");
1548 if (test_data
->removedollar
&&
1549 !torture_setting_bool(tctx
, "run_removedollar_test", false))
1551 torture_skip(tctx
, "--option=torture:run_removedollar_test=true not specified");
1554 if (test_data
->netbios_realm
) {
1555 test_data
->realm
= test_data
->real_domain
;
1557 test_data
->realm
= test_data
->real_realm
;
1560 if (test_data
->upn
) {
1562 test_data
->username
= talloc_strdup(test_data
, upn
);
1563 p
= strchr(test_data
->username
, '@');
1569 * Test the UPN behaviour carefully. We can
1570 * test in two different modes, depending on
1571 * what UPN has been set up for us.
1573 * If the UPN is in our realm, then we do all the tests with this name also.
1575 * If the UPN is not in our realm, then we
1576 * expect the tests that replace the realm to
1577 * fail (as it won't match)
1579 if (strcasecmp(p
, test_data
->real_realm
) != 0) {
1580 test_data
->other_upn_suffix
= true;
1582 test_data
->other_upn_suffix
= false;
1586 * This lets us test the combination of the UPN prefix
1587 * with a valid domain, without adding even more
1590 if (test_data
->netbios_realm
== false) {
1591 test_data
->realm
= p
;
1595 ok
= torture_krb5_init_context_canon(tctx
, test_data
, &test_context
);
1596 torture_assert(tctx
, ok
, "torture_krb5_init_context failed");
1597 k5_context
= test_context
->smb_krb5_context
->krb5_context
;
1599 if (test_data
->upper_realm
) {
1600 test_data
->realm
= strupper_talloc(test_data
, test_data
->realm
);
1602 test_data
->realm
= strlower_talloc(test_data
, test_data
->realm
);
1604 if (test_data
->upper_username
) {
1605 test_data
->username
= strupper_talloc(test_data
, test_data
->username
);
1607 test_data
->username
= talloc_strdup(test_data
, test_data
->username
);
1610 if (test_data
->removedollar
) {
1613 p
= strchr_m(test_data
->username
, '$');
1614 torture_assert(tctx
, p
!= NULL
, talloc_asprintf(tctx
,
1615 "username[%s] contains no '$'\n",
1616 test_data
->username
));
1620 spn
= talloc_asprintf(test_data
, "%s/%s@%s",
1621 test_data
->krb5_service
,
1622 test_data
->krb5_hostname
,
1625 spn_real_realm
= talloc_asprintf(test_data
, "%s/%s@%s",
1626 test_data
->krb5_service
,
1627 test_data
->krb5_hostname
,
1628 test_data
->real_realm
);
1630 if (test_data
->as_req_spn
) {
1631 if (test_data
->enterprise
) {
1633 "This test combination "
1634 "is skipped intentionally");
1636 principal_string
= spn
;
1638 principal_string
= talloc_asprintf(test_data
,
1640 test_data
->username
,
1645 test_data
->spn_is_upn
1646 = (strcasecmp(upn
, spn
) == 0);
1649 * If we are set to canonicalize, we get back the fixed UPPER
1650 * case realm, and the real username (ie matching LDAP
1653 * Otherwise, if we are set to enterprise, we
1654 * get back the whole principal as-sent
1656 * Finally, if we are not set to canonicalize, we get back the
1657 * fixed UPPER case realm, but the as-sent username
1659 if (test_data
->as_req_spn
&& !test_data
->spn_is_upn
) {
1660 expected_principal_string
= spn
;
1661 } else if (test_data
->canonicalize
) {
1662 expected_principal_string
= talloc_asprintf(test_data
,
1664 test_data
->real_username
,
1665 test_data
->real_realm
);
1666 } else if (test_data
->enterprise
) {
1667 expected_principal_string
= principal_string
;
1668 } else if (test_data
->as_req_spn
&& test_data
->spn_is_upn
) {
1669 expected_principal_string
= spn_real_realm
;
1671 expected_principal_string
= talloc_asprintf(test_data
,
1673 test_data
->username
,
1674 test_data
->real_realm
);
1677 if (test_data
->enterprise
) {
1678 principal_flags
= KRB5_PRINCIPAL_PARSE_ENTERPRISE
;
1680 if (test_data
->upn
&& test_data
->other_upn_suffix
) {
1681 torture_skip(tctx
, "UPN test for UPN with other UPN suffix only runs with enterprise principals");
1683 principal_flags
= 0;
1686 if (test_data
->canonicalize
) {
1687 expected_principal_flags
= 0;
1689 expected_principal_flags
= principal_flags
;
1692 torture_assert_int_equal(tctx
,
1693 krb5_parse_name_flags(k5_context
,
1697 0, "krb5_parse_name_flags failed");
1698 torture_assert_int_equal(tctx
,
1699 krb5_parse_name_flags(k5_context
,
1700 expected_principal_string
,
1701 expected_principal_flags
,
1702 &expected_principal
),
1703 0, "krb5_parse_name_flags failed");
1705 if (test_data
->as_req_spn
) {
1706 if (test_data
->upn
) {
1707 krb5_principal_set_type(k5_context
,
1710 krb5_principal_set_type(k5_context
,
1714 krb5_principal_set_type(k5_context
,
1717 krb5_principal_set_type(k5_context
,
1723 torture_assert_int_equal(tctx
,
1724 krb5_unparse_name(k5_context
,
1726 &expected_unparse_principal_string
),
1727 0, "krb5_unparse_name failed");
1729 * Prepare a AS-REQ and run the TEST_AS_REQ tests
1733 test_context
->test_stage
= TEST_AS_REQ
;
1734 test_context
->packet_count
= 0;
1737 * Set the canonicalize flag if this test requires it
1739 torture_assert_int_equal(tctx
,
1740 krb5_get_init_creds_opt_alloc(k5_context
, &krb_options
),
1741 0, "krb5_get_init_creds_opt_alloc failed");
1743 torture_assert_int_equal(tctx
,
1744 krb5_get_init_creds_opt_set_canonicalize(k5_context
,
1746 test_data
->canonicalize
),
1747 0, "krb5_get_init_creds_opt_set_canonicalize failed");
1749 torture_assert_int_equal(tctx
,
1750 krb5_get_init_creds_opt_set_win2k(k5_context
,
1753 0, "krb5_get_init_creds_opt_set_win2k failed");
1755 k5ret
= krb5_get_init_creds_password(k5_context
, &my_creds
, principal
,
1756 password
, NULL
, NULL
, 0,
1759 if (test_data
->netbios_realm
&& test_data
->upn
) {
1760 torture_assert_int_equal(tctx
, k5ret
,
1761 KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN
,
1762 "Got wrong error_code from krb5_get_init_creds_password");
1763 /* We can't proceed with more checks */
1765 } else if (test_context
->test_data
->as_req_spn
1766 && !test_context
->test_data
->spn_is_upn
) {
1767 torture_assert_int_equal(tctx
, k5ret
,
1768 KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN
,
1769 "Got wrong error_code from "
1770 "krb5_get_init_creds_password");
1771 /* We can't proceed with more checks */
1774 assertion_message
= talloc_asprintf(tctx
,
1775 "krb5_get_init_creds_password for %s failed: %s",
1777 smb_get_krb5_error_message(k5_context
, k5ret
, tctx
));
1778 torture_assert_int_equal(tctx
, k5ret
, 0, assertion_message
);
1781 torture_assert(tctx
,
1782 test_context
->packet_count
> 1,
1783 "Expected krb5_get_init_creds_password to send more packets");
1786 * Assert that the reply was with the correct type of
1787 * principal, depending on the flags we set
1789 if (test_data
->canonicalize
== false && test_data
->enterprise
) {
1790 torture_assert_int_equal(tctx
,
1791 krb5_principal_get_type(k5_context
,
1793 KRB5_NT_ENTERPRISE_PRINCIPAL
,
1794 "smb_krb5_init_context gave incorrect client->name.name_type");
1795 } else if (test_data
->canonicalize
== false && test_data
->as_req_spn
) {
1796 torture_assert_int_equal(tctx
,
1797 krb5_principal_get_type(k5_context
,
1800 "smb_krb5_init_context gave incorrect client->name.name_type");
1802 torture_assert_int_equal(tctx
,
1803 krb5_principal_get_type(k5_context
,
1806 "smb_krb5_init_context gave incorrect client->name.name_type");
1809 torture_assert_int_equal(tctx
,
1810 krb5_unparse_name(k5_context
,
1811 my_creds
.client
, &got_principal_string
), 0,
1812 "krb5_unparse_name failed");
1814 assertion_message
= talloc_asprintf(tctx
,
1815 "krb5_get_init_creds_password returned a different principal %s to what was expected %s",
1816 got_principal_string
, expected_principal_string
);
1817 krb5_free_unparsed_name(k5_context
, got_principal_string
);
1819 torture_assert(tctx
, krb5_principal_compare(k5_context
,
1820 my_creds
.client
, expected_principal
),
1824 torture_assert_int_equal(tctx
,
1825 krb5_principal_get_type(k5_context
,
1826 my_creds
.server
), KRB5_NT_SRV_INST
,
1827 "smb_krb5_init_context gave incorrect server->name.name_type");
1829 torture_assert_int_equal(tctx
,
1830 krb5_principal_get_num_comp(k5_context
,
1831 my_creds
.server
), 2,
1832 "smb_krb5_init_context gave incorrect number of components in my_creds.server->name");
1834 torture_assert_str_equal(tctx
,
1835 krb5_principal_get_comp_string(k5_context
,
1836 my_creds
.server
, 0),
1838 "smb_krb5_init_context gave incorrect my_creds.server->name.name_string[0]");
1840 if (test_data
->canonicalize
|| test_data
->enterprise
) {
1841 torture_assert_str_equal(tctx
,
1842 krb5_principal_get_comp_string(k5_context
,
1843 my_creds
.server
, 1),
1844 test_data
->real_realm
,
1846 "smb_krb5_init_context gave incorrect my_creds.server->name.name_string[1]");
1848 torture_assert_str_equal(tctx
,
1849 krb5_principal_get_comp_string(k5_context
,
1850 my_creds
.server
, 1),
1853 "smb_krb5_init_context gave incorrect my_creds.server->name.name_string[1]");
1855 torture_assert_str_equal(tctx
,
1856 krb5_principal_get_realm(k5_context
,
1858 test_data
->real_realm
,
1859 "smb_krb5_init_context gave incorrect my_creds.server->realm");
1861 /* Store the result of the 'kinit' above into a memory ccache */
1862 cc_name
= talloc_asprintf(tctx
, "MEMORY:%s", test_data
->test_name
);
1863 torture_assert_int_equal(tctx
, krb5_cc_resolve(k5_context
, cc_name
,
1865 0, "krb5_cc_resolve failed");
1867 torture_assert_int_equal(tctx
, krb5_cc_initialize(k5_context
,
1868 ccache
, my_creds
.client
),
1869 0, "krb5_cc_initialize failed");
1871 torture_assert_int_equal(tctx
, krb5_cc_store_cred(k5_context
,
1873 0, "krb5_cc_store_cred failed");
1876 * Prepare a TGS-REQ and run the TEST_TGS_REQ_KRBTGT_CANON tests
1878 * This tests krb5_get_creds behaviour, which allows us to set
1879 * the KRB5_GC_CANONICALIZE option against the krbtgt/ principal
1882 krbtgt_other_string
= talloc_asprintf(test_data
, "krbtgt/%s@%s", test_data
->real_domain
, test_data
->real_realm
);
1883 torture_assert_int_equal(tctx
,
1884 krb5_make_principal(k5_context
, &krbtgt_other
,
1885 test_data
->real_realm
, "krbtgt",
1886 test_data
->real_domain
, NULL
),
1887 0, "krb5_make_principal failed");
1889 test_context
->test_stage
= TEST_TGS_REQ_KRBTGT_CANON
;
1890 test_context
->packet_count
= 0;
1892 torture_assert_int_equal(tctx
,
1893 krb5_get_creds_opt_alloc(k5_context
, &opt
),
1894 0, "krb5_get_creds_opt_alloc");
1896 krb5_get_creds_opt_add_options(k5_context
,
1898 KRB5_GC_CANONICALIZE
);
1900 krb5_get_creds_opt_add_options(k5_context
,
1904 /* Confirm if we can get a ticket krbtgt/realm that we got back with the initial kinit */
1905 k5ret
= krb5_get_creds(k5_context
, opt
, ccache
, krbtgt_other
, &server_creds
);
1907 if (test_data
->canonicalize
== false && test_data
->enterprise
== false
1908 && test_data
->netbios_realm
&& test_data
->upper_realm
) {
1910 * In these situations, the code above does store a
1911 * principal in the credentials cache matching what
1912 * krb5_get_creds() needs, so the test succeds, with no packets.
1915 assertion_message
= talloc_asprintf(tctx
,
1916 "krb5_get_creds for %s failed with: %s",
1917 krbtgt_other_string
,
1918 smb_get_krb5_error_message(k5_context
, k5ret
,
1921 torture_assert_int_equal(tctx
, k5ret
, 0, assertion_message
);
1922 torture_assert_int_equal(tctx
,
1923 test_context
->packet_count
,
1924 0, "Expected krb5_get_creds not to send packets");
1925 } else if (test_data
->canonicalize
== false && test_data
->enterprise
== false
1926 && (test_data
->upper_realm
== false || test_data
->netbios_realm
== true)) {
1927 torture_assert_int_equal(tctx
, k5ret
, KRB5_CC_NOTFOUND
,
1928 "krb5_get_creds should have failed with KRB5_CC_NOTFOUND");
1932 * In these situations, the code above does not store a
1933 * principal in the credentials cache matching what
1934 * krb5_get_creds() needs without talking to the KDC, so the
1935 * test fails with looping detected because when we set
1936 * canonicalize we confuse the client libs.
1939 assertion_message
= talloc_asprintf(tctx
,
1940 "krb5_get_creds for %s should have failed with looping detected: %s",
1941 krbtgt_other_string
,
1942 smb_get_krb5_error_message(k5_context
, k5ret
,
1945 torture_assert_int_equal(tctx
, k5ret
, KRB5_GET_IN_TKT_LOOP
, assertion_message
);
1946 torture_assert_int_equal(tctx
,
1947 test_context
->packet_count
,
1948 2, "Expected krb5_get_creds to send packets");
1952 * Prepare a TGS-REQ and run the TEST_TGS_REQ_CANON tests
1954 * This tests krb5_get_creds behaviour, which allows us to set
1955 * the KRB5_GC_CANONICALIZE option
1958 test_context
->test_stage
= TEST_TGS_REQ_CANON
;
1959 test_context
->packet_count
= 0;
1961 torture_assert_int_equal(tctx
,
1962 krb5_get_creds_opt_alloc(k5_context
, &opt
),
1963 0, "krb5_get_creds_opt_alloc");
1965 krb5_get_creds_opt_add_options(k5_context
,
1967 KRB5_GC_CANONICALIZE
);
1969 krb5_get_creds_opt_add_options(k5_context
,
1973 if (test_data
->s4u2self
) {
1974 torture_assert_int_equal(tctx
,
1975 krb5_get_creds_opt_set_impersonate(k5_context
,
1978 0, "krb5_get_creds_opt_set_impersonate failed");
1981 /* Confirm if we can get a ticket to our own name */
1982 k5ret
= krb5_get_creds(k5_context
, opt
, ccache
, principal
, &server_creds
);
1985 * In these situations, the code above does not store a
1986 * principal in the credentials cache matching what
1987 * krb5_get_creds() needs, so the test fails.
1990 if (test_data
->canonicalize
== false && test_data
->enterprise
== false
1991 && (test_data
->upper_realm
== false || test_data
->netbios_realm
== true)) {
1992 torture_assert_int_equal(tctx
, k5ret
, KRB5_CC_NOTFOUND
,
1993 "krb5_get_creds should have failed with KRB5_CC_NOTFOUND");
1995 assertion_message
= talloc_asprintf(tctx
,
1996 "krb5_get_creds for %s failed: %s",
1998 smb_get_krb5_error_message(k5_context
, k5ret
,
2002 * Only machine accounts (strictly, accounts with a
2003 * servicePrincipalName) can expect this test to succeed
2005 if (torture_setting_bool(tctx
, "expect_machine_account", false)
2006 && (test_data
->enterprise
2007 || test_data
->spn_is_upn
2008 || test_data
->upn
== false)) {
2009 torture_assert_int_equal(tctx
, k5ret
, 0, assertion_message
);
2010 torture_assert_int_equal(tctx
, krb5_cc_store_cred(k5_context
,
2011 ccache
, server_creds
),
2012 0, "krb5_cc_store_cred failed");
2014 torture_assert_int_equal(tctx
,
2015 krb5_free_creds(k5_context
,
2017 0, "krb5_free_cred_contents failed");
2020 torture_assert_int_equal(tctx
, k5ret
, KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN
,
2024 torture_assert_int_equal(tctx
,
2025 test_context
->packet_count
,
2026 1, "Expected krb5_get_creds to send packets");
2030 * Confirm gettting a ticket to pass to the server, running
2031 * either the TEST_TGS_REQ or TEST_SELF_TRUST_TGS_REQ stage.
2033 * This triggers the client to attempt to get a
2034 * cross-realm ticket between the alternate names of
2035 * the server, and we need to confirm that behaviour.
2040 * This tries to guess when the krb5 libs will ask for a
2041 * cross-realm ticket, and when they will just ask the KDC
2044 if (test_context
->test_data
->canonicalize
== false
2045 || test_context
->test_data
->enterprise
2046 || (test_context
->test_data
->spn_is_upn
&& test_context
->test_data
->upn
)
2047 || (test_context
->test_data
->upper_realm
2048 && test_context
->test_data
->netbios_realm
== false)) {
2049 test_context
->test_stage
= TEST_TGS_REQ
;
2051 test_context
->test_stage
= TEST_SELF_TRUST_TGS_REQ
;
2054 test_context
->packet_count
= 0;
2055 torture_assert_int_equal(tctx
, krb5_auth_con_init(k5_context
, &auth_context
),
2056 0, "krb5_auth_con_init failed");
2059 k5ret
= krb5_mk_req_exact(k5_context
,
2065 assertion_message
= talloc_asprintf(tctx
,
2066 "krb5_mk_req_exact for %s failed: %s",
2068 smb_get_krb5_error_message(k5_context
, k5ret
, tctx
));
2071 * Only machine accounts (strictly, accounts with a
2072 * servicePrincipalName) can expect this test to succeed
2074 if (torture_setting_bool(tctx
, "expect_machine_account", false)
2075 && (test_data
->enterprise
||
2076 (test_context
->test_data
->as_req_spn
2077 || test_context
->test_data
->spn_is_upn
)
2078 || test_data
->upn
== false)) {
2079 DATA_BLOB client_to_server
;
2080 torture_assert_int_equal(tctx
, k5ret
, 0, assertion_message
);
2081 client_to_server
= data_blob_const(enc_ticket
.data
, enc_ticket
.length
);
2083 /* This is very weird */
2084 if (test_data
->canonicalize
== false
2085 && test_context
->test_data
->as_req_spn
2086 && test_context
->test_data
->spn_is_upn
2087 && test_context
->test_data
->s4u2self
) {
2089 torture_assert(tctx
,
2090 test_accept_ticket(tctx
,
2091 popt_get_cmdline_credentials(),
2094 "test_accept_ticket failed - failed to accept the ticket we just created");
2095 } else if (test_data
->canonicalize
== true
2096 && test_context
->test_data
->as_req_spn
2097 && test_context
->test_data
->spn_is_upn
2098 && test_context
->test_data
->s4u2self
) {
2100 torture_assert(tctx
,
2101 test_accept_ticket(tctx
,
2102 popt_get_cmdline_credentials(),
2105 "test_accept_ticket failed - failed to accept the ticket we just created");
2106 } else if (test_data
->canonicalize
== true
2107 && test_data
->enterprise
== false
2108 && test_context
->test_data
->upn
2109 && test_context
->test_data
->spn_is_upn
2110 && test_context
->test_data
->s4u2self
) {
2112 torture_assert(tctx
,
2113 test_accept_ticket(tctx
,
2114 popt_get_cmdline_credentials(),
2117 "test_accept_ticket failed - failed to accept the ticket we just created");
2118 } else if (test_data
->canonicalize
== false
2119 && test_data
->enterprise
== false
2120 && test_context
->test_data
->upn
2121 && test_context
->test_data
->spn_is_upn
2122 && test_context
->test_data
->s4u2self
) {
2124 const char *accept_expected_principal_string
2125 = talloc_asprintf(test_data
,
2127 test_data
->username
,
2128 test_data
->real_realm
);
2130 torture_assert(tctx
,
2131 test_accept_ticket(tctx
,
2132 popt_get_cmdline_credentials(),
2133 accept_expected_principal_string
,
2135 "test_accept_ticket failed - failed to accept the ticket we just created");
2138 torture_assert(tctx
,
2139 test_accept_ticket(tctx
,
2140 popt_get_cmdline_credentials(),
2141 expected_unparse_principal_string
,
2143 "test_accept_ticket failed - failed to accept the ticket we just created");
2145 krb5_data_free(&enc_ticket
);
2147 torture_assert_int_equal(tctx
, k5ret
, KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN
,
2152 * Only in these cases would the above code have needed to
2153 * send packets to the network
2155 if (test_data
->canonicalize
== false && test_data
->enterprise
== false
2156 && (test_data
->upper_realm
== false || test_data
->netbios_realm
== true)) {
2157 torture_assert(tctx
,
2158 test_context
->packet_count
> 0,
2159 "Expected krb5_mk_req_exact to send packets");
2163 * Confirm gettting a ticket to pass to the server, running
2164 * the TEST_TGS_REQ_HOST, TEST_TGS_REQ_HOST_SRV_INST, TEST_TGS_REQ_HOST_SRV_HST stage
2166 * This triggers the client to attempt to get a
2167 * cross-realm ticket between the alternate names of
2168 * the server, and we need to confirm that behaviour.
2172 if (*test_data
->krb5_service
&& *test_data
->krb5_hostname
) {
2173 bool implied_canonicalize
;
2174 krb5_principal host_principal_srv_inst
;
2176 * This tries to guess when the krb5 libs will ask for a
2177 * cross-realm ticket, and when they will just ask the KDC
2180 test_context
->test_stage
= TEST_TGS_REQ_HOST
;
2181 test_context
->packet_count
= 0;
2182 torture_assert_int_equal(tctx
, krb5_auth_con_init(k5_context
, &auth_context
),
2183 0, "krb5_auth_con_init failed");
2186 k5ret
= krb5_mk_req(k5_context
,
2189 test_data
->krb5_service
,
2190 test_data
->krb5_hostname
,
2194 implied_canonicalize
= test_data
->canonicalize
;
2195 if (test_data
->spn_is_upn
&& (test_data
->upn
|| test_data
->as_req_spn
)) {
2196 implied_canonicalize
= true;
2198 if (test_data
->enterprise
) {
2199 implied_canonicalize
= true;
2202 if (implied_canonicalize
== false
2203 && (test_data
->upper_realm
== false || test_data
->netbios_realm
== true)) {
2204 torture_assert_int_equal(tctx
, k5ret
, KRB5_CC_NOTFOUND
,
2205 "krb5_get_creds should have failed with KRB5_CC_NOTFOUND");
2206 } else if (test_data
->spn_is_upn
2207 && test_data
->canonicalize
== false
2208 && test_data
->enterprise
== false
2209 && test_data
->upper_realm
== false
2210 && test_data
->upper_username
== true
2211 && test_data
->upn
) {
2212 torture_assert_int_equal(tctx
, k5ret
, KRB5_CC_NOTFOUND
,
2213 "krb5_get_creds should have failed with KRB5_CC_NOTFOUND");
2215 assertion_message
= talloc_asprintf(tctx
,
2216 "krb5_mk_req for %s/%s failed: %s",
2217 test_data
->krb5_service
,
2218 test_data
->krb5_hostname
,
2219 smb_get_krb5_error_message(k5_context
, k5ret
, tctx
));
2221 torture_assert_int_equal(tctx
, k5ret
, 0, assertion_message
);
2223 if (test_data
->spn_is_upn
== false) {
2225 * Only in these cases would the above
2226 * code have needed to send packets to
2229 torture_assert(tctx
,
2230 test_context
->packet_count
> 0,
2231 "Expected krb5_get_creds to send packets");
2236 test_context
->test_stage
= TEST_TGS_REQ_HOST_SRV_INST
;
2237 test_context
->packet_count
= 0;
2239 torture_assert_int_equal(tctx
,
2240 krb5_make_principal(k5_context
, &host_principal_srv_inst
,
2241 test_data
->real_realm
,
2242 strupper_talloc(tctx
, test_data
->krb5_service
),
2243 test_data
->krb5_hostname
,
2245 0, "krb5_make_principal failed");
2247 krb5_principal_set_type(k5_context
, host_principal_srv_inst
, KRB5_NT_SRV_INST
);
2249 torture_assert_int_equal(tctx
, krb5_auth_con_init(k5_context
, &auth_context
),
2250 0, "krb5_auth_con_init failed");
2253 k5ret
= krb5_mk_req_exact(k5_context
,
2256 host_principal_srv_inst
,
2259 krb5_free_principal(k5_context
, host_principal_srv_inst
);
2260 if (test_data
->canonicalize
== false && test_data
->enterprise
== false
2261 && (test_data
->upper_realm
== false || test_data
->netbios_realm
== true)) {
2262 torture_assert_int_equal(tctx
, k5ret
, KRB5_CC_NOTFOUND
,
2263 "krb5_get_creds should have failed with KRB5_CC_NOTFOUND");
2265 assertion_message
= talloc_asprintf(tctx
,
2266 "krb5_mk_req for %s/%s KRB5_NT_SRV_INST failed: %s",
2267 test_data
->krb5_service
,
2268 test_data
->krb5_hostname
,
2269 smb_get_krb5_error_message(k5_context
, k5ret
, tctx
));
2271 torture_assert_int_equal(tctx
, k5ret
, 0, assertion_message
);
2273 * Only in these cases would the above code have needed to
2274 * send packets to the network
2276 torture_assert(tctx
,
2277 test_context
->packet_count
> 0,
2278 "Expected krb5_get_creds to send packets");
2282 test_context
->test_stage
= TEST_TGS_REQ_HOST_SRV_HST
;
2283 test_context
->packet_count
= 0;
2285 torture_assert_int_equal(tctx
,
2286 krb5_make_principal(k5_context
, &host_principal_srv_inst
,
2287 test_data
->real_realm
,
2288 test_data
->krb5_service
,
2289 strupper_talloc(tctx
, test_data
->krb5_hostname
),
2291 0, "krb5_make_principal failed");
2293 krb5_principal_set_type(k5_context
, host_principal_srv_inst
, KRB5_NT_SRV_HST
);
2295 torture_assert_int_equal(tctx
, krb5_auth_con_init(k5_context
, &auth_context
),
2296 0, "krb5_auth_con_init failed");
2299 k5ret
= krb5_mk_req_exact(k5_context
,
2302 host_principal_srv_inst
,
2305 krb5_free_principal(k5_context
, host_principal_srv_inst
);
2306 if (test_data
->canonicalize
== false && test_data
->enterprise
== false
2307 && (test_data
->upper_realm
== false || test_data
->netbios_realm
== true)) {
2308 torture_assert_int_equal(tctx
, k5ret
, KRB5_CC_NOTFOUND
,
2309 "krb5_get_creds should have failed with KRB5_CC_NOTFOUND");
2311 assertion_message
= talloc_asprintf(tctx
,
2312 "krb5_mk_req for %s/%s KRB5_NT_SRV_INST failed: %s",
2313 test_data
->krb5_service
,
2314 test_data
->krb5_hostname
,
2315 smb_get_krb5_error_message(k5_context
, k5ret
, tctx
));
2317 torture_assert_int_equal(tctx
, k5ret
, 0, assertion_message
);
2319 * Only in these cases would the above code have needed to
2320 * send packets to the network
2322 torture_assert(tctx
,
2323 test_context
->packet_count
> 0,
2324 "Expected krb5_get_creds to send packets");
2329 * Confirm gettting a ticket for the same krbtgt/realm that we
2330 * got back with the initial ticket, running the
2331 * TEST_TGS_REQ_KRBTGT stage.
2335 test_context
->test_stage
= TEST_TGS_REQ_KRBTGT
;
2336 test_context
->packet_count
= 0;
2339 k5ret
= krb5_mk_req_exact(k5_context
,
2346 assertion_message
= talloc_asprintf(tctx
,
2347 "krb5_mk_req_exact for %s failed: %s",
2349 smb_get_krb5_error_message(k5_context
, k5ret
, tctx
));
2350 torture_assert_int_equal(tctx
, k5ret
, 0, assertion_message
);
2353 * Confirm gettting a ticket for our own principal that we
2354 * got back with the initial ticket, running the
2355 * TEST_AS_REQ_SELF stage.
2358 test_context
->test_stage
= TEST_AS_REQ_SELF
;
2359 test_context
->packet_count
= 0;
2361 k5ret
= krb5_get_init_creds_password(k5_context
, &my_creds
, principal
,
2362 password
, NULL
, NULL
, 0,
2363 principal_string
, krb_options
);
2365 if (torture_setting_bool(test_context
->tctx
, "expect_machine_account", false)
2366 && (test_data
->upn
== false || (test_data
->enterprise
== false && test_data
->upn
== true && test_data
->spn_is_upn
))) {
2367 assertion_message
= talloc_asprintf(tctx
,
2368 "krb5_get_init_creds_password for %s failed: %s",
2370 smb_get_krb5_error_message(k5_context
, k5ret
, tctx
));
2371 torture_assert_int_equal(tctx
, k5ret
, 0, assertion_message
);
2372 torture_assert(tctx
,
2373 test_context
->packet_count
>= 2,
2374 "Expected krb5_get_init_creds_password to send more packets");
2377 assertion_message
= talloc_asprintf(tctx
,
2378 "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
);
2379 torture_assert_int_equal(tctx
, k5ret
,
2380 KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN
,
2382 torture_assert(tctx
,
2383 test_context
->packet_count
>= 1,
2384 "Expected krb5_get_init_creds_password to send more packets");
2386 /* We can't proceed with more checks */
2391 * Assert that the reply was with the correct type of
2392 * principal, depending on the flags we set
2394 if (test_data
->as_req_spn
&& test_data
->spn_is_upn
&& test_data
->canonicalize
== false) {
2395 torture_assert_int_equal(tctx
,
2396 krb5_principal_get_type(k5_context
,
2399 "smb_krb5_init_context gave incorrect client->name.name_type");
2400 torture_assert_int_equal(tctx
,
2401 krb5_principal_get_type(k5_context
,
2404 "smb_krb5_init_context gave incorrect server->name.name_type");
2405 } else if (test_data
->canonicalize
== false && test_data
->enterprise
) {
2406 torture_assert_int_equal(tctx
,
2407 krb5_principal_get_type(k5_context
,
2409 KRB5_NT_ENTERPRISE_PRINCIPAL
,
2410 "smb_krb5_init_context gave incorrect client->name.name_type");
2411 torture_assert_int_equal(tctx
,
2412 krb5_principal_get_type(k5_context
,
2414 KRB5_NT_ENTERPRISE_PRINCIPAL
,
2415 "smb_krb5_init_context gave incorrect server->name.name_type");
2417 torture_assert_int_equal(tctx
,
2418 krb5_principal_get_type(k5_context
,
2421 "smb_krb5_init_context gave incorrect client->name.name_type");
2422 torture_assert_int_equal(tctx
,
2423 krb5_principal_get_type(k5_context
,
2426 "smb_krb5_init_context gave incorrect server->name.name_type");
2429 torture_assert_int_equal(tctx
,
2430 krb5_unparse_name(k5_context
,
2431 my_creds
.client
, &got_principal_string
), 0,
2432 "krb5_unparse_name failed");
2434 assertion_message
= talloc_asprintf(tctx
,
2435 "krb5_get_init_creds_password returned a different principal %s to what was expected %s",
2436 got_principal_string
, expected_principal_string
);
2437 krb5_free_unparsed_name(k5_context
, got_principal_string
);
2439 torture_assert(tctx
, krb5_principal_compare(k5_context
,
2440 my_creds
.client
, expected_principal
),
2443 torture_assert_int_equal(tctx
,
2444 krb5_unparse_name(k5_context
,
2445 my_creds
.client
, &got_principal_string
), 0,
2446 "krb5_unparse_name failed");
2448 assertion_message
= talloc_asprintf(tctx
,
2449 "krb5_get_init_creds_password returned a different server principal %s to what was expected %s",
2450 got_principal_string
, expected_principal_string
);
2451 krb5_free_unparsed_name(k5_context
, got_principal_string
);
2453 torture_assert(tctx
, krb5_principal_compare(k5_context
,
2454 my_creds
.server
, expected_principal
),
2457 krb5_free_principal(k5_context
, principal
);
2458 krb5_get_init_creds_opt_free(k5_context
, krb_options
);
2460 torture_assert_int_equal(tctx
, krb5_free_cred_contents(k5_context
, &my_creds
),
2461 0, "krb5_free_cred_contents failed");
2466 struct torture_suite
*torture_krb5_canon(TALLOC_CTX
*mem_ctx
)
2469 struct torture_suite
*suite
= torture_suite_create(mem_ctx
, "canon");
2470 suite
->description
= talloc_strdup(suite
, "Kerberos Canonicalisation tests");
2472 for (i
= 0; i
< TEST_ALL
; i
++) {
2473 char *name
= talloc_asprintf(suite
, "%s.%s.%s.%s.%s.%s.%s.%s",
2474 (i
& TEST_CANONICALIZE
) ? "canon" : "no-canon",
2475 (i
& TEST_ENTERPRISE
) ? "enterprise" : "no-enterprise",
2476 (i
& TEST_UPPER_REALM
) ? "uc-realm" : "lc-realm",
2477 (i
& TEST_UPPER_USERNAME
) ? "uc-user" : "lc-user",
2478 (i
& TEST_NETBIOS_REALM
) ? "netbios-realm" : "krb5-realm",
2479 (i
& TEST_WIN2K
) ? "win2k" : "no-win2k",
2480 (i
& TEST_UPN
) ? "upn" :
2481 ((i
& TEST_AS_REQ_SPN
) ? "spn" :
2482 ((i
& TEST_REMOVEDOLLAR
) ? "removedollar" : "samaccountname")),
2483 (i
& TEST_S4U2SELF
) ? "s4u2self" : "normal");
2484 struct torture_suite
*sub_suite
= torture_suite_create(mem_ctx
, name
);
2486 struct test_data
*test_data
= talloc_zero(suite
, struct test_data
);
2488 if (i
& TEST_AS_REQ_SPN
) {
2492 if ((i
& TEST_UPN
) || (i
& TEST_AS_REQ_SPN
)) {
2493 if (i
& TEST_REMOVEDOLLAR
) {
2498 test_data
->test_name
= name
;
2499 test_data
->real_realm
2500 = strupper_talloc(test_data
,
2501 cli_credentials_get_realm(
2502 popt_get_cmdline_credentials()));
2503 test_data
->real_domain
= cli_credentials_get_domain(
2504 popt_get_cmdline_credentials());
2505 test_data
->username
= cli_credentials_get_username(
2506 popt_get_cmdline_credentials());
2507 test_data
->real_username
= cli_credentials_get_username(
2508 popt_get_cmdline_credentials());
2509 test_data
->canonicalize
= (i
& TEST_CANONICALIZE
) != 0;
2510 test_data
->enterprise
= (i
& TEST_ENTERPRISE
) != 0;
2511 test_data
->upper_realm
= (i
& TEST_UPPER_REALM
) != 0;
2512 test_data
->upper_username
= (i
& TEST_UPPER_USERNAME
) != 0;
2513 test_data
->netbios_realm
= (i
& TEST_NETBIOS_REALM
) != 0;
2514 test_data
->win2k
= (i
& TEST_WIN2K
) != 0;
2515 test_data
->upn
= (i
& TEST_UPN
) != 0;
2516 test_data
->s4u2self
= (i
& TEST_S4U2SELF
) != 0;
2517 test_data
->removedollar
= (i
& TEST_REMOVEDOLLAR
) != 0;
2518 test_data
->as_req_spn
= (i
& TEST_AS_REQ_SPN
) != 0;
2519 torture_suite_add_simple_tcase_const(sub_suite
, name
, torture_krb5_as_req_canon
,
2521 torture_suite_add_suite(suite
, sub_suite
);