|
|
2fc102 |
From a9278ff6f7b387c529c3b57251974403c5990d44 Mon Sep 17 00:00:00 2001
|
|
|
2fc102 |
From: Jakub Hrozek <jhrozek@redhat.com>
|
|
|
2fc102 |
Date: Tue, 18 Mar 2014 16:48:11 +0100
|
|
|
2fc102 |
Subject: [PATCH] KRB5: Do not attempt to get a TGT after a password change
|
|
|
2fc102 |
using OTP
|
|
|
2fc102 |
|
|
|
2fc102 |
https://fedorahosted.org/sssd/ticket/2271
|
|
|
2fc102 |
|
|
|
2fc102 |
The current krb5_child code attempts to get a TGT for the convenience of
|
|
|
2fc102 |
the user using the new password after a password change operation.
|
|
|
2fc102 |
However, an OTP should never be used twice, which means we can't perform
|
|
|
2fc102 |
the kinit operation after chpass is finished. Instead, we only print a
|
|
|
2fc102 |
PAM information instructing the user to log out and back in manually.
|
|
|
2fc102 |
---
|
|
|
2fc102 |
src/providers/krb5/krb5_auth.c | 21 ++++++++++++++++++---
|
|
|
2fc102 |
src/providers/krb5/krb5_child.c | 12 ++++++++++++
|
|
|
2fc102 |
src/sss_client/pam_sss.c | 19 +++++++++++++++++++
|
|
|
2fc102 |
src/sss_client/sss_cli.h | 3 +++
|
|
|
2fc102 |
4 files changed, 52 insertions(+), 3 deletions(-)
|
|
|
2fc102 |
|
|
|
2fc102 |
diff --git a/src/providers/krb5/krb5_auth.c b/src/providers/krb5/krb5_auth.c
|
|
|
2fc102 |
index ce461f5adefc6e42fdc69726ff71d23526375c0c..48c0746efc3d136a1f13e8982384d503d8d20723 100644
|
|
|
2fc102 |
--- a/src/providers/krb5/krb5_auth.c
|
|
|
2fc102 |
+++ b/src/providers/krb5/krb5_auth.c
|
|
|
2fc102 |
@@ -815,6 +815,7 @@ static void krb5_auth_done(struct tevent_req *subreq)
|
|
|
2fc102 |
char *renew_interval_str;
|
|
|
2fc102 |
time_t renew_interval_time = 0;
|
|
|
2fc102 |
bool use_enterprise_principal;
|
|
|
2fc102 |
+ uint32_t user_info_type;
|
|
|
2fc102 |
|
|
|
2fc102 |
ret = handle_child_recv(subreq, pd, &buf, &len;;
|
|
|
2fc102 |
talloc_zfree(subreq);
|
|
|
2fc102 |
@@ -1062,9 +1063,23 @@ static void krb5_auth_done(struct tevent_req *subreq)
|
|
|
2fc102 |
|
|
|
2fc102 |
ret = sss_krb5_check_ccache_princ(kr->uid, kr->gid, kr->ccname, kr->upn);
|
|
|
2fc102 |
if (ret) {
|
|
|
2fc102 |
- DEBUG(SSSDBG_CRIT_FAILURE,
|
|
|
2fc102 |
- ("No ccache for %s in %s?\n", kr->upn, kr->ccname));
|
|
|
2fc102 |
- goto done;
|
|
|
2fc102 |
+ if (res->otp == true && pd->cmd == SSS_PAM_CHAUTHTOK) {
|
|
|
2fc102 |
+ DEBUG(SSSDBG_IMPORTANT_INFO,
|
|
|
2fc102 |
+ ("Password change succeeded but currently "
|
|
|
2fc102 |
+ "post-chpass kinit is not implemented\n"));
|
|
|
2fc102 |
+
|
|
|
2fc102 |
+ user_info_type = SSS_PAM_USER_INFO_OTP_CHPASS;
|
|
|
2fc102 |
+ ret = pam_add_response(pd, SSS_PAM_USER_INFO, sizeof(uint32_t),
|
|
|
2fc102 |
+ (const uint8_t *) &user_info_type);
|
|
|
2fc102 |
+ if (ret != EOK) {
|
|
|
2fc102 |
+ DEBUG(SSSDBG_CRIT_FAILURE, ("pam_add_response failed.\n"));
|
|
|
2fc102 |
+ /* Not fatal */
|
|
|
2fc102 |
+ }
|
|
|
2fc102 |
+ } else {
|
|
|
2fc102 |
+ DEBUG(SSSDBG_CRIT_FAILURE,
|
|
|
2fc102 |
+ ("No ccache for %s in %s?\n", kr->upn, kr->ccname));
|
|
|
2fc102 |
+ goto done;
|
|
|
2fc102 |
+ }
|
|
|
2fc102 |
}
|
|
|
2fc102 |
|
|
|
2fc102 |
if (kr->old_ccname) {
|
|
|
2fc102 |
diff --git a/src/providers/krb5/krb5_child.c b/src/providers/krb5/krb5_child.c
|
|
|
2fc102 |
index d000d70167936b09bbaa39ec7a665089572d9aaa..3ee49e4678078d15dab98eeddf56d36f87955dcf 100644
|
|
|
2fc102 |
--- a/src/providers/krb5/krb5_child.c
|
|
|
2fc102 |
+++ b/src/providers/krb5/krb5_child.c
|
|
|
2fc102 |
@@ -45,6 +45,7 @@ struct krb5_req {
|
|
|
2fc102 |
krb5_principal princ;
|
|
|
2fc102 |
char* name;
|
|
|
2fc102 |
krb5_creds *creds;
|
|
|
2fc102 |
+ bool otp;
|
|
|
2fc102 |
krb5_get_init_creds_opt *options;
|
|
|
2fc102 |
|
|
|
2fc102 |
struct pam_data *pd;
|
|
|
2fc102 |
@@ -370,6 +371,8 @@ static krb5_error_code answer_otp(krb5_context ctx,
|
|
|
2fc102 |
goto done;
|
|
|
2fc102 |
}
|
|
|
2fc102 |
|
|
|
2fc102 |
+ kr->otp = true;
|
|
|
2fc102 |
+
|
|
|
2fc102 |
/* Validate our assumptions about the contents of authtok. */
|
|
|
2fc102 |
ret = sss_authtok_get_password(kr->pd->authtok, &pwd, &len;;
|
|
|
2fc102 |
if (ret != EOK)
|
|
|
2fc102 |
@@ -694,6 +697,8 @@ static errno_t k5c_send_data(struct krb5_req *kr, int fd, errno_t error)
|
|
|
2fc102 |
size_t len;
|
|
|
2fc102 |
int ret;
|
|
|
2fc102 |
|
|
|
2fc102 |
+ DEBUG(SSSDBG_FUNC_DATA, ("Received error code %d\n", error));
|
|
|
2fc102 |
+
|
|
|
2fc102 |
ret = pack_response_packet(kr, error, kr->pd->resp_list, &buf, &len;;
|
|
|
2fc102 |
if (ret != EOK) {
|
|
|
2fc102 |
DEBUG(1, ("pack_response_packet failed.\n"));
|
|
|
2fc102 |
@@ -1110,6 +1115,8 @@ static errno_t changepw_child(struct krb5_req *kr, bool prelim)
|
|
|
2fc102 |
prompter, kr, 0,
|
|
|
2fc102 |
SSSD_KRB5_CHANGEPW_PRINCIPAL,
|
|
|
2fc102 |
kr->options);
|
|
|
2fc102 |
+ DEBUG(SSSDBG_TRACE_INTERNAL,
|
|
|
2fc102 |
+ ("chpass is%s using OTP\n", kr->otp ? "" : " not"));
|
|
|
2fc102 |
if (kerr != 0) {
|
|
|
2fc102 |
ret = pack_user_info_chpass_error(kr->pd, "Old password not accepted.",
|
|
|
2fc102 |
&msg_len, &msg;;
|
|
|
2fc102 |
@@ -1205,6 +1212,11 @@ static errno_t changepw_child(struct krb5_req *kr, bool prelim)
|
|
|
2fc102 |
|
|
|
2fc102 |
krb5_free_cred_contents(kr->ctx, kr->creds);
|
|
|
2fc102 |
|
|
|
2fc102 |
+ if (kr->otp == true) {
|
|
|
2fc102 |
+ sss_authtok_set_empty(kr->pd->newauthtok);
|
|
|
2fc102 |
+ return map_krb5_error(kerr);
|
|
|
2fc102 |
+ }
|
|
|
2fc102 |
+
|
|
|
2fc102 |
/* We changed some of the gic options for the password change, now we have
|
|
|
2fc102 |
* to change them back to get a fresh TGT. */
|
|
|
2fc102 |
revert_changepw_options(kr->options);
|
|
|
2fc102 |
diff --git a/src/sss_client/pam_sss.c b/src/sss_client/pam_sss.c
|
|
|
2fc102 |
index 4ff38f299bec75a49c8aace06eecab5735ca9443..e629fc19bd705ac35c2fa1ea4946f40c5eb49079 100644
|
|
|
2fc102 |
--- a/src/sss_client/pam_sss.c
|
|
|
2fc102 |
+++ b/src/sss_client/pam_sss.c
|
|
|
2fc102 |
@@ -771,6 +771,22 @@ static int user_info_offline_chpass(pam_handle_t *pamh)
|
|
|
2fc102 |
return PAM_SUCCESS;
|
|
|
2fc102 |
}
|
|
|
2fc102 |
|
|
|
2fc102 |
+static int user_info_otp_chpass(pam_handle_t *pamh)
|
|
|
2fc102 |
+{
|
|
|
2fc102 |
+ int ret;
|
|
|
2fc102 |
+
|
|
|
2fc102 |
+ ret = do_pam_conversation(pamh, PAM_TEXT_INFO,
|
|
|
2fc102 |
+ _("After changing the OTP password, you need to "
|
|
|
2fc102 |
+ "log out and back in order to acquire a ticket"),
|
|
|
2fc102 |
+ NULL, NULL);
|
|
|
2fc102 |
+ if (ret != PAM_SUCCESS) {
|
|
|
2fc102 |
+ D(("do_pam_conversation failed."));
|
|
|
2fc102 |
+ return PAM_SYSTEM_ERR;
|
|
|
2fc102 |
+ }
|
|
|
2fc102 |
+
|
|
|
2fc102 |
+ return PAM_SUCCESS;
|
|
|
2fc102 |
+}
|
|
|
2fc102 |
+
|
|
|
2fc102 |
static int user_info_chpass_error(pam_handle_t *pamh, size_t buflen,
|
|
|
2fc102 |
uint8_t *buf)
|
|
|
2fc102 |
{
|
|
|
2fc102 |
@@ -856,6 +872,9 @@ static int eval_user_info_response(pam_handle_t *pamh, size_t buflen,
|
|
|
2fc102 |
case SSS_PAM_USER_INFO_OFFLINE_CHPASS:
|
|
|
2fc102 |
ret = user_info_offline_chpass(pamh);
|
|
|
2fc102 |
break;
|
|
|
2fc102 |
+ case SSS_PAM_USER_INFO_OTP_CHPASS:
|
|
|
2fc102 |
+ ret = user_info_otp_chpass(pamh);
|
|
|
2fc102 |
+ break;
|
|
|
2fc102 |
case SSS_PAM_USER_INFO_CHPASS_ERROR:
|
|
|
2fc102 |
ret = user_info_chpass_error(pamh, buflen, buf);
|
|
|
2fc102 |
break;
|
|
|
2fc102 |
diff --git a/src/sss_client/sss_cli.h b/src/sss_client/sss_cli.h
|
|
|
2fc102 |
index 285a2979addb0c0677527b76b3b6755f2f173815..16a08e1869bb81ede2c1db87f1fb6d0a51087847 100644
|
|
|
2fc102 |
--- a/src/sss_client/sss_cli.h
|
|
|
2fc102 |
+++ b/src/sss_client/sss_cli.h
|
|
|
2fc102 |
@@ -451,6 +451,9 @@ enum user_info_type {
|
|
|
2fc102 |
* possible to change the password while
|
|
|
2fc102 |
* the system is offline. This message
|
|
|
2fc102 |
* is generated by the PAM responder. */
|
|
|
2fc102 |
+ SSS_PAM_USER_INFO_OTP_CHPASS, /**< Tell the user that he needs to kinit
|
|
|
2fc102 |
+ * or login and logout to get a TGT after
|
|
|
2fc102 |
+ * an OTP password change */
|
|
|
2fc102 |
SSS_PAM_USER_INFO_CHPASS_ERROR, /**< Tell the user that a password change
|
|
|
2fc102 |
* failed and optionally give a reason.
|
|
|
2fc102 |
* @param Size of the message as unsigned
|
|
|
2fc102 |
--
|
|
|
2fc102 |
1.8.5.3
|
|
|
2fc102 |
|