Skip to content

Commit

Permalink
KRB5: Do not attempt to get a TGT after a password change using OTP
Browse files Browse the repository at this point in the history
https://fedorahosted.org/sssd/ticket/2271

The current krb5_child code attempts to get a TGT for the convenience of
the user using the new password after a password change operation.
However, an OTP should never be used twice, which means we can't perform
the kinit operation after chpass is finished. Instead, we only print a
PAM information instructing the user to log out and back in manually.

Reviewed-by: Alexander Bokovoy <abokovoy@redhat.com>
  • Loading branch information
jhrozek authored and sumit-bose committed Mar 26, 2014
1 parent cf13b90 commit 1c1693e
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 3 deletions.
21 changes: 18 additions & 3 deletions src/providers/krb5/krb5_auth.c
Original file line number Diff line number Diff line change
Expand Up @@ -815,6 +815,7 @@ static void krb5_auth_done(struct tevent_req *subreq)
char *renew_interval_str;
time_t renew_interval_time = 0;
bool use_enterprise_principal;
uint32_t user_info_type;

ret = handle_child_recv(subreq, pd, &buf, &len);
talloc_zfree(subreq);
Expand Down Expand Up @@ -1062,9 +1063,23 @@ static void krb5_auth_done(struct tevent_req *subreq)

ret = sss_krb5_check_ccache_princ(kr->uid, kr->gid, kr->ccname, kr->upn);
if (ret) {
DEBUG(SSSDBG_CRIT_FAILURE,
("No ccache for %s in %s?\n", kr->upn, kr->ccname));
goto done;
if (res->otp == true && pd->cmd == SSS_PAM_CHAUTHTOK) {
DEBUG(SSSDBG_IMPORTANT_INFO,
("Password change succeeded but currently "
"post-chpass kinit is not implemented\n"));

user_info_type = SSS_PAM_USER_INFO_OTP_CHPASS;
ret = pam_add_response(pd, SSS_PAM_USER_INFO, sizeof(uint32_t),
(const uint8_t *) &user_info_type);
if (ret != EOK) {
DEBUG(SSSDBG_CRIT_FAILURE, ("pam_add_response failed.\n"));
/* Not fatal */
}
} else {
DEBUG(SSSDBG_CRIT_FAILURE,
("No ccache for %s in %s?\n", kr->upn, kr->ccname));
goto done;
}
}

if (kr->old_ccname) {
Expand Down
12 changes: 12 additions & 0 deletions src/providers/krb5/krb5_child.c
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ struct krb5_req {
krb5_principal princ;
char* name;
krb5_creds *creds;
bool otp;
krb5_get_init_creds_opt *options;

struct pam_data *pd;
Expand Down Expand Up @@ -370,6 +371,8 @@ static krb5_error_code answer_otp(krb5_context ctx,
goto done;
}

kr->otp = true;

/* Validate our assumptions about the contents of authtok. */
ret = sss_authtok_get_password(kr->pd->authtok, &pwd, &len);
if (ret != EOK)
Expand Down Expand Up @@ -694,6 +697,8 @@ static errno_t k5c_send_data(struct krb5_req *kr, int fd, errno_t error)
size_t len;
int ret;

DEBUG(SSSDBG_FUNC_DATA, ("Received error code %d\n", error));

ret = pack_response_packet(kr, error, kr->pd->resp_list, &buf, &len);
if (ret != EOK) {
DEBUG(1, ("pack_response_packet failed.\n"));
Expand Down Expand Up @@ -1110,6 +1115,8 @@ static errno_t changepw_child(struct krb5_req *kr, bool prelim)
prompter, kr, 0,
SSSD_KRB5_CHANGEPW_PRINCIPAL,
kr->options);
DEBUG(SSSDBG_TRACE_INTERNAL,
("chpass is%s using OTP\n", kr->otp ? "" : " not"));
if (kerr != 0) {
ret = pack_user_info_chpass_error(kr->pd, "Old password not accepted.",
&msg_len, &msg);
Expand Down Expand Up @@ -1205,6 +1212,11 @@ static errno_t changepw_child(struct krb5_req *kr, bool prelim)

krb5_free_cred_contents(kr->ctx, kr->creds);

if (kr->otp == true) {
sss_authtok_set_empty(kr->pd->newauthtok);
return map_krb5_error(kerr);
}

/* We changed some of the gic options for the password change, now we have
* to change them back to get a fresh TGT. */
revert_changepw_options(kr->options);
Expand Down
19 changes: 19 additions & 0 deletions src/sss_client/pam_sss.c
Original file line number Diff line number Diff line change
Expand Up @@ -771,6 +771,22 @@ static int user_info_offline_chpass(pam_handle_t *pamh)
return PAM_SUCCESS;
}

static int user_info_otp_chpass(pam_handle_t *pamh)
{
int ret;

ret = do_pam_conversation(pamh, PAM_TEXT_INFO,
_("After changing the OTP password, you need to "
"log out and back in order to acquire a ticket"),
NULL, NULL);
if (ret != PAM_SUCCESS) {
D(("do_pam_conversation failed."));
return PAM_SYSTEM_ERR;
}

return PAM_SUCCESS;
}

static int user_info_chpass_error(pam_handle_t *pamh, size_t buflen,
uint8_t *buf)
{
Expand Down Expand Up @@ -856,6 +872,9 @@ static int eval_user_info_response(pam_handle_t *pamh, size_t buflen,
case SSS_PAM_USER_INFO_OFFLINE_CHPASS:
ret = user_info_offline_chpass(pamh);
break;
case SSS_PAM_USER_INFO_OTP_CHPASS:
ret = user_info_otp_chpass(pamh);
break;
case SSS_PAM_USER_INFO_CHPASS_ERROR:
ret = user_info_chpass_error(pamh, buflen, buf);
break;
Expand Down
3 changes: 3 additions & 0 deletions src/sss_client/sss_cli.h
Original file line number Diff line number Diff line change
Expand Up @@ -451,6 +451,9 @@ enum user_info_type {
* possible to change the password while
* the system is offline. This message
* is generated by the PAM responder. */
SSS_PAM_USER_INFO_OTP_CHPASS, /**< Tell the user that he needs to kinit
* or login and logout to get a TGT after
* an OTP password change */
SSS_PAM_USER_INFO_CHPASS_ERROR, /**< Tell the user that a password change
* failed and optionally give a reason.
* @param Size of the message as unsigned
Expand Down

0 comments on commit 1c1693e

Please sign in to comment.