summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorSumit Bose <sbose@redhat.com>2010-09-10 14:53:50 +0200
committerStephen Gallagher <sgallagh@redhat.com>2010-09-23 13:21:55 -0400
commit047332ebbe8397a70c92e5e3a5fbd40a9d00d0b5 (patch)
tree345ff3517c81c14b5e1591eb43764e13623f8505 /src
parenta685a84bfd4071ccdcc99dd7393d97a7a8d30a1d (diff)
downloadsssd-047332ebbe8397a70c92e5e3a5fbd40a9d00d0b5.tar.gz
sssd-047332ebbe8397a70c92e5e3a5fbd40a9d00d0b5.tar.xz
sssd-047332ebbe8397a70c92e5e3a5fbd40a9d00d0b5.zip
Use new MIT krb5 API for better password expiration warnings
Diffstat (limited to 'src')
-rw-r--r--src/external/krb5.m43
-rw-r--r--src/providers/krb5/krb5_child.c51
-rw-r--r--src/util/sss_krb5.c15
-rw-r--r--src/util/sss_krb5.h13
4 files changed, 79 insertions, 3 deletions
diff --git a/src/external/krb5.m4 b/src/external/krb5.m4
index 39c2cdfd3..d4f563fa2 100644
--- a/src/external/krb5.m4
+++ b/src/external/krb5.m4
@@ -38,7 +38,8 @@ CFLAGS="$CFLAGS $KRB5_CFLAGS"
LIBS="$LIBS $KRB5_LIBS"
AC_CHECK_HEADERS([krb5.h krb5/krb5.h])
AC_CHECK_FUNCS([krb5_get_init_creds_opt_alloc krb5_get_error_message \
- krb5_free_unparsed_name])
+ krb5_free_unparsed_name \
+ krb5_get_init_creds_opt_set_expire_callback])
CFLAGS=$SAVE_CFLAGS
LIBS=$SAVE_LIBS
diff --git a/src/providers/krb5/krb5_child.c b/src/providers/krb5/krb5_child.c
index 6892c6651..b028962a2 100644
--- a/src/providers/krb5/krb5_child.c
+++ b/src/providers/krb5/krb5_child.c
@@ -104,6 +104,43 @@ static const char *__krb5_error_msg;
sss_krb5_free_error_message(krb5_error_ctx, __krb5_error_msg); \
} while(0);
+static void sss_krb5_expire_callback_func(krb5_context context, void *data,
+ krb5_timestamp password_expiration,
+ krb5_timestamp account_expiration,
+ krb5_boolean is_last_req)
+{
+ int ret;
+ uint32_t *blob;
+ long exp_time;
+ struct krb5_req *kr = talloc_get_type(data, struct krb5_req);
+
+ if (password_expiration == 0) {
+ return;
+ }
+
+ exp_time = password_expiration - time(NULL);
+ if (exp_time < 0 || exp_time > UINT32_MAX) {
+ DEBUG(1, ("Time to expire out of range.\n"));
+ return;
+ }
+
+ blob = talloc_array(kr->pd, uint32_t, 2);
+ if (blob == NULL) {
+ DEBUG(1, ("talloc_size failed.\n"));
+ return;
+ }
+
+ blob[0] = SSS_PAM_USER_INFO_EXPIRE_WARN;
+ blob[1] = (uint32_t) exp_time;
+
+ ret = pam_add_response(kr->pd, SSS_PAM_USER_INFO, 2 * sizeof(uint32_t),
+ (uint8_t *) blob);
+ if (ret != EOK) {
+ DEBUG(1, ("pam_add_response failed.\n"));
+ }
+
+ return;
+}
static krb5_error_code sss_krb5_prompter(krb5_context context, void *data,
const char *name, const char *banner,
@@ -516,6 +553,13 @@ static krb5_error_code get_and_save_tgt(struct krb5_req *kr,
krb5_error_code kerr = 0;
int ret;
+ kerr = sss_krb5_get_init_creds_opt_set_expire_callback(kr->ctx, kr->options,
+ sss_krb5_expire_callback_func,
+ kr);
+ if (kerr != 0) {
+ KRB5_DEBUG(1, kerr);
+ DEBUG(1, ("Failed to set expire callback, continue without.\n"));
+ }
kerr = krb5_get_init_creds_password(kr->ctx, kr->creds, kr->princ,
password, sss_krb5_prompter, kr, 0,
NULL, kr->options);
@@ -737,6 +781,13 @@ static errno_t tgt_req_child(int fd, struct krb5_req *kr)
not. In general the password can still be used to get a changepw ticket.
So we validate the password by trying to get a changepw ticket. */
if (kerr == KRB5KDC_ERR_KEY_EXP) {
+ kerr = sss_krb5_get_init_creds_opt_set_expire_callback(kr->ctx,
+ kr->options,
+ NULL, NULL);
+ if (kerr != 0) {
+ KRB5_DEBUG(1, kerr);
+ DEBUG(1, ("Failed to unset expire callback, continue ...\n"));
+ }
kerr = krb5_get_init_creds_password(kr->ctx, kr->creds, kr->princ,
pass_str, sss_krb5_prompter, kr, 0,
changepw_princ,
diff --git a/src/util/sss_krb5.c b/src/util/sss_krb5.c
index bbb62f11a..5cf91f174 100644
--- a/src/util/sss_krb5.c
+++ b/src/util/sss_krb5.c
@@ -2,7 +2,7 @@
Authors:
Sumit Bose <sbose@redhat.com>
- Copyright (C) 2009 Red Hat
+ Copyright (C) 2009-2010 Red Hat
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -347,3 +347,16 @@ done:
return krberr;
}
+krb5_error_code KRB5_CALLCONV sss_krb5_get_init_creds_opt_set_expire_callback(
+ krb5_context context,
+ krb5_get_init_creds_opt *opt,
+ krb5_expire_callback_func cb,
+ void *data)
+{
+#ifdef HAVE_KRB5_GET_INIT_CREDS_OPT_SET_EXPIRE_CALLBACK
+ return krb5_get_init_creds_opt_set_expire_callback(context, opt, cb, data);
+#else
+ DEBUG(5, ("krb5_get_init_creds_opt_set_expire_callback not available.\n"));
+ return 0;
+#endif
+}
diff --git a/src/util/sss_krb5.h b/src/util/sss_krb5.h
index bc7a4f8a2..cf6fedafb 100644
--- a/src/util/sss_krb5.h
+++ b/src/util/sss_krb5.h
@@ -2,7 +2,7 @@
Authors:
Sumit Bose <sbose@redhat.com>
- Copyright (C) 2009 Red Hat
+ Copyright (C) 2009-2010 Red Hat
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -56,4 +56,15 @@ int sss_krb5_verify_keytab(const char *principal,
int sss_krb5_verify_keytab_ex(const char *principal, const char *keytab_name,
krb5_context context, krb5_keytab keytab);
+#ifndef HAVE_KRB5_GET_INIT_CREDS_OPT_SET_EXPIRE_CALLBACK
+typedef void krb5_expire_callback_func(krb5_context context, void *data,
+ krb5_timestamp password_expiration,
+ krb5_timestamp account_expiration,
+ krb5_boolean is_last_req);
+#endif
+krb5_error_code KRB5_CALLCONV sss_krb5_get_init_creds_opt_set_expire_callback(
+ krb5_context context,
+ krb5_get_init_creds_opt *opt,
+ krb5_expire_callback_func cb,
+ void *data);
#endif /* __SSS_KRB5_H__ */