root/source3/libads/kerberos_verify.c

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

DEFINITIONS

This source file includes following definitions.
  1. ads_dedicated_keytab_verify_ticket
  2. ads_keytab_verify_ticket
  3. ads_secrets_verify_ticket
  4. ads_verify_ticket

   1 /* 
   2    Unix SMB/CIFS implementation.
   3    kerberos utility library
   4    Copyright (C) Andrew Tridgell 2001
   5    Copyright (C) Remus Koos 2001
   6    Copyright (C) Luke Howard 2003   
   7    Copyright (C) Guenther Deschner 2003, 2005
   8    Copyright (C) Jim McDonough (jmcd@us.ibm.com) 2003
   9    Copyright (C) Andrew Bartlett <abartlet@samba.org> 2004-2005
  10    Copyright (C) Jeremy Allison 2007
  11    
  12    This program is free software; you can redistribute it and/or modify
  13    it under the terms of the GNU General Public License as published by
  14    the Free Software Foundation; either version 3 of the License, or
  15    (at your option) any later version.
  16    
  17    This program is distributed in the hope that it will be useful,
  18    but WITHOUT ANY WARRANTY; without even the implied warranty of
  19    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  20    GNU General Public License for more details.
  21    
  22    You should have received a copy of the GNU General Public License
  23    along with this program.  If not, see <http://www.gnu.org/licenses/>.
  24 */
  25 
  26 #include "includes.h"
  27 
  28 #ifdef HAVE_KRB5
  29 
  30 #if !defined(HAVE_KRB5_PRINC_COMPONENT)
  31 const krb5_data *krb5_princ_component(krb5_context, krb5_principal, int );
  32 #endif
  33 
  34 static bool ads_dedicated_keytab_verify_ticket(krb5_context context,
     /* [<][>][^][v][top][bottom][index][help] */
  35                                           krb5_auth_context auth_context,
  36                                           const DATA_BLOB *ticket,
  37                                           krb5_ticket **pp_tkt,
  38                                           krb5_keyblock **keyblock,
  39                                           krb5_error_code *perr)
  40 {
  41         krb5_error_code ret = 0;
  42         bool auth_ok = false;
  43         krb5_keytab keytab = NULL;
  44         krb5_keytab_entry kt_entry;
  45         krb5_ticket *dec_ticket = NULL;
  46 
  47         krb5_data packet;
  48         krb5_kvno kvno = 0;
  49         krb5_enctype enctype;
  50 
  51         *pp_tkt = NULL;
  52         *keyblock = NULL;
  53         *perr = 0;
  54 
  55         ZERO_STRUCT(kt_entry);
  56 
  57         ret = smb_krb5_open_keytab(context, lp_dedicated_keytab_file(), true,
  58             &keytab);
  59         if (ret) {
  60                 DEBUG(1, ("smb_krb5_open_keytab failed (%s)\n",
  61                         error_message(ret)));
  62                 goto out;
  63         }
  64 
  65         packet.length = ticket->length;
  66         packet.data = (char *)ticket->data;
  67 
  68         ret = krb5_rd_req(context, &auth_context, &packet, NULL, keytab,
  69             NULL, &dec_ticket);
  70         if (ret) {
  71                 DEBUG(0, ("krb5_rd_req failed (%s)\n", error_message(ret)));
  72                 goto out;
  73         }
  74 
  75 #ifdef HAVE_ETYPE_IN_ENCRYPTEDDATA /* Heimdal */
  76         enctype = dec_ticket->ticket.key.keytype;
  77 #else /* MIT */
  78         enctype = dec_ticket->enc_part.enctype;
  79         kvno    = dec_ticket->enc_part.kvno;
  80 #endif
  81 
  82         /* Get the key for checking the pac signature */
  83         ret = krb5_kt_get_entry(context, keytab, dec_ticket->server,
  84                                 kvno, enctype, &kt_entry);
  85         if (ret) {
  86                 DEBUG(0, ("krb5_kt_get_entry failed (%s)\n",
  87                           error_message(ret)));
  88                 goto out;
  89         }
  90 
  91         ret = krb5_copy_keyblock(context, KRB5_KT_KEY(&kt_entry), keyblock);
  92         smb_krb5_kt_free_entry(context, &kt_entry);
  93 
  94         if (ret) {
  95                 DEBUG(0, ("failed to copy key: %s\n",
  96                           error_message(ret)));
  97                 goto out;
  98         }
  99 
 100         auth_ok = true;
 101         *pp_tkt = dec_ticket;
 102         dec_ticket = NULL;
 103 
 104   out:
 105         if (dec_ticket)
 106                 krb5_free_ticket(context, dec_ticket);
 107 
 108         if (keytab)
 109                 krb5_kt_close(context, keytab);
 110 
 111         *perr = ret;
 112         return auth_ok;
 113 }
 114 
 115 /**********************************************************************************
 116  Try to verify a ticket using the system keytab... the system keytab has kvno -1 entries, so
 117  it's more like what microsoft does... see comment in utils/net_ads.c in the
 118  ads_keytab_add_entry function for details.
 119 ***********************************************************************************/
 120 
 121 static bool ads_keytab_verify_ticket(krb5_context context,
     /* [<][>][^][v][top][bottom][index][help] */
 122                                         krb5_auth_context auth_context,
 123                                         const DATA_BLOB *ticket,
 124                                         krb5_ticket **pp_tkt,
 125                                         krb5_keyblock **keyblock,
 126                                         krb5_error_code *perr)
 127 {
 128         krb5_error_code ret = 0;
 129         bool auth_ok = False;
 130         krb5_keytab keytab = NULL;
 131         krb5_kt_cursor kt_cursor;
 132         krb5_keytab_entry kt_entry;
 133         char *valid_princ_formats[7] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL };
 134         char *entry_princ_s = NULL;
 135         fstring my_name, my_fqdn;
 136         int i;
 137         int number_matched_principals = 0;
 138         krb5_data packet;
 139 
 140         *pp_tkt = NULL;
 141         *keyblock = NULL;
 142         *perr = 0;
 143 
 144         /* Generate the list of principal names which we expect
 145          * clients might want to use for authenticating to the file
 146          * service.  We allow name$,{host,cifs}/{name,fqdn,name.REALM}. */
 147 
 148         fstrcpy(my_name, global_myname());
 149 
 150         my_fqdn[0] = '\0';
 151         name_to_fqdn(my_fqdn, global_myname());
 152 
 153         if (asprintf(&valid_princ_formats[0], "%s$@%s", my_name, lp_realm()) == -1) {
 154                 goto out;
 155         }
 156         if (asprintf(&valid_princ_formats[1], "host/%s@%s", my_name, lp_realm()) == -1) {
 157                 goto out;
 158         }
 159         if (asprintf(&valid_princ_formats[2], "host/%s@%s", my_fqdn, lp_realm()) == -1) {
 160                 goto out;
 161         }
 162         if (asprintf(&valid_princ_formats[3], "host/%s.%s@%s", my_name, lp_realm(), lp_realm()) == -1) {
 163                 goto out;
 164         }
 165         if (asprintf(&valid_princ_formats[4], "cifs/%s@%s", my_name, lp_realm()) == -1) {
 166                 goto out;
 167         }
 168         if (asprintf(&valid_princ_formats[5], "cifs/%s@%s", my_fqdn, lp_realm()) == -1) {
 169                 goto out;
 170         }
 171         if (asprintf(&valid_princ_formats[6], "cifs/%s.%s@%s", my_name, lp_realm(), lp_realm()) == -1) {
 172                 goto out;
 173         }
 174 
 175         ZERO_STRUCT(kt_entry);
 176         ZERO_STRUCT(kt_cursor);
 177 
 178         ret = smb_krb5_open_keytab(context, NULL, False, &keytab);
 179         if (ret) {
 180                 DEBUG(1, ("ads_keytab_verify_ticket: smb_krb5_open_keytab failed (%s)\n", error_message(ret)));
 181                 goto out;
 182         }
 183 
 184         /* Iterate through the keytab.  For each key, if the principal
 185          * name case-insensitively matches one of the allowed formats,
 186          * try verifying the ticket using that principal. */
 187 
 188         ret = krb5_kt_start_seq_get(context, keytab, &kt_cursor);
 189         if (ret) {
 190                 DEBUG(1, ("ads_keytab_verify_ticket: krb5_kt_start_seq_get failed (%s)\n", error_message(ret)));
 191                 goto out;
 192         }
 193   
 194         while (!auth_ok && (krb5_kt_next_entry(context, keytab, &kt_entry, &kt_cursor) == 0)) {
 195                 ret = smb_krb5_unparse_name(talloc_tos(), context, kt_entry.principal, &entry_princ_s);
 196                 if (ret) {
 197                         DEBUG(1, ("ads_keytab_verify_ticket: smb_krb5_unparse_name failed (%s)\n",
 198                                 error_message(ret)));
 199                         goto out;
 200                 }
 201 
 202                 for (i = 0; i < ARRAY_SIZE(valid_princ_formats); i++) {
 203 
 204                         if (!strequal(entry_princ_s, valid_princ_formats[i])) {
 205                                 continue;
 206                         }
 207 
 208                         number_matched_principals++;
 209                         packet.length = ticket->length;
 210                         packet.data = (char *)ticket->data;
 211                         *pp_tkt = NULL;
 212 
 213                         ret = krb5_rd_req_return_keyblock_from_keytab(context, &auth_context, &packet,
 214                                                                       kt_entry.principal, keytab,
 215                                                                       NULL, pp_tkt, keyblock);
 216 
 217                         if (ret) {
 218                                 DEBUG(10,("ads_keytab_verify_ticket: "
 219                                         "krb5_rd_req_return_keyblock_from_keytab(%s) failed: %s\n",
 220                                         entry_princ_s, error_message(ret)));
 221 
 222                                 /* workaround for MIT: 
 223                                 * as krb5_ktfile_get_entry will explicitly
 224                                 * close the krb5_keytab as soon as krb5_rd_req
 225                                 * has successfully decrypted the ticket but the
 226                                 * ticket is not valid yet (due to clockskew)
 227                                 * there is no point in querying more keytab
 228                                 * entries - Guenther */
 229                                         
 230                                 if (ret == KRB5KRB_AP_ERR_TKT_NYV || 
 231                                     ret == KRB5KRB_AP_ERR_TKT_EXPIRED ||
 232                                     ret == KRB5KRB_AP_ERR_SKEW) {
 233                                         break;
 234                                 }
 235                         } else {
 236                                 DEBUG(3,("ads_keytab_verify_ticket: "
 237                                         "krb5_rd_req_return_keyblock_from_keytab succeeded for principal %s\n",
 238                                         entry_princ_s));
 239                                 auth_ok = True;
 240                                 break;
 241                         }
 242                 }
 243 
 244                 /* Free the name we parsed. */
 245                 TALLOC_FREE(entry_princ_s);
 246 
 247                 /* Free the entry we just read. */
 248                 smb_krb5_kt_free_entry(context, &kt_entry);
 249                 ZERO_STRUCT(kt_entry);
 250         }
 251         krb5_kt_end_seq_get(context, keytab, &kt_cursor);
 252 
 253         ZERO_STRUCT(kt_cursor);
 254 
 255   out:
 256         
 257         for (i = 0; i < ARRAY_SIZE(valid_princ_formats); i++) {
 258                 SAFE_FREE(valid_princ_formats[i]);
 259         }
 260         
 261         if (!auth_ok) {
 262                 if (!number_matched_principals) {
 263                         DEBUG(3, ("ads_keytab_verify_ticket: no keytab principals matched expected file service name.\n"));
 264                 } else {
 265                         DEBUG(3, ("ads_keytab_verify_ticket: krb5_rd_req failed for all %d matched keytab principals\n",
 266                                 number_matched_principals));
 267                 }
 268         }
 269 
 270         SAFE_FREE(entry_princ_s);
 271 
 272         {
 273                 krb5_keytab_entry zero_kt_entry;
 274                 ZERO_STRUCT(zero_kt_entry);
 275                 if (memcmp(&zero_kt_entry, &kt_entry, sizeof(krb5_keytab_entry))) {
 276                         smb_krb5_kt_free_entry(context, &kt_entry);
 277                 }
 278         }
 279 
 280         {
 281                 krb5_kt_cursor zero_csr;
 282                 ZERO_STRUCT(zero_csr);
 283                 if ((memcmp(&kt_cursor, &zero_csr, sizeof(krb5_kt_cursor)) != 0) && keytab) {
 284                         krb5_kt_end_seq_get(context, keytab, &kt_cursor);
 285                 }
 286         }
 287 
 288         if (keytab) {
 289                 krb5_kt_close(context, keytab);
 290         }
 291         *perr = ret;
 292         return auth_ok;
 293 }
 294 
 295 /**********************************************************************************
 296  Try to verify a ticket using the secrets.tdb.
 297 ***********************************************************************************/
 298 
 299 static krb5_error_code ads_secrets_verify_ticket(krb5_context context,
     /* [<][>][^][v][top][bottom][index][help] */
 300                                                 krb5_auth_context auth_context,
 301                                                 krb5_principal host_princ,
 302                                                 const DATA_BLOB *ticket,
 303                                                 krb5_ticket **pp_tkt,
 304                                                 krb5_keyblock **keyblock,
 305                                                 krb5_error_code *perr)
 306 {
 307         krb5_error_code ret = 0;
 308         bool auth_ok = False;
 309         char *password_s = NULL;
 310         krb5_data password;
 311         krb5_enctype enctypes[] = { 
 312 #if defined(ENCTYPE_ARCFOUR_HMAC)
 313                 ENCTYPE_ARCFOUR_HMAC,
 314 #endif
 315                 ENCTYPE_DES_CBC_CRC, 
 316                 ENCTYPE_DES_CBC_MD5, 
 317                 ENCTYPE_NULL
 318         };
 319         krb5_data packet;
 320         int i;
 321 
 322         *pp_tkt = NULL;
 323         *keyblock = NULL;
 324         *perr = 0;
 325 
 326 
 327         if (!secrets_init()) {
 328                 DEBUG(1,("ads_secrets_verify_ticket: secrets_init failed\n"));
 329                 *perr = KRB5_CONFIG_CANTOPEN;
 330                 return False;
 331         }
 332 
 333         password_s = secrets_fetch_machine_password(lp_workgroup(), NULL, NULL);
 334         if (!password_s) {
 335                 DEBUG(1,("ads_secrets_verify_ticket: failed to fetch machine password\n"));
 336                 *perr = KRB5_LIBOS_CANTREADPWD;
 337                 return False;
 338         }
 339 
 340         password.data = password_s;
 341         password.length = strlen(password_s);
 342 
 343         /* CIFS doesn't use addresses in tickets. This would break NAT. JRA */
 344 
 345         packet.length = ticket->length;
 346         packet.data = (char *)ticket->data;
 347 
 348         /* We need to setup a auth context with each possible encoding type in turn. */
 349         for (i=0;enctypes[i];i++) {
 350                 krb5_keyblock *key = NULL;
 351 
 352                 if (!(key = SMB_MALLOC_P(krb5_keyblock))) {
 353                         ret = ENOMEM;
 354                         goto out;
 355                 }
 356         
 357                 if (create_kerberos_key_from_string(context, host_princ, &password, key, enctypes[i], false)) {
 358                         SAFE_FREE(key);
 359                         continue;
 360                 }
 361 
 362                 krb5_auth_con_setuseruserkey(context, auth_context, key);
 363 
 364                 if (!(ret = krb5_rd_req(context, &auth_context, &packet, 
 365                                         NULL,
 366                                         NULL, NULL, pp_tkt))) {
 367                         DEBUG(10,("ads_secrets_verify_ticket: enc type [%u] decrypted message !\n",
 368                                 (unsigned int)enctypes[i] ));
 369                         auth_ok = True;
 370                         krb5_copy_keyblock(context, key, keyblock);
 371                         krb5_free_keyblock(context, key);
 372                         break;
 373                 }
 374 
 375                 DEBUG((ret != KRB5_BAD_ENCTYPE) ? 3 : 10,
 376                                 ("ads_secrets_verify_ticket: enc type [%u] failed to decrypt with error %s\n",
 377                                 (unsigned int)enctypes[i], error_message(ret)));
 378 
 379                 /* successfully decrypted but ticket is just not valid at the moment */
 380                 if (ret == KRB5KRB_AP_ERR_TKT_NYV || 
 381                     ret == KRB5KRB_AP_ERR_TKT_EXPIRED ||
 382                     ret == KRB5KRB_AP_ERR_SKEW) {
 383                         krb5_free_keyblock(context, key);
 384                         break;
 385                 }
 386 
 387                 krb5_free_keyblock(context, key);
 388 
 389         }
 390 
 391  out:
 392         SAFE_FREE(password_s);
 393         *perr = ret;
 394         return auth_ok;
 395 }
 396 
 397 /**********************************************************************************
 398  Verify an incoming ticket and parse out the principal name and 
 399  authorization_data if available.
 400 ***********************************************************************************/
 401 
 402 NTSTATUS ads_verify_ticket(TALLOC_CTX *mem_ctx,
     /* [<][>][^][v][top][bottom][index][help] */
 403                            const char *realm,
 404                            time_t time_offset,
 405                            const DATA_BLOB *ticket,
 406                            char **principal,
 407                            struct PAC_DATA **pac_data,
 408                            DATA_BLOB *ap_rep,
 409                            DATA_BLOB *session_key,
 410                            bool use_replay_cache)
 411 {
 412         NTSTATUS sret = NT_STATUS_LOGON_FAILURE;
 413         NTSTATUS pac_ret;
 414         DATA_BLOB auth_data;
 415         krb5_context context = NULL;
 416         krb5_auth_context auth_context = NULL;
 417         krb5_data packet;
 418         krb5_ticket *tkt = NULL;
 419         krb5_rcache rcache = NULL;
 420         krb5_keyblock *keyblock = NULL;
 421         time_t authtime;
 422         krb5_error_code ret = 0;
 423         int flags = 0;  
 424         krb5_principal host_princ = NULL;
 425         krb5_const_principal client_principal = NULL;
 426         char *host_princ_s = NULL;
 427         bool auth_ok = False;
 428         bool got_auth_data = False;
 429         struct named_mutex *mutex = NULL;
 430 
 431         ZERO_STRUCT(packet);
 432         ZERO_STRUCT(auth_data);
 433 
 434         *principal = NULL;
 435         *pac_data = NULL;
 436         *ap_rep = data_blob_null;
 437         *session_key = data_blob_null;
 438 
 439         initialize_krb5_error_table();
 440         ret = krb5_init_context(&context);
 441         if (ret) {
 442                 DEBUG(1,("ads_verify_ticket: krb5_init_context failed (%s)\n", error_message(ret)));
 443                 return NT_STATUS_LOGON_FAILURE;
 444         }
 445 
 446         if (time_offset != 0) {
 447                 krb5_set_real_time(context, time(NULL) + time_offset, 0);
 448         }
 449 
 450         ret = krb5_set_default_realm(context, realm);
 451         if (ret) {
 452                 DEBUG(1,("ads_verify_ticket: krb5_set_default_realm failed (%s)\n", error_message(ret)));
 453                 goto out;
 454         }
 455 
 456         /* This whole process is far more complex than I would
 457            like. We have to go through all this to allow us to store
 458            the secret internally, instead of using /etc/krb5.keytab */
 459 
 460         ret = krb5_auth_con_init(context, &auth_context);
 461         if (ret) {
 462                 DEBUG(1,("ads_verify_ticket: krb5_auth_con_init failed (%s)\n", error_message(ret)));
 463                 goto out;
 464         }
 465 
 466         krb5_auth_con_getflags( context, auth_context, &flags );
 467         if ( !use_replay_cache ) {
 468                 /* Disable default use of a replay cache */
 469                 flags &= ~KRB5_AUTH_CONTEXT_DO_TIME;
 470                 krb5_auth_con_setflags( context, auth_context, flags );
 471         }
 472 
 473         if (asprintf(&host_princ_s, "%s$", global_myname()) == -1) {
 474                 goto out;
 475         }
 476 
 477         strlower_m(host_princ_s);
 478         ret = smb_krb5_parse_name(context, host_princ_s, &host_princ);
 479         if (ret) {
 480                 DEBUG(1,("ads_verify_ticket: smb_krb5_parse_name(%s) failed (%s)\n",
 481                                         host_princ_s, error_message(ret)));
 482                 goto out;
 483         }
 484 
 485 
 486         if ( use_replay_cache ) {
 487                 
 488                 /* Lock a mutex surrounding the replay as there is no 
 489                    locking in the MIT krb5 code surrounding the replay 
 490                    cache... */
 491 
 492                 mutex = grab_named_mutex(talloc_tos(), "replay cache mutex",
 493                                          10);
 494                 if (mutex == NULL) {
 495                         DEBUG(1,("ads_verify_ticket: unable to protect "
 496                                  "replay cache with mutex.\n"));
 497                         ret = KRB5_CC_IO;
 498                         goto out;
 499                 }
 500 
 501                 /* JRA. We must set the rcache here. This will prevent 
 502                    replay attacks. */
 503                 
 504                 ret = krb5_get_server_rcache(context, 
 505                                              krb5_princ_component(context, host_princ, 0), 
 506                                              &rcache);
 507                 if (ret) {
 508                         DEBUG(1,("ads_verify_ticket: krb5_get_server_rcache "
 509                                  "failed (%s)\n", error_message(ret)));
 510                         goto out;
 511                 }
 512 
 513                 ret = krb5_auth_con_setrcache(context, auth_context, rcache);
 514                 if (ret) {
 515                         DEBUG(1,("ads_verify_ticket: krb5_auth_con_setrcache "
 516                                  "failed (%s)\n", error_message(ret)));
 517                         goto out;
 518                 }
 519         }
 520 
 521         switch (lp_kerberos_method()) {
 522         default:
 523         case KERBEROS_VERIFY_SECRETS:
 524                 auth_ok = ads_secrets_verify_ticket(context, auth_context,
 525                     host_princ, ticket, &tkt, &keyblock, &ret);
 526                 break;
 527         case KERBEROS_VERIFY_SYSTEM_KEYTAB:
 528                 auth_ok = ads_keytab_verify_ticket(context, auth_context,
 529                     ticket, &tkt, &keyblock, &ret);
 530                 break;
 531         case KERBEROS_VERIFY_DEDICATED_KEYTAB:
 532                 auth_ok = ads_dedicated_keytab_verify_ticket(context,
 533                     auth_context, ticket, &tkt, &keyblock, &ret);
 534                 break;
 535         case KERBEROS_VERIFY_SECRETS_AND_KEYTAB:
 536                 /* First try secrets.tdb and fallback to the krb5.keytab if
 537                    necessary.  This is the pre 3.4 behavior when
 538                    "use kerberos keytab" was true.*/
 539                 auth_ok = ads_secrets_verify_ticket(context, auth_context,
 540                     host_princ, ticket, &tkt, &keyblock, &ret);
 541 
 542                 if (!auth_ok) {
 543                         /* Only fallback if we failed to decrypt the ticket */
 544                         if (ret != KRB5KRB_AP_ERR_TKT_NYV &&
 545                             ret != KRB5KRB_AP_ERR_TKT_EXPIRED &&
 546                             ret != KRB5KRB_AP_ERR_SKEW) {
 547                                 auth_ok = ads_keytab_verify_ticket(context,
 548                                     auth_context, ticket, &tkt, &keyblock,
 549                                     &ret);
 550                         }
 551                 }
 552                 break;
 553         }
 554 
 555         if ( use_replay_cache ) {               
 556                 TALLOC_FREE(mutex);
 557 #if 0
 558                 /* Heimdal leaks here, if we fix the leak, MIT crashes */
 559                 if (rcache) {
 560                         krb5_rc_close(context, rcache);
 561                 }
 562 #endif
 563         }       
 564 
 565         if (!auth_ok) {
 566                 DEBUG(3,("ads_verify_ticket: krb5_rd_req with auth failed (%s)\n", 
 567                          error_message(ret)));
 568                 /* Try map the error return in case it's something like
 569                  * a clock skew error.
 570                  */
 571                 sret = krb5_to_nt_status(ret);
 572                 if (NT_STATUS_IS_OK(sret) || NT_STATUS_EQUAL(sret,NT_STATUS_UNSUCCESSFUL)) {
 573                         sret = NT_STATUS_LOGON_FAILURE;
 574                 }
 575                 DEBUG(10,("ads_verify_ticket: returning error %s\n",
 576                         nt_errstr(sret) ));
 577                 goto out;
 578         } 
 579         
 580         authtime = get_authtime_from_tkt(tkt);
 581         client_principal = get_principal_from_tkt(tkt);
 582 
 583         ret = krb5_mk_rep(context, auth_context, &packet);
 584         if (ret) {
 585                 DEBUG(3,("ads_verify_ticket: Failed to generate mutual authentication reply (%s)\n",
 586                         error_message(ret)));
 587                 goto out;
 588         }
 589 
 590         *ap_rep = data_blob(packet.data, packet.length);
 591         if (packet.data) {
 592                 kerberos_free_data_contents(context, &packet);
 593                 ZERO_STRUCT(packet);
 594         }
 595 
 596         get_krb5_smb_session_key(context, auth_context, session_key, True);
 597         dump_data_pw("SMB session key (from ticket)\n", session_key->data, session_key->length);
 598 
 599 #if 0
 600         file_save("/tmp/ticket.dat", ticket->data, ticket->length);
 601 #endif
 602 
 603         /* continue when no PAC is retrieved or we couldn't decode the PAC 
 604            (like accounts that have the UF_NO_AUTH_DATA_REQUIRED flag set, or
 605            Kerberos tickets encrypted using a DES key) - Guenther */
 606 
 607         got_auth_data = get_auth_data_from_tkt(mem_ctx, &auth_data, tkt);
 608         if (!got_auth_data) {
 609                 DEBUG(3,("ads_verify_ticket: did not retrieve auth data. continuing without PAC\n"));
 610         }
 611 
 612         if (got_auth_data) {
 613                 pac_ret = decode_pac_data(mem_ctx, &auth_data, context, keyblock, client_principal, authtime, pac_data);
 614                 if (!NT_STATUS_IS_OK(pac_ret)) {
 615                         DEBUG(3,("ads_verify_ticket: failed to decode PAC_DATA: %s\n", nt_errstr(pac_ret)));
 616                         *pac_data = NULL;
 617                 }
 618                 data_blob_free(&auth_data);
 619         }
 620 
 621 #if 0
 622 #if defined(HAVE_KRB5_TKT_ENC_PART2)
 623         /* MIT */
 624         if (tkt->enc_part2) {
 625                 file_save("/tmp/authdata.dat",
 626                           tkt->enc_part2->authorization_data[0]->contents,
 627                           tkt->enc_part2->authorization_data[0]->length);
 628         }
 629 #else
 630         /* Heimdal */
 631         if (tkt->ticket.authorization_data) {
 632                 file_save("/tmp/authdata.dat",
 633                           tkt->ticket.authorization_data->val->ad_data.data,
 634                           tkt->ticket.authorization_data->val->ad_data.length);
 635         }
 636 #endif
 637 #endif
 638 
 639         if ((ret = smb_krb5_unparse_name(mem_ctx, context, client_principal, principal))) {
 640                 DEBUG(3,("ads_verify_ticket: smb_krb5_unparse_name failed (%s)\n", 
 641                          error_message(ret)));
 642                 sret = NT_STATUS_LOGON_FAILURE;
 643                 goto out;
 644         }
 645 
 646         sret = NT_STATUS_OK;
 647 
 648  out:
 649 
 650         TALLOC_FREE(mutex);
 651 
 652         if (!NT_STATUS_IS_OK(sret)) {
 653                 data_blob_free(&auth_data);
 654         }
 655 
 656         if (!NT_STATUS_IS_OK(sret)) {
 657                 data_blob_free(ap_rep);
 658         }
 659 
 660         if (host_princ) {
 661                 krb5_free_principal(context, host_princ);
 662         }
 663 
 664         if (keyblock) {
 665                 krb5_free_keyblock(context, keyblock);
 666         }
 667 
 668         if (tkt != NULL) {
 669                 krb5_free_ticket(context, tkt);
 670         }
 671 
 672         SAFE_FREE(host_princ_s);
 673 
 674         if (auth_context) {
 675                 krb5_auth_con_free(context, auth_context);
 676         }
 677 
 678         if (context) {
 679                 krb5_free_context(context);
 680         }
 681 
 682         return sret;
 683 }
 684 
 685 #endif /* HAVE_KRB5 */

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