summaryrefslogtreecommitdiffstats
path: root/src/responder/kcm/kcmsrv_ccache.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/responder/kcm/kcmsrv_ccache.h')
-rw-r--r--src/responder/kcm/kcmsrv_ccache.h380
1 files changed, 380 insertions, 0 deletions
diff --git a/src/responder/kcm/kcmsrv_ccache.h b/src/responder/kcm/kcmsrv_ccache.h
new file mode 100644
index 0000000..1061ee2
--- /dev/null
+++ b/src/responder/kcm/kcmsrv_ccache.h
@@ -0,0 +1,380 @@
+/*
+ SSSD
+
+ KCM Server - the KCM ccache operations
+
+ Copyright (C) Red Hat, 2016
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+#ifndef _KCMSRV_CCACHE_H_
+#define _KCMSRV_CCACHE_H_
+
+#include "config.h"
+
+#include <krb5/krb5.h>
+#include <uuid/uuid.h>
+
+#include "util/util.h"
+#include "util/sss_iobuf.h"
+#include "util/util_creds.h"
+#include "providers/krb5/krb5_common.h"
+#include "responder/kcm/kcmsrv_pvt.h"
+
+#define UUID_BYTES 16
+#define UUID_STR_SIZE 37
+
+/* Just to keep the name of the ccache readable */
+#define MAX_CC_NUM 99999
+
+/*
+ * Credentials are opaque to the KCM server
+ *
+ * Each ccache has a unique UUID.
+ */
+struct kcm_cred;
+
+/*
+ * An opaque ccache type and its operations
+ *
+ * Contains zero or some KCM credentials. One credential in the cache
+ * is marked as the default one. The client can set and get the default
+ * cache (e.g. with kswitch) but one cache is always the default -- we
+ * fall back to the one created first.
+ *
+ * Each cache has a name and a UUID. Heimdal allows the name to be changed,
+ * we don't (yet, because the MIT client doesn't allow that either)
+ *
+ * Each ccache also stores a client principal.
+ */
+struct kcm_ccache;
+
+/*
+ * Create a new KCM ccache owned by mem_ctx on the
+ * memory level.
+ *
+ * When created, the ccache contains no credentials
+ */
+errno_t kcm_cc_new(TALLOC_CTX *mem_ctx,
+ krb5_context k5c,
+ struct cli_creds *owner,
+ const char *name,
+ 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.
+ *
+ * Note that root can access any ccache */
+bool kcm_cc_access(struct kcm_ccache *cc,
+ struct cli_creds *client);
+
+/*
+ * Since the kcm_ccache structure is opaque, the kcmsrv_ccache
+ * layer contains a number of getsetters to read and write
+ * properties of the kcm_ccache structure
+ */
+const char *kcm_cc_get_name(struct kcm_ccache *cc);
+errno_t kcm_cc_get_uuid(struct kcm_ccache *cc, uuid_t _uuid);
+krb5_principal kcm_cc_get_client_principal(struct kcm_ccache *cc);
+int32_t kcm_cc_get_offset(struct kcm_ccache *cc);
+
+/* Mainly useful for creating a cred structure from a persistent
+ * storage
+ */
+struct kcm_cred *kcm_cred_new(TALLOC_CTX *mem_ctx,
+ uuid_t uuid,
+ struct sss_iobuf *cred_blob);
+
+/* Add a cred to ccache */
+errno_t kcm_cc_store_creds(struct kcm_ccache *cc,
+ struct kcm_cred *crd);
+
+/* Set cc header information from sec key and client */
+errno_t kcm_cc_set_header(struct kcm_ccache *cc,
+ const char *sec_key,
+ struct cli_creds *client);
+
+krb5_creds **kcm_cc_unmarshal(TALLOC_CTX *mem_ctx,
+ krb5_context krb_context,
+ struct kcm_ccache *cc);
+
+errno_t kcm_cred_get_uuid(struct kcm_cred *crd, uuid_t uuid);
+
+/*
+ * At the moment, the credentials are stored without unmarshalling
+ * them, just as the clients sends the credentials.
+ */
+struct sss_iobuf *kcm_cred_get_creds(struct kcm_cred *crd);
+errno_t kcm_cc_store_cred_blob(struct kcm_ccache *cc,
+ struct sss_iobuf *cred_blob);
+ /*
+ * The KCM server can call kcm_cred_get_creds to fetch the first
+ * credential, then iterate over the credentials with
+ * kcm_cc_next_cred until it returns NULL
+ */
+struct kcm_cred *kcm_cc_get_cred(struct kcm_ccache *cc);
+struct kcm_cred *kcm_cc_next_cred(struct kcm_cred *crd);
+
+/* An opaque database that contains all the ccaches */
+struct kcm_ccdb;
+
+/*
+ * Initialize a ccache database of type cc_be
+ */
+struct kcm_ccdb *kcm_ccdb_init(TALLOC_CTX *mem_ctx,
+ struct tevent_context *ev,
+ struct confdb_ctx *cdb,
+ const char *confdb_service_path,
+ enum kcm_ccdb_be cc_be);
+/*
+ * Prepare KCM ccache list for renewals
+ */
+errno_t kcm_ccdb_renew_tgts(TALLOC_CTX *mem_ctx,
+ struct krb5_ctx *kctx,
+ struct tevent_context *ev,
+ struct kcm_ccdb *cdb,
+ struct kcm_ccache ***_cc_list);
+
+/*
+ * In KCM, each ccache name is usually in the form of "UID:<num>
+ *
+ * The <num> is generated by the KCM ccache database. Use this function
+ * to retrieve the next number
+ */
+struct tevent_req *kcm_ccdb_nextid_send(TALLOC_CTX *mem_ctx,
+ struct tevent_context *ev,
+ struct kcm_ccdb *db,
+ struct cli_creds *client);
+errno_t kcm_ccdb_nextid_recv(struct tevent_req *req,
+ TALLOC_CTX *mem_ctx,
+ char **_nextid);
+
+/*
+ * List all ccaches that belong to a given client
+ *
+ * The cc_list the recv function returns is NULL-terminated.
+ *
+ * NOTE: Contrary to how Heimdal behaves, root CAN NOT list all ccaches
+ * of all users. This is a deliberate decision to treat root as any other
+ * user, except it can access a ccache of another user by name, just not
+ * list them.
+ *
+ * If a client has no ccaches, the function returns OK, but an empty list
+ * containing just the NULL sentinel.
+ */
+struct tevent_req *kcm_ccdb_list_send(TALLOC_CTX *mem_ctx,
+ struct tevent_context *ev,
+ struct kcm_ccdb *db,
+ struct cli_creds *client);
+errno_t kcm_ccdb_list_recv(struct tevent_req *req,
+ TALLOC_CTX *mem_ctx,
+ uuid_t **_uuid_list);
+
+/*
+ * Retrieve a ccache by name.
+ *
+ * If there is no such ccache, return EOK, but a NULL _cc pointer
+ */
+struct tevent_req *kcm_ccdb_getbyname_send(TALLOC_CTX *mem_ctx,
+ struct tevent_context *ev,
+ struct kcm_ccdb *db,
+ struct cli_creds *client,
+ const char *name);
+errno_t kcm_ccdb_getbyname_recv(struct tevent_req *req,
+ TALLOC_CTX *mem_ctx,
+ struct kcm_ccache **_cc);
+
+/*
+ * Retrieve a ccache by UUID
+ *
+ * If there is no such ccache, return EOK, but a NULL _cc pointer
+ */
+struct tevent_req *kcm_ccdb_getbyuuid_send(TALLOC_CTX *mem_ctx,
+ struct tevent_context *ev,
+ struct kcm_ccdb *db,
+ struct cli_creds *client,
+ uuid_t uuid);
+errno_t kcm_ccdb_getbyuuid_recv(struct tevent_req *req,
+ TALLOC_CTX *mem_ctx,
+ struct kcm_ccache **_cc);
+
+/*
+ * Retrieve the default ccache. If there is no default cache,
+ * return EOK, but a NULL UUID.
+ */
+struct tevent_req *kcm_ccdb_get_default_send(TALLOC_CTX *mem_ctx,
+ struct tevent_context *ev,
+ struct kcm_ccdb *db,
+ struct cli_creds *client);
+errno_t kcm_ccdb_get_default_recv(struct tevent_req *req,
+ uuid_t *uuid);
+
+/*
+ * Translating name to UUID is often considerably faster than doing a full
+ * CC retrieval, hence this function and the converse. If the UUID cannot
+ * be found in the database, return ERR_KCM_CC_END
+ */
+struct tevent_req *kcm_ccdb_name_by_uuid_send(TALLOC_CTX *mem_ctx,
+ struct tevent_context *ev,
+ struct kcm_ccdb *db,
+ struct cli_creds *client,
+ uuid_t uuid);
+errno_t kcm_ccdb_name_by_uuid_recv(struct tevent_req *req,
+ TALLOC_CTX *mem_ctx,
+ const char **_name);
+
+/*
+ * Translating UUID to name is often considerably faster than doing a full
+ * CC retrieval, hence this function and the converse. If the UUID cannot
+ * be found in the database, return ERR_KCM_CC_END
+ */
+struct tevent_req *kcm_ccdb_uuid_by_name_send(TALLOC_CTX *mem_ctx,
+ struct tevent_context *ev,
+ struct kcm_ccdb *db,
+ struct cli_creds *client,
+ const char *name);
+errno_t kcm_ccdb_uuid_by_name_recv(struct tevent_req *req,
+ TALLOC_CTX *mem_ctx,
+ uuid_t _uuid);
+
+/*
+ * Set the default ccache. Passing a NULL UUID is a legal operation
+ * that 'unsets' the default ccache.
+ */
+struct tevent_req *kcm_ccdb_set_default_send(TALLOC_CTX *mem_ctx,
+ struct tevent_context *ev,
+ struct kcm_ccdb *db,
+ struct cli_creds *client,
+ uuid_t uuid);
+errno_t kcm_ccdb_set_default_recv(struct tevent_req *req);
+
+/*
+ * Add a ccache to the database.
+ */
+struct tevent_req *kcm_ccdb_create_cc_send(TALLOC_CTX *mem_ctx,
+ struct tevent_context *ev,
+ struct kcm_ccdb *db,
+ struct cli_creds *client,
+ struct kcm_ccache *cc);
+errno_t kcm_ccdb_create_cc_recv(struct tevent_req *req);
+
+/*
+ * Modify cache properties in a db
+ */
+struct kcm_mod_ctx {
+ int32_t kdc_offset;
+ krb5_principal client;
+ /* More settable properties (like name, when we support renames
+ * will be added later
+ */
+};
+
+struct kcm_mod_ctx *kcm_mod_ctx_new(TALLOC_CTX *mem_ctx);
+errno_t kcm_mod_cc(struct kcm_ccache *cc, struct kcm_mod_ctx *mod_ctx);
+
+struct tevent_req *kcm_ccdb_mod_cc_send(TALLOC_CTX *mem_ctx,
+ struct tevent_context *ev,
+ struct kcm_ccdb *db,
+ struct cli_creds *client,
+ uuid_t uuid,
+ struct kcm_mod_ctx *mod_cc);
+errno_t kcm_ccdb_mod_cc_recv(struct tevent_req *req);
+
+/*
+ * Store a credential in a cache
+ */
+struct tevent_req *kcm_ccdb_store_cred_blob_send(TALLOC_CTX *mem_ctx,
+ struct tevent_context *ev,
+ struct kcm_ccdb *db,
+ struct cli_creds *client,
+ uuid_t uuid,
+ struct sss_iobuf *cred_blob);
+errno_t kcm_ccdb_store_cred_blob_recv(struct tevent_req *req);
+
+/*
+ * Delete a ccache from the database
+ */
+struct tevent_req *kcm_ccdb_delete_cc_send(TALLOC_CTX *mem_ctx,
+ struct tevent_context *ev,
+ struct kcm_ccdb *db,
+ struct cli_creds *client,
+ uuid_t uuid);
+errno_t kcm_ccdb_delete_cc_recv(struct tevent_req *req);
+
+void kcm_debug_uuid(uuid_t uuid);
+
+/*
+ * The KCM clients are not allowed (except root) to create ccaches
+ * with arbitrary names. Instead, we assert that the ccache name
+ * begins with UID where UID is the stringified representation of
+ * the client's UID number
+ */
+errno_t kcm_check_name(const char *name, struct cli_creds *client);
+
+/*
+ * ccahe marshalling to and from JSON. This is used when the ccaches
+ * are stored in the secrets store
+ */
+
+/*
+ * The secrets store is a key-value store at heart. We store the UUID
+ * and the name in the key to allow easy lookups be either key
+ */
+bool sec_key_match_name(const char *sec_key,
+ const char *name);
+
+bool sec_key_match_uuid(const char *sec_key,
+ uuid_t uuid);
+
+errno_t sec_key_parse(TALLOC_CTX *mem_ctx,
+ const char *sec_key,
+ const char **_name,
+ uuid_t uuid);
+
+const char *sec_key_get_name(const char *sec_key);
+
+errno_t sec_key_get_uuid(const char *sec_key,
+ uuid_t uuid);
+
+const char *sec_key_create(TALLOC_CTX *mem_ctx,
+ const char *name,
+ uuid_t uuid);
+
+/*
+ * sec_key is a concatenation of the ccache's UUID and name
+ * sec_value is the binary representation of ccache.
+ */
+errno_t sec_kv_to_ccache_binary(TALLOC_CTX *mem_ctx,
+ const char *sec_key,
+ struct sss_iobuf *sec_value,
+ struct cli_creds *client,
+ struct kcm_ccache **_cc);
+
+/* Convert a kcm_ccache to its binary representation. */
+errno_t kcm_ccache_to_sec_input_binary(TALLOC_CTX *mem_ctx,
+ struct kcm_ccache *cc,
+ struct sss_iobuf **_payload);
+
+errno_t bin_to_krb_data(TALLOC_CTX *mem_ctx,
+ struct sss_iobuf *buf,
+ krb5_data *out);
+#endif /* _KCMSRV_CCACHE_H_ */