|
|
71e593 |
From d0eae0598cfb37e1e5aca10a0827b912f707d783 Mon Sep 17 00:00:00 2001
|
|
|
71e593 |
From: Jakub Hrozek <jhrozek@redhat.com>
|
|
|
71e593 |
Date: Wed, 16 Jan 2019 13:06:15 +0100
|
|
|
71e593 |
Subject: [PATCH 98/99] KCM: Create an empty ccache on switch to a non-existing
|
|
|
71e593 |
one
|
|
|
71e593 |
MIME-Version: 1.0
|
|
|
71e593 |
Content-Type: text/plain; charset=UTF-8
|
|
|
71e593 |
Content-Transfer-Encoding: 8bit
|
|
|
71e593 |
|
|
|
71e593 |
Related:
|
|
|
71e593 |
https://pagure.io/SSSD/sssd/issue/3873
|
|
|
71e593 |
|
|
|
71e593 |
We need to make it possible to create an internal ccache representation
|
|
|
71e593 |
without passing in a principal. The principal is only assigned to the
|
|
|
71e593 |
ccache with krb5_cc_initialize(), but some programs like openssh use the
|
|
|
71e593 |
following sequence of calls:
|
|
|
71e593 |
cc = krb5_cc_new_unique
|
|
|
71e593 |
krb5_cc_switch(cc)
|
|
|
71e593 |
krb5_cc_initialize(cc, principal)
|
|
|
71e593 |
|
|
|
71e593 |
Since switch changes the default ccache, we create a 'dummy' ccache with
|
|
|
71e593 |
krb5_cc_switch() and then the initialize call just fills in the details.
|
|
|
71e593 |
|
|
|
71e593 |
Reviewed-by: Simo Sorce <simo@redhat.com>
|
|
|
71e593 |
Reviewed-by: Michal Židek <mzidek@redhat.com>
|
|
|
71e593 |
---
|
|
|
71e593 |
src/responder/kcm/kcmsrv_ops.c | 133 +++++++++++++++++++++++++++++----
|
|
|
71e593 |
1 file changed, 118 insertions(+), 15 deletions(-)
|
|
|
71e593 |
|
|
|
71e593 |
diff --git a/src/responder/kcm/kcmsrv_ops.c b/src/responder/kcm/kcmsrv_ops.c
|
|
|
71e593 |
index 60b5677e9..6544c4ed0 100644
|
|
|
71e593 |
--- a/src/responder/kcm/kcmsrv_ops.c
|
|
|
71e593 |
+++ b/src/responder/kcm/kcmsrv_ops.c
|
|
|
71e593 |
@@ -1601,8 +1601,21 @@ static errno_t kcm_op_get_default_ccache_recv(struct tevent_req *req,
|
|
|
71e593 |
|
|
|
71e593 |
/* (name) -> () */
|
|
|
71e593 |
static void kcm_op_set_default_ccache_getbyname_done(struct tevent_req *subreq);
|
|
|
71e593 |
+static void kcm_op_set_default_create_step(struct tevent_req *req);
|
|
|
71e593 |
+static void kcm_op_set_default_create_step_done(struct tevent_req *subreq);
|
|
|
71e593 |
+static void kcm_op_set_default_step(struct tevent_req *req);
|
|
|
71e593 |
static void kcm_op_set_default_done(struct tevent_req *subreq);
|
|
|
71e593 |
|
|
|
71e593 |
+struct kcm_op_set_default_ccache_state {
|
|
|
71e593 |
+ uint32_t op_ret;
|
|
|
71e593 |
+ struct kcm_op_ctx *op_ctx;
|
|
|
71e593 |
+ struct tevent_context *ev;
|
|
|
71e593 |
+
|
|
|
71e593 |
+ const char *name;
|
|
|
71e593 |
+ uuid_t dfl_uuid;
|
|
|
71e593 |
+ struct kcm_ccache *new_cc;
|
|
|
71e593 |
+};
|
|
|
71e593 |
+
|
|
|
71e593 |
static struct tevent_req *
|
|
|
71e593 |
kcm_op_set_default_ccache_send(TALLOC_CTX *mem_ctx,
|
|
|
71e593 |
struct tevent_context *ev,
|
|
|
71e593 |
@@ -1610,30 +1623,31 @@ kcm_op_set_default_ccache_send(TALLOC_CTX *mem_ctx,
|
|
|
71e593 |
{
|
|
|
71e593 |
struct tevent_req *req = NULL;
|
|
|
71e593 |
struct tevent_req *subreq = NULL;
|
|
|
71e593 |
- struct kcm_op_common_state *state = NULL;
|
|
|
71e593 |
+ struct kcm_op_set_default_ccache_state *state = NULL;
|
|
|
71e593 |
errno_t ret;
|
|
|
71e593 |
- const char *name;
|
|
|
71e593 |
|
|
|
71e593 |
- req = tevent_req_create(mem_ctx, &state, struct kcm_op_common_state);
|
|
|
71e593 |
+ req = tevent_req_create(mem_ctx,
|
|
|
71e593 |
+ &state,
|
|
|
71e593 |
+ struct kcm_op_set_default_ccache_state);
|
|
|
71e593 |
if (req == NULL) {
|
|
|
71e593 |
return NULL;
|
|
|
71e593 |
}
|
|
|
71e593 |
state->op_ctx = op_ctx;
|
|
|
71e593 |
state->ev = ev;
|
|
|
71e593 |
|
|
|
71e593 |
- ret = sss_iobuf_read_stringz(op_ctx->input, &name);
|
|
|
71e593 |
+ ret = sss_iobuf_read_stringz(op_ctx->input, &state->name);
|
|
|
71e593 |
if (ret != EOK) {
|
|
|
71e593 |
DEBUG(SSSDBG_CRIT_FAILURE,
|
|
|
71e593 |
"Cannot read input name [%d]: %s\n",
|
|
|
71e593 |
ret, sss_strerror(ret));
|
|
|
71e593 |
goto immediate;
|
|
|
71e593 |
}
|
|
|
71e593 |
- DEBUG(SSSDBG_TRACE_LIBS, "Setting default ccache %s\n", name);
|
|
|
71e593 |
+ DEBUG(SSSDBG_TRACE_LIBS, "Setting default ccache %s\n", state->name);
|
|
|
71e593 |
|
|
|
71e593 |
subreq = kcm_ccdb_uuid_by_name_send(state, ev,
|
|
|
71e593 |
op_ctx->kcm_data->db,
|
|
|
71e593 |
op_ctx->client,
|
|
|
71e593 |
- name);
|
|
|
71e593 |
+ state->name);
|
|
|
71e593 |
if (subreq == NULL) {
|
|
|
71e593 |
ret = ENOMEM;
|
|
|
71e593 |
goto immediate;
|
|
|
71e593 |
@@ -1652,13 +1666,16 @@ static void kcm_op_set_default_ccache_getbyname_done(struct tevent_req *subreq)
|
|
|
71e593 |
errno_t ret;
|
|
|
71e593 |
struct tevent_req *req = tevent_req_callback_data(subreq,
|
|
|
71e593 |
struct tevent_req);
|
|
|
71e593 |
- struct kcm_op_common_state *state = tevent_req_data(req,
|
|
|
71e593 |
- struct kcm_op_common_state);
|
|
|
71e593 |
- uuid_t dfl_uuid;
|
|
|
71e593 |
+ struct kcm_op_set_default_ccache_state *state = tevent_req_data(req,
|
|
|
71e593 |
+ struct kcm_op_set_default_ccache_state);
|
|
|
71e593 |
|
|
|
71e593 |
- ret = kcm_ccdb_uuid_by_name_recv(subreq, state, dfl_uuid);
|
|
|
71e593 |
+ ret = kcm_ccdb_uuid_by_name_recv(subreq, state, state->dfl_uuid);
|
|
|
71e593 |
talloc_zfree(subreq);
|
|
|
71e593 |
- if (ret != EOK) {
|
|
|
71e593 |
+ if (ret == ERR_NO_CREDS) {
|
|
|
71e593 |
+ DEBUG(SSSDBG_TRACE_LIBS,
|
|
|
71e593 |
+ "The ccache does not exist, creating a new one\n");
|
|
|
71e593 |
+ kcm_op_set_default_create_step(req);
|
|
|
71e593 |
+ } else if (ret != EOK) {
|
|
|
71e593 |
DEBUG(SSSDBG_OP_FAILURE,
|
|
|
71e593 |
"Cannot get ccache by name [%d]: %s\n",
|
|
|
71e593 |
ret, sss_strerror(ret));
|
|
|
71e593 |
@@ -1666,11 +1683,91 @@ static void kcm_op_set_default_ccache_getbyname_done(struct tevent_req *subreq)
|
|
|
71e593 |
return;
|
|
|
71e593 |
}
|
|
|
71e593 |
|
|
|
71e593 |
+ kcm_op_set_default_step(req);
|
|
|
71e593 |
+}
|
|
|
71e593 |
+
|
|
|
71e593 |
+static void kcm_op_set_default_create_step(struct tevent_req *req)
|
|
|
71e593 |
+{
|
|
|
71e593 |
+ errno_t ret;
|
|
|
71e593 |
+ struct tevent_req *subreq;
|
|
|
71e593 |
+ struct kcm_op_set_default_ccache_state *state = tevent_req_data(req,
|
|
|
71e593 |
+ struct kcm_op_set_default_ccache_state);
|
|
|
71e593 |
+
|
|
|
71e593 |
+ /* Only allow to create ccaches for 'self' */
|
|
|
71e593 |
+ ret = kcm_check_name(state->name, state->op_ctx->client);
|
|
|
71e593 |
+ if (ret != EOK) {
|
|
|
71e593 |
+ DEBUG(SSSDBG_CRIT_FAILURE,
|
|
|
71e593 |
+ "Name %s is malformed [%d]: %s\n",
|
|
|
71e593 |
+ state->name, ret, sss_strerror(ret));
|
|
|
71e593 |
+ tevent_req_error(req, ret);
|
|
|
71e593 |
+ return;
|
|
|
71e593 |
+ }
|
|
|
71e593 |
+
|
|
|
71e593 |
+ ret = kcm_cc_new(state->op_ctx,
|
|
|
71e593 |
+ state->op_ctx->kcm_data->k5c,
|
|
|
71e593 |
+ state->op_ctx->client,
|
|
|
71e593 |
+ state->name,
|
|
|
71e593 |
+ NULL,
|
|
|
71e593 |
+ &state->new_cc);
|
|
|
71e593 |
+ if (ret != EOK) {
|
|
|
71e593 |
+ DEBUG(SSSDBG_OP_FAILURE,
|
|
|
71e593 |
+ "Cannot create new ccache %d: %s\n", ret, sss_strerror(ret));
|
|
|
71e593 |
+ tevent_req_error(req, ret);
|
|
|
71e593 |
+ return;
|
|
|
71e593 |
+ }
|
|
|
71e593 |
+
|
|
|
71e593 |
+ subreq = kcm_ccdb_create_cc_send(state,
|
|
|
71e593 |
+ state->ev,
|
|
|
71e593 |
+ state->op_ctx->kcm_data->db,
|
|
|
71e593 |
+ state->op_ctx->client,
|
|
|
71e593 |
+ state->new_cc);
|
|
|
71e593 |
+ if (subreq == NULL) {
|
|
|
71e593 |
+ tevent_req_error(req, ENOMEM);
|
|
|
71e593 |
+ return;
|
|
|
71e593 |
+ }
|
|
|
71e593 |
+ tevent_req_set_callback(subreq, kcm_op_set_default_create_step_done, req);
|
|
|
71e593 |
+}
|
|
|
71e593 |
+
|
|
|
71e593 |
+static void kcm_op_set_default_create_step_done(struct tevent_req *subreq)
|
|
|
71e593 |
+{
|
|
|
71e593 |
+ errno_t ret;
|
|
|
71e593 |
+ struct tevent_req *req = tevent_req_callback_data(subreq,
|
|
|
71e593 |
+ struct tevent_req);
|
|
|
71e593 |
+ struct kcm_op_set_default_ccache_state *state = tevent_req_data(req,
|
|
|
71e593 |
+ struct kcm_op_set_default_ccache_state);
|
|
|
71e593 |
+
|
|
|
71e593 |
+ ret = kcm_ccdb_create_cc_recv(subreq);
|
|
|
71e593 |
+ talloc_zfree(subreq);
|
|
|
71e593 |
+ if (ret != EOK) {
|
|
|
71e593 |
+ DEBUG(SSSDBG_OP_FAILURE,
|
|
|
71e593 |
+ "Cannot add ccache to db %d: %s\n", ret, sss_strerror(ret));
|
|
|
71e593 |
+ tevent_req_error(req, ret);
|
|
|
71e593 |
+ return;
|
|
|
71e593 |
+ }
|
|
|
71e593 |
+
|
|
|
71e593 |
+ ret = kcm_cc_get_uuid(state->new_cc, state->dfl_uuid);
|
|
|
71e593 |
+ if (ret != EOK) {
|
|
|
71e593 |
+ DEBUG(SSSDBG_OP_FAILURE,
|
|
|
71e593 |
+ "Cannot get new ccache UUID [%d]: %s\n",
|
|
|
71e593 |
+ ret, sss_strerror(ret));
|
|
|
71e593 |
+ tevent_req_error(req, ret);
|
|
|
71e593 |
+ return;
|
|
|
71e593 |
+ }
|
|
|
71e593 |
+
|
|
|
71e593 |
+ kcm_op_set_default_step(req);
|
|
|
71e593 |
+}
|
|
|
71e593 |
+
|
|
|
71e593 |
+static void kcm_op_set_default_step(struct tevent_req *req)
|
|
|
71e593 |
+{
|
|
|
71e593 |
+ struct kcm_op_set_default_ccache_state *state = tevent_req_data(req,
|
|
|
71e593 |
+ struct kcm_op_set_default_ccache_state);
|
|
|
71e593 |
+ struct tevent_req *subreq;
|
|
|
71e593 |
+
|
|
|
71e593 |
subreq = kcm_ccdb_set_default_send(state,
|
|
|
71e593 |
state->ev,
|
|
|
71e593 |
state->op_ctx->kcm_data->db,
|
|
|
71e593 |
state->op_ctx->client,
|
|
|
71e593 |
- dfl_uuid);
|
|
|
71e593 |
+ state->dfl_uuid);
|
|
|
71e593 |
if (subreq == NULL) {
|
|
|
71e593 |
tevent_req_error(req, ENOMEM);
|
|
|
71e593 |
return;
|
|
|
71e593 |
@@ -1684,8 +1781,8 @@ static void kcm_op_set_default_done(struct tevent_req *subreq)
|
|
|
71e593 |
errno_t ret;
|
|
|
71e593 |
struct tevent_req *req = tevent_req_callback_data(subreq,
|
|
|
71e593 |
struct tevent_req);
|
|
|
71e593 |
- struct kcm_op_common_state *state = tevent_req_data(req,
|
|
|
71e593 |
- struct kcm_op_common_state);
|
|
|
71e593 |
+ struct kcm_op_set_default_ccache_state *state = tevent_req_data(req,
|
|
|
71e593 |
+ struct kcm_op_set_default_ccache_state);
|
|
|
71e593 |
|
|
|
71e593 |
ret = kcm_ccdb_set_default_recv(subreq);
|
|
|
71e593 |
talloc_zfree(subreq);
|
|
|
71e593 |
@@ -1700,6 +1797,12 @@ static void kcm_op_set_default_done(struct tevent_req *subreq)
|
|
|
71e593 |
tevent_req_done(req);
|
|
|
71e593 |
}
|
|
|
71e593 |
|
|
|
71e593 |
+static errno_t kcm_op_set_default_ccache_recv(struct tevent_req *req,
|
|
|
71e593 |
+ uint32_t *_op_ret)
|
|
|
71e593 |
+{
|
|
|
71e593 |
+ KCM_OP_RET_FROM_TYPE(req, struct kcm_op_set_default_ccache_state, _op_ret);
|
|
|
71e593 |
+}
|
|
|
71e593 |
+
|
|
|
71e593 |
/* (name) -> (offset) */
|
|
|
71e593 |
static void kcm_op_get_kdc_offset_getbyname_done(struct tevent_req *subreq);
|
|
|
71e593 |
|
|
|
71e593 |
@@ -1948,7 +2051,7 @@ static struct kcm_op kcm_optable[] = {
|
|
|
71e593 |
{ "GET_CACHE_UUID_LIST", kcm_op_get_cache_uuid_list_send, NULL },
|
|
|
71e593 |
{ "GET_CACHE_BY_UUID", kcm_op_get_cache_by_uuid_send, NULL },
|
|
|
71e593 |
{ "GET_DEFAULT_CACHE", kcm_op_get_default_ccache_send, kcm_op_get_default_ccache_recv },
|
|
|
71e593 |
- { "SET_DEFAULT_CACHE", kcm_op_set_default_ccache_send, NULL },
|
|
|
71e593 |
+ { "SET_DEFAULT_CACHE", kcm_op_set_default_ccache_send, kcm_op_set_default_ccache_recv },
|
|
|
71e593 |
{ "GET_KDC_OFFSET", kcm_op_get_kdc_offset_send, NULL },
|
|
|
71e593 |
{ "SET_KDC_OFFSET", kcm_op_set_kdc_offset_send, kcm_op_set_kdc_offset_recv },
|
|
|
71e593 |
{ "ADD_NTLM_CRED", NULL, NULL },
|
|
|
71e593 |
--
|
|
|
71e593 |
2.19.1
|
|
|
71e593 |
|