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 "librpc/gen_ndr/ndr_samr.h"
31 static BOOL torture_pac_self_check(void)
34 TALLOC_CTX *mem_ctx = talloc_named(NULL, 0, "PAC self check");
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 ret = smb_krb5_init_context(mem_ctx, &smb_krb5_context);
63 generate_random_buffer(server_bytes, 16);
64 generate_random_buffer(krbtgt_bytes, 16);
66 ret = krb5_keyblock_init(smb_krb5_context->krb5_context,
68 server_bytes, sizeof(server_bytes),
71 printf("(self test) Server Keyblock encoding failed: %s\n",
72 smb_get_krb5_error_message(smb_krb5_context->krb5_context,
79 ret = krb5_keyblock_init(smb_krb5_context->krb5_context,
81 krbtgt_bytes, sizeof(krbtgt_bytes),
84 printf("(self test) KRBTGT Keyblock encoding failed: %s\n",
85 smb_get_krb5_error_message(smb_krb5_context->krb5_context,
88 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
94 /* We need an input, and this one requires no underlying database */
95 nt_status = auth_anonymous_server_info(mem_ctx, &server_info);
97 if (!NT_STATUS_IS_OK(nt_status)) {
98 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
100 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
102 talloc_free(mem_ctx);
106 ret = krb5_parse_name_norealm(smb_krb5_context->krb5_context,
107 server_info->account_name, &client_principal);
109 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
111 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
113 talloc_free(mem_ctx);
117 /* OK, go ahead and make a PAC */
118 ret = kerberos_create_pac(mem_ctx, server_info,
119 smb_krb5_context->krb5_context,
127 printf("(self test) PAC encoding failed: %s\n",
128 smb_get_krb5_error_message(smb_krb5_context->krb5_context,
131 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
133 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
135 krb5_free_principal(smb_krb5_context->krb5_context,
137 talloc_free(mem_ctx);
141 dump_data(10,tmp_blob.data,tmp_blob.length);
143 /* Now check that we can read it back */
144 nt_status = kerberos_decode_pac(mem_ctx, &pac_data,
146 smb_krb5_context->krb5_context,
152 if (!NT_STATUS_IS_OK(nt_status)) {
153 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
155 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
157 krb5_free_principal(smb_krb5_context->krb5_context,
159 DEBUG(1, ("(self test) PAC decoding failed: %s\n",
160 nt_errstr(nt_status)));
162 talloc_free(mem_ctx);
166 /* Now check that we can read it back */
167 nt_status = kerberos_pac_logon_info(mem_ctx, &logon_info,
169 smb_krb5_context->krb5_context,
176 if (!NT_STATUS_IS_OK(nt_status)) {
177 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
179 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
181 krb5_free_principal(smb_krb5_context->krb5_context,
183 printf("(self test) PAC decoding (for logon info) failed: %s\n",
184 nt_errstr(nt_status));
186 talloc_free(mem_ctx);
190 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
192 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
194 krb5_free_principal(smb_krb5_context->krb5_context,
197 validation.sam3 = &logon_info->info3;
198 nt_status = make_server_info_netlogon_validation(mem_ctx,
202 if (!NT_STATUS_IS_OK(nt_status)) {
203 printf("(self test) PAC decoding (make server info) failed: %s\n",
204 nt_errstr(nt_status));
206 talloc_free(mem_ctx);
210 if (!dom_sid_equal(server_info->account_sid,
211 server_info_out->account_sid)) {
212 printf("(self test) PAC Decode resulted in *different* domain SID: %s != %s\n",
213 dom_sid_string(mem_ctx, server_info->account_sid),
214 dom_sid_string(mem_ctx, server_info_out->account_sid));
215 talloc_free(mem_ctx);
219 talloc_free(mem_ctx);
224 /* This is the PAC generated on my test network, by my test Win2k3 server.
225 -- abartlet 2005-07-04
228 static const uint8_t saved_pac[] = {
229 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xd8, 0x01, 0x00, 0x00,
230 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,
231 0x20, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
232 0x40, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
233 0x58, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x10, 0x08, 0x00, 0xcc, 0xcc, 0xcc, 0xcc,
234 0xc8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x30, 0xdf, 0xa6, 0xcb,
235 0x4f, 0x7d, 0xc5, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff,
236 0xff, 0xff, 0xff, 0x7f, 0xc0, 0x3c, 0x4e, 0x59, 0x62, 0x73, 0xc5, 0x01, 0xc0, 0x3c, 0x4e, 0x59,
237 0x62, 0x73, 0xc5, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x16, 0x00, 0x16, 0x00,
238 0x04, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
239 0x0c, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
240 0x14, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x02, 0x00, 0x65, 0x00, 0x00, 0x00,
241 0xed, 0x03, 0x00, 0x00, 0x04, 0x02, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x02, 0x00,
242 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
243 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x16, 0x00, 0x20, 0x00, 0x02, 0x00, 0x16, 0x00, 0x18, 0x00,
244 0x24, 0x00, 0x02, 0x00, 0x28, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
245 0x00, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
246 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
247 0x01, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
248 0x00, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00,
249 0x57, 0x00, 0x32, 0x00, 0x30, 0x00, 0x30, 0x00, 0x33, 0x00, 0x46, 0x00, 0x49, 0x00, 0x4e, 0x00,
250 0x41, 0x00, 0x4c, 0x00, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
251 0x00, 0x00, 0x00, 0x00, 0x00, 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, 0x01, 0x00, 0x00, 0x00, 0x04, 0x02, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
255 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x57, 0x00, 0x32, 0x00,
256 0x30, 0x00, 0x30, 0x00, 0x33, 0x00, 0x46, 0x00, 0x49, 0x00, 0x4e, 0x00, 0x41, 0x00, 0x4c, 0x00,
257 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x57, 0x00, 0x49, 0x00,
258 0x4e, 0x00, 0x32, 0x00, 0x4b, 0x00, 0x33, 0x00, 0x54, 0x00, 0x48, 0x00, 0x49, 0x00, 0x4e, 0x00,
259 0x4b, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05,
260 0x15, 0x00, 0x00, 0x00, 0x11, 0x2f, 0xaf, 0xb5, 0x90, 0x04, 0x1b, 0xec, 0x50, 0x3b, 0xec, 0xdc,
261 0x01, 0x00, 0x00, 0x00, 0x30, 0x00, 0x02, 0x00, 0x07, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
262 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
263 0x80, 0x66, 0x28, 0xea, 0x37, 0x80, 0xc5, 0x01, 0x16, 0x00, 0x77, 0x00, 0x32, 0x00, 0x30, 0x00,
264 0x30, 0x00, 0x33, 0x00, 0x66, 0x00, 0x69, 0x00, 0x6e, 0x00, 0x61, 0x00, 0x6c, 0x00, 0x24, 0x00,
265 0x76, 0xff, 0xff, 0xff, 0x37, 0xd5, 0xb0, 0xf7, 0x24, 0xf0, 0xd6, 0xd4, 0xec, 0x09, 0x86, 0x5a,
266 0xa0, 0xe8, 0xc3, 0xa9, 0x00, 0x00, 0x00, 0x00, 0x76, 0xff, 0xff, 0xff, 0xb4, 0xd8, 0xb8, 0xfe,
267 0x83, 0xb3, 0x13, 0x3f, 0xfc, 0x5c, 0x41, 0xad, 0xe2, 0x64, 0x83, 0xe0, 0x00, 0x00, 0x00, 0x00
270 /* Check with a known 'well formed' PAC, from my test server */
271 static BOOL torture_pac_saved_check(void)
274 TALLOC_CTX *mem_ctx = talloc_named(NULL, 0, "PAC saved check");
275 DATA_BLOB tmp_blob, validate_blob;
276 struct PAC_DATA *pac_data, pac_data2;
277 struct PAC_LOGON_INFO *logon_info;
278 union netr_Validation validation;
279 const char *pac_file, *pac_kdc_key, *pac_member_key;
280 struct auth_serversupplied_info *server_info_out;
282 krb5_keyblock server_keyblock;
283 krb5_keyblock krbtgt_keyblock;
284 struct samr_Password *krbtgt_bytes, *krbsrv_bytes;
287 struct smb_krb5_context *smb_krb5_context;
289 const char *principal_string;
290 krb5_principal client_principal;
291 const char *authtime_string;
294 ret = smb_krb5_init_context(mem_ctx, &smb_krb5_context);
297 talloc_free(mem_ctx);
301 pac_kdc_key = lp_parm_string(-1,"torture","pac_kdc_key");
302 if (pac_kdc_key == NULL) {
303 pac_kdc_key = "B286757148AF7FD252C53603A150B7E7";
306 pac_member_key = lp_parm_string(-1,"torture","pac_member_key");
307 if (pac_member_key == NULL) {
308 pac_member_key = "D217FAEAE5E6B5F95CCC94077AB8A5FC";
311 printf("Using pac_kdc_key '%s'\n", pac_kdc_key);
312 printf("Using pac_member_key '%s'\n", pac_member_key);
314 /* The krbtgt key in use when the above PAC was generated.
315 * This is an arcfour-hmac-md5 key, extracted with our 'net
317 krbtgt_bytes = smbpasswd_gethexpwd(mem_ctx, pac_kdc_key);
319 DEBUG(0, ("(saved test) Could not interpret krbtgt key"));
320 talloc_free(mem_ctx);
324 krbsrv_bytes = smbpasswd_gethexpwd(mem_ctx, pac_member_key);
326 DEBUG(0, ("(saved test) Could not interpret krbsrv key"));
327 talloc_free(mem_ctx);
331 ret = krb5_keyblock_init(smb_krb5_context->krb5_context,
332 ENCTYPE_ARCFOUR_HMAC,
333 krbsrv_bytes->hash, sizeof(krbsrv_bytes->hash),
336 DEBUG(1, ("(saved test) Server Keyblock encoding failed: %s\n",
337 smb_get_krb5_error_message(smb_krb5_context->krb5_context,
340 talloc_free(mem_ctx);
344 ret = krb5_keyblock_init(smb_krb5_context->krb5_context,
345 ENCTYPE_ARCFOUR_HMAC,
346 krbtgt_bytes->hash, sizeof(krbtgt_bytes->hash),
349 DEBUG(1, ("(saved test) Server Keyblock encoding failed: %s\n",
350 smb_get_krb5_error_message(smb_krb5_context->krb5_context,
353 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
355 talloc_free(mem_ctx);
359 pac_file = lp_parm_string(-1,"torture","pac_file");
361 tmp_blob.data = (uint8_t *)file_load(pac_file, &tmp_blob.length, mem_ctx);
362 printf("(saved test) Loaded pac of size %d from %s\n", tmp_blob.length, pac_file);
364 tmp_blob = data_blob_talloc(mem_ctx, saved_pac, sizeof(saved_pac));
367 dump_data(10,tmp_blob.data,tmp_blob.length);
369 principal_string = lp_parm_string(-1,"torture","pac_client_principal");
370 if (!principal_string) {
371 principal_string = "w2003final$@WIN2K3.THINKER.LOCAL";
374 authtime_string = lp_parm_string(-1,"torture","pac_authtime");
375 if (!authtime_string) {
376 authtime = 1120440609;
378 authtime = strtoull(authtime_string, NULL, 0);
381 ret = krb5_parse_name(smb_krb5_context->krb5_context, principal_string,
384 DEBUG(1, ("(saved test) parsing of client principal [%s] failed: %s\n",
386 smb_get_krb5_error_message(smb_krb5_context->krb5_context, ret, mem_ctx)));
388 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
390 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
392 talloc_free(mem_ctx);
396 /* Decode and verify the signaure on the PAC */
397 nt_status = kerberos_decode_pac(mem_ctx, &pac_data,
399 smb_krb5_context->krb5_context,
402 client_principal, authtime, NULL);
403 if (!NT_STATUS_IS_OK(nt_status)) {
404 DEBUG(1, ("(saved test) PAC decoding failed: %s\n",
405 nt_errstr(nt_status)));
407 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
409 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
411 krb5_free_principal(smb_krb5_context->krb5_context, client_principal);
413 talloc_free(mem_ctx);
417 /* Parse the PAC again, for the logon info this time */
418 nt_status = kerberos_pac_logon_info(mem_ctx, &logon_info,
420 smb_krb5_context->krb5_context,
423 client_principal, authtime, NULL);
425 if (!NT_STATUS_IS_OK(nt_status)) {
426 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
428 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
430 krb5_free_principal(smb_krb5_context->krb5_context, client_principal);
432 printf("(saved test) PAC decoding (for logon info) failed: %s\n",
433 nt_errstr(nt_status));
435 talloc_free(mem_ctx);
439 validation.sam3 = &logon_info->info3;
440 nt_status = make_server_info_netlogon_validation(mem_ctx,
444 if (!NT_STATUS_IS_OK(nt_status)) {
445 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
447 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
449 krb5_free_principal(smb_krb5_context->krb5_context, client_principal);
451 printf("(saved test) PAC decoding (make server info) failed: %s\n",
452 nt_errstr(nt_status));
454 talloc_free(mem_ctx);
459 !dom_sid_equal(dom_sid_parse_talloc(mem_ctx, "S-1-5-21-3048156945-3961193616-3706469200-1005"),
460 server_info_out->account_sid)) {
461 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
463 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
465 krb5_free_principal(smb_krb5_context->krb5_context, client_principal);
467 printf("(saved test) PAC Decode resulted in *different* domain SID: %s != %s\n",
468 "S-1-5-21-3048156945-3961193616-3706469200-1005",
469 dom_sid_string(mem_ctx, server_info_out->account_sid));
470 talloc_free(mem_ctx);
474 ret = kerberos_encode_pac(mem_ctx,
476 smb_krb5_context->krb5_context,
482 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
484 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
486 krb5_free_principal(smb_krb5_context->krb5_context, client_principal);
488 DEBUG(0, ("(saved test) PAC push failed\n"));
489 talloc_free(mem_ctx);
493 dump_data(10,validate_blob.data,validate_blob.length);
495 /* compare both the length and the data bytes after a
496 * pull/push cycle. This ensures we use the exact same
497 * pointer, padding etc algorithms as win2k3.
499 if (tmp_blob.length != validate_blob.length) {
500 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
502 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
504 krb5_free_principal(smb_krb5_context->krb5_context, client_principal);
506 DEBUG(0, ("(saved test) PAC push failed: original buffer length[%u] != created buffer length[%u]\n",
507 (unsigned)tmp_blob.length, (unsigned)validate_blob.length));
508 talloc_free(mem_ctx);
512 if (memcmp(tmp_blob.data, validate_blob.data, tmp_blob.length) != 0) {
513 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
515 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
517 krb5_free_principal(smb_krb5_context->krb5_context, client_principal);
519 DEBUG(0, ("(saved test) PAC push failed: length[%u] matches, but data does not\n",
520 (unsigned)tmp_blob.length));
521 DEBUG(0, ("tmp_data:\n"));
522 dump_data(0, tmp_blob.data, tmp_blob.length);
523 DEBUG(0, ("validate_blob:\n"));
524 dump_data(0, validate_blob.data, validate_blob.length);
526 talloc_free(mem_ctx);
530 ret = kerberos_create_pac(mem_ctx,
532 smb_krb5_context->krb5_context,
535 client_principal, authtime,
539 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
541 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
543 krb5_free_principal(smb_krb5_context->krb5_context, client_principal);
545 DEBUG(0, ("(saved test) regnerated PAC create failed\n"));
546 talloc_free(mem_ctx);
550 dump_data(10,validate_blob.data,validate_blob.length);
552 /* compare both the length and the data bytes after a
553 * pull/push cycle. This ensures we use the exact same
554 * pointer, padding etc algorithms as win2k3.
556 if (tmp_blob.length != validate_blob.length) {
557 nt_status = ndr_pull_struct_blob(&validate_blob, mem_ctx, &pac_data2,
558 (ndr_pull_flags_fn_t)ndr_pull_PAC_DATA);
559 if (!NT_STATUS_IS_OK(nt_status)) {
560 DEBUG(0,("can't parse the PAC\n"));
564 NDR_PRINT_DEBUG(PAC_DATA, pac_data);
566 NDR_PRINT_DEBUG(PAC_DATA, &pac_data2);
568 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
570 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
572 krb5_free_principal(smb_krb5_context->krb5_context, client_principal);
574 DEBUG(0, ("(saved test) PAC regenerate failed: original buffer length[%u] != created buffer length[%u]\n",
575 (unsigned)tmp_blob.length, (unsigned)validate_blob.length));
576 talloc_free(mem_ctx);
580 if (memcmp(tmp_blob.data, validate_blob.data, tmp_blob.length) != 0) {
581 nt_status = ndr_pull_struct_blob(&validate_blob, mem_ctx, &pac_data2,
582 (ndr_pull_flags_fn_t)ndr_pull_PAC_DATA);
583 if (!NT_STATUS_IS_OK(nt_status)) {
584 DEBUG(0,("can't parse the PAC\n"));
588 NDR_PRINT_DEBUG(PAC_DATA, pac_data);
590 NDR_PRINT_DEBUG(PAC_DATA, &pac_data2);
592 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
594 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
596 krb5_free_principal(smb_krb5_context->krb5_context, client_principal);
598 DEBUG(0, ("(saved test) PAC regenerate failed: length[%u] matches, but data does not\n",
599 (unsigned)tmp_blob.length));
600 DEBUG(0, ("tmp_data:\n"));
601 dump_data(0, tmp_blob.data, tmp_blob.length);
602 DEBUG(0, ("validate_blob:\n"));
603 dump_data(0, validate_blob.data, validate_blob.length);
605 talloc_free(mem_ctx);
609 /* Break the auth time, to ensure we check this vital detail (not setting this caused all the pain in the first place... */
610 nt_status = kerberos_decode_pac(mem_ctx, &pac_data,
612 smb_krb5_context->krb5_context,
617 if (NT_STATUS_IS_OK(nt_status)) {
618 DEBUG(1, ("(saved test) PAC decoding DID NOT fail on broken auth time (time + 1)\n"));
620 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
622 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
624 krb5_free_principal(smb_krb5_context->krb5_context, client_principal);
625 talloc_free(mem_ctx);
629 /* Break the client principal */
630 krb5_free_principal(smb_krb5_context->krb5_context, client_principal);
632 ret = krb5_parse_name(smb_krb5_context->krb5_context,
633 "not the right principal", &client_principal);
635 DEBUG(1, ("(saved test) parsing of bogus client principal failed: %s\n",
636 smb_get_krb5_error_message(smb_krb5_context->krb5_context, ret, mem_ctx)));
638 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
640 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
642 talloc_free(mem_ctx);
646 nt_status = kerberos_decode_pac(mem_ctx, &pac_data,
648 smb_krb5_context->krb5_context,
653 if (NT_STATUS_IS_OK(nt_status)) {
654 DEBUG(1, ("(saved test) PAC decoding DID NOT fail on modified principal\n"));
656 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
658 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
660 talloc_free(mem_ctx);
664 /* Finally... Bugger up the signature, and check we fail the checksum */
665 tmp_blob.data[tmp_blob.length - 2]++;
667 nt_status = kerberos_decode_pac(mem_ctx, &pac_data,
669 smb_krb5_context->krb5_context,
674 if (NT_STATUS_IS_OK(nt_status)) {
675 DEBUG(1, ("(saved test) PAC decoding DID NOT fail on broken checksum\n"));
677 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
679 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
681 talloc_free(mem_ctx);
685 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
687 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
690 talloc_free(mem_ctx);
694 BOOL torture_pac(void)
697 ret &= torture_pac_self_check();
698 ret &= torture_pac_saved_check();