From 436cf4c15b7659b21205affd6743aa6159c55b5c Mon Sep 17 00:00:00 2001 From: Jakub Hrozek Date: Wed, 28 Aug 2019 14:22:49 +0200 Subject: [PATCH 54/55] KCM: Allow modifications of ccache's principal MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Related: https://pagure.io/SSSD/sssd/issue/4017 This patch will be useful to fix credential delegation. Reviewed-by: Michal Židek --- src/responder/kcm/kcmsrv_ccache.c | 37 +++++++++++++++++++++-- src/responder/kcm/kcmsrv_ccache.h | 5 +-- src/responder/kcm/kcmsrv_ccache_mem.c | 8 ++++- src/responder/kcm/kcmsrv_ccache_secdb.c | 8 ++++- src/responder/kcm/kcmsrv_ccache_secrets.c | 9 +++++- src/responder/kcm/kcmsrv_ops.c | 4 +-- 6 files changed, 60 insertions(+), 11 deletions(-) diff --git a/src/responder/kcm/kcmsrv_ccache.c b/src/responder/kcm/kcmsrv_ccache.c index 085cc4464..e24da9aa2 100644 --- a/src/responder/kcm/kcmsrv_ccache.c +++ b/src/responder/kcm/kcmsrv_ccache.c @@ -1089,25 +1089,56 @@ errno_t kcm_ccdb_create_cc_recv(struct tevent_req *req) return EOK; } -void kcm_mod_ctx_clear(struct kcm_mod_ctx *mod_ctx) +static void kcm_mod_ctx_clear(struct kcm_mod_ctx *mod_ctx) { if (mod_ctx == NULL) { return; } mod_ctx->kdc_offset = INT32_MAX; + if (mod_ctx->client != NULL) { + krb5_free_principal(NULL, mod_ctx->client); + mod_ctx->client = NULL; + } + + return; +} + +struct kcm_mod_ctx *kcm_mod_ctx_new(TALLOC_CTX *mem_ctx) +{ + struct kcm_mod_ctx *mod_ctx; + + mod_ctx = talloc_zero(mem_ctx, struct kcm_mod_ctx); + if (mod_ctx == NULL) { + return NULL; + } + + kcm_mod_ctx_clear(mod_ctx); + return mod_ctx; } -void kcm_mod_cc(struct kcm_ccache *cc, struct kcm_mod_ctx *mod_ctx) +errno_t kcm_mod_cc(struct kcm_ccache *cc, struct kcm_mod_ctx *mod_ctx) { if (cc == NULL || mod_ctx == NULL) { - return; + return EINVAL; } if (mod_ctx->kdc_offset != INT32_MAX) { cc->kdc_offset = mod_ctx->kdc_offset; } + if (mod_ctx->client != NULL) { + krb5_error_code kret; + + kret = krb5_copy_principal(NULL, mod_ctx->client, &cc->client); + if (kret != 0) { + DEBUG(SSSDBG_OP_FAILURE, + "krb5_copy_principal failed: %d\n", kret); + return ERR_INTERNAL; + } + } + + return EOK; } struct kcm_ccdb_mod_cc_state { diff --git a/src/responder/kcm/kcmsrv_ccache.h b/src/responder/kcm/kcmsrv_ccache.h index 199b75b16..220220ca9 100644 --- a/src/responder/kcm/kcmsrv_ccache.h +++ b/src/responder/kcm/kcmsrv_ccache.h @@ -257,13 +257,14 @@ errno_t kcm_ccdb_create_cc_recv(struct tevent_req *req); */ struct kcm_mod_ctx { int32_t kdc_offset; + krb5_principal client; /* More settable properties (like name, when we support renames * will be added later */ }; -void kcm_mod_ctx_clear(struct kcm_mod_ctx *mod_ctx); -void kcm_mod_cc(struct kcm_ccache *cc, struct kcm_mod_ctx *mod_ctx); +struct kcm_mod_ctx *kcm_mod_ctx_new(TALLOC_CTX *mem_ctx); +errno_t kcm_mod_cc(struct kcm_ccache *cc, struct kcm_mod_ctx *mod_ctx); struct tevent_req *kcm_ccdb_mod_cc_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, diff --git a/src/responder/kcm/kcmsrv_ccache_mem.c b/src/responder/kcm/kcmsrv_ccache_mem.c index 35955b2f4..18c3878ad 100644 --- a/src/responder/kcm/kcmsrv_ccache_mem.c +++ b/src/responder/kcm/kcmsrv_ccache_mem.c @@ -676,7 +676,13 @@ static struct tevent_req *ccdb_mem_mod_send(TALLOC_CTX *mem_ctx, goto immediate; } - kcm_mod_cc(ccwrap->cc, mod_cc); + ret = kcm_mod_cc(ccwrap->cc, mod_cc); + if (ret != EOK) { + DEBUG(SSSDBG_OP_FAILURE, + "Cannot modify ccache [%d]: %s\n", + ret, sss_strerror(ret)); + goto immediate; + } ret = EOK; immediate: diff --git a/src/responder/kcm/kcmsrv_ccache_secdb.c b/src/responder/kcm/kcmsrv_ccache_secdb.c index 26ee1032d..32137a66e 100644 --- a/src/responder/kcm/kcmsrv_ccache_secdb.c +++ b/src/responder/kcm/kcmsrv_ccache_secdb.c @@ -1290,7 +1290,13 @@ static struct tevent_req *ccdb_secdb_mod_send(TALLOC_CTX *mem_ctx, goto immediate; } - kcm_mod_cc(cc, mod_cc); + ret = kcm_mod_cc(cc, mod_cc); + if (ret != EOK) { + DEBUG(SSSDBG_OP_FAILURE, + "Cannot modify ccache [%d]: %s\n", + ret, sss_strerror(ret)); + goto immediate; + } ret = kcm_ccache_to_sec_input(state, cc, client, &payload); if (ret != EOK) { diff --git a/src/responder/kcm/kcmsrv_ccache_secrets.c b/src/responder/kcm/kcmsrv_ccache_secrets.c index 7b019fded..83c16974d 100644 --- a/src/responder/kcm/kcmsrv_ccache_secrets.c +++ b/src/responder/kcm/kcmsrv_ccache_secrets.c @@ -1846,7 +1846,14 @@ static void ccdb_sec_mod_cred_get_done(struct tevent_req *subreq) return; } - kcm_mod_cc(cc, state->mod_cc); + ret = kcm_mod_cc(cc, state->mod_cc); + if (ret != EOK) { + DEBUG(SSSDBG_OP_FAILURE, + "Cannot modify ccache [%d]: %s\n", + ret, sss_strerror(ret)); + tevent_req_error(req, ret); + return; + } ret = kcm_ccache_to_sec_kv(state, cc, state->client, &url, &payload); if (ret != EOK) { diff --git a/src/responder/kcm/kcmsrv_ops.c b/src/responder/kcm/kcmsrv_ops.c index d8a7b03c5..8bd63165b 100644 --- a/src/responder/kcm/kcmsrv_ops.c +++ b/src/responder/kcm/kcmsrv_ops.c @@ -1990,13 +1990,11 @@ static void kcm_op_set_kdc_offset_getbyname_done(struct tevent_req *subreq) return; } - mod_ctx = talloc(state, struct kcm_mod_ctx); + mod_ctx = kcm_mod_ctx_new(state); if (mod_ctx == NULL) { tevent_req_error(req, ENOMEM); return; } - - kcm_mod_ctx_clear(mod_ctx); mod_ctx->kdc_offset = be32toh(offset_be); subreq = kcm_ccdb_mod_cc_send(state, -- 2.20.1