17c478bd9Sstevel@tonic-gate /* 27c478bd9Sstevel@tonic-gate * CDDL HEADER START 37c478bd9Sstevel@tonic-gate * 47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5a0709436Smp * Common Development and Distribution License (the "License"). 6a0709436Smp * You may not use this file except in compliance with the License. 77c478bd9Sstevel@tonic-gate * 87c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 97c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 107c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 117c478bd9Sstevel@tonic-gate * and limitations under the License. 127c478bd9Sstevel@tonic-gate * 137c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 147c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 157c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 167c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 177c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 187c478bd9Sstevel@tonic-gate * 197c478bd9Sstevel@tonic-gate * CDDL HEADER END 207c478bd9Sstevel@tonic-gate */ 217c478bd9Sstevel@tonic-gate /* 22a0709436Smp * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 237c478bd9Sstevel@tonic-gate * Use is subject to license terms. 247c478bd9Sstevel@tonic-gate */ 257c478bd9Sstevel@tonic-gate 267c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 277c478bd9Sstevel@tonic-gate 287c478bd9Sstevel@tonic-gate #include <security/pam_appl.h> 297c478bd9Sstevel@tonic-gate #include <security/pam_modules.h> 307c478bd9Sstevel@tonic-gate #include <security/pam_impl.h> 317c478bd9Sstevel@tonic-gate #include <string.h> 327c478bd9Sstevel@tonic-gate #include <stdio.h> 337c478bd9Sstevel@tonic-gate #include <stdlib.h> 347c478bd9Sstevel@tonic-gate #include <sys/types.h> 357c478bd9Sstevel@tonic-gate #include <sys/stat.h> 367c478bd9Sstevel@tonic-gate #include <pwd.h> 377c478bd9Sstevel@tonic-gate #include <syslog.h> 387c478bd9Sstevel@tonic-gate #include <libintl.h> 397c478bd9Sstevel@tonic-gate #include <k5-int.h> 407c478bd9Sstevel@tonic-gate #include "profile/prof_int.h" 417c478bd9Sstevel@tonic-gate #include <netdb.h> 427c478bd9Sstevel@tonic-gate #include <ctype.h> 437c478bd9Sstevel@tonic-gate #include "utils.h" 447c478bd9Sstevel@tonic-gate #include "krb5_repository.h" 457c478bd9Sstevel@tonic-gate 467c478bd9Sstevel@tonic-gate #define KRB5_DEFAULT_OPTIONS 0 477c478bd9Sstevel@tonic-gate 487c478bd9Sstevel@tonic-gate int forwardable_flag = 0; 497c478bd9Sstevel@tonic-gate int renewable_flag = 0; 507c478bd9Sstevel@tonic-gate int proxiable_flag = 0; 517c478bd9Sstevel@tonic-gate int no_address_flag = 0; 527c478bd9Sstevel@tonic-gate profile_options_boolean config_option[] = { 537c478bd9Sstevel@tonic-gate { "forwardable", &forwardable_flag, 0 }, 547c478bd9Sstevel@tonic-gate { "renewable", &renewable_flag, 0 }, 557c478bd9Sstevel@tonic-gate { "proxiable", &proxiable_flag, 0 }, 567c478bd9Sstevel@tonic-gate { "no_addresses", &no_address_flag, 0 }, 577c478bd9Sstevel@tonic-gate { NULL, NULL, 0 } 587c478bd9Sstevel@tonic-gate }; 597c478bd9Sstevel@tonic-gate char *renew_timeval; 607c478bd9Sstevel@tonic-gate char *life_timeval; 617c478bd9Sstevel@tonic-gate profile_option_strings config_times[] = { 627c478bd9Sstevel@tonic-gate { "max_life", &life_timeval, 0 }, 637c478bd9Sstevel@tonic-gate { "max_renewable_life", &renew_timeval, 0 }, 647c478bd9Sstevel@tonic-gate { NULL, NULL, 0 } 657c478bd9Sstevel@tonic-gate }; 667c478bd9Sstevel@tonic-gate char *realmdef[] = { "realms", NULL, NULL, NULL }; 677c478bd9Sstevel@tonic-gate char *appdef[] = { "appdefaults", "kinit", NULL }; 687c478bd9Sstevel@tonic-gate 697c478bd9Sstevel@tonic-gate #define krb_realm (*(realmdef + 1)) 707c478bd9Sstevel@tonic-gate 71*2278144aSsemery int attempt_krb5_auth(krb5_module_data_t *, char *, char **, boolean_t); 727c478bd9Sstevel@tonic-gate void krb5_cleanup(pam_handle_t *, void *, int); 737c478bd9Sstevel@tonic-gate 747c478bd9Sstevel@tonic-gate extern errcode_t profile_get_options_boolean(); 757c478bd9Sstevel@tonic-gate extern errcode_t profile_get_options_string(); 76*2278144aSsemery extern int krb5_verifypw(char *, char *, int); 777c478bd9Sstevel@tonic-gate extern krb5_error_code krb5_verify_init_creds(krb5_context, 787c478bd9Sstevel@tonic-gate krb5_creds *, krb5_principal, krb5_keytab, krb5_ccache *, 797c478bd9Sstevel@tonic-gate krb5_verify_init_creds_opt *); 807c478bd9Sstevel@tonic-gate 817c478bd9Sstevel@tonic-gate /* 827c478bd9Sstevel@tonic-gate * pam_sm_authenticate - Authenticate user 837c478bd9Sstevel@tonic-gate */ 847c478bd9Sstevel@tonic-gate int 857c478bd9Sstevel@tonic-gate pam_sm_authenticate( 867c478bd9Sstevel@tonic-gate pam_handle_t *pamh, 877c478bd9Sstevel@tonic-gate int flags, 887c478bd9Sstevel@tonic-gate int argc, 897c478bd9Sstevel@tonic-gate const char **argv) 907c478bd9Sstevel@tonic-gate { 910be37caaSsemery char *user = NULL; 927c478bd9Sstevel@tonic-gate int err; 937c478bd9Sstevel@tonic-gate int result = PAM_AUTH_ERR; 947c478bd9Sstevel@tonic-gate /* pam.conf options */ 957c478bd9Sstevel@tonic-gate int debug = 0; 967c478bd9Sstevel@tonic-gate int warn = 1; 977c478bd9Sstevel@tonic-gate /* return an error on password expire */ 987c478bd9Sstevel@tonic-gate int err_on_exp = 0; 997c478bd9Sstevel@tonic-gate int i; 1007c478bd9Sstevel@tonic-gate char *password = NULL; 1017c478bd9Sstevel@tonic-gate uid_t pw_uid; 1027c478bd9Sstevel@tonic-gate krb5_module_data_t *kmd = NULL; 1037c478bd9Sstevel@tonic-gate krb5_repository_data_t *krb5_data = NULL; 1047c478bd9Sstevel@tonic-gate pam_repository_t *rep_data = NULL; 1057c478bd9Sstevel@tonic-gate 1067c478bd9Sstevel@tonic-gate for (i = 0; i < argc; i++) { 1077c478bd9Sstevel@tonic-gate if (strcmp(argv[i], "debug") == 0) { 1087c478bd9Sstevel@tonic-gate debug = 1; 1097c478bd9Sstevel@tonic-gate } else if (strcmp(argv[i], "nowarn") == 0) { 1107c478bd9Sstevel@tonic-gate warn = 0; 1117c478bd9Sstevel@tonic-gate } else if (strcmp(argv[i], "err_on_exp") == 0) { 1127c478bd9Sstevel@tonic-gate err_on_exp = 1; 1137c478bd9Sstevel@tonic-gate } else { 1147c478bd9Sstevel@tonic-gate syslog(LOG_ERR, dgettext(TEXT_DOMAIN, 1157c478bd9Sstevel@tonic-gate "PAM-KRB5 (auth) unrecognized option %s"), 1167c478bd9Sstevel@tonic-gate argv[i]); 1177c478bd9Sstevel@tonic-gate } 1187c478bd9Sstevel@tonic-gate } 1197c478bd9Sstevel@tonic-gate if (flags & PAM_SILENT) warn = 0; 1207c478bd9Sstevel@tonic-gate 1217c478bd9Sstevel@tonic-gate if (debug) 1227c478bd9Sstevel@tonic-gate syslog(LOG_DEBUG, 1237c478bd9Sstevel@tonic-gate "PAM-KRB5 (auth): pam_sm_authenticate flags=%d", 1247c478bd9Sstevel@tonic-gate flags); 1257c478bd9Sstevel@tonic-gate 1260be37caaSsemery (void) pam_get_item(pamh, PAM_USER, (void**) &user); 1277c478bd9Sstevel@tonic-gate 128a0e56b0eSsemery if (user == NULL || *user == '\0') { 1297c478bd9Sstevel@tonic-gate if (debug) 1307c478bd9Sstevel@tonic-gate syslog(LOG_DEBUG, "PAM-KRB5 (auth): user empty " 1317c478bd9Sstevel@tonic-gate "or null"); 132a0e56b0eSsemery return (PAM_USER_UNKNOWN); 1337c478bd9Sstevel@tonic-gate } 1347c478bd9Sstevel@tonic-gate 1357c478bd9Sstevel@tonic-gate /* make sure a password entry exists for this user */ 1360be37caaSsemery if (!get_pw_uid(user, &pw_uid)) 1370be37caaSsemery return (PAM_USER_UNKNOWN); 1387c478bd9Sstevel@tonic-gate 1397c478bd9Sstevel@tonic-gate /* 1407c478bd9Sstevel@tonic-gate * pam_get_data could fail if we are being called for the first time 1417c478bd9Sstevel@tonic-gate * or if the module is not found, PAM_NO_MODULE_DATA is not an error 1427c478bd9Sstevel@tonic-gate */ 1437c478bd9Sstevel@tonic-gate err = pam_get_data(pamh, KRB5_DATA, (const void**)&kmd); 1447c478bd9Sstevel@tonic-gate if (!(err == PAM_SUCCESS || err == PAM_NO_MODULE_DATA)) 1457c478bd9Sstevel@tonic-gate return (PAM_AUTH_ERR); 1467c478bd9Sstevel@tonic-gate 1477c478bd9Sstevel@tonic-gate if (kmd == NULL) { 1487c478bd9Sstevel@tonic-gate kmd = calloc(1, sizeof (krb5_module_data_t)); 1497c478bd9Sstevel@tonic-gate if (kmd == NULL) { 1507c478bd9Sstevel@tonic-gate result = PAM_BUF_ERR; 1517c478bd9Sstevel@tonic-gate goto out; 1527c478bd9Sstevel@tonic-gate } 1537c478bd9Sstevel@tonic-gate 1547c478bd9Sstevel@tonic-gate err = pam_set_data(pamh, KRB5_DATA, kmd, &krb5_cleanup); 1557c478bd9Sstevel@tonic-gate if (err != PAM_SUCCESS) { 1567c478bd9Sstevel@tonic-gate free(kmd); 1577c478bd9Sstevel@tonic-gate result = err; 1587c478bd9Sstevel@tonic-gate goto out; 1597c478bd9Sstevel@tonic-gate } 1607c478bd9Sstevel@tonic-gate } 1617c478bd9Sstevel@tonic-gate 1627c478bd9Sstevel@tonic-gate if (!kmd->env) { 1637c478bd9Sstevel@tonic-gate char buffer[512]; 1647c478bd9Sstevel@tonic-gate 1657c478bd9Sstevel@tonic-gate if (snprintf(buffer, sizeof (buffer), 1667c478bd9Sstevel@tonic-gate "%s=FILE:/tmp/krb5cc_%d", 1677c478bd9Sstevel@tonic-gate KRB5_ENV_CCNAME, (int)pw_uid) >= sizeof (buffer)) { 1687c478bd9Sstevel@tonic-gate result = PAM_SYSTEM_ERR; 1697c478bd9Sstevel@tonic-gate goto out; 1707c478bd9Sstevel@tonic-gate } 1717c478bd9Sstevel@tonic-gate 1727c478bd9Sstevel@tonic-gate /* we MUST copy this to the heap for the putenv to work! */ 1737c478bd9Sstevel@tonic-gate kmd->env = strdup(buffer); 1747c478bd9Sstevel@tonic-gate if (!kmd->env) { 1757c478bd9Sstevel@tonic-gate result = PAM_BUF_ERR; 1767c478bd9Sstevel@tonic-gate goto out; 1777c478bd9Sstevel@tonic-gate } else { 1787c478bd9Sstevel@tonic-gate if (putenv(kmd->env)) { 1797c478bd9Sstevel@tonic-gate result = PAM_SYSTEM_ERR; 1807c478bd9Sstevel@tonic-gate goto out; 1817c478bd9Sstevel@tonic-gate } 1827c478bd9Sstevel@tonic-gate } 1837c478bd9Sstevel@tonic-gate } 1847c478bd9Sstevel@tonic-gate 1857c478bd9Sstevel@tonic-gate kmd->auth_status = PAM_AUTH_ERR; 1867c478bd9Sstevel@tonic-gate kmd->debug = debug; 1877c478bd9Sstevel@tonic-gate kmd->warn = warn; 1887c478bd9Sstevel@tonic-gate kmd->err_on_exp = err_on_exp; 1897c478bd9Sstevel@tonic-gate kmd->ccache = NULL; 1907c478bd9Sstevel@tonic-gate kmd->kcontext = NULL; 1917c478bd9Sstevel@tonic-gate kmd->password = NULL; 1927c478bd9Sstevel@tonic-gate kmd->age_status = PAM_SUCCESS; 1937c478bd9Sstevel@tonic-gate (void) memset((char *)&kmd->initcreds, 0, sizeof (krb5_creds)); 1947c478bd9Sstevel@tonic-gate 1957c478bd9Sstevel@tonic-gate /* 1967c478bd9Sstevel@tonic-gate * For apps that already did krb5 auth exchange... 1977c478bd9Sstevel@tonic-gate * Now that we've created the kmd structure, we can 1987c478bd9Sstevel@tonic-gate * return SUCCESS. 'kmd' may be needed later by other 1997c478bd9Sstevel@tonic-gate * PAM functions, thats why we wait until this point to 2007c478bd9Sstevel@tonic-gate * return. 2017c478bd9Sstevel@tonic-gate */ 2020be37caaSsemery (void) pam_get_item(pamh, PAM_REPOSITORY, (void **)&rep_data); 2037c478bd9Sstevel@tonic-gate 2047c478bd9Sstevel@tonic-gate if (rep_data != NULL) { 2057c478bd9Sstevel@tonic-gate if (strcmp(rep_data->type, KRB5_REPOSITORY_NAME) != 0) { 2067c478bd9Sstevel@tonic-gate if (debug) 2077c478bd9Sstevel@tonic-gate syslog(LOG_DEBUG, "PAM-KRB5 (auth): wrong" 2087c478bd9Sstevel@tonic-gate "repository found (%s), returning " 2097c478bd9Sstevel@tonic-gate "PAM_IGNORE", rep_data->type); 2107c478bd9Sstevel@tonic-gate return (PAM_IGNORE); 2117c478bd9Sstevel@tonic-gate } 2127c478bd9Sstevel@tonic-gate if (rep_data->scope_len == sizeof (krb5_repository_data_t)) { 2137c478bd9Sstevel@tonic-gate krb5_data = (krb5_repository_data_t *)rep_data->scope; 2147c478bd9Sstevel@tonic-gate 2157c478bd9Sstevel@tonic-gate if (krb5_data->flags == 2167c478bd9Sstevel@tonic-gate SUNW_PAM_KRB5_ALREADY_AUTHENTICATED && 2177c478bd9Sstevel@tonic-gate krb5_data->principal != NULL && 2187c478bd9Sstevel@tonic-gate strlen(krb5_data->principal)) { 2197c478bd9Sstevel@tonic-gate if (debug) 2207c478bd9Sstevel@tonic-gate syslog(LOG_DEBUG, 2217c478bd9Sstevel@tonic-gate "PAM-KRB5 (auth): Principal " 2227c478bd9Sstevel@tonic-gate "%s already authenticated", 2237c478bd9Sstevel@tonic-gate krb5_data->principal); 2247c478bd9Sstevel@tonic-gate kmd->auth_status = PAM_SUCCESS; 2257c478bd9Sstevel@tonic-gate return (PAM_SUCCESS); 2267c478bd9Sstevel@tonic-gate } 2277c478bd9Sstevel@tonic-gate } 2287c478bd9Sstevel@tonic-gate } 2297c478bd9Sstevel@tonic-gate 2307c478bd9Sstevel@tonic-gate /* 2317c478bd9Sstevel@tonic-gate * if root key exists in the keytab, it's a random key so no 2327c478bd9Sstevel@tonic-gate * need to prompt for pw and we just return IGNORE. 2337c478bd9Sstevel@tonic-gate * 2347c478bd9Sstevel@tonic-gate * note we don't need to force a prompt for pw as authtok_get 2357c478bd9Sstevel@tonic-gate * is required to be stacked above this module. 2367c478bd9Sstevel@tonic-gate */ 2377c478bd9Sstevel@tonic-gate if ((strcmp(user, ROOT_UNAME) == 0) && 2387c478bd9Sstevel@tonic-gate key_in_keytab(user, debug)) { 2397c478bd9Sstevel@tonic-gate if (debug) 2407c478bd9Sstevel@tonic-gate syslog(LOG_DEBUG, 2417c478bd9Sstevel@tonic-gate "PAM-KRB5 (auth): " 2427c478bd9Sstevel@tonic-gate "key for '%s' in keytab, returning IGNORE", user); 2437c478bd9Sstevel@tonic-gate result = PAM_IGNORE; 2447c478bd9Sstevel@tonic-gate goto out; 2457c478bd9Sstevel@tonic-gate } 2467c478bd9Sstevel@tonic-gate 2470be37caaSsemery (void) pam_get_item(pamh, PAM_AUTHTOK, (void **)&password); 2487c478bd9Sstevel@tonic-gate 249*2278144aSsemery result = attempt_krb5_auth(kmd, user, &password, 1); 2507c478bd9Sstevel@tonic-gate 2517c478bd9Sstevel@tonic-gate out: 2527c478bd9Sstevel@tonic-gate if (kmd) { 2537c478bd9Sstevel@tonic-gate if (debug) 2547c478bd9Sstevel@tonic-gate syslog(LOG_DEBUG, 2557c478bd9Sstevel@tonic-gate "PAM-KRB5 (auth): pam_sm_auth finalize" 2567c478bd9Sstevel@tonic-gate " ccname env, result =%d, env ='%s'," 2577c478bd9Sstevel@tonic-gate " age = %d, status = %d", 2587c478bd9Sstevel@tonic-gate result, kmd->env ? kmd->env : "<null>", 2597c478bd9Sstevel@tonic-gate kmd->age_status, kmd->auth_status); 2607c478bd9Sstevel@tonic-gate 2617c478bd9Sstevel@tonic-gate if (kmd->env && 2627c478bd9Sstevel@tonic-gate !(kmd->age_status == PAM_NEW_AUTHTOK_REQD && 2637c478bd9Sstevel@tonic-gate kmd->auth_status == PAM_SUCCESS)) { 2647c478bd9Sstevel@tonic-gate 2657c478bd9Sstevel@tonic-gate 2667c478bd9Sstevel@tonic-gate if (result == PAM_SUCCESS) { 2677c478bd9Sstevel@tonic-gate /* 2687c478bd9Sstevel@tonic-gate * Put ccname into the pamh so that login 2697c478bd9Sstevel@tonic-gate * apps can pick this up when they run 2707c478bd9Sstevel@tonic-gate * pam_getenvlist(). 2717c478bd9Sstevel@tonic-gate */ 2727c478bd9Sstevel@tonic-gate if ((result = pam_putenv(pamh, kmd->env)) 2737c478bd9Sstevel@tonic-gate != PAM_SUCCESS) { 2747c478bd9Sstevel@tonic-gate /* should not happen but... */ 2757c478bd9Sstevel@tonic-gate syslog(LOG_ERR, 2767c478bd9Sstevel@tonic-gate dgettext(TEXT_DOMAIN, 2777c478bd9Sstevel@tonic-gate "PAM-KRB5 (auth):" 2787c478bd9Sstevel@tonic-gate " pam_putenv failed: result: %d"), 2797c478bd9Sstevel@tonic-gate result); 2807c478bd9Sstevel@tonic-gate goto cleanupccname; 2817c478bd9Sstevel@tonic-gate } 2827c478bd9Sstevel@tonic-gate } else { 2837c478bd9Sstevel@tonic-gate cleanupccname: 2847c478bd9Sstevel@tonic-gate /* for lack of a Solaris unputenv() */ 2857c478bd9Sstevel@tonic-gate krb5_unsetenv(KRB5_ENV_CCNAME); 2867c478bd9Sstevel@tonic-gate free(kmd->env); 2877c478bd9Sstevel@tonic-gate kmd->env = NULL; 2887c478bd9Sstevel@tonic-gate } 2897c478bd9Sstevel@tonic-gate } 2907c478bd9Sstevel@tonic-gate kmd->auth_status = result; 2917c478bd9Sstevel@tonic-gate } 2927c478bd9Sstevel@tonic-gate 2937c478bd9Sstevel@tonic-gate if (debug) 2947c478bd9Sstevel@tonic-gate syslog(LOG_DEBUG, 2957c478bd9Sstevel@tonic-gate "PAM-KRB5 (auth): end: %s", pam_strerror(pamh, result)); 2967c478bd9Sstevel@tonic-gate 2977c478bd9Sstevel@tonic-gate return (result); 2987c478bd9Sstevel@tonic-gate } 2997c478bd9Sstevel@tonic-gate 3007c478bd9Sstevel@tonic-gate int 3017c478bd9Sstevel@tonic-gate attempt_krb5_auth( 3027c478bd9Sstevel@tonic-gate krb5_module_data_t *kmd, 3037c478bd9Sstevel@tonic-gate char *user, 3047c478bd9Sstevel@tonic-gate char **krb5_pass, 3050be37caaSsemery boolean_t verify_tik) 3067c478bd9Sstevel@tonic-gate { 3077c478bd9Sstevel@tonic-gate krb5_principal me = NULL; 3087c478bd9Sstevel@tonic-gate krb5_principal server = NULL; 3097c478bd9Sstevel@tonic-gate krb5_creds *my_creds; 3107c478bd9Sstevel@tonic-gate krb5_timestamp now; 3117c478bd9Sstevel@tonic-gate krb5_error_code code = 0; 3127c478bd9Sstevel@tonic-gate char kuser[2*MAXHOSTNAMELEN]; 3137c478bd9Sstevel@tonic-gate krb5_deltat lifetime; 3147c478bd9Sstevel@tonic-gate krb5_deltat rlife; 3157c478bd9Sstevel@tonic-gate krb5_deltat krb5_max_duration; 3167c478bd9Sstevel@tonic-gate int options = KRB5_DEFAULT_OPTIONS; 3177c478bd9Sstevel@tonic-gate krb5_data tgtname = { 3187c478bd9Sstevel@tonic-gate 0, 3197c478bd9Sstevel@tonic-gate KRB5_TGS_NAME_SIZE, 3207c478bd9Sstevel@tonic-gate KRB5_TGS_NAME 3217c478bd9Sstevel@tonic-gate }; 3227c478bd9Sstevel@tonic-gate krb5_get_init_creds_opt opts; 3237c478bd9Sstevel@tonic-gate /* 3247c478bd9Sstevel@tonic-gate * "result" should not be assigned PAM_SUCCESS unless 3257c478bd9Sstevel@tonic-gate * authentication has succeeded and there are no other errors. 3267c478bd9Sstevel@tonic-gate * 3277c478bd9Sstevel@tonic-gate * "code" is sometimes used for PAM codes, sometimes for krb5 3287c478bd9Sstevel@tonic-gate * codes. Be careful. 3297c478bd9Sstevel@tonic-gate */ 3307c478bd9Sstevel@tonic-gate int result = PAM_AUTH_ERR; 3317c478bd9Sstevel@tonic-gate 3327c478bd9Sstevel@tonic-gate if (kmd->debug) 3337c478bd9Sstevel@tonic-gate syslog(LOG_DEBUG, 3347c478bd9Sstevel@tonic-gate "PAM-KRB5 (auth): attempt_krb5_auth: start: user='%s'", 3357c478bd9Sstevel@tonic-gate user ? user : "<null>"); 3367c478bd9Sstevel@tonic-gate 3377c478bd9Sstevel@tonic-gate krb5_get_init_creds_opt_init(&opts); 3387c478bd9Sstevel@tonic-gate 3397c478bd9Sstevel@tonic-gate /* need to free context with krb5_free_context */ 3407c478bd9Sstevel@tonic-gate if (code = krb5_init_context(&kmd->kcontext)) { 3417c478bd9Sstevel@tonic-gate syslog(LOG_ERR, dgettext(TEXT_DOMAIN, 3427c478bd9Sstevel@tonic-gate "PAM-KRB5 (auth): Error initializing " 3437c478bd9Sstevel@tonic-gate "krb5: %s"), 3447c478bd9Sstevel@tonic-gate error_message(code)); 3457c478bd9Sstevel@tonic-gate return (PAM_SYSTEM_ERR); 3467c478bd9Sstevel@tonic-gate } 3477c478bd9Sstevel@tonic-gate 3487c478bd9Sstevel@tonic-gate if ((code = get_kmd_kuser(kmd->kcontext, (const char *)user, kuser, 3497c478bd9Sstevel@tonic-gate 2*MAXHOSTNAMELEN)) != 0) { 3507c478bd9Sstevel@tonic-gate /* get_kmd_kuser returns proper PAM error statuses */ 3517c478bd9Sstevel@tonic-gate return (code); 3527c478bd9Sstevel@tonic-gate } 3537c478bd9Sstevel@tonic-gate 3547c478bd9Sstevel@tonic-gate if ((code = krb5_parse_name(kmd->kcontext, kuser, &me)) != 0) { 3557c478bd9Sstevel@tonic-gate krb5_free_context(kmd->kcontext); 3567c478bd9Sstevel@tonic-gate kmd->kcontext = NULL; 3577c478bd9Sstevel@tonic-gate return (PAM_AUTH_ERR); 3587c478bd9Sstevel@tonic-gate } 3597c478bd9Sstevel@tonic-gate 3607c478bd9Sstevel@tonic-gate /* call krb5_free_cred_contents() on error */ 3617c478bd9Sstevel@tonic-gate my_creds = &kmd->initcreds; 3627c478bd9Sstevel@tonic-gate 3637c478bd9Sstevel@tonic-gate if ((code = krb5_copy_principal(kmd->kcontext, me, &my_creds->client))) 3647c478bd9Sstevel@tonic-gate goto out_err; 3657c478bd9Sstevel@tonic-gate 3667c478bd9Sstevel@tonic-gate if (code = krb5_build_principal_ext(kmd->kcontext, &server, 3677c478bd9Sstevel@tonic-gate krb5_princ_realm(kmd->kcontext, me)->length, 3687c478bd9Sstevel@tonic-gate krb5_princ_realm(kmd->kcontext, me)->data, 3697c478bd9Sstevel@tonic-gate tgtname.length, tgtname.data, 3707c478bd9Sstevel@tonic-gate krb5_princ_realm(kmd->kcontext, me)->length, 3717c478bd9Sstevel@tonic-gate krb5_princ_realm(kmd->kcontext, me)->data, 0)) { 3727c478bd9Sstevel@tonic-gate syslog(LOG_ERR, dgettext(TEXT_DOMAIN, 3737c478bd9Sstevel@tonic-gate "PAM-KRB5 (auth): attempt_krb5_auth: " 3747c478bd9Sstevel@tonic-gate "krb5_build_princ_ext failed: %s"), 3757c478bd9Sstevel@tonic-gate error_message(code)); 3767c478bd9Sstevel@tonic-gate goto out; 3777c478bd9Sstevel@tonic-gate } 3787c478bd9Sstevel@tonic-gate 3797c478bd9Sstevel@tonic-gate if (code = krb5_copy_principal(kmd->kcontext, server, 3807c478bd9Sstevel@tonic-gate &my_creds->server)) { 3817c478bd9Sstevel@tonic-gate goto out_err; 3827c478bd9Sstevel@tonic-gate } 3837c478bd9Sstevel@tonic-gate 3847c478bd9Sstevel@tonic-gate if (code = krb5_timeofday(kmd->kcontext, &now)) { 3857c478bd9Sstevel@tonic-gate syslog(LOG_ERR, dgettext(TEXT_DOMAIN, 3867c478bd9Sstevel@tonic-gate "PAM-KRB5 (auth): attempt_krb5_auth: " 3877c478bd9Sstevel@tonic-gate "krb5_timeofday failed: %s"), 3887c478bd9Sstevel@tonic-gate error_message(code)); 3897c478bd9Sstevel@tonic-gate goto out; 3907c478bd9Sstevel@tonic-gate } 3917c478bd9Sstevel@tonic-gate 3927c478bd9Sstevel@tonic-gate /* 3937c478bd9Sstevel@tonic-gate * set the values for lifetime and rlife to be the maximum 3947c478bd9Sstevel@tonic-gate * possible 3957c478bd9Sstevel@tonic-gate */ 3967c478bd9Sstevel@tonic-gate krb5_max_duration = KRB5_KDB_EXPIRATION - now - 60*60; 3977c478bd9Sstevel@tonic-gate lifetime = krb5_max_duration; 3987c478bd9Sstevel@tonic-gate rlife = krb5_max_duration; 3997c478bd9Sstevel@tonic-gate 4007c478bd9Sstevel@tonic-gate /* 4017c478bd9Sstevel@tonic-gate * Let us get the values for various options 4027c478bd9Sstevel@tonic-gate * from Kerberos configuration file 4037c478bd9Sstevel@tonic-gate */ 4047c478bd9Sstevel@tonic-gate 4057c478bd9Sstevel@tonic-gate krb_realm = krb5_princ_realm(kmd->kcontext, me)->data; 4067c478bd9Sstevel@tonic-gate profile_get_options_boolean(kmd->kcontext->profile, 4077c478bd9Sstevel@tonic-gate realmdef, config_option); 4087c478bd9Sstevel@tonic-gate profile_get_options_boolean(kmd->kcontext->profile, 4097c478bd9Sstevel@tonic-gate appdef, config_option); 4107c478bd9Sstevel@tonic-gate profile_get_options_string(kmd->kcontext->profile, 4117c478bd9Sstevel@tonic-gate realmdef, config_times); 4127c478bd9Sstevel@tonic-gate profile_get_options_string(kmd->kcontext->profile, 4137c478bd9Sstevel@tonic-gate appdef, config_times); 4147c478bd9Sstevel@tonic-gate 4157c478bd9Sstevel@tonic-gate if (renew_timeval) { 4167c478bd9Sstevel@tonic-gate code = krb5_string_to_deltat(renew_timeval, &rlife); 4177c478bd9Sstevel@tonic-gate if (code != 0 || rlife == 0 || rlife > krb5_max_duration) { 4187c478bd9Sstevel@tonic-gate syslog(LOG_ERR, 4197c478bd9Sstevel@tonic-gate dgettext(TEXT_DOMAIN, 4207c478bd9Sstevel@tonic-gate "PAM-KRB5 (auth): Bad max_renewable_life " 4217c478bd9Sstevel@tonic-gate " value '%s' in Kerberos config file"), 4227c478bd9Sstevel@tonic-gate renew_timeval); 4237c478bd9Sstevel@tonic-gate result = PAM_SYSTEM_ERR; 4247c478bd9Sstevel@tonic-gate goto out; 4257c478bd9Sstevel@tonic-gate } 4267c478bd9Sstevel@tonic-gate } 4277c478bd9Sstevel@tonic-gate if (life_timeval) { 4287c478bd9Sstevel@tonic-gate code = krb5_string_to_deltat(life_timeval, &lifetime); 4297c478bd9Sstevel@tonic-gate if (code != 0 || lifetime == 0 || 4307c478bd9Sstevel@tonic-gate lifetime > krb5_max_duration) { 4317c478bd9Sstevel@tonic-gate syslog(LOG_ERR, 4327c478bd9Sstevel@tonic-gate dgettext(TEXT_DOMAIN, "PAM-KRB5 (auth): Bad " 4337c478bd9Sstevel@tonic-gate "lifetime value '%s' in Kerberos config file"), 4347c478bd9Sstevel@tonic-gate life_timeval); 4357c478bd9Sstevel@tonic-gate result = PAM_SYSTEM_ERR; 4367c478bd9Sstevel@tonic-gate goto out; 4377c478bd9Sstevel@tonic-gate } 4387c478bd9Sstevel@tonic-gate } 4397c478bd9Sstevel@tonic-gate /* start timer when request gets to KDC */ 4407c478bd9Sstevel@tonic-gate my_creds->times.starttime = 0; 4417c478bd9Sstevel@tonic-gate my_creds->times.endtime = now + lifetime; 4427c478bd9Sstevel@tonic-gate 4437c478bd9Sstevel@tonic-gate if (options & KDC_OPT_RENEWABLE) { 4447c478bd9Sstevel@tonic-gate my_creds->times.renew_till = now + rlife; 4457c478bd9Sstevel@tonic-gate } else 4467c478bd9Sstevel@tonic-gate my_creds->times.renew_till = 0; 4477c478bd9Sstevel@tonic-gate 4487c478bd9Sstevel@tonic-gate krb5_get_init_creds_opt_set_tkt_life(&opts, lifetime); 4497c478bd9Sstevel@tonic-gate 4507c478bd9Sstevel@tonic-gate if (proxiable_flag) { /* Set in config file */ 4517c478bd9Sstevel@tonic-gate if (kmd->debug) 4527c478bd9Sstevel@tonic-gate syslog(LOG_DEBUG, dgettext(TEXT_DOMAIN, 4537c478bd9Sstevel@tonic-gate "PAM-KRB5 (auth): Proxiable tickets " 4547c478bd9Sstevel@tonic-gate "requested")); 4557c478bd9Sstevel@tonic-gate krb5_get_init_creds_opt_set_proxiable(&opts, TRUE); 4567c478bd9Sstevel@tonic-gate } 4577c478bd9Sstevel@tonic-gate if (forwardable_flag) { 4587c478bd9Sstevel@tonic-gate if (kmd->debug) 4597c478bd9Sstevel@tonic-gate syslog(LOG_DEBUG, dgettext(TEXT_DOMAIN, 4607c478bd9Sstevel@tonic-gate "PAM-KRB5 (auth): Forwardable tickets " 4617c478bd9Sstevel@tonic-gate "requested")); 4627c478bd9Sstevel@tonic-gate krb5_get_init_creds_opt_set_forwardable(&opts, TRUE); 4637c478bd9Sstevel@tonic-gate } 4647c478bd9Sstevel@tonic-gate if (renewable_flag) { 4657c478bd9Sstevel@tonic-gate if (kmd->debug) 4667c478bd9Sstevel@tonic-gate syslog(LOG_DEBUG, dgettext(TEXT_DOMAIN, 4677c478bd9Sstevel@tonic-gate "PAM-KRB5 (auth): Renewable tickets " 4687c478bd9Sstevel@tonic-gate "requested")); 4697c478bd9Sstevel@tonic-gate krb5_get_init_creds_opt_set_renew_life(&opts, rlife); 4707c478bd9Sstevel@tonic-gate } 4717c478bd9Sstevel@tonic-gate if (no_address_flag) { 4727c478bd9Sstevel@tonic-gate if (kmd->debug) 4737c478bd9Sstevel@tonic-gate syslog(LOG_DEBUG, dgettext(TEXT_DOMAIN, 4747c478bd9Sstevel@tonic-gate "PAM-KRB5 (auth): Addressless tickets " 4757c478bd9Sstevel@tonic-gate "requested")); 4767c478bd9Sstevel@tonic-gate krb5_get_init_creds_opt_set_address_list(&opts, NULL); 4777c478bd9Sstevel@tonic-gate } 4787c478bd9Sstevel@tonic-gate 4797c478bd9Sstevel@tonic-gate /* 4807c478bd9Sstevel@tonic-gate * mech_krb5 interprets empty passwords as NULL passwords 4817c478bd9Sstevel@tonic-gate * and tries to read a password from stdin. Since we are in 4827c478bd9Sstevel@tonic-gate * pam this is bad and should not be allowed. 4837c478bd9Sstevel@tonic-gate */ 4847c478bd9Sstevel@tonic-gate if (*krb5_pass == NULL || strlen(*krb5_pass) == 0) { 4857c478bd9Sstevel@tonic-gate code = KRB5KRB_AP_ERR_BAD_INTEGRITY; 4867c478bd9Sstevel@tonic-gate } else { 4877c478bd9Sstevel@tonic-gate code = krb5_get_init_creds_password(kmd->kcontext, 4887c478bd9Sstevel@tonic-gate my_creds, 4897c478bd9Sstevel@tonic-gate me, 4907c478bd9Sstevel@tonic-gate *krb5_pass, /* clear text passwd */ 4917c478bd9Sstevel@tonic-gate NULL, /* prompter */ 4927c478bd9Sstevel@tonic-gate NULL, /* data */ 4937c478bd9Sstevel@tonic-gate 0, /* start time */ 4947c478bd9Sstevel@tonic-gate NULL, /* defaults to krbtgt@REALM */ 4957c478bd9Sstevel@tonic-gate &opts); 4967c478bd9Sstevel@tonic-gate } 4977c478bd9Sstevel@tonic-gate 4987c478bd9Sstevel@tonic-gate if (kmd->debug) 4997c478bd9Sstevel@tonic-gate syslog(LOG_DEBUG, 5007c478bd9Sstevel@tonic-gate "PAM-KRB5 (auth): attempt_krb5_auth: " 5017c478bd9Sstevel@tonic-gate "krb5_get_init_creds_password returns: %s", 5027c478bd9Sstevel@tonic-gate code == 0 ? "SUCCESS" : error_message(code)); 5037c478bd9Sstevel@tonic-gate 5047c478bd9Sstevel@tonic-gate switch (code) { 5057c478bd9Sstevel@tonic-gate case 0: 5067c478bd9Sstevel@tonic-gate /* got a tgt, let's verify it */ 5077c478bd9Sstevel@tonic-gate if (verify_tik) { 5087c478bd9Sstevel@tonic-gate krb5_verify_init_creds_opt vopts; 5097c478bd9Sstevel@tonic-gate 510a0709436Smp krb5_principal sp = NULL; 511a0709436Smp char kt_name[MAX_KEYTAB_NAME_LEN]; 512a0709436Smp char *fqdn; 513a0709436Smp 5147c478bd9Sstevel@tonic-gate krb5_verify_init_creds_opt_init(&vopts); 5157c478bd9Sstevel@tonic-gate 5167c478bd9Sstevel@tonic-gate code = krb5_verify_init_creds(kmd->kcontext, 5177c478bd9Sstevel@tonic-gate my_creds, 5187c478bd9Sstevel@tonic-gate NULL, /* defaults to host/localhost@REALM */ 5197c478bd9Sstevel@tonic-gate NULL, 5207c478bd9Sstevel@tonic-gate NULL, 5217c478bd9Sstevel@tonic-gate &vopts); 5227c478bd9Sstevel@tonic-gate 5237c478bd9Sstevel@tonic-gate if (code) { 5247c478bd9Sstevel@tonic-gate result = PAM_SYSTEM_ERR; 5257c478bd9Sstevel@tonic-gate 5260be37caaSsemery /* 5270be37caaSsemery * Give a better error message when the 5280be37caaSsemery * keytable entry isn't found or the keytab 5290be37caaSsemery * file cannot be found. 5300be37caaSsemery */ 531a0709436Smp if (krb5_sname_to_principal(kmd->kcontext, NULL, 532a0709436Smp NULL, KRB5_NT_SRV_HST, &sp)) 533a0709436Smp fqdn = "<fqdn>"; 534a0709436Smp else 535a0709436Smp fqdn = sp->data[1].data; 536a0709436Smp 537a0709436Smp if (krb5_kt_default_name(kmd->kcontext, kt_name, 538a0709436Smp sizeof (kt_name))) 539a0709436Smp (void) strncpy(kt_name, 540a0709436Smp "default keytab", 541a0709436Smp sizeof (kt_name)); 542a0709436Smp 543a0709436Smp switch (code) { 544a0709436Smp case KRB5_KT_NOTFOUND: 545a0709436Smp syslog(LOG_ERR, 546a0709436Smp dgettext(TEXT_DOMAIN, 547a0709436Smp "PAM-KRB5 (auth): " 548a0709436Smp "krb5_verify_init_creds failed:" 549a0709436Smp " Key table entry \"host/%s\"" 550a0709436Smp " not found in %s"), 551a0709436Smp fqdn, kt_name); 552a0709436Smp break; 553a0709436Smp case ENOENT: 554a0709436Smp syslog(LOG_ERR, 5557c478bd9Sstevel@tonic-gate dgettext(TEXT_DOMAIN, 556a0709436Smp "PAM-KRB5 (auth): " 557a0709436Smp "krb5_verify_init_creds failed:" 558a0709436Smp " Keytab file \"%s\"" 559a0709436Smp " does not exist.\n"), 560a0709436Smp kt_name); 561a0709436Smp break; 562a0709436Smp default: 563a0709436Smp syslog(LOG_ERR, 564a0709436Smp dgettext(TEXT_DOMAIN, 565a0709436Smp "PAM-KRB5 (auth): " 566a0709436Smp "krb5_verify_init_creds failed:" 567a0709436Smp " %s"), 568a0709436Smp error_message(code)); 569a0709436Smp break; 570a0709436Smp } 571a0709436Smp 572a0709436Smp if (sp) 573a0709436Smp krb5_free_principal(kmd->kcontext, sp); 5747c478bd9Sstevel@tonic-gate } 5757c478bd9Sstevel@tonic-gate } 5767c478bd9Sstevel@tonic-gate break; 5777c478bd9Sstevel@tonic-gate 5787c478bd9Sstevel@tonic-gate case KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN: 5797c478bd9Sstevel@tonic-gate /* 5807c478bd9Sstevel@tonic-gate * Since this principal is not part of the local 5817c478bd9Sstevel@tonic-gate * Kerberos realm, we just return PAM_USER_UNKNOWN. 5827c478bd9Sstevel@tonic-gate */ 5837c478bd9Sstevel@tonic-gate result = PAM_USER_UNKNOWN; 5847c478bd9Sstevel@tonic-gate 5857c478bd9Sstevel@tonic-gate if (kmd->debug) 5867c478bd9Sstevel@tonic-gate syslog(LOG_DEBUG, "PAM-KRB5 (auth): attempt_krb5_auth:" 5877c478bd9Sstevel@tonic-gate " User is not part of the local Kerberos" 5887c478bd9Sstevel@tonic-gate " realm: %s", error_message(code)); 5897c478bd9Sstevel@tonic-gate break; 5907c478bd9Sstevel@tonic-gate 5917c478bd9Sstevel@tonic-gate case KRB5KDC_ERR_PREAUTH_FAILED: 5927c478bd9Sstevel@tonic-gate case KRB5KRB_AP_ERR_BAD_INTEGRITY: 5937c478bd9Sstevel@tonic-gate /* 5947c478bd9Sstevel@tonic-gate * We could be trying the password from a previous 5957c478bd9Sstevel@tonic-gate * pam authentication module, but we don't want to 5967c478bd9Sstevel@tonic-gate * generate an error if the unix password is different 5977c478bd9Sstevel@tonic-gate * than the Kerberos password... 5987c478bd9Sstevel@tonic-gate */ 5997c478bd9Sstevel@tonic-gate break; 6007c478bd9Sstevel@tonic-gate 6017c478bd9Sstevel@tonic-gate case KRB5KDC_ERR_KEY_EXP: 6027c478bd9Sstevel@tonic-gate if (!kmd->err_on_exp) { 6037c478bd9Sstevel@tonic-gate /* 6047c478bd9Sstevel@tonic-gate * Request a tik for changepw service 6057c478bd9Sstevel@tonic-gate * and it will tell us if pw is good or not. 6067c478bd9Sstevel@tonic-gate */ 607*2278144aSsemery code = krb5_verifypw(kuser, *krb5_pass, kmd->debug); 6087c478bd9Sstevel@tonic-gate 6097c478bd9Sstevel@tonic-gate if (kmd->debug) 6107c478bd9Sstevel@tonic-gate syslog(LOG_DEBUG, 6117c478bd9Sstevel@tonic-gate "PAM-KRB5 (auth): attempt_krb5_auth: " 612*2278144aSsemery "verifypw %d", code); 6137c478bd9Sstevel@tonic-gate 6147c478bd9Sstevel@tonic-gate if (code == 0) { 6157c478bd9Sstevel@tonic-gate /* pw is good, set age status for acct_mgmt */ 6167c478bd9Sstevel@tonic-gate kmd->age_status = PAM_NEW_AUTHTOK_REQD; 6177c478bd9Sstevel@tonic-gate } 6187c478bd9Sstevel@tonic-gate } 6197c478bd9Sstevel@tonic-gate break; 6207c478bd9Sstevel@tonic-gate 6217c478bd9Sstevel@tonic-gate default: 6227c478bd9Sstevel@tonic-gate result = PAM_SYSTEM_ERR; 6237c478bd9Sstevel@tonic-gate if (kmd->debug) 6247c478bd9Sstevel@tonic-gate syslog(LOG_DEBUG, "PAM-KRB5 (auth): error %d - %s", 6257c478bd9Sstevel@tonic-gate code, error_message(code)); 6267c478bd9Sstevel@tonic-gate break; 6277c478bd9Sstevel@tonic-gate } 6287c478bd9Sstevel@tonic-gate 6297c478bd9Sstevel@tonic-gate if (code == 0) { 6307c478bd9Sstevel@tonic-gate /* 6317c478bd9Sstevel@tonic-gate * success for the entered pw 6327c478bd9Sstevel@tonic-gate * 6337c478bd9Sstevel@tonic-gate * we can't rely on the pw in PAM_AUTHTOK 6347c478bd9Sstevel@tonic-gate * to be the (correct) krb5 one so 6357c478bd9Sstevel@tonic-gate * store krb5 pw in module data for 6367c478bd9Sstevel@tonic-gate * use in acct_mgmt 6377c478bd9Sstevel@tonic-gate */ 6387c478bd9Sstevel@tonic-gate if (!(kmd->password = strdup(*krb5_pass))) { 6397c478bd9Sstevel@tonic-gate syslog(LOG_ERR, "Cannot strdup password"); 6407c478bd9Sstevel@tonic-gate result = PAM_BUF_ERR; 6417c478bd9Sstevel@tonic-gate goto out_err; 6427c478bd9Sstevel@tonic-gate } 6437c478bd9Sstevel@tonic-gate result = PAM_SUCCESS; 6447c478bd9Sstevel@tonic-gate goto out; 6457c478bd9Sstevel@tonic-gate } 6467c478bd9Sstevel@tonic-gate 6477c478bd9Sstevel@tonic-gate out_err: 6487c478bd9Sstevel@tonic-gate /* jump (or reach) here if error and cred cache has been init */ 6497c478bd9Sstevel@tonic-gate 6507c478bd9Sstevel@tonic-gate if (kmd->debug) 6517c478bd9Sstevel@tonic-gate syslog(LOG_DEBUG, 6527c478bd9Sstevel@tonic-gate "PAM-KRB5 (auth): clearing initcreds in " 6537c478bd9Sstevel@tonic-gate "pam_authenticate()"); 6547c478bd9Sstevel@tonic-gate 6557c478bd9Sstevel@tonic-gate krb5_free_cred_contents(kmd->kcontext, &kmd->initcreds); 6567c478bd9Sstevel@tonic-gate (void) memset((char *)&kmd->initcreds, 0, sizeof (krb5_creds)); 6577c478bd9Sstevel@tonic-gate 6587c478bd9Sstevel@tonic-gate out: 6597c478bd9Sstevel@tonic-gate if (server) 6607c478bd9Sstevel@tonic-gate krb5_free_principal(kmd->kcontext, server); 6617c478bd9Sstevel@tonic-gate if (me) 6627c478bd9Sstevel@tonic-gate krb5_free_principal(kmd->kcontext, me); 6637c478bd9Sstevel@tonic-gate if (kmd->kcontext) { 6647c478bd9Sstevel@tonic-gate krb5_free_context(kmd->kcontext); 6657c478bd9Sstevel@tonic-gate kmd->kcontext = NULL; 6667c478bd9Sstevel@tonic-gate } 6677c478bd9Sstevel@tonic-gate 6687c478bd9Sstevel@tonic-gate if (kmd->debug) 6697c478bd9Sstevel@tonic-gate syslog(LOG_DEBUG, 6707c478bd9Sstevel@tonic-gate "PAM-KRB5 (auth): attempt_krb5_auth returning %d", 6717c478bd9Sstevel@tonic-gate result); 6727c478bd9Sstevel@tonic-gate 6737c478bd9Sstevel@tonic-gate return (kmd->auth_status = result); 6747c478bd9Sstevel@tonic-gate } 6757c478bd9Sstevel@tonic-gate 6767c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 6777c478bd9Sstevel@tonic-gate void 6787c478bd9Sstevel@tonic-gate krb5_cleanup(pam_handle_t *pamh, void *data, int pam_status) 6797c478bd9Sstevel@tonic-gate { 6807c478bd9Sstevel@tonic-gate krb5_module_data_t *kmd = (krb5_module_data_t *)data; 6817c478bd9Sstevel@tonic-gate 6827c478bd9Sstevel@tonic-gate if (kmd == NULL) 6837c478bd9Sstevel@tonic-gate return; 6847c478bd9Sstevel@tonic-gate 6857c478bd9Sstevel@tonic-gate if (kmd->debug) { 6867c478bd9Sstevel@tonic-gate syslog(LOG_DEBUG, 6877c478bd9Sstevel@tonic-gate dgettext(TEXT_DOMAIN, 6887c478bd9Sstevel@tonic-gate "PAM-KRB5 (auth): krb5_cleanup auth_status = %d"), 6897c478bd9Sstevel@tonic-gate kmd->auth_status); 6907c478bd9Sstevel@tonic-gate } 6917c478bd9Sstevel@tonic-gate 6927c478bd9Sstevel@tonic-gate /* 6937c478bd9Sstevel@tonic-gate * if pam_status is PAM_SUCCESS, clean up based on value in 6947c478bd9Sstevel@tonic-gate * auth_status, otherwise just purge the context 6957c478bd9Sstevel@tonic-gate */ 6967c478bd9Sstevel@tonic-gate if ((pam_status == PAM_SUCCESS) && 6977c478bd9Sstevel@tonic-gate (kmd->auth_status == PAM_SUCCESS) && kmd->ccache) 6987c478bd9Sstevel@tonic-gate krb5_cc_close(kmd->kcontext, kmd->ccache); 6997c478bd9Sstevel@tonic-gate 7007c478bd9Sstevel@tonic-gate if (kmd->password) { 7017c478bd9Sstevel@tonic-gate (void) memset(kmd->password, 0, strlen(kmd->password)); 7027c478bd9Sstevel@tonic-gate free(kmd->password); 7037c478bd9Sstevel@tonic-gate } 7047c478bd9Sstevel@tonic-gate 7057c478bd9Sstevel@tonic-gate if ((pam_status != PAM_SUCCESS) || 7067c478bd9Sstevel@tonic-gate (kmd->auth_status != PAM_SUCCESS)) { 7077c478bd9Sstevel@tonic-gate krb5_free_cred_contents(kmd->kcontext, &kmd->initcreds); 7087c478bd9Sstevel@tonic-gate (void) memset((char *)&kmd->initcreds, 0, sizeof (krb5_creds)); 7097c478bd9Sstevel@tonic-gate } 7107c478bd9Sstevel@tonic-gate 7117c478bd9Sstevel@tonic-gate free(kmd); 7127c478bd9Sstevel@tonic-gate } 713