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 "librpc/gen_ndr/ndr_security.h"
32 #include "torture/torture.h"
34 static BOOL torture_pac_self_check(void)
37 TALLOC_CTX *mem_ctx = talloc_named(NULL, 0, "PAC self check");
39 struct PAC_DATA *pac_data;
40 struct PAC_LOGON_INFO *logon_info;
41 union netr_Validation validation;
43 /* Generate a nice, arbitary keyblock */
44 uint8_t server_bytes[16];
45 uint8_t krbtgt_bytes[16];
46 krb5_keyblock server_keyblock;
47 krb5_keyblock krbtgt_keyblock;
51 struct smb_krb5_context *smb_krb5_context;
53 struct auth_serversupplied_info *server_info;
54 struct auth_serversupplied_info *server_info_out;
56 krb5_principal client_principal;
57 time_t logon_time = time(NULL);
59 ret = smb_krb5_init_context(mem_ctx, &smb_krb5_context);
66 generate_random_buffer(server_bytes, 16);
67 generate_random_buffer(krbtgt_bytes, 16);
69 ret = krb5_keyblock_init(smb_krb5_context->krb5_context,
71 server_bytes, sizeof(server_bytes),
74 printf("(self test) Server Keyblock encoding failed: %s\n",
75 smb_get_krb5_error_message(smb_krb5_context->krb5_context,
82 ret = krb5_keyblock_init(smb_krb5_context->krb5_context,
84 krbtgt_bytes, sizeof(krbtgt_bytes),
87 printf("(self test) KRBTGT Keyblock encoding failed: %s\n",
88 smb_get_krb5_error_message(smb_krb5_context->krb5_context,
91 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
97 /* We need an input, and this one requires no underlying database */
98 nt_status = auth_anonymous_server_info(mem_ctx, &server_info);
100 if (!NT_STATUS_IS_OK(nt_status)) {
101 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
103 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
105 talloc_free(mem_ctx);
109 ret = krb5_parse_name_norealm(smb_krb5_context->krb5_context,
110 server_info->account_name, &client_principal);
112 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
114 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
116 talloc_free(mem_ctx);
120 /* OK, go ahead and make a PAC */
121 ret = kerberos_create_pac(mem_ctx, server_info,
122 smb_krb5_context->krb5_context,
130 printf("(self test) PAC encoding failed: %s\n",
131 smb_get_krb5_error_message(smb_krb5_context->krb5_context,
134 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
136 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
138 krb5_free_principal(smb_krb5_context->krb5_context,
140 talloc_free(mem_ctx);
144 dump_data(10,tmp_blob.data,tmp_blob.length);
146 /* Now check that we can read it back */
147 nt_status = kerberos_decode_pac(mem_ctx, &pac_data,
149 smb_krb5_context->krb5_context,
155 if (!NT_STATUS_IS_OK(nt_status)) {
156 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
158 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
160 krb5_free_principal(smb_krb5_context->krb5_context,
162 DEBUG(1, ("(self test) PAC decoding failed: %s\n",
163 nt_errstr(nt_status)));
165 talloc_free(mem_ctx);
169 /* Now check that we can read it back */
170 nt_status = kerberos_pac_logon_info(mem_ctx, &logon_info,
172 smb_krb5_context->krb5_context,
179 if (!NT_STATUS_IS_OK(nt_status)) {
180 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
182 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
184 krb5_free_principal(smb_krb5_context->krb5_context,
186 printf("(self test) PAC decoding (for logon info) failed: %s\n",
187 nt_errstr(nt_status));
189 talloc_free(mem_ctx);
193 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
195 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
197 krb5_free_principal(smb_krb5_context->krb5_context,
200 validation.sam3 = &logon_info->info3;
201 nt_status = make_server_info_netlogon_validation(mem_ctx,
205 if (!NT_STATUS_IS_OK(nt_status)) {
206 printf("(self test) PAC decoding (make server info) failed: %s\n",
207 nt_errstr(nt_status));
209 talloc_free(mem_ctx);
213 if (!dom_sid_equal(server_info->account_sid,
214 server_info_out->account_sid)) {
215 printf("(self test) PAC Decode resulted in *different* domain SID: %s != %s\n",
216 dom_sid_string(mem_ctx, server_info->account_sid),
217 dom_sid_string(mem_ctx, server_info_out->account_sid));
218 talloc_free(mem_ctx);
222 talloc_free(mem_ctx);
227 /* This is the PAC generated on my test network, by my test Win2k3 server.
228 -- abartlet 2005-07-04
231 static const uint8_t saved_pac[] = {
232 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xd8, 0x01, 0x00, 0x00,
233 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,
234 0x20, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
235 0x40, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
236 0x58, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x10, 0x08, 0x00, 0xcc, 0xcc, 0xcc, 0xcc,
237 0xc8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x30, 0xdf, 0xa6, 0xcb,
238 0x4f, 0x7d, 0xc5, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff,
239 0xff, 0xff, 0xff, 0x7f, 0xc0, 0x3c, 0x4e, 0x59, 0x62, 0x73, 0xc5, 0x01, 0xc0, 0x3c, 0x4e, 0x59,
240 0x62, 0x73, 0xc5, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x16, 0x00, 0x16, 0x00,
241 0x04, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
242 0x0c, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
243 0x14, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x02, 0x00, 0x65, 0x00, 0x00, 0x00,
244 0xed, 0x03, 0x00, 0x00, 0x04, 0x02, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x02, 0x00,
245 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
246 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x16, 0x00, 0x20, 0x00, 0x02, 0x00, 0x16, 0x00, 0x18, 0x00,
247 0x24, 0x00, 0x02, 0x00, 0x28, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
248 0x00, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
249 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
250 0x01, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
251 0x00, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00,
252 0x57, 0x00, 0x32, 0x00, 0x30, 0x00, 0x30, 0x00, 0x33, 0x00, 0x46, 0x00, 0x49, 0x00, 0x4e, 0x00,
253 0x41, 0x00, 0x4c, 0x00, 0x24, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
257 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x02, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
258 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x57, 0x00, 0x32, 0x00,
259 0x30, 0x00, 0x30, 0x00, 0x33, 0x00, 0x46, 0x00, 0x49, 0x00, 0x4e, 0x00, 0x41, 0x00, 0x4c, 0x00,
260 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x57, 0x00, 0x49, 0x00,
261 0x4e, 0x00, 0x32, 0x00, 0x4b, 0x00, 0x33, 0x00, 0x54, 0x00, 0x48, 0x00, 0x49, 0x00, 0x4e, 0x00,
262 0x4b, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05,
263 0x15, 0x00, 0x00, 0x00, 0x11, 0x2f, 0xaf, 0xb5, 0x90, 0x04, 0x1b, 0xec, 0x50, 0x3b, 0xec, 0xdc,
264 0x01, 0x00, 0x00, 0x00, 0x30, 0x00, 0x02, 0x00, 0x07, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
265 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
266 0x80, 0x66, 0x28, 0xea, 0x37, 0x80, 0xc5, 0x01, 0x16, 0x00, 0x77, 0x00, 0x32, 0x00, 0x30, 0x00,
267 0x30, 0x00, 0x33, 0x00, 0x66, 0x00, 0x69, 0x00, 0x6e, 0x00, 0x61, 0x00, 0x6c, 0x00, 0x24, 0x00,
268 0x76, 0xff, 0xff, 0xff, 0x37, 0xd5, 0xb0, 0xf7, 0x24, 0xf0, 0xd6, 0xd4, 0xec, 0x09, 0x86, 0x5a,
269 0xa0, 0xe8, 0xc3, 0xa9, 0x00, 0x00, 0x00, 0x00, 0x76, 0xff, 0xff, 0xff, 0xb4, 0xd8, 0xb8, 0xfe,
270 0x83, 0xb3, 0x13, 0x3f, 0xfc, 0x5c, 0x41, 0xad, 0xe2, 0x64, 0x83, 0xe0, 0x00, 0x00, 0x00, 0x00
273 /* Check with a known 'well formed' PAC, from my test server */
274 static BOOL torture_pac_saved_check(void)
277 TALLOC_CTX *mem_ctx = talloc_named(NULL, 0, "PAC saved check");
278 DATA_BLOB tmp_blob, validate_blob;
279 struct PAC_DATA *pac_data, pac_data2;
280 struct PAC_LOGON_INFO *logon_info;
281 union netr_Validation validation;
282 const char *pac_file, *pac_kdc_key, *pac_member_key;
283 struct auth_serversupplied_info *server_info_out;
285 krb5_keyblock server_keyblock;
286 krb5_keyblock krbtgt_keyblock;
287 struct samr_Password *krbtgt_bytes, *krbsrv_bytes;
290 struct smb_krb5_context *smb_krb5_context;
292 const char *principal_string;
293 krb5_principal client_principal;
294 const char *authtime_string;
297 ret = smb_krb5_init_context(mem_ctx, &smb_krb5_context);
300 talloc_free(mem_ctx);
304 pac_kdc_key = lp_parm_string(-1,"torture","pac_kdc_key");
305 if (pac_kdc_key == NULL) {
306 pac_kdc_key = "B286757148AF7FD252C53603A150B7E7";
309 pac_member_key = lp_parm_string(-1,"torture","pac_member_key");
310 if (pac_member_key == NULL) {
311 pac_member_key = "D217FAEAE5E6B5F95CCC94077AB8A5FC";
314 printf("Using pac_kdc_key '%s'\n", pac_kdc_key);
315 printf("Using pac_member_key '%s'\n", pac_member_key);
317 /* The krbtgt key in use when the above PAC was generated.
318 * This is an arcfour-hmac-md5 key, extracted with our 'net
320 krbtgt_bytes = smbpasswd_gethexpwd(mem_ctx, pac_kdc_key);
322 DEBUG(0, ("(saved test) Could not interpret krbtgt key"));
323 talloc_free(mem_ctx);
327 krbsrv_bytes = smbpasswd_gethexpwd(mem_ctx, pac_member_key);
329 DEBUG(0, ("(saved test) Could not interpret krbsrv key"));
330 talloc_free(mem_ctx);
334 ret = krb5_keyblock_init(smb_krb5_context->krb5_context,
335 ENCTYPE_ARCFOUR_HMAC,
336 krbsrv_bytes->hash, sizeof(krbsrv_bytes->hash),
339 DEBUG(1, ("(saved test) Server Keyblock encoding failed: %s\n",
340 smb_get_krb5_error_message(smb_krb5_context->krb5_context,
343 talloc_free(mem_ctx);
347 ret = krb5_keyblock_init(smb_krb5_context->krb5_context,
348 ENCTYPE_ARCFOUR_HMAC,
349 krbtgt_bytes->hash, sizeof(krbtgt_bytes->hash),
352 DEBUG(1, ("(saved test) Server Keyblock encoding failed: %s\n",
353 smb_get_krb5_error_message(smb_krb5_context->krb5_context,
356 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
358 talloc_free(mem_ctx);
362 pac_file = lp_parm_string(-1,"torture","pac_file");
364 tmp_blob.data = (uint8_t *)file_load(pac_file, &tmp_blob.length, mem_ctx);
365 printf("(saved test) Loaded pac of size %ld from %s\n", (long)tmp_blob.length, pac_file);
367 tmp_blob = data_blob_talloc(mem_ctx, saved_pac, sizeof(saved_pac));
370 dump_data(10,tmp_blob.data,tmp_blob.length);
372 principal_string = lp_parm_string(-1,"torture","pac_client_principal");
373 if (!principal_string) {
374 principal_string = "w2003final$@WIN2K3.THINKER.LOCAL";
377 authtime_string = lp_parm_string(-1,"torture","pac_authtime");
378 if (!authtime_string) {
379 authtime = 1120440609;
381 authtime = strtoull(authtime_string, NULL, 0);
384 ret = krb5_parse_name(smb_krb5_context->krb5_context, principal_string,
387 DEBUG(1, ("(saved test) parsing of client principal [%s] failed: %s\n",
389 smb_get_krb5_error_message(smb_krb5_context->krb5_context, ret, mem_ctx)));
391 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
393 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
395 talloc_free(mem_ctx);
399 /* Decode and verify the signaure on the PAC */
400 nt_status = kerberos_decode_pac(mem_ctx, &pac_data,
402 smb_krb5_context->krb5_context,
405 client_principal, authtime, NULL);
406 if (!NT_STATUS_IS_OK(nt_status)) {
407 DEBUG(1, ("(saved test) PAC decoding failed: %s\n",
408 nt_errstr(nt_status)));
410 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
412 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
414 krb5_free_principal(smb_krb5_context->krb5_context, client_principal);
416 talloc_free(mem_ctx);
420 /* Parse the PAC again, for the logon info this time */
421 nt_status = kerberos_pac_logon_info(mem_ctx, &logon_info,
423 smb_krb5_context->krb5_context,
426 client_principal, authtime, NULL);
428 if (!NT_STATUS_IS_OK(nt_status)) {
429 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
431 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
433 krb5_free_principal(smb_krb5_context->krb5_context, client_principal);
435 printf("(saved test) PAC decoding (for logon info) failed: %s\n",
436 nt_errstr(nt_status));
438 talloc_free(mem_ctx);
442 validation.sam3 = &logon_info->info3;
443 nt_status = make_server_info_netlogon_validation(mem_ctx,
447 if (!NT_STATUS_IS_OK(nt_status)) {
448 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
450 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
452 krb5_free_principal(smb_krb5_context->krb5_context, client_principal);
454 printf("(saved test) PAC decoding (make server info) failed: %s\n",
455 nt_errstr(nt_status));
457 talloc_free(mem_ctx);
462 !dom_sid_equal(dom_sid_parse_talloc(mem_ctx, "S-1-5-21-3048156945-3961193616-3706469200-1005"),
463 server_info_out->account_sid)) {
464 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
466 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
468 krb5_free_principal(smb_krb5_context->krb5_context, client_principal);
470 printf("(saved test) PAC Decode resulted in *different* domain SID: %s != %s\n",
471 "S-1-5-21-3048156945-3961193616-3706469200-1005",
472 dom_sid_string(mem_ctx, server_info_out->account_sid));
473 talloc_free(mem_ctx);
477 ret = kerberos_encode_pac(mem_ctx,
479 smb_krb5_context->krb5_context,
485 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
487 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
489 krb5_free_principal(smb_krb5_context->krb5_context, client_principal);
491 DEBUG(0, ("(saved test) PAC push failed\n"));
492 talloc_free(mem_ctx);
496 dump_data(10,validate_blob.data,validate_blob.length);
498 /* compare both the length and the data bytes after a
499 * pull/push cycle. This ensures we use the exact same
500 * pointer, padding etc algorithms as win2k3.
502 if (tmp_blob.length != validate_blob.length) {
503 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
505 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
507 krb5_free_principal(smb_krb5_context->krb5_context, client_principal);
509 DEBUG(0, ("(saved test) PAC push failed: original buffer length[%u] != created buffer length[%u]\n",
510 (unsigned)tmp_blob.length, (unsigned)validate_blob.length));
511 talloc_free(mem_ctx);
515 if (memcmp(tmp_blob.data, validate_blob.data, tmp_blob.length) != 0) {
516 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
518 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
520 krb5_free_principal(smb_krb5_context->krb5_context, client_principal);
522 DEBUG(0, ("(saved test) PAC push failed: length[%u] matches, but data does not\n",
523 (unsigned)tmp_blob.length));
524 DEBUG(0, ("tmp_data:\n"));
525 dump_data(0, tmp_blob.data, tmp_blob.length);
526 DEBUG(0, ("validate_blob:\n"));
527 dump_data(0, validate_blob.data, validate_blob.length);
529 talloc_free(mem_ctx);
533 ret = kerberos_create_pac(mem_ctx,
535 smb_krb5_context->krb5_context,
538 client_principal, authtime,
542 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
544 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
546 krb5_free_principal(smb_krb5_context->krb5_context, client_principal);
548 DEBUG(0, ("(saved test) regnerated PAC create failed\n"));
549 talloc_free(mem_ctx);
553 dump_data(10,validate_blob.data,validate_blob.length);
555 /* compare both the length and the data bytes after a
556 * pull/push cycle. This ensures we use the exact same
557 * pointer, padding etc algorithms as win2k3.
559 if (tmp_blob.length != validate_blob.length) {
560 nt_status = ndr_pull_struct_blob(&validate_blob, mem_ctx, &pac_data2,
561 (ndr_pull_flags_fn_t)ndr_pull_PAC_DATA);
562 if (!NT_STATUS_IS_OK(nt_status)) {
563 DEBUG(0,("can't parse the PAC\n"));
567 NDR_PRINT_DEBUG(PAC_DATA, pac_data);
569 NDR_PRINT_DEBUG(PAC_DATA, &pac_data2);
571 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
573 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
575 krb5_free_principal(smb_krb5_context->krb5_context, client_principal);
577 DEBUG(0, ("(saved test) PAC regenerate failed: original buffer length[%u] != created buffer length[%u]\n",
578 (unsigned)tmp_blob.length, (unsigned)validate_blob.length));
579 talloc_free(mem_ctx);
583 if (memcmp(tmp_blob.data, validate_blob.data, tmp_blob.length) != 0) {
584 nt_status = ndr_pull_struct_blob(&validate_blob, mem_ctx, &pac_data2,
585 (ndr_pull_flags_fn_t)ndr_pull_PAC_DATA);
586 if (!NT_STATUS_IS_OK(nt_status)) {
587 DEBUG(0,("can't parse the PAC\n"));
591 NDR_PRINT_DEBUG(PAC_DATA, pac_data);
593 NDR_PRINT_DEBUG(PAC_DATA, &pac_data2);
595 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
597 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
599 krb5_free_principal(smb_krb5_context->krb5_context, client_principal);
601 DEBUG(0, ("(saved test) PAC regenerate failed: length[%u] matches, but data does not\n",
602 (unsigned)tmp_blob.length));
603 DEBUG(0, ("tmp_data:\n"));
604 dump_data(0, tmp_blob.data, tmp_blob.length);
605 DEBUG(0, ("validate_blob:\n"));
606 dump_data(0, validate_blob.data, validate_blob.length);
608 talloc_free(mem_ctx);
612 /* Break the auth time, to ensure we check this vital detail (not setting this caused all the pain in the first place... */
613 nt_status = kerberos_decode_pac(mem_ctx, &pac_data,
615 smb_krb5_context->krb5_context,
620 if (NT_STATUS_IS_OK(nt_status)) {
621 DEBUG(1, ("(saved test) PAC decoding DID NOT fail on broken auth time (time + 1)\n"));
623 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
625 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
627 krb5_free_principal(smb_krb5_context->krb5_context, client_principal);
628 talloc_free(mem_ctx);
632 /* Break the client principal */
633 krb5_free_principal(smb_krb5_context->krb5_context, client_principal);
635 ret = krb5_parse_name(smb_krb5_context->krb5_context,
636 "not the right principal", &client_principal);
638 DEBUG(1, ("(saved test) parsing of bogus client principal failed: %s\n",
639 smb_get_krb5_error_message(smb_krb5_context->krb5_context, ret, mem_ctx)));
641 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
643 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
645 talloc_free(mem_ctx);
649 nt_status = kerberos_decode_pac(mem_ctx, &pac_data,
651 smb_krb5_context->krb5_context,
656 if (NT_STATUS_IS_OK(nt_status)) {
657 DEBUG(1, ("(saved test) PAC decoding DID NOT fail on modified principal\n"));
659 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
661 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
663 talloc_free(mem_ctx);
667 /* Finally... Bugger up the signature, and check we fail the checksum */
668 tmp_blob.data[tmp_blob.length - 2]++;
670 nt_status = kerberos_decode_pac(mem_ctx, &pac_data,
672 smb_krb5_context->krb5_context,
677 if (NT_STATUS_IS_OK(nt_status)) {
678 DEBUG(1, ("(saved test) PAC decoding DID NOT fail on broken checksum\n"));
680 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
682 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
684 talloc_free(mem_ctx);
688 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
690 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
693 talloc_free(mem_ctx);
697 BOOL torture_pac(struct torture_context *torture)
700 ret &= torture_pac_self_check();
701 ret &= torture_pac_saved_check();