diff options
-rw-r--r-- | src/providers/krb5/krb5_child.c | 87 | ||||
-rw-r--r-- | src/sss_client/sss_cli.h | 8 |
2 files changed, 94 insertions, 1 deletions
diff --git a/src/providers/krb5/krb5_child.c b/src/providers/krb5/krb5_child.c index 5a5281a3..c4af471d 100644 --- a/src/providers/krb5/krb5_child.c +++ b/src/providers/krb5/krb5_child.c @@ -863,6 +863,89 @@ static errno_t kuserok_child(int fd, struct krb5_req *kr) return ret; } +static errno_t renew_tgt_child(int fd, struct krb5_req *kr) +{ + int ret; + int status = PAM_AUTHTOK_ERR; + int kerr; + char *ccname; + krb5_ccache ccache = NULL; + + if (kr->pd->authtok_type != SSS_AUTHTOK_TYPE_CCFILE) { + DEBUG(1, ("Unsupported authtok type for TGT renewal [%d].\n", + kr->pd->authtok_type)); + goto done; + } + + ccname = talloc_strndup(kr, (char *) kr->pd->authtok, kr->pd->authtok_size); + if (ccname == NULL) { + DEBUG(1, ("talloc_strndup failed.\n")); + goto done; + } + + kerr = krb5_cc_resolve(kr->ctx, ccname, &ccache); + if (kerr != 0) { + KRB5_DEBUG(1, kerr); + goto done; + } + + kerr = krb5_get_renewed_creds(kr->ctx, kr->creds, kr->princ, ccache, NULL); + if (kerr != 0) { + KRB5_DEBUG(1, kerr); + goto done; + } + + if (kr->validate) { + kerr = validate_tgt(kr); + if (kerr != 0) { + KRB5_DEBUG(1, kerr); + goto done; + } + + } else { + DEBUG(9, ("TGT validation is disabled.\n")); + } + + if (kr->validate) { + /* We drop root privileges which were needed to read the keytab file + * for the validation of the credentials or for FAST here to run the + * ccache I/O operations with user privileges. */ + ret = become_user(kr->uid, kr->gid); + if (ret != EOK) { + DEBUG(1, ("become_user failed.\n")); + goto done; + } + } + + kerr = krb5_cc_initialize(kr->ctx, ccache, kr->princ); + if (kerr != 0) { + KRB5_DEBUG(1, kerr); + goto done; + } + + kerr = krb5_cc_store_cred(kr->ctx, ccache, kr->creds); + if (kerr != 0) { + KRB5_DEBUG(1, kerr); + goto done; + } + + status = PAM_SUCCESS; + +done: + krb5_free_cred_contents(kr->ctx, kr->creds); + + if (ccache != NULL) { + krb5_cc_close(kr->ctx, ccache); + } + + ret = sendresponse(fd, 0, status, kr); + if (ret != EOK) { + DEBUG(1, ("sendresponse failed.\n")); + } + + return ret; +} + static errno_t create_empty_ccache(int fd, struct krb5_req *kr) { int ret; @@ -903,6 +986,7 @@ static errno_t unpack_buffer(uint8_t *buf, size_t size, struct pam_data *pd, p += len; if (pd->cmd == SSS_PAM_AUTHENTICATE || + pd->cmd == SSS_CMD_RENEW || pd->cmd == SSS_PAM_CHAUTHTOK_PRELIM || pd->cmd == SSS_PAM_CHAUTHTOK) { SAFEALIGN_COPY_UINT32_CHECK(&len, buf + p, size, &p); if ((p + len ) > size) return EINVAL; @@ -1017,6 +1101,9 @@ static int krb5_child_setup(struct krb5_req *kr, uint32_t offline) case SSS_PAM_ACCT_MGMT: kr->child_req = kuserok_child; break; + case SSS_CMD_RENEW: + kr->child_req = renew_tgt_child; + break; default: DEBUG(1, ("PAM command [%d] not supported.\n", kr->pd->cmd)); kerr = EINVAL; diff --git a/src/sss_client/sss_cli.h b/src/sss_client/sss_cli.h index b0521067..7f579da6 100644 --- a/src/sss_client/sss_cli.h +++ b/src/sss_client/sss_cli.h @@ -181,7 +181,9 @@ enum sss_cli_command { * operation where the PAM_PRELIM_CHECK * flag is set, see pam_sm_chauthtok(3) * for details */ - + SSS_CMD_RENEW = 0x00F8, /**< Renew a credential with a limited + * lifetime, e.g. a Kerberos Ticket + * Granting Ticket (TGT) */ }; /** @@ -228,6 +230,10 @@ enum sss_authtok_type { SSS_AUTHTOK_TYPE_PASSWORD = 0x0001, /**< Authentication token is a * password, it may or may no contain * a trailing \\0 */ + SSS_AUTHTOK_TYPE_CCFILE = 0x0002, /**< Authentication token is a path to + * a Kerberos credential cache file, + * it may or may no contain + * a trailing \\0 */ }; /** |