Hi,
this series for patches add support for automatic Kerberos ticket
renewal, see also trac ticket #369.
There are several things I like to discuss:
- in the ticket a separate process which should handle the renewal was
mentioned. Currently the patches just create a timed task in the krb5
provider because I think most of the typically uses cases do not
justify to overhead we create with a separate process. But I'm open
for other arguments.
- I have added option to request TGT with a specific lifetime/renewal
time. The corresponding option in krb5.conf have a trailing letter
indicating the time unit. I have copied this behaviour to help
migrations although we typically use only seconds without a unit in
sssd.conf. Is this a good idea or shall I change it to seconds or do
we want to support both formats.
- Currently everything is held in RAM and after a restart nothing is
renewed automatically. I plan to send a new patch which checks all
ccfiles we have in the cache and if renewal is possible it adds them
to the list at startup. I think this approach makes more sense than
writing the list of renewable ticket to disk. Do you agree?
bye,
Sumit
From dd0b3d75426765c5c8d03852584a35a58c19d144 Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose(a)redhat.com>
Date: Mon, 8 Nov 2010 14:24:05 +0100
Subject: [PATCH 2/8] Add a renew task to krb5_child
---
src/providers/krb5/krb5_child.c | 65 +++++++++++++++++++++++++++++++++++++++
src/sss_client/sss_cli.h | 8 ++++-
2 files changed, 72 insertions(+), 1 deletions(-)
diff --git a/src/providers/krb5/krb5_child.c b/src/providers/krb5/krb5_child.c
index 5a5281a..0f729d8 100644
--- a/src/providers/krb5/krb5_child.c
+++ b/src/providers/krb5/krb5_child.c
@@ -863,6 +863,67 @@ 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;
+ }
+
+ 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 +964,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 +1079,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 f8ccb4f..223524e 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 */
};
/**
--
1.7.3.2