From 8a1fd0633e85221da1fb63451516a70d66c0af31 Mon Sep 17 00:00:00 2001 From: Pavel Březina Date: Fri, 2 May 2014 13:08:21 +0200 Subject: IFP: Implement SSSD components Reviewed-by: Jakub Hrozek --- Makefile.am | 7 + src/responder/ifp/ifp_components.c | 988 +++++++++++++++++++++ src/responder/ifp/ifp_components.h | 87 ++ src/responder/ifp/ifp_iface.xml | 51 ++ src/responder/ifp/ifp_iface_generated.c | 378 +++++++- src/responder/ifp/ifp_iface_generated.h | 71 ++ src/responder/ifp/ifpsrv.c | 26 + .../ifp/org.freedesktop.sssd.infopipe.conf | 4 + 8 files changed, 1611 insertions(+), 1 deletion(-) create mode 100644 src/responder/ifp/ifp_components.c create mode 100644 src/responder/ifp/ifp_components.h 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 + + 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 . +*/ + +#include +#include +#include + +#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 + + 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 . +*/ + +#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 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -32,6 +60,29 @@ + + + + + + + + + + + + + + + + + + + + + + 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" }, @@ -86,6 +179,48 @@ const struct sbus_method_meta infopipe_iface__methods[] = { offsetof(struct infopipe_iface, Ping), 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, @@ -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 @@ + + + + -- cgit