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) Nalin Dahyabhai <nalin@redhat.com> 2004. 7 Copyright (C) Jeremy Allison 2004. 8 9 This program is free software; you can redistribute it and/or modify 10 it under the terms of the GNU General Public License as published by 11 the Free Software Foundation; either version 2 of the License, or 12 (at your option) any later version. 13 14 This program is distributed in the hope that it will be useful, 15 but WITHOUT ANY WARRANTY; without even the implied warranty of 16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 GNU General Public License for more details. 18 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. 22*/ 23 24#include "includes.h" 25 26#ifdef HAVE_KRB5 27 28#define LIBADS_CCACHE_NAME "MEMORY:libads" 29 30/* 31 we use a prompter to avoid a crash bug in the kerberos libs when 32 dealing with empty passwords 33 this prompter is just a string copy ... 34*/ 35static krb5_error_code 36kerb_prompter(krb5_context ctx, void *data, 37 const char *name, 38 const char *banner, 39 int num_prompts, 40 krb5_prompt prompts[]) 41{ 42 if (num_prompts == 0) return 0; 43 44 memset(prompts[0].reply->data, '\0', prompts[0].reply->length); 45 if (prompts[0].reply->length > 0) { 46 if (data) { 47 strncpy(prompts[0].reply->data, data, prompts[0].reply->length-1); 48 prompts[0].reply->length = strlen(prompts[0].reply->data); 49 } else { 50 prompts[0].reply->length = 0; 51 } 52 } 53 return 0; 54} 55 56/* 57 simulate a kinit, putting the tgt in the given cache location. If cache_name == NULL 58 place in default cache location. 59 remus@snapserver.com 60*/ 61int kerberos_kinit_password(const char *principal, 62 const char *password, 63 int time_offset, 64 time_t *expire_time, 65 const char *cache_name) 66{ 67 krb5_context ctx = NULL; 68 krb5_error_code code = 0; 69 krb5_ccache cc = NULL; 70 krb5_principal me; 71 krb5_creds my_creds; 72 73 if ((code = krb5_init_context(&ctx))) 74 return code; 75 76 if (time_offset != 0) { 77 krb5_set_real_time(ctx, time(NULL) + time_offset, 0); 78 } 79 80 if ((code = krb5_cc_resolve(ctx, cache_name ? 81 cache_name : krb5_cc_default_name(ctx), &cc))) { 82 krb5_free_context(ctx); 83 return code; 84 } 85 86 if ((code = krb5_parse_name(ctx, principal, &me))) { 87 krb5_free_context(ctx); 88 return code; 89 } 90 91 if ((code = krb5_get_init_creds_password(ctx, &my_creds, me, password, 92 kerb_prompter, 93 NULL, 0, NULL, NULL))) { 94 krb5_free_principal(ctx, me); 95 krb5_free_context(ctx); 96 return code; 97 } 98 99 if ((code = krb5_cc_initialize(ctx, cc, me))) { 100 krb5_free_cred_contents(ctx, &my_creds); 101 krb5_free_principal(ctx, me); 102 krb5_free_context(ctx); 103 return code; 104 } 105 106 if ((code = krb5_cc_store_cred(ctx, cc, &my_creds))) { 107 krb5_cc_close(ctx, cc); 108 krb5_free_cred_contents(ctx, &my_creds); 109 krb5_free_principal(ctx, me); 110 krb5_free_context(ctx); 111 return code; 112 } 113 114 if (expire_time) 115 *expire_time = (time_t) my_creds.times.endtime; 116 117 krb5_cc_close(ctx, cc); 118 krb5_free_cred_contents(ctx, &my_creds); 119 krb5_free_principal(ctx, me); 120 krb5_free_context(ctx); 121 122 return 0; 123} 124 125 126 127/* run kinit to setup our ccache */ 128int ads_kinit_password(ADS_STRUCT *ads) 129{ 130 char *s; 131 int ret; 132 133 if (asprintf(&s, "%s@%s", ads->auth.user_name, ads->auth.realm) == -1) { 134 return KRB5_CC_NOMEM; 135 } 136 137 if (!ads->auth.password) { 138 return KRB5_LIBOS_CANTREADPWD; 139 } 140 141 ret = kerberos_kinit_password(s, ads->auth.password, ads->auth.time_offset, 142 &ads->auth.expire, NULL); 143 144 if (ret) { 145 DEBUG(0,("kerberos_kinit_password %s failed: %s\n", 146 s, error_message(ret))); 147 } 148 free(s); 149 return ret; 150} 151 152int ads_kdestroy(const char *cc_name) 153{ 154 krb5_error_code code; 155 krb5_context ctx = NULL; 156 krb5_ccache cc = NULL; 157 158 if ((code = krb5_init_context (&ctx))) { 159 DEBUG(3, ("ads_kdestroy: kdb5_init_context failed: %s\n", 160 error_message(code))); 161 return code; 162 } 163 164 if (!cc_name) { 165 if ((code = krb5_cc_default(ctx, &cc))) { 166 krb5_free_context(ctx); 167 return code; 168 } 169 } else { 170 if ((code = krb5_cc_resolve(ctx, cc_name, &cc))) { 171 DEBUG(3, ("ads_kdestroy: krb5_cc_resolve failed: %s\n", 172 error_message(code))); 173 krb5_free_context(ctx); 174 return code; 175 } 176 } 177 178 if ((code = krb5_cc_destroy (ctx, cc))) { 179 DEBUG(3, ("ads_kdestroy: krb5_cc_destroy failed: %s\n", 180 error_message(code))); 181 } 182 183 krb5_free_context (ctx); 184 return code; 185} 186 187/************************************************************************ 188 Routine to fetch the salting principal for a service. Active 189 Directory may use a non-obvious principal name to generate the salt 190 when it determines the key to use for encrypting tickets for a service, 191 and hopefully we detected that when we joined the domain. 192 ************************************************************************/ 193 194static char *kerberos_secrets_fetch_salting_principal(const char *service, int enctype) 195{ 196 char *key = NULL; 197 char *ret = NULL; 198 199 asprintf(&key, "%s/%s/enctype=%d", SECRETS_SALTING_PRINCIPAL, service, enctype); 200 if (!key) { 201 return NULL; 202 } 203 ret = (char *)secrets_fetch(key, NULL); 204 SAFE_FREE(key); 205 return ret; 206} 207 208/************************************************************************ 209 Routine to get the salting principal for this service. Active 210 Directory may use a non-obvious principal name to generate the salt 211 when it determines the key to use for encrypting tickets for a service, 212 and hopefully we detected that when we joined the domain. 213 Caller must free if return is not null. 214 ************************************************************************/ 215 216krb5_principal kerberos_fetch_salt_princ_for_host_princ(krb5_context context, 217 krb5_principal host_princ, 218 int enctype) 219{ 220 char *unparsed_name = NULL, *salt_princ_s = NULL; 221 krb5_principal ret_princ = NULL; 222 223 if (krb5_unparse_name(context, host_princ, &unparsed_name) != 0) { 224 return (krb5_principal)NULL; 225 } 226 227 if ((salt_princ_s = kerberos_secrets_fetch_salting_principal(unparsed_name, enctype)) == NULL) { 228 krb5_free_unparsed_name(context, unparsed_name); 229 return (krb5_principal)NULL; 230 } 231 232 if (krb5_parse_name(context, salt_princ_s, &ret_princ) != 0) { 233 krb5_free_unparsed_name(context, unparsed_name); 234 SAFE_FREE(salt_princ_s); 235 return (krb5_principal)NULL; 236 } 237 krb5_free_unparsed_name(context, unparsed_name); 238 SAFE_FREE(salt_princ_s); 239 return ret_princ; 240} 241 242/************************************************************************ 243 Routine to set the salting principal for this service. Active 244 Directory may use a non-obvious principal name to generate the salt 245 when it determines the key to use for encrypting tickets for a service, 246 and hopefully we detected that when we joined the domain. 247 Setting principal to NULL deletes this entry. 248 ************************************************************************/ 249 250 BOOL kerberos_secrets_store_salting_principal(const char *service, 251 int enctype, 252 const char *principal) 253{ 254 char *key = NULL; 255 BOOL ret = False; 256 krb5_context context = NULL; 257 krb5_principal princ = NULL; 258 char *princ_s = NULL; 259 char *unparsed_name = NULL; 260 261 krb5_init_context(&context); 262 if (!context) { 263 return False; 264 } 265 if (strchr_m(service, '@')) { 266 asprintf(&princ_s, "%s", service); 267 } else { 268 asprintf(&princ_s, "%s@%s", service, lp_realm()); 269 } 270 271 if (krb5_parse_name(context, princ_s, &princ) != 0) { 272 goto out; 273 274 } 275 if (krb5_unparse_name(context, princ, &unparsed_name) != 0) { 276 goto out; 277 } 278 279 asprintf(&key, "%s/%s/enctype=%d", SECRETS_SALTING_PRINCIPAL, unparsed_name, enctype); 280 if (!key) { 281 goto out; 282 } 283 284 if ((principal != NULL) && (strlen(principal) > 0)) { 285 ret = secrets_store(key, principal, strlen(principal) + 1); 286 } else { 287 ret = secrets_delete(key); 288 } 289 290 out: 291 292 SAFE_FREE(key); 293 SAFE_FREE(princ_s); 294 295 if (unparsed_name) { 296 krb5_free_unparsed_name(context, unparsed_name); 297 } 298 if (context) { 299 krb5_free_context(context); 300 } 301 302 return ret; 303} 304 305/************************************************************************ 306 Routine to get initial credentials as a service ticket for the local machine. 307 Returns a buffer initialized with krb5_mk_req_extended. 308 ************************************************************************/ 309 310static krb5_error_code get_service_ticket(krb5_context ctx, 311 krb5_ccache ccache, 312 const char *service_principal, 313 int enctype, 314 krb5_data *p_outbuf) 315{ 316 krb5_creds creds, *new_creds = NULL; 317 char *service_s = NULL; 318 char *machine_account = NULL, *password = NULL; 319 krb5_data in_data; 320 krb5_auth_context auth_context = NULL; 321 krb5_error_code err = 0; 322 323 ZERO_STRUCT(creds); 324 325 asprintf(&machine_account, "%s$@%s", global_myname(), lp_realm()); 326 if (machine_account == NULL) { 327 goto out; 328 } 329 password = secrets_fetch_machine_password(lp_workgroup(), NULL, NULL); 330 if (password == NULL) { 331 goto out; 332 } 333 if ((err = kerberos_kinit_password(machine_account, password, 0, NULL, LIBADS_CCACHE_NAME)) != 0) { 334 DEBUG(0,("get_service_ticket: kerberos_kinit_password %s@%s failed: %s\n", 335 machine_account, 336 lp_realm(), 337 error_message(err))); 338 goto out; 339 } 340 341 /* Ok - the above call has gotten a TGT. Now we need to get a service 342 ticket to ourselves. */ 343 344 /* Set up the enctype and client and server principal fields for krb5_get_credentials. */ 345 kerberos_set_creds_enctype(&creds, enctype); 346 347 if ((err = krb5_cc_get_principal(ctx, ccache, &creds.client))) { 348 DEBUG(3, ("get_service_ticket: krb5_cc_get_principal failed: %s\n", 349 error_message(err))); 350 goto out; 351 } 352 353 if (strchr_m(service_principal, '@')) { 354 asprintf(&service_s, "%s", service_principal); 355 } else { 356 asprintf(&service_s, "%s@%s", service_principal, lp_realm()); 357 } 358 359 if ((err = krb5_parse_name(ctx, service_s, &creds.server))) { 360 DEBUG(0,("get_service_ticket: krb5_parse_name %s failed: %s\n", 361 service_s, error_message(err))); 362 goto out; 363 } 364 365 if ((err = krb5_get_credentials(ctx, 0, ccache, &creds, &new_creds))) { 366 DEBUG(5,("get_service_ticket: krb5_get_credentials for %s enctype %d failed: %s\n", 367 service_s, enctype, error_message(err))); 368 goto out; 369 } 370 371 memset(&in_data, '\0', sizeof(in_data)); 372 if ((err = krb5_mk_req_extended(ctx, &auth_context, 0, &in_data, 373 new_creds, p_outbuf)) != 0) { 374 DEBUG(0,("get_service_ticket: krb5_mk_req_extended failed: %s\n", 375 error_message(err))); 376 goto out; 377 } 378 379 out: 380 381 if (auth_context) { 382 krb5_auth_con_free(ctx, auth_context); 383 } 384 if (new_creds) { 385 krb5_free_creds(ctx, new_creds); 386 } 387 if (creds.server) { 388 krb5_free_principal(ctx, creds.server); 389 } 390 if (creds.client) { 391 krb5_free_principal(ctx, creds.client); 392 } 393 394 SAFE_FREE(service_s); 395 SAFE_FREE(password); 396 SAFE_FREE(machine_account); 397 return err; 398} 399 400/************************************************************************ 401 Check if the machine password can be used in conjunction with the salting_principal 402 to generate a key which will successfully decrypt the AP_REQ already 403 gotten as a message to the local machine. 404 ************************************************************************/ 405 406static BOOL verify_service_password(krb5_context ctx, 407 int enctype, 408 const char *salting_principal, 409 krb5_data *in_data) 410{ 411 BOOL ret = False; 412 krb5_principal salting_kprinc = NULL; 413 krb5_ticket *ticket = NULL; 414 krb5_keyblock key; 415 krb5_data passdata; 416 char *salting_s = NULL; 417 char *machine_account = NULL, *password = NULL; 418 krb5_auth_context auth_context = NULL; 419 krb5_error_code err; 420 421 memset(&passdata, '\0', sizeof(passdata)); 422 memset(&key, '\0', sizeof(key)); 423 424 asprintf(&machine_account, "%s$@%s", global_myname(), lp_realm()); 425 if (machine_account == NULL) { 426 goto out; 427 } 428 password = secrets_fetch_machine_password(lp_workgroup(), NULL, NULL); 429 if (password == NULL) { 430 goto out; 431 } 432 433 if (strchr_m(salting_principal, '@')) { 434 asprintf(&salting_s, "%s", salting_principal); 435 } else { 436 asprintf(&salting_s, "%s@%s", salting_principal, lp_realm()); 437 } 438 439 if ((err = krb5_parse_name(ctx, salting_s, &salting_kprinc))) { 440 DEBUG(0,("verify_service_password: krb5_parse_name %s failed: %s\n", 441 salting_s, error_message(err))); 442 goto out; 443 } 444 445 passdata.length = strlen(password); 446 passdata.data = (char*)password; 447 if ((err = create_kerberos_key_from_string_direct(ctx, salting_kprinc, &passdata, &key, enctype))) { 448 DEBUG(0,("verify_service_password: create_kerberos_key_from_string %d failed: %s\n", 449 enctype, error_message(err))); 450 goto out; 451 } 452 453 if ((err = krb5_auth_con_init(ctx, &auth_context)) != 0) { 454 DEBUG(0,("verify_service_password: krb5_auth_con_init failed %s\n", error_message(err))); 455 goto out; 456 } 457 458 if ((err = krb5_auth_con_setuseruserkey(ctx, auth_context, &key)) != 0) { 459 DEBUG(0,("verify_service_password: krb5_auth_con_setuseruserkey failed %s\n", error_message(err))); 460 goto out; 461 } 462 463 if (!(err = krb5_rd_req(ctx, &auth_context, in_data, NULL, NULL, NULL, &ticket))) { 464 DEBUG(10,("verify_service_password: decrypted message with enctype %u salt %s!\n", 465 (unsigned int)enctype, salting_s)); 466 ret = True; 467 } 468 469 out: 470 471 memset(&passdata, 0, sizeof(passdata)); 472 krb5_free_keyblock_contents(ctx, &key); 473 if (ticket != NULL) { 474 krb5_free_ticket(ctx, ticket); 475 } 476 if (salting_kprinc) { 477 krb5_free_principal(ctx, salting_kprinc); 478 } 479 SAFE_FREE(salting_s); 480 SAFE_FREE(password); 481 SAFE_FREE(machine_account); 482 return ret; 483} 484 485/************************************************************************ 486 * 487 * From the current draft of kerberos-clarifications: 488 * 489 * It is not possible to reliably generate a user's key given a pass 490 * phrase without contacting the KDC, since it will not be known 491 * whether alternate salt or parameter values are required. 492 * 493 * And because our server has a password, we have this exact problem. We 494 * make multiple guesses as to which principal name provides the salt which 495 * the KDC is using. 496 * 497 ************************************************************************/ 498 499static void kerberos_derive_salting_principal_for_enctype(const char *service_principal, 500 krb5_context ctx, 501 krb5_ccache ccache, 502 krb5_enctype enctype, 503 krb5_enctype *enctypes) 504{ 505 char *salting_principals[3] = {NULL, NULL, NULL}, *second_principal = NULL; 506 krb5_error_code err = 0; 507 krb5_data outbuf; 508 int i, j; 509 510 memset(&outbuf, '\0', sizeof(outbuf)); 511 512 /* Check that the service_principal is useful. */ 513 if ((service_principal == NULL) || (strlen(service_principal) == 0)) { 514 return; 515 } 516 517 /* Generate our first guess -- the principal as-given. */ 518 asprintf(&salting_principals[0], "%s", service_principal); 519 if ((salting_principals[0] == NULL) || (strlen(salting_principals[0]) == 0)) { 520 return; 521 } 522 523 /* Generate our second guess -- the computer's principal, as Win2k3. */ 524 asprintf(&second_principal, "host/%s.%s", global_myname(), lp_realm()); 525 if (second_principal != NULL) { 526 strlower_m(second_principal); 527 asprintf(&salting_principals[1], "%s@%s", second_principal, lp_realm()); 528 SAFE_FREE(second_principal); 529 } 530 if ((salting_principals[1] == NULL) || (strlen(salting_principals[1]) == 0)) { 531 goto out; 532 } 533 534 /* Generate our third guess -- the computer's principal, as Win2k. */ 535 asprintf(&second_principal, "HOST/%s", global_myname()); 536 if (second_principal != NULL) { 537 strlower_m(second_principal + 5); 538 asprintf(&salting_principals[2], "%s@%s", 539 second_principal, lp_realm()); 540 SAFE_FREE(second_principal); 541 } 542 if ((salting_principals[2] == NULL) || (strlen(salting_principals[2]) == 0)) { 543 goto out; 544 } 545 546 /* Get a service ticket for ourselves into our memory ccache. */ 547 /* This will commonly fail if there is no principal by that name (and we're trying 548 many names). So don't print a debug 0 error. */ 549 550 if ((err = get_service_ticket(ctx, ccache, service_principal, enctype, &outbuf)) != 0) { 551 DEBUG(3, ("verify_service_password: get_service_ticket failed: %s\n", 552 error_message(err))); 553 goto out; 554 } 555 556 /* At this point we have a message to ourselves, salted only the KDC knows how. We 557 have to work out what that salting is. */ 558 559 /* Try and find the correct salting principal. */ 560 for (i = 0; i < sizeof(salting_principals) / sizeof(salting_principals[i]); i++) { 561 if (verify_service_password(ctx, enctype, salting_principals[i], &outbuf)) { 562 break; 563 } 564 } 565 566 /* If we failed to get a match, return. */ 567 if (i >= sizeof(salting_principals) / sizeof(salting_principals[i])) { 568 goto out; 569 } 570 571 /* If we succeeded, store the principal for use for all enctypes which 572 * share the same cipher and string-to-key function. Doing this here 573 * allows servers which just pass a keytab to krb5_rd_req() to work 574 * correctly. */ 575 for (j = 0; enctypes[j] != 0; j++) { 576 if (enctype != enctypes[j]) { 577 /* If this enctype isn't compatible with the one which 578 * we used, skip it. */ 579 580 if (!kerberos_compatible_enctypes(ctx, enctypes[j], enctype)) 581 continue; 582 } 583 /* If the principal which gives us the proper salt is the one 584 * which we would normally guess, don't bother noting anything 585 * in the secrets tdb. */ 586 if (strcmp(service_principal, salting_principals[i]) != 0) { 587 kerberos_secrets_store_salting_principal(service_principal, 588 enctypes[j], 589 salting_principals[i]); 590 } 591 } 592 593 out : 594 595 kerberos_free_data_contents(ctx, &outbuf); 596 SAFE_FREE(salting_principals[0]); 597 SAFE_FREE(salting_principals[1]); 598 SAFE_FREE(salting_principals[2]); 599 SAFE_FREE(second_principal); 600} 601 602/************************************************************************ 603 Go through all the possible enctypes for this principal. 604 ************************************************************************/ 605 606static void kerberos_derive_salting_principal_direct(krb5_context context, 607 krb5_ccache ccache, 608 krb5_enctype *enctypes, 609 char *service_principal) 610{ 611 int i; 612 613 /* Try for each enctype separately, because the rules are 614 * different for different enctypes. */ 615 for (i = 0; enctypes[i] != 0; i++) { 616 /* Delete secrets entry first. */ 617 kerberos_secrets_store_salting_principal(service_principal, 0, NULL); 618#ifdef ENCTYPE_ARCFOUR_HMAC 619 if (enctypes[i] == ENCTYPE_ARCFOUR_HMAC) { 620 /* Of course this'll always work, so just save 621 * ourselves the effort. */ 622 continue; 623 } 624#endif 625 /* Try to figure out what's going on with this 626 * principal. */ 627 kerberos_derive_salting_principal_for_enctype(service_principal, 628 context, 629 ccache, 630 enctypes[i], 631 enctypes); 632 } 633} 634 635/************************************************************************ 636 Wrapper function for the above. 637 ************************************************************************/ 638 639BOOL kerberos_derive_salting_principal(char *service_principal) 640{ 641 krb5_context context = NULL; 642 krb5_enctype *enctypes = NULL; 643 krb5_ccache ccache = NULL; 644 krb5_error_code ret = 0; 645 646 initialize_krb5_error_table(); 647 if ((ret = krb5_init_context(&context)) != 0) { 648 DEBUG(1,("kerberos_derive_cifs_salting_principals: krb5_init_context failed. %s\n", 649 error_message(ret))); 650 return False; 651 } 652 if ((ret = get_kerberos_allowed_etypes(context, &enctypes)) != 0) { 653 DEBUG(1,("kerberos_derive_cifs_salting_principals: get_kerberos_allowed_etypes failed. %s\n", 654 error_message(ret))); 655 goto out; 656 } 657 658 if ((ret = krb5_cc_resolve(context, LIBADS_CCACHE_NAME, &ccache)) != 0) { 659 DEBUG(3, ("get_service_ticket: krb5_cc_resolve for %s failed: %s\n", 660 LIBADS_CCACHE_NAME, error_message(ret))); 661 goto out; 662 } 663 664 kerberos_derive_salting_principal_direct(context, ccache, enctypes, service_principal); 665 666 out: 667 if (enctypes) { 668 free_kerberos_etypes(context, enctypes); 669 } 670 if (ccache) { 671 krb5_cc_destroy(context, ccache); 672 } 673 if (context) { 674 krb5_free_context(context); 675 } 676 677 return ret ? False : True; 678} 679 680/************************************************************************ 681 Core function to try and determine what salt is being used for any keytab 682 keys. 683 ************************************************************************/ 684 685BOOL kerberos_derive_cifs_salting_principals(void) 686{ 687 fstring my_fqdn; 688 char *service = NULL; 689 krb5_context context = NULL; 690 krb5_enctype *enctypes = NULL; 691 krb5_ccache ccache = NULL; 692 krb5_error_code ret = 0; 693 BOOL retval = False; 694 695 initialize_krb5_error_table(); 696 if ((ret = krb5_init_context(&context)) != 0) { 697 DEBUG(1,("kerberos_derive_cifs_salting_principals: krb5_init_context failed. %s\n", 698 error_message(ret))); 699 return False; 700 } 701 if ((ret = get_kerberos_allowed_etypes(context, &enctypes)) != 0) { 702 DEBUG(1,("kerberos_derive_cifs_salting_principals: get_kerberos_allowed_etypes failed. %s\n", 703 error_message(ret))); 704 goto out; 705 } 706 707 if ((ret = krb5_cc_resolve(context, LIBADS_CCACHE_NAME, &ccache)) != 0) { 708 DEBUG(3, ("get_service_ticket: krb5_cc_resolve for %s failed: %s\n", 709 LIBADS_CCACHE_NAME, error_message(ret))); 710 goto out; 711 } 712 713 if (asprintf(&service, "%s$", global_myname()) != -1) { 714 strlower_m(service); 715 kerberos_derive_salting_principal_direct(context, ccache, enctypes, service); 716 SAFE_FREE(service); 717 } 718 if (asprintf(&service, "cifs/%s", global_myname()) != -1) { 719 strlower_m(service); 720 kerberos_derive_salting_principal_direct(context, ccache, enctypes, service); 721 SAFE_FREE(service); 722 } 723 if (asprintf(&service, "host/%s", global_myname()) != -1) { 724 strlower_m(service); 725 kerberos_derive_salting_principal_direct(context, ccache, enctypes, service); 726 SAFE_FREE(service); 727 } 728 if (asprintf(&service, "cifs/%s.%s", global_myname(), lp_realm()) != -1) { 729 strlower_m(service); 730 kerberos_derive_salting_principal_direct(context, ccache, enctypes, service); 731 SAFE_FREE(service); 732 } 733 if (asprintf(&service, "host/%s.%s", global_myname(), lp_realm()) != -1) { 734 strlower_m(service); 735 kerberos_derive_salting_principal_direct(context, ccache, enctypes, service); 736 SAFE_FREE(service); 737 } 738 name_to_fqdn(my_fqdn, global_myname()); 739 if (asprintf(&service, "cifs/%s", my_fqdn) != -1) { 740 strlower_m(service); 741 kerberos_derive_salting_principal_direct(context, ccache, enctypes, service); 742 SAFE_FREE(service); 743 } 744 if (asprintf(&service, "host/%s", my_fqdn) != -1) { 745 strlower_m(service); 746 kerberos_derive_salting_principal_direct(context, ccache, enctypes, service); 747 SAFE_FREE(service); 748 } 749 750 retval = True; 751 752 out: 753 if (enctypes) { 754 free_kerberos_etypes(context, enctypes); 755 } 756 if (ccache) { 757 krb5_cc_destroy(context, ccache); 758 } 759 if (context) { 760 krb5_free_context(context); 761 } 762 return retval; 763} 764#endif 765