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/proto.h"
32 static BOOL torture_pac_self_check(void)
35 TALLOC_CTX *mem_ctx = talloc_named(NULL, 0, "PAC self check");
37 struct PAC_DATA *pac_data;
38 struct PAC_LOGON_INFO *logon_info;
39 union netr_Validation validation;
41 /* Generate a nice, arbitary keyblock */
42 uint8_t server_bytes[16];
43 uint8_t krbtgt_bytes[16];
44 krb5_keyblock server_keyblock;
45 krb5_keyblock krbtgt_keyblock;
49 struct smb_krb5_context *smb_krb5_context;
51 struct auth_serversupplied_info *server_info;
52 struct auth_serversupplied_info *server_info_out;
54 krb5_principal client_principal;
55 time_t logon_time = time(NULL);
57 ret = smb_krb5_init_context(mem_ctx, &smb_krb5_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),
72 printf("(self test) Server Keyblock encoding failed: %s\n",
73 smb_get_krb5_error_message(smb_krb5_context->krb5_context,
80 ret = krb5_keyblock_init(smb_krb5_context->krb5_context,
82 krbtgt_bytes, sizeof(krbtgt_bytes),
85 printf("(self test) KRBTGT Keyblock encoding failed: %s\n",
86 smb_get_krb5_error_message(smb_krb5_context->krb5_context,
89 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
95 /* We need an input, and this one requires no underlying database */
96 nt_status = auth_anonymous_server_info(mem_ctx, &server_info);
98 if (!NT_STATUS_IS_OK(nt_status)) {
99 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
101 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
103 talloc_free(mem_ctx);
107 ret = krb5_parse_name_norealm(smb_krb5_context->krb5_context,
108 server_info->account_name, &client_principal);
110 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
112 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
114 talloc_free(mem_ctx);
118 /* OK, go ahead and make a PAC */
119 ret = kerberos_create_pac(mem_ctx, server_info,
120 smb_krb5_context->krb5_context,
128 printf("(self test) PAC encoding failed: %s\n",
129 smb_get_krb5_error_message(smb_krb5_context->krb5_context,
132 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
134 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
136 krb5_free_principal(smb_krb5_context->krb5_context,
138 talloc_free(mem_ctx);
142 dump_data(10,tmp_blob.data,tmp_blob.length);
144 /* Now check that we can read it back */
145 nt_status = kerberos_decode_pac(mem_ctx, &pac_data,
147 smb_krb5_context->krb5_context,
153 if (!NT_STATUS_IS_OK(nt_status)) {
154 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
156 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
158 krb5_free_principal(smb_krb5_context->krb5_context,
160 DEBUG(1, ("(self test) PAC decoding failed: %s\n",
161 nt_errstr(nt_status)));
163 talloc_free(mem_ctx);
167 /* Now check that we can read it back */
168 nt_status = kerberos_pac_logon_info(mem_ctx, &logon_info,
170 smb_krb5_context->krb5_context,
177 if (!NT_STATUS_IS_OK(nt_status)) {
178 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
180 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
182 krb5_free_principal(smb_krb5_context->krb5_context,
184 printf("(self test) PAC decoding (for logon info) failed: %s\n",
185 nt_errstr(nt_status));
187 talloc_free(mem_ctx);
191 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
193 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
195 krb5_free_principal(smb_krb5_context->krb5_context,
198 validation.sam3 = &logon_info->info3;
199 nt_status = make_server_info_netlogon_validation(mem_ctx,
203 if (!NT_STATUS_IS_OK(nt_status)) {
204 printf("(self test) PAC decoding (make server info) failed: %s\n",
205 nt_errstr(nt_status));
207 talloc_free(mem_ctx);
211 if (!dom_sid_equal(server_info->account_sid,
212 server_info_out->account_sid)) {
213 printf("(self test) PAC Decode resulted in *different* domain SID: %s != %s\n",
214 dom_sid_string(mem_ctx, server_info->account_sid),
215 dom_sid_string(mem_ctx, server_info_out->account_sid));
216 talloc_free(mem_ctx);
220 talloc_free(mem_ctx);
225 /* This is the PAC generated on my test network, by my test Win2k3 server.
226 -- abartlet 2005-07-04
229 static const uint8_t saved_pac[] = {
230 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xd8, 0x01, 0x00, 0x00,
231 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,
232 0x20, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
233 0x40, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
234 0x58, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x10, 0x08, 0x00, 0xcc, 0xcc, 0xcc, 0xcc,
235 0xc8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x30, 0xdf, 0xa6, 0xcb,
236 0x4f, 0x7d, 0xc5, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff,
237 0xff, 0xff, 0xff, 0x7f, 0xc0, 0x3c, 0x4e, 0x59, 0x62, 0x73, 0xc5, 0x01, 0xc0, 0x3c, 0x4e, 0x59,
238 0x62, 0x73, 0xc5, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x16, 0x00, 0x16, 0x00,
239 0x04, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
240 0x0c, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
241 0x14, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x02, 0x00, 0x65, 0x00, 0x00, 0x00,
242 0xed, 0x03, 0x00, 0x00, 0x04, 0x02, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x02, 0x00,
243 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
244 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x16, 0x00, 0x20, 0x00, 0x02, 0x00, 0x16, 0x00, 0x18, 0x00,
245 0x24, 0x00, 0x02, 0x00, 0x28, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
246 0x00, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
247 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
248 0x01, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
249 0x00, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00,
250 0x57, 0x00, 0x32, 0x00, 0x30, 0x00, 0x30, 0x00, 0x33, 0x00, 0x46, 0x00, 0x49, 0x00, 0x4e, 0x00,
251 0x41, 0x00, 0x4c, 0x00, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
252 0x00, 0x00, 0x00, 0x00, 0x00, 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, 0x01, 0x00, 0x00, 0x00, 0x04, 0x02, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
256 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x57, 0x00, 0x32, 0x00,
257 0x30, 0x00, 0x30, 0x00, 0x33, 0x00, 0x46, 0x00, 0x49, 0x00, 0x4e, 0x00, 0x41, 0x00, 0x4c, 0x00,
258 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x57, 0x00, 0x49, 0x00,
259 0x4e, 0x00, 0x32, 0x00, 0x4b, 0x00, 0x33, 0x00, 0x54, 0x00, 0x48, 0x00, 0x49, 0x00, 0x4e, 0x00,
260 0x4b, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05,
261 0x15, 0x00, 0x00, 0x00, 0x11, 0x2f, 0xaf, 0xb5, 0x90, 0x04, 0x1b, 0xec, 0x50, 0x3b, 0xec, 0xdc,
262 0x01, 0x00, 0x00, 0x00, 0x30, 0x00, 0x02, 0x00, 0x07, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
263 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
264 0x80, 0x66, 0x28, 0xea, 0x37, 0x80, 0xc5, 0x01, 0x16, 0x00, 0x77, 0x00, 0x32, 0x00, 0x30, 0x00,
265 0x30, 0x00, 0x33, 0x00, 0x66, 0x00, 0x69, 0x00, 0x6e, 0x00, 0x61, 0x00, 0x6c, 0x00, 0x24, 0x00,
266 0x76, 0xff, 0xff, 0xff, 0x37, 0xd5, 0xb0, 0xf7, 0x24, 0xf0, 0xd6, 0xd4, 0xec, 0x09, 0x86, 0x5a,
267 0xa0, 0xe8, 0xc3, 0xa9, 0x00, 0x00, 0x00, 0x00, 0x76, 0xff, 0xff, 0xff, 0xb4, 0xd8, 0xb8, 0xfe,
268 0x83, 0xb3, 0x13, 0x3f, 0xfc, 0x5c, 0x41, 0xad, 0xe2, 0x64, 0x83, 0xe0, 0x00, 0x00, 0x00, 0x00
271 /* Check with a known 'well formed' PAC, from my test server */
272 static BOOL torture_pac_saved_check(void)
275 TALLOC_CTX *mem_ctx = talloc_named(NULL, 0, "PAC saved check");
276 DATA_BLOB tmp_blob, validate_blob;
277 struct PAC_DATA *pac_data, pac_data2;
278 struct PAC_LOGON_INFO *logon_info;
279 union netr_Validation validation;
280 const char *pac_file, *pac_kdc_key, *pac_member_key;
281 struct auth_serversupplied_info *server_info_out;
283 krb5_keyblock server_keyblock;
284 krb5_keyblock krbtgt_keyblock;
285 struct samr_Password *krbtgt_bytes, *krbsrv_bytes;
288 struct smb_krb5_context *smb_krb5_context;
290 const char *principal_string;
291 krb5_principal client_principal;
292 const char *authtime_string;
295 ret = smb_krb5_init_context(mem_ctx, &smb_krb5_context);
298 talloc_free(mem_ctx);
302 pac_kdc_key = lp_parm_string(-1,"torture","pac_kdc_key");
303 if (pac_kdc_key == NULL) {
304 pac_kdc_key = "B286757148AF7FD252C53603A150B7E7";
307 pac_member_key = lp_parm_string(-1,"torture","pac_member_key");
308 if (pac_member_key == NULL) {
309 pac_member_key = "D217FAEAE5E6B5F95CCC94077AB8A5FC";
312 printf("Using pac_kdc_key '%s'\n", pac_kdc_key);
313 printf("Using pac_member_key '%s'\n", pac_member_key);
315 /* The krbtgt key in use when the above PAC was generated.
316 * This is an arcfour-hmac-md5 key, extracted with our 'net
318 krbtgt_bytes = smbpasswd_gethexpwd(mem_ctx, pac_kdc_key);
320 DEBUG(0, ("(saved test) Could not interpret krbtgt key"));
321 talloc_free(mem_ctx);
325 krbsrv_bytes = smbpasswd_gethexpwd(mem_ctx, pac_member_key);
327 DEBUG(0, ("(saved test) Could not interpret krbsrv key"));
328 talloc_free(mem_ctx);
332 ret = krb5_keyblock_init(smb_krb5_context->krb5_context,
333 ENCTYPE_ARCFOUR_HMAC,
334 krbsrv_bytes->hash, sizeof(krbsrv_bytes->hash),
337 DEBUG(1, ("(saved test) Server Keyblock encoding failed: %s\n",
338 smb_get_krb5_error_message(smb_krb5_context->krb5_context,
341 talloc_free(mem_ctx);
345 ret = krb5_keyblock_init(smb_krb5_context->krb5_context,
346 ENCTYPE_ARCFOUR_HMAC,
347 krbtgt_bytes->hash, sizeof(krbtgt_bytes->hash),
350 DEBUG(1, ("(saved test) Server Keyblock encoding failed: %s\n",
351 smb_get_krb5_error_message(smb_krb5_context->krb5_context,
354 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
356 talloc_free(mem_ctx);
360 pac_file = lp_parm_string(-1,"torture","pac_file");
362 tmp_blob.data = (uint8_t *)file_load(pac_file, &tmp_blob.length, mem_ctx);
363 printf("(saved test) Loaded pac of size %ld from %s\n", (long)tmp_blob.length, pac_file);
365 tmp_blob = data_blob_talloc(mem_ctx, saved_pac, sizeof(saved_pac));
368 dump_data(10,tmp_blob.data,tmp_blob.length);
370 principal_string = lp_parm_string(-1,"torture","pac_client_principal");
371 if (!principal_string) {
372 principal_string = "w2003final$@WIN2K3.THINKER.LOCAL";
375 authtime_string = lp_parm_string(-1,"torture","pac_authtime");
376 if (!authtime_string) {
377 authtime = 1120440609;
379 authtime = strtoull(authtime_string, NULL, 0);
382 ret = krb5_parse_name(smb_krb5_context->krb5_context, principal_string,
385 DEBUG(1, ("(saved test) parsing of client principal [%s] failed: %s\n",
387 smb_get_krb5_error_message(smb_krb5_context->krb5_context, ret, mem_ctx)));
389 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
391 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
393 talloc_free(mem_ctx);
397 /* Decode and verify the signaure on the PAC */
398 nt_status = kerberos_decode_pac(mem_ctx, &pac_data,
400 smb_krb5_context->krb5_context,
403 client_principal, authtime, NULL);
404 if (!NT_STATUS_IS_OK(nt_status)) {
405 DEBUG(1, ("(saved test) PAC decoding failed: %s\n",
406 nt_errstr(nt_status)));
408 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
410 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
412 krb5_free_principal(smb_krb5_context->krb5_context, client_principal);
414 talloc_free(mem_ctx);
418 /* Parse the PAC again, for the logon info this time */
419 nt_status = kerberos_pac_logon_info(mem_ctx, &logon_info,
421 smb_krb5_context->krb5_context,
424 client_principal, authtime, NULL);
426 if (!NT_STATUS_IS_OK(nt_status)) {
427 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
429 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
431 krb5_free_principal(smb_krb5_context->krb5_context, client_principal);
433 printf("(saved test) PAC decoding (for logon info) failed: %s\n",
434 nt_errstr(nt_status));
436 talloc_free(mem_ctx);
440 validation.sam3 = &logon_info->info3;
441 nt_status = make_server_info_netlogon_validation(mem_ctx,
445 if (!NT_STATUS_IS_OK(nt_status)) {
446 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
448 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
450 krb5_free_principal(smb_krb5_context->krb5_context, client_principal);
452 printf("(saved test) PAC decoding (make server info) failed: %s\n",
453 nt_errstr(nt_status));
455 talloc_free(mem_ctx);
460 !dom_sid_equal(dom_sid_parse_talloc(mem_ctx, "S-1-5-21-3048156945-3961193616-3706469200-1005"),
461 server_info_out->account_sid)) {
462 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
464 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
466 krb5_free_principal(smb_krb5_context->krb5_context, client_principal);
468 printf("(saved test) PAC Decode resulted in *different* domain SID: %s != %s\n",
469 "S-1-5-21-3048156945-3961193616-3706469200-1005",
470 dom_sid_string(mem_ctx, server_info_out->account_sid));
471 talloc_free(mem_ctx);
475 ret = kerberos_encode_pac(mem_ctx,
477 smb_krb5_context->krb5_context,
483 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
485 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
487 krb5_free_principal(smb_krb5_context->krb5_context, client_principal);
489 DEBUG(0, ("(saved test) PAC push failed\n"));
490 talloc_free(mem_ctx);
494 dump_data(10,validate_blob.data,validate_blob.length);
496 /* compare both the length and the data bytes after a
497 * pull/push cycle. This ensures we use the exact same
498 * pointer, padding etc algorithms as win2k3.
500 if (tmp_blob.length != validate_blob.length) {
501 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
503 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
505 krb5_free_principal(smb_krb5_context->krb5_context, client_principal);
507 DEBUG(0, ("(saved test) PAC push failed: original buffer length[%u] != created buffer length[%u]\n",
508 (unsigned)tmp_blob.length, (unsigned)validate_blob.length));
509 talloc_free(mem_ctx);
513 if (memcmp(tmp_blob.data, validate_blob.data, tmp_blob.length) != 0) {
514 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
516 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
518 krb5_free_principal(smb_krb5_context->krb5_context, client_principal);
520 DEBUG(0, ("(saved test) PAC push failed: length[%u] matches, but data does not\n",
521 (unsigned)tmp_blob.length));
522 DEBUG(0, ("tmp_data:\n"));
523 dump_data(0, tmp_blob.data, tmp_blob.length);
524 DEBUG(0, ("validate_blob:\n"));
525 dump_data(0, validate_blob.data, validate_blob.length);
527 talloc_free(mem_ctx);
531 ret = kerberos_create_pac(mem_ctx,
533 smb_krb5_context->krb5_context,
536 client_principal, authtime,
540 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
542 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
544 krb5_free_principal(smb_krb5_context->krb5_context, client_principal);
546 DEBUG(0, ("(saved test) regnerated PAC create failed\n"));
547 talloc_free(mem_ctx);
551 dump_data(10,validate_blob.data,validate_blob.length);
553 /* compare both the length and the data bytes after a
554 * pull/push cycle. This ensures we use the exact same
555 * pointer, padding etc algorithms as win2k3.
557 if (tmp_blob.length != validate_blob.length) {
558 nt_status = ndr_pull_struct_blob(&validate_blob, mem_ctx, &pac_data2,
559 (ndr_pull_flags_fn_t)ndr_pull_PAC_DATA);
560 if (!NT_STATUS_IS_OK(nt_status)) {
561 DEBUG(0,("can't parse the PAC\n"));
565 NDR_PRINT_DEBUG(PAC_DATA, pac_data);
567 NDR_PRINT_DEBUG(PAC_DATA, &pac_data2);
569 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
571 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
573 krb5_free_principal(smb_krb5_context->krb5_context, client_principal);
575 DEBUG(0, ("(saved test) PAC regenerate failed: original buffer length[%u] != created buffer length[%u]\n",
576 (unsigned)tmp_blob.length, (unsigned)validate_blob.length));
577 talloc_free(mem_ctx);
581 if (memcmp(tmp_blob.data, validate_blob.data, tmp_blob.length) != 0) {
582 nt_status = ndr_pull_struct_blob(&validate_blob, mem_ctx, &pac_data2,
583 (ndr_pull_flags_fn_t)ndr_pull_PAC_DATA);
584 if (!NT_STATUS_IS_OK(nt_status)) {
585 DEBUG(0,("can't parse the PAC\n"));
589 NDR_PRINT_DEBUG(PAC_DATA, pac_data);
591 NDR_PRINT_DEBUG(PAC_DATA, &pac_data2);
593 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
595 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
597 krb5_free_principal(smb_krb5_context->krb5_context, client_principal);
599 DEBUG(0, ("(saved test) PAC regenerate failed: length[%u] matches, but data does not\n",
600 (unsigned)tmp_blob.length));
601 DEBUG(0, ("tmp_data:\n"));
602 dump_data(0, tmp_blob.data, tmp_blob.length);
603 DEBUG(0, ("validate_blob:\n"));
604 dump_data(0, validate_blob.data, validate_blob.length);
606 talloc_free(mem_ctx);
610 /* Break the auth time, to ensure we check this vital detail (not setting this caused all the pain in the first place... */
611 nt_status = kerberos_decode_pac(mem_ctx, &pac_data,
613 smb_krb5_context->krb5_context,
618 if (NT_STATUS_IS_OK(nt_status)) {
619 DEBUG(1, ("(saved test) PAC decoding DID NOT fail on broken auth time (time + 1)\n"));
621 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
623 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
625 krb5_free_principal(smb_krb5_context->krb5_context, client_principal);
626 talloc_free(mem_ctx);
630 /* Break the client principal */
631 krb5_free_principal(smb_krb5_context->krb5_context, client_principal);
633 ret = krb5_parse_name(smb_krb5_context->krb5_context,
634 "not the right principal", &client_principal);
636 DEBUG(1, ("(saved test) parsing of bogus client principal failed: %s\n",
637 smb_get_krb5_error_message(smb_krb5_context->krb5_context, ret, mem_ctx)));
639 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
641 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
643 talloc_free(mem_ctx);
647 nt_status = kerberos_decode_pac(mem_ctx, &pac_data,
649 smb_krb5_context->krb5_context,
654 if (NT_STATUS_IS_OK(nt_status)) {
655 DEBUG(1, ("(saved test) PAC decoding DID NOT fail on modified principal\n"));
657 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
659 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
661 talloc_free(mem_ctx);
665 /* Finally... Bugger up the signature, and check we fail the checksum */
666 tmp_blob.data[tmp_blob.length - 2]++;
668 nt_status = kerberos_decode_pac(mem_ctx, &pac_data,
670 smb_krb5_context->krb5_context,
675 if (NT_STATUS_IS_OK(nt_status)) {
676 DEBUG(1, ("(saved test) PAC decoding DID NOT fail on broken checksum\n"));
678 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
680 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
682 talloc_free(mem_ctx);
686 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
688 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
691 talloc_free(mem_ctx);
695 BOOL torture_pac(void)
698 ret &= torture_pac_self_check();
699 ret &= torture_pac_saved_check();