summaryrefslogtreecommitdiff
path: root/usr/src
diff options
context:
space:
mode:
authorsemery <none@none>2007-02-13 10:15:31 -0800
committersemery <none@none>2007-02-13 10:15:31 -0800
commit3125ebfc35130d243e775dc38a6a59be4df0b137 (patch)
tree35a9f1bc94fa3d99936bd154bc74a408ae96d1ab /usr/src
parentfa871852ed0075b7564289cb07481ed343bb162f (diff)
downloadillumos-gate-3125ebfc35130d243e775dc38a6a59be4df0b137.tar.gz
6394510 error table is out of whack
6497698 krb5kdc(1) should also provide password expiration information 6497703 pam_krb5(5) should interpret the key expiration field to display expiration warning information 6514446 pam_dhkeys prompts for secure RPC password when neither LOCAL or DES credentials exist 6515558 Pre-s10 client's keytab file are generated incorrectly when auth princ == target princ 6523684 Memory rcache function doesn't acquire the right locks
Diffstat (limited to 'usr/src')
-rw-r--r--usr/src/cmd/krb5/kadmin/server/misc.c18
-rw-r--r--usr/src/cmd/krb5/kadmin/server/server_stubs.c6
-rw-r--r--usr/src/cmd/krb5/krb5kdc/do_as_req.c15
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/et/krb5_err.c88
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/krb5/krb/gic_pwd.c53
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/krb5/rcache/rc_mem.c11
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/mapfile-vers3
-rw-r--r--usr/src/lib/pam_modules/dhkeys/dhkeys.c19
-rw-r--r--usr/src/lib/pam_modules/krb5/krb5_acct_mgmt.c118
-rw-r--r--usr/src/lib/pam_modules/krb5/krb5_authenticate.c23
-rw-r--r--usr/src/lib/pam_modules/krb5/utils.h1
-rw-r--r--usr/src/lib/passwdutil/nisplus_attr.c9
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 *