552 lines
18 KiB
Diff
552 lines
18 KiB
Diff
From 9ffc2c6447f2177ff406a9f4d17d8413967ab7ad Mon Sep 17 00:00:00 2001
|
|
From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <pbrezina@redhat.com>
|
|
Date: Mon, 19 Oct 2020 12:40:07 +0200
|
|
Subject: [PATCH 15/19] kcm: store credentials list in hash table to avoid
|
|
cache lookups
|
|
|
|
Iteration over ccache requires CRED_UUID_LIST and then calling
|
|
CRED_BY_UUID for each uuid in the obtained list. Each CRED_BY_UUID
|
|
operation invoked ldb_search and decryption. This was a substantional
|
|
bottle neck.
|
|
|
|
Resolves: https://github.com/SSSD/sssd/issues/5349
|
|
|
|
:fixes: KCM performance has improved dramatically for cases where
|
|
large amount of credentials are stored in the ccache.
|
|
---
|
|
src/responder/kcm/kcmsrv_ccache.c | 46 +++++
|
|
src/responder/kcm/kcmsrv_ccache.h | 7 +
|
|
src/responder/kcm/kcmsrv_ccache_mem.c | 30 ++--
|
|
src/responder/kcm/kcmsrv_ops.c | 245 +++++++++++++++++++-------
|
|
src/responder/kcm/kcmsrv_ops.h | 5 +-
|
|
5 files changed, 249 insertions(+), 84 deletions(-)
|
|
|
|
diff --git a/src/responder/kcm/kcmsrv_ccache.c b/src/responder/kcm/kcmsrv_ccache.c
|
|
index 59f8a7293fa7422c199ca2916c8e6ae6039d9312..60eacd4516b1269168caea744d91377686ab03f6 100644
|
|
--- a/src/responder/kcm/kcmsrv_ccache.c
|
|
+++ b/src/responder/kcm/kcmsrv_ccache.c
|
|
@@ -28,6 +28,9 @@
|
|
#include "responder/kcm/kcmsrv_ccache_pvt.h"
|
|
#include "responder/kcm/kcmsrv_ccache_be.h"
|
|
|
|
+static struct kcm_cred *kcm_cred_dup(TALLOC_CTX *mem_ctx,
|
|
+ struct kcm_cred *crd);
|
|
+
|
|
static int kcm_cc_destructor(struct kcm_ccache *cc)
|
|
{
|
|
if (cc == NULL) {
|
|
@@ -94,6 +97,33 @@ done:
|
|
return ret;
|
|
}
|
|
|
|
+struct kcm_ccache *kcm_cc_dup(TALLOC_CTX *mem_ctx,
|
|
+ const struct kcm_ccache *cc)
|
|
+{
|
|
+ struct kcm_ccache *dup;
|
|
+ struct kcm_cred *crd_dup;
|
|
+ struct kcm_cred *crd;
|
|
+
|
|
+ dup = talloc_zero(mem_ctx, struct kcm_ccache);
|
|
+ if (dup == NULL) {
|
|
+ return NULL;
|
|
+ }
|
|
+ memcpy(dup, cc, sizeof(struct kcm_ccache));
|
|
+
|
|
+ dup->creds = NULL;
|
|
+ DLIST_FOR_EACH(crd, cc->creds) {
|
|
+ crd_dup = kcm_cred_dup(dup, crd);
|
|
+ if (crd_dup == NULL) {
|
|
+ talloc_free(dup);
|
|
+ return NULL;
|
|
+ }
|
|
+
|
|
+ DLIST_ADD(dup->creds, crd_dup);
|
|
+ }
|
|
+
|
|
+ return dup;
|
|
+}
|
|
+
|
|
const char *kcm_cc_get_name(struct kcm_ccache *cc)
|
|
{
|
|
return cc ? cc->name : NULL;
|
|
@@ -204,6 +234,22 @@ struct kcm_cred *kcm_cred_new(TALLOC_CTX *mem_ctx,
|
|
return kcreds;
|
|
}
|
|
|
|
+static struct kcm_cred *kcm_cred_dup(TALLOC_CTX *mem_ctx,
|
|
+ struct kcm_cred *crd)
|
|
+{
|
|
+ struct kcm_cred *dup;
|
|
+
|
|
+ dup = talloc_zero(mem_ctx, struct kcm_cred);
|
|
+ if (dup == NULL) {
|
|
+ return NULL;
|
|
+ }
|
|
+
|
|
+ uuid_copy(dup->uuid, crd->uuid);
|
|
+ dup->cred_blob = crd->cred_blob;
|
|
+
|
|
+ return dup;
|
|
+}
|
|
+
|
|
/* Add a cred to ccache */
|
|
errno_t kcm_cc_store_creds(struct kcm_ccache *cc,
|
|
struct kcm_cred *crd)
|
|
diff --git a/src/responder/kcm/kcmsrv_ccache.h b/src/responder/kcm/kcmsrv_ccache.h
|
|
index b0a7acb9fed8a8f89a3d0e2239ab28c7ce80fa23..77cf8f61d563d29afe00d8a04e8053b24547746d 100644
|
|
--- a/src/responder/kcm/kcmsrv_ccache.h
|
|
+++ b/src/responder/kcm/kcmsrv_ccache.h
|
|
@@ -72,6 +72,13 @@ errno_t kcm_cc_new(TALLOC_CTX *mem_ctx,
|
|
krb5_principal princ,
|
|
struct kcm_ccache **_cc);
|
|
|
|
+/*
|
|
+ * Duplicate the ccache. Only ccache and credentials are duplicated,
|
|
+ * but their data are a shallow copy.
|
|
+ */
|
|
+struct kcm_ccache *kcm_cc_dup(TALLOC_CTX *mem_ctx,
|
|
+ const struct kcm_ccache *cc);
|
|
+
|
|
/*
|
|
* Returns true if a client can access a ccache.
|
|
*
|
|
diff --git a/src/responder/kcm/kcmsrv_ccache_mem.c b/src/responder/kcm/kcmsrv_ccache_mem.c
|
|
index baa698054fa4c6952b41b0f25dfdfa825f8e675b..0e3a7b239eda83c9fdec3b116231d4ec1444ef10 100644
|
|
--- a/src/responder/kcm/kcmsrv_ccache_mem.c
|
|
+++ b/src/responder/kcm/kcmsrv_ccache_mem.c
|
|
@@ -49,24 +49,6 @@ struct ccdb_mem {
|
|
unsigned int nextid;
|
|
};
|
|
|
|
-/* In order to provide a consistent interface, we need to let the caller
|
|
- * of getbyXXX own the ccache, therefore the memory back end returns a shallow
|
|
- * copy of the ccache
|
|
- */
|
|
-static struct kcm_ccache *kcm_ccache_dup(TALLOC_CTX *mem_ctx,
|
|
- struct kcm_ccache *in)
|
|
-{
|
|
- struct kcm_ccache *out;
|
|
-
|
|
- out = talloc_zero(mem_ctx, struct kcm_ccache);
|
|
- if (out == NULL) {
|
|
- return NULL;
|
|
- }
|
|
- memcpy(out, in, sizeof(struct kcm_ccache));
|
|
-
|
|
- return out;
|
|
-}
|
|
-
|
|
static struct ccache_mem_wrap *memdb_get_by_uuid(struct ccdb_mem *memdb,
|
|
struct cli_creds *client,
|
|
uuid_t uuid)
|
|
@@ -417,7 +399,11 @@ static struct tevent_req *ccdb_mem_getbyuuid_send(TALLOC_CTX *mem_ctx,
|
|
|
|
ccwrap = memdb_get_by_uuid(memdb, client, uuid);
|
|
if (ccwrap != NULL) {
|
|
- state->cc = kcm_ccache_dup(state, ccwrap->cc);
|
|
+ /* In order to provide a consistent interface, we need to let the caller
|
|
+ * of getbyXXX own the ccache, therefore the memory back end returns a shallow
|
|
+ * copy of the ccache
|
|
+ */
|
|
+ state->cc = kcm_cc_dup(state, ccwrap->cc);
|
|
if (state->cc == NULL) {
|
|
ret = ENOMEM;
|
|
goto immediate;
|
|
@@ -470,7 +456,11 @@ static struct tevent_req *ccdb_mem_getbyname_send(TALLOC_CTX *mem_ctx,
|
|
|
|
ccwrap = memdb_get_by_name(memdb, client, name);
|
|
if (ccwrap != NULL) {
|
|
- state->cc = kcm_ccache_dup(state, ccwrap->cc);
|
|
+ /* In order to provide a consistent interface, we need to let the caller
|
|
+ * of getbyXXX own the ccache, therefore the memory back end returns a shallow
|
|
+ * copy of the ccache
|
|
+ */
|
|
+ state->cc = kcm_cc_dup(state, ccwrap->cc);
|
|
if (state->cc == NULL) {
|
|
ret = ENOMEM;
|
|
goto immediate;
|
|
diff --git a/src/responder/kcm/kcmsrv_ops.c b/src/responder/kcm/kcmsrv_ops.c
|
|
index 6ae1f0c647f4d385477ddeadbad93287cba05c55..f458c724b0eaa3d43df4ad30baa3f896b8d87965 100644
|
|
--- a/src/responder/kcm/kcmsrv_ops.c
|
|
+++ b/src/responder/kcm/kcmsrv_ops.c
|
|
@@ -22,9 +22,11 @@
|
|
#include "config.h"
|
|
|
|
#include <krb5/krb5.h>
|
|
+#include <dhash.h>
|
|
|
|
#include "util/sss_iobuf.h"
|
|
#include "util/sss_krb5.h"
|
|
+#include "util/sss_ptr_hash.h"
|
|
#include "util/util_creds.h"
|
|
#include "responder/kcm/kcm.h"
|
|
#include "responder/kcm/kcmsrv_pvt.h"
|
|
@@ -1074,6 +1076,73 @@ static void kcm_op_get_principal_getbyname_done(struct tevent_req *subreq)
|
|
tevent_req_done(req);
|
|
}
|
|
|
|
+static void
|
|
+kcm_creds_table_delete_cb(hash_entry_t *item,
|
|
+ hash_destroy_enum deltype,
|
|
+ void *pvt)
|
|
+{
|
|
+ /* Delete the old credential if it is being overwritten. */
|
|
+ talloc_free(item->value.ptr);
|
|
+}
|
|
+
|
|
+/* Store credentials in a hash table.
|
|
+ *
|
|
+ * If the table already exist we add the new credentials to the table and
|
|
+ * overwrite the ones that already exist. This allows us to correctly serve
|
|
+ * also parallel GET_CRED_UUID_LIST requests from the same connection since
|
|
+ * it will have its own uuid list and cursor on the client side and we make
|
|
+ * all uuid (old, updated and newly added) available.
|
|
+ */
|
|
+static errno_t
|
|
+kcm_creds_to_table(TALLOC_CTX *mem_ctx,
|
|
+ struct kcm_cred *creds,
|
|
+ hash_table_t **_table)
|
|
+{
|
|
+ char str[UUID_STR_SIZE];
|
|
+ uuid_t uuid;
|
|
+ errno_t ret;
|
|
+
|
|
+ if (*_table == NULL) {
|
|
+ *_table = sss_ptr_hash_create(mem_ctx, kcm_creds_table_delete_cb, NULL);
|
|
+ if (*_table == NULL) {
|
|
+ return ENOMEM;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ for (struct kcm_cred *crd = creds;
|
|
+ crd != NULL;
|
|
+ crd = kcm_cc_next_cred(crd)) {
|
|
+ ret = kcm_cred_get_uuid(crd, uuid);
|
|
+ if (ret != EOK) {
|
|
+ DEBUG(SSSDBG_MINOR_FAILURE, "Credential has no UUID, skipping\n");
|
|
+ continue;
|
|
+ }
|
|
+ uuid_unparse(uuid, str);
|
|
+
|
|
+ ret = sss_ptr_hash_add_or_override(*_table, str, crd, struct kcm_cred);
|
|
+ if (ret != EOK) {
|
|
+ return ret;
|
|
+ }
|
|
+
|
|
+ talloc_steal(*_table, crd);
|
|
+ }
|
|
+
|
|
+ return EOK;
|
|
+}
|
|
+
|
|
+static struct kcm_cred *
|
|
+kcm_creds_lookup(hash_table_t *table, uuid_t uuid)
|
|
+{
|
|
+ char str[UUID_STR_SIZE];
|
|
+
|
|
+ if (uuid == NULL) {
|
|
+ return NULL;
|
|
+ }
|
|
+
|
|
+ uuid_unparse(uuid, str);
|
|
+ return sss_ptr_hash_lookup(table, str, struct kcm_cred);
|
|
+}
|
|
+
|
|
/* (name) -> (uuid, ...) */
|
|
static void kcm_op_get_cred_uuid_list_getbyname_done(struct tevent_req *subreq);
|
|
|
|
@@ -1123,12 +1192,15 @@ static void kcm_op_get_cred_uuid_list_getbyname_done(struct tevent_req *subreq)
|
|
errno_t ret;
|
|
struct kcm_ccache *cc;
|
|
struct kcm_cred *crd;
|
|
+ struct kcm_conn_data *conn_data;
|
|
uuid_t uuid;
|
|
struct tevent_req *req = tevent_req_callback_data(subreq,
|
|
struct tevent_req);
|
|
struct kcm_op_common_state *state = tevent_req_data(req,
|
|
struct kcm_op_common_state);
|
|
|
|
+ conn_data = state->op_ctx->conn_data;
|
|
+
|
|
ret = kcm_ccdb_getbyname_recv(subreq, state, &cc);
|
|
talloc_zfree(subreq);
|
|
if (ret != EOK) {
|
|
@@ -1140,12 +1212,20 @@ static void kcm_op_get_cred_uuid_list_getbyname_done(struct tevent_req *subreq)
|
|
}
|
|
|
|
if (cc == NULL) {
|
|
- DEBUG(SSSDBG_MINOR_FAILURE, "No credentials by that UUID\n");
|
|
+ DEBUG(SSSDBG_MINOR_FAILURE, "No ccache by that name\n");
|
|
state->op_ret = ERR_NO_CREDS;
|
|
tevent_req_done(req);
|
|
return;
|
|
}
|
|
|
|
+ ret = kcm_creds_to_table(conn_data, kcm_cc_get_cred(cc), &conn_data->creds);
|
|
+ if (ret != EOK) {
|
|
+ DEBUG(SSSDBG_OP_FAILURE, "Unable to build credentials hash table "
|
|
+ "[%d]: %s\n", ret, sss_strerror(ret));
|
|
+ tevent_req_error(req, ret);
|
|
+ return;
|
|
+ }
|
|
+
|
|
for (crd = kcm_cc_get_cred(cc);
|
|
crd != NULL;
|
|
crd = kcm_cc_next_cred(crd)) {
|
|
@@ -1172,6 +1252,34 @@ static void kcm_op_get_cred_uuid_list_getbyname_done(struct tevent_req *subreq)
|
|
tevent_req_done(req);
|
|
}
|
|
|
|
+static errno_t
|
|
+kcm_op_get_cred_by_uuid_reply(struct kcm_cred *crd,
|
|
+ struct sss_iobuf *reply)
|
|
+{
|
|
+ struct sss_iobuf *cred_blob;
|
|
+ errno_t ret;
|
|
+
|
|
+ cred_blob = kcm_cred_get_creds(crd);
|
|
+ if (cred_blob == NULL) {
|
|
+ DEBUG(SSSDBG_CRIT_FAILURE, "Credentials lack the creds blob\n");
|
|
+ return ERR_NO_CREDS;
|
|
+ }
|
|
+
|
|
+ ret = sss_iobuf_write_len(reply, sss_iobuf_get_data(cred_blob),
|
|
+ sss_iobuf_get_size(cred_blob));
|
|
+ if (ret != EOK) {
|
|
+ DEBUG(SSSDBG_OP_FAILURE, "Cannot write ccache blob [%d]: %s\n",
|
|
+ ret, sss_strerror(ret));
|
|
+ }
|
|
+
|
|
+ return ret;
|
|
+}
|
|
+
|
|
+struct kcm_op_get_cred_by_uuid_state {
|
|
+ struct kcm_op_common_state common;
|
|
+ uuid_t uuid;
|
|
+};
|
|
+
|
|
/* (name, uuid) -> (cred) */
|
|
static void kcm_op_get_cred_by_uuid_getbyname_done(struct tevent_req *subreq);
|
|
|
|
@@ -1182,20 +1290,51 @@ kcm_op_get_cred_by_uuid_send(TALLOC_CTX *mem_ctx,
|
|
{
|
|
struct tevent_req *req = NULL;
|
|
struct tevent_req *subreq = NULL;
|
|
- struct kcm_op_common_state *state = NULL;
|
|
+ struct kcm_op_get_cred_by_uuid_state *state;
|
|
+ struct kcm_cred *crd;
|
|
errno_t ret;
|
|
const char *name;
|
|
|
|
- req = tevent_req_create(mem_ctx, &state, struct kcm_op_common_state);
|
|
+ req = tevent_req_create(mem_ctx, &state,
|
|
+ struct kcm_op_get_cred_by_uuid_state);
|
|
if (req == NULL) {
|
|
return NULL;
|
|
}
|
|
- state->op_ctx = op_ctx;
|
|
+ state->common.op_ctx = op_ctx;
|
|
|
|
ret = sss_iobuf_read_stringz(op_ctx->input, &name);
|
|
if (ret != EOK) {
|
|
goto immediate;
|
|
}
|
|
+
|
|
+ ret = sss_iobuf_read_len(state->common.op_ctx->input, UUID_BYTES,
|
|
+ state->uuid);
|
|
+ if (ret != EOK) {
|
|
+ DEBUG(SSSDBG_OP_FAILURE, "Cannot read input UUID [%d]: %s\n",
|
|
+ ret, sss_strerror(ret));
|
|
+ goto immediate;
|
|
+ }
|
|
+
|
|
+ if (op_ctx->conn_data->creds != NULL) {
|
|
+ crd = kcm_creds_lookup(op_ctx->conn_data->creds, state->uuid);
|
|
+ if (crd == NULL) {
|
|
+ /* This should not happen, it can only happen if wrong UUID was
|
|
+ * requested which suggests bug in the caller application. */
|
|
+ DEBUG(SSSDBG_MINOR_FAILURE, "No credentials by that UUID\n");
|
|
+ kcm_debug_uuid(state->uuid);
|
|
+ state->common.op_ret = ERR_KCM_CC_END;
|
|
+ ret = EOK;
|
|
+ goto immediate;
|
|
+ } else {
|
|
+ ret = kcm_op_get_cred_by_uuid_reply(crd, op_ctx->reply);
|
|
+ if (ret == ERR_NO_CREDS) {
|
|
+ state->common.op_ret = ret;
|
|
+ ret = EOK;
|
|
+ }
|
|
+ goto immediate;
|
|
+ }
|
|
+ }
|
|
+
|
|
DEBUG(SSSDBG_TRACE_LIBS, "Returning creds by UUID for %s\n", name);
|
|
|
|
subreq = kcm_ccdb_getbyname_send(state, ev,
|
|
@@ -1210,7 +1349,11 @@ kcm_op_get_cred_by_uuid_send(TALLOC_CTX *mem_ctx,
|
|
return req;
|
|
|
|
immediate:
|
|
- tevent_req_error(req, ret);
|
|
+ if (ret == EOK) {
|
|
+ tevent_req_done(req);
|
|
+ } else {
|
|
+ tevent_req_error(req, ret);
|
|
+ }
|
|
tevent_req_post(req, ev);
|
|
return req;
|
|
}
|
|
@@ -1219,14 +1362,14 @@ static void kcm_op_get_cred_by_uuid_getbyname_done(struct tevent_req *subreq)
|
|
{
|
|
struct tevent_req *req = tevent_req_callback_data(subreq,
|
|
struct tevent_req);
|
|
- struct kcm_op_common_state *state = tevent_req_data(req,
|
|
- struct kcm_op_common_state);
|
|
+ struct kcm_op_get_cred_by_uuid_state *state = tevent_req_data(req,
|
|
+ struct kcm_op_get_cred_by_uuid_state);
|
|
errno_t ret;
|
|
struct kcm_ccache *cc;
|
|
struct kcm_cred *crd;
|
|
- uuid_t uuid_in;
|
|
- uuid_t uuid;
|
|
- struct sss_iobuf *cred_blob;
|
|
+ struct kcm_conn_data *conn_data;
|
|
+
|
|
+ conn_data = state->common.op_ctx->conn_data;
|
|
|
|
ret = kcm_ccdb_getbyname_recv(subreq, state, &cc);
|
|
talloc_zfree(subreq);
|
|
@@ -1238,69 +1381,45 @@ static void kcm_op_get_cred_by_uuid_getbyname_done(struct tevent_req *subreq)
|
|
return;
|
|
}
|
|
|
|
- if (cc == NULL) {
|
|
- DEBUG(SSSDBG_MINOR_FAILURE, "No credentials by that name\n");
|
|
- state->op_ret = ERR_NO_MATCHING_CREDS;
|
|
- tevent_req_done(req);
|
|
- return;
|
|
- }
|
|
-
|
|
- ret = sss_iobuf_read_len(state->op_ctx->input,
|
|
- UUID_BYTES, uuid_in);
|
|
+ ret = kcm_creds_to_table(conn_data, kcm_cc_get_cred(cc), &conn_data->creds);
|
|
if (ret != EOK) {
|
|
- DEBUG(SSSDBG_OP_FAILURE,
|
|
- "Cannot read input UUID [%d]: %s\n",
|
|
- ret, sss_strerror(ret));
|
|
+ DEBUG(SSSDBG_OP_FAILURE, "Unable to build credentials hash table "
|
|
+ "[%d]: %s\n", ret, sss_strerror(ret));
|
|
tevent_req_error(req, ret);
|
|
return;
|
|
}
|
|
|
|
- for (crd = kcm_cc_get_cred(cc);
|
|
- crd != NULL;
|
|
- crd = kcm_cc_next_cred(crd)) {
|
|
- ret = kcm_cred_get_uuid(crd, uuid);
|
|
- if (ret != EOK) {
|
|
- DEBUG(SSSDBG_MINOR_FAILURE,
|
|
- "Cannot get UUID from creds, skipping\n");
|
|
- continue;
|
|
- }
|
|
-
|
|
- if (uuid_compare(uuid, uuid_in) == 0) {
|
|
- break;
|
|
+ if (conn_data->creds != NULL) {
|
|
+ crd = kcm_creds_lookup(conn_data->creds, state->uuid);
|
|
+ if (crd == NULL) {
|
|
+ DEBUG(SSSDBG_MINOR_FAILURE, "No credentials by that UUID\n");
|
|
+ kcm_debug_uuid(state->uuid);
|
|
+ state->common.op_ret = ERR_KCM_CC_END;
|
|
+ } else {
|
|
+ ret = kcm_op_get_cred_by_uuid_reply(crd, state->common.op_ctx->reply);
|
|
+ if (ret != EOK && ret != ERR_NO_CREDS) {
|
|
+ tevent_req_error(req, ret);
|
|
+ return;
|
|
+ }
|
|
+ state->common.op_ret = ret;
|
|
}
|
|
- kcm_debug_uuid(uuid);
|
|
- }
|
|
-
|
|
- if (crd == NULL) {
|
|
- state->op_ret = ERR_KCM_CC_END;
|
|
- DEBUG(SSSDBG_MINOR_FAILURE, "No credentials by that UUID\n");
|
|
- tevent_req_done(req);
|
|
- return;
|
|
- }
|
|
-
|
|
- cred_blob = kcm_cred_get_creds(crd);
|
|
- if (cred_blob == NULL) {
|
|
- DEBUG(SSSDBG_CRIT_FAILURE, "Credentials lack the creds blob\n");
|
|
- state->op_ret = ERR_NO_CREDS;
|
|
- tevent_req_done(req);
|
|
- return;
|
|
- }
|
|
-
|
|
- ret = sss_iobuf_write_len(state->op_ctx->reply,
|
|
- sss_iobuf_get_data(cred_blob),
|
|
- sss_iobuf_get_size(cred_blob));
|
|
- if (ret != EOK) {
|
|
- DEBUG(SSSDBG_OP_FAILURE,
|
|
- "Cannot write ccache blob [%d]: %s\n",
|
|
- ret, sss_strerror(ret));
|
|
- tevent_req_error(req, ret);
|
|
- return;
|
|
}
|
|
|
|
- state->op_ret = EOK;
|
|
tevent_req_done(req);
|
|
}
|
|
|
|
+static errno_t kcm_op_get_cred_by_uuid_recv(struct tevent_req *req,
|
|
+ uint32_t *_op_ret)
|
|
+{
|
|
+ struct kcm_op_get_cred_by_uuid_state *state;
|
|
+
|
|
+ state = tevent_req_data(req, struct kcm_op_get_cred_by_uuid_state);
|
|
+
|
|
+ TEVENT_REQ_RETURN_ON_ERROR(req);
|
|
+ *_op_ret = state->common.op_ret;
|
|
+ return EOK;
|
|
+}
|
|
+
|
|
/* (name, flags, credtag) -> () */
|
|
/* FIXME */
|
|
static struct tevent_req *
|
|
@@ -2156,7 +2275,7 @@ static struct kcm_op kcm_optable[] = {
|
|
{ "RETRIEVE", NULL, NULL },
|
|
{ "GET_PRINCIPAL", kcm_op_get_principal_send, NULL },
|
|
{ "GET_CRED_UUID_LIST", kcm_op_get_cred_uuid_list_send, NULL },
|
|
- { "GET_CRED_BY_UUID", kcm_op_get_cred_by_uuid_send, NULL },
|
|
+ { "GET_CRED_BY_UUID", kcm_op_get_cred_by_uuid_send, kcm_op_get_cred_by_uuid_recv },
|
|
{ "REMOVE_CRED", kcm_op_remove_cred_send, NULL },
|
|
{ "SET_FLAGS", NULL, NULL },
|
|
{ "CHOWN", NULL, NULL },
|
|
diff --git a/src/responder/kcm/kcmsrv_ops.h b/src/responder/kcm/kcmsrv_ops.h
|
|
index fd2dd03c9da3660e0c1346752e4db59c7cbe2c41..ab6c13791baa43837cf84ebd523735b622a24020 100644
|
|
--- a/src/responder/kcm/kcmsrv_ops.h
|
|
+++ b/src/responder/kcm/kcmsrv_ops.h
|
|
@@ -24,6 +24,7 @@
|
|
|
|
#include "config.h"
|
|
|
|
+#include <dhash.h>
|
|
#include <sys/types.h>
|
|
#include "util/sss_iobuf.h"
|
|
#include "responder/kcm/kcmsrv_pvt.h"
|
|
@@ -33,7 +34,9 @@ struct kcm_op *kcm_get_opt(uint16_t opcode);
|
|
const char *kcm_opt_name(struct kcm_op *op);
|
|
|
|
struct kcm_conn_data {
|
|
- void *data;
|
|
+ /* Credentials obtained by GET_CRED_UUID_LIST. We use to improve performance
|
|
+ * by avoiding ccache lookups in GET_CRED_BY_UUID. */
|
|
+ hash_table_t *creds;
|
|
};
|
|
|
|
struct tevent_req *kcm_cmd_send(TALLOC_CTX *mem_ctx,
|
|
--
|
|
2.25.4
|
|
|