From 047332ebbe8397a70c92e5e3a5fbd40a9d00d0b5 Mon Sep 17 00:00:00 2001 From: Sumit Bose Date: Fri, 10 Sep 2010 14:53:50 +0200 Subject: Use new MIT krb5 API for better password expiration warnings --- src/external/krb5.m4 | 3 ++- src/providers/krb5/krb5_child.c | 51 +++++++++++++++++++++++++++++++++++++++++ src/util/sss_krb5.c | 15 +++++++++++- src/util/sss_krb5.h | 13 ++++++++++- 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 - 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 - 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__ */ -- cgit