diff options
-rw-r--r-- | usr/src/cmd/krb5/kadmin/server/misc.c | 18 | ||||
-rw-r--r-- | usr/src/cmd/krb5/kadmin/server/server_stubs.c | 6 | ||||
-rw-r--r-- | usr/src/cmd/krb5/krb5kdc/do_as_req.c | 15 | ||||
-rw-r--r-- | usr/src/lib/gss_mechs/mech_krb5/et/krb5_err.c | 88 | ||||
-rw-r--r-- | usr/src/lib/gss_mechs/mech_krb5/krb5/krb/gic_pwd.c | 53 | ||||
-rw-r--r-- | usr/src/lib/gss_mechs/mech_krb5/krb5/rcache/rc_mem.c | 11 | ||||
-rw-r--r-- | usr/src/lib/gss_mechs/mech_krb5/mapfile-vers | 3 | ||||
-rw-r--r-- | usr/src/lib/pam_modules/dhkeys/dhkeys.c | 19 | ||||
-rw-r--r-- | usr/src/lib/pam_modules/krb5/krb5_acct_mgmt.c | 118 | ||||
-rw-r--r-- | usr/src/lib/pam_modules/krb5/krb5_authenticate.c | 23 | ||||
-rw-r--r-- | usr/src/lib/pam_modules/krb5/utils.h | 1 | ||||
-rw-r--r-- | usr/src/lib/passwdutil/nisplus_attr.c | 9 |
12 files changed, 252 insertions, 112 deletions
diff --git a/usr/src/cmd/krb5/kadmin/server/misc.c b/usr/src/cmd/krb5/kadmin/server/misc.c index 03bdf8758d..c1d31d25c3 100644 --- a/usr/src/cmd/krb5/kadmin/server/misc.c +++ b/usr/src/cmd/krb5/kadmin/server/misc.c @@ -1,3 +1,8 @@ +/* + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + #pragma ident "%Z%%M% %I% %E% SMI" /* @@ -131,6 +136,19 @@ chpass_util_wrapper(void *server_handle, krb5_principal princ, } kadm5_ret_t +randkey_principal_wrapper(void *server_handle, krb5_principal princ, + krb5_keyblock ** keys, int *n_keys) +{ + kadm5_ret_t ret; + + ret = check_min_life(server_handle, princ); + if (ret) + return ret; + + return kadm5_randkey_principal(server_handle, princ, keys, n_keys); +} + +kadm5_ret_t check_min_life(void *server_handle, krb5_principal principal) { krb5_int32 now; diff --git a/usr/src/cmd/krb5/kadmin/server/server_stubs.c b/usr/src/cmd/krb5/kadmin/server/server_stubs.c index b992cc5e57..b76a002ab2 100644 --- a/usr/src/cmd/krb5/kadmin/server/server_stubs.c +++ b/usr/src/cmd/krb5/kadmin/server/server_stubs.c @@ -1,5 +1,5 @@ /* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -1414,8 +1414,8 @@ chrand_principal_1_svc(chrand_arg *arg, struct svc_req *rqstp) } if (cmp_gss_krb5_name(handle, name, arg->princ)) { - ret.code = randkey_principal_wrapper_3((void *)handle, arg->princ, - FALSE, 0, NULL, &k, &nkeys); + ret.code = randkey_principal_wrapper((void *)handle, arg->princ, &k, + &nkeys); } else if (!(CHANGEPW_SERVICE(rqstp)) && kadm5int_acl_check(handle->context, name, ACL_CHANGEPW, arg->princ, NULL)) { diff --git a/usr/src/cmd/krb5/krb5kdc/do_as_req.c b/usr/src/cmd/krb5/krb5kdc/do_as_req.c index 22f3e97d37..4751eb18e5 100644 --- a/usr/src/cmd/krb5/krb5kdc/do_as_req.c +++ b/usr/src/cmd/krb5/krb5kdc/do_as_req.c @@ -1,5 +1,5 @@ /* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -69,7 +69,7 @@ process_as_req(krb5_kdc_req *request, const krb5_fulladdr *from, krb5_error_code errcode; int c_nprincs = 0, s_nprincs = 0; krb5_boolean more; - krb5_timestamp kdc_time, authtime; + krb5_timestamp kdc_time, authtime, etime = 0; krb5_keyblock session_key; krb5_keyblock encrypting_key; const char *status; @@ -398,7 +398,16 @@ process_as_req(krb5_kdc_req *request, const krb5_fulladdr *from, goto errout; } reply_encpart.nonce = request->nonce; - reply_encpart.key_exp = client.expiration; + + /* + * Take the minimum of expiration or pw_expiration if not zero. + */ + if (client.expiration != 0 && client.pw_expiration != 0) + etime = min(client.expiration, client.pw_expiration); + else + etime = client.expiration ? client.expiration : client.pw_expiration; + + reply_encpart.key_exp = etime; reply_encpart.flags = enc_tkt_reply.flags; reply_encpart.server = ticket_reply.server; diff --git a/usr/src/lib/gss_mechs/mech_krb5/et/krb5_err.c b/usr/src/lib/gss_mechs/mech_krb5/et/krb5_err.c index 3fa140c718..f9017f813d 100644 --- a/usr/src/lib/gss_mechs/mech_krb5/et/krb5_err.c +++ b/usr/src/lib/gss_mechs/mech_krb5/et/krb5_err.c @@ -1,5 +1,5 @@ /* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -704,72 +704,86 @@ switch (errorno) { case 225: return (dgettext(TEXT_DOMAIN, "Bad SAM flags in obtain_sam_padata")); - case 226: + case 226: /* KRB5_SAM_INVALID_ETYPE */ + return (dgettext(TEXT_DOMAIN, + "Invalid encryption type in SAM challenge")); + case 227: /* KRB5_SAM_NO_CHECKSUM */ + return (dgettext(TEXT_DOMAIN, + "Missing checksum in SAM challenge")); + case 228: /* KRB5_SAM_BAD_CHECKSUM */ + return (dgettext(TEXT_DOMAIN, + "Bad checksum in SAM challenge")); + case 229: /* KRB5_KT_NAME_TOOLONG */ return (dgettext(TEXT_DOMAIN, "Keytab name too long")); - case 227: + case 230: /* KRB5_KT_KVNONOTFOUND */ return (dgettext(TEXT_DOMAIN, "Key version number for principal in key table is " "incorrect")); - case 228: + case 231: /* KRB5_APPL_EXPIRED */ return (dgettext(TEXT_DOMAIN, "This application has expired")); - case 229: + case 232: /* KRB5_LIB_EXPIRED */ return (dgettext(TEXT_DOMAIN, "This Krb5 library has expired")); - case 230: + case 233: /* KRB5_CHPW_PWDNULL */ return (dgettext(TEXT_DOMAIN, "New password cannot be zero length")); - case 231: + case 234: /* KRB5_CHPW_FAIL */ return (dgettext(TEXT_DOMAIN, "Password change failed")); - case 232: + case 235: /* KRB5_KT_FORMAT */ return (dgettext(TEXT_DOMAIN, "Bad format in keytab")); - case 233: + case 236: /* KRB5_NOPERM_ETYPE */ return (dgettext(TEXT_DOMAIN, "Encryption type not permitted")); - case 234: + case 237: /* KRB5_CONFIG_ETYPE_NOSUPP */ return (dgettext(TEXT_DOMAIN, "No supported encryption types (config file error?)")); - case 235: + case 238: /* KRB5_OBSOLETE_FN */ return (dgettext(TEXT_DOMAIN, "Program called an obsolete, deleted function")); - case 236: /* KRB5_CONF_NOT_CONFIGURED */ + case 239: /* KRB5_EAI_FAIL */ + return (dgettext(TEXT_DOMAIN, + "unknown getaddrinfo failure")); + case 240: /* KRB5_EAI_NODATA */ return (dgettext(TEXT_DOMAIN, - "Kerberos /etc/krb5/krb5.conf configuration file not configured")); - case 237: /* PKCS_ERR */ + "no data available for host/domain name")); + case 241: /* KRB5_EAI_NONAME */ return (dgettext(TEXT_DOMAIN, - "Error in the PKCS 11 library calls")); - case 238: /* KRB5_EAI_FAIL */ + "host/domain name not found")); + case 242: /* KRB5_EAI_SERVICE */ return (dgettext(TEXT_DOMAIN, - "unknown getaddrinfo failure")); - case 239: /* KRB5_EAI_NODATA */ + "service name unknown")); + case 243: /* KRB5_ERR_NUMERIC_REALM */ return (dgettext(TEXT_DOMAIN, - "no data available for host/domain name")); - case 240: /* KRB5_EAI_NONAME */ + "Cannot determine realm for numeric host address")); + case 244: /* KRB5_ERR_BAD_S2K_PARAMS */ + return (dgettext(TEXT_DOMAIN, + "Invalid key generation parameters from KDC")); + case 245: /* KRB5_ERR_NO_SERVICE */ + return (dgettext(TEXT_DOMAIN, + "service not available")); + case 246: /* KRB5_CC_READONLY */ + return (dgettext(TEXT_DOMAIN, + "Ccache function not supported: read-only ccache " + "type")); + case 247: /* KRB5_CC_NOSUPP */ return (dgettext(TEXT_DOMAIN, - "host/domain name not found")); - case 241: /* KRB5_EAI_SERVICE */ + "Ccache function not supported: not implemented")); + case 249: /* KRB5_RC_BADNAME */ return (dgettext(TEXT_DOMAIN, - "service name unknown")); - case 242: /* KRB5_ERR_NUMERIC_REALM */ + "Bad replay cache name")); + case 250: /* KRB5_CONF_NOT_CONFIGURED */ return (dgettext(TEXT_DOMAIN, - "Cannot determine realm for numeric host address")); - case 243: /* KRB5_ERR_NO_SERVICE */ + "krb5 conf file not configured")); + case 251: /* PKCS_ERR */ return (dgettext(TEXT_DOMAIN, - "service not available")); - case 244: /* KRB5_RC_BADNAME */ - return (dgettext(TEXT_DOMAIN, "Bad replay cache name")); - case 245: /* KRB5_CONF_NOT_CONFIGURED */ + "Error in the PKCS 11 library calls")); + case 252: /* KRB5_DELTAT_BADFORMAT */ return (dgettext(TEXT_DOMAIN, - "krb5 conf file not configured")); - case 246: /* PKCS_ERR */ - return (dgettext(TEXT_DOMAIN, "PKCS error")); - /* SUNW14resync start */ - case 247: /* KRB5_DELTAT_BADFORMAT */ - return (dgettext(TEXT_DOMAIN, "Delta time bad format")); - /* SUNW14resync end */ + "Delta time bad format")); default: return ("unknown error"); } diff --git a/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/gic_pwd.c b/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/gic_pwd.c index 6cda1024ab..4b2dda5dcf 100644 --- a/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/gic_pwd.c +++ b/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/gic_pwd.c @@ -1,5 +1,5 @@ /* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -35,6 +35,14 @@ extern kadm5_ret_t kadm5_init_with_password(char *, char *, char *, extern kadm5_ret_t kadm5_chpass_principal_util(void *, krb5_principal, char *, char **, char *, unsigned int); +/* + * Solaris Kerberos: + * See the function's definition for the description of this interface. + */ +krb5_error_code __krb5_get_init_creds_password(krb5_context, + krb5_creds *, krb5_principal, char *, krb5_prompter_fct, void *, + krb5_deltat, char *, krb5_get_init_creds_opt *, krb5_kdc_rep **); + static krb5_error_code krb5_get_as_key_password( krb5_context context, @@ -131,6 +139,37 @@ krb5_get_init_creds_password( char *in_tkt_service, krb5_get_init_creds_opt *options) { + /* + * Solaris Kerberos: + * We call our own private function that returns the as_reply back to + * the caller. This structure contains information, such as + * key-expiration and last-req fields. Entities such as pam_krb5 can + * use this information to provide account/password expiration warnings. + * The original "prompter" interface is not granular enough for PAM, + * as it will perform all passes w/o coordination with other modules. + */ + return (__krb5_get_init_creds_password(context, creds, client, password, + prompter, data, start_time, in_tkt_service, options, NULL)); +} + +/* + * Solaris Kerberos: + * See krb5_get_init_creds_password()'s comments for the justification of this + * private function. Caller must free ptr_as_reply if non-NULL. + */ +krb5_error_code KRB5_CALLCONV +__krb5_get_init_creds_password( + krb5_context context, + krb5_creds *creds, + krb5_principal client, + char *password, + krb5_prompter_fct prompter, + void *data, + krb5_deltat start_time, + char *in_tkt_service, + krb5_get_init_creds_opt *options, + krb5_kdc_rep **ptr_as_reply) +{ krb5_error_code ret, ret2; int use_master; krb5_kdc_rep *as_reply; @@ -420,8 +459,16 @@ cleanup: memset(pw0array, 0, sizeof(pw0array)); memset(pw1array, 0, sizeof(pw1array)); krb5_free_cred_contents(context, &chpw_creds); - if (as_reply) - krb5_free_kdc_rep(context, as_reply); + /* + * Solaris Kerberos: + * Argument, ptr_as_reply, being returned to caller if success and non-NULL. + */ + if (as_reply != NULL) { + if (ptr_as_reply == NULL) + krb5_free_kdc_rep(context, as_reply); + else + *ptr_as_reply = as_reply; + } return(ret); } diff --git a/usr/src/lib/gss_mechs/mech_krb5/krb5/rcache/rc_mem.c b/usr/src/lib/gss_mechs/mech_krb5/krb5/rcache/rc_mem.c index 206de86aeb..b629135d41 100644 --- a/usr/src/lib/gss_mechs/mech_krb5/krb5/rcache/rc_mem.c +++ b/usr/src/lib/gss_mechs/mech_krb5/krb5/rcache/rc_mem.c @@ -1,5 +1,5 @@ /* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -252,13 +252,10 @@ krb5_rc_mem_recover_or_init(krb5_context context, krb5_rcache id, { krb5_error_code retval; - retval = k5_mutex_lock(&id->lock); - if (retval) - return retval; - retval = krb5_rc_mem_recover(context, id); + retval = krb5_rc_mem_recover(context, id); if (retval) - retval = krb5_rc_mem_init_locked(context, id, lifespan); - k5_mutex_unlock(&id->lock); + retval = krb5_rc_mem_init(context, id, lifespan); + return retval; } diff --git a/usr/src/lib/gss_mechs/mech_krb5/mapfile-vers b/usr/src/lib/gss_mechs/mech_krb5/mapfile-vers index 199a3d4442..b35332024f 100644 --- a/usr/src/lib/gss_mechs/mech_krb5/mapfile-vers +++ b/usr/src/lib/gss_mechs/mech_krb5/mapfile-vers @@ -19,7 +19,7 @@ # CDDL HEADER END # # -# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Copyright 2007 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # # ident "%Z%%M% %I% %E% SMI" @@ -526,6 +526,7 @@ SUNWprivate_1.1 { krb5_get_init_creds_opt_set_salt; krb5_get_init_creds_opt_set_tkt_life; krb5_get_init_creds_password; + __krb5_get_init_creds_password; krb5_get_key_data; krb5_get_key_enctype; krb5_get_key_length; diff --git a/usr/src/lib/pam_modules/dhkeys/dhkeys.c b/usr/src/lib/pam_modules/dhkeys/dhkeys.c index 0e1114e797..2439202923 100644 --- a/usr/src/lib/pam_modules/dhkeys/dhkeys.c +++ b/usr/src/lib/pam_modules/dhkeys/dhkeys.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -704,9 +703,19 @@ pam_sm_chauthtok(pam_handle_t *pamh, int flags, int argc, const char **argv) free(pwu_rep); (void) memset(short_pass, '\0', sizeof (short_pass)); return (PAM_USER_UNKNOWN); - case PWU_CRED_ERROR: + case PWU_BAD_CREDPASS: /* The old password does not decrypt any credentials */ break; + case PWU_CRED_ERROR: + /* + * Indicates that the user's credentials could not be + * retrieved or removed. This could occur when a NIS+ + * user is in transition to another account authority. + */ + if (pwu_rep != PWU_DEFAULT_REP) + free(pwu_rep); + (void) memset(short_pass, '\0', sizeof (short_pass)); + return (PAM_AUTHTOK_ERR); default: if (pwu_rep != PWU_DEFAULT_REP) free(pwu_rep); diff --git a/usr/src/lib/pam_modules/krb5/krb5_acct_mgmt.c b/usr/src/lib/pam_modules/krb5/krb5_acct_mgmt.c index d838613187..b2fc5168c2 100644 --- a/usr/src/lib/pam_modules/krb5/krb5_acct_mgmt.c +++ b/usr/src/lib/pam_modules/krb5/krb5_acct_mgmt.c @@ -47,16 +47,17 @@ #define KRB5_AUTOMIGRATE_DATA "SUNW-KRB5-AUTOMIGRATE-DATA" +#define min(a, b) ((a) < (b) ? (a) : (b)) + /* * pam_sm_acct_mgmt main account managment routine. */ static int fetch_princ_entry( + krb5_module_data_t *kmd, char *princ_str, - char *password, kadm5_principal_ent_rec *prent, /* out */ - krb5_timestamp *now, /* out */ int debug) { @@ -64,17 +65,16 @@ fetch_princ_entry( krb5_principal princ = 0; char admin_realm[1024]; char kprinc[2*MAXHOSTNAMELEN]; - char *cpw_service; + char *cpw_service, *password; void *server_handle; krb5_context context; kadm5_config_params params; - if (code = krb5_init_context(&context)) { - return (PAM_SYSTEM_ERR); - } + password = kmd->password; + context = kmd->kcontext; - if ((code = get_kmd_kuser(context, (const char *)princ_str, kprinc, - 2*MAXHOSTNAMELEN)) != 0) { + if ((code = get_kmd_kuser(context, (const char *)princ_str, + kprinc, 2*MAXHOSTNAMELEN)) != 0) { return (code); } @@ -148,16 +148,6 @@ fetch_princ_entry( PAM_USER_UNKNOWN : PAM_SYSTEM_ERR); } - if (code = krb5_timeofday(context, now)) { - (void) kadm5_destroy(server_handle); - krb5_free_principal(context, princ); - krb5_free_context(context); - __pam_log(LOG_AUTH | LOG_ERR, - "PAM-KRB5 (acct): krb5_timeofday fail: code=%d", - code); - return (PAM_SYSTEM_ERR); - } - (void) kadm5_destroy(server_handle); krb5_free_principal(context, princ); krb5_free_context(context); @@ -168,76 +158,112 @@ fetch_princ_entry( /* * exp_warn * - * warn the user if her pw is set to expire + * Warn the user if their pw is set to expire. * - * We use the kadm protocol and chpw svc to fetch the user's KDC db - * entry. The user's default perms on the KDC db should allow this. - * Note since the SEAM kadm API uses rpcsec_gss (which is diff from - * what MS and MIT 1.2 and before uses), this probably only works - * with a SEAM KDC. + * We first check to see if the KDC had set any account or password + * expiration information in the key expiration field. If this was + * not set then we must assume that the KDC could be broken and revert + * to fetching pw/account expiration information from kadm. We can not + * determine the difference between broken KDCs that do not send key-exp + * vs. principals that do not have an expiration policy. The up-shot + * is that pam_krb5 will probably not be stacked for acct mgmt if the + * environment does not have an exp policy, avoiding the second exchange + * using the kadm protocol. */ - static int exp_warn( pam_handle_t *pamh, char *user, - char *password, + krb5_module_data_t *kmd, int debug) { int err; kadm5_principal_ent_rec prent; - krb5_timestamp now, days; - char messages[PAM_MAX_NUM_MSG][PAM_MAX_MSG_SIZE]; + krb5_timestamp now, days, expiration; + char messages[PAM_MAX_NUM_MSG][PAM_MAX_MSG_SIZE], *password; + krb5_error_code code; if (debug) __pam_log(LOG_AUTH | LOG_DEBUG, "PAM-KRB5 (acct): exp_warn start: user = '%s'", user ? user : "<null>"); + password = kmd->password; + if (!pamh || !user || !password) { err = PAM_SERVICE_ERR; goto out; } - (void) memset(&prent, 0, sizeof (prent)); - if ((err = fetch_princ_entry(user, password, &prent, - &now, debug)) != PAM_SUCCESS) { + if (code = krb5_init_context(&kmd->kcontext)) { + err = PAM_SYSTEM_ERR; if (debug) - __pam_log(LOG_AUTH | LOG_DEBUG, - "PAM-KRB5 (acct): exp_warn: fetch_pr failed %d", - err); + __pam_log(LOG_AUTH | LOG_ERR, "PAM-KRB5 (acct): " + "krb5_init_context failed: code=%d", + code); goto out; } + if (code = krb5_timeofday(kmd->kcontext, &now)) { + err = PAM_SYSTEM_ERR; + if (debug) + __pam_log(LOG_AUTH | LOG_ERR, + "PAM-KRB5 (acct): krb5_timeofday failed: code=%d", + code); + goto out; + } + + if (kmd->expiration != 0) { + expiration = kmd->expiration; + } else { + (void) memset(&prent, 0, sizeof (prent)); + if ((err = fetch_princ_entry(kmd, user, &prent, debug)) + != PAM_SUCCESS) { + if (debug) + __pam_log(LOG_AUTH | LOG_DEBUG, + "PAM-KRB5 (acct): exp_warn: fetch_pr failed %d", + err); + goto out; + } + if (prent.princ_expire_time != 0 && prent.pw_expiration != 0) + expiration = min(prent.princ_expire_time, + prent.pw_expiration); + else + expiration = prent.princ_expire_time ? + prent.princ_expire_time : prent.pw_expiration; + } if (debug) __pam_log(LOG_AUTH | LOG_DEBUG, - "PAM-KRB5 (acct): exp_warn: fetch_princ success:" - " princ exp=%ld pw_exp = %ld, now =%ld, days=%ld", - prent.princ_expire_time, - prent.pw_expiration, now, - prent.pw_expiration > 0 - ? ((prent.pw_expiration - now) / DAY) + "PAM-KRB5 (acct): exp_warn: " + "princ/pw_exp exp=%ld, now =%ld, days=%ld", + expiration, + now, + expiration > 0 + ? ((expiration - now) / DAY) : 0); /* warn user if principal's pw is set to expire */ - if (prent.pw_expiration > 0) { - days = (prent.pw_expiration - now) / DAY; + if (expiration > 0) { + days = (expiration - now) / DAY; if (days <= 0) (void) snprintf(messages[0], sizeof (messages[0]), dgettext(TEXT_DOMAIN, - "Your Kerberos password will expire within 24 hours.\n")); + "Your Kerberos account/password will expire " + "within 24 hours.\n")); else if (days == 1) (void) snprintf(messages[0], sizeof (messages[0]), dgettext(TEXT_DOMAIN, - "Your Kerberos password will expire in 1 day.\n")); + "Your Kerberos account/password will expire " + "in 1 day.\n")); else (void) snprintf(messages[0], sizeof (messages[0]), dgettext(TEXT_DOMAIN, - "Your Kerberos password will expire in %d days.\n"), + "Your Kerberos account/password will expire in " + "%d days.\n"), (int)days); (void) __pam_display_msg(pamh, PAM_TEXT_INFO, 1, @@ -423,7 +449,7 @@ pam_sm_acct_mgmt( if (!(flags & PAM_SILENT) && !nowarn && kmd->password) { /* if we fail, let it slide, it's only a warning brah */ - (void) exp_warn(pamh, user, kmd->password, debug); + (void) exp_warn(pamh, user, kmd, debug); } /* diff --git a/usr/src/lib/pam_modules/krb5/krb5_authenticate.c b/usr/src/lib/pam_modules/krb5/krb5_authenticate.c index aec4b426b7..eb0ac73162 100644 --- a/usr/src/lib/pam_modules/krb5/krb5_authenticate.c +++ b/usr/src/lib/pam_modules/krb5/krb5_authenticate.c @@ -77,6 +77,10 @@ extern int krb5_verifypw(char *, char *, int); extern krb5_error_code krb5_verify_init_creds(krb5_context, krb5_creds *, krb5_principal, krb5_keytab, krb5_ccache *, krb5_verify_init_creds_opt *); +extern krb5_error_code __krb5_get_init_creds_password(krb5_context, + krb5_creds *, krb5_principal, char *, krb5_prompter_fct, void *, + krb5_deltat, char *, krb5_get_init_creds_opt *, + krb5_kdc_rep **); /* * pam_sm_authenticate - Authenticate user @@ -325,6 +329,7 @@ attempt_krb5_auth( KRB5_TGS_NAME }; krb5_get_init_creds_opt opts; + krb5_kdc_rep *as_reply = NULL; /* * "result" should not be assigned PAM_SUCCESS unless * authentication has succeeded and there are no other errors. @@ -493,7 +498,14 @@ attempt_krb5_auth( if (*krb5_pass == NULL || strlen(*krb5_pass) == 0) { code = KRB5KRB_AP_ERR_BAD_INTEGRITY; } else { - code = krb5_get_init_creds_password(kmd->kcontext, + + /* + * We call our own private version of gic_pwd, because we need + * more information, such as password/account expiration, that + * is found in the as_reply. The "prompter" interface is not + * granular enough for PAM to make use of. + */ + code = __krb5_get_init_creds_password(kmd->kcontext, my_creds, me, *krb5_pass, /* clear text passwd */ @@ -501,7 +513,8 @@ attempt_krb5_auth( NULL, /* data */ 0, /* start time */ NULL, /* defaults to krbtgt@REALM */ - &opts); + &opts, + &as_reply); } if (kmd->debug) @@ -579,6 +592,10 @@ attempt_krb5_auth( krb5_free_principal(kmd->kcontext, sp); } } + + if (code == 0) + kmd->expiration = as_reply->enc_part2->key_exp; + break; case KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN: @@ -668,6 +685,8 @@ out: krb5_free_principal(kmd->kcontext, server); if (me) krb5_free_principal(kmd->kcontext, me); + if (as_reply) + krb5_free_kdc_rep(kmd->kcontext, as_reply); if (kmd->kcontext) { krb5_free_context(kmd->kcontext); kmd->kcontext = NULL; diff --git a/usr/src/lib/pam_modules/krb5/utils.h b/usr/src/lib/pam_modules/krb5/utils.h index a976a5ced6..ddc9136d90 100644 --- a/usr/src/lib/pam_modules/krb5/utils.h +++ b/usr/src/lib/pam_modules/krb5/utils.h @@ -53,6 +53,7 @@ typedef struct { /* pam_authenticate() */ char *password; int age_status; + krb5_timestamp expiration; } krb5_module_data_t; int get_pw_uid(char *, uid_t *); diff --git a/usr/src/lib/passwdutil/nisplus_attr.c b/usr/src/lib/passwdutil/nisplus_attr.c index 518cf8fb4e..57db02ba8a 100644 --- a/usr/src/lib/passwdutil/nisplus_attr.c +++ b/usr/src/lib/passwdutil/nisplus_attr.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -1442,7 +1441,7 @@ nisplus_verify_rpc_passwd(char *name, char *oldpw, pwu_repository_t *rep) if (success_cnt) return (PWU_SUCCESS); else - return (PWU_CRED_ERROR); + return (PWU_BAD_CREDPASS); } char * |