2 Unix SMB/CIFS implementation.
4 Validate the krb5 pac generation routines
6 Copyright (C) Andrew Bartlett <abartlet@samba.org> 2005
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 "auth/auth.h"
26 #include "auth/kerberos/kerberos.h"
27 #include "librpc/gen_ndr/ndr_krb5pac.h"
28 #include "samba3/samba3.h"
29 #include "libcli/security/security.h"
30 #include "torture/torture.h"
32 static bool torture_pac_self_check(struct torture_context *tctx)
36 struct PAC_DATA *pac_data;
37 struct PAC_LOGON_INFO *logon_info;
38 union netr_Validation validation;
40 /* Generate a nice, arbitary keyblock */
41 uint8_t server_bytes[16];
42 uint8_t krbtgt_bytes[16];
43 krb5_keyblock server_keyblock;
44 krb5_keyblock krbtgt_keyblock;
48 struct smb_krb5_context *smb_krb5_context;
50 struct auth_serversupplied_info *server_info;
51 struct auth_serversupplied_info *server_info_out;
53 krb5_principal client_principal;
54 time_t logon_time = time(NULL);
56 TALLOC_CTX *mem_ctx = tctx;
58 torture_assert(tctx, 0 == smb_krb5_init_context(mem_ctx,
62 "smb_krb5_init_context");
64 generate_random_buffer(server_bytes, 16);
65 generate_random_buffer(krbtgt_bytes, 16);
67 ret = krb5_keyblock_init(smb_krb5_context->krb5_context,
69 server_bytes, sizeof(server_bytes),
71 torture_assert(tctx, !ret, talloc_asprintf(tctx,
72 "(self test) Server Keyblock encoding failed: %s",
73 smb_get_krb5_error_message(smb_krb5_context->krb5_context,
76 ret = krb5_keyblock_init(smb_krb5_context->krb5_context,
78 krbtgt_bytes, sizeof(krbtgt_bytes),
81 char *err = smb_get_krb5_error_message(smb_krb5_context->krb5_context,
84 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
87 torture_fail(tctx, talloc_asprintf(tctx,
88 "(self test) KRBTGT Keyblock encoding failed: %s", err));
91 /* We need an input, and this one requires no underlying database */
92 nt_status = auth_anonymous_server_info(mem_ctx, &server_info);
94 if (!NT_STATUS_IS_OK(nt_status)) {
95 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
97 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
99 torture_fail(tctx, "auth_anonymous_server_info");
102 ret = krb5_parse_name_flags(smb_krb5_context->krb5_context,
103 server_info->account_name,
104 KRB5_PRINCIPAL_PARSE_NO_REALM,
107 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
109 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
111 torture_fail(tctx, "krb5_parse_name_flags(norealm)");
114 /* OK, go ahead and make a PAC */
115 ret = kerberos_create_pac(mem_ctx, server_info,
116 smb_krb5_context->krb5_context,
124 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
126 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
128 krb5_free_principal(smb_krb5_context->krb5_context,
131 torture_fail(tctx, talloc_asprintf(tctx,
132 "(self test) PAC encoding failed: %s",
133 smb_get_krb5_error_message(smb_krb5_context->krb5_context,
137 dump_data(10,tmp_blob.data,tmp_blob.length);
139 /* Now check that we can read it back */
140 nt_status = kerberos_decode_pac(mem_ctx, &pac_data,
142 smb_krb5_context->krb5_context,
148 if (!NT_STATUS_IS_OK(nt_status)) {
149 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
151 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
153 krb5_free_principal(smb_krb5_context->krb5_context,
156 torture_fail(tctx, talloc_asprintf(tctx,
157 "(self test) PAC decoding failed: %s",
158 nt_errstr(nt_status)));
161 /* Now check that we can read it back */
162 nt_status = kerberos_pac_logon_info(mem_ctx, &logon_info,
164 smb_krb5_context->krb5_context,
171 if (!NT_STATUS_IS_OK(nt_status)) {
172 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
174 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
176 krb5_free_principal(smb_krb5_context->krb5_context,
180 talloc_asprintf(tctx,
181 "(self test) PAC decoding (for logon info) failed: %s",
182 nt_errstr(nt_status)));
185 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
187 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
189 krb5_free_principal(smb_krb5_context->krb5_context,
192 validation.sam3 = &logon_info->info3;
193 nt_status = make_server_info_netlogon_validation(mem_ctx,
197 if (!NT_STATUS_IS_OK(nt_status)) {
199 talloc_asprintf(tctx,
200 "(self test) PAC decoding (make server info) failed: %s",
201 nt_errstr(nt_status)));
204 if (!dom_sid_equal(server_info->account_sid,
205 server_info_out->account_sid)) {
207 talloc_asprintf(tctx,
208 "(self test) PAC Decode resulted in *different* domain SID: %s != %s",
209 dom_sid_string(mem_ctx, server_info->account_sid),
210 dom_sid_string(mem_ctx, server_info_out->account_sid)));
216 /* This is the PAC generated on my test network, by my test Win2k3 server.
217 -- abartlet 2005-07-04
220 static const uint8_t saved_pac[] = {
221 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xd8, 0x01, 0x00, 0x00,
222 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,
223 0x20, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
224 0x40, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
225 0x58, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x10, 0x08, 0x00, 0xcc, 0xcc, 0xcc, 0xcc,
226 0xc8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x30, 0xdf, 0xa6, 0xcb,
227 0x4f, 0x7d, 0xc5, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff,
228 0xff, 0xff, 0xff, 0x7f, 0xc0, 0x3c, 0x4e, 0x59, 0x62, 0x73, 0xc5, 0x01, 0xc0, 0x3c, 0x4e, 0x59,
229 0x62, 0x73, 0xc5, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x16, 0x00, 0x16, 0x00,
230 0x04, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
231 0x0c, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
232 0x14, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x02, 0x00, 0x65, 0x00, 0x00, 0x00,
233 0xed, 0x03, 0x00, 0x00, 0x04, 0x02, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x02, 0x00,
234 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
235 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x16, 0x00, 0x20, 0x00, 0x02, 0x00, 0x16, 0x00, 0x18, 0x00,
236 0x24, 0x00, 0x02, 0x00, 0x28, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
237 0x00, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
238 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
239 0x01, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
240 0x00, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00,
241 0x57, 0x00, 0x32, 0x00, 0x30, 0x00, 0x30, 0x00, 0x33, 0x00, 0x46, 0x00, 0x49, 0x00, 0x4e, 0x00,
242 0x41, 0x00, 0x4c, 0x00, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
243 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
244 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
245 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
246 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x02, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
247 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x57, 0x00, 0x32, 0x00,
248 0x30, 0x00, 0x30, 0x00, 0x33, 0x00, 0x46, 0x00, 0x49, 0x00, 0x4e, 0x00, 0x41, 0x00, 0x4c, 0x00,
249 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x57, 0x00, 0x49, 0x00,
250 0x4e, 0x00, 0x32, 0x00, 0x4b, 0x00, 0x33, 0x00, 0x54, 0x00, 0x48, 0x00, 0x49, 0x00, 0x4e, 0x00,
251 0x4b, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05,
252 0x15, 0x00, 0x00, 0x00, 0x11, 0x2f, 0xaf, 0xb5, 0x90, 0x04, 0x1b, 0xec, 0x50, 0x3b, 0xec, 0xdc,
253 0x01, 0x00, 0x00, 0x00, 0x30, 0x00, 0x02, 0x00, 0x07, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
254 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
255 0x80, 0x66, 0x28, 0xea, 0x37, 0x80, 0xc5, 0x01, 0x16, 0x00, 0x77, 0x00, 0x32, 0x00, 0x30, 0x00,
256 0x30, 0x00, 0x33, 0x00, 0x66, 0x00, 0x69, 0x00, 0x6e, 0x00, 0x61, 0x00, 0x6c, 0x00, 0x24, 0x00,
257 0x76, 0xff, 0xff, 0xff, 0x37, 0xd5, 0xb0, 0xf7, 0x24, 0xf0, 0xd6, 0xd4, 0xec, 0x09, 0x86, 0x5a,
258 0xa0, 0xe8, 0xc3, 0xa9, 0x00, 0x00, 0x00, 0x00, 0x76, 0xff, 0xff, 0xff, 0xb4, 0xd8, 0xb8, 0xfe,
259 0x83, 0xb3, 0x13, 0x3f, 0xfc, 0x5c, 0x41, 0xad, 0xe2, 0x64, 0x83, 0xe0, 0x00, 0x00, 0x00, 0x00
262 /* Check with a known 'well formed' PAC, from my test server */
263 static bool torture_pac_saved_check(struct torture_context *tctx)
266 enum ndr_err_code ndr_err;
267 DATA_BLOB tmp_blob, validate_blob;
268 struct PAC_DATA *pac_data, pac_data2;
269 struct PAC_LOGON_INFO *logon_info;
270 union netr_Validation validation;
271 const char *pac_file, *pac_kdc_key, *pac_member_key;
272 struct auth_serversupplied_info *server_info_out;
274 krb5_keyblock server_keyblock;
275 krb5_keyblock krbtgt_keyblock;
276 struct samr_Password *krbtgt_bytes, *krbsrv_bytes;
279 struct smb_krb5_context *smb_krb5_context;
281 const char *principal_string;
282 char *broken_principal_string;
283 krb5_principal client_principal;
284 const char *authtime_string;
286 TALLOC_CTX *mem_ctx = tctx;
288 torture_assert(tctx, 0 == smb_krb5_init_context(mem_ctx, NULL,
291 "smb_krb5_init_context");
293 pac_kdc_key = torture_setting_string(tctx, "pac_kdc_key",
294 "B286757148AF7FD252C53603A150B7E7");
296 pac_member_key = torture_setting_string(tctx, "pac_member_key",
297 "D217FAEAE5E6B5F95CCC94077AB8A5FC");
299 torture_comment(tctx, "Using pac_kdc_key '%s'\n", pac_kdc_key);
300 torture_comment(tctx, "Using pac_member_key '%s'\n", pac_member_key);
302 /* The krbtgt key in use when the above PAC was generated.
303 * This is an arcfour-hmac-md5 key, extracted with our 'net
305 krbtgt_bytes = smbpasswd_gethexpwd(mem_ctx, pac_kdc_key);
307 torture_fail(tctx, "(saved test) Could not interpret krbtgt key");
310 krbsrv_bytes = smbpasswd_gethexpwd(mem_ctx, pac_member_key);
312 torture_fail(tctx, "(saved test) Could not interpret krbsrv key");
315 ret = krb5_keyblock_init(smb_krb5_context->krb5_context,
316 ENCTYPE_ARCFOUR_HMAC,
317 krbsrv_bytes->hash, sizeof(krbsrv_bytes->hash),
319 torture_assert(tctx, !ret,
320 talloc_asprintf(tctx,
321 "(saved test) Server Keyblock encoding failed: %s",
322 smb_get_krb5_error_message(smb_krb5_context->krb5_context,
325 ret = krb5_keyblock_init(smb_krb5_context->krb5_context,
326 ENCTYPE_ARCFOUR_HMAC,
327 krbtgt_bytes->hash, sizeof(krbtgt_bytes->hash),
330 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
333 talloc_asprintf(tctx,
334 "(saved test) Server Keyblock encoding failed: %s",
335 smb_get_krb5_error_message(smb_krb5_context->krb5_context,
339 pac_file = torture_setting_string(tctx, "pac_file", NULL);
341 tmp_blob.data = (uint8_t *)file_load(pac_file, &tmp_blob.length, mem_ctx);
342 torture_comment(tctx, "(saved test) Loaded pac of size %ld from %s\n", (long)tmp_blob.length, pac_file);
344 tmp_blob = data_blob_talloc(mem_ctx, saved_pac, sizeof(saved_pac));
347 dump_data(10,tmp_blob.data,tmp_blob.length);
349 principal_string = torture_setting_string(tctx, "pac_client_principal",
350 "w2003final$@WIN2K3.THINKER.LOCAL");
352 authtime_string = torture_setting_string(tctx, "pac_authtime", "1120440609");
353 authtime = strtoull(authtime_string, NULL, 0);
355 ret = krb5_parse_name(smb_krb5_context->krb5_context, principal_string,
358 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
360 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
363 talloc_asprintf(tctx,
364 "(saved test) parsing of client principal [%s] failed: %s",
366 smb_get_krb5_error_message(smb_krb5_context->krb5_context, ret, mem_ctx)));
369 /* Decode and verify the signaure on the PAC */
370 nt_status = kerberos_decode_pac(mem_ctx, &pac_data,
372 smb_krb5_context->krb5_context,
375 client_principal, authtime, NULL);
376 if (!NT_STATUS_IS_OK(nt_status)) {
377 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
379 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
381 krb5_free_principal(smb_krb5_context->krb5_context, client_principal);
383 torture_fail(tctx, talloc_asprintf(tctx,
384 "(saved test) PAC decoding failed: %s",
385 nt_errstr(nt_status)));
388 /* Parse the PAC again, for the logon info this time */
389 nt_status = kerberos_pac_logon_info(mem_ctx, &logon_info,
391 smb_krb5_context->krb5_context,
394 client_principal, authtime, NULL);
396 if (!NT_STATUS_IS_OK(nt_status)) {
397 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
399 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
401 krb5_free_principal(smb_krb5_context->krb5_context, client_principal);
404 talloc_asprintf(tctx,
405 "(saved test) PAC decoding (for logon info) failed: %s",
406 nt_errstr(nt_status)));
409 validation.sam3 = &logon_info->info3;
410 nt_status = make_server_info_netlogon_validation(mem_ctx,
414 if (!NT_STATUS_IS_OK(nt_status)) {
415 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
417 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
419 krb5_free_principal(smb_krb5_context->krb5_context, client_principal);
422 talloc_asprintf(tctx,
423 "(saved test) PAC decoding (make server info) failed: %s",
424 nt_errstr(nt_status)));
428 !dom_sid_equal(dom_sid_parse_talloc(mem_ctx,
429 "S-1-5-21-3048156945-3961193616-3706469200-1005"),
430 server_info_out->account_sid)) {
431 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
433 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
435 krb5_free_principal(smb_krb5_context->krb5_context, client_principal);
438 talloc_asprintf(tctx,
439 "(saved test) PAC Decode resulted in *different* domain SID: %s != %s",
440 "S-1-5-21-3048156945-3961193616-3706469200-1005",
441 dom_sid_string(mem_ctx, server_info_out->account_sid)));
444 ret = kerberos_encode_pac(mem_ctx,
446 smb_krb5_context->krb5_context,
452 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
454 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
456 krb5_free_principal(smb_krb5_context->krb5_context, client_principal);
458 torture_fail(tctx, "(saved test) PAC push failed");
461 dump_data(10, validate_blob.data, validate_blob.length);
463 /* compare both the length and the data bytes after a
464 * pull/push cycle. This ensures we use the exact same
465 * pointer, padding etc algorithms as win2k3.
467 if (tmp_blob.length != validate_blob.length) {
468 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
470 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
472 krb5_free_principal(smb_krb5_context->krb5_context, client_principal);
475 talloc_asprintf(tctx,
476 "(saved test) PAC push failed: original buffer length[%u] != created buffer length[%u]",
477 (unsigned)tmp_blob.length, (unsigned)validate_blob.length));
480 if (memcmp(tmp_blob.data, validate_blob.data, tmp_blob.length) != 0) {
481 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
483 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
485 krb5_free_principal(smb_krb5_context->krb5_context, client_principal);
487 DEBUG(0, ("tmp_data:\n"));
488 dump_data(0, tmp_blob.data, tmp_blob.length);
489 DEBUG(0, ("validate_blob:\n"));
490 dump_data(0, validate_blob.data, validate_blob.length);
492 torture_fail(tctx, talloc_asprintf(tctx, "(saved test) PAC push failed: length[%u] matches, but data does not", (unsigned)tmp_blob.length));
495 ret = kerberos_create_pac(mem_ctx,
497 smb_krb5_context->krb5_context,
500 client_principal, authtime,
504 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
506 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
508 krb5_free_principal(smb_krb5_context->krb5_context, client_principal);
510 torture_fail(tctx, "(saved test) regnerated PAC create failed");
513 dump_data(10,validate_blob.data,validate_blob.length);
515 /* compare both the length and the data bytes after a
516 * pull/push cycle. This ensures we use the exact same
517 * pointer, padding etc algorithms as win2k3.
519 if (tmp_blob.length != validate_blob.length) {
520 ndr_err = ndr_pull_struct_blob(&validate_blob, mem_ctx, &pac_data2,
521 (ndr_pull_flags_fn_t)ndr_pull_PAC_DATA);
522 nt_status = ndr_map_error2ntstatus(ndr_err);
523 torture_assert_ntstatus_ok(tctx, nt_status, "can't parse the PAC");
525 NDR_PRINT_DEBUG(PAC_DATA, pac_data);
527 NDR_PRINT_DEBUG(PAC_DATA, &pac_data2);
529 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
531 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
533 krb5_free_principal(smb_krb5_context->krb5_context, client_principal);
535 torture_fail(tctx, talloc_asprintf(tctx,
536 "(saved test) PAC regenerate failed: original buffer length[%u] != created buffer length[%u]",
537 (unsigned)tmp_blob.length, (unsigned)validate_blob.length));
540 if (memcmp(tmp_blob.data, validate_blob.data, tmp_blob.length) != 0) {
541 ndr_err = ndr_pull_struct_blob(&validate_blob, mem_ctx, &pac_data2,
542 (ndr_pull_flags_fn_t)ndr_pull_PAC_DATA);
543 nt_status = ndr_map_error2ntstatus(ndr_err);
544 torture_assert_ntstatus_ok(tctx, nt_status, "can't parse the PAC");
546 NDR_PRINT_DEBUG(PAC_DATA, pac_data);
548 NDR_PRINT_DEBUG(PAC_DATA, &pac_data2);
550 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
552 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
554 krb5_free_principal(smb_krb5_context->krb5_context, client_principal);
556 DEBUG(0, ("tmp_data:\n"));
557 dump_data(0, tmp_blob.data, tmp_blob.length);
558 DEBUG(0, ("validate_blob:\n"));
559 dump_data(0, validate_blob.data, validate_blob.length);
561 torture_fail(tctx, talloc_asprintf(tctx,
562 "(saved test) PAC regenerate failed: length[%u] matches, but data does not", (unsigned)tmp_blob.length));
565 /* Break the auth time, to ensure we check this vital detail (not setting this caused all the pain in the first place... */
566 nt_status = kerberos_decode_pac(mem_ctx, &pac_data,
568 smb_krb5_context->krb5_context,
573 if (NT_STATUS_IS_OK(nt_status)) {
575 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
577 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
579 krb5_free_principal(smb_krb5_context->krb5_context, client_principal);
580 torture_fail(tctx, "(saved test) PAC decoding DID NOT fail on broken auth time (time + 1)");
583 /* Break the client principal */
584 krb5_free_principal(smb_krb5_context->krb5_context, client_principal);
586 broken_principal_string = talloc_strdup(mem_ctx, principal_string);
587 broken_principal_string[0]++;
589 ret = krb5_parse_name(smb_krb5_context->krb5_context,
590 broken_principal_string, &client_principal);
593 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
595 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
597 torture_fail(tctx, talloc_asprintf(tctx,
598 "(saved test) parsing of broken client principal failed: %s",
599 smb_get_krb5_error_message(smb_krb5_context->krb5_context, ret, mem_ctx)));
602 nt_status = kerberos_decode_pac(mem_ctx, &pac_data,
604 smb_krb5_context->krb5_context,
609 if (NT_STATUS_IS_OK(nt_status)) {
610 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
612 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
614 torture_fail(tctx, "(saved test) PAC decoding DID NOT fail on modified principal");
617 /* Finally... Bugger up the signature, and check we fail the checksum */
618 tmp_blob.data[tmp_blob.length - 2]++;
620 nt_status = kerberos_decode_pac(mem_ctx, &pac_data,
622 smb_krb5_context->krb5_context,
627 if (NT_STATUS_IS_OK(nt_status)) {
628 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
630 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
632 torture_fail(tctx, "(saved test) PAC decoding DID NOT fail on broken checksum");
635 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
637 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
642 _PUBLIC_ struct torture_suite *torture_pac(TALLOC_CTX *mem_ctx)
644 struct torture_suite *suite = torture_suite_create(mem_ctx, "PAC");
646 torture_suite_add_simple_test(suite, "self check",
647 torture_pac_self_check);
649 torture_suite_add_simple_test(suite, "saved check",
650 torture_pac_saved_check);