root/source4/torture/auth/pac.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. torture_pac_self_check
  2. torture_pac_saved_check
  3. torture_pac

   1 /* 
   2    Unix SMB/CIFS implementation.
   3 
   4    Validate the krb5 pac generation routines
   5    
   6    Copyright (C) Andrew Bartlett <abartlet@samba.org> 2005
   7 
   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.
  12    
  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.
  17 
  18    
  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/>.
  21 */
  22 
  23 #include "includes.h"
  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"
  31 #include "auth/auth_sam_reply.h"
  32 
  33 static bool torture_pac_self_check(struct torture_context *tctx)
     /* [<][>][^][v][top][bottom][index][help] */
  34 {
  35         NTSTATUS nt_status;
  36         DATA_BLOB tmp_blob;
  37         struct PAC_DATA *pac_data;
  38         struct PAC_LOGON_INFO *logon_info;
  39         union netr_Validation validation;
  40 
  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;
  46         
  47         krb5_error_code ret;
  48 
  49         struct smb_krb5_context *smb_krb5_context;
  50 
  51         struct auth_serversupplied_info *server_info;
  52         struct auth_serversupplied_info *server_info_out;
  53 
  54         krb5_principal client_principal;
  55         time_t logon_time = time(NULL);
  56 
  57         TALLOC_CTX *mem_ctx = tctx;
  58 
  59         torture_assert(tctx, 0 == smb_krb5_init_context(mem_ctx, 
  60                                                         NULL,
  61                                                         tctx->lp_ctx,
  62                                                         &smb_krb5_context), 
  63                        "smb_krb5_init_context");
  64 
  65         generate_random_buffer(server_bytes, 16);
  66         generate_random_buffer(krbtgt_bytes, 16);
  67 
  68         ret = krb5_keyblock_init(smb_krb5_context->krb5_context,
  69                                  ENCTYPE_ARCFOUR_HMAC,
  70                                  server_bytes, sizeof(server_bytes),
  71                                  &server_keyblock);
  72         torture_assert(tctx, !ret, talloc_asprintf(tctx, 
  73                                                    "(self test) Server Keyblock encoding failed: %s", 
  74                                                    smb_get_krb5_error_message(smb_krb5_context->krb5_context, 
  75                                                                               ret, mem_ctx)));
  76 
  77         ret = krb5_keyblock_init(smb_krb5_context->krb5_context,
  78                                  ENCTYPE_ARCFOUR_HMAC,
  79                                  krbtgt_bytes, sizeof(krbtgt_bytes),
  80                                  &krbtgt_keyblock);
  81         if (ret) {
  82                 char *err = smb_get_krb5_error_message(smb_krb5_context->krb5_context, 
  83                                                        ret, mem_ctx);
  84         
  85                 krb5_free_keyblock_contents(smb_krb5_context->krb5_context, 
  86                                             &server_keyblock);
  87 
  88                 torture_fail(tctx, talloc_asprintf(tctx, 
  89                                                    "(self test) KRBTGT Keyblock encoding failed: %s", err));
  90         }
  91 
  92         /* We need an input, and this one requires no underlying database */
  93         nt_status = auth_anonymous_server_info(mem_ctx, lp_netbios_name(tctx->lp_ctx), &server_info);
  94 
  95         if (!NT_STATUS_IS_OK(nt_status)) {
  96                 krb5_free_keyblock_contents(smb_krb5_context->krb5_context, 
  97                                             &server_keyblock);
  98                 krb5_free_keyblock_contents(smb_krb5_context->krb5_context, 
  99                                             &krbtgt_keyblock);
 100                 torture_fail(tctx, "auth_anonymous_server_info");
 101         }
 102 
 103         ret = krb5_parse_name_flags(smb_krb5_context->krb5_context, 
 104                                     server_info->account_name, 
 105                                     KRB5_PRINCIPAL_PARSE_NO_REALM, 
 106                                     &client_principal);
 107         if (ret) {
 108                 krb5_free_keyblock_contents(smb_krb5_context->krb5_context, 
 109                                             &server_keyblock);
 110                 krb5_free_keyblock_contents(smb_krb5_context->krb5_context, 
 111                                             &krbtgt_keyblock);
 112                 torture_fail(tctx, "krb5_parse_name_flags(norealm)");
 113         }
 114 
 115         /* OK, go ahead and make a PAC */
 116         ret = kerberos_create_pac(mem_ctx, 
 117                                   lp_iconv_convenience(tctx->lp_ctx),
 118                                   server_info, 
 119                                   smb_krb5_context->krb5_context,  
 120                                   &krbtgt_keyblock,
 121                                   &server_keyblock,
 122                                   client_principal,
 123                                   logon_time,
 124                                   &tmp_blob);
 125         
 126         if (ret) {
 127                 krb5_free_keyblock_contents(smb_krb5_context->krb5_context, 
 128                                             &krbtgt_keyblock);
 129                 krb5_free_keyblock_contents(smb_krb5_context->krb5_context, 
 130                                             &server_keyblock);
 131                 krb5_free_principal(smb_krb5_context->krb5_context, 
 132                                     client_principal);
 133 
 134                 torture_fail(tctx, talloc_asprintf(tctx,
 135                                                    "(self test) PAC encoding failed: %s", 
 136                                                    smb_get_krb5_error_message(smb_krb5_context->krb5_context, 
 137                                                                               ret, mem_ctx)));
 138         }
 139 
 140         dump_data(10,tmp_blob.data,tmp_blob.length);
 141 
 142         /* Now check that we can read it back (using full decode and validate) */
 143         nt_status = kerberos_decode_pac(mem_ctx, 
 144                                         lp_iconv_convenience(tctx->lp_ctx),
 145                                         &pac_data,
 146                                         tmp_blob,
 147                                         smb_krb5_context->krb5_context,
 148                                         &krbtgt_keyblock,
 149                                         &server_keyblock,
 150                                         client_principal, 
 151                                         logon_time, NULL);
 152 
 153         if (!NT_STATUS_IS_OK(nt_status)) {
 154                 krb5_free_keyblock_contents(smb_krb5_context->krb5_context, 
 155                                             &krbtgt_keyblock);
 156                 krb5_free_keyblock_contents(smb_krb5_context->krb5_context, 
 157                                             &server_keyblock);
 158                 krb5_free_principal(smb_krb5_context->krb5_context, 
 159                                     client_principal);
 160 
 161                 torture_fail(tctx, talloc_asprintf(tctx,
 162                                                    "(self test) PAC decoding failed: %s", 
 163                                                    nt_errstr(nt_status)));
 164         }
 165 
 166         /* Now check we can read it back (using Heimdal's pac parsing) */
 167         nt_status = kerberos_pac_blob_to_server_info(mem_ctx, 
 168                                                      lp_iconv_convenience(tctx->lp_ctx),
 169                                                      tmp_blob, 
 170                                                      smb_krb5_context->krb5_context,
 171                                                      &server_info_out);
 172 
 173         if (!dom_sid_equal(server_info->account_sid, 
 174                            server_info_out->account_sid)) {
 175                 krb5_free_keyblock_contents(smb_krb5_context->krb5_context, 
 176                                             &krbtgt_keyblock);
 177                 krb5_free_keyblock_contents(smb_krb5_context->krb5_context, 
 178                                             &server_keyblock);
 179                 krb5_free_principal(smb_krb5_context->krb5_context, 
 180                                     client_principal);
 181 
 182                 torture_fail(tctx,  
 183                              talloc_asprintf(tctx, 
 184                                              "(self test) PAC Decode resulted in *different* domain SID: %s != %s",
 185                                              dom_sid_string(mem_ctx, server_info->account_sid), 
 186                                              dom_sid_string(mem_ctx, server_info_out->account_sid)));
 187         }
 188         talloc_free(server_info_out);
 189 
 190         /* Now check that we can read it back (yet again) */
 191         nt_status = kerberos_pac_logon_info(mem_ctx, 
 192                                             lp_iconv_convenience(tctx->lp_ctx),
 193                                             &logon_info,
 194                                             tmp_blob,
 195                                             smb_krb5_context->krb5_context,
 196                                             &krbtgt_keyblock,
 197                                             &server_keyblock,
 198                                             client_principal, 
 199                                             logon_time, 
 200                                             NULL);
 201         
 202         if (!NT_STATUS_IS_OK(nt_status)) {
 203                 krb5_free_keyblock_contents(smb_krb5_context->krb5_context, 
 204                                             &krbtgt_keyblock);
 205                 krb5_free_keyblock_contents(smb_krb5_context->krb5_context, 
 206                                             &server_keyblock);
 207                 krb5_free_principal(smb_krb5_context->krb5_context, 
 208                                     client_principal);
 209                 
 210                 torture_fail(tctx,  
 211                              talloc_asprintf(tctx, 
 212                                              "(self test) PAC decoding (for logon info) failed: %s", 
 213                                              nt_errstr(nt_status)));
 214         }
 215         
 216         krb5_free_keyblock_contents(smb_krb5_context->krb5_context, 
 217                                     &krbtgt_keyblock);
 218         krb5_free_keyblock_contents(smb_krb5_context->krb5_context, 
 219                                     &server_keyblock);
 220         krb5_free_principal(smb_krb5_context->krb5_context, 
 221                             client_principal);
 222 
 223         /* And make a server info from the samba-parsed PAC */
 224         validation.sam3 = &logon_info->info3;
 225         nt_status = make_server_info_netlogon_validation(mem_ctx,
 226                                                          "",
 227                                                          3, &validation,
 228                                                          &server_info_out); 
 229         if (!NT_STATUS_IS_OK(nt_status)) {
 230                 torture_fail(tctx, 
 231                              talloc_asprintf(tctx, 
 232                                              "(self test) PAC decoding (make server info) failed: %s", 
 233                                              nt_errstr(nt_status)));
 234         }
 235         
 236         if (!dom_sid_equal(server_info->account_sid, 
 237                            server_info_out->account_sid)) {
 238                 torture_fail(tctx,  
 239                              talloc_asprintf(tctx, 
 240                                              "(self test) PAC Decode resulted in *different* domain SID: %s != %s",
 241                                              dom_sid_string(mem_ctx, server_info->account_sid), 
 242                                              dom_sid_string(mem_ctx, server_info_out->account_sid)));
 243         }
 244         return true;
 245 }
 246 
 247 
 248 /* This is the PAC generated on my test network, by my test Win2k3 server.
 249    -- abartlet 2005-07-04
 250 */
 251 
 252 static const uint8_t saved_pac[] = {
 253         0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xd8, 0x01, 0x00, 0x00, 
 254         0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,
 255         0x20, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
 256         0x40, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
 257         0x58, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x10, 0x08, 0x00, 0xcc, 0xcc, 0xcc, 0xcc,
 258         0xc8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x30, 0xdf, 0xa6, 0xcb, 
 259         0x4f, 0x7d, 0xc5, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 
 260         0xff, 0xff, 0xff, 0x7f, 0xc0, 0x3c, 0x4e, 0x59, 0x62, 0x73, 0xc5, 0x01, 0xc0, 0x3c, 0x4e, 0x59,
 261         0x62, 0x73, 0xc5, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x16, 0x00, 0x16, 0x00,
 262         0x04, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
 263         0x0c, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 
 264         0x14, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x02, 0x00, 0x65, 0x00, 0x00, 0x00, 
 265         0xed, 0x03, 0x00, 0x00, 0x04, 0x02, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x02, 0x00,
 266         0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 267         0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x16, 0x00, 0x20, 0x00, 0x02, 0x00, 0x16, 0x00, 0x18, 0x00,
 268         0x24, 0x00, 0x02, 0x00, 0x28, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 269         0x00, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 270         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 271         0x01, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 272         0x00, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00,
 273         0x57, 0x00, 0x32, 0x00, 0x30, 0x00, 0x30, 0x00, 0x33, 0x00, 0x46, 0x00, 0x49, 0x00, 0x4e, 0x00,
 274         0x41, 0x00, 0x4c, 0x00, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 275         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 276         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 277         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 278         0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x02, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
 279         0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x57, 0x00, 0x32, 0x00,
 280         0x30, 0x00, 0x30, 0x00, 0x33, 0x00, 0x46, 0x00, 0x49, 0x00, 0x4e, 0x00, 0x41, 0x00, 0x4c, 0x00,
 281         0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x57, 0x00, 0x49, 0x00,
 282         0x4e, 0x00, 0x32, 0x00, 0x4b, 0x00, 0x33, 0x00, 0x54, 0x00, 0x48, 0x00, 0x49, 0x00, 0x4e, 0x00,
 283         0x4b, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05,
 284         0x15, 0x00, 0x00, 0x00, 0x11, 0x2f, 0xaf, 0xb5, 0x90, 0x04, 0x1b, 0xec, 0x50, 0x3b, 0xec, 0xdc,
 285         0x01, 0x00, 0x00, 0x00, 0x30, 0x00, 0x02, 0x00, 0x07, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
 286         0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 287         0x80, 0x66, 0x28, 0xea, 0x37, 0x80, 0xc5, 0x01, 0x16, 0x00, 0x77, 0x00, 0x32, 0x00, 0x30, 0x00,
 288         0x30, 0x00, 0x33, 0x00, 0x66, 0x00, 0x69, 0x00, 0x6e, 0x00, 0x61, 0x00, 0x6c, 0x00, 0x24, 0x00,
 289         0x76, 0xff, 0xff, 0xff, 0x37, 0xd5, 0xb0, 0xf7, 0x24, 0xf0, 0xd6, 0xd4, 0xec, 0x09, 0x86, 0x5a,
 290         0xa0, 0xe8, 0xc3, 0xa9, 0x00, 0x00, 0x00, 0x00, 0x76, 0xff, 0xff, 0xff, 0xb4, 0xd8, 0xb8, 0xfe,
 291         0x83, 0xb3, 0x13, 0x3f, 0xfc, 0x5c, 0x41, 0xad, 0xe2, 0x64, 0x83, 0xe0, 0x00, 0x00, 0x00, 0x00
 292 };
 293 
 294 /* Check with a known 'well formed' PAC, from my test server */
 295 static bool torture_pac_saved_check(struct torture_context *tctx)
     /* [<][>][^][v][top][bottom][index][help] */
 296 {
 297         NTSTATUS nt_status;
 298         enum ndr_err_code ndr_err;
 299         DATA_BLOB tmp_blob, validate_blob;
 300         struct PAC_DATA *pac_data, pac_data2;
 301         struct PAC_LOGON_INFO *logon_info;
 302         union netr_Validation validation;
 303         const char *pac_file, *pac_kdc_key, *pac_member_key;
 304         struct auth_serversupplied_info *server_info_out;
 305 
 306         krb5_keyblock server_keyblock;
 307         krb5_keyblock krbtgt_keyblock, *krbtgt_keyblock_p;
 308         struct samr_Password *krbtgt_bytes, *krbsrv_bytes;
 309         
 310         krb5_error_code ret;
 311         struct smb_krb5_context *smb_krb5_context;
 312 
 313         const char *principal_string;
 314         char *broken_principal_string;
 315         krb5_principal client_principal;
 316         const char *authtime_string;
 317         time_t authtime;
 318         TALLOC_CTX *mem_ctx = tctx;
 319 
 320         torture_assert(tctx, 0 == smb_krb5_init_context(mem_ctx, NULL,
 321                                                         tctx->lp_ctx,
 322                                                         &smb_krb5_context),
 323                        "smb_krb5_init_context");
 324 
 325         pac_kdc_key = torture_setting_string(tctx, "pac_kdc_key", 
 326                                              "B286757148AF7FD252C53603A150B7E7");
 327 
 328         pac_member_key = torture_setting_string(tctx, "pac_member_key", 
 329                                                 "D217FAEAE5E6B5F95CCC94077AB8A5FC");
 330 
 331         torture_comment(tctx, "Using pac_kdc_key '%s'\n", pac_kdc_key);
 332         torture_comment(tctx, "Using pac_member_key '%s'\n", pac_member_key);
 333 
 334         /* The krbtgt key in use when the above PAC was generated.
 335          * This is an arcfour-hmac-md5 key, extracted with our 'net
 336          * samdump' tool. */
 337         if (*pac_kdc_key == 0) {
 338                 krbtgt_bytes = NULL;
 339         } else {
 340                 krbtgt_bytes = smbpasswd_gethexpwd(mem_ctx, pac_kdc_key);
 341                 if (!krbtgt_bytes) {
 342                         torture_fail(tctx, "(saved test) Could not interpret krbtgt key");
 343                 }
 344         }
 345 
 346         krbsrv_bytes = smbpasswd_gethexpwd(mem_ctx, pac_member_key);
 347         if (!krbsrv_bytes) {
 348                 torture_fail(tctx, "(saved test) Could not interpret krbsrv key");
 349         }
 350 
 351         ret = krb5_keyblock_init(smb_krb5_context->krb5_context,
 352                                  ENCTYPE_ARCFOUR_HMAC,
 353                                  krbsrv_bytes->hash, sizeof(krbsrv_bytes->hash),
 354                                  &server_keyblock);
 355         torture_assert(tctx, !ret,
 356                        talloc_asprintf(tctx,
 357                                        "(saved test) Server Keyblock encoding failed: %s", 
 358                                        smb_get_krb5_error_message(smb_krb5_context->krb5_context, 
 359                                                                   ret, mem_ctx)));
 360 
 361         if (krbtgt_bytes) {
 362                 ret = krb5_keyblock_init(smb_krb5_context->krb5_context,
 363                                          ENCTYPE_ARCFOUR_HMAC,
 364                                          krbtgt_bytes->hash, sizeof(krbtgt_bytes->hash),
 365                                          &krbtgt_keyblock);
 366                 if (ret) {
 367                         krb5_free_keyblock_contents(smb_krb5_context->krb5_context, 
 368                                                     &server_keyblock);
 369                         torture_fail(tctx, 
 370                                      talloc_asprintf(tctx, 
 371                                                      "(saved test) Server Keyblock encoding failed: %s", 
 372                                                      smb_get_krb5_error_message(smb_krb5_context->krb5_context, 
 373                                                                                 ret, mem_ctx)));
 374                 }
 375                 krbtgt_keyblock_p = &krbtgt_keyblock;
 376         } else {
 377                 krbtgt_keyblock_p = NULL;
 378         }
 379 
 380         pac_file = torture_setting_string(tctx, "pac_file", NULL);
 381         if (pac_file) {
 382                 tmp_blob.data = (uint8_t *)file_load(pac_file, &tmp_blob.length, 0, mem_ctx);
 383                 torture_comment(tctx, "(saved test) Loaded pac of size %ld from %s\n", (long)tmp_blob.length, pac_file);
 384         } else {
 385                 tmp_blob = data_blob_talloc(mem_ctx, saved_pac, sizeof(saved_pac));
 386         }
 387         
 388         dump_data(10,tmp_blob.data,tmp_blob.length);
 389 
 390         principal_string = torture_setting_string(tctx, "pac_client_principal", 
 391                                                   "w2003final$@WIN2K3.THINKER.LOCAL");
 392 
 393         authtime_string = torture_setting_string(tctx, "pac_authtime", "1120440609");
 394         authtime = strtoull(authtime_string, NULL, 0);
 395 
 396         ret = krb5_parse_name(smb_krb5_context->krb5_context, principal_string, 
 397                               &client_principal);
 398         if (ret) {
 399                 krb5_free_keyblock_contents(smb_krb5_context->krb5_context, 
 400                                             krbtgt_keyblock_p);
 401                 krb5_free_keyblock_contents(smb_krb5_context->krb5_context, 
 402                                             &server_keyblock);
 403                 torture_fail(tctx,  
 404                              talloc_asprintf(tctx, 
 405                                              "(saved test) parsing of client principal [%s] failed: %s", 
 406                                              principal_string, 
 407                                              smb_get_krb5_error_message(smb_krb5_context->krb5_context, ret, mem_ctx)));
 408         }
 409 
 410         /* Decode and verify the signaure on the PAC */
 411         nt_status = kerberos_decode_pac(mem_ctx, 
 412                                         lp_iconv_convenience(tctx->lp_ctx),
 413                                         &pac_data,
 414                                         tmp_blob,
 415                                         smb_krb5_context->krb5_context,
 416                                         krbtgt_keyblock_p,
 417                                         &server_keyblock, 
 418                                         client_principal, authtime, NULL);
 419         if (!NT_STATUS_IS_OK(nt_status)) {
 420                 krb5_free_keyblock_contents(smb_krb5_context->krb5_context, 
 421                                             krbtgt_keyblock_p);
 422                 krb5_free_keyblock_contents(smb_krb5_context->krb5_context, 
 423                                             &server_keyblock);
 424                 krb5_free_principal(smb_krb5_context->krb5_context, client_principal);
 425                 
 426                 torture_fail(tctx, talloc_asprintf(tctx, 
 427                                                    "(saved test) PAC decoding failed: %s", 
 428                                                    nt_errstr(nt_status)));
 429         }
 430 
 431         /* Now check we can read it back (using Heimdal's pac parsing) */
 432         nt_status = kerberos_pac_blob_to_server_info(mem_ctx, 
 433                                                      lp_iconv_convenience(tctx->lp_ctx),
 434                                                      tmp_blob, 
 435                                                      smb_krb5_context->krb5_context,
 436                                                      &server_info_out);
 437 
 438         if (!NT_STATUS_IS_OK(nt_status)) {
 439                 krb5_free_keyblock_contents(smb_krb5_context->krb5_context, 
 440                                             krbtgt_keyblock_p);
 441                 krb5_free_keyblock_contents(smb_krb5_context->krb5_context, 
 442                                             &server_keyblock);
 443                 krb5_free_principal(smb_krb5_context->krb5_context, client_principal);
 444                 
 445                 torture_fail(tctx, talloc_asprintf(tctx, 
 446                                                    "(saved test) Heimdal PAC decoding failed: %s", 
 447                                                    nt_errstr(nt_status)));
 448         }
 449 
 450         if (!pac_file &&
 451             !dom_sid_equal(dom_sid_parse_talloc(mem_ctx, 
 452                                                 "S-1-5-21-3048156945-3961193616-3706469200-1005"), 
 453                            server_info_out->account_sid)) {
 454                 krb5_free_keyblock_contents(smb_krb5_context->krb5_context, 
 455                                             krbtgt_keyblock_p);
 456                 krb5_free_keyblock_contents(smb_krb5_context->krb5_context, 
 457                                             &server_keyblock);
 458                 krb5_free_principal(smb_krb5_context->krb5_context, client_principal);
 459 
 460                 torture_fail(tctx,  
 461                              talloc_asprintf(tctx, 
 462                                              "(saved test) Heimdal PAC Decode resulted in *different* domain SID: %s != %s",
 463                                              "S-1-5-21-3048156945-3961193616-3706469200-1005", 
 464                                              dom_sid_string(mem_ctx, server_info_out->account_sid)));
 465         }
 466 
 467         talloc_free(server_info_out);
 468 
 469         /* Parse the PAC again, for the logon info this time (using Samba4's parsing) */
 470         nt_status = kerberos_pac_logon_info(mem_ctx, 
 471                                             lp_iconv_convenience(tctx->lp_ctx),
 472                                             &logon_info,
 473                                             tmp_blob,
 474                                             smb_krb5_context->krb5_context,
 475                                             krbtgt_keyblock_p,
 476                                             &server_keyblock,
 477                                             client_principal, authtime, NULL);
 478 
 479         if (!NT_STATUS_IS_OK(nt_status)) {
 480                 krb5_free_keyblock_contents(smb_krb5_context->krb5_context, 
 481                                             krbtgt_keyblock_p);
 482                 krb5_free_keyblock_contents(smb_krb5_context->krb5_context, 
 483                                             &server_keyblock);
 484                 krb5_free_principal(smb_krb5_context->krb5_context, client_principal);
 485         
 486                 torture_fail(tctx,  
 487                              talloc_asprintf(tctx, 
 488                                              "(saved test) PAC decoding (for logon info) failed: %s", 
 489                                              nt_errstr(nt_status)));
 490         }
 491 
 492         validation.sam3 = &logon_info->info3;
 493         nt_status = make_server_info_netlogon_validation(mem_ctx,
 494                                                          "",
 495                                                          3, &validation,
 496                                                          &server_info_out); 
 497         if (!NT_STATUS_IS_OK(nt_status)) {
 498                 krb5_free_keyblock_contents(smb_krb5_context->krb5_context, 
 499                                             krbtgt_keyblock_p);
 500                 krb5_free_keyblock_contents(smb_krb5_context->krb5_context, 
 501                                             &server_keyblock);
 502                 krb5_free_principal(smb_krb5_context->krb5_context, client_principal);
 503 
 504                 torture_fail(tctx,  
 505                              talloc_asprintf(tctx, 
 506                                              "(saved test) PAC decoding (make server info) failed: %s", 
 507                                              nt_errstr(nt_status)));
 508         }
 509 
 510         if (!pac_file &&
 511             !dom_sid_equal(dom_sid_parse_talloc(mem_ctx, 
 512                                                 "S-1-5-21-3048156945-3961193616-3706469200-1005"), 
 513                            server_info_out->account_sid)) {
 514                 krb5_free_keyblock_contents(smb_krb5_context->krb5_context, 
 515                                             krbtgt_keyblock_p);
 516                 krb5_free_keyblock_contents(smb_krb5_context->krb5_context, 
 517                                             &server_keyblock);
 518                 krb5_free_principal(smb_krb5_context->krb5_context, client_principal);
 519 
 520                 torture_fail(tctx,  
 521                              talloc_asprintf(tctx, 
 522                                              "(saved test) PAC Decode resulted in *different* domain SID: %s != %s",
 523                                              "S-1-5-21-3048156945-3961193616-3706469200-1005", 
 524                                              dom_sid_string(mem_ctx, server_info_out->account_sid)));
 525         }
 526 
 527         if (krbtgt_bytes == NULL) {
 528                 torture_comment(tctx, "skipping PAC encoding tests as non kdc key\n");
 529                 krb5_free_keyblock_contents(smb_krb5_context->krb5_context, 
 530                                             &server_keyblock);
 531                 krb5_free_principal(smb_krb5_context->krb5_context, client_principal);
 532                 return true;
 533         }
 534 
 535         ret = kerberos_encode_pac(mem_ctx, 
 536                                   lp_iconv_convenience(tctx->lp_ctx),
 537                                   pac_data,
 538                                   smb_krb5_context->krb5_context,
 539                                   krbtgt_keyblock_p,
 540                                   &server_keyblock,
 541                                   &validate_blob);
 542 
 543         if (ret != 0) {
 544                 krb5_free_keyblock_contents(smb_krb5_context->krb5_context, 
 545                                             krbtgt_keyblock_p);
 546                 krb5_free_keyblock_contents(smb_krb5_context->krb5_context, 
 547                                             &server_keyblock);
 548                 krb5_free_principal(smb_krb5_context->krb5_context, client_principal);
 549 
 550                 torture_fail(tctx, "(saved test) PAC push failed");
 551         }
 552 
 553         dump_data(10, validate_blob.data, validate_blob.length);
 554 
 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.
 558          */
 559         if (tmp_blob.length != validate_blob.length) {
 560                 krb5_free_keyblock_contents(smb_krb5_context->krb5_context, 
 561                                             krbtgt_keyblock_p);
 562                 krb5_free_keyblock_contents(smb_krb5_context->krb5_context, 
 563                                             &server_keyblock);
 564                 krb5_free_principal(smb_krb5_context->krb5_context, client_principal);
 565 
 566                 torture_fail(tctx, 
 567                              talloc_asprintf(tctx, 
 568                                              "(saved test) PAC push failed: original buffer length[%u] != created buffer length[%u]",
 569                                              (unsigned)tmp_blob.length, (unsigned)validate_blob.length));
 570         }
 571 
 572         if (memcmp(tmp_blob.data, validate_blob.data, tmp_blob.length) != 0) {
 573                 krb5_free_keyblock_contents(smb_krb5_context->krb5_context, 
 574                                             krbtgt_keyblock_p);
 575                 krb5_free_keyblock_contents(smb_krb5_context->krb5_context, 
 576                                             &server_keyblock);
 577                 krb5_free_principal(smb_krb5_context->krb5_context, client_principal);
 578 
 579                 DEBUG(0, ("tmp_data:\n"));
 580                 dump_data(0, tmp_blob.data, tmp_blob.length);
 581                 DEBUG(0, ("validate_blob:\n"));
 582                 dump_data(0, validate_blob.data, validate_blob.length);
 583 
 584                 torture_fail(tctx, talloc_asprintf(tctx, "(saved test) PAC push failed: length[%u] matches, but data does not", (unsigned)tmp_blob.length));
 585         }
 586 
 587         ret = kerberos_create_pac(mem_ctx, 
 588                                   lp_iconv_convenience(tctx->lp_ctx),
 589                                   server_info_out,
 590                                   smb_krb5_context->krb5_context,
 591                                   krbtgt_keyblock_p,
 592                                   &server_keyblock,
 593                                   client_principal, authtime,
 594                                   &validate_blob);
 595 
 596         if (ret != 0) {
 597                 krb5_free_keyblock_contents(smb_krb5_context->krb5_context, 
 598                                             krbtgt_keyblock_p);
 599                 krb5_free_keyblock_contents(smb_krb5_context->krb5_context, 
 600                                             &server_keyblock);
 601                 krb5_free_principal(smb_krb5_context->krb5_context, client_principal);
 602 
 603                 torture_fail(tctx, "(saved test) regnerated PAC create failed");
 604         }
 605 
 606         dump_data(10,validate_blob.data,validate_blob.length);
 607 
 608         /* compare both the length and the data bytes after a
 609          * pull/push cycle.  This ensures we use the exact same
 610          * pointer, padding etc algorithms as win2k3.
 611          */
 612         if (tmp_blob.length != validate_blob.length) {
 613                 ndr_err = ndr_pull_struct_blob(&validate_blob, mem_ctx, 
 614                                                lp_iconv_convenience(tctx->lp_ctx), &pac_data2,
 615                                                (ndr_pull_flags_fn_t)ndr_pull_PAC_DATA);
 616                 nt_status = ndr_map_error2ntstatus(ndr_err);
 617                 torture_assert_ntstatus_ok(tctx, nt_status, "can't parse the PAC");
 618                 
 619                 NDR_PRINT_DEBUG(PAC_DATA, pac_data);
 620 
 621                 NDR_PRINT_DEBUG(PAC_DATA, &pac_data2);
 622 
 623                 krb5_free_keyblock_contents(smb_krb5_context->krb5_context, 
 624                                             krbtgt_keyblock_p);
 625                 krb5_free_keyblock_contents(smb_krb5_context->krb5_context, 
 626                                             &server_keyblock);
 627                 krb5_free_principal(smb_krb5_context->krb5_context, client_principal);
 628 
 629                 torture_fail(tctx, talloc_asprintf(tctx, 
 630                                                    "(saved test) PAC regenerate failed: original buffer length[%u] != created buffer length[%u]",
 631                                                    (unsigned)tmp_blob.length, (unsigned)validate_blob.length));
 632         }
 633 
 634         if (memcmp(tmp_blob.data, validate_blob.data, tmp_blob.length) != 0) {
 635                 ndr_err = ndr_pull_struct_blob(&validate_blob, mem_ctx, 
 636                                                lp_iconv_convenience(tctx->lp_ctx), &pac_data2,
 637                                                (ndr_pull_flags_fn_t)ndr_pull_PAC_DATA);
 638                 nt_status = ndr_map_error2ntstatus(ndr_err);
 639                 torture_assert_ntstatus_ok(tctx, nt_status, "can't parse the PAC");
 640                 
 641                 NDR_PRINT_DEBUG(PAC_DATA, pac_data);
 642 
 643                 NDR_PRINT_DEBUG(PAC_DATA, &pac_data2);
 644 
 645                 krb5_free_keyblock_contents(smb_krb5_context->krb5_context, 
 646                                             krbtgt_keyblock_p);
 647                 krb5_free_keyblock_contents(smb_krb5_context->krb5_context, 
 648                                             &server_keyblock);
 649                 krb5_free_principal(smb_krb5_context->krb5_context, client_principal);
 650 
 651                 DEBUG(0, ("tmp_data:\n"));
 652                 dump_data(0, tmp_blob.data, tmp_blob.length);
 653                 DEBUG(0, ("validate_blob:\n"));
 654                 dump_data(0, validate_blob.data, validate_blob.length);
 655 
 656                 torture_fail(tctx, talloc_asprintf(tctx, 
 657                                                    "(saved test) PAC regenerate failed: length[%u] matches, but data does not", (unsigned)tmp_blob.length));
 658         }
 659 
 660         /* Break the auth time, to ensure we check this vital detail (not setting this caused all the pain in the first place... */
 661         nt_status = kerberos_decode_pac(mem_ctx, 
 662                                         lp_iconv_convenience(tctx->lp_ctx),
 663                                         &pac_data,
 664                                         tmp_blob,
 665                                         smb_krb5_context->krb5_context,
 666                                         krbtgt_keyblock_p,
 667                                         &server_keyblock,
 668                                         client_principal, 
 669                                         authtime + 1, NULL);
 670         if (NT_STATUS_IS_OK(nt_status)) {
 671 
 672                 krb5_free_keyblock_contents(smb_krb5_context->krb5_context, 
 673                                             krbtgt_keyblock_p);
 674                 krb5_free_keyblock_contents(smb_krb5_context->krb5_context, 
 675                                             &server_keyblock);
 676                 krb5_free_principal(smb_krb5_context->krb5_context, client_principal);
 677                 torture_fail(tctx, "(saved test) PAC decoding DID NOT fail on broken auth time (time + 1)");
 678         }
 679 
 680         /* Break the client principal */
 681         krb5_free_principal(smb_krb5_context->krb5_context, client_principal);
 682 
 683         broken_principal_string = talloc_strdup(mem_ctx, principal_string);
 684         broken_principal_string[0]++;
 685 
 686         ret = krb5_parse_name(smb_krb5_context->krb5_context,
 687                               broken_principal_string, &client_principal);
 688         if (ret) {
 689 
 690                 krb5_free_keyblock_contents(smb_krb5_context->krb5_context, 
 691                                             krbtgt_keyblock_p);
 692                 krb5_free_keyblock_contents(smb_krb5_context->krb5_context, 
 693                                             &server_keyblock);
 694                 torture_fail(tctx, talloc_asprintf(tctx, 
 695                                                    "(saved test) parsing of broken client principal failed: %s", 
 696                                                    smb_get_krb5_error_message(smb_krb5_context->krb5_context, ret, mem_ctx)));
 697         }
 698 
 699         nt_status = kerberos_decode_pac(mem_ctx, 
 700                                         lp_iconv_convenience(tctx->lp_ctx),
 701                                         &pac_data,
 702                                         tmp_blob,
 703                                         smb_krb5_context->krb5_context,
 704                                         krbtgt_keyblock_p,
 705                                         &server_keyblock,
 706                                         client_principal, 
 707                                         authtime, NULL);
 708         if (NT_STATUS_IS_OK(nt_status)) {
 709                 krb5_free_keyblock_contents(smb_krb5_context->krb5_context, 
 710                                             krbtgt_keyblock_p);
 711                 krb5_free_keyblock_contents(smb_krb5_context->krb5_context, 
 712                                             &server_keyblock);
 713                 torture_fail(tctx, "(saved test) PAC decoding DID NOT fail on modified principal");
 714         }
 715 
 716         /* Finally...  Bugger up the signature, and check we fail the checksum */
 717         tmp_blob.data[tmp_blob.length - 2]++;
 718 
 719         nt_status = kerberos_decode_pac(mem_ctx, 
 720                                         lp_iconv_convenience(tctx->lp_ctx),
 721                                         &pac_data,
 722                                         tmp_blob,
 723                                         smb_krb5_context->krb5_context,
 724                                         krbtgt_keyblock_p,
 725                                         &server_keyblock,
 726                                         client_principal, 
 727                                         authtime, NULL);
 728         if (NT_STATUS_IS_OK(nt_status)) {
 729                 krb5_free_keyblock_contents(smb_krb5_context->krb5_context, 
 730                                             krbtgt_keyblock_p);
 731                 krb5_free_keyblock_contents(smb_krb5_context->krb5_context, 
 732                                             &server_keyblock);
 733                 torture_fail(tctx, "(saved test) PAC decoding DID NOT fail on broken checksum");
 734         }
 735 
 736         krb5_free_keyblock_contents(smb_krb5_context->krb5_context, 
 737                                     krbtgt_keyblock_p);
 738         krb5_free_keyblock_contents(smb_krb5_context->krb5_context, 
 739                                     &server_keyblock);
 740         return true;
 741 }
 742 
 743 struct torture_suite *torture_pac(TALLOC_CTX *mem_ctx)
     /* [<][>][^][v][top][bottom][index][help] */
 744 {
 745         struct torture_suite *suite = torture_suite_create(mem_ctx, "PAC");
 746 
 747         torture_suite_add_simple_test(suite, "self check", 
 748                                       torture_pac_self_check);
 749         torture_suite_add_simple_test(suite, "saved check",
 750                                       torture_pac_saved_check);
 751         return suite;
 752 }

/* [<][>][^][v][top][bottom][index][help] */