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 2 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, write to the Free Software
21 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 #include "system/kerberos.h"
26 #include "auth/auth.h"
27 #include "auth/kerberos/kerberos.h"
28 #include "librpc/gen_ndr/ndr_krb5pac.h"
29 #include "samba3/samba3.h"
30 #include "libcli/security/security.h"
31 #include "torture/torture.h"
33 static BOOL torture_pac_self_check(void)
36 TALLOC_CTX *mem_ctx = talloc_named(NULL, 0, "PAC self check");
38 struct PAC_DATA *pac_data;
39 struct PAC_LOGON_INFO *logon_info;
40 union netr_Validation validation;
42 /* Generate a nice, arbitary keyblock */
43 uint8_t server_bytes[16];
44 uint8_t krbtgt_bytes[16];
45 krb5_keyblock server_keyblock;
46 krb5_keyblock krbtgt_keyblock;
50 struct smb_krb5_context *smb_krb5_context;
52 struct auth_serversupplied_info *server_info;
53 struct auth_serversupplied_info *server_info_out;
55 krb5_principal client_principal;
56 time_t logon_time = time(NULL);
58 ret = smb_krb5_init_context(mem_ctx, &smb_krb5_context);
65 generate_random_buffer(server_bytes, 16);
66 generate_random_buffer(krbtgt_bytes, 16);
68 ret = krb5_keyblock_init(smb_krb5_context->krb5_context,
70 server_bytes, sizeof(server_bytes),
73 printf("(self test) Server Keyblock encoding failed: %s\n",
74 smb_get_krb5_error_message(smb_krb5_context->krb5_context,
81 ret = krb5_keyblock_init(smb_krb5_context->krb5_context,
83 krbtgt_bytes, sizeof(krbtgt_bytes),
86 printf("(self test) KRBTGT Keyblock encoding failed: %s\n",
87 smb_get_krb5_error_message(smb_krb5_context->krb5_context,
90 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
96 /* We need an input, and this one requires no underlying database */
97 nt_status = auth_anonymous_server_info(mem_ctx, &server_info);
99 if (!NT_STATUS_IS_OK(nt_status)) {
100 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
102 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
104 talloc_free(mem_ctx);
108 ret = krb5_parse_name_norealm(smb_krb5_context->krb5_context,
109 server_info->account_name, &client_principal);
111 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
113 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
115 talloc_free(mem_ctx);
119 /* OK, go ahead and make a PAC */
120 ret = kerberos_create_pac(mem_ctx, server_info,
121 smb_krb5_context->krb5_context,
129 printf("(self test) PAC encoding failed: %s\n",
130 smb_get_krb5_error_message(smb_krb5_context->krb5_context,
133 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
135 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
137 krb5_free_principal(smb_krb5_context->krb5_context,
139 talloc_free(mem_ctx);
143 dump_data(10,tmp_blob.data,tmp_blob.length);
145 /* Now check that we can read it back */
146 nt_status = kerberos_decode_pac(mem_ctx, &pac_data,
148 smb_krb5_context->krb5_context,
154 if (!NT_STATUS_IS_OK(nt_status)) {
155 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
157 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
159 krb5_free_principal(smb_krb5_context->krb5_context,
161 DEBUG(1, ("(self test) PAC decoding failed: %s\n",
162 nt_errstr(nt_status)));
164 talloc_free(mem_ctx);
168 /* Now check that we can read it back */
169 nt_status = kerberos_pac_logon_info(mem_ctx, &logon_info,
171 smb_krb5_context->krb5_context,
178 if (!NT_STATUS_IS_OK(nt_status)) {
179 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
181 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
183 krb5_free_principal(smb_krb5_context->krb5_context,
185 printf("(self test) PAC decoding (for logon info) failed: %s\n",
186 nt_errstr(nt_status));
188 talloc_free(mem_ctx);
192 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
194 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
196 krb5_free_principal(smb_krb5_context->krb5_context,
199 validation.sam3 = &logon_info->info3;
200 nt_status = make_server_info_netlogon_validation(mem_ctx,
204 if (!NT_STATUS_IS_OK(nt_status)) {
205 printf("(self test) PAC decoding (make server info) failed: %s\n",
206 nt_errstr(nt_status));
208 talloc_free(mem_ctx);
212 if (!dom_sid_equal(server_info->account_sid,
213 server_info_out->account_sid)) {
214 printf("(self test) PAC Decode resulted in *different* domain SID: %s != %s\n",
215 dom_sid_string(mem_ctx, server_info->account_sid),
216 dom_sid_string(mem_ctx, server_info_out->account_sid));
217 talloc_free(mem_ctx);
221 talloc_free(mem_ctx);
226 /* This is the PAC generated on my test network, by my test Win2k3 server.
227 -- abartlet 2005-07-04
230 static const uint8_t saved_pac[] = {
231 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xd8, 0x01, 0x00, 0x00,
232 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,
233 0x20, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
234 0x40, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
235 0x58, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x10, 0x08, 0x00, 0xcc, 0xcc, 0xcc, 0xcc,
236 0xc8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x30, 0xdf, 0xa6, 0xcb,
237 0x4f, 0x7d, 0xc5, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff,
238 0xff, 0xff, 0xff, 0x7f, 0xc0, 0x3c, 0x4e, 0x59, 0x62, 0x73, 0xc5, 0x01, 0xc0, 0x3c, 0x4e, 0x59,
239 0x62, 0x73, 0xc5, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x16, 0x00, 0x16, 0x00,
240 0x04, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
241 0x0c, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
242 0x14, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x02, 0x00, 0x65, 0x00, 0x00, 0x00,
243 0xed, 0x03, 0x00, 0x00, 0x04, 0x02, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x02, 0x00,
244 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
245 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x16, 0x00, 0x20, 0x00, 0x02, 0x00, 0x16, 0x00, 0x18, 0x00,
246 0x24, 0x00, 0x02, 0x00, 0x28, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
247 0x00, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
248 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
249 0x01, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
250 0x00, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00,
251 0x57, 0x00, 0x32, 0x00, 0x30, 0x00, 0x30, 0x00, 0x33, 0x00, 0x46, 0x00, 0x49, 0x00, 0x4e, 0x00,
252 0x41, 0x00, 0x4c, 0x00, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
253 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
254 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
255 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
256 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x02, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
257 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x57, 0x00, 0x32, 0x00,
258 0x30, 0x00, 0x30, 0x00, 0x33, 0x00, 0x46, 0x00, 0x49, 0x00, 0x4e, 0x00, 0x41, 0x00, 0x4c, 0x00,
259 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x57, 0x00, 0x49, 0x00,
260 0x4e, 0x00, 0x32, 0x00, 0x4b, 0x00, 0x33, 0x00, 0x54, 0x00, 0x48, 0x00, 0x49, 0x00, 0x4e, 0x00,
261 0x4b, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05,
262 0x15, 0x00, 0x00, 0x00, 0x11, 0x2f, 0xaf, 0xb5, 0x90, 0x04, 0x1b, 0xec, 0x50, 0x3b, 0xec, 0xdc,
263 0x01, 0x00, 0x00, 0x00, 0x30, 0x00, 0x02, 0x00, 0x07, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
264 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
265 0x80, 0x66, 0x28, 0xea, 0x37, 0x80, 0xc5, 0x01, 0x16, 0x00, 0x77, 0x00, 0x32, 0x00, 0x30, 0x00,
266 0x30, 0x00, 0x33, 0x00, 0x66, 0x00, 0x69, 0x00, 0x6e, 0x00, 0x61, 0x00, 0x6c, 0x00, 0x24, 0x00,
267 0x76, 0xff, 0xff, 0xff, 0x37, 0xd5, 0xb0, 0xf7, 0x24, 0xf0, 0xd6, 0xd4, 0xec, 0x09, 0x86, 0x5a,
268 0xa0, 0xe8, 0xc3, 0xa9, 0x00, 0x00, 0x00, 0x00, 0x76, 0xff, 0xff, 0xff, 0xb4, 0xd8, 0xb8, 0xfe,
269 0x83, 0xb3, 0x13, 0x3f, 0xfc, 0x5c, 0x41, 0xad, 0xe2, 0x64, 0x83, 0xe0, 0x00, 0x00, 0x00, 0x00
272 /* Check with a known 'well formed' PAC, from my test server */
273 static BOOL torture_pac_saved_check(void)
276 TALLOC_CTX *mem_ctx = talloc_named(NULL, 0, "PAC saved check");
277 DATA_BLOB tmp_blob, validate_blob;
278 struct PAC_DATA *pac_data, pac_data2;
279 struct PAC_LOGON_INFO *logon_info;
280 union netr_Validation validation;
281 const char *pac_file, *pac_kdc_key, *pac_member_key;
282 struct auth_serversupplied_info *server_info_out;
284 krb5_keyblock server_keyblock;
285 krb5_keyblock krbtgt_keyblock;
286 struct samr_Password *krbtgt_bytes, *krbsrv_bytes;
289 struct smb_krb5_context *smb_krb5_context;
291 const char *principal_string;
292 krb5_principal client_principal;
293 const char *authtime_string;
296 ret = smb_krb5_init_context(mem_ctx, &smb_krb5_context);
299 talloc_free(mem_ctx);
303 pac_kdc_key = lp_parm_string(-1,"torture","pac_kdc_key");
304 if (pac_kdc_key == NULL) {
305 pac_kdc_key = "B286757148AF7FD252C53603A150B7E7";
308 pac_member_key = lp_parm_string(-1,"torture","pac_member_key");
309 if (pac_member_key == NULL) {
310 pac_member_key = "D217FAEAE5E6B5F95CCC94077AB8A5FC";
313 printf("Using pac_kdc_key '%s'\n", pac_kdc_key);
314 printf("Using pac_member_key '%s'\n", pac_member_key);
316 /* The krbtgt key in use when the above PAC was generated.
317 * This is an arcfour-hmac-md5 key, extracted with our 'net
319 krbtgt_bytes = smbpasswd_gethexpwd(mem_ctx, pac_kdc_key);
321 DEBUG(0, ("(saved test) Could not interpret krbtgt key"));
322 talloc_free(mem_ctx);
326 krbsrv_bytes = smbpasswd_gethexpwd(mem_ctx, pac_member_key);
328 DEBUG(0, ("(saved test) Could not interpret krbsrv key"));
329 talloc_free(mem_ctx);
333 ret = krb5_keyblock_init(smb_krb5_context->krb5_context,
334 ENCTYPE_ARCFOUR_HMAC,
335 krbsrv_bytes->hash, sizeof(krbsrv_bytes->hash),
338 DEBUG(1, ("(saved test) Server Keyblock encoding failed: %s\n",
339 smb_get_krb5_error_message(smb_krb5_context->krb5_context,
342 talloc_free(mem_ctx);
346 ret = krb5_keyblock_init(smb_krb5_context->krb5_context,
347 ENCTYPE_ARCFOUR_HMAC,
348 krbtgt_bytes->hash, sizeof(krbtgt_bytes->hash),
351 DEBUG(1, ("(saved test) Server Keyblock encoding failed: %s\n",
352 smb_get_krb5_error_message(smb_krb5_context->krb5_context,
355 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
357 talloc_free(mem_ctx);
361 pac_file = lp_parm_string(-1,"torture","pac_file");
363 tmp_blob.data = (uint8_t *)file_load(pac_file, &tmp_blob.length, mem_ctx);
364 printf("(saved test) Loaded pac of size %ld from %s\n", (long)tmp_blob.length, pac_file);
366 tmp_blob = data_blob_talloc(mem_ctx, saved_pac, sizeof(saved_pac));
369 dump_data(10,tmp_blob.data,tmp_blob.length);
371 principal_string = lp_parm_string(-1,"torture","pac_client_principal");
372 if (!principal_string) {
373 principal_string = "w2003final$@WIN2K3.THINKER.LOCAL";
376 authtime_string = lp_parm_string(-1,"torture","pac_authtime");
377 if (!authtime_string) {
378 authtime = 1120440609;
380 authtime = strtoull(authtime_string, NULL, 0);
383 ret = krb5_parse_name(smb_krb5_context->krb5_context, principal_string,
386 DEBUG(1, ("(saved test) parsing of client principal [%s] failed: %s\n",
388 smb_get_krb5_error_message(smb_krb5_context->krb5_context, ret, mem_ctx)));
390 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
392 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
394 talloc_free(mem_ctx);
398 /* Decode and verify the signaure on the PAC */
399 nt_status = kerberos_decode_pac(mem_ctx, &pac_data,
401 smb_krb5_context->krb5_context,
404 client_principal, authtime, NULL);
405 if (!NT_STATUS_IS_OK(nt_status)) {
406 DEBUG(1, ("(saved test) PAC decoding failed: %s\n",
407 nt_errstr(nt_status)));
409 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
411 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
413 krb5_free_principal(smb_krb5_context->krb5_context, client_principal);
415 talloc_free(mem_ctx);
419 /* Parse the PAC again, for the logon info this time */
420 nt_status = kerberos_pac_logon_info(mem_ctx, &logon_info,
422 smb_krb5_context->krb5_context,
425 client_principal, authtime, NULL);
427 if (!NT_STATUS_IS_OK(nt_status)) {
428 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
430 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
432 krb5_free_principal(smb_krb5_context->krb5_context, client_principal);
434 printf("(saved test) PAC decoding (for logon info) failed: %s\n",
435 nt_errstr(nt_status));
437 talloc_free(mem_ctx);
441 validation.sam3 = &logon_info->info3;
442 nt_status = make_server_info_netlogon_validation(mem_ctx,
446 if (!NT_STATUS_IS_OK(nt_status)) {
447 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
449 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
451 krb5_free_principal(smb_krb5_context->krb5_context, client_principal);
453 printf("(saved test) PAC decoding (make server info) failed: %s\n",
454 nt_errstr(nt_status));
456 talloc_free(mem_ctx);
461 !dom_sid_equal(dom_sid_parse_talloc(mem_ctx, "S-1-5-21-3048156945-3961193616-3706469200-1005"),
462 server_info_out->account_sid)) {
463 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
465 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
467 krb5_free_principal(smb_krb5_context->krb5_context, client_principal);
469 printf("(saved test) PAC Decode resulted in *different* domain SID: %s != %s\n",
470 "S-1-5-21-3048156945-3961193616-3706469200-1005",
471 dom_sid_string(mem_ctx, server_info_out->account_sid));
472 talloc_free(mem_ctx);
476 ret = kerberos_encode_pac(mem_ctx,
478 smb_krb5_context->krb5_context,
484 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
486 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
488 krb5_free_principal(smb_krb5_context->krb5_context, client_principal);
490 DEBUG(0, ("(saved test) PAC push failed\n"));
491 talloc_free(mem_ctx);
495 dump_data(10,validate_blob.data,validate_blob.length);
497 /* compare both the length and the data bytes after a
498 * pull/push cycle. This ensures we use the exact same
499 * pointer, padding etc algorithms as win2k3.
501 if (tmp_blob.length != validate_blob.length) {
502 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
504 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
506 krb5_free_principal(smb_krb5_context->krb5_context, client_principal);
508 DEBUG(0, ("(saved test) PAC push failed: original buffer length[%u] != created buffer length[%u]\n",
509 (unsigned)tmp_blob.length, (unsigned)validate_blob.length));
510 talloc_free(mem_ctx);
514 if (memcmp(tmp_blob.data, validate_blob.data, tmp_blob.length) != 0) {
515 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
517 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
519 krb5_free_principal(smb_krb5_context->krb5_context, client_principal);
521 DEBUG(0, ("(saved test) PAC push failed: length[%u] matches, but data does not\n",
522 (unsigned)tmp_blob.length));
523 DEBUG(0, ("tmp_data:\n"));
524 dump_data(0, tmp_blob.data, tmp_blob.length);
525 DEBUG(0, ("validate_blob:\n"));
526 dump_data(0, validate_blob.data, validate_blob.length);
528 talloc_free(mem_ctx);
532 ret = kerberos_create_pac(mem_ctx,
534 smb_krb5_context->krb5_context,
537 client_principal, authtime,
541 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
543 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
545 krb5_free_principal(smb_krb5_context->krb5_context, client_principal);
547 DEBUG(0, ("(saved test) regnerated PAC create failed\n"));
548 talloc_free(mem_ctx);
552 dump_data(10,validate_blob.data,validate_blob.length);
554 /* compare both the length and the data bytes after a
555 * pull/push cycle. This ensures we use the exact same
556 * pointer, padding etc algorithms as win2k3.
558 if (tmp_blob.length != validate_blob.length) {
559 nt_status = ndr_pull_struct_blob(&validate_blob, mem_ctx, &pac_data2,
560 (ndr_pull_flags_fn_t)ndr_pull_PAC_DATA);
561 if (!NT_STATUS_IS_OK(nt_status)) {
562 DEBUG(0,("can't parse the PAC\n"));
566 NDR_PRINT_DEBUG(PAC_DATA, pac_data);
568 NDR_PRINT_DEBUG(PAC_DATA, &pac_data2);
570 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
572 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
574 krb5_free_principal(smb_krb5_context->krb5_context, client_principal);
576 DEBUG(0, ("(saved test) PAC regenerate failed: original buffer length[%u] != created buffer length[%u]\n",
577 (unsigned)tmp_blob.length, (unsigned)validate_blob.length));
578 talloc_free(mem_ctx);
582 if (memcmp(tmp_blob.data, validate_blob.data, tmp_blob.length) != 0) {
583 nt_status = ndr_pull_struct_blob(&validate_blob, mem_ctx, &pac_data2,
584 (ndr_pull_flags_fn_t)ndr_pull_PAC_DATA);
585 if (!NT_STATUS_IS_OK(nt_status)) {
586 DEBUG(0,("can't parse the PAC\n"));
590 NDR_PRINT_DEBUG(PAC_DATA, pac_data);
592 NDR_PRINT_DEBUG(PAC_DATA, &pac_data2);
594 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
596 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
598 krb5_free_principal(smb_krb5_context->krb5_context, client_principal);
600 DEBUG(0, ("(saved test) PAC regenerate failed: length[%u] matches, but data does not\n",
601 (unsigned)tmp_blob.length));
602 DEBUG(0, ("tmp_data:\n"));
603 dump_data(0, tmp_blob.data, tmp_blob.length);
604 DEBUG(0, ("validate_blob:\n"));
605 dump_data(0, validate_blob.data, validate_blob.length);
607 talloc_free(mem_ctx);
611 /* Break the auth time, to ensure we check this vital detail (not setting this caused all the pain in the first place... */
612 nt_status = kerberos_decode_pac(mem_ctx, &pac_data,
614 smb_krb5_context->krb5_context,
619 if (NT_STATUS_IS_OK(nt_status)) {
620 DEBUG(1, ("(saved test) PAC decoding DID NOT fail on broken auth time (time + 1)\n"));
622 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
624 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
626 krb5_free_principal(smb_krb5_context->krb5_context, client_principal);
627 talloc_free(mem_ctx);
631 /* Break the client principal */
632 krb5_free_principal(smb_krb5_context->krb5_context, client_principal);
634 ret = krb5_parse_name(smb_krb5_context->krb5_context,
635 "not the right principal", &client_principal);
637 DEBUG(1, ("(saved test) parsing of bogus client principal failed: %s\n",
638 smb_get_krb5_error_message(smb_krb5_context->krb5_context, ret, mem_ctx)));
640 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
642 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
644 talloc_free(mem_ctx);
648 nt_status = kerberos_decode_pac(mem_ctx, &pac_data,
650 smb_krb5_context->krb5_context,
655 if (NT_STATUS_IS_OK(nt_status)) {
656 DEBUG(1, ("(saved test) PAC decoding DID NOT fail on modified principal\n"));
658 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
660 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
662 talloc_free(mem_ctx);
666 /* Finally... Bugger up the signature, and check we fail the checksum */
667 tmp_blob.data[tmp_blob.length - 2]++;
669 nt_status = kerberos_decode_pac(mem_ctx, &pac_data,
671 smb_krb5_context->krb5_context,
676 if (NT_STATUS_IS_OK(nt_status)) {
677 DEBUG(1, ("(saved test) PAC decoding DID NOT fail on broken checksum\n"));
679 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
681 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
683 talloc_free(mem_ctx);
687 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
689 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
692 talloc_free(mem_ctx);
696 BOOL torture_pac(struct torture_context *torture)
699 ret &= torture_pac_self_check();
700 ret &= torture_pac_saved_check();