summaryrefslogtreecommitdiffstats
path: root/src/providers/data_provider/dp_private.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/providers/data_provider/dp_private.h')
-rw-r--r--src/providers/data_provider/dp_private.h247
1 files changed, 247 insertions, 0 deletions
diff --git a/src/providers/data_provider/dp_private.h b/src/providers/data_provider/dp_private.h
new file mode 100644
index 000000000..ece60e7a4
--- /dev/null
+++ b/src/providers/data_provider/dp_private.h
@@ -0,0 +1,247 @@
+/*
+ Authors:
+ Pavel Březina <pbrezina@redhat.com>
+
+ Copyright (C) 2016 Red Hat
+
+ 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 _DP_PRIVATE_H_
+#define _DP_PRIVATE_H_
+
+#include <tevent.h>
+#include <dhash.h>
+#include "sbus/sssd_dbus.h"
+#include "providers/data_provider/dp.h"
+#include "util/util.h"
+
+#define DP_REQ_DEBUG(level, name, fmt, ...) \
+ DEBUG(level, "DP Request [%s]: " fmt "\n", (name ?: "Unknown"), ##__VA_ARGS__)
+
+enum dp_clients {
+ DPC_NSS,
+ DPC_PAM,
+ DPC_IFP,
+ DPC_PAC,
+ DPC_SUDO,
+ DPC_HOST,
+ DPC_AUTOFS,
+
+ DP_CLIENT_SENTINEL
+};
+
+struct dp_req;
+struct dp_client;
+
+struct dp_module {
+ bool initialized;
+ const char *name;
+ void *module_data;
+ void *libhandle;
+};
+
+struct dp_target {
+ const char *name;
+ const char *module_name;
+ bool explicitly_configured;
+
+ bool initialized;
+ enum dp_targets target;
+ struct dp_module *module;
+ struct dp_method *methods;
+};
+
+struct dp_method {
+ dp_req_send_fn send_fn;
+ dp_req_recv_fn recv_fn;
+ void *method_data;
+ const char *method_dtype;
+ const char *request_dtype;
+ const char *output_dtype;
+ uint32_t output_size;
+};
+
+struct data_provider {
+ uid_t uid;
+ gid_t gid;
+ struct be_ctx *be_ctx;
+ struct tevent_context *ev;
+ struct sbus_connection *srv_conn;
+ struct dp_client *clients[DP_CLIENT_SENTINEL];
+ bool terminating;
+
+ struct {
+ /* Numeric identificator that will be assigned to next request. */
+ uint32_t index;
+
+ /* List of all ongoing requests. */
+ uint32_t num_active;
+ struct dp_req *active;
+
+ /* Table containing list of sbus_requests where DP sends reply when
+ * a request is finished. Value of this table is pair
+ * <tevent_req, list of sbus_request>
+ */
+ hash_table_t *reply_table;
+ } requests;
+
+ struct dp_module **modules;
+ struct dp_target **targets;
+};
+
+errno_t dp_find_method(struct data_provider *provider,
+ enum dp_targets target,
+ enum dp_methods method,
+ struct dp_method **_execute);
+
+struct dp_module *dp_load_module(TALLOC_CTX *mem_ctx,
+ struct be_ctx *be_ctx,
+ struct data_provider *provider,
+ struct dp_module **modules,
+ const char *name);
+
+errno_t dp_init_modules(TALLOC_CTX *mem_ctx, struct dp_module ***_modules);
+
+const char *dp_target_to_string(enum dp_targets target);
+
+bool dp_target_initialized(struct dp_target **targets, enum dp_targets type);
+
+errno_t dp_init_targets(TALLOC_CTX *mem_ctx,
+ struct be_ctx *be_ctx,
+ struct data_provider *provider,
+ struct dp_module **modules);
+
+/* Reply callbacks. */
+
+typedef void (*dp_req_post_fn)(const char *req_name,
+ struct data_provider *provider,
+ void *post_data,
+ void *reply_data);
+
+typedef void (*dp_req_reply_fn)(const char *req_name,
+ struct sbus_request *sbus_req,
+ void *data);
+
+void dp_req_reply_default(const char *req_name,
+ struct sbus_request *sbus_req,
+ void *data);
+
+/* Data provider request table. */
+
+struct dp_sbus_req_item;
+
+struct dp_table_value {
+ hash_table_t *table;
+ const char *key;
+
+ struct tevent_req *req;
+ struct dp_sbus_req_item *list;
+};
+
+struct dp_sbus_req_item {
+ struct dp_table_value *parent;
+ struct sbus_request *sbus_req;
+
+ struct dp_sbus_req_item *prev;
+ struct dp_sbus_req_item *next;
+};
+
+char *dp_req_table_key(TALLOC_CTX *mem_ctx,
+ enum dp_targets target,
+ enum dp_methods method,
+ uint32_t dp_flags,
+ const char *custom_part);
+
+errno_t dp_req_table_init(TALLOC_CTX *mem_ctx, hash_table_t **_table);
+
+struct dp_table_value *dp_req_table_lookup(hash_table_t *table,
+ const char *key);
+
+errno_t dp_req_table_add(hash_table_t *table,
+ const char *key,
+ struct tevent_req *req,
+ struct sbus_request *sbus_req);
+
+void dp_req_table_del(hash_table_t *table,
+ const char *key);
+
+void dp_req_table_del_and_free(hash_table_t *table,
+ const char *key);
+
+bool dp_req_table_has_key(hash_table_t *table,
+ const char *key);
+
+/* Data provider request. */
+
+void dp_terminate_active_requests(struct data_provider *provider);
+
+void dp_req_reply_error(struct sbus_request *sbus_req,
+ const char *req_name,
+ errno_t ret);
+
+void _dp_req_with_reply(struct dp_client *dp_cli,
+ const char *domain,
+ const char *request_name,
+ const char *custom_key,
+ struct sbus_request *sbus_req,
+ enum dp_targets target,
+ enum dp_methods method,
+ uint32_t dp_flags,
+ void *request_data,
+ dp_req_post_fn postprocess_fn,
+ void *postprocess_data,
+ dp_req_reply_fn reply_fn,
+ const char *output_dtype);
+
+/**
+ * If @domain is NULL, be_ctx->domain is used.
+ * If req_key is NULL, address of sbus_req is used.
+ *
+ * If @pp_fn (post process function) is set it is call on a successful
+ * DP request before reply is sent.
+ */
+#define dp_req_with_reply_pp(dp_cli, domain, req_name, req_key, sbus_req, \
+ target, method, dp_flags, req_data, pp_fn, \
+ pp_data, pp_dtype, reply_fn, output_dtype) \
+ do { \
+ /* Check postprocess function parameter types. */ \
+ void (*__pp_fn)(const char *, struct data_provider *, \
+ pp_dtype *, output_dtype *) = (pp_fn); \
+ pp_dtype *__pp_data = (pp_data); \
+ \
+ /* Check reply function parameter types. */ \
+ void (*__reply_fn)(const char *, struct sbus_request *, \
+ output_dtype *) = (reply_fn); \
+ \
+ _dp_req_with_reply(dp_cli, domain, req_name, req_key, sbus_req, \
+ target, method, dp_flags, req_data, \
+ (dp_req_post_fn)__pp_fn, __pp_data, \
+ (dp_req_reply_fn)__reply_fn, #output_dtype); \
+ } while(0)
+
+#define dp_req_with_reply(dp_cli, domain, req_name, req_key, sbus_req, target,\
+ method, dp_flags, req_data, reply_fn, \
+ output_dtype) \
+ dp_req_with_reply_pp(dp_cli, domain, req_name, req_key, sbus_req, target, \
+ method, dp_flags, req_data, NULL, NULL, void, \
+ reply_fn, output_dtype)
+
+/* Client shared functions. */
+
+errno_t dp_client_init(struct sbus_connection *conn, void *data);
+struct data_provider *dp_client_provider(struct dp_client *dp_cli);
+struct sbus_connection *dp_client_conn(struct dp_client *dp_cli);
+
+#endif /* _DP_PRIVATE_H_ */