|
|
ecf709 |
From 79f6ccd2dc3f0c1369d5a93678c88ee76ec761e0 Mon Sep 17 00:00:00 2001
|
|
|
ecf709 |
From: Jakub Hrozek <jhrozek@redhat.com>
|
|
|
ecf709 |
Date: Tue, 7 Mar 2017 13:49:21 +0100
|
|
|
ecf709 |
Subject: [PATCH 24/36] KCM: Implement an internal ccache storage and retrieval
|
|
|
ecf709 |
API
|
|
|
ecf709 |
MIME-Version: 1.0
|
|
|
ecf709 |
Content-Type: text/plain; charset=UTF-8
|
|
|
ecf709 |
Content-Transfer-Encoding: 8bit
|
|
|
ecf709 |
|
|
|
ecf709 |
In order for the KCM server to work with ccaches stored in different
|
|
|
ecf709 |
locations, implement a middle-man between the KCM server and the ccache
|
|
|
ecf709 |
storage.
|
|
|
ecf709 |
|
|
|
ecf709 |
This module has asynchronous API because we can't assume anything about
|
|
|
ecf709 |
where the ccaches are stored.
|
|
|
ecf709 |
|
|
|
ecf709 |
Reviewed-by: Michal Židek <mzidek@redhat.com>
|
|
|
ecf709 |
Reviewed-by: Simo Sorce <simo@redhat.com>
|
|
|
ecf709 |
---
|
|
|
ecf709 |
Makefile.am | 9 +
|
|
|
ecf709 |
configure.ac | 1 +
|
|
|
ecf709 |
contrib/sssd.spec.in | 1 +
|
|
|
ecf709 |
src/external/libuuid.m4 | 17 +
|
|
|
ecf709 |
src/responder/kcm/kcmsrv_ccache.c | 1423 +++++++++++++++++++++++++++++++++
|
|
|
ecf709 |
src/responder/kcm/kcmsrv_ccache.h | 306 +++++++
|
|
|
ecf709 |
src/responder/kcm/kcmsrv_ccache_be.h | 204 +++++
|
|
|
ecf709 |
src/responder/kcm/kcmsrv_ccache_pvt.h | 62 ++
|
|
|
ecf709 |
src/responder/kcm/kcmsrv_pvt.h | 1 +
|
|
|
ecf709 |
9 files changed, 2024 insertions(+)
|
|
|
ecf709 |
create mode 100644 src/external/libuuid.m4
|
|
|
ecf709 |
create mode 100644 src/responder/kcm/kcmsrv_ccache.c
|
|
|
ecf709 |
create mode 100644 src/responder/kcm/kcmsrv_ccache.h
|
|
|
ecf709 |
create mode 100644 src/responder/kcm/kcmsrv_ccache_be.h
|
|
|
ecf709 |
create mode 100644 src/responder/kcm/kcmsrv_ccache_pvt.h
|
|
|
ecf709 |
|
|
|
ecf709 |
diff --git a/Makefile.am b/Makefile.am
|
|
|
ecf709 |
index 4248536e90370c1aab59549a9c18408ef314e6d4..a2b9dc49e95fa2d025f5174d2902866fab180a78 100644
|
|
|
ecf709 |
--- a/Makefile.am
|
|
|
ecf709 |
+++ b/Makefile.am
|
|
|
ecf709 |
@@ -711,6 +711,9 @@ dist_noinst_HEADERS = \
|
|
|
ecf709 |
src/responder/secrets/secsrv_proxy.h \
|
|
|
ecf709 |
src/responder/kcm/kcm.h \
|
|
|
ecf709 |
src/responder/kcm/kcmsrv_pvt.h \
|
|
|
ecf709 |
+ src/responder/kcm/kcmsrv_ccache.h \
|
|
|
ecf709 |
+ src/responder/kcm/kcmsrv_ccache_pvt.h \
|
|
|
ecf709 |
+ src/responder/kcm/kcmsrv_ccache_be.h \
|
|
|
ecf709 |
src/sbus/sbus_client.h \
|
|
|
ecf709 |
src/sbus/sssd_dbus.h \
|
|
|
ecf709 |
src/sbus/sssd_dbus_meta.h \
|
|
|
ecf709 |
@@ -1488,16 +1491,22 @@ if BUILD_KCM
|
|
|
ecf709 |
sssd_kcm_SOURCES = \
|
|
|
ecf709 |
src/responder/kcm/kcm.c \
|
|
|
ecf709 |
src/responder/kcm/kcmsrv_cmd.c \
|
|
|
ecf709 |
+ src/responder/kcm/kcmsrv_ccache.c \
|
|
|
ecf709 |
src/util/sss_sockets.c \
|
|
|
ecf709 |
+ src/util/sss_krb5.c \
|
|
|
ecf709 |
+ src/util/sss_iobuf.c \
|
|
|
ecf709 |
$(SSSD_RESPONDER_OBJ) \
|
|
|
ecf709 |
$(NULL)
|
|
|
ecf709 |
sssd_kcm_CFLAGS = \
|
|
|
ecf709 |
$(AM_CFLAGS) \
|
|
|
ecf709 |
$(KRB5_CFLAGS) \
|
|
|
ecf709 |
+ $(UUID_CFLAGS) \
|
|
|
ecf709 |
$(NULL)
|
|
|
ecf709 |
sssd_kcm_LDADD = \
|
|
|
ecf709 |
$(KRB5_LIBS) \
|
|
|
ecf709 |
$(SSSD_LIBS) \
|
|
|
ecf709 |
+ $(UUID_LIBS) \
|
|
|
ecf709 |
+ $(SYSTEMD_DAEMON_LIBS) \
|
|
|
ecf709 |
$(SSSD_INTERNAL_LTLIBS) \
|
|
|
ecf709 |
$(NULL)
|
|
|
ecf709 |
endif
|
|
|
ecf709 |
diff --git a/configure.ac b/configure.ac
|
|
|
ecf709 |
index c363d48a806cc1998e85779a92b6b59b0e2a5c9c..cf5e2557ef0a1bd6374200aa33abea6c509d03aa 100644
|
|
|
ecf709 |
--- a/configure.ac
|
|
|
ecf709 |
+++ b/configure.ac
|
|
|
ecf709 |
@@ -202,6 +202,7 @@ fi
|
|
|
ecf709 |
|
|
|
ecf709 |
if test x$with_kcm = xyes; then
|
|
|
ecf709 |
m4_include([src/external/libcurl.m4])
|
|
|
ecf709 |
+ m4_include([src/external/libuuid.m4])
|
|
|
ecf709 |
fi
|
|
|
ecf709 |
# This variable is defined by external/libcurl.m4, but conditionals
|
|
|
ecf709 |
# must be always evaluated
|
|
|
ecf709 |
diff --git a/contrib/sssd.spec.in b/contrib/sssd.spec.in
|
|
|
ecf709 |
index 5c7c2af521a84ef2ca6cca7b2d6cd1f9b3057056..52d33b4de281dc1d91a9027ac1c8c878e66fb396 100644
|
|
|
ecf709 |
--- a/contrib/sssd.spec.in
|
|
|
ecf709 |
+++ b/contrib/sssd.spec.in
|
|
|
ecf709 |
@@ -222,6 +222,7 @@ BuildRequires: systemtap-sdt-devel
|
|
|
ecf709 |
%endif
|
|
|
ecf709 |
BuildRequires: http-parser-devel
|
|
|
ecf709 |
BuildRequires: jansson-devel
|
|
|
ecf709 |
+BuildRequires: libuuid-devel
|
|
|
ecf709 |
|
|
|
ecf709 |
%description
|
|
|
ecf709 |
Provides a set of daemons to manage access to remote directories and
|
|
|
ecf709 |
diff --git a/src/external/libuuid.m4 b/src/external/libuuid.m4
|
|
|
ecf709 |
new file mode 100644
|
|
|
ecf709 |
index 0000000000000000000000000000000000000000..55411a2118bd787c9d50ba61f9cb791e1c76088d
|
|
|
ecf709 |
--- /dev/null
|
|
|
ecf709 |
+++ b/src/external/libuuid.m4
|
|
|
ecf709 |
@@ -0,0 +1,17 @@
|
|
|
ecf709 |
+AC_SUBST(UUID_LIBS)
|
|
|
ecf709 |
+AC_SUBST(UUID_CFLAGS)
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+PKG_CHECK_MODULES([UUID], [uuid], [found_uuid=yes], [found_uuid=no])
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+SSS_AC_EXPAND_LIB_DIR()
|
|
|
ecf709 |
+AS_IF([test x"$found_uuid" = xyes],
|
|
|
ecf709 |
+ [AC_CHECK_HEADERS([uuid/uuid.h],
|
|
|
ecf709 |
+ [AC_CHECK_LIB([uuid],
|
|
|
ecf709 |
+ [uuid_generate],
|
|
|
ecf709 |
+ [UUID_LIBS="-L$sss_extra_libdir -luuid"],
|
|
|
ecf709 |
+ [AC_MSG_ERROR([libuuid missing uuid_generate])],
|
|
|
ecf709 |
+ [-L$sss_extra_libdir -luuid])],
|
|
|
ecf709 |
+ [AC_MSG_ERROR([
|
|
|
ecf709 |
+You must have the header file uuid.h installed to build sssd
|
|
|
ecf709 |
+with KCM responder. If you want to build sssd without KCM responder
|
|
|
ecf709 |
+then specify --without-kcm when running configure.])])])
|
|
|
ecf709 |
diff --git a/src/responder/kcm/kcmsrv_ccache.c b/src/responder/kcm/kcmsrv_ccache.c
|
|
|
ecf709 |
new file mode 100644
|
|
|
ecf709 |
index 0000000000000000000000000000000000000000..2c565b8378e3ec297faf655d3c48d7ab902713d3
|
|
|
ecf709 |
--- /dev/null
|
|
|
ecf709 |
+++ b/src/responder/kcm/kcmsrv_ccache.c
|
|
|
ecf709 |
@@ -0,0 +1,1423 @@
|
|
|
ecf709 |
+/*
|
|
|
ecf709 |
+ SSSD
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+ KCM Server - the KCM ccache operations
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+ Copyright (C) Red Hat, 2016
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+ This program is free software; you can redistribute it and/or modify
|
|
|
ecf709 |
+ it under the terms of the GNU General Public License as published by
|
|
|
ecf709 |
+ the Free Software Foundation; either version 3 of the License, or
|
|
|
ecf709 |
+ (at your option) any later version.
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+ This program is distributed in the hope that it will be useful,
|
|
|
ecf709 |
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
ecf709 |
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
ecf709 |
+ GNU General Public License for more details.
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+ You should have received a copy of the GNU General Public License
|
|
|
ecf709 |
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
ecf709 |
+*/
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+#include "config.h"
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+#include "util/crypto/sss_crypto.h"
|
|
|
ecf709 |
+#include "util/util.h"
|
|
|
ecf709 |
+#include "util/sss_krb5.h"
|
|
|
ecf709 |
+#include "responder/kcm/kcmsrv_ccache.h"
|
|
|
ecf709 |
+#include "responder/kcm/kcmsrv_ccache_pvt.h"
|
|
|
ecf709 |
+#include "responder/kcm/kcmsrv_ccache_be.h"
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+static int kcm_cc_destructor(struct kcm_ccache *cc)
|
|
|
ecf709 |
+{
|
|
|
ecf709 |
+ if (cc == NULL) {
|
|
|
ecf709 |
+ return 0;
|
|
|
ecf709 |
+ }
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+ krb5_free_principal(NULL, cc->client);
|
|
|
ecf709 |
+ return 0;
|
|
|
ecf709 |
+}
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+errno_t kcm_cc_new(TALLOC_CTX *mem_ctx,
|
|
|
ecf709 |
+ krb5_context k5c,
|
|
|
ecf709 |
+ struct cli_creds *owner,
|
|
|
ecf709 |
+ const char *name,
|
|
|
ecf709 |
+ krb5_principal princ,
|
|
|
ecf709 |
+ struct kcm_ccache **_cc)
|
|
|
ecf709 |
+{
|
|
|
ecf709 |
+ struct kcm_ccache *cc;
|
|
|
ecf709 |
+ krb5_error_code kret;
|
|
|
ecf709 |
+ errno_t ret;
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+ cc = talloc_zero(mem_ctx, struct kcm_ccache);
|
|
|
ecf709 |
+ if (cc == NULL) {
|
|
|
ecf709 |
+ return ENOMEM;
|
|
|
ecf709 |
+ }
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+ ret = kcm_check_name(name, owner);
|
|
|
ecf709 |
+ if (ret != EOK) {
|
|
|
ecf709 |
+ DEBUG(SSSDBG_CRIT_FAILURE, "Name %s is malformed\n", name);
|
|
|
ecf709 |
+ return ret;
|
|
|
ecf709 |
+ }
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+ cc->name = talloc_strdup(cc, name);
|
|
|
ecf709 |
+ if (cc->name == NULL) {
|
|
|
ecf709 |
+ talloc_free(cc);
|
|
|
ecf709 |
+ return ENOMEM;
|
|
|
ecf709 |
+ }
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+ uuid_generate(cc->uuid);
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+ kret = krb5_copy_principal(k5c, princ, &cc->client);
|
|
|
ecf709 |
+ if (kret != 0) {
|
|
|
ecf709 |
+ const char *err_msg = sss_krb5_get_error_message(k5c, kret);
|
|
|
ecf709 |
+ DEBUG(SSSDBG_OP_FAILURE,
|
|
|
ecf709 |
+ "krb5_copy_principal failed: [%d][%s]\n", kret, err_msg);
|
|
|
ecf709 |
+ sss_krb5_free_error_message(k5c, err_msg);
|
|
|
ecf709 |
+ talloc_free(cc);
|
|
|
ecf709 |
+ return ERR_INTERNAL;
|
|
|
ecf709 |
+ }
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+ cc->owner.uid = cli_creds_get_uid(owner);
|
|
|
ecf709 |
+ cc->owner.gid = cli_creds_get_gid(owner);
|
|
|
ecf709 |
+ cc->kdc_offset = INT32_MAX;
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+ talloc_set_destructor(cc, kcm_cc_destructor);
|
|
|
ecf709 |
+ *_cc = cc;
|
|
|
ecf709 |
+ return EOK;
|
|
|
ecf709 |
+}
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+const char *kcm_cc_get_name(struct kcm_ccache *cc)
|
|
|
ecf709 |
+{
|
|
|
ecf709 |
+ return cc ? cc->name : NULL;
|
|
|
ecf709 |
+}
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+errno_t kcm_cc_get_uuid(struct kcm_ccache *cc, uuid_t _uuid)
|
|
|
ecf709 |
+{
|
|
|
ecf709 |
+ if (cc == NULL) {
|
|
|
ecf709 |
+ return EINVAL;
|
|
|
ecf709 |
+ }
|
|
|
ecf709 |
+ uuid_copy(_uuid, cc->uuid);
|
|
|
ecf709 |
+ return EOK;
|
|
|
ecf709 |
+}
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+krb5_principal kcm_cc_get_client_principal(struct kcm_ccache *cc)
|
|
|
ecf709 |
+{
|
|
|
ecf709 |
+ return cc ? cc->client : NULL;
|
|
|
ecf709 |
+}
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+bool kcm_cc_access(struct kcm_ccache *cc,
|
|
|
ecf709 |
+ struct cli_creds *client)
|
|
|
ecf709 |
+{
|
|
|
ecf709 |
+ bool ok;
|
|
|
ecf709 |
+ uid_t uid = cli_creds_get_uid(client);
|
|
|
ecf709 |
+ gid_t gid = cli_creds_get_gid(client);
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+ if (cc == NULL) {
|
|
|
ecf709 |
+ return false;
|
|
|
ecf709 |
+ }
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+ if (uid == 0 && gid == 0) {
|
|
|
ecf709 |
+ /* root can access any ccache */
|
|
|
ecf709 |
+ return true;
|
|
|
ecf709 |
+ }
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+ ok = ((cc->owner.uid == uid) && (cc->owner.gid == gid));
|
|
|
ecf709 |
+ if (!ok) {
|
|
|
ecf709 |
+ DEBUG(SSSDBG_MINOR_FAILURE,
|
|
|
ecf709 |
+ "Client %"SPRIuid":%"SPRIgid" has no access to ccache %s\n",
|
|
|
ecf709 |
+ cli_creds_get_uid(client),
|
|
|
ecf709 |
+ cli_creds_get_gid(client),
|
|
|
ecf709 |
+ cc->name);
|
|
|
ecf709 |
+ }
|
|
|
ecf709 |
+ return ok;
|
|
|
ecf709 |
+}
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+int32_t kcm_cc_get_offset(struct kcm_ccache *cc)
|
|
|
ecf709 |
+{
|
|
|
ecf709 |
+ return cc ? cc->kdc_offset : INT32_MAX;
|
|
|
ecf709 |
+}
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+errno_t kcm_cc_store_cred_blob(struct kcm_ccache *cc,
|
|
|
ecf709 |
+ struct sss_iobuf *cred_blob)
|
|
|
ecf709 |
+{
|
|
|
ecf709 |
+ struct kcm_cred *kcreds;
|
|
|
ecf709 |
+ uuid_t uuid;
|
|
|
ecf709 |
+ errno_t ret;
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+ if (cc == NULL || cred_blob == NULL) {
|
|
|
ecf709 |
+ return EINVAL;
|
|
|
ecf709 |
+ }
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+ uuid_generate(uuid);
|
|
|
ecf709 |
+ kcreds = kcm_cred_new(cc, uuid, cred_blob);
|
|
|
ecf709 |
+ if (kcreds == NULL) {
|
|
|
ecf709 |
+ return ENOMEM;
|
|
|
ecf709 |
+ }
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+ ret = kcm_cc_store_creds(cc, kcreds);
|
|
|
ecf709 |
+ if (ret != EOK) {
|
|
|
ecf709 |
+ return ret;
|
|
|
ecf709 |
+ }
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+ return EOK;
|
|
|
ecf709 |
+}
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+struct kcm_cred *kcm_cc_get_cred(struct kcm_ccache *cc)
|
|
|
ecf709 |
+{
|
|
|
ecf709 |
+ if (cc == NULL) {
|
|
|
ecf709 |
+ return NULL;
|
|
|
ecf709 |
+ }
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+ return cc->creds;
|
|
|
ecf709 |
+}
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+struct kcm_cred *kcm_cc_next_cred(struct kcm_cred *crd)
|
|
|
ecf709 |
+{
|
|
|
ecf709 |
+ if (crd == NULL) {
|
|
|
ecf709 |
+ return NULL;
|
|
|
ecf709 |
+ }
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+ return crd->next;
|
|
|
ecf709 |
+}
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+struct kcm_cred *kcm_cred_new(TALLOC_CTX *mem_ctx,
|
|
|
ecf709 |
+ uuid_t uuid,
|
|
|
ecf709 |
+ struct sss_iobuf *cred_blob)
|
|
|
ecf709 |
+{
|
|
|
ecf709 |
+ struct kcm_cred *kcreds;
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+ kcreds = talloc_zero(mem_ctx, struct kcm_cred);
|
|
|
ecf709 |
+ if (kcreds == NULL) {
|
|
|
ecf709 |
+ return NULL;
|
|
|
ecf709 |
+ }
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+ uuid_copy(kcreds->uuid, uuid);
|
|
|
ecf709 |
+ kcreds->cred_blob = talloc_steal(kcreds, cred_blob);
|
|
|
ecf709 |
+ return kcreds;
|
|
|
ecf709 |
+}
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+/* Add a cred to ccache */
|
|
|
ecf709 |
+errno_t kcm_cc_store_creds(struct kcm_ccache *cc,
|
|
|
ecf709 |
+ struct kcm_cred *crd)
|
|
|
ecf709 |
+{
|
|
|
ecf709 |
+ DLIST_ADD(cc->creds, crd);
|
|
|
ecf709 |
+ talloc_steal(cc, crd);
|
|
|
ecf709 |
+ return EOK;
|
|
|
ecf709 |
+}
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+errno_t kcm_cred_get_uuid(struct kcm_cred *crd, uuid_t _uuid)
|
|
|
ecf709 |
+{
|
|
|
ecf709 |
+ if (crd == NULL) {
|
|
|
ecf709 |
+ return EINVAL;
|
|
|
ecf709 |
+ }
|
|
|
ecf709 |
+ uuid_copy(_uuid, crd->uuid);
|
|
|
ecf709 |
+ return EOK;
|
|
|
ecf709 |
+}
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+struct sss_iobuf *kcm_cred_get_creds(struct kcm_cred *crd)
|
|
|
ecf709 |
+{
|
|
|
ecf709 |
+ return crd ? crd->cred_blob : NULL;
|
|
|
ecf709 |
+}
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+struct kcm_ccdb *kcm_ccdb_init(TALLOC_CTX *mem_ctx,
|
|
|
ecf709 |
+ struct tevent_context *ev,
|
|
|
ecf709 |
+ enum kcm_ccdb_be cc_be)
|
|
|
ecf709 |
+{
|
|
|
ecf709 |
+ errno_t ret;
|
|
|
ecf709 |
+ struct kcm_ccdb *ccdb = NULL;
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+ if (ev == NULL) {
|
|
|
ecf709 |
+ return NULL;
|
|
|
ecf709 |
+ }
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+ ccdb = talloc_zero(mem_ctx, struct kcm_ccdb);
|
|
|
ecf709 |
+ if (ccdb == NULL) {
|
|
|
ecf709 |
+ return NULL;
|
|
|
ecf709 |
+ }
|
|
|
ecf709 |
+ ccdb->ev = ev;
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+ switch (cc_be) {
|
|
|
ecf709 |
+ case CCDB_BE_MEMORY:
|
|
|
ecf709 |
+ DEBUG(SSSDBG_FUNC_DATA, "KCM back end: memory\n");
|
|
|
ecf709 |
+ /* Not implemented yet */
|
|
|
ecf709 |
+ break;
|
|
|
ecf709 |
+ case CCDB_BE_SECRETS:
|
|
|
ecf709 |
+ DEBUG(SSSDBG_FUNC_DATA, "KCM back end: sssd-secrets\n");
|
|
|
ecf709 |
+ /* Not implemented yet */
|
|
|
ecf709 |
+ break;
|
|
|
ecf709 |
+ default:
|
|
|
ecf709 |
+ DEBUG(SSSDBG_CRIT_FAILURE, "Unknown ccache database\n");
|
|
|
ecf709 |
+ break;
|
|
|
ecf709 |
+ }
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+ if (ccdb->ops == NULL) {
|
|
|
ecf709 |
+ DEBUG(SSSDBG_CRIT_FAILURE, "Ccache database not initialized\n");
|
|
|
ecf709 |
+ talloc_free(ccdb);
|
|
|
ecf709 |
+ return NULL;
|
|
|
ecf709 |
+ }
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+ ret = ccdb->ops->init(ccdb);
|
|
|
ecf709 |
+ if (ret != EOK) {
|
|
|
ecf709 |
+ DEBUG(SSSDBG_CRIT_FAILURE, "Cannot initialize ccache database\n");
|
|
|
ecf709 |
+ talloc_free(ccdb);
|
|
|
ecf709 |
+ return NULL;
|
|
|
ecf709 |
+ }
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+ return ccdb;
|
|
|
ecf709 |
+}
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+struct kcm_ccdb_nextid_state {
|
|
|
ecf709 |
+ char *next_cc;
|
|
|
ecf709 |
+ struct kcm_ccdb *db;
|
|
|
ecf709 |
+ struct cli_creds *client;
|
|
|
ecf709 |
+};
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+static void kcm_ccdb_nextid_done(struct tevent_req *subreq);
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+struct tevent_req *kcm_ccdb_nextid_send(TALLOC_CTX *mem_ctx,
|
|
|
ecf709 |
+ struct tevent_context *ev,
|
|
|
ecf709 |
+ struct kcm_ccdb *db,
|
|
|
ecf709 |
+ struct cli_creds *client)
|
|
|
ecf709 |
+{
|
|
|
ecf709 |
+ struct tevent_req *req = NULL;
|
|
|
ecf709 |
+ struct tevent_req *subreq = NULL;
|
|
|
ecf709 |
+ struct kcm_ccdb_nextid_state *state = NULL;
|
|
|
ecf709 |
+ errno_t ret;
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+ req = tevent_req_create(mem_ctx, &state, struct kcm_ccdb_nextid_state);
|
|
|
ecf709 |
+ if (req == NULL) {
|
|
|
ecf709 |
+ return NULL;
|
|
|
ecf709 |
+ }
|
|
|
ecf709 |
+ state->db = db;
|
|
|
ecf709 |
+ state->client = client;
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+ if (ev == NULL || db == NULL || client == NULL) {
|
|
|
ecf709 |
+ ret = EINVAL;
|
|
|
ecf709 |
+ goto immediate;
|
|
|
ecf709 |
+ }
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+ subreq = state->db->ops->nextid_send(mem_ctx, ev, state->db, client);
|
|
|
ecf709 |
+ if (subreq == NULL) {
|
|
|
ecf709 |
+ ret = ENOMEM;
|
|
|
ecf709 |
+ goto immediate;
|
|
|
ecf709 |
+ }
|
|
|
ecf709 |
+ tevent_req_set_callback(subreq, kcm_ccdb_nextid_done, req);
|
|
|
ecf709 |
+ return req;
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+immediate:
|
|
|
ecf709 |
+ tevent_req_error(req, ret);
|
|
|
ecf709 |
+ tevent_req_post(req, ev);
|
|
|
ecf709 |
+ return req;
|
|
|
ecf709 |
+}
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+static void kcm_ccdb_nextid_done(struct tevent_req *subreq)
|
|
|
ecf709 |
+{
|
|
|
ecf709 |
+ struct tevent_req *req = tevent_req_callback_data(subreq,
|
|
|
ecf709 |
+ struct tevent_req);
|
|
|
ecf709 |
+ struct kcm_ccdb_nextid_state *state = tevent_req_data(req,
|
|
|
ecf709 |
+ struct kcm_ccdb_nextid_state);
|
|
|
ecf709 |
+ errno_t ret;
|
|
|
ecf709 |
+ unsigned int nextid;
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+ ret = state->db->ops->nextid_recv(subreq, &nextid);
|
|
|
ecf709 |
+ talloc_zfree(subreq);
|
|
|
ecf709 |
+ if (ret != EOK) {
|
|
|
ecf709 |
+ DEBUG(SSSDBG_OP_FAILURE,
|
|
|
ecf709 |
+ "Failed to generate next UID [%d]: %s\n",
|
|
|
ecf709 |
+ ret, sss_strerror(ret));
|
|
|
ecf709 |
+ tevent_req_error(req, ret);
|
|
|
ecf709 |
+ return;
|
|
|
ecf709 |
+ }
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+ state->next_cc = talloc_asprintf(state, "%"SPRIuid":%u",
|
|
|
ecf709 |
+ cli_creds_get_uid(state->client),
|
|
|
ecf709 |
+ nextid);
|
|
|
ecf709 |
+ if (state->next_cc == NULL) {
|
|
|
ecf709 |
+ DEBUG(SSSDBG_CRIT_FAILURE, "talloc_asprintf failed\n");
|
|
|
ecf709 |
+ tevent_req_error(req, ENOMEM);
|
|
|
ecf709 |
+ return;
|
|
|
ecf709 |
+ }
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+ DEBUG(SSSDBG_TRACE_LIBS, "generated %s\n", state->next_cc);
|
|
|
ecf709 |
+ tevent_req_done(req);
|
|
|
ecf709 |
+}
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+errno_t kcm_ccdb_nextid_recv(struct tevent_req *req,
|
|
|
ecf709 |
+ TALLOC_CTX *mem_ctx,
|
|
|
ecf709 |
+ char **_next_cc)
|
|
|
ecf709 |
+{
|
|
|
ecf709 |
+ struct kcm_ccdb_nextid_state *state = tevent_req_data(req,
|
|
|
ecf709 |
+ struct kcm_ccdb_nextid_state);
|
|
|
ecf709 |
+ TEVENT_REQ_RETURN_ON_ERROR(req);
|
|
|
ecf709 |
+ *_next_cc = talloc_steal(mem_ctx, state->next_cc);
|
|
|
ecf709 |
+ return EOK;
|
|
|
ecf709 |
+}
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+struct kcm_ccdb_list_state {
|
|
|
ecf709 |
+ struct kcm_ccdb *db;
|
|
|
ecf709 |
+ struct cli_creds *client;
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+ uuid_t *uuid_list;
|
|
|
ecf709 |
+};
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+static void kcm_ccdb_list_done(struct tevent_req *subreq);
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+struct tevent_req *kcm_ccdb_list_send(TALLOC_CTX *mem_ctx,
|
|
|
ecf709 |
+ struct tevent_context *ev,
|
|
|
ecf709 |
+ struct kcm_ccdb *db,
|
|
|
ecf709 |
+ struct cli_creds *client)
|
|
|
ecf709 |
+{
|
|
|
ecf709 |
+ struct tevent_req *req = NULL;
|
|
|
ecf709 |
+ struct tevent_req *subreq = NULL;
|
|
|
ecf709 |
+ struct kcm_ccdb_list_state *state = NULL;
|
|
|
ecf709 |
+ errno_t ret;
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+ req = tevent_req_create(mem_ctx, &state, struct kcm_ccdb_list_state);
|
|
|
ecf709 |
+ if (req == NULL) {
|
|
|
ecf709 |
+ return NULL;
|
|
|
ecf709 |
+ }
|
|
|
ecf709 |
+ state->db = db;
|
|
|
ecf709 |
+ state->client = client;
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+ if (ev == NULL || db == NULL || client == NULL) {
|
|
|
ecf709 |
+ ret = EINVAL;
|
|
|
ecf709 |
+ goto immediate;
|
|
|
ecf709 |
+ }
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+ subreq = state->db->ops->list_send(mem_ctx,
|
|
|
ecf709 |
+ ev,
|
|
|
ecf709 |
+ state->db,
|
|
|
ecf709 |
+ client);
|
|
|
ecf709 |
+ if (subreq == NULL) {
|
|
|
ecf709 |
+ ret = ENOMEM;
|
|
|
ecf709 |
+ goto immediate;
|
|
|
ecf709 |
+ }
|
|
|
ecf709 |
+ tevent_req_set_callback(subreq, kcm_ccdb_list_done, req);
|
|
|
ecf709 |
+ return req;
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+immediate:
|
|
|
ecf709 |
+ tevent_req_error(req, ret);
|
|
|
ecf709 |
+ tevent_req_post(req, ev);
|
|
|
ecf709 |
+ return req;
|
|
|
ecf709 |
+}
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+static void kcm_ccdb_list_done(struct tevent_req *subreq)
|
|
|
ecf709 |
+{
|
|
|
ecf709 |
+ struct tevent_req *req = tevent_req_callback_data(subreq,
|
|
|
ecf709 |
+ struct tevent_req);
|
|
|
ecf709 |
+ struct kcm_ccdb_list_state *state = tevent_req_data(req,
|
|
|
ecf709 |
+ struct kcm_ccdb_list_state);
|
|
|
ecf709 |
+ errno_t ret;
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+ ret = state->db->ops->list_recv(subreq, state, &state->uuid_list);
|
|
|
ecf709 |
+ talloc_zfree(subreq);
|
|
|
ecf709 |
+ if (ret != EOK) {
|
|
|
ecf709 |
+ DEBUG(SSSDBG_OP_FAILURE,
|
|
|
ecf709 |
+ "Failed to list all ccaches [%d]: %s\n",
|
|
|
ecf709 |
+ ret, sss_strerror(ret));
|
|
|
ecf709 |
+ tevent_req_error(req, ret);
|
|
|
ecf709 |
+ return;
|
|
|
ecf709 |
+ }
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+ tevent_req_done(req);
|
|
|
ecf709 |
+}
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+errno_t kcm_ccdb_list_recv(struct tevent_req *req,
|
|
|
ecf709 |
+ TALLOC_CTX *mem_ctx,
|
|
|
ecf709 |
+ uuid_t **_uuid_list)
|
|
|
ecf709 |
+{
|
|
|
ecf709 |
+ struct kcm_ccdb_list_state *state = tevent_req_data(req,
|
|
|
ecf709 |
+ struct kcm_ccdb_list_state);
|
|
|
ecf709 |
+ TEVENT_REQ_RETURN_ON_ERROR(req);
|
|
|
ecf709 |
+ *_uuid_list = talloc_steal(mem_ctx, state->uuid_list);
|
|
|
ecf709 |
+ return EOK;
|
|
|
ecf709 |
+}
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+struct kcm_ccdb_get_default_state {
|
|
|
ecf709 |
+ struct kcm_ccdb *db;
|
|
|
ecf709 |
+ uuid_t uuid;
|
|
|
ecf709 |
+};
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+static void kcm_ccdb_get_default_done(struct tevent_req *subreq);
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+struct tevent_req *kcm_ccdb_get_default_send(TALLOC_CTX *mem_ctx,
|
|
|
ecf709 |
+ struct tevent_context *ev,
|
|
|
ecf709 |
+ struct kcm_ccdb *db,
|
|
|
ecf709 |
+ struct cli_creds *client)
|
|
|
ecf709 |
+{
|
|
|
ecf709 |
+ struct tevent_req *req = NULL;
|
|
|
ecf709 |
+ struct tevent_req *subreq = NULL;
|
|
|
ecf709 |
+ struct kcm_ccdb_get_default_state *state = NULL;
|
|
|
ecf709 |
+ errno_t ret;
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+ req = tevent_req_create(mem_ctx, &state, struct kcm_ccdb_get_default_state);
|
|
|
ecf709 |
+ if (req == NULL) {
|
|
|
ecf709 |
+ return NULL;
|
|
|
ecf709 |
+ }
|
|
|
ecf709 |
+ state->db = db;
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+ if (ev == NULL || db == NULL || client == NULL) {
|
|
|
ecf709 |
+ ret = EINVAL;
|
|
|
ecf709 |
+ goto immediate;
|
|
|
ecf709 |
+ }
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+ subreq = db->ops->get_default_send(mem_ctx, ev, db, client);
|
|
|
ecf709 |
+ if (subreq == NULL) {
|
|
|
ecf709 |
+ ret = ENOMEM;
|
|
|
ecf709 |
+ goto immediate;
|
|
|
ecf709 |
+ }
|
|
|
ecf709 |
+ tevent_req_set_callback(subreq, kcm_ccdb_get_default_done, req);
|
|
|
ecf709 |
+ return req;
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+immediate:
|
|
|
ecf709 |
+ tevent_req_error(req, ret);
|
|
|
ecf709 |
+ tevent_req_post(req, ev);
|
|
|
ecf709 |
+ return req;
|
|
|
ecf709 |
+}
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+static void kcm_ccdb_get_default_done(struct tevent_req *subreq)
|
|
|
ecf709 |
+{
|
|
|
ecf709 |
+ struct tevent_req *req = tevent_req_callback_data(subreq,
|
|
|
ecf709 |
+ struct tevent_req);
|
|
|
ecf709 |
+ struct kcm_ccdb_get_default_state *state = tevent_req_data(req,
|
|
|
ecf709 |
+ struct kcm_ccdb_get_default_state);
|
|
|
ecf709 |
+ errno_t ret;
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+ ret = state->db->ops->get_default_recv(subreq, state->uuid);
|
|
|
ecf709 |
+ talloc_zfree(subreq);
|
|
|
ecf709 |
+ if (ret != EOK) {
|
|
|
ecf709 |
+ DEBUG(SSSDBG_OP_FAILURE,
|
|
|
ecf709 |
+ "Failed to get the default ccache [%d]: %s\n",
|
|
|
ecf709 |
+ ret, sss_strerror(ret));
|
|
|
ecf709 |
+ tevent_req_error(req, ret);
|
|
|
ecf709 |
+ return;
|
|
|
ecf709 |
+ }
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+ tevent_req_done(req);
|
|
|
ecf709 |
+}
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+errno_t kcm_ccdb_get_default_recv(struct tevent_req *req,
|
|
|
ecf709 |
+ uuid_t *uuid)
|
|
|
ecf709 |
+{
|
|
|
ecf709 |
+ struct kcm_ccdb_get_default_state *state = tevent_req_data(req,
|
|
|
ecf709 |
+ struct kcm_ccdb_get_default_state);
|
|
|
ecf709 |
+ TEVENT_REQ_RETURN_ON_ERROR(req);
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+ if (uuid != NULL) {
|
|
|
ecf709 |
+ /* The caller might supply a NULL dfl to just check if there is
|
|
|
ecf709 |
+ * some default ccache
|
|
|
ecf709 |
+ */
|
|
|
ecf709 |
+ uuid_copy(*uuid, state->uuid);
|
|
|
ecf709 |
+ }
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+ return EOK;
|
|
|
ecf709 |
+}
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+struct kcm_ccdb_set_default_state {
|
|
|
ecf709 |
+ struct tevent_context *ev;
|
|
|
ecf709 |
+ struct kcm_ccdb *db;
|
|
|
ecf709 |
+ struct cli_creds *client;
|
|
|
ecf709 |
+ uuid_t uuid;
|
|
|
ecf709 |
+};
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+static void kcm_ccdb_set_default_uuid_resolved(struct tevent_req *subreq);
|
|
|
ecf709 |
+static void kcm_ccdb_set_default_done(struct tevent_req *subreq);
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+struct tevent_req *kcm_ccdb_set_default_send(TALLOC_CTX *mem_ctx,
|
|
|
ecf709 |
+ struct tevent_context *ev,
|
|
|
ecf709 |
+ struct kcm_ccdb *db,
|
|
|
ecf709 |
+ struct cli_creds *client,
|
|
|
ecf709 |
+ uuid_t uuid)
|
|
|
ecf709 |
+{
|
|
|
ecf709 |
+ struct tevent_req *req = NULL;
|
|
|
ecf709 |
+ struct tevent_req *subreq = NULL;
|
|
|
ecf709 |
+ struct kcm_ccdb_set_default_state *state = NULL;
|
|
|
ecf709 |
+ errno_t ret;
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+ req = tevent_req_create(mem_ctx, &state, struct kcm_ccdb_set_default_state);
|
|
|
ecf709 |
+ if (req == NULL) {
|
|
|
ecf709 |
+ return NULL;
|
|
|
ecf709 |
+ }
|
|
|
ecf709 |
+ state->db = db;
|
|
|
ecf709 |
+ state->ev = ev;
|
|
|
ecf709 |
+ state->client = client;
|
|
|
ecf709 |
+ uuid_copy(state->uuid, uuid);
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+ if (ev == NULL || db == NULL || client == NULL) {
|
|
|
ecf709 |
+ ret = EINVAL;
|
|
|
ecf709 |
+ goto immediate;
|
|
|
ecf709 |
+ }
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+ if (uuid_is_null(uuid)) {
|
|
|
ecf709 |
+ /* NULL UUID means to just reset the default to 'no default' */
|
|
|
ecf709 |
+ subreq = state->db->ops->set_default_send(state,
|
|
|
ecf709 |
+ state->ev,
|
|
|
ecf709 |
+ state->db,
|
|
|
ecf709 |
+ state->client,
|
|
|
ecf709 |
+ state->uuid);
|
|
|
ecf709 |
+ if (subreq == NULL) {
|
|
|
ecf709 |
+ ret = ENOMEM;
|
|
|
ecf709 |
+ goto immediate;
|
|
|
ecf709 |
+ }
|
|
|
ecf709 |
+ tevent_req_set_callback(subreq, kcm_ccdb_set_default_done, req);
|
|
|
ecf709 |
+ } else {
|
|
|
ecf709 |
+ /* Otherwise we need to check if the client can access the UUID
|
|
|
ecf709 |
+ * about to be set as default
|
|
|
ecf709 |
+ */
|
|
|
ecf709 |
+ subreq = db->ops->getbyuuid_send(state, ev, db, client, uuid);
|
|
|
ecf709 |
+ if (subreq == NULL) {
|
|
|
ecf709 |
+ ret = ENOMEM;
|
|
|
ecf709 |
+ goto immediate;
|
|
|
ecf709 |
+ }
|
|
|
ecf709 |
+ tevent_req_set_callback(subreq, kcm_ccdb_set_default_uuid_resolved, req);
|
|
|
ecf709 |
+ }
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+ return req;
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+immediate:
|
|
|
ecf709 |
+ tevent_req_error(req, ret);
|
|
|
ecf709 |
+ tevent_req_post(req, ev);
|
|
|
ecf709 |
+ return req;
|
|
|
ecf709 |
+}
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+static void kcm_ccdb_set_default_uuid_resolved(struct tevent_req *subreq)
|
|
|
ecf709 |
+{
|
|
|
ecf709 |
+ struct tevent_req *req = tevent_req_callback_data(subreq,
|
|
|
ecf709 |
+ struct tevent_req);
|
|
|
ecf709 |
+ struct kcm_ccdb_set_default_state *state = tevent_req_data(req,
|
|
|
ecf709 |
+ struct kcm_ccdb_set_default_state);
|
|
|
ecf709 |
+ errno_t ret;
|
|
|
ecf709 |
+ bool ok;
|
|
|
ecf709 |
+ struct kcm_ccache *cc;
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+ ret = state->db->ops->getbyuuid_recv(subreq, state, &cc);
|
|
|
ecf709 |
+ talloc_zfree(subreq);
|
|
|
ecf709 |
+ if (ret != EOK) {
|
|
|
ecf709 |
+ DEBUG(SSSDBG_OP_FAILURE,
|
|
|
ecf709 |
+ "Failed to get cache by UUID [%d]: %s\n",
|
|
|
ecf709 |
+ ret, sss_strerror(ret));
|
|
|
ecf709 |
+ tevent_req_error(req, ret);
|
|
|
ecf709 |
+ return;
|
|
|
ecf709 |
+ }
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+ if (cc == NULL) {
|
|
|
ecf709 |
+ DEBUG(SSSDBG_TRACE_LIBS, "No cache found by UUID\n");
|
|
|
ecf709 |
+ tevent_req_error(req, ERR_KCM_CC_END);
|
|
|
ecf709 |
+ return;
|
|
|
ecf709 |
+ }
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+ ok = kcm_cc_access(cc, state->client);
|
|
|
ecf709 |
+ if (!ok) {
|
|
|
ecf709 |
+ tevent_req_error(req, EACCES);
|
|
|
ecf709 |
+ return;
|
|
|
ecf709 |
+ }
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+ subreq = state->db->ops->set_default_send(state,
|
|
|
ecf709 |
+ state->ev,
|
|
|
ecf709 |
+ state->db,
|
|
|
ecf709 |
+ state->client,
|
|
|
ecf709 |
+ state->uuid);
|
|
|
ecf709 |
+ if (subreq == NULL) {
|
|
|
ecf709 |
+ tevent_req_error(req, ENOMEM);
|
|
|
ecf709 |
+ return;
|
|
|
ecf709 |
+ }
|
|
|
ecf709 |
+ tevent_req_set_callback(subreq, kcm_ccdb_set_default_done, req);
|
|
|
ecf709 |
+}
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+static void kcm_ccdb_set_default_done(struct tevent_req *subreq)
|
|
|
ecf709 |
+{
|
|
|
ecf709 |
+ struct tevent_req *req = tevent_req_callback_data(subreq,
|
|
|
ecf709 |
+ struct tevent_req);
|
|
|
ecf709 |
+ struct kcm_ccdb_set_default_state *state = tevent_req_data(req,
|
|
|
ecf709 |
+ struct kcm_ccdb_set_default_state);
|
|
|
ecf709 |
+ errno_t ret;
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+ ret = state->db->ops->set_default_recv(subreq);
|
|
|
ecf709 |
+ talloc_zfree(subreq);
|
|
|
ecf709 |
+ if (ret != EOK) {
|
|
|
ecf709 |
+ DEBUG(SSSDBG_OP_FAILURE,
|
|
|
ecf709 |
+ "Failed to set the default ccache [%d]: %s\n",
|
|
|
ecf709 |
+ ret, sss_strerror(ret));
|
|
|
ecf709 |
+ tevent_req_error(req, ret);
|
|
|
ecf709 |
+ return;
|
|
|
ecf709 |
+ }
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+ tevent_req_done(req);
|
|
|
ecf709 |
+}
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+errno_t kcm_ccdb_set_default_recv(struct tevent_req *req)
|
|
|
ecf709 |
+{
|
|
|
ecf709 |
+ TEVENT_REQ_RETURN_ON_ERROR(req);
|
|
|
ecf709 |
+ return EOK;
|
|
|
ecf709 |
+}
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+struct kcm_ccdb_getbyname_state {
|
|
|
ecf709 |
+ struct kcm_ccdb *db;
|
|
|
ecf709 |
+ struct cli_creds *client;
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+ struct kcm_ccache *cc;
|
|
|
ecf709 |
+};
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+static void kcm_ccdb_getbyname_done(struct tevent_req *subreq);
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+struct tevent_req *kcm_ccdb_getbyname_send(TALLOC_CTX *mem_ctx,
|
|
|
ecf709 |
+ struct tevent_context *ev,
|
|
|
ecf709 |
+ struct kcm_ccdb *db,
|
|
|
ecf709 |
+ struct cli_creds *client,
|
|
|
ecf709 |
+ const char *name)
|
|
|
ecf709 |
+{
|
|
|
ecf709 |
+ struct tevent_req *req = NULL;
|
|
|
ecf709 |
+ struct tevent_req *subreq = NULL;
|
|
|
ecf709 |
+ struct kcm_ccdb_getbyname_state *state = NULL;
|
|
|
ecf709 |
+ errno_t ret;
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+ req = tevent_req_create(mem_ctx, &state, struct kcm_ccdb_getbyname_state);
|
|
|
ecf709 |
+ if (req == NULL) {
|
|
|
ecf709 |
+ return NULL;
|
|
|
ecf709 |
+ }
|
|
|
ecf709 |
+ state->db = db;
|
|
|
ecf709 |
+ state->client = client;
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+ if (ev == NULL || db == NULL || client == NULL || name == NULL) {
|
|
|
ecf709 |
+ ret = EINVAL;
|
|
|
ecf709 |
+ goto immediate;
|
|
|
ecf709 |
+ }
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+ subreq = db->ops->getbyname_send(state, ev, db, client, name);
|
|
|
ecf709 |
+ if (subreq == NULL) {
|
|
|
ecf709 |
+ ret = ENOMEM;
|
|
|
ecf709 |
+ goto immediate;
|
|
|
ecf709 |
+ }
|
|
|
ecf709 |
+ tevent_req_set_callback(subreq, kcm_ccdb_getbyname_done, req);
|
|
|
ecf709 |
+ return req;
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+immediate:
|
|
|
ecf709 |
+ tevent_req_error(req, ret);
|
|
|
ecf709 |
+ tevent_req_post(req, ev);
|
|
|
ecf709 |
+ return req;
|
|
|
ecf709 |
+}
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+static void kcm_ccdb_getbyname_done(struct tevent_req *subreq)
|
|
|
ecf709 |
+{
|
|
|
ecf709 |
+ struct tevent_req *req = tevent_req_callback_data(subreq,
|
|
|
ecf709 |
+ struct tevent_req);
|
|
|
ecf709 |
+ struct kcm_ccdb_getbyname_state *state = tevent_req_data(req,
|
|
|
ecf709 |
+ struct kcm_ccdb_getbyname_state);
|
|
|
ecf709 |
+ errno_t ret;
|
|
|
ecf709 |
+ bool ok;
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+ ret = state->db->ops->getbyname_recv(subreq, state, &state->cc);
|
|
|
ecf709 |
+ talloc_zfree(subreq);
|
|
|
ecf709 |
+ if (ret != EOK) {
|
|
|
ecf709 |
+ DEBUG(SSSDBG_OP_FAILURE,
|
|
|
ecf709 |
+ "Failed to get cache by name [%d]: %s\n",
|
|
|
ecf709 |
+ ret, sss_strerror(ret));
|
|
|
ecf709 |
+ tevent_req_error(req, ret);
|
|
|
ecf709 |
+ return;
|
|
|
ecf709 |
+ }
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+ if (state->cc == NULL) {
|
|
|
ecf709 |
+ DEBUG(SSSDBG_TRACE_LIBS, "No cache found by name\n");
|
|
|
ecf709 |
+ tevent_req_done(req);
|
|
|
ecf709 |
+ return;
|
|
|
ecf709 |
+ }
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+ ok = kcm_cc_access(state->cc, state->client);
|
|
|
ecf709 |
+ if (!ok) {
|
|
|
ecf709 |
+ tevent_req_error(req, EACCES);
|
|
|
ecf709 |
+ return;
|
|
|
ecf709 |
+ }
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+ tevent_req_done(req);
|
|
|
ecf709 |
+}
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+errno_t kcm_ccdb_getbyname_recv(struct tevent_req *req,
|
|
|
ecf709 |
+ TALLOC_CTX *mem_ctx,
|
|
|
ecf709 |
+ struct kcm_ccache **_cc)
|
|
|
ecf709 |
+{
|
|
|
ecf709 |
+ struct kcm_ccdb_getbyname_state *state = tevent_req_data(req,
|
|
|
ecf709 |
+ struct kcm_ccdb_getbyname_state);
|
|
|
ecf709 |
+ TEVENT_REQ_RETURN_ON_ERROR(req);
|
|
|
ecf709 |
+ *_cc = talloc_steal(mem_ctx, state->cc);
|
|
|
ecf709 |
+ return EOK;
|
|
|
ecf709 |
+}
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+struct kcm_ccdb_getbyuuid_state {
|
|
|
ecf709 |
+ struct kcm_ccdb *db;
|
|
|
ecf709 |
+ struct cli_creds *client;
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+ struct kcm_ccache *cc;
|
|
|
ecf709 |
+};
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+static void kcm_ccdb_getbyuuid_done(struct tevent_req *subreq);
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+struct tevent_req *kcm_ccdb_getbyuuid_send(TALLOC_CTX *mem_ctx,
|
|
|
ecf709 |
+ struct tevent_context *ev,
|
|
|
ecf709 |
+ struct kcm_ccdb *db,
|
|
|
ecf709 |
+ struct cli_creds *client,
|
|
|
ecf709 |
+ uuid_t uuid)
|
|
|
ecf709 |
+{
|
|
|
ecf709 |
+ struct tevent_req *req = NULL;
|
|
|
ecf709 |
+ struct tevent_req *subreq = NULL;
|
|
|
ecf709 |
+ struct kcm_ccdb_getbyuuid_state *state = NULL;
|
|
|
ecf709 |
+ errno_t ret;
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+ req = tevent_req_create(mem_ctx, &state, struct kcm_ccdb_getbyuuid_state);
|
|
|
ecf709 |
+ if (req == NULL) {
|
|
|
ecf709 |
+ return NULL;
|
|
|
ecf709 |
+ }
|
|
|
ecf709 |
+ state->db = db;
|
|
|
ecf709 |
+ state->client = client;
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+ if (ev == NULL || db == NULL || client == NULL) {
|
|
|
ecf709 |
+ ret = EINVAL;
|
|
|
ecf709 |
+ goto immediate;
|
|
|
ecf709 |
+ }
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+ subreq = db->ops->getbyuuid_send(state, ev, db, client, uuid);
|
|
|
ecf709 |
+ if (subreq == NULL) {
|
|
|
ecf709 |
+ ret = ENOMEM;
|
|
|
ecf709 |
+ goto immediate;
|
|
|
ecf709 |
+ }
|
|
|
ecf709 |
+ tevent_req_set_callback(subreq, kcm_ccdb_getbyuuid_done, req);
|
|
|
ecf709 |
+ return req;
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+immediate:
|
|
|
ecf709 |
+ tevent_req_error(req, ret);
|
|
|
ecf709 |
+ tevent_req_post(req, ev);
|
|
|
ecf709 |
+ return req;
|
|
|
ecf709 |
+}
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+static void kcm_ccdb_getbyuuid_done(struct tevent_req *subreq)
|
|
|
ecf709 |
+{
|
|
|
ecf709 |
+ struct tevent_req *req = tevent_req_callback_data(subreq,
|
|
|
ecf709 |
+ struct tevent_req);
|
|
|
ecf709 |
+ struct kcm_ccdb_getbyuuid_state *state = tevent_req_data(req,
|
|
|
ecf709 |
+ struct kcm_ccdb_getbyuuid_state);
|
|
|
ecf709 |
+ errno_t ret;
|
|
|
ecf709 |
+ bool ok;
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+ ret = state->db->ops->getbyuuid_recv(subreq, state, &state->cc);
|
|
|
ecf709 |
+ talloc_zfree(subreq);
|
|
|
ecf709 |
+ if (ret != EOK) {
|
|
|
ecf709 |
+ DEBUG(SSSDBG_OP_FAILURE,
|
|
|
ecf709 |
+ "Failed to get cache by UUID [%d]: %s\n",
|
|
|
ecf709 |
+ ret, sss_strerror(ret));
|
|
|
ecf709 |
+ tevent_req_error(req, ret);
|
|
|
ecf709 |
+ return;
|
|
|
ecf709 |
+ }
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+ if (state->cc == NULL) {
|
|
|
ecf709 |
+ DEBUG(SSSDBG_TRACE_LIBS, "No cache found by UUID\n");
|
|
|
ecf709 |
+ tevent_req_done(req);
|
|
|
ecf709 |
+ return;
|
|
|
ecf709 |
+ }
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+ ok = kcm_cc_access(state->cc, state->client);
|
|
|
ecf709 |
+ if (!ok) {
|
|
|
ecf709 |
+ tevent_req_error(req, EACCES);
|
|
|
ecf709 |
+ return;
|
|
|
ecf709 |
+ }
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+ tevent_req_done(req);
|
|
|
ecf709 |
+}
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+errno_t kcm_ccdb_getbyuuid_recv(struct tevent_req *req,
|
|
|
ecf709 |
+ TALLOC_CTX *mem_ctx,
|
|
|
ecf709 |
+ struct kcm_ccache **_cc)
|
|
|
ecf709 |
+{
|
|
|
ecf709 |
+ struct kcm_ccdb_getbyuuid_state *state = tevent_req_data(req,
|
|
|
ecf709 |
+ struct kcm_ccdb_getbyuuid_state);
|
|
|
ecf709 |
+ TEVENT_REQ_RETURN_ON_ERROR(req);
|
|
|
ecf709 |
+ *_cc = talloc_steal(mem_ctx, state->cc);
|
|
|
ecf709 |
+ return EOK;
|
|
|
ecf709 |
+}
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+struct kcm_ccdb_name_by_uuid_state {
|
|
|
ecf709 |
+ struct kcm_ccdb *db;
|
|
|
ecf709 |
+ struct cli_creds *client;
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+ const char *name;
|
|
|
ecf709 |
+};
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+static void kcm_ccdb_name_by_uuid_done(struct tevent_req *subreq);
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+struct tevent_req *kcm_ccdb_name_by_uuid_send(TALLOC_CTX *mem_ctx,
|
|
|
ecf709 |
+ struct tevent_context *ev,
|
|
|
ecf709 |
+ struct kcm_ccdb *db,
|
|
|
ecf709 |
+ struct cli_creds *client,
|
|
|
ecf709 |
+ uuid_t uuid)
|
|
|
ecf709 |
+{
|
|
|
ecf709 |
+ struct tevent_req *req = NULL;
|
|
|
ecf709 |
+ struct tevent_req *subreq = NULL;
|
|
|
ecf709 |
+ struct kcm_ccdb_name_by_uuid_state *state = NULL;
|
|
|
ecf709 |
+ errno_t ret;
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+ req = tevent_req_create(mem_ctx,
|
|
|
ecf709 |
+ &state,
|
|
|
ecf709 |
+ struct kcm_ccdb_name_by_uuid_state);
|
|
|
ecf709 |
+ if (req == NULL) {
|
|
|
ecf709 |
+ return NULL;
|
|
|
ecf709 |
+ }
|
|
|
ecf709 |
+ state->db = db;
|
|
|
ecf709 |
+ state->client = client;
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+ if (ev == NULL || db == NULL || client == NULL || uuid_is_null(uuid)) {
|
|
|
ecf709 |
+ ret = EINVAL;
|
|
|
ecf709 |
+ goto immediate;
|
|
|
ecf709 |
+ }
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+ subreq = db->ops->name_by_uuid_send(state, ev, db, client, uuid);
|
|
|
ecf709 |
+ if (subreq == NULL) {
|
|
|
ecf709 |
+ ret = ENOMEM;
|
|
|
ecf709 |
+ goto immediate;
|
|
|
ecf709 |
+ }
|
|
|
ecf709 |
+ tevent_req_set_callback(subreq, kcm_ccdb_name_by_uuid_done, req);
|
|
|
ecf709 |
+ return req;
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+immediate:
|
|
|
ecf709 |
+ tevent_req_error(req, ret);
|
|
|
ecf709 |
+ tevent_req_post(req, ev);
|
|
|
ecf709 |
+ return req;
|
|
|
ecf709 |
+}
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+static void kcm_ccdb_name_by_uuid_done(struct tevent_req *subreq)
|
|
|
ecf709 |
+{
|
|
|
ecf709 |
+ struct tevent_req *req = tevent_req_callback_data(subreq,
|
|
|
ecf709 |
+ struct tevent_req);
|
|
|
ecf709 |
+ struct kcm_ccdb_name_by_uuid_state *state = tevent_req_data(req,
|
|
|
ecf709 |
+ struct kcm_ccdb_name_by_uuid_state);
|
|
|
ecf709 |
+ errno_t ret;
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+ ret = state->db->ops->name_by_uuid_recv(subreq, state, &state->name);
|
|
|
ecf709 |
+ talloc_zfree(subreq);
|
|
|
ecf709 |
+ if (ret != EOK) {
|
|
|
ecf709 |
+ DEBUG(SSSDBG_OP_FAILURE,
|
|
|
ecf709 |
+ "Failed to resolve cache by UUID [%d]: %s\n",
|
|
|
ecf709 |
+ ret, sss_strerror(ret));
|
|
|
ecf709 |
+ tevent_req_error(req, ret);
|
|
|
ecf709 |
+ return;
|
|
|
ecf709 |
+ }
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+ tevent_req_done(req);
|
|
|
ecf709 |
+}
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+errno_t kcm_ccdb_name_by_uuid_recv(struct tevent_req *req,
|
|
|
ecf709 |
+ TALLOC_CTX *mem_ctx,
|
|
|
ecf709 |
+ const char **_name)
|
|
|
ecf709 |
+{
|
|
|
ecf709 |
+ struct kcm_ccdb_name_by_uuid_state *state = tevent_req_data(req,
|
|
|
ecf709 |
+ struct kcm_ccdb_name_by_uuid_state);
|
|
|
ecf709 |
+ TEVENT_REQ_RETURN_ON_ERROR(req);
|
|
|
ecf709 |
+ *_name = talloc_steal(mem_ctx, state->name);
|
|
|
ecf709 |
+ return EOK;
|
|
|
ecf709 |
+}
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+struct kcm_ccdb_uuid_by_name_state {
|
|
|
ecf709 |
+ struct kcm_ccdb *db;
|
|
|
ecf709 |
+ struct cli_creds *client;
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+ uuid_t uuid;
|
|
|
ecf709 |
+};
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+static void kcm_ccdb_uuid_by_name_done(struct tevent_req *subreq);
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+struct tevent_req *kcm_ccdb_uuid_by_name_send(TALLOC_CTX *mem_ctx,
|
|
|
ecf709 |
+ struct tevent_context *ev,
|
|
|
ecf709 |
+ struct kcm_ccdb *db,
|
|
|
ecf709 |
+ struct cli_creds *client,
|
|
|
ecf709 |
+ const char *name)
|
|
|
ecf709 |
+{
|
|
|
ecf709 |
+ struct tevent_req *req = NULL;
|
|
|
ecf709 |
+ struct tevent_req *subreq = NULL;
|
|
|
ecf709 |
+ struct kcm_ccdb_uuid_by_name_state *state = NULL;
|
|
|
ecf709 |
+ errno_t ret;
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+ req = tevent_req_create(mem_ctx,
|
|
|
ecf709 |
+ &state,
|
|
|
ecf709 |
+ struct kcm_ccdb_uuid_by_name_state);
|
|
|
ecf709 |
+ if (req == NULL) {
|
|
|
ecf709 |
+ return NULL;
|
|
|
ecf709 |
+ }
|
|
|
ecf709 |
+ state->db = db;
|
|
|
ecf709 |
+ state->client = client;
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+ if (ev == NULL || db == NULL || client == NULL || name == NULL) {
|
|
|
ecf709 |
+ ret = EINVAL;
|
|
|
ecf709 |
+ goto immediate;
|
|
|
ecf709 |
+ }
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+ subreq = db->ops->uuid_by_name_send(state, ev, db, client, name);
|
|
|
ecf709 |
+ if (subreq == NULL) {
|
|
|
ecf709 |
+ ret = ENOMEM;
|
|
|
ecf709 |
+ goto immediate;
|
|
|
ecf709 |
+ }
|
|
|
ecf709 |
+ tevent_req_set_callback(subreq, kcm_ccdb_uuid_by_name_done, req);
|
|
|
ecf709 |
+ return req;
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+immediate:
|
|
|
ecf709 |
+ tevent_req_error(req, ret);
|
|
|
ecf709 |
+ tevent_req_post(req, ev);
|
|
|
ecf709 |
+ return req;
|
|
|
ecf709 |
+}
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+static void kcm_ccdb_uuid_by_name_done(struct tevent_req *subreq)
|
|
|
ecf709 |
+{
|
|
|
ecf709 |
+ struct tevent_req *req = tevent_req_callback_data(subreq,
|
|
|
ecf709 |
+ struct tevent_req);
|
|
|
ecf709 |
+ struct kcm_ccdb_uuid_by_name_state *state = tevent_req_data(req,
|
|
|
ecf709 |
+ struct kcm_ccdb_uuid_by_name_state);
|
|
|
ecf709 |
+ errno_t ret;
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+ ret = state->db->ops->uuid_by_name_recv(subreq, state, state->uuid);
|
|
|
ecf709 |
+ talloc_zfree(subreq);
|
|
|
ecf709 |
+ if (ret != EOK) {
|
|
|
ecf709 |
+ DEBUG(SSSDBG_OP_FAILURE,
|
|
|
ecf709 |
+ "Failed to resolve cache by UUID [%d]: %s\n",
|
|
|
ecf709 |
+ ret, sss_strerror(ret));
|
|
|
ecf709 |
+ tevent_req_error(req, ret);
|
|
|
ecf709 |
+ return;
|
|
|
ecf709 |
+ }
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+ tevent_req_done(req);
|
|
|
ecf709 |
+}
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+errno_t kcm_ccdb_uuid_by_name_recv(struct tevent_req *req,
|
|
|
ecf709 |
+ TALLOC_CTX *mem_ctx,
|
|
|
ecf709 |
+ uuid_t _uuid)
|
|
|
ecf709 |
+{
|
|
|
ecf709 |
+ struct kcm_ccdb_uuid_by_name_state *state = tevent_req_data(req,
|
|
|
ecf709 |
+ struct kcm_ccdb_uuid_by_name_state);
|
|
|
ecf709 |
+ TEVENT_REQ_RETURN_ON_ERROR(req);
|
|
|
ecf709 |
+ uuid_copy(_uuid, state->uuid);
|
|
|
ecf709 |
+ return EOK;
|
|
|
ecf709 |
+}
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+struct kcm_ccdb_create_cc_state {
|
|
|
ecf709 |
+ struct kcm_ccdb *db;
|
|
|
ecf709 |
+};
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+static void kcm_ccdb_create_done(struct tevent_req *subreq);
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+struct tevent_req *kcm_ccdb_create_cc_send(TALLOC_CTX *mem_ctx,
|
|
|
ecf709 |
+ struct tevent_context *ev,
|
|
|
ecf709 |
+ struct kcm_ccdb *db,
|
|
|
ecf709 |
+ struct cli_creds *client,
|
|
|
ecf709 |
+ struct kcm_ccache *cc)
|
|
|
ecf709 |
+{
|
|
|
ecf709 |
+ struct tevent_req *req = NULL;
|
|
|
ecf709 |
+ struct tevent_req *subreq = NULL;
|
|
|
ecf709 |
+ struct kcm_ccdb_create_cc_state *state = NULL;
|
|
|
ecf709 |
+ errno_t ret;
|
|
|
ecf709 |
+ bool ok;
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+ req = tevent_req_create(mem_ctx, &state, struct kcm_ccdb_create_cc_state);
|
|
|
ecf709 |
+ if (req == NULL) {
|
|
|
ecf709 |
+ return NULL;
|
|
|
ecf709 |
+ }
|
|
|
ecf709 |
+ state->db = db;
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+ if (ev == NULL || db == NULL || client == NULL || cc == NULL) {
|
|
|
ecf709 |
+ ret = EINVAL;
|
|
|
ecf709 |
+ goto immediate;
|
|
|
ecf709 |
+ }
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+ ok = kcm_cc_access(cc, client);
|
|
|
ecf709 |
+ if (!ok) {
|
|
|
ecf709 |
+ ret = EACCES;
|
|
|
ecf709 |
+ goto immediate;
|
|
|
ecf709 |
+ }
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+ subreq = state->db->ops->create_send(mem_ctx,
|
|
|
ecf709 |
+ ev,
|
|
|
ecf709 |
+ state->db,
|
|
|
ecf709 |
+ client,
|
|
|
ecf709 |
+ cc);
|
|
|
ecf709 |
+ if (subreq == NULL) {
|
|
|
ecf709 |
+ ret = ENOMEM;
|
|
|
ecf709 |
+ goto immediate;
|
|
|
ecf709 |
+ }
|
|
|
ecf709 |
+ tevent_req_set_callback(subreq, kcm_ccdb_create_done, req);
|
|
|
ecf709 |
+ return req;
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+immediate:
|
|
|
ecf709 |
+ tevent_req_error(req, ret);
|
|
|
ecf709 |
+ tevent_req_post(req, ev);
|
|
|
ecf709 |
+ return req;
|
|
|
ecf709 |
+}
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+static void kcm_ccdb_create_done(struct tevent_req *subreq)
|
|
|
ecf709 |
+{
|
|
|
ecf709 |
+ struct tevent_req *req = tevent_req_callback_data(subreq,
|
|
|
ecf709 |
+ struct tevent_req);
|
|
|
ecf709 |
+ struct kcm_ccdb_create_cc_state *state = tevent_req_data(req,
|
|
|
ecf709 |
+ struct kcm_ccdb_create_cc_state);
|
|
|
ecf709 |
+ errno_t ret;
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+ ret = state->db->ops->create_recv(subreq);
|
|
|
ecf709 |
+ talloc_zfree(subreq);
|
|
|
ecf709 |
+ if (ret != EOK) {
|
|
|
ecf709 |
+ DEBUG(SSSDBG_OP_FAILURE,
|
|
|
ecf709 |
+ "Failed to create ccache [%d]: %s\n",
|
|
|
ecf709 |
+ ret, sss_strerror(ret));
|
|
|
ecf709 |
+ tevent_req_error(req, ret);
|
|
|
ecf709 |
+ return;
|
|
|
ecf709 |
+ }
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+ tevent_req_done(req);
|
|
|
ecf709 |
+}
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+errno_t kcm_ccdb_create_cc_recv(struct tevent_req *req)
|
|
|
ecf709 |
+{
|
|
|
ecf709 |
+ TEVENT_REQ_RETURN_ON_ERROR(req);
|
|
|
ecf709 |
+ return EOK;
|
|
|
ecf709 |
+}
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+void kcm_mod_ctx_clear(struct kcm_mod_ctx *mod_ctx)
|
|
|
ecf709 |
+{
|
|
|
ecf709 |
+ if (mod_ctx == NULL) {
|
|
|
ecf709 |
+ return;
|
|
|
ecf709 |
+ }
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+ mod_ctx->kdc_offset = INT32_MAX;
|
|
|
ecf709 |
+}
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+void kcm_mod_cc(struct kcm_ccache *cc, struct kcm_mod_ctx *mod_ctx)
|
|
|
ecf709 |
+{
|
|
|
ecf709 |
+ if (cc == NULL || mod_ctx == NULL) {
|
|
|
ecf709 |
+ return;
|
|
|
ecf709 |
+ }
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+ if (mod_ctx->kdc_offset != INT32_MAX) {
|
|
|
ecf709 |
+ cc->kdc_offset = mod_ctx->kdc_offset;
|
|
|
ecf709 |
+ }
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+}
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+struct kcm_ccdb_mod_cc_state {
|
|
|
ecf709 |
+ struct kcm_ccdb *db;
|
|
|
ecf709 |
+};
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+static void kcm_ccdb_mod_done(struct tevent_req *subreq);
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+struct tevent_req *kcm_ccdb_mod_cc_send(TALLOC_CTX *mem_ctx,
|
|
|
ecf709 |
+ struct tevent_context *ev,
|
|
|
ecf709 |
+ struct kcm_ccdb *db,
|
|
|
ecf709 |
+ struct cli_creds *client,
|
|
|
ecf709 |
+ uuid_t uuid,
|
|
|
ecf709 |
+ struct kcm_mod_ctx *mod_cc)
|
|
|
ecf709 |
+{
|
|
|
ecf709 |
+ struct tevent_req *req = NULL;
|
|
|
ecf709 |
+ struct tevent_req *subreq = NULL;
|
|
|
ecf709 |
+ struct kcm_ccdb_mod_cc_state *state = NULL;
|
|
|
ecf709 |
+ errno_t ret;
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+ req = tevent_req_create(mem_ctx, &state, struct kcm_ccdb_mod_cc_state);
|
|
|
ecf709 |
+ if (req == NULL) {
|
|
|
ecf709 |
+ return NULL;
|
|
|
ecf709 |
+ }
|
|
|
ecf709 |
+ state->db = db;
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+ if (ev == NULL || db == NULL || client == NULL || mod_cc == NULL) {
|
|
|
ecf709 |
+ ret = EINVAL;
|
|
|
ecf709 |
+ goto immediate;
|
|
|
ecf709 |
+ }
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+ subreq = state->db->ops->mod_send(mem_ctx,
|
|
|
ecf709 |
+ ev,
|
|
|
ecf709 |
+ state->db,
|
|
|
ecf709 |
+ client,
|
|
|
ecf709 |
+ uuid,
|
|
|
ecf709 |
+ mod_cc);
|
|
|
ecf709 |
+ if (subreq == NULL) {
|
|
|
ecf709 |
+ ret = ENOMEM;
|
|
|
ecf709 |
+ goto immediate;
|
|
|
ecf709 |
+ }
|
|
|
ecf709 |
+ tevent_req_set_callback(subreq, kcm_ccdb_mod_done, req);
|
|
|
ecf709 |
+ return req;
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+immediate:
|
|
|
ecf709 |
+ tevent_req_error(req, ret);
|
|
|
ecf709 |
+ tevent_req_post(req, ev);
|
|
|
ecf709 |
+ return req;
|
|
|
ecf709 |
+}
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+static void kcm_ccdb_mod_done(struct tevent_req *subreq)
|
|
|
ecf709 |
+{
|
|
|
ecf709 |
+ struct tevent_req *req = tevent_req_callback_data(subreq,
|
|
|
ecf709 |
+ struct tevent_req);
|
|
|
ecf709 |
+ struct kcm_ccdb_mod_cc_state *state = tevent_req_data(req,
|
|
|
ecf709 |
+ struct kcm_ccdb_mod_cc_state);
|
|
|
ecf709 |
+ errno_t ret;
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+ ret = state->db->ops->mod_recv(subreq);
|
|
|
ecf709 |
+ talloc_zfree(subreq);
|
|
|
ecf709 |
+ if (ret != EOK) {
|
|
|
ecf709 |
+ DEBUG(SSSDBG_OP_FAILURE,
|
|
|
ecf709 |
+ "Failed to create ccache [%d]: %s\n",
|
|
|
ecf709 |
+ ret, sss_strerror(ret));
|
|
|
ecf709 |
+ tevent_req_error(req, ret);
|
|
|
ecf709 |
+ return;
|
|
|
ecf709 |
+ }
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+ tevent_req_done(req);
|
|
|
ecf709 |
+}
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+errno_t kcm_ccdb_mod_cc_recv(struct tevent_req *req)
|
|
|
ecf709 |
+{
|
|
|
ecf709 |
+ TEVENT_REQ_RETURN_ON_ERROR(req);
|
|
|
ecf709 |
+ return EOK;
|
|
|
ecf709 |
+}
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+struct kcm_ccdb_store_cred_blob_state {
|
|
|
ecf709 |
+ struct kcm_ccdb *db;
|
|
|
ecf709 |
+};
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+static void kcm_ccdb_store_cred_blob_done(struct tevent_req *subreq);
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+struct tevent_req *kcm_ccdb_store_cred_blob_send(TALLOC_CTX *mem_ctx,
|
|
|
ecf709 |
+ struct tevent_context *ev,
|
|
|
ecf709 |
+ struct kcm_ccdb *db,
|
|
|
ecf709 |
+ struct cli_creds *client,
|
|
|
ecf709 |
+ uuid_t uuid,
|
|
|
ecf709 |
+ struct sss_iobuf *cred_blob)
|
|
|
ecf709 |
+{
|
|
|
ecf709 |
+ struct tevent_req *req = NULL;
|
|
|
ecf709 |
+ struct tevent_req *subreq = NULL;
|
|
|
ecf709 |
+ struct kcm_ccdb_store_cred_blob_state *state = NULL;
|
|
|
ecf709 |
+ errno_t ret;
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+ req = tevent_req_create(mem_ctx, &state, struct kcm_ccdb_store_cred_blob_state);
|
|
|
ecf709 |
+ if (req == NULL) {
|
|
|
ecf709 |
+ return NULL;
|
|
|
ecf709 |
+ }
|
|
|
ecf709 |
+ state->db = db;
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+ if (ev == NULL || db == NULL || client == NULL || cred_blob == NULL) {
|
|
|
ecf709 |
+ ret = EINVAL;
|
|
|
ecf709 |
+ goto immediate;
|
|
|
ecf709 |
+ }
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+ subreq = state->db->ops->store_cred_send(mem_ctx,
|
|
|
ecf709 |
+ ev,
|
|
|
ecf709 |
+ state->db,
|
|
|
ecf709 |
+ client,
|
|
|
ecf709 |
+ uuid,
|
|
|
ecf709 |
+ cred_blob);
|
|
|
ecf709 |
+ if (subreq == NULL) {
|
|
|
ecf709 |
+ ret = ENOMEM;
|
|
|
ecf709 |
+ goto immediate;
|
|
|
ecf709 |
+ }
|
|
|
ecf709 |
+ tevent_req_set_callback(subreq, kcm_ccdb_store_cred_blob_done, req);
|
|
|
ecf709 |
+ return req;
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+immediate:
|
|
|
ecf709 |
+ tevent_req_error(req, ret);
|
|
|
ecf709 |
+ tevent_req_post(req, ev);
|
|
|
ecf709 |
+ return req;
|
|
|
ecf709 |
+}
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+static void kcm_ccdb_store_cred_blob_done(struct tevent_req *subreq)
|
|
|
ecf709 |
+{
|
|
|
ecf709 |
+ struct tevent_req *req = tevent_req_callback_data(subreq,
|
|
|
ecf709 |
+ struct tevent_req);
|
|
|
ecf709 |
+ struct kcm_ccdb_store_cred_blob_state *state = tevent_req_data(req,
|
|
|
ecf709 |
+ struct kcm_ccdb_store_cred_blob_state);
|
|
|
ecf709 |
+ errno_t ret;
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+ ret = state->db->ops->store_cred_recv(subreq);
|
|
|
ecf709 |
+ talloc_zfree(subreq);
|
|
|
ecf709 |
+ if (ret != EOK) {
|
|
|
ecf709 |
+ DEBUG(SSSDBG_OP_FAILURE,
|
|
|
ecf709 |
+ "Failed to create ccache [%d]: %s\n",
|
|
|
ecf709 |
+ ret, sss_strerror(ret));
|
|
|
ecf709 |
+ tevent_req_error(req, ret);
|
|
|
ecf709 |
+ return;
|
|
|
ecf709 |
+ }
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+ tevent_req_done(req);
|
|
|
ecf709 |
+}
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+errno_t kcm_ccdb_store_cred_blob_recv(struct tevent_req *req)
|
|
|
ecf709 |
+{
|
|
|
ecf709 |
+ TEVENT_REQ_RETURN_ON_ERROR(req);
|
|
|
ecf709 |
+ return EOK;
|
|
|
ecf709 |
+}
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+struct kcm_ccdb_delete_cc_state {
|
|
|
ecf709 |
+ struct tevent_context *ev;
|
|
|
ecf709 |
+ struct kcm_ccdb *db;
|
|
|
ecf709 |
+ struct cli_creds *client;
|
|
|
ecf709 |
+ uuid_t uuid;
|
|
|
ecf709 |
+};
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+static void kcm_ccdb_delete_done(struct tevent_req *subreq);
|
|
|
ecf709 |
+static void kcm_ccdb_delete_get_default_done(struct tevent_req *subreq);
|
|
|
ecf709 |
+static void kcm_ccdb_delete_default_reset_done(struct tevent_req *subreq);
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+struct tevent_req *kcm_ccdb_delete_cc_send(TALLOC_CTX *mem_ctx,
|
|
|
ecf709 |
+ struct tevent_context *ev,
|
|
|
ecf709 |
+ struct kcm_ccdb *db,
|
|
|
ecf709 |
+ struct cli_creds *client,
|
|
|
ecf709 |
+ uuid_t uuid)
|
|
|
ecf709 |
+{
|
|
|
ecf709 |
+ struct tevent_req *req = NULL;
|
|
|
ecf709 |
+ struct tevent_req *subreq = NULL;
|
|
|
ecf709 |
+ struct kcm_ccdb_delete_cc_state *state = NULL;
|
|
|
ecf709 |
+ errno_t ret;
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+ req = tevent_req_create(mem_ctx, &state, struct kcm_ccdb_delete_cc_state);
|
|
|
ecf709 |
+ if (req == NULL) {
|
|
|
ecf709 |
+ return NULL;
|
|
|
ecf709 |
+ }
|
|
|
ecf709 |
+ state->db = db;
|
|
|
ecf709 |
+ state->ev = ev;
|
|
|
ecf709 |
+ state->client = client;
|
|
|
ecf709 |
+ uuid_copy(state->uuid, uuid);
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+ if (ev == NULL || db == NULL || client == NULL) {
|
|
|
ecf709 |
+ ret = EINVAL;
|
|
|
ecf709 |
+ goto immediate;
|
|
|
ecf709 |
+ }
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+ subreq = state->db->ops->delete_send(state,
|
|
|
ecf709 |
+ state->ev,
|
|
|
ecf709 |
+ state->db,
|
|
|
ecf709 |
+ state->client,
|
|
|
ecf709 |
+ state->uuid);
|
|
|
ecf709 |
+ tevent_req_set_callback(subreq, kcm_ccdb_delete_done, req);
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+ return req;
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+immediate:
|
|
|
ecf709 |
+ tevent_req_error(req, ret);
|
|
|
ecf709 |
+ tevent_req_post(req, ev);
|
|
|
ecf709 |
+ return req;
|
|
|
ecf709 |
+}
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+static void kcm_ccdb_delete_done(struct tevent_req *subreq)
|
|
|
ecf709 |
+{
|
|
|
ecf709 |
+ struct tevent_req *req = tevent_req_callback_data(subreq,
|
|
|
ecf709 |
+ struct tevent_req);
|
|
|
ecf709 |
+ struct kcm_ccdb_delete_cc_state *state = tevent_req_data(req,
|
|
|
ecf709 |
+ struct kcm_ccdb_delete_cc_state);
|
|
|
ecf709 |
+ errno_t ret;
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+ ret = state->db->ops->delete_recv(subreq);
|
|
|
ecf709 |
+ talloc_zfree(subreq);
|
|
|
ecf709 |
+ if (ret != EOK) {
|
|
|
ecf709 |
+ DEBUG(SSSDBG_OP_FAILURE,
|
|
|
ecf709 |
+ "Failed to delete ccache [%d]: %s\n",
|
|
|
ecf709 |
+ ret, sss_strerror(ret));
|
|
|
ecf709 |
+ tevent_req_error(req, ret);
|
|
|
ecf709 |
+ return;
|
|
|
ecf709 |
+ }
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+ /* The delete operation must also check if the deleted ccache was
|
|
|
ecf709 |
+ * the default and reset the default if it was
|
|
|
ecf709 |
+ */
|
|
|
ecf709 |
+ subreq = state->db->ops->get_default_send(state,
|
|
|
ecf709 |
+ state->ev,
|
|
|
ecf709 |
+ state->db,
|
|
|
ecf709 |
+ state->client);
|
|
|
ecf709 |
+ if (subreq == NULL) {
|
|
|
ecf709 |
+ tevent_req_error(req, ENOMEM);
|
|
|
ecf709 |
+ return;
|
|
|
ecf709 |
+ }
|
|
|
ecf709 |
+ tevent_req_set_callback(subreq, kcm_ccdb_delete_get_default_done, req);
|
|
|
ecf709 |
+}
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+static void kcm_ccdb_delete_get_default_done(struct tevent_req *subreq)
|
|
|
ecf709 |
+{
|
|
|
ecf709 |
+ struct tevent_req *req = tevent_req_callback_data(subreq,
|
|
|
ecf709 |
+ struct tevent_req);
|
|
|
ecf709 |
+ struct kcm_ccdb_delete_cc_state *state = tevent_req_data(req,
|
|
|
ecf709 |
+ struct kcm_ccdb_delete_cc_state);
|
|
|
ecf709 |
+ errno_t ret;
|
|
|
ecf709 |
+ uuid_t dfl_uuid;
|
|
|
ecf709 |
+ uuid_t null_uuid;
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+ ret = state->db->ops->get_default_recv(subreq, dfl_uuid);
|
|
|
ecf709 |
+ talloc_zfree(subreq);
|
|
|
ecf709 |
+ if (ret != EOK) {
|
|
|
ecf709 |
+ DEBUG(SSSDBG_OP_FAILURE,
|
|
|
ecf709 |
+ "Failed to get the default ccache [%d]: %s\n",
|
|
|
ecf709 |
+ ret, sss_strerror(ret));
|
|
|
ecf709 |
+ tevent_req_error(req, ret);
|
|
|
ecf709 |
+ return;
|
|
|
ecf709 |
+ }
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+ if (uuid_compare(dfl_uuid, state->uuid) != 0) {
|
|
|
ecf709 |
+ /* The ccache about to be deleted was not the default, quit */
|
|
|
ecf709 |
+ tevent_req_done(req);
|
|
|
ecf709 |
+ return;
|
|
|
ecf709 |
+ }
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+ /* If we deleted the default ccache, reset the default ccache to 'none' */
|
|
|
ecf709 |
+ uuid_clear(null_uuid);
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+ subreq = state->db->ops->set_default_send(state,
|
|
|
ecf709 |
+ state->ev,
|
|
|
ecf709 |
+ state->db,
|
|
|
ecf709 |
+ state->client,
|
|
|
ecf709 |
+ null_uuid);
|
|
|
ecf709 |
+ if (subreq == NULL) {
|
|
|
ecf709 |
+ tevent_req_error(req, ENOMEM);
|
|
|
ecf709 |
+ return;
|
|
|
ecf709 |
+ }
|
|
|
ecf709 |
+ tevent_req_set_callback(subreq, kcm_ccdb_delete_default_reset_done, req);
|
|
|
ecf709 |
+}
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+static void kcm_ccdb_delete_default_reset_done(struct tevent_req *subreq)
|
|
|
ecf709 |
+{
|
|
|
ecf709 |
+ struct tevent_req *req = tevent_req_callback_data(subreq,
|
|
|
ecf709 |
+ struct tevent_req);
|
|
|
ecf709 |
+ struct kcm_ccdb_delete_cc_state *state = tevent_req_data(req,
|
|
|
ecf709 |
+ struct kcm_ccdb_delete_cc_state);
|
|
|
ecf709 |
+ errno_t ret;
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+ ret = state->db->ops->set_default_recv(subreq);
|
|
|
ecf709 |
+ talloc_zfree(subreq);
|
|
|
ecf709 |
+ if (ret != EOK) {
|
|
|
ecf709 |
+ DEBUG(SSSDBG_OP_FAILURE,
|
|
|
ecf709 |
+ "Failed to NULL the default ccache [%d]: %s\n",
|
|
|
ecf709 |
+ ret, sss_strerror(ret));
|
|
|
ecf709 |
+ tevent_req_error(req, ret);
|
|
|
ecf709 |
+ return;
|
|
|
ecf709 |
+ }
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+ tevent_req_done(req);
|
|
|
ecf709 |
+}
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+errno_t kcm_ccdb_delete_cc_recv(struct tevent_req *req)
|
|
|
ecf709 |
+{
|
|
|
ecf709 |
+ TEVENT_REQ_RETURN_ON_ERROR(req);
|
|
|
ecf709 |
+ return EOK;
|
|
|
ecf709 |
+}
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+void kcm_debug_uuid(uuid_t uuid)
|
|
|
ecf709 |
+{
|
|
|
ecf709 |
+ char dbgbuf[UUID_STR_SIZE];
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+ if (!(debug_level & SSSDBG_TRACE_ALL) || uuid == NULL) {
|
|
|
ecf709 |
+ return;
|
|
|
ecf709 |
+ }
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+ uuid_unparse(uuid, dbgbuf);
|
|
|
ecf709 |
+ DEBUG(SSSDBG_TRACE_ALL, "UUID: %s\n", dbgbuf);
|
|
|
ecf709 |
+}
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+errno_t kcm_check_name(const char *name, struct cli_creds *client)
|
|
|
ecf709 |
+{
|
|
|
ecf709 |
+ char prefix[64];
|
|
|
ecf709 |
+ size_t prefix_len;
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+ prefix_len = snprintf(prefix, sizeof(prefix),
|
|
|
ecf709 |
+ "%"SPRIuid, cli_creds_get_uid(client));
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+ if (strncmp(name, prefix, prefix_len) != 0) {
|
|
|
ecf709 |
+ return ERR_KCM_WRONG_CCNAME_FORMAT;
|
|
|
ecf709 |
+ }
|
|
|
ecf709 |
+ return EOK;
|
|
|
ecf709 |
+}
|
|
|
ecf709 |
diff --git a/src/responder/kcm/kcmsrv_ccache.h b/src/responder/kcm/kcmsrv_ccache.h
|
|
|
ecf709 |
new file mode 100644
|
|
|
ecf709 |
index 0000000000000000000000000000000000000000..130ae48ae30d5e1e2ab238a647a9b9dc76cc4945
|
|
|
ecf709 |
--- /dev/null
|
|
|
ecf709 |
+++ b/src/responder/kcm/kcmsrv_ccache.h
|
|
|
ecf709 |
@@ -0,0 +1,306 @@
|
|
|
ecf709 |
+/*
|
|
|
ecf709 |
+ SSSD
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+ KCM Server - the KCM ccache operations
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+ Copyright (C) Red Hat, 2016
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+ This program is free software; you can redistribute it and/or modify
|
|
|
ecf709 |
+ it under the terms of the GNU General Public License as published by
|
|
|
ecf709 |
+ the Free Software Foundation; either version 3 of the License, or
|
|
|
ecf709 |
+ (at your option) any later version.
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+ This program is distributed in the hope that it will be useful,
|
|
|
ecf709 |
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
ecf709 |
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
ecf709 |
+ GNU General Public License for more details.
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+ You should have received a copy of the GNU General Public License
|
|
|
ecf709 |
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
ecf709 |
+*/
|
|
|
ecf709 |
+#ifndef _KCMSRV_CCACHE_H_
|
|
|
ecf709 |
+#define _KCMSRV_CCACHE_H_
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+#include "config.h"
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+#include <krb5/krb5.h>
|
|
|
ecf709 |
+#include <uuid/uuid.h>
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+#include "util/util.h"
|
|
|
ecf709 |
+#include "util/sss_iobuf.h"
|
|
|
ecf709 |
+#include "util/util_creds.h"
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+#define UUID_BYTES 16
|
|
|
ecf709 |
+#define UUID_STR_SIZE 37
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+/*
|
|
|
ecf709 |
+ * Credentials are opaque to the KCM server
|
|
|
ecf709 |
+ *
|
|
|
ecf709 |
+ * Each ccache has a unique UUID.
|
|
|
ecf709 |
+ */
|
|
|
ecf709 |
+struct kcm_cred;
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+/*
|
|
|
ecf709 |
+ * An opaque ccache type and its operations
|
|
|
ecf709 |
+ *
|
|
|
ecf709 |
+ * Contains zero or some KCM credentials. One credential in the cache
|
|
|
ecf709 |
+ * is marked as the default one. The client can set and get the default
|
|
|
ecf709 |
+ * cache (e.g. with kswitch) but one cache is always the default -- we
|
|
|
ecf709 |
+ * fall back to the one created first.
|
|
|
ecf709 |
+ *
|
|
|
ecf709 |
+ * Each cache has a name and a UUID. Heimdal allows the name to be changed,
|
|
|
ecf709 |
+ * we don't (yet, because the MIT client doesn't allow that either)
|
|
|
ecf709 |
+ *
|
|
|
ecf709 |
+ * Each ccache also stores a client principal.
|
|
|
ecf709 |
+ */
|
|
|
ecf709 |
+struct kcm_ccache;
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+/*
|
|
|
ecf709 |
+ * Create a new KCM ccache owned by mem_ctx on the
|
|
|
ecf709 |
+ * memory level.
|
|
|
ecf709 |
+ *
|
|
|
ecf709 |
+ * When created, the ccache contains no credendials
|
|
|
ecf709 |
+ */
|
|
|
ecf709 |
+errno_t kcm_cc_new(TALLOC_CTX *mem_ctx,
|
|
|
ecf709 |
+ krb5_context k5c,
|
|
|
ecf709 |
+ struct cli_creds *owner,
|
|
|
ecf709 |
+ const char *name,
|
|
|
ecf709 |
+ krb5_principal princ,
|
|
|
ecf709 |
+ struct kcm_ccache **_cc);
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+/*
|
|
|
ecf709 |
+ * Returns true if a client can access a ccache.
|
|
|
ecf709 |
+ *
|
|
|
ecf709 |
+ * Note that root can access any ccache */
|
|
|
ecf709 |
+bool kcm_cc_access(struct kcm_ccache *cc,
|
|
|
ecf709 |
+ struct cli_creds *client);
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+/*
|
|
|
ecf709 |
+ * Since the kcm_ccache structure is opaque, the kcmsrv_ccache
|
|
|
ecf709 |
+ * layer contains a number of getsetters to read and write
|
|
|
ecf709 |
+ * properties of the kcm_ccache structure
|
|
|
ecf709 |
+ */
|
|
|
ecf709 |
+const char *kcm_cc_get_name(struct kcm_ccache *cc);
|
|
|
ecf709 |
+errno_t kcm_cc_get_uuid(struct kcm_ccache *cc, uuid_t _uuid);
|
|
|
ecf709 |
+krb5_principal kcm_cc_get_client_principal(struct kcm_ccache *cc);
|
|
|
ecf709 |
+int32_t kcm_cc_get_offset(struct kcm_ccache *cc);
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+/* Mainly useful for creating a cred structure from a persistent
|
|
|
ecf709 |
+ * storage
|
|
|
ecf709 |
+ */
|
|
|
ecf709 |
+struct kcm_cred *kcm_cred_new(TALLOC_CTX *mem_ctx,
|
|
|
ecf709 |
+ uuid_t uuid,
|
|
|
ecf709 |
+ struct sss_iobuf *cred_blob);
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+/* Add a cred to ccache */
|
|
|
ecf709 |
+errno_t kcm_cc_store_creds(struct kcm_ccache *cc,
|
|
|
ecf709 |
+ struct kcm_cred *crd);
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+errno_t kcm_cred_get_uuid(struct kcm_cred *crd, uuid_t uuid);
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+/*
|
|
|
ecf709 |
+ * At the moment, the credentials are stored without unmarshalling
|
|
|
ecf709 |
+ * them, just as the clients sends the credentials.
|
|
|
ecf709 |
+ */
|
|
|
ecf709 |
+struct sss_iobuf *kcm_cred_get_creds(struct kcm_cred *crd);
|
|
|
ecf709 |
+errno_t kcm_cc_store_cred_blob(struct kcm_ccache *cc,
|
|
|
ecf709 |
+ struct sss_iobuf *cred_blob);
|
|
|
ecf709 |
+ /*
|
|
|
ecf709 |
+ * The KCM server can call kcm_cred_get_creds to fetch the first
|
|
|
ecf709 |
+ * credential, then iterate over the credentials with
|
|
|
ecf709 |
+ * kcm_cc_next_cred until it returns NULL
|
|
|
ecf709 |
+ */
|
|
|
ecf709 |
+struct kcm_cred *kcm_cc_get_cred(struct kcm_ccache *cc);
|
|
|
ecf709 |
+struct kcm_cred *kcm_cc_next_cred(struct kcm_cred *crd);
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+enum kcm_ccdb_be {
|
|
|
ecf709 |
+ CCDB_BE_MEMORY,
|
|
|
ecf709 |
+ CCDB_BE_SECRETS,
|
|
|
ecf709 |
+};
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+/* An opaque database that contains all the ccaches */
|
|
|
ecf709 |
+struct kcm_ccdb;
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+/*
|
|
|
ecf709 |
+ * Initialize a ccache database of type cc_be
|
|
|
ecf709 |
+ */
|
|
|
ecf709 |
+struct kcm_ccdb *kcm_ccdb_init(TALLOC_CTX *mem_ctx,
|
|
|
ecf709 |
+ struct tevent_context *ev,
|
|
|
ecf709 |
+ enum kcm_ccdb_be cc_be);
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+/*
|
|
|
ecf709 |
+ * In KCM, each ccache name is usually in the form of "UID:<num>
|
|
|
ecf709 |
+ *
|
|
|
ecf709 |
+ * The <num> is generated by the KCM ccache database. Use this function
|
|
|
ecf709 |
+ * to retrieve the next number
|
|
|
ecf709 |
+ */
|
|
|
ecf709 |
+struct tevent_req *kcm_ccdb_nextid_send(TALLOC_CTX *mem_ctx,
|
|
|
ecf709 |
+ struct tevent_context *ev,
|
|
|
ecf709 |
+ struct kcm_ccdb *db,
|
|
|
ecf709 |
+ struct cli_creds *client);
|
|
|
ecf709 |
+errno_t kcm_ccdb_nextid_recv(struct tevent_req *req,
|
|
|
ecf709 |
+ TALLOC_CTX *mem_ctx,
|
|
|
ecf709 |
+ char **_nextid);
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+/*
|
|
|
ecf709 |
+ * List all ccaches that belong to a given client
|
|
|
ecf709 |
+ *
|
|
|
ecf709 |
+ * The cc_list the recv function returns is NULL-terminated.
|
|
|
ecf709 |
+ *
|
|
|
ecf709 |
+ * NOTE: Contrary to how Heimdal behaves, root CAN NOT list all ccaches
|
|
|
ecf709 |
+ * of all users. This is a deliberate decision to treat root as any other
|
|
|
ecf709 |
+ * user, except it can access a ccache of another user by name, just not
|
|
|
ecf709 |
+ * list them.
|
|
|
ecf709 |
+ *
|
|
|
ecf709 |
+ * If a client has no ccaches, the function returns OK, but an empty list
|
|
|
ecf709 |
+ * containing just the NULL sentinel.
|
|
|
ecf709 |
+ */
|
|
|
ecf709 |
+struct tevent_req *kcm_ccdb_list_send(TALLOC_CTX *mem_ctx,
|
|
|
ecf709 |
+ struct tevent_context *ev,
|
|
|
ecf709 |
+ struct kcm_ccdb *db,
|
|
|
ecf709 |
+ struct cli_creds *client);
|
|
|
ecf709 |
+errno_t kcm_ccdb_list_recv(struct tevent_req *req,
|
|
|
ecf709 |
+ TALLOC_CTX *mem_ctx,
|
|
|
ecf709 |
+ uuid_t **_uuid_list);
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+/*
|
|
|
ecf709 |
+ * Retrieve a ccache by name.
|
|
|
ecf709 |
+ *
|
|
|
ecf709 |
+ * If there is no such ccache, return EOK, but a NULL _cc pointer
|
|
|
ecf709 |
+ */
|
|
|
ecf709 |
+struct tevent_req *kcm_ccdb_getbyname_send(TALLOC_CTX *mem_ctx,
|
|
|
ecf709 |
+ struct tevent_context *ev,
|
|
|
ecf709 |
+ struct kcm_ccdb *db,
|
|
|
ecf709 |
+ struct cli_creds *client,
|
|
|
ecf709 |
+ const char *name);
|
|
|
ecf709 |
+errno_t kcm_ccdb_getbyname_recv(struct tevent_req *req,
|
|
|
ecf709 |
+ TALLOC_CTX *mem_ctx,
|
|
|
ecf709 |
+ struct kcm_ccache **_cc);
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+/*
|
|
|
ecf709 |
+ * Retrieve a ccache by UUID
|
|
|
ecf709 |
+ *
|
|
|
ecf709 |
+ * If there is no such ccache, return EOK, but a NULL _cc pointer
|
|
|
ecf709 |
+ */
|
|
|
ecf709 |
+struct tevent_req *kcm_ccdb_getbyuuid_send(TALLOC_CTX *mem_ctx,
|
|
|
ecf709 |
+ struct tevent_context *ev,
|
|
|
ecf709 |
+ struct kcm_ccdb *db,
|
|
|
ecf709 |
+ struct cli_creds *client,
|
|
|
ecf709 |
+ uuid_t uuid);
|
|
|
ecf709 |
+errno_t kcm_ccdb_getbyuuid_recv(struct tevent_req *req,
|
|
|
ecf709 |
+ TALLOC_CTX *mem_ctx,
|
|
|
ecf709 |
+ struct kcm_ccache **_cc);
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+/*
|
|
|
ecf709 |
+ * Retrieve the default ccache. If there is no default cache,
|
|
|
ecf709 |
+ * return EOK, but a NULL UUID.
|
|
|
ecf709 |
+ */
|
|
|
ecf709 |
+struct tevent_req *kcm_ccdb_get_default_send(TALLOC_CTX *mem_ctx,
|
|
|
ecf709 |
+ struct tevent_context *ev,
|
|
|
ecf709 |
+ struct kcm_ccdb *db,
|
|
|
ecf709 |
+ struct cli_creds *client);
|
|
|
ecf709 |
+errno_t kcm_ccdb_get_default_recv(struct tevent_req *req,
|
|
|
ecf709 |
+ uuid_t *uuid);
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+/*
|
|
|
ecf709 |
+ * Translating name to UUID is often considerably faster than doing a full
|
|
|
ecf709 |
+ * CC retrieval, hence this function and the converse. If the UUID cannot
|
|
|
ecf709 |
+ * be found in the database, return ERR_KCM_CC_END
|
|
|
ecf709 |
+ */
|
|
|
ecf709 |
+struct tevent_req *kcm_ccdb_name_by_uuid_send(TALLOC_CTX *mem_ctx,
|
|
|
ecf709 |
+ struct tevent_context *ev,
|
|
|
ecf709 |
+ struct kcm_ccdb *db,
|
|
|
ecf709 |
+ struct cli_creds *client,
|
|
|
ecf709 |
+ uuid_t uuid);
|
|
|
ecf709 |
+errno_t kcm_ccdb_name_by_uuid_recv(struct tevent_req *req,
|
|
|
ecf709 |
+ TALLOC_CTX *mem_ctx,
|
|
|
ecf709 |
+ const char **_name);
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+/*
|
|
|
ecf709 |
+ * Translating UUID to name is often considerably faster than doing a full
|
|
|
ecf709 |
+ * CC retrieval, hence this function and the converse. If the UUID cannot
|
|
|
ecf709 |
+ * be found in the database, return ERR_KCM_CC_END
|
|
|
ecf709 |
+ */
|
|
|
ecf709 |
+struct tevent_req *kcm_ccdb_uuid_by_name_send(TALLOC_CTX *mem_ctx,
|
|
|
ecf709 |
+ struct tevent_context *ev,
|
|
|
ecf709 |
+ struct kcm_ccdb *db,
|
|
|
ecf709 |
+ struct cli_creds *client,
|
|
|
ecf709 |
+ const char *name);
|
|
|
ecf709 |
+errno_t kcm_ccdb_uuid_by_name_recv(struct tevent_req *req,
|
|
|
ecf709 |
+ TALLOC_CTX *mem_ctx,
|
|
|
ecf709 |
+ uuid_t _uuid);
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+/*
|
|
|
ecf709 |
+ * Set the default ccache. Passing a NULL UUID is a legal operation
|
|
|
ecf709 |
+ * that 'unsets' the default ccache.
|
|
|
ecf709 |
+ */
|
|
|
ecf709 |
+struct tevent_req *kcm_ccdb_set_default_send(TALLOC_CTX *mem_ctx,
|
|
|
ecf709 |
+ struct tevent_context *ev,
|
|
|
ecf709 |
+ struct kcm_ccdb *db,
|
|
|
ecf709 |
+ struct cli_creds *client,
|
|
|
ecf709 |
+ uuid_t uuid);
|
|
|
ecf709 |
+errno_t kcm_ccdb_set_default_recv(struct tevent_req *req);
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+/*
|
|
|
ecf709 |
+ * Add a ccache to the database.
|
|
|
ecf709 |
+ */
|
|
|
ecf709 |
+struct tevent_req *kcm_ccdb_create_cc_send(TALLOC_CTX *mem_ctx,
|
|
|
ecf709 |
+ struct tevent_context *ev,
|
|
|
ecf709 |
+ struct kcm_ccdb *db,
|
|
|
ecf709 |
+ struct cli_creds *client,
|
|
|
ecf709 |
+ struct kcm_ccache *cc);
|
|
|
ecf709 |
+errno_t kcm_ccdb_create_cc_recv(struct tevent_req *req);
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+/*
|
|
|
ecf709 |
+ * Modify cache properties in a db
|
|
|
ecf709 |
+ */
|
|
|
ecf709 |
+struct kcm_mod_ctx {
|
|
|
ecf709 |
+ int32_t kdc_offset;
|
|
|
ecf709 |
+ /* More settable properties (like name, when we support renames
|
|
|
ecf709 |
+ * will be added later
|
|
|
ecf709 |
+ */
|
|
|
ecf709 |
+};
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+void kcm_mod_ctx_clear(struct kcm_mod_ctx *mod_ctx);
|
|
|
ecf709 |
+void kcm_mod_cc(struct kcm_ccache *cc, struct kcm_mod_ctx *mod_ctx);
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+struct tevent_req *kcm_ccdb_mod_cc_send(TALLOC_CTX *mem_ctx,
|
|
|
ecf709 |
+ struct tevent_context *ev,
|
|
|
ecf709 |
+ struct kcm_ccdb *db,
|
|
|
ecf709 |
+ struct cli_creds *client,
|
|
|
ecf709 |
+ uuid_t uuid,
|
|
|
ecf709 |
+ struct kcm_mod_ctx *mod_cc);
|
|
|
ecf709 |
+errno_t kcm_ccdb_mod_cc_recv(struct tevent_req *req);
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+/*
|
|
|
ecf709 |
+ * Store a credential in a cache
|
|
|
ecf709 |
+ */
|
|
|
ecf709 |
+struct tevent_req *kcm_ccdb_store_cred_blob_send(TALLOC_CTX *mem_ctx,
|
|
|
ecf709 |
+ struct tevent_context *ev,
|
|
|
ecf709 |
+ struct kcm_ccdb *db,
|
|
|
ecf709 |
+ struct cli_creds *client,
|
|
|
ecf709 |
+ uuid_t uuid,
|
|
|
ecf709 |
+ struct sss_iobuf *cred_blob);
|
|
|
ecf709 |
+errno_t kcm_ccdb_store_cred_blob_recv(struct tevent_req *req);
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+/*
|
|
|
ecf709 |
+ * Delete a ccache from the database
|
|
|
ecf709 |
+ */
|
|
|
ecf709 |
+struct tevent_req *kcm_ccdb_delete_cc_send(TALLOC_CTX *mem_ctx,
|
|
|
ecf709 |
+ struct tevent_context *ev,
|
|
|
ecf709 |
+ struct kcm_ccdb *db,
|
|
|
ecf709 |
+ struct cli_creds *client,
|
|
|
ecf709 |
+ uuid_t uuid);
|
|
|
ecf709 |
+errno_t kcm_ccdb_delete_cc_recv(struct tevent_req *req);
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+void kcm_debug_uuid(uuid_t uuid);
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+/*
|
|
|
ecf709 |
+ * The KCM clients are not allowed (except root) to create ccaches
|
|
|
ecf709 |
+ * with arbitrary names. Instead, we assert that the ccache name
|
|
|
ecf709 |
+ * begins with UID where UID is the stringified representation of
|
|
|
ecf709 |
+ * the client's UID number
|
|
|
ecf709 |
+ */
|
|
|
ecf709 |
+errno_t kcm_check_name(const char *name, struct cli_creds *client);
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+#endif /* _KCMSRV_CCACHE_H_ */
|
|
|
ecf709 |
diff --git a/src/responder/kcm/kcmsrv_ccache_be.h b/src/responder/kcm/kcmsrv_ccache_be.h
|
|
|
ecf709 |
new file mode 100644
|
|
|
ecf709 |
index 0000000000000000000000000000000000000000..1bd2b6981e227675866e82e0a5389445cac4df66
|
|
|
ecf709 |
--- /dev/null
|
|
|
ecf709 |
+++ b/src/responder/kcm/kcmsrv_ccache_be.h
|
|
|
ecf709 |
@@ -0,0 +1,204 @@
|
|
|
ecf709 |
+/*
|
|
|
ecf709 |
+ SSSD
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+ KCM Server - the KCM ccache database interface
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+ This file should only be included from the ccache.c module.
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+ Copyright (C) Red Hat, 2016
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+ This program is free software; you can redistribute it and/or modify
|
|
|
ecf709 |
+ it under the terms of the GNU General Public License as published by
|
|
|
ecf709 |
+ the Free Software Foundation; either version 3 of the License, or
|
|
|
ecf709 |
+ (at your option) any later version.
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+ This program is distributed in the hope that it will be useful,
|
|
|
ecf709 |
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
ecf709 |
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
ecf709 |
+ GNU General Public License for more details.
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+ You should have received a copy of the GNU General Public License
|
|
|
ecf709 |
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
ecf709 |
+*/
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+#ifndef _KCMSRV_CCACHE_BE_
|
|
|
ecf709 |
+#define _KCMSRV_CCACHE_BE_
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+#include "config.h"
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+#include <talloc.h>
|
|
|
ecf709 |
+#include "responder/kcm/kcmsrv_ccache.h"
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+typedef errno_t
|
|
|
ecf709 |
+(*ccdb_init_fn)(struct kcm_ccdb *db);
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+typedef struct tevent_req *
|
|
|
ecf709 |
+(*ccdb_nextid_send_fn)(TALLOC_CTX *mem_ctx,
|
|
|
ecf709 |
+ struct tevent_context *ev,
|
|
|
ecf709 |
+ struct kcm_ccdb *db,
|
|
|
ecf709 |
+ struct cli_creds *client);
|
|
|
ecf709 |
+typedef errno_t
|
|
|
ecf709 |
+(*ccdb_nextid_recv_fn)(struct tevent_req *req,
|
|
|
ecf709 |
+ unsigned int *_nextid);
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+typedef struct tevent_req *
|
|
|
ecf709 |
+(*ccdb_set_default_send_fn)(TALLOC_CTX *mem_ctx,
|
|
|
ecf709 |
+ struct tevent_context *ev,
|
|
|
ecf709 |
+ struct kcm_ccdb *db,
|
|
|
ecf709 |
+ struct cli_creds *client,
|
|
|
ecf709 |
+ uuid_t uuid);
|
|
|
ecf709 |
+typedef errno_t
|
|
|
ecf709 |
+(*ccdb_set_default_recv_fn)(struct tevent_req *req);
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+typedef struct tevent_req *
|
|
|
ecf709 |
+(*ccdb_get_default_send_fn)(TALLOC_CTX *mem_ctx,
|
|
|
ecf709 |
+ struct tevent_context *ev,
|
|
|
ecf709 |
+ struct kcm_ccdb *db,
|
|
|
ecf709 |
+ struct cli_creds *client);
|
|
|
ecf709 |
+typedef errno_t
|
|
|
ecf709 |
+(*ccdb_get_default_recv_fn)(struct tevent_req *req,
|
|
|
ecf709 |
+ uuid_t dfl);
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+typedef struct tevent_req *
|
|
|
ecf709 |
+(*ccdb_list_send_fn)(TALLOC_CTX *mem_ctx,
|
|
|
ecf709 |
+ struct tevent_context *ev,
|
|
|
ecf709 |
+ struct kcm_ccdb *db,
|
|
|
ecf709 |
+ struct cli_creds *client);
|
|
|
ecf709 |
+typedef errno_t
|
|
|
ecf709 |
+(*ccdb_list_recv_fn)(struct tevent_req *req,
|
|
|
ecf709 |
+ TALLOC_CTX *mem_ctx,
|
|
|
ecf709 |
+ uuid_t **_uuid_list);
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+typedef struct tevent_req *
|
|
|
ecf709 |
+(*ccdb_getbyname_send_fn)(TALLOC_CTX *mem_ctx,
|
|
|
ecf709 |
+ struct tevent_context *ev,
|
|
|
ecf709 |
+ struct kcm_ccdb *db,
|
|
|
ecf709 |
+ struct cli_creds *client,
|
|
|
ecf709 |
+ const char *name);
|
|
|
ecf709 |
+typedef errno_t
|
|
|
ecf709 |
+(*ccdb_getbyname_recv_fn)(struct tevent_req *req,
|
|
|
ecf709 |
+ TALLOC_CTX *mem_ctx,
|
|
|
ecf709 |
+ struct kcm_ccache **_cc);
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+typedef struct tevent_req *
|
|
|
ecf709 |
+(*ccdb_getbyuuid_send_fn)(TALLOC_CTX *mem_ctx,
|
|
|
ecf709 |
+ struct tevent_context *ev,
|
|
|
ecf709 |
+ struct kcm_ccdb *db,
|
|
|
ecf709 |
+ struct cli_creds *client,
|
|
|
ecf709 |
+ uuid_t uuid);
|
|
|
ecf709 |
+typedef errno_t
|
|
|
ecf709 |
+(*ccdb_getbyuuid_recv_fn)(struct tevent_req *req,
|
|
|
ecf709 |
+ TALLOC_CTX *mem_ctx,
|
|
|
ecf709 |
+ struct kcm_ccache **_cc);
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+typedef struct tevent_req *
|
|
|
ecf709 |
+(*ccdb_name_by_uuid_send_fn)(TALLOC_CTX *mem_ctx,
|
|
|
ecf709 |
+ struct tevent_context *ev,
|
|
|
ecf709 |
+ struct kcm_ccdb *db,
|
|
|
ecf709 |
+ struct cli_creds *client,
|
|
|
ecf709 |
+ uuid_t uuid);
|
|
|
ecf709 |
+typedef errno_t
|
|
|
ecf709 |
+(*ccdb_name_by_uuid_recv_fn)(struct tevent_req *req,
|
|
|
ecf709 |
+ TALLOC_CTX *mem_ctx,
|
|
|
ecf709 |
+ const char **_name);
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+typedef struct tevent_req *
|
|
|
ecf709 |
+(*ccdb_uuid_by_name_send_fn)(TALLOC_CTX *mem_ctx,
|
|
|
ecf709 |
+ struct tevent_context *ev,
|
|
|
ecf709 |
+ struct kcm_ccdb *db,
|
|
|
ecf709 |
+ struct cli_creds *client,
|
|
|
ecf709 |
+ const char *name);
|
|
|
ecf709 |
+typedef errno_t
|
|
|
ecf709 |
+(*ccdb_uuid_by_name_recv_fn)(struct tevent_req *req,
|
|
|
ecf709 |
+ TALLOC_CTX *mem_ctx,
|
|
|
ecf709 |
+ uuid_t _uuid);
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+typedef struct tevent_req *
|
|
|
ecf709 |
+(*ccdb_create_send_fn)(TALLOC_CTX *mem_ctx,
|
|
|
ecf709 |
+ struct tevent_context *ev,
|
|
|
ecf709 |
+ struct kcm_ccdb *db,
|
|
|
ecf709 |
+ struct cli_creds *client,
|
|
|
ecf709 |
+ struct kcm_ccache *cc);
|
|
|
ecf709 |
+typedef errno_t
|
|
|
ecf709 |
+(*ccdb_create_recv_fn)(struct tevent_req *req);
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+typedef struct tevent_req *
|
|
|
ecf709 |
+(*ccdb_mod_send_fn)(TALLOC_CTX *mem_ctx,
|
|
|
ecf709 |
+ struct tevent_context *ev,
|
|
|
ecf709 |
+ struct kcm_ccdb *db,
|
|
|
ecf709 |
+ struct cli_creds *client,
|
|
|
ecf709 |
+ uuid_t uuid,
|
|
|
ecf709 |
+ struct kcm_mod_ctx *mod_cc);
|
|
|
ecf709 |
+typedef errno_t
|
|
|
ecf709 |
+(*ccdb_mod_recv_fn)(struct tevent_req *req);
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+typedef struct tevent_req *
|
|
|
ecf709 |
+(*kcm_ccdb_store_cred_blob_send_fn)(TALLOC_CTX *mem_ctx,
|
|
|
ecf709 |
+ struct tevent_context *ev,
|
|
|
ecf709 |
+ struct kcm_ccdb *db,
|
|
|
ecf709 |
+ struct cli_creds *client,
|
|
|
ecf709 |
+ uuid_t uuid,
|
|
|
ecf709 |
+ struct sss_iobuf *cred_blob);
|
|
|
ecf709 |
+typedef errno_t
|
|
|
ecf709 |
+(*kcm_ccdb_store_cred_blob_recv_fn)(struct tevent_req *req);
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+typedef struct tevent_req *
|
|
|
ecf709 |
+(*ccdb_delete_send_fn)(TALLOC_CTX *mem_ctx,
|
|
|
ecf709 |
+ struct tevent_context *ev,
|
|
|
ecf709 |
+ struct kcm_ccdb *db,
|
|
|
ecf709 |
+ struct cli_creds *client,
|
|
|
ecf709 |
+ uuid_t uuid);
|
|
|
ecf709 |
+typedef errno_t
|
|
|
ecf709 |
+(*ccdb_delete_recv_fn)(struct tevent_req *req);
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+/*
|
|
|
ecf709 |
+ * Each ccache back end (for example memory or secrets) must implement
|
|
|
ecf709 |
+ * all these functions. The functions are wrapped by the kcm_ccdb
|
|
|
ecf709 |
+ * interface that performs additional sanity checks or contains shared
|
|
|
ecf709 |
+ * logic such as access checks but in general doesn't assume anything
|
|
|
ecf709 |
+ * about how the operations work.
|
|
|
ecf709 |
+ */
|
|
|
ecf709 |
+struct kcm_ccdb_ops {
|
|
|
ecf709 |
+ ccdb_init_fn init;
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+ ccdb_nextid_send_fn nextid_send;
|
|
|
ecf709 |
+ ccdb_nextid_recv_fn nextid_recv;
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+ ccdb_set_default_send_fn set_default_send;
|
|
|
ecf709 |
+ ccdb_set_default_recv_fn set_default_recv;
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+ ccdb_get_default_send_fn get_default_send;
|
|
|
ecf709 |
+ ccdb_get_default_recv_fn get_default_recv;
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+ ccdb_list_send_fn list_send;
|
|
|
ecf709 |
+ ccdb_list_recv_fn list_recv;
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+ ccdb_getbyname_send_fn getbyname_send;
|
|
|
ecf709 |
+ ccdb_getbyname_recv_fn getbyname_recv;
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+ ccdb_getbyuuid_send_fn getbyuuid_send;
|
|
|
ecf709 |
+ ccdb_getbyuuid_recv_fn getbyuuid_recv;
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+ ccdb_name_by_uuid_send_fn name_by_uuid_send;
|
|
|
ecf709 |
+ ccdb_name_by_uuid_recv_fn name_by_uuid_recv;
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+ ccdb_uuid_by_name_send_fn uuid_by_name_send;
|
|
|
ecf709 |
+ ccdb_uuid_by_name_recv_fn uuid_by_name_recv;
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+ ccdb_create_send_fn create_send;
|
|
|
ecf709 |
+ ccdb_create_recv_fn create_recv;
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+ ccdb_mod_send_fn mod_send;
|
|
|
ecf709 |
+ ccdb_mod_recv_fn mod_recv;
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+ kcm_ccdb_store_cred_blob_send_fn store_cred_send;
|
|
|
ecf709 |
+ kcm_ccdb_store_cred_blob_recv_fn store_cred_recv;
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+ ccdb_delete_send_fn delete_send;
|
|
|
ecf709 |
+ ccdb_delete_recv_fn delete_recv;
|
|
|
ecf709 |
+};
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+extern const struct kcm_ccdb_ops ccdb_mem_ops;
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+#endif /* _KCMSRV_CCACHE_BE_ */
|
|
|
ecf709 |
diff --git a/src/responder/kcm/kcmsrv_ccache_pvt.h b/src/responder/kcm/kcmsrv_ccache_pvt.h
|
|
|
ecf709 |
new file mode 100644
|
|
|
ecf709 |
index 0000000000000000000000000000000000000000..0cc24c2b8cd4d44080d2aa4384f7b2a73520c5a0
|
|
|
ecf709 |
--- /dev/null
|
|
|
ecf709 |
+++ b/src/responder/kcm/kcmsrv_ccache_pvt.h
|
|
|
ecf709 |
@@ -0,0 +1,62 @@
|
|
|
ecf709 |
+/*
|
|
|
ecf709 |
+ SSSD
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+ KCM Server - the KCM ccache operations - private structures
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+ Should be accessed only from the ccache layer.
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+ Copyright (C) Red Hat, 2016
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+ This program is free software; you can redistribute it and/or modify
|
|
|
ecf709 |
+ it under the terms of the GNU General Public License as published by
|
|
|
ecf709 |
+ the Free Software Foundation; either version 3 of the License, or
|
|
|
ecf709 |
+ (at your option) any later version.
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+ This program is distributed in the hope that it will be useful,
|
|
|
ecf709 |
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
ecf709 |
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
ecf709 |
+ GNU General Public License for more details.
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+ You should have received a copy of the GNU General Public License
|
|
|
ecf709 |
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
ecf709 |
+*/
|
|
|
ecf709 |
+#ifndef _KCMSRV_CCACHE_PVT_H
|
|
|
ecf709 |
+#define _KCMSRV_CCACHE_PVT_H
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+#include "responder/kcm/kcmsrv_ccache.h"
|
|
|
ecf709 |
+#include "responder/kcm/kcmsrv_ccache_be.h"
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+struct kcm_ccache_owner {
|
|
|
ecf709 |
+ uid_t uid;
|
|
|
ecf709 |
+ gid_t gid;
|
|
|
ecf709 |
+};
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+struct kcm_cred {
|
|
|
ecf709 |
+ struct sss_iobuf *cred_blob;
|
|
|
ecf709 |
+ /* Randomly generated 16 bytes */
|
|
|
ecf709 |
+ uuid_t uuid;
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+ struct kcm_cred *next;
|
|
|
ecf709 |
+ struct kcm_cred *prev;
|
|
|
ecf709 |
+};
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+struct kcm_ccdb {
|
|
|
ecf709 |
+ enum kcm_ccdb_be cc_be_type;
|
|
|
ecf709 |
+ struct tevent_context *ev;
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+ void *db_handle;
|
|
|
ecf709 |
+ const struct kcm_ccdb_ops *ops;
|
|
|
ecf709 |
+};
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+struct kcm_ccache {
|
|
|
ecf709 |
+ const char *name;
|
|
|
ecf709 |
+ struct kcm_ccache_owner owner;
|
|
|
ecf709 |
+ uuid_t uuid;
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+ krb5_principal client;
|
|
|
ecf709 |
+ int32_t kdc_offset;
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+ struct kcm_cred *creds;
|
|
|
ecf709 |
+};
|
|
|
ecf709 |
+
|
|
|
ecf709 |
+#endif /* _KCMSRV_CCACHE_PVT_H */
|
|
|
ecf709 |
diff --git a/src/responder/kcm/kcmsrv_pvt.h b/src/responder/kcm/kcmsrv_pvt.h
|
|
|
ecf709 |
index fd1fd9fa32d59a323d465def68999f24f84e3923..a29680246c1e616da75e1bbff951ce2fad66fb65 100644
|
|
|
ecf709 |
--- a/src/responder/kcm/kcmsrv_pvt.h
|
|
|
ecf709 |
+++ b/src/responder/kcm/kcmsrv_pvt.h
|
|
|
ecf709 |
@@ -46,6 +46,7 @@ struct kcm_data {
|
|
|
ecf709 |
*/
|
|
|
ecf709 |
struct kcm_resp_ctx {
|
|
|
ecf709 |
krb5_context k5c;
|
|
|
ecf709 |
+ struct kcm_ccdb *db;
|
|
|
ecf709 |
};
|
|
|
ecf709 |
|
|
|
ecf709 |
/*
|
|
|
ecf709 |
--
|
|
|
ecf709 |
2.9.3
|
|
|
ecf709 |
|