summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPavel Březina <pbrezina@redhat.com>2014-05-02 13:08:21 +0200
committerJakub Hrozek <jhrozek@redhat.com>2014-05-28 16:41:08 +0200
commit8a1fd0633e85221da1fb63451516a70d66c0af31 (patch)
tree54e3a8bc7eb8f9915ac6dadc4e258bd9b6798ab3
parentebd2db737485d334cd54316e05f848f3ccfd2fee (diff)
downloadsssd-8a1fd0633e85221da1fb63451516a70d66c0af31.tar.gz
sssd-8a1fd0633e85221da1fb63451516a70d66c0af31.tar.xz
sssd-8a1fd0633e85221da1fb63451516a70d66c0af31.zip
IFP: Implement SSSD components
Reviewed-by: Jakub Hrozek <jhrozek@redhat.com>
-rw-r--r--Makefile.am7
-rw-r--r--src/responder/ifp/ifp_components.c988
-rw-r--r--src/responder/ifp/ifp_components.h87
-rw-r--r--src/responder/ifp/ifp_iface.xml51
-rw-r--r--src/responder/ifp/ifp_iface_generated.c378
-rw-r--r--src/responder/ifp/ifp_iface_generated.h71
-rw-r--r--src/responder/ifp/ifpsrv.c26
-rw-r--r--src/responder/ifp/org.freedesktop.sssd.infopipe.conf4
8 files changed, 1611 insertions, 1 deletions
diff --git a/Makefile.am b/Makefile.am
index cf925bc51..8e7d9ebe3 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -486,6 +486,7 @@ dist_noinst_HEADERS = \
src/responder/ssh/sshsrv_private.h \
src/responder/ifp/ifp_private.h \
src/responder/ifp/ifp_domains.h \
+ src/responder/ifp/ifp_components.h \
src/sbus/sbus_client.h \
src/sbus/sssd_dbus.h \
src/sbus/sssd_dbus_meta.h \
@@ -860,6 +861,7 @@ sssd_ifp_SOURCES = \
src/responder/ifp/ifp_iface_generated.h \
src/responder/ifp/ifpsrv_util.c \
src/responder/ifp/ifp_domains.c \
+ src/responder/ifp/ifp_components.c \
$(SSSD_UTIL_OBJ) \
$(SSSD_RESPONDER_OBJ)
sssd_ifp_CFLAGS = \
@@ -869,6 +871,11 @@ sssd_ifp_LDADD = \
$(SSSD_INTERNAL_LTLIBS)
dist_dbuspolicy_DATA = \
src/responder/ifp/org.freedesktop.sssd.infopipe.conf
+
+if BUILD_CONFIG_LIB
+sssd_ifp_LDADD += libsss_config.la
+endif
+
endif
sssd_be_SOURCES = \
diff --git a/src/responder/ifp/ifp_components.c b/src/responder/ifp/ifp_components.c
new file mode 100644
index 000000000..e5fa06cdd
--- /dev/null
+++ b/src/responder/ifp/ifp_components.c
@@ -0,0 +1,988 @@
+/*
+ Authors:
+ Pavel Březina <pbrezina@redhat.com>
+
+ Copyright (C) 2014 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/>.
+*/
+
+#include <string.h>
+#include <talloc.h>
+#include <signal.h>
+
+#include "config.h"
+#include "confdb/confdb.h"
+#include "util/util.h"
+#include "responder/common/responder.h"
+#include "responder/ifp/ifp_components.h"
+
+#ifdef HAVE_CONFIG_LIB
+#include "util/sss_config.h"
+#endif
+
+#define PATH_MONITOR INFOPIPE_COMPONENT_PATH_PFX "/monitor"
+#define PATH_RESPONDERS INFOPIPE_COMPONENT_PATH_PFX "/Responders"
+#define PATH_BACKENDS INFOPIPE_COMPONENT_PATH_PFX "/Backends"
+
+enum component_type {
+ COMPONENT_MONITOR,
+ COMPONENT_RESPONDER,
+ COMPONENT_BACKEND
+};
+
+static bool responder_exists(const char *name)
+{
+ const char * const *svc = get_known_services();
+ int i;
+
+ for (i = 0; svc[i] != NULL; i++) {
+ if (strcmp(svc[i], name) == 0) {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+static bool backend_exists(struct confdb_ctx *confdb, const char *name)
+{
+ char **names = NULL;
+ errno_t ret;
+ int i;
+
+ ret = confdb_list_all_domain_names(NULL, confdb, &names);
+ if (ret != EOK) {
+ return false;
+ }
+
+ for (i = 0; names[i] != NULL; i++) {
+ if (strcmp(names[i], name) == 0) {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+static errno_t check_and_get_component_from_path(TALLOC_CTX *mem_ctx,
+ struct confdb_ctx *confdb,
+ const char *path,
+ enum component_type *_type,
+ char **_name)
+{
+ enum component_type type;
+ const char *name = NULL;
+ char *safe_name = NULL;
+ errno_t ret;
+
+ if (confdb == NULL || path == NULL) {
+ return EINVAL;
+ }
+
+ if (strcmp(path, PATH_MONITOR) == 0) {
+ type = COMPONENT_MONITOR;
+ name = "monitor";
+ } else {
+ name = ifp_path_strip_prefix(path, PATH_RESPONDERS "/");
+ if (name != NULL) {
+ type = COMPONENT_RESPONDER;
+ } else {
+ name = ifp_path_strip_prefix(path, PATH_BACKENDS "/");
+ if (name != NULL) {
+ type = COMPONENT_BACKEND;
+ } else {
+ ret = EINVAL;
+ goto done;
+ }
+ }
+ }
+
+ if (strchr(name, '/') != NULL) {
+ ret = EINVAL;
+ goto done;
+ }
+
+ safe_name = ifp_bus_path_unescape(mem_ctx, name);
+ if (safe_name == NULL) {
+ ret = ENOMEM;
+ goto done;
+ }
+
+ switch (type) {
+ case COMPONENT_MONITOR:
+ /* noop */
+ break;
+ case COMPONENT_RESPONDER:
+ if (!responder_exists(safe_name)) {
+ ret = ENOENT;
+ goto done;
+ }
+ break;
+ case COMPONENT_BACKEND:
+ if (!backend_exists(confdb, safe_name)) {
+ ret = ENOENT;
+ goto done;
+ }
+ break;
+ }
+
+ if (_type != NULL) {
+ *_type = type;
+ }
+
+ if (_name != NULL) {
+ *_name = safe_name;
+ }
+
+ ret = EOK;
+
+done:
+ return ret;
+}
+
+static errno_t change_debug_level_tmp(struct confdb_ctx *confdb,
+ const char *name,
+ enum component_type type,
+ uint32_t level)
+{
+ TALLOC_CTX *tmp_ctx = NULL;
+ const char *confdb_path = NULL;
+ const char **values = NULL;
+ errno_t ret;
+
+ tmp_ctx = talloc_new(NULL);
+ if (tmp_ctx == NULL) {
+ return ENOMEM;
+ }
+
+ switch (type) {
+ case COMPONENT_MONITOR:
+ confdb_path = CONFDB_MONITOR_CONF_ENTRY;
+ break;
+ case COMPONENT_RESPONDER:
+ confdb_path = talloc_asprintf(tmp_ctx, CONFDB_SERVICE_PATH_TMPL, name);
+ break;
+ case COMPONENT_BACKEND:
+ confdb_path = talloc_asprintf(tmp_ctx, CONFDB_DOMAIN_PATH_TMPL, name);
+ break;
+ }
+
+ if (confdb_path == NULL) {
+ ret = ENOMEM;
+ goto done;
+ }
+
+ values = talloc_zero_array(tmp_ctx, const char*, 2);
+ if (values == NULL) {
+ ret = ENOMEM;
+ goto done;
+ }
+
+ values[0] = talloc_asprintf(tmp_ctx, "0x%.4x", level);
+ if (values[0] == NULL) {
+ ret = ENOMEM;
+ goto done;
+ }
+
+ ret = confdb_add_param(confdb, true, confdb_path,
+ CONFDB_SERVICE_DEBUG_LEVEL, values);
+ if (ret != EOK) {
+ goto done;
+ }
+
+ /* reload the configuration */
+ if (kill(getppid(), SIGHUP) != 0) {
+ ret = errno;
+ goto done;
+ }
+
+ ret = EOK;
+
+done:
+ talloc_free(tmp_ctx);
+ return ret;
+}
+
+static errno_t list_responders(TALLOC_CTX *mem_ctx,
+ const char ***_list,
+ int *_num)
+{
+ const char **list = NULL;
+ const char * const *svc = get_known_services();
+ errno_t ret;
+ int num;
+ int i;
+
+ for (num = 0; svc[num] != NULL; num++);
+
+ list = talloc_array(mem_ctx, const char*, num);
+ if (list == NULL) {
+ ret = ENOMEM;
+ goto done;
+ }
+
+ for (i = 0; i < num; i++) {
+ list[i] = ifp_reply_objpath(list, PATH_RESPONDERS, svc[i]);
+ if (list[i] == NULL) {
+ ret = ENOMEM;
+ goto done;
+ }
+ }
+
+ *_num = num;
+ *_list = list;
+ ret = EOK;
+
+done:
+ if (ret != EOK) {
+ talloc_free(list);
+ }
+
+ return ret;
+}
+
+static errno_t list_backends(TALLOC_CTX *mem_ctx,
+ struct confdb_ctx *confdb,
+ const char ***_list,
+ int *_num)
+{
+ TALLOC_CTX *tmp_ctx = NULL;
+ const char **list = NULL;
+ char **names = NULL;
+ errno_t ret;
+ int num;
+ int i;
+
+ tmp_ctx = talloc_new(NULL);
+ if (tmp_ctx == NULL) {
+ return ENOMEM;
+ }
+
+ ret = confdb_list_all_domain_names(tmp_ctx, confdb, &names);
+ if (ret != EOK) {
+ goto done;
+ }
+
+ for (num = 0; names[num] != NULL; num++);
+
+ list = talloc_array(tmp_ctx, const char*, num);
+ if (list == NULL) {
+ ret = ENOMEM;
+ goto done;
+ }
+
+ for (i = 0; i < num; i++) {
+ list[i] = ifp_reply_objpath(list, PATH_BACKENDS, names[i]);
+ if (list[i] == NULL) {
+ ret = ENOMEM;
+ goto done;
+ }
+ }
+
+ *_num = num;
+ *_list = talloc_steal(mem_ctx, list);
+ ret = EOK;
+
+done:
+ talloc_free(tmp_ctx);
+ return ret;
+}
+
+int ifp_list_components(struct sbus_request *dbus_req, void *data)
+{
+ struct ifp_ctx *ctx = NULL;
+ DBusError *error = NULL;
+ const char **responders = NULL;
+ const char **backends = NULL;
+ const char **result = NULL;
+ int num_responders;
+ int num_backends;
+ int num;
+ int i;
+ errno_t ret;
+
+ ctx = talloc_get_type(data, struct ifp_ctx);
+ if (ctx == NULL) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "Invalid ifp context!\n");
+ ret = EINVAL;
+ goto done;
+ }
+
+ ret = list_responders(dbus_req, &responders, &num_responders);
+ if (ret != EOK) {
+ goto done;
+ }
+
+ ret = list_backends(dbus_req, ctx->rctx->cdb, &backends, &num_backends);
+ if (ret != EOK) {
+ goto done;
+ }
+
+ num = num_responders + num_backends + 1;
+ result = talloc_array(dbus_req, const char*, num);
+ if (result == NULL) {
+ ret = ENOMEM;
+ goto done;
+ }
+
+ result[0] = PATH_MONITOR;
+
+ for (i = 0; i < num_responders; i++) {
+ result[i + 1] = talloc_steal(result, responders[i]);
+ }
+
+ for (i = 0; i < num_backends; i++) {
+ result[i + num_responders + 1] = talloc_steal(result, backends[i]);
+ }
+
+ ret = EOK;
+
+done:
+ if (ret != EOK) {
+ error = sbus_error_new(dbus_req, DBUS_ERROR_FAILED,
+ "%s", strerror(ret));
+ return sbus_request_fail_and_finish(dbus_req, error);
+ }
+
+ return infopipe_iface_ListComponents_finish(dbus_req, result, num);
+}
+
+int ifp_list_responders(struct sbus_request *dbus_req, void *data)
+{
+ DBusError *error = NULL;
+ const char **result = NULL;
+ int num;
+ errno_t ret;
+
+ ret = list_responders(dbus_req, &result, &num);
+ if (ret != EOK) {
+ error = sbus_error_new(dbus_req, DBUS_ERROR_FAILED,
+ "%s", strerror(ret));
+ return sbus_request_fail_and_finish(dbus_req, error);
+ }
+
+ return infopipe_iface_ListResponders_finish(dbus_req, result, num);
+}
+
+int ifp_list_backends(struct sbus_request *dbus_req, void *data)
+{
+ struct ifp_ctx *ctx = NULL;
+ DBusError *error = NULL;
+ const char **result = NULL;
+ int num;
+ errno_t ret;
+
+ ctx = talloc_get_type(data, struct ifp_ctx);
+ if (ctx == NULL) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "Invalid ifp context!\n");
+ ret = EINVAL;
+ goto done;
+ }
+
+ ret = list_backends(dbus_req, ctx->rctx->cdb, &result, &num);
+
+done:
+ if (ret != EOK) {
+ error = sbus_error_new(dbus_req, DBUS_ERROR_FAILED,
+ "%s", strerror(ret));
+ return sbus_request_fail_and_finish(dbus_req, error);
+ }
+
+ return infopipe_iface_ListBackends_finish(dbus_req, result, num);
+}
+
+int ifp_find_monitor(struct sbus_request *dbus_req, void *data)
+{
+ return infopipe_iface_FindMonitor_finish(dbus_req, PATH_MONITOR);
+}
+
+int ifp_find_responder_by_name(struct sbus_request *dbus_req,
+ void *data,
+ const char *arg_name)
+{
+ DBusError *error = NULL;
+ const char *result = NULL;
+
+ if (responder_exists(arg_name)) {
+ result = ifp_reply_objpath(dbus_req, PATH_RESPONDERS, arg_name);
+ if (result == NULL) {
+ return sbus_request_fail_and_finish(dbus_req, NULL);
+ }
+ } else {
+ error = sbus_error_new(dbus_req, DBUS_ERROR_FAILED,
+ "Responder \"%s\" does not exist", arg_name);
+ return sbus_request_fail_and_finish(dbus_req, error);
+ }
+
+ return infopipe_iface_FindResponderByName_finish(dbus_req, result);
+}
+
+int ifp_find_backend_by_name(struct sbus_request *dbus_req,
+ void *data,
+ const char *arg_name)
+{
+ struct ifp_ctx *ctx = NULL;
+ DBusError *error = NULL;
+ const char *result = NULL;
+
+ ctx = talloc_get_type(data, struct ifp_ctx);
+ if (ctx == NULL) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "Invalid ifp context!\n");
+ error = sbus_error_new(dbus_req, DBUS_ERROR_FAILED,
+ "%s\n", strerror(EINVAL));
+ return sbus_request_fail_and_finish(dbus_req, error);
+ }
+
+ if (backend_exists(ctx->rctx->cdb, arg_name)) {
+ result = ifp_reply_objpath(dbus_req, PATH_BACKENDS, arg_name);
+ if (result == NULL) {
+ return sbus_request_fail_and_finish(dbus_req, NULL);
+ }
+ } else {
+ error = sbus_error_new(dbus_req, DBUS_ERROR_FAILED,
+ "Backend \"%s\" does not exist", arg_name);
+ return sbus_request_fail_and_finish(dbus_req, error);
+ }
+
+ return infopipe_iface_FindBackendByName_finish(dbus_req, result);
+}
+
+int ifp_component_enable(struct sbus_request *dbus_req, void *data)
+{
+#ifndef HAVE_CONFIG_LIB
+ return sbus_request_fail_and_finish(dbus_req,
+ sbus_error_new(dbus_req, DBUS_ERROR_NOT_SUPPORTED, NULL));
+#else
+ struct ifp_ctx *ctx = NULL;
+ DBusError *error = NULL;
+ const char *path = dbus_message_get_path(dbus_req->message);
+ char *name = NULL;
+ enum component_type type;
+ struct sss_config_ctx *config_ctx = NULL;
+ errno_t ret;
+
+ ctx = talloc_get_type(data, struct ifp_ctx);
+ if (ctx == NULL) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "Invalid ifp context!\n");
+ ret = EINVAL;
+ goto done;
+ }
+
+ ret = check_and_get_component_from_path(dbus_req, ctx->rctx->cdb,
+ path, &type, &name);
+ if (ret != EOK) {
+ goto done;
+ }
+
+ config_ctx = sss_config_open(dbus_req, NULL, CONFDB_DEFAULT_CONFIG_FILE);
+ if (config_ctx == NULL) {
+ ret = ENOMEM;
+ goto done;
+ }
+
+ switch (type) {
+ case COMPONENT_MONITOR:
+ error = sbus_error_new(dbus_req, DBUS_ERROR_NOT_SUPPORTED, NULL);
+ goto done;
+ break;
+ case COMPONENT_RESPONDER:
+ ret = sss_config_service_enable(config_ctx, name);
+ break;
+ case COMPONENT_BACKEND:
+ ret = sss_config_domain_enable(config_ctx, name);
+ break;
+ }
+
+ if (ret != EOK) {
+ goto done;
+ }
+
+ ret = sss_config_save(config_ctx);
+ if (ret != EOK) {
+ goto done;
+ }
+
+done:
+ sss_config_close(&config_ctx);
+
+ if (ret == ENOMEM) {
+ return sbus_request_fail_and_finish(dbus_req, NULL);
+ } else if (error != NULL) {
+ return sbus_request_fail_and_finish(dbus_req, error);
+ } else if (ret != EOK) {
+ error = sbus_error_new(dbus_req, DBUS_ERROR_FAILED, "%s", strerror(ret));
+ return sbus_request_fail_and_finish(dbus_req, error);
+ }
+
+ return infopipe_component_Enable_finish(dbus_req);
+#endif
+}
+
+int ifp_component_disable(struct sbus_request *dbus_req, void *data)
+{
+#ifndef HAVE_CONFIG_LIB
+ return sbus_request_fail_and_finish(dbus_req,
+ sbus_error_new(dbus_req, DBUS_ERROR_NOT_SUPPORTED, NULL));
+#else
+ struct ifp_ctx *ctx = NULL;
+ DBusError *error = NULL;
+ const char *path = dbus_message_get_path(dbus_req->message);
+ char *name = NULL;
+ enum component_type type;
+ struct sss_config_ctx *config_ctx = NULL;
+ errno_t ret;
+
+ ctx = talloc_get_type(data, struct ifp_ctx);
+ if (ctx == NULL) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "Invalid ifp context!\n");
+ ret = EINVAL;
+ goto done;
+ }
+
+ ret = check_and_get_component_from_path(dbus_req, ctx->rctx->cdb,
+ path, &type, &name);
+ if (ret != EOK) {
+ goto done;
+ }
+
+ config_ctx = sss_config_open(dbus_req, NULL, CONFDB_DEFAULT_CONFIG_FILE);
+ if (config_ctx == NULL) {
+ ret = ENOMEM;
+ goto done;
+ }
+
+ switch (type) {
+ case COMPONENT_MONITOR:
+ error = sbus_error_new(dbus_req, DBUS_ERROR_NOT_SUPPORTED, NULL);
+ goto done;
+ break;
+ case COMPONENT_RESPONDER:
+ ret = sss_config_service_disable(config_ctx, name);
+ break;
+ case COMPONENT_BACKEND:
+ ret = sss_config_domain_disable(config_ctx, name);
+ break;
+ }
+
+ if (ret != EOK) {
+ goto done;
+ }
+
+ ret = sss_config_save(config_ctx);
+ if (ret != EOK) {
+ goto done;
+ }
+
+done:
+ sss_config_close(&config_ctx);
+
+ if (ret == ENOMEM) {
+ return sbus_request_fail_and_finish(dbus_req, NULL);
+ } else if (error != NULL) {
+ return sbus_request_fail_and_finish(dbus_req, error);
+ } else if (ret != EOK) {
+ error = sbus_error_new(dbus_req, DBUS_ERROR_FAILED, "%s", strerror(ret));
+ return sbus_request_fail_and_finish(dbus_req, error);
+ }
+
+ return infopipe_component_Disable_finish(dbus_req);
+#endif
+}
+
+int ifp_component_change_debug_level(struct sbus_request *dbus_req,
+ void *data,
+ uint32_t arg_new_level)
+{
+#ifndef HAVE_CONFIG_LIB
+ return sbus_request_fail_and_finish(dbus_req,
+ sbus_error_new(dbus_req, DBUS_ERROR_NOT_SUPPORTED, NULL));
+#else
+ struct ifp_ctx *ctx = NULL;
+ DBusError *error = NULL;
+ const char *path = dbus_message_get_path(dbus_req->message);
+ char *name = NULL;
+ enum component_type type;
+ struct sss_config_ctx *config_ctx = NULL;
+ const char *section = NULL;
+ errno_t ret;
+
+ ctx = talloc_get_type(data, struct ifp_ctx);
+ if (ctx == NULL) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "Invalid ifp context!\n");
+ ret = EINVAL;
+ goto done;
+ }
+
+ ret = check_and_get_component_from_path(dbus_req, ctx->rctx->cdb,
+ path, &type, &name);
+ if (ret != EOK) {
+ goto done;
+ }
+
+ switch (type) {
+ case COMPONENT_MONITOR:
+ section = "sssd";
+ break;
+ case COMPONENT_RESPONDER:
+ section = name;
+ break;
+ case COMPONENT_BACKEND:
+ section = talloc_asprintf(dbus_req, "domain/%s", name);
+ break;
+ }
+
+ if (section == NULL) {
+ ret = ENOMEM;
+ goto done;
+ }
+
+ config_ctx = sss_config_open(dbus_req, NULL, CONFDB_DEFAULT_CONFIG_FILE);
+ if (config_ctx == NULL) {
+ ret = ENOMEM;
+ goto done;
+ }
+
+ ret = sss_config_set_debug_level(config_ctx, section, arg_new_level);
+ if (ret != EOK) {
+ goto done;
+ }
+
+ ret = sss_config_save(config_ctx);
+ if (ret != EOK) {
+ goto done;
+ }
+
+ ret = change_debug_level_tmp(ctx->rctx->cdb, name, type, arg_new_level);
+ if (ret != EOK) {
+ goto done;
+ }
+
+done:
+ sss_config_close(&config_ctx);
+
+ if (ret == ENOMEM) {
+ return sbus_request_fail_and_finish(dbus_req, NULL);
+ } else if (ret != EOK) {
+ error = sbus_error_new(dbus_req, DBUS_ERROR_FAILED, "%s", strerror(ret));
+ return sbus_request_fail_and_finish(dbus_req, error);
+ }
+
+ return infopipe_component_ChangeDebugLevel_finish(dbus_req);
+#endif
+}
+
+int ifp_component_change_debug_level_tmp(struct sbus_request *dbus_req,
+ void *data,
+ uint32_t arg_new_level)
+{
+ struct ifp_ctx *ctx = NULL;
+ DBusError *error = NULL;
+ const char *path = dbus_message_get_path(dbus_req->message);
+ char *name = NULL;
+ enum component_type type;
+ errno_t ret;
+
+ ctx = talloc_get_type(data, struct ifp_ctx);
+ if (ctx == NULL) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "Invalid ifp context!\n");
+ ret = EINVAL;
+ goto done;
+ }
+
+ ret = check_and_get_component_from_path(dbus_req, ctx->rctx->cdb,
+ path, &type, &name);
+ if (ret != EOK) {
+ goto done;
+ }
+
+ ret = change_debug_level_tmp(ctx->rctx->cdb, name, type, arg_new_level);
+
+done:
+ if (ret != EOK) {
+ error = sbus_error_new(dbus_req, DBUS_ERROR_FAILED, "%s", strerror(ret));
+ return sbus_request_fail_and_finish(dbus_req, error);
+ }
+
+ return infopipe_component_ChangeDebugLevelTemporarily_finish(dbus_req);
+}
+
+void ifp_component_get_name(struct sbus_request *dbus_req,
+ void *data,
+ const char **_out)
+{
+ struct ifp_ctx *ctx = NULL;
+ const char *path = dbus_message_get_path(dbus_req->message);
+ char *name = NULL;
+ errno_t ret;
+
+ *_out = NULL;
+
+ ctx = talloc_get_type(data, struct ifp_ctx);
+ if (ctx == NULL) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "Invalid ifp context!\n");
+ return;
+ }
+
+ ret = check_and_get_component_from_path(dbus_req, ctx->rctx->cdb,
+ path, NULL, &name);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE, "Unknown object [%d]: %s\n",
+ ret, strerror(ret));
+ return;
+ }
+
+ *_out = name;
+}
+
+void ifp_component_get_debug_level(struct sbus_request *dbus_req,
+ void *data,
+ uint32_t *_out)
+{
+ struct ifp_ctx *ctx = NULL;
+ const char *path = dbus_message_get_path(dbus_req->message);
+ const char *confdb_path = NULL;
+ char *name = NULL;
+ enum component_type type;
+ int level;
+ errno_t ret;
+
+ *_out = 0;
+
+ ctx = talloc_get_type(data, struct ifp_ctx);
+ if (ctx == NULL) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "Invalid ifp context!\n");
+ return;
+ }
+
+ ret = check_and_get_component_from_path(dbus_req, ctx->rctx->cdb,
+ path, &type, &name);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE, "Unknown object [%d]: %s\n",
+ ret, strerror(ret));
+ return;
+ }
+
+ switch (type) {
+ case COMPONENT_MONITOR:
+ confdb_path = CONFDB_MONITOR_CONF_ENTRY;
+ break;
+ case COMPONENT_RESPONDER:
+ confdb_path = talloc_asprintf(dbus_req, CONFDB_SERVICE_PATH_TMPL, name);
+ break;
+ case COMPONENT_BACKEND:
+ confdb_path = talloc_asprintf(dbus_req, CONFDB_DOMAIN_PATH_TMPL, name);
+ break;
+ }
+
+ if (confdb_path == NULL) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "Out of memory\n");
+ return;
+ }
+
+ ret = confdb_get_int(ctx->rctx->cdb, confdb_path,
+ CONFDB_SERVICE_DEBUG_LEVEL, SSSDBG_DEFAULT, &level);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE, "Unable to retrieve configuration option"
+ "[%d]: %s\n", ret, strerror(ret));
+ return;
+ }
+
+ *_out = level;
+}
+
+void ifp_component_get_enabled(struct sbus_request *dbus_req,
+ void *data,
+ bool *_out)
+{
+ struct ifp_ctx *ctx = NULL;
+ const char *path = dbus_message_get_path(dbus_req->message);
+ const char *param = NULL;
+ char **values = NULL;
+ char *name = NULL;
+ enum component_type type;
+ errno_t ret;
+ int i;
+
+ *_out = false;
+
+ ctx = talloc_get_type(data, struct ifp_ctx);
+ if (ctx == NULL) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "Invalid ifp context!\n");
+ return;
+ }
+
+ ret = check_and_get_component_from_path(dbus_req, ctx->rctx->cdb,
+ path, &type, &name);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE, "Unknown object [%d]: %s\n",
+ ret, strerror(ret));
+ return;
+ }
+
+ switch (type) {
+ case COMPONENT_MONITOR:
+ *_out = true;
+ return;
+ case COMPONENT_RESPONDER:
+ param = CONFDB_MONITOR_ACTIVE_SERVICES;
+ break;
+ case COMPONENT_BACKEND:
+ param = CONFDB_MONITOR_ACTIVE_DOMAINS;
+ break;
+ }
+
+ ret = confdb_get_string_as_list(ctx->rctx->cdb, dbus_req,
+ CONFDB_MONITOR_CONF_ENTRY, param, &values);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE, "Unable to retrieve configuration option"
+ "[%d]: %s\n", ret, strerror(ret));
+ return;
+ }
+
+ for (i = 0; values[i] != NULL; i++) {
+ if (strcmp(values[i], name) == 0) {
+ *_out = true;
+ return;
+ }
+ }
+}
+
+void ifp_component_get_type(struct sbus_request *dbus_req,
+ void *data,
+ const char **_out)
+{
+ struct ifp_ctx *ctx = NULL;
+ const char *path = dbus_message_get_path(dbus_req->message);
+ enum component_type type;
+ errno_t ret;
+
+ *_out = NULL;
+
+ ctx = talloc_get_type(data, struct ifp_ctx);
+ if (ctx == NULL) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "Invalid ifp context!\n");
+ return;
+ }
+
+ ret = check_and_get_component_from_path(dbus_req, ctx->rctx->cdb,
+ path, &type, NULL);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE, "Unknown object [%d]: %s\n",
+ ret, strerror(ret));
+ return;
+ }
+
+ switch (type) {
+ case COMPONENT_MONITOR:
+ *_out = "monitor";
+ break;
+ case COMPONENT_RESPONDER:
+ *_out = "responder";
+ break;
+ case COMPONENT_BACKEND:
+ *_out = "backend";
+ break;
+ }
+}
+
+void ifp_backend_get_providers(struct sbus_request *dbus_req,
+ void *data,
+ const char ***_out,
+ int *_out_len)
+{
+ TALLOC_CTX *tmp_ctx = NULL;
+ struct ifp_ctx *ctx = NULL;
+ const char *path = dbus_message_get_path(dbus_req->message);
+ const char *confdb_path = NULL;
+ char *name = NULL;
+ enum component_type type;
+ const char **out = NULL;
+ char *value = NULL;
+ static const char *providers[] = {CONFDB_DOMAIN_ID_PROVIDER,
+ CONFDB_DOMAIN_AUTH_PROVIDER,
+ CONFDB_DOMAIN_ACCESS_PROVIDER,
+ CONFDB_DOMAIN_CHPASS_PROVIDER,
+ CONFDB_DOMAIN_SUDO_PROVIDER,
+ CONFDB_DOMAIN_AUTOFS_PROVIDER,
+ CONFDB_DOMAIN_SELINUX_PROVIDER,
+ CONFDB_DOMAIN_HOSTID_PROVIDER,
+ CONFDB_DOMAIN_SUBDOMAINS_PROVIDER};
+ int num_providers = sizeof(providers) / sizeof(providers[0]);
+ errno_t ret;
+ int i;
+ int j;
+
+ *_out = NULL;
+ *_out_len = 0;
+
+ tmp_ctx = talloc_new(NULL);
+ if (tmp_ctx == NULL) {
+ return;
+ }
+
+ ctx = talloc_get_type(data, struct ifp_ctx);
+ if (ctx == NULL) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "Invalid ifp context!\n");
+ return;
+ }
+
+ ret = check_and_get_component_from_path(tmp_ctx, ctx->rctx->cdb,
+ path, &type, &name);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE, "Unknown object [%d]: %s\n",
+ ret, strerror(ret));
+ return;
+ }
+
+ if (type != COMPONENT_BACKEND) {
+ return;
+ }
+
+ confdb_path = talloc_asprintf(tmp_ctx, CONFDB_DOMAIN_PATH_TMPL, name);
+ if (confdb_path == NULL) {
+ return;
+ }
+
+ out = talloc_zero_array(tmp_ctx, const char*, num_providers);
+ if (out == NULL) {
+ return;
+ }
+
+ j = 0;
+ for (i = 0; i < num_providers; i++) {
+ ret = confdb_get_string(ctx->rctx->cdb, tmp_ctx, confdb_path,
+ providers[i], NULL, &value);
+ if (ret != EOK) {
+ return;
+ }
+
+ if (value == NULL) {
+ continue;
+ }
+
+ out[j] = talloc_asprintf(out, "%s=%s", providers[i], value);
+ if (out[j] == NULL) {
+ return;
+ }
+
+ j++;
+ }
+
+ *_out = talloc_steal(dbus_req, out);
+ *_out_len = j;
+
+ talloc_free(tmp_ctx);
+ return;
+}
diff --git a/src/responder/ifp/ifp_components.h b/src/responder/ifp/ifp_components.h
new file mode 100644
index 000000000..49f1294cd
--- /dev/null
+++ b/src/responder/ifp/ifp_components.h
@@ -0,0 +1,87 @@
+/*
+ Authors:
+ Pavel Březina <pbrezina@redhat.com>
+
+ Copyright (C) 2014 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 _IFP_COMPONENTS_H_
+#define _IFP_COMPONENTS_H_
+
+#include "responder/ifp/ifp_iface_generated.h"
+#include "responder/ifp/ifp_private.h"
+
+#define INFOPIPE_COMPONENT_PATH_PFX "/org/freedesktop/sssd/infopipe/Components"
+#define INFOPIPE_COMPONENT_PATH INFOPIPE_COMPONENT_PATH_PFX "*"
+
+#define INFOPIPE_BACKEND_PATH INFOPIPE_COMPONENT_PATH_PFX "/Backends*"
+
+/* org.freedesktop.sssd.infopipe */
+
+int ifp_list_components(struct sbus_request *dbus_req, void *data);
+
+int ifp_list_responders(struct sbus_request *dbus_req, void *data);
+
+int ifp_list_backends(struct sbus_request *dbus_req, void *data);
+
+int ifp_find_monitor(struct sbus_request *dbus_req, void *data);
+
+int ifp_find_responder_by_name(struct sbus_request *dbus_req,
+ void *data,
+ const char *arg_name);
+
+int ifp_find_backend_by_name(struct sbus_request *dbus_req,
+ void *data,
+ const char *arg_name);
+
+/* org.freedesktop.sssd.infopipe.Components */
+
+int ifp_component_enable(struct sbus_request *dbus_req, void *data);
+
+int ifp_component_disable(struct sbus_request *dbus_req, void *data);
+
+int ifp_component_change_debug_level(struct sbus_request *dbus_req,
+ void *data,
+ uint32_t arg_new_level);
+
+int ifp_component_change_debug_level_tmp(struct sbus_request *dbus_req,
+ void *data,
+ uint32_t arg_new_level);
+
+void ifp_component_get_name(struct sbus_request *dbus_req,
+ void *data,
+ const char **_out);
+
+void ifp_component_get_debug_level(struct sbus_request *dbus_req,
+ void *data,
+ uint32_t *_out);
+
+void ifp_component_get_enabled(struct sbus_request *dbus_req,
+ void *data,
+ bool *_out);
+
+void ifp_component_get_type(struct sbus_request *dbus_req,
+ void *data,
+ const char **_out);
+
+/* org.freedesktop.sssd.infopipe.Components.Backends */
+
+void ifp_backend_get_providers(struct sbus_request *dbus_req,
+ void *data,
+ const char ***_out,
+ int *_out_len);
+
+#endif /* _IFP_COMPONENTS_H_ */
diff --git a/src/responder/ifp/ifp_iface.xml b/src/responder/ifp/ifp_iface.xml
index 1b9acd113..815abd1ae 100644
--- a/src/responder/ifp/ifp_iface.xml
+++ b/src/responder/ifp/ifp_iface.xml
@@ -9,6 +9,34 @@
<annotation name="org.freedesktop.sssd.RawHandler" value="true"/>
</method>
+ <!-- SSSD components -->
+
+ <method name="ListComponents">
+ <arg name="components" type="ao" direction="out"/>
+ </method>
+
+ <method name="ListResponders">
+ <arg name="responders" type="ao" direction="out"/>
+ </method>
+
+ <method name="ListBackends">
+ <arg name="backends" type="ao" direction="out"/>
+ </method>
+
+ <method name="FindMonitor">
+ <arg name="monitor" type="o" direction="out"/>
+ </method>
+
+ <method name="FindResponderByName">
+ <arg name="name" type="s" direction="in" />
+ <arg name="responder" type="o" direction="out"/>
+ </method>
+
+ <method name="FindBackendByName">
+ <arg name="name" type="s" direction="in" />
+ <arg name="backend" type="o" direction="out"/>
+ </method>
+
<method name="GetUserAttr">
<arg name="user" type="s" direction="in" />
<arg name="attr" type="as" direction="in" />
@@ -32,6 +60,29 @@
</interface>
+ <interface name="org.freedesktop.sssd.infopipe.Components">
+ <annotation name="org.freedesktop.DBus.GLib.CSymbol" value="infopipe_component"/>
+
+ <method name="Enable" />
+ <method name="Disable" />
+ <method name="ChangeDebugLevel">
+ <arg name="new_level" type="u" direction="in" />
+ </method>
+
+ <method name="ChangeDebugLevelTemporarily">
+ <arg name="new_level" type="u" direction="in" />
+ </method>
+
+ <property name="name" type="s" access="read" />
+ <property name="debug_level" type="u" access="read" />
+ <property name="enabled" type="b" access="read" />
+ <property name="type" type="s" access="read" />
+
+ <!-- FIXME: This should be part of Components.Backends interface, onece
+ SSSD supports multiple interfaces per object path. -->
+ <property name="providers" type="as" access="read" />
+ </interface>
+
<interface name="org.freedesktop.sssd.infopipe.Domains">
<annotation name="org.freedesktop.DBus.GLib.CSymbol" value="infopipe_domain"/>
diff --git a/src/responder/ifp/ifp_iface_generated.c b/src/responder/ifp/ifp_iface_generated.c
index 16beb6509..20ad56373 100644
--- a/src/responder/ifp/ifp_iface_generated.c
+++ b/src/responder/ifp/ifp_iface_generated.c
@@ -7,12 +7,105 @@
/* invokes a handler with a 's' DBus signature */
static int invoke_s_method(struct sbus_request *dbus_req, void *function_ptr);
+
+/* invokes a handler with a 'u' DBus signature */
+static int invoke_u_method(struct sbus_request *dbus_req, void *function_ptr);
static int invoke_get_s(struct sbus_request *dbus_req, void *function_ptr);
-static int invoke_get_as(struct sbus_request *dbus_req, void *function_ptr);
static int invoke_get_u(struct sbus_request *dbus_req, void *function_ptr);
static int invoke_get_b(struct sbus_request *dbus_req, void *function_ptr);
+static int invoke_get_as(struct sbus_request *dbus_req, void *function_ptr);
static int invoke_get_o(struct sbus_request *dbus_req, void *function_ptr);
+/* arguments for org.freedesktop.sssd.infopipe.ListComponents */
+const struct sbus_arg_meta infopipe_iface_ListComponents__out[] = {
+ { "components", "ao" },
+ { NULL, }
+};
+
+int infopipe_iface_ListComponents_finish(struct sbus_request *req, const char *arg_components[], int len_components)
+{
+ return sbus_request_return_and_finish(req,
+ DBUS_TYPE_ARRAY, DBUS_TYPE_OBJECT_PATH, &arg_components, len_components,
+ DBUS_TYPE_INVALID);
+}
+
+/* arguments for org.freedesktop.sssd.infopipe.ListResponders */
+const struct sbus_arg_meta infopipe_iface_ListResponders__out[] = {
+ { "responders", "ao" },
+ { NULL, }
+};
+
+int infopipe_iface_ListResponders_finish(struct sbus_request *req, const char *arg_responders[], int len_responders)
+{
+ return sbus_request_return_and_finish(req,
+ DBUS_TYPE_ARRAY, DBUS_TYPE_OBJECT_PATH, &arg_responders, len_responders,
+ DBUS_TYPE_INVALID);
+}
+
+/* arguments for org.freedesktop.sssd.infopipe.ListBackends */
+const struct sbus_arg_meta infopipe_iface_ListBackends__out[] = {
+ { "backends", "ao" },
+ { NULL, }
+};
+
+int infopipe_iface_ListBackends_finish(struct sbus_request *req, const char *arg_backends[], int len_backends)
+{
+ return sbus_request_return_and_finish(req,
+ DBUS_TYPE_ARRAY, DBUS_TYPE_OBJECT_PATH, &arg_backends, len_backends,
+ DBUS_TYPE_INVALID);
+}
+
+/* arguments for org.freedesktop.sssd.infopipe.FindMonitor */
+const struct sbus_arg_meta infopipe_iface_FindMonitor__out[] = {
+ { "monitor", "o" },
+ { NULL, }
+};
+
+int infopipe_iface_FindMonitor_finish(struct sbus_request *req, const char *arg_monitor)
+{
+ return sbus_request_return_and_finish(req,
+ DBUS_TYPE_OBJECT_PATH, &arg_monitor,
+ DBUS_TYPE_INVALID);
+}
+
+/* arguments for org.freedesktop.sssd.infopipe.FindResponderByName */
+const struct sbus_arg_meta infopipe_iface_FindResponderByName__in[] = {
+ { "name", "s" },
+ { NULL, }
+};
+
+/* arguments for org.freedesktop.sssd.infopipe.FindResponderByName */
+const struct sbus_arg_meta infopipe_iface_FindResponderByName__out[] = {
+ { "responder", "o" },
+ { NULL, }
+};
+
+int infopipe_iface_FindResponderByName_finish(struct sbus_request *req, const char *arg_responder)
+{
+ return sbus_request_return_and_finish(req,
+ DBUS_TYPE_OBJECT_PATH, &arg_responder,
+ DBUS_TYPE_INVALID);
+}
+
+/* arguments for org.freedesktop.sssd.infopipe.FindBackendByName */
+const struct sbus_arg_meta infopipe_iface_FindBackendByName__in[] = {
+ { "name", "s" },
+ { NULL, }
+};
+
+/* arguments for org.freedesktop.sssd.infopipe.FindBackendByName */
+const struct sbus_arg_meta infopipe_iface_FindBackendByName__out[] = {
+ { "backend", "o" },
+ { NULL, }
+};
+
+int infopipe_iface_FindBackendByName_finish(struct sbus_request *req, const char *arg_backend)
+{
+ return sbus_request_return_and_finish(req,
+ DBUS_TYPE_OBJECT_PATH, &arg_backend,
+ DBUS_TYPE_INVALID);
+}
+
/* arguments for org.freedesktop.sssd.infopipe.GetUserAttr */
const struct sbus_arg_meta infopipe_iface_GetUserAttr__in[] = {
{ "user", "s" },
@@ -87,6 +180,48 @@ const struct sbus_method_meta infopipe_iface__methods[] = {
NULL, /* no invoker */
},
{
+ "ListComponents", /* name */
+ NULL, /* no in_args */
+ infopipe_iface_ListComponents__out,
+ offsetof(struct infopipe_iface, ListComponents),
+ NULL, /* no invoker */
+ },
+ {
+ "ListResponders", /* name */
+ NULL, /* no in_args */
+ infopipe_iface_ListResponders__out,
+ offsetof(struct infopipe_iface, ListResponders),
+ NULL, /* no invoker */
+ },
+ {
+ "ListBackends", /* name */
+ NULL, /* no in_args */
+ infopipe_iface_ListBackends__out,
+ offsetof(struct infopipe_iface, ListBackends),
+ NULL, /* no invoker */
+ },
+ {
+ "FindMonitor", /* name */
+ NULL, /* no in_args */
+ infopipe_iface_FindMonitor__out,
+ offsetof(struct infopipe_iface, FindMonitor),
+ NULL, /* no invoker */
+ },
+ {
+ "FindResponderByName", /* name */
+ infopipe_iface_FindResponderByName__in,
+ infopipe_iface_FindResponderByName__out,
+ offsetof(struct infopipe_iface, FindResponderByName),
+ invoke_s_method,
+ },
+ {
+ "FindBackendByName", /* name */
+ infopipe_iface_FindBackendByName__in,
+ infopipe_iface_FindBackendByName__out,
+ offsetof(struct infopipe_iface, FindBackendByName),
+ invoke_s_method,
+ },
+ {
"GetUserAttr", /* name */
infopipe_iface_GetUserAttr__in,
infopipe_iface_GetUserAttr__out,
@@ -152,6 +287,231 @@ const struct sbus_interface_meta infopipe_iface_meta = {
invoke_infopipe_iface_get_all, /* GetAll invoker */
};
+int infopipe_component_Enable_finish(struct sbus_request *req)
+{
+ return sbus_request_return_and_finish(req,
+ DBUS_TYPE_INVALID);
+}
+
+int infopipe_component_Disable_finish(struct sbus_request *req)
+{
+ return sbus_request_return_and_finish(req,
+ DBUS_TYPE_INVALID);
+}
+
+/* arguments for org.freedesktop.sssd.infopipe.Components.ChangeDebugLevel */
+const struct sbus_arg_meta infopipe_component_ChangeDebugLevel__in[] = {
+ { "new_level", "u" },
+ { NULL, }
+};
+
+int infopipe_component_ChangeDebugLevel_finish(struct sbus_request *req)
+{
+ return sbus_request_return_and_finish(req,
+ DBUS_TYPE_INVALID);
+}
+
+/* arguments for org.freedesktop.sssd.infopipe.Components.ChangeDebugLevelTemporarily */
+const struct sbus_arg_meta infopipe_component_ChangeDebugLevelTemporarily__in[] = {
+ { "new_level", "u" },
+ { NULL, }
+};
+
+int infopipe_component_ChangeDebugLevelTemporarily_finish(struct sbus_request *req)
+{
+ return sbus_request_return_and_finish(req,
+ DBUS_TYPE_INVALID);
+}
+
+/* methods for org.freedesktop.sssd.infopipe.Components */
+const struct sbus_method_meta infopipe_component__methods[] = {
+ {
+ "Enable", /* name */
+ NULL, /* no in_args */
+ NULL, /* no out_args */
+ offsetof(struct infopipe_component, Enable),
+ NULL, /* no invoker */
+ },
+ {
+ "Disable", /* name */
+ NULL, /* no in_args */
+ NULL, /* no out_args */
+ offsetof(struct infopipe_component, Disable),
+ NULL, /* no invoker */
+ },
+ {
+ "ChangeDebugLevel", /* name */
+ infopipe_component_ChangeDebugLevel__in,
+ NULL, /* no out_args */
+ offsetof(struct infopipe_component, ChangeDebugLevel),
+ invoke_u_method,
+ },
+ {
+ "ChangeDebugLevelTemporarily", /* name */
+ infopipe_component_ChangeDebugLevelTemporarily__in,
+ NULL, /* no out_args */
+ offsetof(struct infopipe_component, ChangeDebugLevelTemporarily),
+ invoke_u_method,
+ },
+ { NULL, }
+};
+
+/* invokes GetAll for the 'org.freedesktop.sssd.infopipe.Components' interface */
+static int invoke_infopipe_component_get_all(struct sbus_request *dbus_req, void *function_ptr)
+{
+ struct sbus_interface *intf = dbus_req->intf;
+ const struct sbus_property_meta *property;
+ DBusMessage *reply;
+ dbus_bool_t dbret;
+ DBusMessageIter iter;
+ DBusMessageIter iter_dict;
+ int ret;
+ const char * s_prop_val;
+ const char * s_out_val;
+ void (*s_handler)(struct sbus_request *, void *data, const char * *);
+ bool b_prop_val;
+ dbus_bool_t b_out_val;
+ void (*b_handler)(struct sbus_request *, void *data, bool *);
+ uint32_t u_prop_val;
+ uint32_t u_out_val;
+ void (*u_handler)(struct sbus_request *, void *data, uint32_t *);
+ const char * *as_prop_val;
+ int as_prop_len;
+ const char * *as_out_val;
+ void (*as_handler)(struct sbus_request *, void *data, const char * * *, int *);
+
+ reply = dbus_message_new_method_return(dbus_req->message);
+ if (!reply) return ENOMEM;
+ dbus_message_iter_init_append(reply, &iter);
+ dbret = dbus_message_iter_open_container(
+ &iter, DBUS_TYPE_ARRAY,
+ DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
+ DBUS_TYPE_STRING_AS_STRING
+ DBUS_TYPE_VARIANT_AS_STRING
+ DBUS_DICT_ENTRY_END_CHAR_AS_STRING,
+ &iter_dict);
+ if (!dbret) return ENOMEM;
+
+ property = sbus_meta_find_property(intf->vtable->meta, "name");
+ if (property != NULL && property->flags & SBUS_PROPERTY_READABLE) {
+ s_handler = VTABLE_FUNC(intf->vtable, property->vtable_offset_get);
+ if (s_handler) {
+ (s_handler)(dbus_req, dbus_req->intf->instance_data, &s_prop_val);
+ s_out_val = s_prop_val == NULL ? "" : s_prop_val;
+ ret = sbus_add_variant_to_dict(&iter_dict, "name", DBUS_TYPE_STRING, &s_out_val);
+ if (ret != EOK) return ret;
+ }
+ }
+
+ property = sbus_meta_find_property(intf->vtable->meta, "debug_level");
+ if (property != NULL && property->flags & SBUS_PROPERTY_READABLE) {
+ u_handler = VTABLE_FUNC(intf->vtable, property->vtable_offset_get);
+ if (u_handler) {
+ (u_handler)(dbus_req, dbus_req->intf->instance_data, &u_prop_val);
+ u_out_val = u_prop_val;
+ ret = sbus_add_variant_to_dict(&iter_dict, "debug_level", DBUS_TYPE_UINT32, &u_out_val);
+ if (ret != EOK) return ret;
+ }
+ }
+
+ property = sbus_meta_find_property(intf->vtable->meta, "enabled");
+ if (property != NULL && property->flags & SBUS_PROPERTY_READABLE) {
+ b_handler = VTABLE_FUNC(intf->vtable, property->vtable_offset_get);
+ if (b_handler) {
+ (b_handler)(dbus_req, dbus_req->intf->instance_data, &b_prop_val);
+ b_out_val = b_prop_val;
+ ret = sbus_add_variant_to_dict(&iter_dict, "enabled", DBUS_TYPE_BOOLEAN, &b_out_val);
+ if (ret != EOK) return ret;
+ }
+ }
+
+ property = sbus_meta_find_property(intf->vtable->meta, "type");
+ if (property != NULL && property->flags & SBUS_PROPERTY_READABLE) {
+ s_handler = VTABLE_FUNC(intf->vtable, property->vtable_offset_get);
+ if (s_handler) {
+ (s_handler)(dbus_req, dbus_req->intf->instance_data, &s_prop_val);
+ s_out_val = s_prop_val == NULL ? "" : s_prop_val;
+ ret = sbus_add_variant_to_dict(&iter_dict, "type", DBUS_TYPE_STRING, &s_out_val);
+ if (ret != EOK) return ret;
+ }
+ }
+
+ property = sbus_meta_find_property(intf->vtable->meta, "providers");
+ if (property != NULL && property->flags & SBUS_PROPERTY_READABLE) {
+ as_handler = VTABLE_FUNC(intf->vtable, property->vtable_offset_get);
+ if (as_handler) {
+ (as_handler)(dbus_req, dbus_req->intf->instance_data, &as_prop_val, &as_prop_len);
+ as_out_val = as_prop_val;
+ ret = sbus_add_array_as_variant_to_dict(&iter_dict, "providers", DBUS_TYPE_STRING, (uint8_t*)as_out_val, as_prop_len, sizeof(const char *));
+ if (ret != EOK) return ret;
+ }
+ }
+
+ dbret = dbus_message_iter_close_container(&iter, &iter_dict);
+ if (!dbret) return ENOMEM;
+
+ return sbus_request_finish(dbus_req, reply);
+}
+
+/* property info for org.freedesktop.sssd.infopipe.Components */
+const struct sbus_property_meta infopipe_component__properties[] = {
+ {
+ "name", /* name */
+ "s", /* type */
+ SBUS_PROPERTY_READABLE,
+ offsetof(struct infopipe_component, infopipe_component_get_name),
+ invoke_get_s,
+ 0, /* not writable */
+ NULL, /* no invoker */
+ },
+ {
+ "debug_level", /* name */
+ "u", /* type */
+ SBUS_PROPERTY_READABLE,
+ offsetof(struct infopipe_component, infopipe_component_get_debug_level),
+ invoke_get_u,
+ 0, /* not writable */
+ NULL, /* no invoker */
+ },
+ {
+ "enabled", /* name */
+ "b", /* type */
+ SBUS_PROPERTY_READABLE,
+ offsetof(struct infopipe_component, infopipe_component_get_enabled),
+ invoke_get_b,
+ 0, /* not writable */
+ NULL, /* no invoker */
+ },
+ {
+ "type", /* name */
+ "s", /* type */
+ SBUS_PROPERTY_READABLE,
+ offsetof(struct infopipe_component, infopipe_component_get_type),
+ invoke_get_s,
+ 0, /* not writable */
+ NULL, /* no invoker */
+ },
+ {
+ "providers", /* name */
+ "as", /* type */
+ SBUS_PROPERTY_READABLE,
+ offsetof(struct infopipe_component, infopipe_component_get_providers),
+ invoke_get_as,
+ 0, /* not writable */
+ NULL, /* no invoker */
+ },
+ { NULL, }
+};
+
+/* interface info for org.freedesktop.sssd.infopipe.Components */
+const struct sbus_interface_meta infopipe_component_meta = {
+ "org.freedesktop.sssd.infopipe.Components", /* name */
+ infopipe_component__methods,
+ NULL, /* no signals */
+ infopipe_component__properties,
+ invoke_infopipe_component_get_all, /* GetAll invoker */
+};
+
/* invokes GetAll for the 'org.freedesktop.sssd.infopipe.Domains' interface */
static int invoke_infopipe_domain_get_all(struct sbus_request *dbus_req, void *function_ptr)
{
@@ -507,6 +867,22 @@ static int invoke_s_method(struct sbus_request *dbus_req, void *function_ptr)
arg_0);
}
+/* invokes a handler with a 'u' DBus signature */
+static int invoke_u_method(struct sbus_request *dbus_req, void *function_ptr)
+{
+ uint32_t arg_0;
+ int (*handler)(struct sbus_request *, void *, uint32_t) = function_ptr;
+
+ if (!sbus_request_parse_or_finish(dbus_req,
+ DBUS_TYPE_UINT32, &arg_0,
+ DBUS_TYPE_INVALID)) {
+ return EOK; /* request handled */
+ }
+
+ return (handler)(dbus_req, dbus_req->intf->instance_data,
+ arg_0);
+}
+
/* invokes a getter with a 'const char *' DBus type */
static int invoke_get_s(struct sbus_request *dbus_req, void *function_ptr)
{
diff --git a/src/responder/ifp/ifp_iface_generated.h b/src/responder/ifp/ifp_iface_generated.h
index 3fe8c41e9..3a3e6955e 100644
--- a/src/responder/ifp/ifp_iface_generated.h
+++ b/src/responder/ifp/ifp_iface_generated.h
@@ -14,11 +14,29 @@
/* constants for org.freedesktop.sssd.infopipe */
#define INFOPIPE_IFACE "org.freedesktop.sssd.infopipe"
#define INFOPIPE_IFACE_PING "Ping"
+#define INFOPIPE_IFACE_LISTCOMPONENTS "ListComponents"
+#define INFOPIPE_IFACE_LISTRESPONDERS "ListResponders"
+#define INFOPIPE_IFACE_LISTBACKENDS "ListBackends"
+#define INFOPIPE_IFACE_FINDMONITOR "FindMonitor"
+#define INFOPIPE_IFACE_FINDRESPONDERBYNAME "FindResponderByName"
+#define INFOPIPE_IFACE_FINDBACKENDBYNAME "FindBackendByName"
#define INFOPIPE_IFACE_GETUSERATTR "GetUserAttr"
#define INFOPIPE_IFACE_GETUSERGROUPS "GetUserGroups"
#define INFOPIPE_IFACE_FINDDOMAINBYNAME "FindDomainByName"
#define INFOPIPE_IFACE_LISTDOMAINS "ListDomains"
+/* constants for org.freedesktop.sssd.infopipe.Components */
+#define INFOPIPE_COMPONENT "org.freedesktop.sssd.infopipe.Components"
+#define INFOPIPE_COMPONENT_ENABLE "Enable"
+#define INFOPIPE_COMPONENT_DISABLE "Disable"
+#define INFOPIPE_COMPONENT_CHANGEDEBUGLEVEL "ChangeDebugLevel"
+#define INFOPIPE_COMPONENT_CHANGEDEBUGLEVELTEMPORARILY "ChangeDebugLevelTemporarily"
+#define INFOPIPE_COMPONENT_NAME "name"
+#define INFOPIPE_COMPONENT_DEBUG_LEVEL "debug_level"
+#define INFOPIPE_COMPONENT_ENABLED "enabled"
+#define INFOPIPE_COMPONENT_TYPE "type"
+#define INFOPIPE_COMPONENT_PROVIDERS "providers"
+
/* constants for org.freedesktop.sssd.infopipe.Domains */
#define INFOPIPE_DOMAIN "org.freedesktop.sssd.infopipe.Domains"
#define INFOPIPE_DOMAIN_NAME "name"
@@ -58,12 +76,36 @@
struct infopipe_iface {
struct sbus_vtable vtable; /* derive from sbus_vtable */
sbus_msg_handler_fn Ping;
+ int (*ListComponents)(struct sbus_request *req, void *data);
+ int (*ListResponders)(struct sbus_request *req, void *data);
+ int (*ListBackends)(struct sbus_request *req, void *data);
+ int (*FindMonitor)(struct sbus_request *req, void *data);
+ int (*FindResponderByName)(struct sbus_request *req, void *data, const char *arg_name);
+ int (*FindBackendByName)(struct sbus_request *req, void *data, const char *arg_name);
sbus_msg_handler_fn GetUserAttr;
int (*GetUserGroups)(struct sbus_request *req, void *data, const char *arg_user);
int (*FindDomainByName)(struct sbus_request *req, void *data, const char *arg_name);
int (*ListDomains)(struct sbus_request *req, void *data);
};
+/* finish function for ListComponents */
+int infopipe_iface_ListComponents_finish(struct sbus_request *req, const char *arg_components[], int len_components);
+
+/* finish function for ListResponders */
+int infopipe_iface_ListResponders_finish(struct sbus_request *req, const char *arg_responders[], int len_responders);
+
+/* finish function for ListBackends */
+int infopipe_iface_ListBackends_finish(struct sbus_request *req, const char *arg_backends[], int len_backends);
+
+/* finish function for FindMonitor */
+int infopipe_iface_FindMonitor_finish(struct sbus_request *req, const char *arg_monitor);
+
+/* finish function for FindResponderByName */
+int infopipe_iface_FindResponderByName_finish(struct sbus_request *req, const char *arg_responder);
+
+/* finish function for FindBackendByName */
+int infopipe_iface_FindBackendByName_finish(struct sbus_request *req, const char *arg_backend);
+
/* finish function for GetUserGroups */
int infopipe_iface_GetUserGroups_finish(struct sbus_request *req, const char *arg_values[], int len_values);
@@ -73,6 +115,32 @@ int infopipe_iface_FindDomainByName_finish(struct sbus_request *req, const char
/* finish function for ListDomains */
int infopipe_iface_ListDomains_finish(struct sbus_request *req, const char *arg_domain[], int len_domain);
+/* vtable for org.freedesktop.sssd.infopipe.Components */
+struct infopipe_component {
+ struct sbus_vtable vtable; /* derive from sbus_vtable */
+ int (*Enable)(struct sbus_request *req, void *data);
+ int (*Disable)(struct sbus_request *req, void *data);
+ int (*ChangeDebugLevel)(struct sbus_request *req, void *data, uint32_t arg_new_level);
+ int (*ChangeDebugLevelTemporarily)(struct sbus_request *req, void *data, uint32_t arg_new_level);
+ void (*infopipe_component_get_name)(struct sbus_request *, void *data, const char * *);
+ void (*infopipe_component_get_debug_level)(struct sbus_request *, void *data, uint32_t *);
+ void (*infopipe_component_get_enabled)(struct sbus_request *, void *data, bool *);
+ void (*infopipe_component_get_type)(struct sbus_request *, void *data, const char * *);
+ void (*infopipe_component_get_providers)(struct sbus_request *, void *data, const char * * *, int *);
+};
+
+/* finish function for Enable */
+int infopipe_component_Enable_finish(struct sbus_request *req);
+
+/* finish function for Disable */
+int infopipe_component_Disable_finish(struct sbus_request *req);
+
+/* finish function for ChangeDebugLevel */
+int infopipe_component_ChangeDebugLevel_finish(struct sbus_request *req);
+
+/* finish function for ChangeDebugLevelTemporarily */
+int infopipe_component_ChangeDebugLevelTemporarily_finish(struct sbus_request *req);
+
/* vtable for org.freedesktop.sssd.infopipe.Domains */
struct infopipe_domain {
struct sbus_vtable vtable; /* derive from sbus_vtable */
@@ -105,6 +173,9 @@ struct infopipe_domain {
/* interface info for org.freedesktop.sssd.infopipe */
extern const struct sbus_interface_meta infopipe_iface_meta;
+/* interface info for org.freedesktop.sssd.infopipe.Components */
+extern const struct sbus_interface_meta infopipe_component_meta;
+
/* interface info for org.freedesktop.sssd.infopipe.Domains */
extern const struct sbus_interface_meta infopipe_domain_meta;
diff --git a/src/responder/ifp/ifpsrv.c b/src/responder/ifp/ifpsrv.c
index 3e7d0dff6..8613504b4 100644
--- a/src/responder/ifp/ifpsrv.c
+++ b/src/responder/ifp/ifpsrv.c
@@ -39,6 +39,7 @@
#include "confdb/confdb.h"
#include "responder/ifp/ifp_private.h"
#include "responder/ifp/ifp_domains.h"
+#include "responder/ifp/ifp_components.h"
#include "responder/common/responder_sbus.h"
#define DEFAULT_ALLOWED_UIDS "0"
@@ -67,12 +68,36 @@ static struct data_provider_iface ifp_dp_methods = {
struct infopipe_iface ifp_iface = {
{ &infopipe_iface_meta, 0 },
.Ping = ifp_ping,
+
+ /* components */
+ .ListComponents = ifp_list_components,
+ .ListResponders = ifp_list_responders,
+ .ListBackends = ifp_list_backends,
+ .FindMonitor = ifp_find_monitor,
+ .FindResponderByName = ifp_find_responder_by_name,
+ .FindBackendByName = ifp_find_backend_by_name,
+
.GetUserAttr = ifp_user_get_attr,
.GetUserGroups = ifp_user_get_groups,
.ListDomains = ifp_list_domains,
.FindDomainByName = ifp_find_domain_by_name,
};
+struct infopipe_component ifp_component = {
+ { &infopipe_component_meta, 0 },
+ .Enable = ifp_component_enable,
+ .Disable = ifp_component_disable,
+ .ChangeDebugLevel = ifp_component_change_debug_level,
+ .ChangeDebugLevelTemporarily = ifp_component_change_debug_level_tmp,
+ .infopipe_component_get_name = ifp_component_get_name,
+ .infopipe_component_get_debug_level = ifp_component_get_debug_level,
+ .infopipe_component_get_enabled = ifp_component_get_enabled,
+ .infopipe_component_get_type = ifp_component_get_type,
+ /* FIXME: This should be part of Components.Backends interface, onece
+ * SSSD supports multiple interfaces per object path. */
+ .infopipe_component_get_providers = ifp_backend_get_providers
+};
+
struct infopipe_domain ifp_domain = {
{ &infopipe_domain_meta, 0 },
.infopipe_domain_get_name = ifp_dom_get_name,
@@ -99,6 +124,7 @@ struct sysbus_iface {
static struct sysbus_iface ifp_ifaces[] = {
{ INFOPIPE_PATH, &ifp_iface.vtable },
{ INFOPIPE_DOMAIN_PATH, &ifp_domain.vtable },
+ { INFOPIPE_COMPONENT_PATH, &ifp_component.vtable },
{ NULL, NULL },
};
diff --git a/src/responder/ifp/org.freedesktop.sssd.infopipe.conf b/src/responder/ifp/org.freedesktop.sssd.infopipe.conf
index 4f2a906ba..a6f379afc 100644
--- a/src/responder/ifp/org.freedesktop.sssd.infopipe.conf
+++ b/src/responder/ifp/org.freedesktop.sssd.infopipe.conf
@@ -32,4 +32,8 @@
<allow send_interface="org.freedesktop.sssd.infopipe"/>
</policy>
+ <policy user="root">
+ <allow send_interface="org.freedesktop.sssd.infopipe.Components"/>
+ </policy>
+
</busconfig>