diff options
Diffstat (limited to 'src/responder/ifp')
40 files changed, 18306 insertions, 0 deletions
diff --git a/src/responder/ifp/ifp_cache.c b/src/responder/ifp/ifp_cache.c new file mode 100644 index 0000000..a4dd393 --- /dev/null +++ b/src/responder/ifp/ifp_cache.c @@ -0,0 +1,270 @@ +/* + Authors: + Pavel Březina <pbrezina@redhat.com> + + Copyright (C) 2015 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 <talloc.h> +#include <tevent.h> + +#include "db/sysdb.h" +#include "util/util.h" +#include "responder/common/responder.h" +#include "responder/ifp/ifp_cache.h" +#include "responder/ifp/ifp_users.h" +#include "responder/ifp/ifp_groups.h" + +static struct ldb_dn * +ifp_cache_build_base_dn(TALLOC_CTX *mem_ctx, + enum ifp_cache_type type, + struct sss_domain_info *domain) +{ + struct ldb_dn *base_dn = NULL; + + switch (type) { + case IFP_CACHE_USER: + base_dn = sysdb_user_base_dn(mem_ctx, domain); + break; + case IFP_CACHE_GROUP: + base_dn = sysdb_group_base_dn(mem_ctx, domain); + break; + } + + return base_dn; +} + +static char * +ifp_cache_build_path(TALLOC_CTX *mem_ctx, + enum ifp_cache_type type, + struct sss_domain_info *domain, + struct ldb_message *msg) +{ + char *path = NULL; + + switch (type) { + case IFP_CACHE_USER: + path = ifp_users_build_path_from_msg(mem_ctx, domain, msg); + break; + case IFP_CACHE_GROUP: + path = ifp_groups_build_path_from_msg(mem_ctx, domain, msg); + break; + } + + return path; +} + +static const char * +ifp_cache_object_class(enum ifp_cache_type type) +{ + const char *class = NULL; + + switch (type) { + case IFP_CACHE_USER: + class = SYSDB_USER_CLASS; + break; + case IFP_CACHE_GROUP: + class = SYSDB_GROUP_CLASS; + break; + } + + return class; +} + +static errno_t +ifp_cache_get_cached_objects(TALLOC_CTX *mem_ctx, + enum ifp_cache_type type, + struct sss_domain_info *domain, + const char ***_paths) +{ + TALLOC_CTX *tmp_ctx; + struct ldb_dn *base_dn; + struct ldb_result *result; + const char *class = ifp_cache_object_class(type); + const char **paths; + errno_t ret; + int ldb_ret; + int i; + const char *attrs[] = {SYSDB_OBJECTCATEGORY, SYSDB_UIDNUM, + SYSDB_GIDNUM, NULL}; + + tmp_ctx = talloc_new(NULL); + if (tmp_ctx == NULL) { + return ENOMEM; + } + + base_dn = ifp_cache_build_base_dn(tmp_ctx, type, domain); + if (base_dn == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "Unable to create base dn\n"); + ret = ENOMEM; + goto done; + } + + ldb_ret = ldb_search(sysdb_ctx_get_ldb(domain->sysdb), tmp_ctx, &result, + base_dn, LDB_SCOPE_SUBTREE, attrs, + "(&(%s=%s)(%s=TRUE))", SYSDB_OBJECTCATEGORY, class, + SYSDB_IFP_CACHED); + if (ldb_ret != LDB_SUCCESS) { + DEBUG(SSSDBG_CRIT_FAILURE, "Unable to search the cache\n"); + ret = sss_ldb_error_to_errno(ldb_ret); + goto done; + } + + paths = talloc_zero_array(tmp_ctx, const char *, result->count + 1); + if (paths == NULL) { + ret = ENOMEM; + goto done; + } + + for (i = 0; i < result->count; i++) { + paths[i] = ifp_cache_build_path(paths, type, domain, result->msgs[i]); + if (paths[i] == NULL) { + ret = ENOMEM; + goto done; + } + } + + *_paths = talloc_steal(mem_ctx, paths); + + ret = EOK; + +done: + talloc_free(tmp_ctx); + return ret; +} + +errno_t +ifp_cache_list_domains(TALLOC_CTX *mem_ctx, + struct sss_domain_info *domains, + enum ifp_cache_type type, + const char ***_paths) +{ + TALLOC_CTX *tmp_ctx; + struct sss_domain_info *domain; + const char **tmp_paths = NULL; + const char **paths; + errno_t ret; + + tmp_ctx = talloc_new(NULL); + if (tmp_ctx == NULL) { + return ENOMEM; + } + + domain = domains; + paths = NULL; + while (domain != NULL) { + ret = ifp_cache_get_cached_objects(tmp_ctx, type, domain, &tmp_paths); + if (ret != EOK) { + DEBUG(SSSDBG_CRIT_FAILURE, "Unable to build object list " + "[%d]: %s\n", ret, sss_strerror(ret)); + goto done; + } + + ret = add_strings_lists(tmp_ctx, paths, tmp_paths, true, &paths); + if (ret != EOK) { + DEBUG(SSSDBG_CRIT_FAILURE, "Unable to build object list " + "[%d]: %s\n", ret, sss_strerror(ret)); + goto done; + } + + domain = get_next_domain(domain, SSS_GND_DESCEND); + } + + if (_paths != NULL) { + *_paths = talloc_steal(mem_ctx, paths); + } + + ret = EOK; + +done: + talloc_free(tmp_ctx); + return ret; +} + +errno_t +ifp_cache_list(TALLOC_CTX *mem_ctx, + struct ifp_ctx *ifp_ctx, + enum ifp_cache_type type, + const char ***_paths) +{ + return ifp_cache_list_domains(mem_ctx, ifp_ctx->rctx->domains, + type, _paths); +} + +errno_t +ifp_cache_list_by_domain(TALLOC_CTX *mem_ctx, + struct ifp_ctx *ifp_ctx, + const char *domainname, + enum ifp_cache_type type, + const char ***_paths) +{ + struct sss_domain_info *domain; + + domain = find_domain_by_name(ifp_ctx->rctx->domains, domainname, true); + if (domain == NULL) { + return ERR_DOMAIN_NOT_FOUND; + } + + return ifp_cache_get_cached_objects(mem_ctx, type, domain, _paths); +} + +static errno_t ifp_cache_object_set(struct sss_domain_info *domain, + struct ldb_dn *dn, + bool value) +{ + struct sysdb_attrs *attrs; + errno_t ret; + + attrs = sysdb_new_attrs(NULL); + if (attrs == NULL) { + return ENOMEM; + } + + ret = sysdb_attrs_add_bool(attrs, SYSDB_IFP_CACHED, value); + if (ret != EOK) { + DEBUG(SSSDBG_CRIT_FAILURE, "Unable to add attribute [%d]: %s\n", + ret, sss_strerror(ret)); + goto done; + } + + ret = sysdb_set_entry_attr(domain->sysdb, dn, attrs, SYSDB_MOD_REP); + if (ret != EOK) { + DEBUG(SSSDBG_CRIT_FAILURE, "Unable to modify entry [%d]: %s\n", + ret, sss_strerror(ret)); + goto done; + } + + ret = EOK; + +done: + talloc_free(attrs); + + return ret; +} + +errno_t +ifp_cache_object_store(struct sss_domain_info *domain, + struct ldb_dn *dn) +{ + return ifp_cache_object_set(domain, dn, true); +} + +errno_t +ifp_cache_object_remove(struct sss_domain_info *domain, + struct ldb_dn *dn) +{ + return ifp_cache_object_set(domain, dn, false); +} diff --git a/src/responder/ifp/ifp_cache.h b/src/responder/ifp/ifp_cache.h new file mode 100644 index 0000000..5c05a7f --- /dev/null +++ b/src/responder/ifp/ifp_cache.h @@ -0,0 +1,63 @@ +/* + Authors: + Pavel Březina <pbrezina@redhat.com> + + Copyright (C) 2015 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_CACHE_H_ +#define IFP_CACHE_H_ + +#include "confdb/confdb.h" +#include "responder/common/responder.h" +#include "responder/ifp/ifp_private.h" + +enum ifp_cache_type { + IFP_CACHE_USER, + IFP_CACHE_GROUP +}; + +errno_t +ifp_cache_list_domains(TALLOC_CTX *mem_ctx, + struct sss_domain_info *domains, + enum ifp_cache_type type, + const char ***_paths); + +/* org.freedesktop-sssd-infopipe.Cache */ + +errno_t +ifp_cache_list(TALLOC_CTX *mem_ctx, + struct ifp_ctx *ifp_ctx, + enum ifp_cache_type type, + const char ***_paths); + +errno_t +ifp_cache_list_by_domain(TALLOC_CTX *mem_ctx, + struct ifp_ctx *ifp_ctx, + const char *domainname, + enum ifp_cache_type type, + const char ***_paths); + +/* org.freedesktop-sssd-infopipe.Cache.Object */ + +errno_t +ifp_cache_object_store(struct sss_domain_info *domain, + struct ldb_dn *dn); + +errno_t +ifp_cache_object_remove(struct sss_domain_info *domain, + struct ldb_dn *dn); +#endif /* IFP_CACHE_H_ */ diff --git a/src/responder/ifp/ifp_components.c b/src/responder/ifp/ifp_components.c new file mode 100644 index 0000000..c6b9837 --- /dev/null +++ b/src/responder/ifp/ifp_components.c @@ -0,0 +1,662 @@ +/* + 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 <errno.h> +#include <utime.h> + +#include "config.h" +#include "confdb/confdb.h" +#include "util/util.h" +#include "responder/common/responder.h" +#include "responder/ifp/ifp_components.h" + +#define PATH_MONITOR IFP_PATH_COMPONENTS "/monitor" +#define PATH_RESPONDERS IFP_PATH_COMPONENTS "/Responders" +#define PATH_BACKENDS IFP_PATH_COMPONENTS "/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; + char *name = NULL; + errno_t ret; + + if (confdb == NULL || path == NULL) { + return EINVAL; + } + + if (strcmp(path, PATH_MONITOR) == 0) { + type = COMPONENT_MONITOR; + name = talloc_strdup(mem_ctx, "monitor"); + if (name == NULL) { + ret = ENOMEM; + goto done; + } + } else { + name = sbus_opath_object_name(mem_ctx, path, PATH_RESPONDERS); + if (name != NULL) { + type = COMPONENT_RESPONDER; + } else { + name = sbus_opath_object_name(mem_ctx, path, PATH_BACKENDS); + if (name != NULL) { + type = COMPONENT_BACKEND; + } else { + ret = EINVAL; + goto done; + } + } + } + + if (strchr(name, '/') != NULL) { + ret = EINVAL; + goto done; + } + + switch (type) { + case COMPONENT_MONITOR: + /* noop */ + break; + case COMPONENT_RESPONDER: + if (!responder_exists(name)) { + ret = ENOENT; + goto done; + } + break; + case COMPONENT_BACKEND: + if (!backend_exists(confdb, name)) { + ret = ENOENT; + goto done; + } + break; + } + + if (_type != NULL) { + *_type = type; + } + + if (_name != NULL) { + *_name = name; + } + + ret = EOK; + +done: + if (ret != EOK) { + talloc_free(name); + } + + 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_zero_array(mem_ctx, const char*, num + 1); + if (list == NULL) { + ret = ENOMEM; + goto done; + } + + for (i = 0; i < num; i++) { + list[i] = sbus_opath_compose(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_zero_array(tmp_ctx, const char*, num + 1); + if (list == NULL) { + ret = ENOMEM; + goto done; + } + + for (i = 0; i < num; i++) { + list[i] = sbus_opath_compose(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; +} + +errno_t +ifp_list_components(TALLOC_CTX *mem_ctx, + struct sbus_request *sbus_req, + struct ifp_ctx *ctx, + const char ***_paths) +{ + TALLOC_CTX *tmp_ctx; + const char **responders; + const char **backends; + const char **result; + int num_responders; + int num_backends; + int num; + int i; + errno_t ret; + + tmp_ctx = talloc_new(NULL); + if (tmp_ctx == NULL) { + DEBUG(SSSDBG_FATAL_FAILURE, "Out of memory!\n"); + return ENOMEM; + } + + ret = list_responders(tmp_ctx, &responders, &num_responders); + if (ret != EOK) { + goto done; + } + + ret = list_backends(tmp_ctx, ctx->rctx->cdb, &backends, &num_backends); + if (ret != EOK) { + goto done; + } + + num = num_responders + num_backends + 1; + result = talloc_zero_array(mem_ctx, const char *, num + 1); + 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]); + } + + *_paths = result; + + ret = EOK; + +done: + talloc_free(tmp_ctx); + + return ret; +} + + +errno_t +ifp_list_responders(TALLOC_CTX *mem_ctx, + struct sbus_request *sbus_req, + struct ifp_ctx *ctx, + const char ***_paths) +{ + const char **result; + int num; + errno_t ret; + + ret = list_responders(mem_ctx, &result, &num); + if (ret != EOK) { + return ret; + } + + *_paths = result; + + return EOK; +} + +errno_t +ifp_list_backends(TALLOC_CTX *mem_ctx, + struct sbus_request *sbus_req, + struct ifp_ctx *ctx, + const char ***_paths) +{ + const char **result; + int num; + errno_t ret; + + ret = list_backends(mem_ctx, ctx->rctx->cdb, &result, &num); + if (ret != EOK) { + return ret; + } + + *_paths = result; + + return EOK; +} + +errno_t +ifp_find_monitor(TALLOC_CTX *mem_ctx, + struct sbus_request *sbus_req, + struct ifp_ctx *ctx, + const char **_path) +{ + *_path = PATH_MONITOR; + + return EOK; +} + + +errno_t +ifp_find_responder_by_name(TALLOC_CTX *mem_ctx, + struct sbus_request *sbus_req, + struct ifp_ctx *ctx, + const char *name, + const char **_path) +{ + const char *result; + + if (responder_exists(name)) { + result = sbus_opath_compose(mem_ctx, PATH_RESPONDERS, name); + if (result == NULL) { + return ENOMEM; + } + + *_path = result; + return EOK; + } + + DEBUG(SSSDBG_MINOR_FAILURE, "Responder \"%s\" does not exist", name); + return ENOENT; +} + +errno_t +ifp_find_backend_by_name(TALLOC_CTX *mem_ctx, + struct sbus_request *sbus_req, + struct ifp_ctx *ctx, + const char *name, + const char **_path) +{ + const char *result; + + if (backend_exists(ctx->rctx->cdb, name)) { + result = sbus_opath_compose(mem_ctx, PATH_BACKENDS, name); + if (result == NULL) { + return ENOMEM; + } + + *_path = result; + return EOK; + } + + DEBUG(SSSDBG_MINOR_FAILURE, "Backend \"%s\" does not exist", name); + return ENOENT; +} + +errno_t +ifp_component_get_name(TALLOC_CTX *mem_ctx, + struct sbus_request *sbus_req, + struct ifp_ctx *ctx, + const char **_out) +{ + char *name; + errno_t ret; + + ret = check_and_get_component_from_path(mem_ctx, ctx->rctx->cdb, + sbus_req->path, NULL, &name); + if (ret != EOK) { + DEBUG(SSSDBG_OP_FAILURE, "Unknown object [%d]: %s\n", + ret, sss_strerror(ret)); + return ret; + } + + *_out = name; + + return EOK; +} + +errno_t +ifp_component_get_debug_level(TALLOC_CTX *mem_ctx, + struct sbus_request *sbus_req, + struct ifp_ctx *ctx, + uint32_t *_out) +{ + TALLOC_CTX *tmp_ctx; + const char *confdb_path = NULL; + enum component_type type; + char *name; + int level; + errno_t ret; + + tmp_ctx = talloc_new(NULL); + if (tmp_ctx == NULL) { + DEBUG(SSSDBG_FATAL_FAILURE, "Out of memory!\n"); + return ENOMEM; + } + + ret = check_and_get_component_from_path(tmp_ctx, ctx->rctx->cdb, + sbus_req->path, &type, &name); + if (ret != EOK) { + DEBUG(SSSDBG_OP_FAILURE, "Unknown object [%d]: %s\n", + ret, sss_strerror(ret)); + goto done; + } + + 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) { + DEBUG(SSSDBG_CRIT_FAILURE, "Out of memory\n"); + ret = ENOMEM; + goto done; + } + + 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, sss_strerror(ret)); + goto done; + } + + *_out = level; + + ret = EOK; + +done: + talloc_free(tmp_ctx); + + return ret; +} + +errno_t +ifp_component_get_enabled(TALLOC_CTX *mem_ctx, + struct sbus_request *sbus_req, + struct ifp_ctx *ctx, + bool *_out) +{ + TALLOC_CTX *tmp_ctx; + enum component_type type; + const char *param = NULL; + char **values; + char *name; + errno_t ret; + int i; + + tmp_ctx = talloc_new(NULL); + if (tmp_ctx == NULL) { + DEBUG(SSSDBG_FATAL_FAILURE, "Out of memory!\n"); + return ENOMEM; + } + + ret = check_and_get_component_from_path(tmp_ctx, ctx->rctx->cdb, + sbus_req->path, &type, &name); + if (ret != EOK) { + DEBUG(SSSDBG_OP_FAILURE, "Unknown object [%d]: %s\n", + ret, sss_strerror(ret)); + goto done; + } + + switch (type) { + case COMPONENT_MONITOR: + *_out = true; + ret = EOK; + goto done; + 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, tmp_ctx, + CONFDB_MONITOR_CONF_ENTRY, param, &values); + if (ret != EOK) { + DEBUG(SSSDBG_OP_FAILURE, "Unable to retrieve configuration option" + "[%d]: %s\n", ret, sss_strerror(ret)); + goto done; + } + + for (i = 0; values[i] != NULL; i++) { + if (strcmp(values[i], name) == 0) { + *_out = true; + break; + } + } + + ret = EOK; + +done: + talloc_free(tmp_ctx); + + return ret; +} + +errno_t +ifp_component_get_type(TALLOC_CTX *mem_ctx, + struct sbus_request *sbus_req, + struct ifp_ctx *ctx, + const char **_out) +{ + enum component_type type; + errno_t ret; + + ret = check_and_get_component_from_path(mem_ctx, ctx->rctx->cdb, + sbus_req->path, &type, NULL); + if (ret != EOK) { + DEBUG(SSSDBG_OP_FAILURE, "Unknown object [%d]: %s\n", + ret, sss_strerror(ret)); + return ret; + } + + switch (type) { + case COMPONENT_MONITOR: + *_out = "monitor"; + break; + case COMPONENT_RESPONDER: + *_out = "responder"; + break; + case COMPONENT_BACKEND: + *_out = "backend"; + break; + } + + return EOK; +} + +errno_t +ifp_backend_get_providers(TALLOC_CTX *mem_ctx, + struct sbus_request *sbus_req, + struct ifp_ctx *ctx, + const char ***_out) +{ + TALLOC_CTX *tmp_ctx; + const char *confdb_path; + char *name; + enum component_type type; + const char **out; + char *value; + 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, + CONFDB_DOMAIN_SESSION_PROVIDER}; + int num_providers = sizeof(providers) / sizeof(providers[0]); + errno_t ret; + int i; + int j; + + tmp_ctx = talloc_new(NULL); + if (tmp_ctx == NULL) { + return ENOMEM; + } + + ret = check_and_get_component_from_path(tmp_ctx, ctx->rctx->cdb, + sbus_req->path, &type, &name); + if (ret != EOK) { + DEBUG(SSSDBG_OP_FAILURE, "Unknown object [%d]: %s\n", + ret, sss_strerror(ret)); + goto done; + } + + if (type != COMPONENT_BACKEND) { + ret = EINVAL; + goto done; + } + + confdb_path = talloc_asprintf(tmp_ctx, CONFDB_DOMAIN_PATH_TMPL, name); + if (confdb_path == NULL) { + ret = ENOMEM; + goto done; + } + + out = talloc_zero_array(tmp_ctx, const char *, num_providers + 1); + if (out == NULL) { + ret = ENOMEM; + goto done; + } + + 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) { + goto done; + } + + if (value == NULL) { + continue; + } + + out[j] = talloc_asprintf(out, "%s=%s", providers[i], value); + if (out[j] == NULL) { + ret = ENOMEM; + goto done; + } + + j++; + } + + *_out = talloc_steal(mem_ctx, out); + +done: + talloc_free(tmp_ctx); + + return ret; +} diff --git a/src/responder/ifp/ifp_components.h b/src/responder/ifp/ifp_components.h new file mode 100644 index 0000000..50e8c44 --- /dev/null +++ b/src/responder/ifp/ifp_components.h @@ -0,0 +1,100 @@ +/* + 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/ifp_iface_async.h" +#include "responder/ifp/ifp_private.h" + +/* org.freedesktop.sssd.infopipe */ + +errno_t +ifp_list_components(TALLOC_CTX *mem_ctx, + struct sbus_request *sbus_req, + struct ifp_ctx *ctx, + const char ***_paths); + +errno_t +ifp_list_responders(TALLOC_CTX *mem_ctx, + struct sbus_request *sbus_req, + struct ifp_ctx *ctx, + const char ***_paths); +errno_t +ifp_list_backends(TALLOC_CTX *mem_ctx, + struct sbus_request *sbus_req, + struct ifp_ctx *ctx, + const char ***_paths); + +errno_t +ifp_find_monitor(TALLOC_CTX *mem_ctx, + struct sbus_request *sbus_req, + struct ifp_ctx *ctx, + const char **_path); + +errno_t +ifp_find_responder_by_name(TALLOC_CTX *mem_ctx, + struct sbus_request *sbus_req, + struct ifp_ctx *ctx, + const char *name, + const char **_path); + +errno_t +ifp_find_backend_by_name(TALLOC_CTX *mem_ctx, + struct sbus_request *sbus_req, + struct ifp_ctx *ctx, + const char *name, + const char **_path); + +/* org.freedesktop.sssd.infopipe.Components */ + +errno_t +ifp_component_get_name(TALLOC_CTX *mem_ctx, + struct sbus_request *sbus_req, + struct ifp_ctx *ctx, + const char **_out); + +errno_t +ifp_component_get_debug_level(TALLOC_CTX *mem_ctx, + struct sbus_request *sbus_req, + struct ifp_ctx *ctx, + uint32_t *_out); + +errno_t +ifp_component_get_enabled(TALLOC_CTX *mem_ctx, + struct sbus_request *sbus_req, + struct ifp_ctx *ctx, + bool *_out); + +errno_t +ifp_component_get_type(TALLOC_CTX *mem_ctx, + struct sbus_request *sbus_req, + struct ifp_ctx *ctx, + const char **_out); + +/* org.freedesktop.sssd.infopipe.Components.Backends */ + +errno_t +ifp_backend_get_providers(TALLOC_CTX *mem_ctx, + struct sbus_request *sbus_req, + struct ifp_ctx *ctx, + const char ***_out); + +#endif /* _IFP_COMPONENTS_H_ */ diff --git a/src/responder/ifp/ifp_domains.c b/src/responder/ifp/ifp_domains.c new file mode 100644 index 0000000..16d80e6 --- /dev/null +++ b/src/responder/ifp/ifp_domains.c @@ -0,0 +1,1022 @@ +/* + Authors: + Jakub Hrozek <jhrozek@redhat.com> + 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 <talloc.h> +#include <tevent.h> +#include <string.h> + +#include "db/sysdb.h" +#include "util/util.h" +#include "confdb/confdb.h" +#include "responder/common/responder.h" +#include "responder/ifp/ifp_domains.h" +#include "responder/ifp/ifp_iface/ifp_iface_async.h" +#include "sss_iface/sss_iface_async.h" + +#define RETURN_DOM_PROP(dbus_req, ctx, out, property) ({ \ + struct sss_domain_info *__dom; \ + errno_t __ret; \ + \ + __dom = get_domain_info_from_req((dbus_req), (ctx)); \ + if (__dom == NULL) { \ + __ret = ERR_DOMAIN_NOT_FOUND; \ + } else { \ + *(out) = __dom->property; \ + __ret = EOK; \ + } \ + __ret; \ +}) + + +struct ifp_list_domains_state { + struct ifp_ctx *ifp_ctx; + const char **paths; +}; + +static void ifp_list_domains_done(struct tevent_req *subreq); + +struct tevent_req * +ifp_list_domains_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct sbus_request *sbus_req, + struct ifp_ctx *ifp_ctx) +{ + struct ifp_list_domains_state *state; + struct tevent_req *subreq; + struct tevent_req *req; + errno_t ret; + + req = tevent_req_create(mem_ctx, &state, struct ifp_list_domains_state); + if (req == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "Unable to create tevent request!\n"); + return NULL; + } + + state->ifp_ctx = ifp_ctx; + + subreq = sss_dp_get_domains_send(state, ifp_ctx->rctx, false, NULL); + if (subreq == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "Unable to create subrequest!\n"); + ret = ENOMEM; + goto done; + } + + tevent_req_set_callback(subreq, ifp_list_domains_done, req); + + ret = EAGAIN; + +done: + if (ret != EAGAIN) { + tevent_req_error(req, ret); + tevent_req_post(req, ev); + } + + return req; +} + +static void ifp_list_domains_done(struct tevent_req *subreq) +{ + struct ifp_list_domains_state *state; + struct sss_domain_info *dom; + struct tevent_req *req; + size_t num_domains; + size_t pi; + errno_t ret; + + req = tevent_req_callback_data(subreq, struct tevent_req); + state = tevent_req_data(req, struct ifp_list_domains_state); + + ret = sss_dp_get_domains_recv(subreq); + talloc_zfree(subreq); + if (ret != EOK) { + DEBUG(SSSDBG_CRIT_FAILURE, "Failed to refresh domain objects\n"); + tevent_req_error(req, ret); + return; + } + + ret = sysdb_master_domain_update(state->ifp_ctx->rctx->domains); + if (ret != EOK) { + DEBUG(SSSDBG_CRIT_FAILURE, "Failed to refresh subdomain list\n"); + tevent_req_error(req, ret); + return; + } + + num_domains = 0; + for (dom = state->ifp_ctx->rctx->domains; + dom != NULL; + dom = get_next_domain(dom, SSS_GND_DESCEND)) { + num_domains++; + } + + state->paths = talloc_zero_array(state, const char *, num_domains + 1); + if (state->paths == NULL) { + tevent_req_error(req, ENOMEM); + return; + } + + pi = 0; + for (dom = state->ifp_ctx->rctx->domains; + dom != NULL; + dom = get_next_domain(dom, SSS_GND_DESCEND)) { + state->paths[pi] = sbus_opath_compose(state->paths, IFP_PATH_DOMAINS, dom->name); + if (state->paths[pi] == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "Could not create path for dom %s\n", + dom->name); + tevent_req_error(req, ENOMEM); + return; + } + pi++; + } + + tevent_req_done(req); + return; +} + +errno_t ifp_list_domains_recv(TALLOC_CTX *mem_ctx, + struct tevent_req *req, + const char ***_paths) +{ + struct ifp_list_domains_state *state; + state = tevent_req_data(req, struct ifp_list_domains_state); + + TEVENT_REQ_RETURN_ON_ERROR(req); + + *_paths = talloc_steal(mem_ctx, state->paths); + + return EOK; +} + +struct ifp_find_domain_by_name_state { + struct ifp_ctx *ifp_ctx; + const char *name; + const char *path; +}; + +static void ifp_find_domain_by_name_done(struct tevent_req *subreq); + +struct tevent_req * +ifp_find_domain_by_name_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct sbus_request *sbus_req, + struct ifp_ctx *ifp_ctx, + const char *name) +{ + struct ifp_find_domain_by_name_state *state; + struct tevent_req *subreq; + struct tevent_req *req; + errno_t ret; + + req = tevent_req_create(mem_ctx, &state, struct ifp_find_domain_by_name_state); + if (req == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "Unable to create tevent request!\n"); + return NULL; + } + + state->ifp_ctx = ifp_ctx; + state->name = name; + + subreq = sss_dp_get_domains_send(state, ifp_ctx->rctx, false, NULL); + if (subreq == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "Unable to create subrequest!\n"); + ret = ENOMEM; + goto done; + } + + tevent_req_set_callback(subreq, ifp_find_domain_by_name_done, req); + + ret = EAGAIN; + +done: + if (ret != EAGAIN) { + tevent_req_error(req, ret); + tevent_req_post(req, ev); + } + + return req; +} + +static void ifp_find_domain_by_name_done(struct tevent_req *subreq) +{ + struct ifp_find_domain_by_name_state *state; + struct sss_domain_info *iter; + struct tevent_req *req; + errno_t ret; + + req = tevent_req_callback_data(subreq, struct tevent_req); + state = tevent_req_data(req, struct ifp_find_domain_by_name_state); + + ret = sss_dp_get_domains_recv(subreq); + talloc_zfree(subreq); + if (ret != EOK) { + DEBUG(SSSDBG_CRIT_FAILURE, "Failed to refresh domain objects\n"); + tevent_req_error(req, ret); + return; + } + + ret = sysdb_master_domain_update(state->ifp_ctx->rctx->domains); + if (ret != EOK) { + DEBUG(SSSDBG_CRIT_FAILURE, "Failed to refresh subdomain list\n"); + tevent_req_error(req, ret); + return; + } + + /* Reply with the domain that was asked for */ + for (iter = state->ifp_ctx->rctx->domains; + iter != NULL; + iter = get_next_domain(iter, SSS_GND_DESCEND)) { + if (strcasecmp(iter->name, state->name) == 0) { + break; + } + } + + if (iter == NULL) { + DEBUG(SSSDBG_MINOR_FAILURE, "Domain not found: %s\n", state->name); + tevent_req_error(req, ERR_DOMAIN_NOT_FOUND); + return; + } + + state->path = sbus_opath_compose(state, IFP_PATH_DOMAINS, iter->name); + if (state->path == NULL) { + DEBUG(SSSDBG_MINOR_FAILURE, + "Could not create path for domain %s, skipping\n", iter->name); + tevent_req_error(req, ENOMEM); + return; + } + + tevent_req_done(req); + return; +} + +errno_t +ifp_find_domain_by_name_recv(TALLOC_CTX *mem_ctx, + struct tevent_req *req, + const char **_path) +{ + struct ifp_find_domain_by_name_state *state; + state = tevent_req_data(req, struct ifp_find_domain_by_name_state); + + TEVENT_REQ_RETURN_ON_ERROR(req); + + *_path = talloc_steal(mem_ctx, state->path); + + return EOK; +} + +static struct sss_domain_info * +get_domain_info_from_req(struct sbus_request *dbus_req, + struct ifp_ctx *ctx) +{ + struct sss_domain_info *domains = NULL; + struct sss_domain_info *iter = NULL; + char *name = NULL; + + name = sbus_opath_object_name(NULL, dbus_req->path, IFP_PATH_DOMAINS); + if (name == NULL) { + return NULL; + } + + DEBUG(SSSDBG_TRACE_INTERNAL, "Looking for domain %s\n", name); + + domains = ctx->rctx->domains; + for (iter = domains; iter != NULL; + iter = get_next_domain(iter, SSS_GND_DESCEND)) { + if (strcasecmp(iter->name, name) == 0) { + break; + } + } + + talloc_free(name); + return iter; +} + +static errno_t +get_server_list(TALLOC_CTX *mem_ctx, + struct sbus_request *dbus_req, + struct ifp_ctx *ctx, + const char ***_out, + bool backup) +{ + TALLOC_CTX *tmp_ctx; + static const char *srv[] = {"_srv_", NULL}; + struct sss_domain_info *dom = NULL; + char *conf_path = NULL; + const char *option = NULL; + const char **out = NULL; + char **servers = NULL; + int num_servers; + errno_t ret; + int i; + + tmp_ctx = talloc_new(NULL); + if (tmp_ctx == NULL) { + DEBUG(SSSDBG_FATAL_FAILURE, "Out of memory!\n"); + return ENOMEM; + } + + dom = get_domain_info_from_req(dbus_req, ctx); + if (dom == NULL) { + return ERR_DOMAIN_NOT_FOUND; + } + + if (dom->parent != NULL) { + /* subdomains are not present in configuration */ + ret = ENOENT; + goto done; + } + + conf_path = talloc_asprintf(tmp_ctx, CONFDB_DOMAIN_PATH_TMPL, dom->name); + if (conf_path == NULL) { + ret = ENOMEM; + goto done; + } + + /* TODO: replace hardcoded values with option names from the provider */ + if (strcasecmp(dom->provider, "ldap") == 0) { + option = backup == false ? "ldap_uri" : "ldap_backup_uri"; + } else if (strcasecmp(dom->provider, "ipa") == 0) { + option = backup == false ? "ipa_server" : "ipa_backup_server"; + } else if (strcasecmp(dom->provider, "ad") == 0) { + option = backup == false ? "ad_server" : "ad_backup_server"; + } else { + ret = EINVAL; + goto done; + } + + ret = confdb_get_string_as_list(ctx->rctx->cdb, tmp_ctx, conf_path, + option, &servers); + if (ret != EOK) { + goto done; + } + + for (num_servers = 0; servers[num_servers] != NULL; num_servers++); + + if (num_servers == 0) { + ret = ENOENT; + goto done; + } + + out = talloc_zero_array(mem_ctx, const char *, num_servers + 1); + if (out == NULL) { + ret = ENOMEM; + goto done; + } + + for (i = 0; i < num_servers; i++) { + out[i] = talloc_steal(out, servers[i]); + } + + *_out = out; + + ret = EOK; + +done: + talloc_free(tmp_ctx); + + if (ret == ENOENT) { + *_out = srv; + } + + return ret; +} + +errno_t +ifp_dom_get_name(TALLOC_CTX *mem_ctx, + struct sbus_request *sbus_req, + struct ifp_ctx *ctx, + const char **_out) +{ + return RETURN_DOM_PROP(sbus_req, ctx, _out, name); +} + +errno_t +ifp_dom_get_provider(TALLOC_CTX *mem_ctx, + struct sbus_request *sbus_req, + struct ifp_ctx *ctx, + const char **_out) +{ + return RETURN_DOM_PROP(sbus_req, ctx, _out, provider); +} + +errno_t +ifp_dom_get_primary_servers(TALLOC_CTX *mem_ctx, + struct sbus_request *sbus_req, + struct ifp_ctx *ctx, + const char ***_out) +{ + return get_server_list(mem_ctx, sbus_req, ctx, _out, false); +} + +errno_t +ifp_dom_get_backup_servers(TALLOC_CTX *mem_ctx, + struct sbus_request *sbus_req, + struct ifp_ctx *ctx, + const char ***_out) +{ + return get_server_list(mem_ctx, sbus_req, ctx, _out, true); +} + +errno_t +ifp_dom_get_min_id(TALLOC_CTX *mem_ctx, + struct sbus_request *sbus_req, + struct ifp_ctx *ctx, + uint32_t *_out) +{ + return RETURN_DOM_PROP(sbus_req, ctx, _out, id_min); +} + +errno_t +ifp_dom_get_max_id(TALLOC_CTX *mem_ctx, + struct sbus_request *sbus_req, + struct ifp_ctx *ctx, + uint32_t *_out) +{ + return RETURN_DOM_PROP(sbus_req, ctx, _out, id_max); +} + +errno_t +ifp_dom_get_realm(TALLOC_CTX *mem_ctx, + struct sbus_request *sbus_req, + struct ifp_ctx *ctx, + const char **_out) +{ + return RETURN_DOM_PROP(sbus_req, ctx, _out, realm); +} + +errno_t +ifp_dom_get_forest(TALLOC_CTX *mem_ctx, + struct sbus_request *sbus_req, + struct ifp_ctx *ctx, + const char **_out) +{ + return RETURN_DOM_PROP(sbus_req, ctx, _out, forest); +} + +errno_t +ifp_dom_get_login_format(TALLOC_CTX *mem_ctx, + struct sbus_request *sbus_req, + struct ifp_ctx *ctx, + const char **_out) +{ + return RETURN_DOM_PROP(sbus_req, ctx, _out, names->re_pattern); +} + +errno_t +ifp_dom_get_fqdn_format(TALLOC_CTX *mem_ctx, + struct sbus_request *sbus_req, + struct ifp_ctx *ctx, + const char **_out) +{ + return RETURN_DOM_PROP(sbus_req, ctx, _out, names->fq_fmt); +} + +errno_t +ifp_dom_get_enumerable(TALLOC_CTX *mem_ctx, + struct sbus_request *sbus_req, + struct ifp_ctx *ctx, + bool *_out) +{ + return RETURN_DOM_PROP(sbus_req, ctx, _out, enumerate); +} + +errno_t +ifp_dom_get_use_fqdn(TALLOC_CTX *mem_ctx, + struct sbus_request *sbus_req, + struct ifp_ctx *ctx, + bool *_out) +{ + return RETURN_DOM_PROP(sbus_req, ctx, _out, fqnames); +} + +errno_t +ifp_dom_get_subdomain(TALLOC_CTX *mem_ctx, + struct sbus_request *sbus_req, + struct ifp_ctx *ctx, + bool *_out) +{ + struct sss_domain_info *dom; + + dom = get_domain_info_from_req(sbus_req, ctx); + if (dom == NULL) { + return ERR_DOMAIN_NOT_FOUND; + } + + *_out = dom->parent != NULL ? true : false; + + return EOK; +} + +errno_t +ifp_dom_get_parent_domain(TALLOC_CTX *mem_ctx, + struct sbus_request *sbus_req, + struct ifp_ctx *ctx, + const char **_out) +{ + struct sss_domain_info *dom; + const char *path; + + dom = get_domain_info_from_req(sbus_req, ctx); + if (dom == NULL) { + return ERR_DOMAIN_NOT_FOUND; + } + + if (dom->parent == NULL) { + *_out = "/"; + return EOK; + } + + path = sbus_opath_compose(mem_ctx, IFP_PATH_DOMAINS, dom->parent->name); + if (path == NULL) { + return ENOMEM; + } + + *_out = path; + + return EOK; +} + +struct ifp_domains_domain_is_online_state { + bool is_online; +}; + +static void ifp_domains_domain_is_online_done(struct tevent_req *subreq); + +struct tevent_req * +ifp_domains_domain_is_online_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct sbus_request *sbus_req, + struct ifp_ctx *ifp_ctx) +{ + struct ifp_domains_domain_is_online_state *state; + struct sss_domain_info *dom; + struct tevent_req *subreq; + struct tevent_req *req; + struct be_conn *be_conn; + errno_t ret; + + req = tevent_req_create(mem_ctx, &state, + struct ifp_domains_domain_is_online_state); + if (req == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "Unable to create tevent request!\n"); + return NULL; + } + + dom = get_domain_info_from_req(sbus_req, ifp_ctx); + if (dom == NULL) { + ret = ERR_DOMAIN_NOT_FOUND; + goto done; + } + + ret = sss_dp_get_domain_conn(ifp_ctx->rctx, dom->conn_name, &be_conn); + if (ret != EOK) { + DEBUG(SSSDBG_CRIT_FAILURE, "BUG: The Data Provider connection for " + "%s is not available!\n", dom->name); + goto done; + } + + subreq = sbus_call_dp_backend_IsOnline_send(state, be_conn->conn, + be_conn->bus_name, SSS_BUS_PATH, dom->name); + if (subreq == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "Unable to create subrequest!\n"); + ret = ENOMEM; + goto done; + } + + tevent_req_set_callback(subreq, ifp_domains_domain_is_online_done, req); + + ret = EAGAIN; + +done: + if (ret != EAGAIN) { + tevent_req_error(req, ret); + tevent_req_post(req, ev); + } + + return req; +} + +static void ifp_domains_domain_is_online_done(struct tevent_req *subreq) +{ + struct ifp_domains_domain_is_online_state *state; + struct tevent_req *req; + errno_t ret; + + req = tevent_req_callback_data(subreq, struct tevent_req); + state = tevent_req_data(req, struct ifp_domains_domain_is_online_state); + + ret = sbus_call_dp_backend_IsOnline_recv(subreq, &state->is_online); + talloc_zfree(subreq); + if (ret != EOK) { + tevent_req_error(req, ret); + return; + } + + tevent_req_done(req); + return; +} + +errno_t +ifp_domains_domain_is_online_recv(TALLOC_CTX *mem_ctx, + struct tevent_req *req, + bool *_is_online) +{ + struct ifp_domains_domain_is_online_state *state; + state = tevent_req_data(req, struct ifp_domains_domain_is_online_state); + + TEVENT_REQ_RETURN_ON_ERROR(req); + + *_is_online = state->is_online; + + return EOK; +} + +struct ifp_domains_domain_list_services_state { + const char **services; +}; + +static void ifp_domains_domain_list_services_done(struct tevent_req *subreq); + +struct tevent_req * +ifp_domains_domain_list_services_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct sbus_request *sbus_req, + struct ifp_ctx *ifp_ctx) +{ + struct ifp_domains_domain_list_services_state *state; + struct sss_domain_info *dom; + struct tevent_req *subreq; + struct tevent_req *req; + struct be_conn *be_conn; + errno_t ret; + + req = tevent_req_create(mem_ctx, &state, + struct ifp_domains_domain_list_services_state); + if (req == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "Unable to create tevent request!\n"); + return NULL; + } + + dom = get_domain_info_from_req(sbus_req, ifp_ctx); + if (dom == NULL) { + ret = ERR_DOMAIN_NOT_FOUND; + goto done; + } + + ret = sss_dp_get_domain_conn(ifp_ctx->rctx, dom->conn_name, &be_conn); + if (ret != EOK) { + DEBUG(SSSDBG_CRIT_FAILURE, "BUG: The Data Provider connection for " + "%s is not available!\n", dom->name); + goto done; + } + + subreq = sbus_call_dp_failover_ListServices_send(state, be_conn->conn, + be_conn->bus_name, SSS_BUS_PATH, dom->name); + if (subreq == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "Unable to create subrequest!\n"); + ret = ENOMEM; + goto done; + } + + tevent_req_set_callback(subreq, ifp_domains_domain_list_services_done, req); + + ret = EAGAIN; + +done: + if (ret != EAGAIN) { + tevent_req_error(req, ret); + tevent_req_post(req, ev); + } + + return req; +} + +static void ifp_domains_domain_list_services_done(struct tevent_req *subreq) +{ + struct ifp_domains_domain_list_services_state *state; + struct tevent_req *req; + errno_t ret; + + req = tevent_req_callback_data(subreq, struct tevent_req); + state = tevent_req_data(req, struct ifp_domains_domain_list_services_state); + + ret = sbus_call_dp_failover_ListServices_recv(state, subreq, &state->services); + talloc_zfree(subreq); + if (ret != EOK) { + tevent_req_error(req, ret); + return; + } + + tevent_req_done(req); + return; +} + +errno_t +ifp_domains_domain_list_services_recv(TALLOC_CTX *mem_ctx, + struct tevent_req *req, + const char ***_services) +{ + struct ifp_domains_domain_list_services_state *state; + state = tevent_req_data(req, struct ifp_domains_domain_list_services_state); + + TEVENT_REQ_RETURN_ON_ERROR(req); + + *_services = talloc_steal(mem_ctx, state->services); + + return EOK; +} + +struct ifp_domains_domain_active_server_state { + const char *server; +}; + +static void ifp_domains_domain_active_server_done(struct tevent_req *subreq); + +struct tevent_req * +ifp_domains_domain_active_server_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct sbus_request *sbus_req, + struct ifp_ctx *ifp_ctx, + const char *service) +{ + struct ifp_domains_domain_active_server_state *state; + struct sss_domain_info *dom; + struct tevent_req *subreq; + struct tevent_req *req; + struct be_conn *be_conn; + errno_t ret; + + req = tevent_req_create(mem_ctx, &state, + struct ifp_domains_domain_active_server_state); + if (req == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "Unable to create tevent request!\n"); + return NULL; + } + + dom = get_domain_info_from_req(sbus_req, ifp_ctx); + if (dom == NULL) { + ret = ERR_DOMAIN_NOT_FOUND; + goto done; + } + + ret = sss_dp_get_domain_conn(ifp_ctx->rctx, dom->conn_name, &be_conn); + if (ret != EOK) { + DEBUG(SSSDBG_CRIT_FAILURE, "BUG: The Data Provider connection for " + "%s is not available!\n", dom->name); + goto done; + } + + subreq = sbus_call_dp_failover_ActiveServer_send(state, be_conn->conn, + be_conn->bus_name, SSS_BUS_PATH, service); + if (subreq == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "Unable to create subrequest!\n"); + ret = ENOMEM; + goto done; + } + + tevent_req_set_callback(subreq, ifp_domains_domain_active_server_done, req); + + ret = EAGAIN; + +done: +if (ret != EAGAIN) { + tevent_req_error(req, ret); + tevent_req_post(req, ev); +} + + return req; +} + +static void ifp_domains_domain_active_server_done(struct tevent_req *subreq) +{ + struct ifp_domains_domain_active_server_state *state; + struct tevent_req *req; + errno_t ret; + + req = tevent_req_callback_data(subreq, struct tevent_req); + state = tevent_req_data(req, struct ifp_domains_domain_active_server_state); + + ret = sbus_call_dp_failover_ActiveServer_recv(state, subreq, &state->server); + talloc_zfree(subreq); + if (ret != EOK) { + tevent_req_error(req, ret); + return; + } + + tevent_req_done(req); + return; +} + +errno_t +ifp_domains_domain_active_server_recv(TALLOC_CTX *mem_ctx, + struct tevent_req *req, + const char **_server) +{ + struct ifp_domains_domain_active_server_state *state; + state = tevent_req_data(req, struct ifp_domains_domain_active_server_state); + + TEVENT_REQ_RETURN_ON_ERROR(req); + + *_server = talloc_steal(mem_ctx, state->server); + + return EOK; +} + +struct ifp_domains_domain_list_servers_state { + const char **servers; +}; + +static void ifp_domains_domain_list_servers_done(struct tevent_req *subreq); + +struct tevent_req * +ifp_domains_domain_list_servers_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct sbus_request *sbus_req, + struct ifp_ctx *ifp_ctx, + const char *service) +{ + struct ifp_domains_domain_list_servers_state *state; + struct sss_domain_info *dom; + struct tevent_req *subreq; + struct tevent_req *req; + struct be_conn *be_conn; + errno_t ret; + + req = tevent_req_create(mem_ctx, &state, + struct ifp_domains_domain_list_servers_state); + if (req == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "Unable to create tevent request!\n"); + return NULL; + } + + dom = get_domain_info_from_req(sbus_req, ifp_ctx); + if (dom == NULL) { + ret = ERR_DOMAIN_NOT_FOUND; + goto done; + } + + ret = sss_dp_get_domain_conn(ifp_ctx->rctx, dom->conn_name, &be_conn); + if (ret != EOK) { + DEBUG(SSSDBG_CRIT_FAILURE, "BUG: The Data Provider connection for " + "%s is not available!\n", dom->name); + goto done; + } + + subreq = sbus_call_dp_failover_ListServers_send(state, be_conn->conn, + be_conn->bus_name, SSS_BUS_PATH, service); + if (subreq == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "Unable to create subrequest!\n"); + ret = ENOMEM; + goto done; + } + + tevent_req_set_callback(subreq, ifp_domains_domain_list_servers_done, req); + + ret = EAGAIN; + +done: + if (ret != EAGAIN) { + tevent_req_error(req, ret); + tevent_req_post(req, ev); + } + + return req; +} + +static void ifp_domains_domain_list_servers_done(struct tevent_req *subreq) +{ + struct ifp_domains_domain_list_servers_state *state; + struct tevent_req *req; + errno_t ret; + + req = tevent_req_callback_data(subreq, struct tevent_req); + state = tevent_req_data(req, struct ifp_domains_domain_list_servers_state); + + ret = sbus_call_dp_failover_ListServers_recv(state, subreq, &state->servers); + talloc_zfree(subreq); + if (ret != EOK) { + tevent_req_error(req, ret); + return; + } + + tevent_req_done(req); + return; +} + +errno_t +ifp_domains_domain_list_servers_recv(TALLOC_CTX *mem_ctx, + struct tevent_req *req, + const char ***_servers) +{ + struct ifp_domains_domain_list_servers_state *state; + state = tevent_req_data(req, struct ifp_domains_domain_list_servers_state); + + TEVENT_REQ_RETURN_ON_ERROR(req); + + *_servers = talloc_steal(mem_ctx, state->servers); + + return EOK; +} + +struct ifp_domains_domain_refresh_access_rules_state { + int dummy; +}; + +static void ifp_domains_domain_refresh_access_rules_done(struct tevent_req *subreq); + +struct tevent_req * +ifp_domains_domain_refresh_access_rules_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct sbus_request *sbus_req, + struct ifp_ctx *ifp_ctx) +{ + struct ifp_domains_domain_refresh_access_rules_state *state; + struct sss_domain_info *dom; + struct tevent_req *subreq; + struct tevent_req *req; + struct be_conn *be_conn; + errno_t ret; + + req = tevent_req_create(mem_ctx, &state, + struct ifp_domains_domain_refresh_access_rules_state); + if (req == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "Unable to create tevent request!\n"); + return NULL; + } + + dom = get_domain_info_from_req(sbus_req, ifp_ctx); + if (dom == NULL) { + ret = ERR_DOMAIN_NOT_FOUND; + goto done; + } + + ret = sss_dp_get_domain_conn(ifp_ctx->rctx, dom->conn_name, &be_conn); + if (ret != EOK) { + DEBUG(SSSDBG_CRIT_FAILURE, "BUG: The Data Provider connection for " + "%s is not available!\n", dom->name); + goto done; + } + + subreq = sbus_call_dp_access_RefreshRules_send(state, be_conn->conn, + be_conn->bus_name, SSS_BUS_PATH); + if (subreq == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "Unable to create subrequest!\n"); + ret = ENOMEM; + goto done; + } + + tevent_req_set_callback(subreq, ifp_domains_domain_refresh_access_rules_done, req); + + ret = EAGAIN; + +done: +if (ret != EAGAIN) { + tevent_req_error(req, ret); + tevent_req_post(req, ev); +} + + return req; +} + +static void ifp_domains_domain_refresh_access_rules_done(struct tevent_req *subreq) +{ + struct tevent_req *req; + errno_t ret; + + req = tevent_req_callback_data(subreq, struct tevent_req); + + ret = sbus_call_dp_access_RefreshRules_recv(subreq); + talloc_zfree(subreq); + if (ret != EOK) { + tevent_req_error(req, ret); + return; + } + + tevent_req_done(req); + return; +} + +errno_t +ifp_domains_domain_refresh_access_rules_recv(TALLOC_CTX *mem_ctx, + struct tevent_req *req) +{ + TEVENT_REQ_RETURN_ON_ERROR(req); + + return EOK; +} diff --git a/src/responder/ifp/ifp_domains.h b/src/responder/ifp/ifp_domains.h new file mode 100644 index 0000000..1c84163 --- /dev/null +++ b/src/responder/ifp/ifp_domains.h @@ -0,0 +1,193 @@ +/* + Authors: + Jakub Hrozek <jhrozek@redhat.com> + 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_DOMAINS_H_ +#define IFP_DOMAINS_H_ + +#include "responder/ifp/ifp_private.h" + +/* org.freedesktop.sssd.infopipe */ + +struct tevent_req * +ifp_list_domains_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct sbus_request *sbus_req, + struct ifp_ctx *ifp_ctx); + +errno_t ifp_list_domains_recv(TALLOC_CTX *mem_ctx, + struct tevent_req *req, + const char ***_paths); + +struct tevent_req * +ifp_find_domain_by_name_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct sbus_request *sbus_req, + struct ifp_ctx *ifp_ctx, + const char *name); + +errno_t +ifp_find_domain_by_name_recv(TALLOC_CTX *mem_ctx, + struct tevent_req *req, + const char **_path); + +/* org.freedesktop.sssd.infopipe.Domains */ + +errno_t +ifp_dom_get_name(TALLOC_CTX *mem_ctx, + struct sbus_request *sbus_req, + struct ifp_ctx *ctx, + const char **_out); + +errno_t +ifp_dom_get_provider(TALLOC_CTX *mem_ctx, + struct sbus_request *sbus_req, + struct ifp_ctx *ctx, + const char **_out); + +errno_t +ifp_dom_get_primary_servers(TALLOC_CTX *mem_ctx, + struct sbus_request *sbus_req, + struct ifp_ctx *ctx, + const char ***_out); + +errno_t +ifp_dom_get_backup_servers(TALLOC_CTX *mem_ctx, + struct sbus_request *sbus_req, + struct ifp_ctx *ctx, + const char ***_out); + +errno_t +ifp_dom_get_min_id(TALLOC_CTX *mem_ctx, + struct sbus_request *sbus_req, + struct ifp_ctx *ctx, + uint32_t *_out); + +errno_t +ifp_dom_get_max_id(TALLOC_CTX *mem_ctx, + struct sbus_request *sbus_req, + struct ifp_ctx *ctx, + uint32_t *_out); + +errno_t +ifp_dom_get_realm(TALLOC_CTX *mem_ctx, + struct sbus_request *sbus_req, + struct ifp_ctx *ctx, + const char **_out); + +errno_t +ifp_dom_get_forest(TALLOC_CTX *mem_ctx, + struct sbus_request *sbus_req, + struct ifp_ctx *ctx, + const char **_out); + +errno_t +ifp_dom_get_login_format(TALLOC_CTX *mem_ctx, + struct sbus_request *sbus_req, + struct ifp_ctx *ctx, + const char **_out); + +errno_t +ifp_dom_get_fqdn_format(TALLOC_CTX *mem_ctx, + struct sbus_request *sbus_req, + struct ifp_ctx *ctx, + const char **_out); + +errno_t +ifp_dom_get_enumerable(TALLOC_CTX *mem_ctx, + struct sbus_request *sbus_req, + struct ifp_ctx *ctx, + bool *_out); + +errno_t +ifp_dom_get_use_fqdn(TALLOC_CTX *mem_ctx, + struct sbus_request *sbus_req, + struct ifp_ctx *ctx, + bool *_out); + +errno_t +ifp_dom_get_subdomain(TALLOC_CTX *mem_ctx, + struct sbus_request *sbus_req, + struct ifp_ctx *ctx, + bool *_out); + +errno_t +ifp_dom_get_parent_domain(TALLOC_CTX *mem_ctx, + struct sbus_request *sbus_req, + struct ifp_ctx *ctx, + const char **_out); + +struct tevent_req * +ifp_domains_domain_is_online_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct sbus_request *sbus_req, + struct ifp_ctx *ifp_ctx); + +errno_t +ifp_domains_domain_is_online_recv(TALLOC_CTX *mem_ctx, + struct tevent_req *req, + bool *_is_online); + +struct tevent_req * +ifp_domains_domain_list_services_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct sbus_request *sbus_req, + struct ifp_ctx *ifp_ctx); + +errno_t +ifp_domains_domain_list_services_recv(TALLOC_CTX *mem_ctx, + struct tevent_req *req, + const char ***_services); + +struct tevent_req * +ifp_domains_domain_active_server_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct sbus_request *sbus_req, + struct ifp_ctx *ifp_ctx, + const char *service); + +errno_t +ifp_domains_domain_active_server_recv(TALLOC_CTX *mem_ctx, + struct tevent_req *req, + const char **_server); + +struct tevent_req * +ifp_domains_domain_list_servers_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct sbus_request *sbus_req, + struct ifp_ctx *ifp_ctx, + const char *service); + +errno_t +ifp_domains_domain_list_servers_recv(TALLOC_CTX *mem_ctx, + struct tevent_req *req, + const char ***_servers); + +struct tevent_req * +ifp_domains_domain_refresh_access_rules_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct sbus_request *sbus_req, + struct ifp_ctx *ifp_ctx); + +errno_t +ifp_domains_domain_refresh_access_rules_recv(TALLOC_CTX *mem_ctx, + struct tevent_req *req); + +#endif /* IFP_DOMAINS_H_ */ diff --git a/src/responder/ifp/ifp_groups.c b/src/responder/ifp/ifp_groups.c new file mode 100644 index 0000000..e65716d --- /dev/null +++ b/src/responder/ifp/ifp_groups.c @@ -0,0 +1,1169 @@ +/* + Authors: + Pavel Březina <pbrezina@redhat.com> + + Copyright (C) 2015 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 <talloc.h> +#include <tevent.h> + +#include "util/util.h" +#include "db/sysdb.h" +#include "util/strtonum.h" +#include "responder/common/responder.h" +#include "responder/common/cache_req/cache_req.h" +#include "responder/ifp/ifp_groups.h" +#include "responder/ifp/ifp_users.h" +#include "responder/ifp/ifp_cache.h" +#include "responder/ifp/ifp_iface/ifp_iface_async.h" + +char * ifp_groups_build_path_from_msg(TALLOC_CTX *mem_ctx, + struct sss_domain_info *domain, + struct ldb_message *msg) +{ + const char *key = NULL; + + switch (domain->type) { + case DOM_TYPE_APPLICATION: + key = ldb_msg_find_attr_as_string(msg, SYSDB_NAME, NULL); + break; + case DOM_TYPE_POSIX: + key = ldb_msg_find_attr_as_string(msg, SYSDB_GIDNUM, NULL); + break; + } + + + if (key == NULL) { + return NULL; + } + + return sbus_opath_compose(mem_ctx, IFP_PATH_GROUPS, domain->name, key); +} + +static errno_t ifp_groups_decompose_path(TALLOC_CTX *mem_ctx, + struct sss_domain_info *domains, + const char *path, + struct sss_domain_info **_domain, + char **_key) +{ + char **parts = NULL; + struct sss_domain_info *domain; + errno_t ret; + + ret = sbus_opath_decompose_expected(NULL, path, IFP_PATH_GROUPS, 2, &parts); + if (ret != EOK) { + return ret; + } + + domain = find_domain_by_name(domains, parts[0], false); + if (domain == NULL) { + ret = ERR_DOMAIN_NOT_FOUND; + goto done; + } + + *_domain = domain; + *_key = talloc_steal(mem_ctx, parts[1]); + +done: + talloc_free(parts); + return ret; +} + +static int ifp_groups_list_copy(struct ifp_list_ctx *list_ctx, + struct sss_domain_info *domain, + struct ldb_result *result) +{ + size_t copy_count, i; + errno_t ret; + + ret = ifp_list_ctx_remaining_capacity(list_ctx, result->count, ©_count); + if (ret != EOK) { + goto done; + } + + for (i = 0; i < copy_count; i++) { + list_ctx->paths[list_ctx->path_count + i] = \ + ifp_groups_build_path_from_msg(list_ctx->paths, domain, + result->msgs[i]); + if (list_ctx->paths[list_ctx->path_count + i] == NULL) { + ret = ENOMEM; + goto done; + } + } + + list_ctx->path_count += copy_count; + ret = EOK; + +done: + return ret; +} + +struct ifp_groups_find_by_name_state { + const char *path; +}; + +static void ifp_groups_find_by_name_done(struct tevent_req *subreq); + +struct tevent_req * +ifp_groups_find_by_name_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct sbus_request *sbus_req, + struct ifp_ctx *ctx, + const char *name) +{ + struct ifp_groups_find_by_name_state *state; + struct tevent_req *subreq; + struct tevent_req *req; + errno_t ret; + + req = tevent_req_create(mem_ctx, &state, + struct ifp_groups_find_by_name_state); + if (req == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "Unable to create tevent request!\n"); + return NULL; + } + + subreq = cache_req_group_by_name_send(state, ctx->rctx->ev, ctx->rctx, + ctx->rctx->ncache, 0, + CACHE_REQ_ANY_DOM, NULL, + name); + if (subreq == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "Unable to create subrequest!\n"); + ret = ENOMEM; + goto done; + } + + tevent_req_set_callback(subreq, ifp_groups_find_by_name_done, req); + + ret = EAGAIN; + +done: + if (ret != EAGAIN) { + tevent_req_error(req, ret); + tevent_req_post(req, ev); + } + + return req; +} + +static void ifp_groups_find_by_name_done(struct tevent_req *subreq) +{ + struct ifp_groups_find_by_name_state *state; + struct cache_req_result *result; + struct tevent_req *req; + errno_t ret; + + req = tevent_req_callback_data(subreq, struct tevent_req); + state = tevent_req_data(req, struct ifp_groups_find_by_name_state); + + ret = cache_req_group_by_name_recv(state, subreq, &result); + talloc_zfree(subreq); + if (ret != EOK) { + DEBUG(SSSDBG_MINOR_FAILURE, "Unable to find group [%d]: %s\n", + ret, sss_strerror(ret)); + tevent_req_error(req, ret); + return; + } + + state->path = ifp_groups_build_path_from_msg(state, result->domain, + result->msgs[0]); + if (state->path == NULL) { + tevent_req_error(req, ENOMEM); + return; + } + + tevent_req_done(req); + return; +} + +errno_t +ifp_groups_find_by_name_recv(TALLOC_CTX *mem_ctx, + struct tevent_req *req, + const char **_path) +{ + struct ifp_groups_find_by_name_state *state; + state = tevent_req_data(req, struct ifp_groups_find_by_name_state); + + TEVENT_REQ_RETURN_ON_ERROR(req); + + *_path = talloc_steal(mem_ctx, state->path); + + return EOK; +} + +struct ifp_groups_find_by_id_state { + const char *path; +}; + +static void ifp_groups_find_by_id_done(struct tevent_req *subreq); + +struct tevent_req * +ifp_groups_find_by_id_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct sbus_request *sbus_req, + struct ifp_ctx *ctx, + uint32_t id) +{ + struct ifp_groups_find_by_id_state *state; + struct tevent_req *subreq; + struct tevent_req *req; + errno_t ret; + + req = tevent_req_create(mem_ctx, &state, struct ifp_groups_find_by_id_state); + if (req == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "Unable to create tevent request!\n"); + return NULL; + } + + subreq = cache_req_group_by_id_send(state, ctx->rctx->ev, ctx->rctx, + ctx->rctx->ncache, 0, NULL, id); + if (subreq == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "Unable to create subrequest!\n"); + ret = ENOMEM; + goto done; + } + + tevent_req_set_callback(subreq, ifp_groups_find_by_id_done, req); + + ret = EAGAIN; + +done: + if (ret != EAGAIN) { + tevent_req_error(req, ret); + tevent_req_post(req, ev); + } + + return req; +} + +static void ifp_groups_find_by_id_done(struct tevent_req *subreq) +{ + struct ifp_groups_find_by_id_state *state; + struct cache_req_result *result; + struct tevent_req *req; + errno_t ret; + + req = tevent_req_callback_data(subreq, struct tevent_req); + state = tevent_req_data(req, struct ifp_groups_find_by_id_state); + + ret = cache_req_group_by_id_recv(state, subreq, &result); + talloc_zfree(subreq); + if (ret != EOK) { + DEBUG(SSSDBG_MINOR_FAILURE, "Unable to find group [%d]: %s\n", + ret, sss_strerror(ret)); + tevent_req_error(req, ret); + return; + } + + state->path = ifp_groups_build_path_from_msg(state, result->domain, + result->msgs[0]); + if (state->path == NULL) { + tevent_req_error(req, ENOMEM); + return; + } + + tevent_req_done(req); + return; +} + +errno_t +ifp_groups_find_by_id_recv(TALLOC_CTX *mem_ctx, + struct tevent_req *req, + const char **_path) +{ + struct ifp_groups_find_by_id_state *state; + state = tevent_req_data(req, struct ifp_groups_find_by_id_state); + + TEVENT_REQ_RETURN_ON_ERROR(req); + + *_path = talloc_steal(mem_ctx, state->path); + + return EOK; +} + +struct ifp_groups_list_by_name_state { + struct ifp_ctx *ifp_ctx; + struct ifp_list_ctx *list_ctx; +}; + +static errno_t ifp_groups_list_by_name_step(struct tevent_req *req); +static void ifp_groups_list_by_name_done(struct tevent_req *subreq); + +struct tevent_req * +ifp_groups_list_by_name_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct sbus_request *sbus_req, + struct ifp_ctx *ctx, + const char *filter, + uint32_t limit) +{ + struct ifp_groups_list_by_name_state *state; + struct tevent_req *req; + errno_t ret; + + req = tevent_req_create(mem_ctx, &state, struct ifp_groups_list_by_name_state); + if (req == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "Unable to create tevent request!\n"); + return NULL; + } + + state->ifp_ctx = ctx; + state->list_ctx = ifp_list_ctx_new(state, ctx, NULL, filter, limit); + if (state->list_ctx == NULL) { + ret = ENOMEM; + goto done; + } + + ret = ifp_groups_list_by_name_step(req); + +done: + if (ret == EOK) { + tevent_req_done(req); + tevent_req_post(req, ev); + } else if (ret != EAGAIN) { + tevent_req_error(req, ret); + tevent_req_post(req, ev); + } + + return req; +} + +static errno_t +ifp_groups_list_by_name_step(struct tevent_req *req) +{ + struct ifp_groups_list_by_name_state *state; + struct tevent_req *subreq; + + state = tevent_req_data(req, struct ifp_groups_list_by_name_state); + + if (state->list_ctx->dom == NULL) { + return EOK; + } + + subreq = cache_req_group_by_filter_send(state->list_ctx, + state->ifp_ctx->rctx->ev, + state->ifp_ctx->rctx, + CACHE_REQ_ANY_DOM, + state->list_ctx->dom->name, + state->list_ctx->filter); + if (subreq == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "Unable to create subrequest!\n"); + return ENOMEM; + } + + tevent_req_set_callback(subreq, ifp_groups_list_by_name_done, req); + + state->list_ctx->dom = get_next_domain(state->list_ctx->dom, + SSS_GND_DESCEND); + + return EAGAIN; +} + +static void ifp_groups_list_by_name_done(struct tevent_req *subreq) +{ + struct ifp_groups_list_by_name_state *state; + struct cache_req_result *result; + struct tevent_req *req; + errno_t ret; + + req = tevent_req_callback_data(subreq, struct tevent_req); + state = tevent_req_data(req, struct ifp_groups_list_by_name_state); + + ret = cache_req_group_by_name_recv(state, subreq, &result); + talloc_zfree(subreq); + if (ret == EOK) { + ret = ifp_groups_list_copy(state->list_ctx, result->domain, + result->ldb_result); + if (ret != EOK) { + DEBUG(SSSDBG_CRIT_FAILURE, "Failed to copy domain result\n"); + tevent_req_error(req, ret); + return; + } + } else if (ret != ENOENT) { + DEBUG(SSSDBG_MINOR_FAILURE, "Unable to list groups [%d]: %s\n", + ret, sss_strerror(ret)); + tevent_req_error(req, ret); + return; + } + + ret = ifp_groups_list_by_name_step(req); + if (ret == EOK) { + tevent_req_done(req); + } else if (ret != EAGAIN) { + tevent_req_error(req, ret); + } +} + +errno_t +ifp_groups_list_by_name_recv(TALLOC_CTX *mem_ctx, + struct tevent_req *req, + const char ***_paths) +{ + struct ifp_groups_list_by_name_state *state; + state = tevent_req_data(req, struct ifp_groups_list_by_name_state); + + TEVENT_REQ_RETURN_ON_ERROR(req); + + *_paths = talloc_steal(mem_ctx, state->list_ctx->paths); + + return EOK; +} + +struct ifp_groups_list_by_domain_and_name_state { + struct ifp_list_ctx *list_ctx; +}; + +static void ifp_groups_list_by_domain_and_name_done(struct tevent_req *subreq); + +struct tevent_req * +ifp_groups_list_by_domain_and_name_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct sbus_request *sbus_req, + struct ifp_ctx *ctx, + const char *domain, + const char *filter, + uint32_t limit) +{ + struct ifp_groups_list_by_domain_and_name_state *state; + struct tevent_req *subreq; + struct tevent_req *req; + errno_t ret; + + req = tevent_req_create(mem_ctx, &state, struct ifp_groups_list_by_domain_and_name_state); + if (req == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "Unable to create tevent request!\n"); + return NULL; + } + + state->list_ctx = ifp_list_ctx_new(state, ctx, NULL, filter, limit); + if (state->list_ctx == NULL) { + ret = ENOMEM; + goto done; + } + + subreq = cache_req_group_by_filter_send(state->list_ctx, ctx->rctx->ev, + ctx->rctx, CACHE_REQ_ANY_DOM, + domain, filter); + if (subreq == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "Unable to create subrequest!\n"); + ret = ENOMEM; + goto done; + } + + tevent_req_set_callback(subreq, ifp_groups_list_by_domain_and_name_done, req); + + ret = EAGAIN; + +done: + if (ret != EAGAIN) { + tevent_req_error(req, ret); + tevent_req_post(req, ev); + } + + return req; +} + +static void ifp_groups_list_by_domain_and_name_done(struct tevent_req *subreq) +{ + struct ifp_groups_list_by_domain_and_name_state *state; + struct cache_req_result *result; + struct tevent_req *req; + errno_t ret; + + req = tevent_req_callback_data(subreq, struct tevent_req); + state = tevent_req_data(req, struct ifp_groups_list_by_domain_and_name_state); + + ret = cache_req_group_by_filter_recv(state, subreq, &result); + talloc_zfree(subreq); + if (ret != EOK) { + tevent_req_error(req, ret); + return; + } + + ret = ifp_groups_list_copy(state->list_ctx, result->domain, + result->ldb_result); + if (ret != EOK) { + DEBUG(SSSDBG_CRIT_FAILURE, "Failed to copy domain result\n"); + tevent_req_error(req, ret); + return; + } + + tevent_req_done(req); + return; +} + +errno_t +ifp_groups_list_by_domain_and_name_recv(TALLOC_CTX *mem_ctx, + struct tevent_req *req, + const char ***_paths) +{ + struct ifp_groups_list_by_domain_and_name_state *state; + state = tevent_req_data(req, struct ifp_groups_list_by_domain_and_name_state); + + TEVENT_REQ_RETURN_ON_ERROR(req); + + *_paths = talloc_steal(mem_ctx, state->list_ctx->paths); + + return EOK; +} + +static errno_t +ifp_groups_get_from_cache(TALLOC_CTX *mem_ctx, + struct sss_domain_info *domain, + const char *key, + struct ldb_message **_group) +{ + struct ldb_result *group_res = NULL; + errno_t ret; + gid_t gid; + char *endptr; + + switch (domain->type) { + case DOM_TYPE_POSIX: + gid = strtouint32(key, &endptr, 10); + if ((errno != 0) || *endptr || (key == endptr)) { + ret = errno ? errno : EINVAL; + DEBUG(SSSDBG_CRIT_FAILURE, "Invalid GID value\n"); + return ret; + } + + ret = sysdb_getgrgid_with_views(NULL, domain, gid, &group_res); + if (ret == EOK && group_res->count == 0) { + *_group = NULL; + ret = ENOENT; + goto done; + } else if (ret != EOK) { + DEBUG(SSSDBG_CRIT_FAILURE, "Unable to lookup group %u@%s [%d]: %s\n", + gid, domain->name, ret, sss_strerror(ret)); + goto done; + } + break; + case DOM_TYPE_APPLICATION: + ret = sysdb_getgrnam_with_views(NULL, domain, key, &group_res); + if (ret == EOK && group_res->count == 0) { + *_group = NULL; + ret = ENOENT; + goto done; + } else if (ret != EOK) { + DEBUG(SSSDBG_CRIT_FAILURE, "Unable to lookup group %s@%s [%d]: %s\n", + key, domain->name, ret, sss_strerror(ret)); + goto done; + } + break; + } + + if (group_res->count > 1) { + DEBUG(SSSDBG_CRIT_FAILURE, "More groups matched by the single key\n"); + return EIO; + } + + *_group = talloc_steal(mem_ctx, group_res->msgs[0]); + + ret = EOK; + +done: + talloc_free(group_res); + + return ret; +} + +static errno_t +ifp_groups_group_get(TALLOC_CTX *mem_ctx, + struct sbus_request *sbus_req, + struct ifp_ctx *ctx, + struct sss_domain_info **_domain, + struct ldb_message **_group) +{ + struct sss_domain_info *domain; + char *key; + errno_t ret; + + ret = ifp_groups_decompose_path(NULL, ctx->rctx->domains, sbus_req->path, + &domain, &key); + if (ret != EOK) { + DEBUG(SSSDBG_CRIT_FAILURE, "Unable to decompose object path" + "[%s] [%d]: %s\n", sbus_req->path, ret, sss_strerror(ret)); + return ret; + } + + if (_group != NULL) { + ret = ifp_groups_get_from_cache(mem_ctx, domain, key, _group); + } + + talloc_free(key); + + if (ret == EOK || ret == ENOENT) { + if (_domain != NULL) { + *_domain = domain; + } + } else if (ret != EOK) { + DEBUG(SSSDBG_OP_FAILURE, "Unable to retrieve group from cache\n"); + } + + return ret; +} + +struct resolv_ghosts_state { + struct tevent_context *ev; + struct sbus_request *sbus_req; + struct ifp_ctx *ctx; + + struct sss_domain_info *domain; + const char **ghosts; + int index; +}; + +static void resolv_ghosts_group_done(struct tevent_req *subreq); +static errno_t resolv_ghosts_step(struct tevent_req *req); +static void resolv_ghosts_done(struct tevent_req *subreq); + +static struct tevent_req *resolv_ghosts_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct sbus_request *sbus_req, + struct ifp_ctx *ctx) +{ + struct resolv_ghosts_state *state; + struct sss_domain_info *domain; + struct tevent_req *req; + struct tevent_req *subreq; + struct ldb_message *group; + const char *name; + errno_t ret; + + req = tevent_req_create(mem_ctx, &state, struct resolv_ghosts_state); + if (req == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "tevent_req_create() failed\n"); + return NULL; + } + + state->ev = ev; + state->sbus_req = sbus_req; + state->ctx = ctx; + + ret = ifp_groups_group_get(state, sbus_req, ctx, &domain, &group); + if (ret != EOK) { + goto immediately; + } + + name = ldb_msg_find_attr_as_string(group, SYSDB_NAME, NULL); + if (name == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "Group name is empty!\n"); + ret = ERR_INTERNAL; + goto immediately; + } + + subreq = cache_req_group_by_name_send(state, ev, ctx->rctx, + ctx->rctx->ncache, 0, + CACHE_REQ_ANY_DOM, + domain->name, + name); + if (subreq == NULL) { + ret = ENOMEM; + goto immediately; + } + + tevent_req_set_callback(subreq, resolv_ghosts_group_done, req); + + return req; + +immediately: + if (ret == EOK) { + tevent_req_done(req); + } else { + tevent_req_error(req, ret); + } + tevent_req_post(req, ev); + + return req; +} + +static void resolv_ghosts_group_done(struct tevent_req *subreq) +{ + struct resolv_ghosts_state *state; + struct ldb_message *group = NULL; + struct ldb_message_element *el; + struct tevent_req *req; + errno_t ret; + + req = tevent_req_callback_data(subreq, struct tevent_req); + state = tevent_req_data(req, struct resolv_ghosts_state); + + ret = ifp_groups_group_get(state, state->sbus_req, state->ctx, + &state->domain, &group); + if (ret != EOK) { + goto done; + } + + el = ldb_msg_find_element(group, SYSDB_GHOST); + if (el == NULL || el->num_values == 0) { + ret = EOK; + goto done; + } + + state->ghosts = sss_ldb_el_to_string_list(state, el); + if (state->ghosts == NULL) { + ret = ENOMEM; + goto done; + } + + state->index = 0; + ret = resolv_ghosts_step(req); + +done: + if (ret == EOK) { + tevent_req_done(req); + } else if (ret != EAGAIN) { + tevent_req_error(req, ret); + } +} + +errno_t resolv_ghosts_step(struct tevent_req *req) +{ + struct resolv_ghosts_state *state; + struct tevent_req *subreq; + + state = tevent_req_data(req, struct resolv_ghosts_state); + + if (state->ghosts[state->index] == NULL) { + return EOK; + } + + subreq = cache_req_user_by_name_send(state, state->ev, state->ctx->rctx, + state->ctx->rctx->ncache, 0, + CACHE_REQ_ANY_DOM, + state->domain->name, + state->ghosts[state->index]); + if (subreq == NULL) { + return ENOMEM; + } + + tevent_req_set_callback(subreq, resolv_ghosts_done, req); + + state->index++; + + return EAGAIN; +} + +static void resolv_ghosts_done(struct tevent_req *subreq) +{ + struct resolv_ghosts_state *state = NULL; + struct tevent_req *req = NULL; + errno_t ret; + + req = tevent_req_callback_data(subreq, struct tevent_req); + state = tevent_req_data(req, struct resolv_ghosts_state); + + ret = cache_req_user_by_name_recv(state, subreq, NULL); + talloc_zfree(subreq); + if (ret != EOK) { + goto done; + } + + ret = resolv_ghosts_step(req); + +done: + if (ret == EOK) { + tevent_req_done(req); + } else if (ret != EAGAIN) { + tevent_req_error(req, ret); + } +} + +static errno_t resolv_ghosts_recv(struct tevent_req *req) +{ + TEVENT_REQ_RETURN_ON_ERROR(req); + + return EOK; +} + +struct ifp_groups_group_update_member_list_state { + int dummy; +}; + +static void ifp_groups_group_update_member_list_done(struct tevent_req *subreq); + +struct tevent_req * +ifp_groups_group_update_member_list_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct sbus_request *sbus_req, + struct ifp_ctx *ctx) +{ + struct ifp_groups_group_update_member_list_state *state; + struct tevent_req *subreq; + struct tevent_req *req; + errno_t ret; + + req = tevent_req_create(mem_ctx, &state, struct ifp_groups_group_update_member_list_state); + if (req == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "Unable to create tevent request!\n"); + return NULL; + } + + subreq = resolv_ghosts_send(state, ev, sbus_req, ctx); + if (subreq == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "Unable to create subrequest!\n"); + ret = ENOMEM; + goto done; + } + + tevent_req_set_callback(subreq, ifp_groups_group_update_member_list_done, req); + + ret = EAGAIN; + +done: + if (ret != EAGAIN) { + tevent_req_error(req, ret); + tevent_req_post(req, ev); + } + + return req; +} + +static void ifp_groups_group_update_member_list_done(struct tevent_req *subreq) +{ + struct tevent_req *req; + errno_t ret; + + req = tevent_req_callback_data(subreq, struct tevent_req); + + ret = resolv_ghosts_recv(subreq); + talloc_zfree(subreq); + if (ret != EOK) { + DEBUG(SSSDBG_CRIT_FAILURE, "Unable to resolve ghost members [%d]: %s\n", + ret, sss_strerror(ret)); + tevent_req_error(req, ret); + return; + } + + tevent_req_done(req); + return; +} + +errno_t +ifp_groups_group_update_member_list_recv(TALLOC_CTX *mem_ctx, + struct tevent_req *req) +{ + TEVENT_REQ_RETURN_ON_ERROR(req); + + return EOK; +} + +errno_t +ifp_groups_group_get_name(TALLOC_CTX *mem_ctx, + struct sbus_request *sbus_req, + struct ifp_ctx *ctx, + const char **_out) +{ + struct sss_domain_info *domain; + struct ldb_message *msg; + const char *in_name; + const char *out; + errno_t ret; + + ret = ifp_groups_group_get(mem_ctx, sbus_req, ctx, &domain, &msg); + if (ret != EOK) { + return ret; + } + + in_name = sss_view_ldb_msg_find_attr_as_string(domain, msg, + SYSDB_NAME, NULL); + if (in_name == NULL) { + talloc_zfree(msg); + DEBUG(SSSDBG_OP_FAILURE, "No name?\n"); + return ERR_INTERNAL; + } + + out = ifp_format_name_attr(mem_ctx, ctx, in_name, domain); + talloc_zfree(msg); + if (out == NULL) { + return ENOMEM; + } + + *_out = out; + + return EOK; +} + +errno_t +ifp_groups_group_get_gid_number(TALLOC_CTX *mem_ctx, + struct sbus_request *sbus_req, + struct ifp_ctx *ctx, + uint32_t *_out) +{ + struct ldb_message *msg; + struct sss_domain_info *domain; + errno_t ret; + + ret = ifp_groups_group_get(mem_ctx, sbus_req, ctx, &domain, &msg); + if (ret != EOK) { + return ret; + } + + *_out = sss_view_ldb_msg_find_attr_as_uint64(domain, msg, SYSDB_GIDNUM, 0); + talloc_zfree(msg); + + return EOK; +} + +errno_t +ifp_groups_group_get_unique_id(TALLOC_CTX *mem_ctx, + struct sbus_request *sbus_req, + struct ifp_ctx *ctx, + const char **_out) +{ + struct ldb_message *msg; + struct sss_domain_info *domain; + const char *uuid; + errno_t ret; + + ret = ifp_groups_group_get(mem_ctx, sbus_req, ctx, &domain, &msg); + if (ret != EOK) { + return ret; + } + + uuid = sss_view_ldb_msg_find_attr_as_string(domain, msg, SYSDB_UUID, NULL); + if (uuid == NULL) { + talloc_zfree(msg); + return ENOENT; + } + + uuid = talloc_strdup(mem_ctx, uuid); + talloc_zfree(msg); + if (uuid == NULL) { + return ENOMEM; + } + + *_out = uuid; + + return EOK; +} + +static errno_t +ifp_groups_group_get_members(TALLOC_CTX *mem_ctx, + struct sbus_request *sbus_req, + struct ifp_ctx *ctx, + const char ***_users, + const char ***_groups) +{ + TALLOC_CTX *tmp_ctx; + struct sss_domain_info *domain; + struct ldb_message *group; + struct ldb_message **members; + size_t num_members; + const char *class; + const char **users; + const char **groups; + int num_users; + int num_groups; + int i; + errno_t ret; + const char *attrs[] = {SYSDB_OBJECTCATEGORY, SYSDB_UIDNUM, + SYSDB_GIDNUM, NULL}; + + tmp_ctx = talloc_new(NULL); + if (tmp_ctx == NULL) { + return ENOMEM; + } + + ret = ifp_groups_group_get(tmp_ctx, sbus_req, ctx, &domain, &group); + if (ret != EOK) { + goto done; + } + + ret = sysdb_asq_search(tmp_ctx, domain, group->dn, NULL, SYSDB_MEMBER, + attrs, &num_members, &members); + if (ret != EOK) { + DEBUG(SSSDBG_CRIT_FAILURE, "Unable to perform ASQ search [%d]: %s\n", + ret, sss_strerror(ret)); + goto done; + } + + if (num_members == 0) { + users = NULL; + groups = NULL; + ret = EOK; + goto done; + } + + users = talloc_zero_array(tmp_ctx, const char *, num_members + 1); + if (users == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "talloc_zero_array() failed\n"); + ret = ENOMEM; + goto done; + } + + groups = talloc_zero_array(tmp_ctx, const char *, num_members + 1); + if (groups == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "talloc_zero_array() failed\n"); + ret = ENOMEM; + goto done; + } + + num_users = 0; + num_groups = 0; + for (i = 0; i < num_members; i++) { + class = ldb_msg_find_attr_as_string(members[i], SYSDB_OBJECTCATEGORY, + NULL); + if (class == NULL) { + ret = ERR_INTERNAL; + goto done; + } + + if (strcmp(class, SYSDB_USER_CLASS) == 0) { + users[num_users] = ifp_users_build_path_from_msg(users, domain, + members[i]); + if (users[num_users] == NULL) { + ret = ENOMEM; + goto done; + } + + num_users++; + } else if (strcmp(class, SYSDB_GROUP_CLASS) == 0) { + groups[num_groups] = ifp_groups_build_path_from_msg(groups, + domain, members[i]); + if (groups[num_groups] == NULL) { + ret = ENOMEM; + goto done; + } + + num_groups++; + } else { + DEBUG(SSSDBG_CRIT_FAILURE, "Unexpected object class %s\n", class); + ret = ERR_INTERNAL; + goto done; + } + } + + ret = EOK; + +done: + if (ret == EOK) { + if (_users != NULL) { + *_users = talloc_steal(mem_ctx, users); + } + + if (_groups != NULL) { + *_groups = talloc_steal(mem_ctx, groups); + } + } + + talloc_free(tmp_ctx); + return ret; +} + +errno_t +ifp_groups_group_get_users(TALLOC_CTX *mem_ctx, + struct sbus_request *sbus_req, + struct ifp_ctx *ctx, + const char ***_out) +{ + errno_t ret; + + ret = ifp_groups_group_get_members(mem_ctx, sbus_req, ctx, _out, NULL); + if (ret != EOK) { + DEBUG(SSSDBG_CRIT_FAILURE, "Unable to acquire groups members\n"); + return ret; + } + + return EOK; +} + +errno_t +ifp_groups_group_get_groups(TALLOC_CTX *mem_ctx, + struct sbus_request *sbus_req, + struct ifp_ctx *ctx, + const char ***_out) +{ + errno_t ret; + + ret = ifp_groups_group_get_members(mem_ctx, sbus_req, ctx, NULL, _out); + if (ret != EOK) { + DEBUG(SSSDBG_CRIT_FAILURE, "Unable to acquire groups members\n"); + return ret; + } + + return EOK; +} + +errno_t +ifp_cache_list_group(TALLOC_CTX *mem_ctx, + struct sbus_request *sbus_req, + struct ifp_ctx *ctx, + const char ***_out) +{ + return ifp_cache_list(mem_ctx, ctx, IFP_CACHE_GROUP, _out); +} + +errno_t +ifp_cache_list_by_domain_group(TALLOC_CTX *mem_ctx, + struct sbus_request *sbus_req, + struct ifp_ctx *ctx, + const char *domain, + const char ***_out) +{ + return ifp_cache_list_by_domain(mem_ctx, ctx, domain, IFP_CACHE_GROUP, _out); +} + +errno_t +ifp_cache_object_store_group(TALLOC_CTX *mem_ctx, + struct sbus_request *sbus_req, + struct ifp_ctx *ctx, + bool *_result) +{ + struct sss_domain_info *domain; + struct ldb_message *group; + errno_t ret; + + ret = ifp_groups_group_get(NULL, sbus_req, ctx, &domain, &group); + if (ret != EOK) { + return ret; + } + + ret = ifp_cache_object_store(domain, group->dn); + talloc_free(group); + + if (ret == EOK) { + *_result = true; + } + + return ret; +} + +errno_t +ifp_cache_object_remove_group(TALLOC_CTX *mem_ctx, + struct sbus_request *sbus_req, + struct ifp_ctx *ctx, + bool *_result) +{ + struct sss_domain_info *domain; + struct ldb_message *group; + errno_t ret; + + ret = ifp_groups_group_get(NULL, sbus_req, ctx, &domain, &group); + if (ret != EOK) { + return ret; + } + + ret = ifp_cache_object_remove(domain, group->dn); + talloc_free(group); + + if (ret == EOK) { + *_result = true; + } + + return ret; +} diff --git a/src/responder/ifp/ifp_groups.h b/src/responder/ifp/ifp_groups.h new file mode 100644 index 0000000..114962f --- /dev/null +++ b/src/responder/ifp/ifp_groups.h @@ -0,0 +1,156 @@ +/* + Authors: + Pavel Březina <pbrezina@redhat.com> + + Copyright (C) 2015 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_GROUPS_H_ +#define IFP_GROUPS_H_ + +#include "responder/ifp/ifp_private.h" + +/* Utility functions */ + +char * ifp_groups_build_path_from_msg(TALLOC_CTX *mem_ctx, + struct sss_domain_info *domain, + struct ldb_message *msg); + +/* org.freedesktop.sssd.infopipe.Groups */ + +struct tevent_req * +ifp_groups_find_by_name_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct sbus_request *sbus_req, + struct ifp_ctx *ctx, + const char *name); + +errno_t +ifp_groups_find_by_name_recv(TALLOC_CTX *mem_ctx, + struct tevent_req *req, + const char **_path); + +struct tevent_req * +ifp_groups_find_by_id_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct sbus_request *sbus_req, + struct ifp_ctx *ctx, + uint32_t id); + +errno_t +ifp_groups_find_by_id_recv(TALLOC_CTX *mem_ctx, + struct tevent_req *req, + const char **_path); + +struct tevent_req * +ifp_groups_list_by_name_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct sbus_request *sbus_req, + struct ifp_ctx *ctx, + const char *filter, + uint32_t limit); + +errno_t +ifp_groups_list_by_name_recv(TALLOC_CTX *mem_ctx, + struct tevent_req *req, + const char ***_paths); + +struct tevent_req * +ifp_groups_list_by_domain_and_name_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct sbus_request *sbus_req, + struct ifp_ctx *ctx, + const char *domain, + const char *filter, + uint32_t limit); + +errno_t +ifp_groups_list_by_domain_and_name_recv(TALLOC_CTX *mem_ctx, + struct tevent_req *req, + const char ***_paths); + +/* org.freedesktop.sssd.infopipe.Groups.Group */ + +struct tevent_req * +ifp_groups_group_update_member_list_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct sbus_request *sbus_req, + struct ifp_ctx *ctx); + +errno_t +ifp_groups_group_update_member_list_recv(TALLOC_CTX *mem_ctx, + struct tevent_req *req); + +errno_t +ifp_groups_group_get_name(TALLOC_CTX *mem_ctx, + struct sbus_request *sbus_req, + struct ifp_ctx *ctx, + const char **_out); + +errno_t +ifp_groups_group_get_gid_number(TALLOC_CTX *mem_ctx, + struct sbus_request *sbus_req, + struct ifp_ctx *ctx, + uint32_t *_out); + +errno_t +ifp_groups_group_get_unique_id(TALLOC_CTX *mem_ctx, + struct sbus_request *sbus_req, + struct ifp_ctx *ctx, + const char **_out); + +errno_t +ifp_groups_group_get_users(TALLOC_CTX *mem_ctx, + struct sbus_request *sbus_req, + struct ifp_ctx *ctx, + const char ***_out); + +errno_t +ifp_groups_group_get_groups(TALLOC_CTX *mem_ctx, + struct sbus_request *sbus_req, + struct ifp_ctx *ctx, + const char ***_out); + +/* org.freedesktop.sssd.infopipe.Cache */ + +errno_t +ifp_cache_list_group(TALLOC_CTX *mem_ctx, + struct sbus_request *sbus_req, + struct ifp_ctx *ctx, + const char ***_out); + +errno_t +ifp_cache_list_by_domain_group(TALLOC_CTX *mem_ctx, + struct sbus_request *sbus_req, + struct ifp_ctx *ctx, + const char *domain, + const char ***_out); + +/* org.freedesktop.sssd.infopipe.Cache.Object */ + +errno_t +ifp_cache_object_store_group(TALLOC_CTX *mem_ctx, + struct sbus_request *sbus_req, + struct ifp_ctx *ctx, + bool *_result); + +errno_t +ifp_cache_object_remove_group(TALLOC_CTX *mem_ctx, + struct sbus_request *sbus_req, + struct ifp_ctx *ctx, + bool *_result); + +#endif /* IFP_GROUPS_H_ */ diff --git a/src/responder/ifp/ifp_iface/ifp_iface.c b/src/responder/ifp/ifp_iface/ifp_iface.c new file mode 100644 index 0000000..cbab470 --- /dev/null +++ b/src/responder/ifp/ifp_iface/ifp_iface.c @@ -0,0 +1,274 @@ +/* + Authors: + Pavel Březina <pbrezina@redhat.com> + + Copyright (C) 2018 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 "responder/common/responder.h" +#include "responder/ifp/ifp_private.h" +#include "responder/ifp/ifp_iface/ifp_iface_async.h" +#include "responder/ifp/ifp_cache.h" +#include "responder/ifp/ifp_components.h" +#include "responder/ifp/ifp_domains.h" +#include "responder/ifp/ifp_groups.h" +#include "responder/ifp/ifp_users.h" + +errno_t +ifp_access_check(struct sbus_request *sbus_req, + struct ifp_ctx *ifp_ctx) +{ + uid_t uid; + errno_t ret; + + /* We allow those special cases to access infopipe. */ + if (sbus_req->sender->uid < 0) { + return EOK; + } + + uid = (uid_t)sbus_req->sender->uid; + + ret = check_allowed_uids(uid, + ifp_ctx->rctx->allowed_uids_count, + ifp_ctx->rctx->allowed_uids); + if (ret == EACCES) { + DEBUG(SSSDBG_MINOR_FAILURE, "User %"PRIi64" not in ACL\n", + sbus_req->sender->uid); + return ret; + } else if (ret != EOK) { + DEBUG(SSSDBG_OP_FAILURE, "Cannot check if user %"PRIi64 + "is present in ACL\n", sbus_req->sender->uid); + return ret; + } + + switch (sbus_req->type) { + case SBUS_REQUEST_PROPERTY_GET: + if (strcmp(sbus_req->interface, "org.freedesktop.sssd.infopipe.Users.User") == 0) { + if (!ifp_is_user_attr_allowed(ifp_ctx, sbus_req->property)) { + DEBUG(SSSDBG_TRACE_ALL, "Attribute %s is not allowed\n", + sbus_req->property); + return EACCES; + } + } + break; + default: + return EOK; + } + + return EOK; +} + +errno_t +ifp_register_sbus_interface(struct sbus_connection *conn, + struct ifp_ctx *ctx) +{ + errno_t ret; + + SBUS_INTERFACE(iface_ifp, + org_freedesktop_sssd_infopipe, + SBUS_METHODS( + SBUS_SYNC(METHOD, org_freedesktop_sssd_infopipe, Ping, ifp_ping, ctx), + SBUS_SYNC(METHOD, org_freedesktop_sssd_infopipe, ListComponents, ifp_list_components, ctx), + SBUS_SYNC(METHOD, org_freedesktop_sssd_infopipe, ListResponders, ifp_list_responders, ctx), + SBUS_SYNC(METHOD, org_freedesktop_sssd_infopipe, ListBackends, ifp_list_backends, ctx), + SBUS_SYNC(METHOD, org_freedesktop_sssd_infopipe, FindMonitor, ifp_find_monitor, ctx), + SBUS_SYNC(METHOD, org_freedesktop_sssd_infopipe, FindResponderByName, ifp_find_responder_by_name, ctx), + SBUS_SYNC(METHOD, org_freedesktop_sssd_infopipe, FindBackendByName, ifp_find_backend_by_name, ctx), + SBUS_ASYNC(METHOD, org_freedesktop_sssd_infopipe, GetUserAttr, ifp_get_user_attr_send, ifp_get_user_attr_recv, ctx), + SBUS_ASYNC(METHOD, org_freedesktop_sssd_infopipe, GetUserGroups, ifp_user_get_groups_send, ifp_user_get_groups_recv, ctx), + SBUS_ASYNC(METHOD, org_freedesktop_sssd_infopipe, FindDomainByName, ifp_find_domain_by_name_send, ifp_find_domain_by_name_recv, ctx), + SBUS_ASYNC(METHOD, org_freedesktop_sssd_infopipe, ListDomains, ifp_list_domains_send, ifp_list_domains_recv, ctx) + ), + SBUS_SIGNALS(SBUS_NO_SIGNALS), + SBUS_PROPERTIES(SBUS_NO_PROPERTIES) + ); + + SBUS_INTERFACE(iface_ifp_components, + org_freedesktop_sssd_infopipe_Components, + SBUS_METHODS(SBUS_NO_METHODS), + SBUS_SIGNALS(SBUS_NO_SIGNALS), + SBUS_PROPERTIES( + SBUS_SYNC(GETTER, org_freedesktop_sssd_infopipe_Components, name, ifp_component_get_name, ctx), + SBUS_SYNC(GETTER, org_freedesktop_sssd_infopipe_Components, debug_level, ifp_component_get_debug_level, ctx), + SBUS_SYNC(GETTER, org_freedesktop_sssd_infopipe_Components, enabled, ifp_component_get_enabled, ctx), + SBUS_SYNC(GETTER, org_freedesktop_sssd_infopipe_Components, type, ifp_component_get_type, ctx), + SBUS_SYNC(GETTER, org_freedesktop_sssd_infopipe_Components, providers, ifp_backend_get_providers, ctx) + ) + ); + + SBUS_INTERFACE(iface_ifp_domains, + org_freedesktop_sssd_infopipe_Domains, + SBUS_METHODS(SBUS_NO_METHODS), + SBUS_SIGNALS(SBUS_NO_SIGNALS), + SBUS_PROPERTIES( + SBUS_SYNC(GETTER, org_freedesktop_sssd_infopipe_Domains, name, ifp_dom_get_name, ctx), + SBUS_SYNC(GETTER, org_freedesktop_sssd_infopipe_Domains, provider, ifp_dom_get_provider, ctx), + SBUS_SYNC(GETTER, org_freedesktop_sssd_infopipe_Domains, primary_servers, ifp_dom_get_primary_servers, ctx), + SBUS_SYNC(GETTER, org_freedesktop_sssd_infopipe_Domains, backup_servers, ifp_dom_get_backup_servers, ctx), + SBUS_SYNC(GETTER, org_freedesktop_sssd_infopipe_Domains, min_id, ifp_dom_get_min_id, ctx), + SBUS_SYNC(GETTER, org_freedesktop_sssd_infopipe_Domains, max_id, ifp_dom_get_max_id, ctx), + SBUS_SYNC(GETTER, org_freedesktop_sssd_infopipe_Domains, realm, ifp_dom_get_realm, ctx), + SBUS_SYNC(GETTER, org_freedesktop_sssd_infopipe_Domains, forest, ifp_dom_get_forest, ctx), + SBUS_SYNC(GETTER, org_freedesktop_sssd_infopipe_Domains, login_format, ifp_dom_get_login_format, ctx), + SBUS_SYNC(GETTER, org_freedesktop_sssd_infopipe_Domains, fully_qualified_name_format, ifp_dom_get_fqdn_format, ctx), + SBUS_SYNC(GETTER, org_freedesktop_sssd_infopipe_Domains, enumerable, ifp_dom_get_enumerable, ctx), + SBUS_SYNC(GETTER, org_freedesktop_sssd_infopipe_Domains, use_fully_qualified_names, ifp_dom_get_use_fqdn, ctx), + SBUS_SYNC(GETTER, org_freedesktop_sssd_infopipe_Domains, subdomain, ifp_dom_get_subdomain, ctx), + SBUS_SYNC(GETTER, org_freedesktop_sssd_infopipe_Domains, parent_domain, ifp_dom_get_parent_domain, ctx) + ) + ); + + SBUS_INTERFACE(iface_ifp_domains_domain, + org_freedesktop_sssd_infopipe_Domains_Domain, + SBUS_METHODS( + SBUS_ASYNC(METHOD, org_freedesktop_sssd_infopipe_Domains_Domain, IsOnline, ifp_domains_domain_is_online_send, ifp_domains_domain_is_online_recv, ctx), + SBUS_ASYNC(METHOD, org_freedesktop_sssd_infopipe_Domains_Domain, ListServices, ifp_domains_domain_list_services_send, ifp_domains_domain_list_services_recv, ctx), + SBUS_ASYNC(METHOD, org_freedesktop_sssd_infopipe_Domains_Domain, ActiveServer, ifp_domains_domain_active_server_send, ifp_domains_domain_active_server_recv, ctx), + SBUS_ASYNC(METHOD, org_freedesktop_sssd_infopipe_Domains_Domain, ListServers, ifp_domains_domain_list_servers_send, ifp_domains_domain_list_servers_recv, ctx), + SBUS_ASYNC(METHOD, org_freedesktop_sssd_infopipe_Domains_Domain, RefreshAccessRules, ifp_domains_domain_refresh_access_rules_send, ifp_domains_domain_refresh_access_rules_recv, ctx) + ), + SBUS_SIGNALS(SBUS_NO_SIGNALS), + SBUS_PROPERTIES(SBUS_NO_PROPERTIES) + ); + + SBUS_INTERFACE(iface_ifp_users, + org_freedesktop_sssd_infopipe_Users, + SBUS_METHODS( + SBUS_ASYNC(METHOD, org_freedesktop_sssd_infopipe_Users, FindByName, ifp_users_find_by_name_send, ifp_users_find_by_name_recv, ctx), + SBUS_ASYNC(METHOD, org_freedesktop_sssd_infopipe_Users, FindByID, ifp_users_find_by_id_send, ifp_users_find_by_id_recv, ctx), + SBUS_ASYNC(METHOD, org_freedesktop_sssd_infopipe_Users, FindByCertificate, ifp_users_find_by_cert_send, ifp_users_find_by_cert_recv, ctx), + SBUS_ASYNC(METHOD, org_freedesktop_sssd_infopipe_Users, ListByCertificate, ifp_users_list_by_cert_send, ifp_users_list_by_cert_recv, ctx), + SBUS_ASYNC(METHOD, org_freedesktop_sssd_infopipe_Users, FindByNameAndCertificate, ifp_users_find_by_name_and_cert_send, ifp_users_find_by_name_and_cert_recv, ctx), + SBUS_ASYNC(METHOD, org_freedesktop_sssd_infopipe_Users, ListByName, ifp_users_list_by_name_send, ifp_users_list_by_attr_recv, ctx), + SBUS_ASYNC(METHOD, org_freedesktop_sssd_infopipe_Users, ListByDomainAndName, ifp_users_list_by_domain_and_name_send, ifp_users_list_by_domain_and_name_recv, ctx), + SBUS_ASYNC(METHOD, org_freedesktop_sssd_infopipe_Users, FindByValidCertificate, ifp_users_find_by_valid_cert_send, ifp_users_find_by_valid_cert_recv, ctx), + SBUS_ASYNC(METHOD, org_freedesktop_sssd_infopipe_Users, ListByAttr, ifp_users_list_by_attr_send, ifp_users_list_by_attr_recv, ctx) + ), + SBUS_SIGNALS(SBUS_NO_SIGNALS), + SBUS_PROPERTIES(SBUS_NO_PROPERTIES) + ); + + SBUS_INTERFACE(iface_ifp_users_user, + org_freedesktop_sssd_infopipe_Users_User, + SBUS_METHODS(SBUS_NO_METHODS), + SBUS_SIGNALS(SBUS_NO_SIGNALS), + SBUS_PROPERTIES( + SBUS_SYNC(GETTER, org_freedesktop_sssd_infopipe_Users_User, name, ifp_users_user_get_name, ctx), + SBUS_SYNC(GETTER, org_freedesktop_sssd_infopipe_Users_User, uidNumber, ifp_users_user_get_uid_number, ctx), + SBUS_SYNC(GETTER, org_freedesktop_sssd_infopipe_Users_User, gidNumber, ifp_users_user_get_gid_number, ctx), + SBUS_SYNC(GETTER, org_freedesktop_sssd_infopipe_Users_User, gecos, ifp_users_user_get_gecos, ctx), + SBUS_SYNC(GETTER, org_freedesktop_sssd_infopipe_Users_User, homeDirectory, ifp_users_user_get_home_directory, ctx), + SBUS_SYNC(GETTER, org_freedesktop_sssd_infopipe_Users_User, loginShell, ifp_users_user_get_login_shell, ctx), + SBUS_SYNC(GETTER, org_freedesktop_sssd_infopipe_Users_User, uniqueID, ifp_users_user_get_unique_id, ctx), + SBUS_SYNC(GETTER, org_freedesktop_sssd_infopipe_Users_User, groups, ifp_users_user_get_groups, ctx), + SBUS_SYNC(GETTER, org_freedesktop_sssd_infopipe_Users_User, domain, ifp_users_user_get_domain, ctx), + SBUS_SYNC(GETTER, org_freedesktop_sssd_infopipe_Users_User, domainname, ifp_users_user_get_domainname, ctx), + SBUS_SYNC(GETTER, org_freedesktop_sssd_infopipe_Users_User, extraAttributes, ifp_users_user_get_extra_attributes, ctx) + ) + ); + + SBUS_INTERFACE(iface_ifp_cache_user, + org_freedesktop_sssd_infopipe_Cache, + SBUS_METHODS( + SBUS_SYNC(METHOD, org_freedesktop_sssd_infopipe_Cache, List, ifp_cache_list_user, ctx), + SBUS_SYNC(METHOD, org_freedesktop_sssd_infopipe_Cache, ListByDomain, ifp_cache_list_by_domain_user, ctx) + ), + SBUS_SIGNALS(SBUS_NO_SIGNALS), + SBUS_PROPERTIES(SBUS_NO_PROPERTIES) + ); + + SBUS_INTERFACE(iface_ifp_cache_object_user, + org_freedesktop_sssd_infopipe_Cache_Object, + SBUS_METHODS( + SBUS_SYNC(METHOD, org_freedesktop_sssd_infopipe_Cache_Object, Store, ifp_cache_object_store_user, ctx), + SBUS_SYNC(METHOD, org_freedesktop_sssd_infopipe_Cache_Object, Remove, ifp_cache_object_remove_user, ctx) + ), + SBUS_SIGNALS(SBUS_NO_SIGNALS), + SBUS_PROPERTIES(SBUS_NO_PROPERTIES) + ); + + SBUS_INTERFACE(iface_ifp_groups, + org_freedesktop_sssd_infopipe_Groups, + SBUS_METHODS( + SBUS_ASYNC(METHOD, org_freedesktop_sssd_infopipe_Groups, FindByName, ifp_groups_find_by_name_send, ifp_groups_find_by_name_recv, ctx), + SBUS_ASYNC(METHOD, org_freedesktop_sssd_infopipe_Groups, FindByID, ifp_groups_find_by_id_send, ifp_groups_find_by_id_recv, ctx), + SBUS_ASYNC(METHOD, org_freedesktop_sssd_infopipe_Groups, ListByName, ifp_groups_list_by_name_send, ifp_groups_list_by_name_recv, ctx), + SBUS_ASYNC(METHOD, org_freedesktop_sssd_infopipe_Groups, ListByDomainAndName, ifp_groups_list_by_domain_and_name_send, ifp_groups_list_by_domain_and_name_recv, ctx) + ), + SBUS_SIGNALS(SBUS_NO_SIGNALS), + SBUS_PROPERTIES(SBUS_NO_PROPERTIES) + ); + + SBUS_INTERFACE(iface_ifp_groups_group, + org_freedesktop_sssd_infopipe_Groups_Group, + SBUS_METHODS( + SBUS_ASYNC(METHOD, org_freedesktop_sssd_infopipe_Groups_Group, UpdateMemberList, ifp_groups_group_update_member_list_send, ifp_groups_group_update_member_list_recv, ctx) + ), + SBUS_SIGNALS(SBUS_NO_SIGNALS), + SBUS_PROPERTIES( + SBUS_SYNC(GETTER, org_freedesktop_sssd_infopipe_Groups_Group, name, ifp_groups_group_get_name, ctx), + SBUS_SYNC(GETTER, org_freedesktop_sssd_infopipe_Groups_Group, gidNumber, ifp_groups_group_get_gid_number, ctx), + SBUS_SYNC(GETTER, org_freedesktop_sssd_infopipe_Groups_Group, uniqueID, ifp_groups_group_get_unique_id, ctx), + SBUS_SYNC(GETTER, org_freedesktop_sssd_infopipe_Groups_Group, users, ifp_groups_group_get_users, ctx), + SBUS_SYNC(GETTER, org_freedesktop_sssd_infopipe_Groups_Group, groups, ifp_groups_group_get_groups, ctx) + ) + ); + + SBUS_INTERFACE(iface_ifp_cache_group, + org_freedesktop_sssd_infopipe_Cache, + SBUS_METHODS( + SBUS_SYNC(METHOD, org_freedesktop_sssd_infopipe_Cache, List, ifp_cache_list_group, ctx), + SBUS_SYNC(METHOD, org_freedesktop_sssd_infopipe_Cache, ListByDomain, ifp_cache_list_by_domain_group, ctx) + ), + SBUS_SIGNALS(SBUS_NO_SIGNALS), + SBUS_PROPERTIES(SBUS_NO_PROPERTIES) + ); + + SBUS_INTERFACE(iface_ifp_cache_object_group, + org_freedesktop_sssd_infopipe_Cache_Object, + SBUS_METHODS( + SBUS_SYNC(METHOD, org_freedesktop_sssd_infopipe_Cache_Object, Store, ifp_cache_object_store_group, ctx), + SBUS_SYNC(METHOD, org_freedesktop_sssd_infopipe_Cache_Object, Remove, ifp_cache_object_remove_group, ctx) + ), + SBUS_SIGNALS(SBUS_NO_SIGNALS), + SBUS_PROPERTIES(SBUS_NO_PROPERTIES) + ); + + struct sbus_path paths[] = { + { IFP_PATH, &iface_ifp }, + { IFP_PATH_DOMAINS, &iface_ifp_domains }, + { IFP_PATH_DOMAINS_TREE, &iface_ifp_domains }, + { IFP_PATH_DOMAINS_TREE, &iface_ifp_domains_domain }, + { IFP_PATH_COMPONENTS_TREE, &iface_ifp_components }, + { IFP_PATH_USERS, &iface_ifp_users }, + { IFP_PATH_USERS, &iface_ifp_cache_user }, + { IFP_PATH_USERS_TREE, &iface_ifp_users_user }, + { IFP_PATH_USERS_TREE, &iface_ifp_cache_object_user }, + { IFP_PATH_GROUPS, &iface_ifp_groups }, + { IFP_PATH_GROUPS, &iface_ifp_cache_group }, + { IFP_PATH_GROUPS_TREE, &iface_ifp_groups_group }, + { IFP_PATH_GROUPS_TREE, &iface_ifp_cache_object_group }, + {NULL, NULL} + }; + + ret = sbus_connection_add_path_map(conn, paths); + if (ret != EOK) { + DEBUG(SSSDBG_FATAL_FAILURE, "Unable to add paths [%d]: %s\n", + ret, sss_strerror(ret)); + } + + return ret; +} diff --git a/src/responder/ifp/ifp_iface/ifp_iface.h b/src/responder/ifp/ifp_iface/ifp_iface.h new file mode 100644 index 0000000..0bf6510 --- /dev/null +++ b/src/responder/ifp/ifp_iface/ifp_iface.h @@ -0,0 +1,40 @@ +/* + Authors: + Pavel Březina <pbrezina@redhat.com> + + Copyright (C) 2018 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_IFACE_H_ +#define _IFP_IFACE_H_ + +#define IFP_BUS "org.freedesktop.sssd.infopipe" + +#define IFP_PATH "/org/freedesktop/sssd/infopipe" + +#define IFP_PATH_DOMAINS IFP_PATH "/Domains" +#define IFP_PATH_DOMAINS_TREE IFP_PATH_DOMAINS "/*" + +#define IFP_PATH_COMPONENTS IFP_PATH "/Components" +#define IFP_PATH_COMPONENTS_TREE IFP_PATH_COMPONENTS "/*" + +#define IFP_PATH_GROUPS IFP_PATH "/Groups" +#define IFP_PATH_GROUPS_TREE IFP_PATH_GROUPS "/*" + +#define IFP_PATH_USERS IFP_PATH "/Users" +#define IFP_PATH_USERS_TREE IFP_PATH_USERS "/*" + +#endif /* _IFP_IFACE_H_ */ diff --git a/src/responder/ifp/ifp_iface/ifp_iface.xml b/src/responder/ifp/ifp_iface/ifp_iface.xml new file mode 100644 index 0000000..75b4891 --- /dev/null +++ b/src/responder/ifp/ifp_iface/ifp_iface.xml @@ -0,0 +1,253 @@ +<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" + "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd"> +<node> + <interface name="org.freedesktop.sssd.infopipe"> + <annotation name="codegen.Name" value="ifp" /> + <annotation name="codegen.AsyncCaller" value="false" /> + + <method name="Ping"> + <arg name="ping" type="s" direction="in" key="1" /> + <arg name="pong" type="s" direction="out" /> + </method> + + <!-- SSSD components --> + + <method name="ListComponents" key="True"> + <arg name="components" type="ao" direction="out"/> + </method> + + <method name="ListResponders" key="True"> + <arg name="responders" type="ao" direction="out"/> + </method> + + <method name="ListBackends" key="True"> + <arg name="backends" type="ao" direction="out"/> + </method> + + <method name="FindMonitor" key="True"> + <arg name="monitor" type="o" direction="out"/> + </method> + + <method name="FindResponderByName"> + <arg name="name" type="s" direction="in" key="1" /> + <arg name="responder" type="o" direction="out"/> + </method> + + <method name="FindBackendByName"> + <arg name="name" type="s" direction="in" key="1" /> + <arg name="backend" type="o" direction="out"/> + </method> + + <method name="GetUserAttr"> + <annotation name="codegen.CustomOutputHandler" value="true"/> + <arg name="user" type="s" direction="in" /> + <arg name="attr" type="as" direction="in" /> + <arg name="values" type="a{sv}" direction="out"/> + </method> + + <method name="GetUserGroups"> + <arg name="user" type="s" direction="in" key="1" /> + <arg name="values" type="as" direction="out"/> + </method> + + <method name="FindDomainByName"> + <arg name="name" type="s" direction="in" key="1" /> + <arg name="domain" type="o" direction="out"/> + </method> + + <method name="ListDomains" key="True"> + <arg name="domain" type="ao" direction="out"/> + </method> + + </interface> + + <interface name="org.freedesktop.sssd.infopipe.Components"> + <annotation name="codegen.Name" value="ifp_components" /> + <annotation name="codegen.AsyncCaller" value="false" /> + + <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="codegen.Name" value="ifp_domains" /> + <annotation name="codegen.AsyncCaller" value="false" /> + + <property name="name" type="s" access="read"/> + <property name="provider" type="s" access="read"/> + <property name="primary_servers" type="as" access="read"/> + <property name="backup_servers" type="as" access="read"/> + <property name="min_id" type="u" access="read"/> + <property name="max_id" type="u" access="read"/> + <property name="realm" type="s" access="read"/> + <property name="forest" type="s" access="read"/> + <property name="login_format" type="s" access="read"/> + <property name="fully_qualified_name_format" type="s" access="read"/> + <property name="enumerable" type="b" access="read"/> + <property name="use_fully_qualified_names" type="b" access="read"/> + <property name="subdomain" type="b" access="read"/> + <property name="parent_domain" type="o" access="read"/> + </interface> + + <interface name="org.freedesktop.sssd.infopipe.Domains.Domain"> + <annotation name="codegen.Name" value="ifp_domain" /> + <annotation name="codegen.AsyncCaller" value="false" /> + + <method name="IsOnline" key="True"> + <arg name="status" type="b" direction="out" /> + </method> + + <method name="ListServices" key="True"> + <arg name="services" type="as" direction="out" /> + </method> + + <method name="ActiveServer"> + <arg name="service" type="s" direction="in" key="1" /> + <arg name="server" type="s" direction="out" /> + </method> + + <method name="ListServers"> + <arg name="service_name" type="s" direction="in" key="1" /> + <arg name="servers" type="as" direction="out" /> + </method> + + <method name="RefreshAccessRules" key="True" /> + </interface> + + <interface name="org.freedesktop.sssd.infopipe.Cache"> + <annotation name="codegen.Name" value="ifp_cache" /> + <annotation name="codegen.AsyncCaller" value="false" /> + + <method name="List" key="True"> + <arg name="result" type="ao" direction="out" /> + </method> + <method name="ListByDomain"> + <arg name="domain_name" type="s" direction="in" key="1" /> + <arg name="result" type="ao" direction="out"/> + </method> + </interface> + + <interface name="org.freedesktop.sssd.infopipe.Cache.Object"> + <annotation name="codegen.Name" value="ifp_cache_object" /> + <annotation name="codegen.AsyncCaller" value="false" /> + + <method name="Store" key="True"> + <arg name="result" type="b" direction="out" /> + </method> + <method name="Remove" key="True"> + <arg name="result" type="b" direction="out" /> + </method> + </interface> + + <interface name="org.freedesktop.sssd.infopipe.Users"> + <annotation name="codegen.Name" value="ifp_users" /> + <annotation name="codegen.AsyncCaller" value="false" /> + + <method name="FindByName"> + <arg name="name" type="s" direction="in" key="1" /> + <arg name="result" type="o" direction="out" /> + </method> + <method name="FindByID"> + <arg name="id" type="u" direction="in" key="1" /> + <arg name="result" type="o" direction="out" /> + </method> + <method name="FindByCertificate"> + <arg name="pem_cert" type="s" direction="in" /> + <arg name="result" type="o" direction="out" /> + </method> + <method name="ListByCertificate"> + <arg name="pem_cert" type="s" direction="in" /> + <arg name="limit" type="u" direction="in" /> + <arg name="result" type="ao" direction="out" /> + </method> + <method name="FindByNameAndCertificate"> + <arg name="name" type="s" direction="in" /> + <arg name="pem_cert" type="s" direction="in" /> + <arg name="result" type="o" direction="out" /> + </method> + <method name="ListByName"> + <arg name="name_filter" type="s" direction="in" key="1" /> + <arg name="limit" type="u" direction="in" key="2" /> + <arg name="result" type="ao" direction="out" /> + </method> + <method name="ListByDomainAndName"> + <arg name="domain_name" type="s" direction="in" key="1" /> + <arg name="name_filter" type="s" direction="in" key="2" /> + <arg name="limit" type="u" direction="in" key="3" /> + <arg name="result" type="ao" direction="out"/> + </method> + <method name="FindByValidCertificate"> + <arg name="pem_cert" type="s" direction="in" /> + <arg name="result" type="o" direction="out" /> + </method> + <method name="ListByAttr"> + <arg name="attribute" type="s" direction="in" key="1" /> + <arg name="attr_filter" type="s" direction="in" key="2" /> + <arg name="limit" type="u" direction="in" key="3" /> + <arg name="result" type="ao" direction="out" /> + </method> + </interface> + + <interface name="org.freedesktop.sssd.infopipe.Users.User"> + <annotation name="codegen.Name" value="ifp_user" /> + <annotation name="codegen.AsyncCaller" value="false" /> + + <method name="UpdateGroupsList" key="True" /> + + <property name="name" type="s" access="read" /> + <property name="uidNumber" type="u" access="read" /> + <property name="gidNumber" type="u" access="read" /> + <property name="gecos" type="s" access="read" /> + <property name="homeDirectory" type="s" access="read" /> + <property name="loginShell" type="s" access="read" /> + <property name="uniqueID" type="s" access="read" /> + <property name="groups" type="ao" access="read" /> + <property name="domain" type="o" access="read" /> + <property name="domainname" type="s" access="read" /> + <property name="extraAttributes" type="ifp_extra" access="read" /> + </interface> + + <interface name="org.freedesktop.sssd.infopipe.Groups"> + <annotation name="codegen.Name" value="ifp_groups" /> + <annotation name="codegen.AsyncCaller" value="false" /> + + <method name="FindByName"> + <arg name="name" type="s" direction="in" key="1" /> + <arg name="result" type="o" direction="out" /> + </method> + <method name="FindByID"> + <arg name="id" type="u" direction="in" key="1" /> + <arg name="result" type="o" direction="out" /> + </method> + <method name="ListByName"> + <arg name="name_filter" type="s" direction="in" key="1" /> + <arg name="limit" type="u" direction="in" key="2" /> + <arg name="result" type="ao" direction="out" /> + </method> + <method name="ListByDomainAndName"> + <arg name="domain_name" type="s" direction="in" key="1" /> + <arg name="name_filter" type="s" direction="in" key="2" /> + <arg name="limit" type="u" direction="in" key="3" /> + <arg name="result" type="ao" direction="out"/> + </method> + </interface> + + <interface name="org.freedesktop.sssd.infopipe.Groups.Group"> + <annotation name="codegen.Name" value="ifp_group" /> + <annotation name="codegen.AsyncCaller" value="false" /> + + <method name="UpdateMemberList" key="True" /> + + <property name="name" type="s" access="read" /> + <property name="gidNumber" type="u" access="read" /> + <property name="uniqueID" type="s" access="read" /> + <property name="users" type="ao" access="read" /> + <property name="groups" type="ao" access="read" /> + </interface> +</node> diff --git a/src/responder/ifp/ifp_iface/ifp_iface_async.h b/src/responder/ifp/ifp_iface/ifp_iface_async.h new file mode 100644 index 0000000..bdf737d --- /dev/null +++ b/src/responder/ifp/ifp_iface/ifp_iface_async.h @@ -0,0 +1,28 @@ +/* + Authors: + Pavel Březina <pbrezina@redhat.com> + + Copyright (C) 2018 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_IFACE_ASYNC_H_ +#define _IFP_IFACE_ASYNC_H_ + +#include "responder/ifp/ifp_iface/sbus_ifp_server.h" +#include "responder/ifp/ifp_iface/sbus_ifp_client_async.h" +#include "responder/ifp/ifp_iface/ifp_iface.h" + +#endif /* _IFP_IFACE_ASYNC_H_ */ diff --git a/src/responder/ifp/ifp_iface/ifp_iface_sync.h b/src/responder/ifp/ifp_iface/ifp_iface_sync.h new file mode 100644 index 0000000..804e0dd --- /dev/null +++ b/src/responder/ifp/ifp_iface/ifp_iface_sync.h @@ -0,0 +1,27 @@ +/* + Authors: + Pavel Březina <pbrezina@redhat.com> + + Copyright (C) 2018 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_IFACE_SYNC_H_ +#define _IFP_IFACE_SYNC_H_ + +#include "responder/ifp/ifp_iface/sbus_ifp_client_sync.h" +#include "responder/ifp/ifp_iface/ifp_iface.h" + +#endif /* _IFP_IFACE_SYNC_H_ */ diff --git a/src/responder/ifp/ifp_iface/ifp_iface_types.c b/src/responder/ifp/ifp_iface/ifp_iface_types.c new file mode 100644 index 0000000..ad18304 --- /dev/null +++ b/src/responder/ifp/ifp_iface/ifp_iface_types.c @@ -0,0 +1,225 @@ +/* + Authors: + Pavel Březina <pbrezina@redhat.com> + + Copyright (C) 2017 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 <errno.h> +#include <string.h> +#include <stdint.h> +#include <talloc.h> +#include <dbus/dbus.h> + +#include "util/util.h" +#include "responder/ifp/ifp_iface/ifp_iface_types.h" +#include "sbus/interface/sbus_iterator_readers.h" +#include "sbus/interface/sbus_iterator_writers.h" + +/** + * D-Bus signature: a{sas} + */ +errno_t sbus_iterator_read_ifp_extra(TALLOC_CTX *mem_ctx, + DBusMessageIter *iterator, + hash_table_t **_table) +{ + DBusMessageIter iter_array; + DBusMessageIter iter_dict; + hash_table_t *table; + hash_key_t hkey; + hash_value_t hvalue; + char **values; + char *key; + int arg_type; + errno_t ret; + int count; + int hret; + int i; + + ret = sss_hash_create(mem_ctx, 0, &table); + if (ret != EOK) { + return ret; + } + + arg_type = dbus_message_iter_get_arg_type(iterator); + if (arg_type != DBUS_TYPE_ARRAY) { + ret = ERR_SBUS_INVALID_TYPE; + goto done; + } + + count = dbus_message_iter_get_element_count(iterator); + dbus_message_iter_recurse(iterator, &iter_array); + + for (i = 0; i < count; i++) { + arg_type = dbus_message_iter_get_arg_type(&iter_array); + if (arg_type != DBUS_TYPE_DICT_ENTRY) { + ret = ERR_SBUS_INVALID_TYPE; + goto done; + } + + dbus_message_iter_recurse(&iter_array, &iter_dict); + + ret = sbus_iterator_read_S(table, &iter_dict, &key); + if (ret != EOK) { + goto done; + } + + ret = sbus_iterator_read_aS(table, &iter_dict, &values); + if (ret != EOK) { + goto done; + } + + hkey.type = HASH_KEY_STRING; + hkey.str = key; + + hvalue.type = HASH_VALUE_PTR; + hvalue.ptr = values; + + hret = hash_enter(table, &hkey, &hvalue); + if (hret != HASH_SUCCESS) { + ret = EIO; + goto done; + } + + /* dhash will duplicate the key internally */ + talloc_free(key); + + dbus_message_iter_next(&iter_array); + } + + *_table = table; + + ret = EOK; + +done: + if (ret != EOK) { + talloc_free(table); + } + + return ret; +} + +/** + * D-Bus signature: a{sas} + */ +errno_t sbus_iterator_write_ifp_extra(DBusMessageIter *iterator, + hash_table_t *table) +{ + DBusMessageIter it_array; + DBusMessageIter it_dict; + struct hash_iter_context_t *table_iter = NULL; + bool in_array = false; + bool in_dict = false; + hash_entry_t *entry; + const char **values; + dbus_bool_t dbret; + errno_t ret; + + dbret = dbus_message_iter_open_container(iterator, DBUS_TYPE_ARRAY, + DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING + DBUS_TYPE_STRING_AS_STRING + DBUS_TYPE_ARRAY_AS_STRING + DBUS_TYPE_STRING_AS_STRING + DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &it_array); + if (!dbret) { + ret = EIO; + goto done; + } + + in_array = true; + + if (table == NULL) { + dbret = dbus_message_iter_close_container(iterator, &it_array); + if (!dbret) { + ret = EIO; + goto done; + } + + in_array = false; + ret = EOK; + goto done; + } + + table_iter = new_hash_iter_context(table); + if (table_iter == NULL) { + DEBUG(SSSDBG_OP_FAILURE, "new_hash_iter_context failed.\n"); + ret = EINVAL; + goto done; + } + + while ((entry = table_iter->next(table_iter)) != NULL) { + if (entry->key.type != HASH_KEY_STRING || entry->key.str == NULL + || entry->value.type != HASH_VALUE_PTR + || entry->value.ptr == NULL) { + continue; + } + + dbret = dbus_message_iter_open_container(&it_array, + DBUS_TYPE_DICT_ENTRY, NULL, + &it_dict); + if (!dbret) { + ret = EIO; + goto done; + } + + in_dict = true; + + ret = sbus_iterator_write_s(&it_dict, entry->key.str); + if (ret != EOK) { + goto done; + } + + values = entry->value.ptr; + ret = sbus_iterator_write_as(&it_dict, values); + if (ret != EOK) { + goto done; + } + + dbret = dbus_message_iter_close_container(&it_array, &it_dict); + if (!dbret) { + ret = EIO; + goto done; + } + + in_dict = false; + } + + dbret = dbus_message_iter_close_container(iterator, &it_array); + if (!dbret) { + ret = EIO; + goto done; + } + + in_array = false; + ret = EOK; + +done: + if (ret != EOK) { + if (in_dict) { + dbus_message_iter_abandon_container(&it_array, &it_dict); + } + + if (in_array) { + dbus_message_iter_abandon_container(iterator, &it_array); + } + } + + if (table_iter != NULL) { + talloc_free(table_iter); + } + + return ret; +} diff --git a/src/responder/ifp/ifp_iface/ifp_iface_types.h b/src/responder/ifp/ifp_iface/ifp_iface_types.h new file mode 100644 index 0000000..0a3cbd0 --- /dev/null +++ b/src/responder/ifp/ifp_iface/ifp_iface_types.h @@ -0,0 +1,35 @@ +/* + Authors: + Pavel Březina <pbrezina@redhat.com> + + Copyright (C) 2017 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_IFACE_CUSTOM_TYPES_H_ +#define _IFP_IFACE_CUSTOM_TYPES_H_ + +#include <talloc.h> +#include <dhash.h> +#include <dbus/dbus.h> + +errno_t sbus_iterator_read_ifp_extra(TALLOC_CTX *mem_ctx, + DBusMessageIter *iterator, + hash_table_t **_table); + +errno_t sbus_iterator_write_ifp_extra(DBusMessageIter *iterator, + hash_table_t *table); + +#endif /* _IFP_IFACE_CUSTOM_TYPES_H_ */ diff --git a/src/responder/ifp/ifp_iface/sbus_ifp_arguments.c b/src/responder/ifp/ifp_iface/sbus_ifp_arguments.c new file mode 100644 index 0000000..031db83 --- /dev/null +++ b/src/responder/ifp/ifp_iface/sbus_ifp_arguments.c @@ -0,0 +1,397 @@ +/* + Generated by sbus code generator + + Copyright (C) 2017 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 <errno.h> +#include <stdint.h> +#include <talloc.h> +#include <stdbool.h> +#include <dbus/dbus.h> + +#include "sbus/interface/sbus_iterator_readers.h" +#include "sbus/interface/sbus_iterator_writers.h" +#include "responder/ifp/ifp_iface/sbus_ifp_arguments.h" + +errno_t _sbus_ifp_invoker_read_ao + (TALLOC_CTX *mem_ctx, + DBusMessageIter *iter, + struct _sbus_ifp_invoker_args_ao *args) +{ + errno_t ret; + + ret = sbus_iterator_read_ao(mem_ctx, iter, &args->arg0); + if (ret != EOK) { + return ret; + } + + return EOK; +} + +errno_t _sbus_ifp_invoker_write_ao + (DBusMessageIter *iter, + struct _sbus_ifp_invoker_args_ao *args) +{ + errno_t ret; + + ret = sbus_iterator_write_ao(iter, args->arg0); + if (ret != EOK) { + return ret; + } + + return EOK; +} + +errno_t _sbus_ifp_invoker_read_as + (TALLOC_CTX *mem_ctx, + DBusMessageIter *iter, + struct _sbus_ifp_invoker_args_as *args) +{ + errno_t ret; + + ret = sbus_iterator_read_as(mem_ctx, iter, &args->arg0); + if (ret != EOK) { + return ret; + } + + return EOK; +} + +errno_t _sbus_ifp_invoker_write_as + (DBusMessageIter *iter, + struct _sbus_ifp_invoker_args_as *args) +{ + errno_t ret; + + ret = sbus_iterator_write_as(iter, args->arg0); + if (ret != EOK) { + return ret; + } + + return EOK; +} + +errno_t _sbus_ifp_invoker_read_b + (TALLOC_CTX *mem_ctx, + DBusMessageIter *iter, + struct _sbus_ifp_invoker_args_b *args) +{ + errno_t ret; + + ret = sbus_iterator_read_b(iter, &args->arg0); + if (ret != EOK) { + return ret; + } + + return EOK; +} + +errno_t _sbus_ifp_invoker_write_b + (DBusMessageIter *iter, + struct _sbus_ifp_invoker_args_b *args) +{ + errno_t ret; + + ret = sbus_iterator_write_b(iter, args->arg0); + if (ret != EOK) { + return ret; + } + + return EOK; +} + +errno_t _sbus_ifp_invoker_read_ifp_extra + (TALLOC_CTX *mem_ctx, + DBusMessageIter *iter, + struct _sbus_ifp_invoker_args_ifp_extra *args) +{ + errno_t ret; + + ret = sbus_iterator_read_ifp_extra(mem_ctx, iter, &args->arg0); + if (ret != EOK) { + return ret; + } + + return EOK; +} + +errno_t _sbus_ifp_invoker_write_ifp_extra + (DBusMessageIter *iter, + struct _sbus_ifp_invoker_args_ifp_extra *args) +{ + errno_t ret; + + ret = sbus_iterator_write_ifp_extra(iter, args->arg0); + if (ret != EOK) { + return ret; + } + + return EOK; +} + +errno_t _sbus_ifp_invoker_read_o + (TALLOC_CTX *mem_ctx, + DBusMessageIter *iter, + struct _sbus_ifp_invoker_args_o *args) +{ + errno_t ret; + + ret = sbus_iterator_read_o(mem_ctx, iter, &args->arg0); + if (ret != EOK) { + return ret; + } + + return EOK; +} + +errno_t _sbus_ifp_invoker_write_o + (DBusMessageIter *iter, + struct _sbus_ifp_invoker_args_o *args) +{ + errno_t ret; + + ret = sbus_iterator_write_o(iter, args->arg0); + if (ret != EOK) { + return ret; + } + + return EOK; +} + +errno_t _sbus_ifp_invoker_read_s + (TALLOC_CTX *mem_ctx, + DBusMessageIter *iter, + struct _sbus_ifp_invoker_args_s *args) +{ + errno_t ret; + + ret = sbus_iterator_read_s(mem_ctx, iter, &args->arg0); + if (ret != EOK) { + return ret; + } + + return EOK; +} + +errno_t _sbus_ifp_invoker_write_s + (DBusMessageIter *iter, + struct _sbus_ifp_invoker_args_s *args) +{ + errno_t ret; + + ret = sbus_iterator_write_s(iter, args->arg0); + if (ret != EOK) { + return ret; + } + + return EOK; +} + +errno_t _sbus_ifp_invoker_read_sas + (TALLOC_CTX *mem_ctx, + DBusMessageIter *iter, + struct _sbus_ifp_invoker_args_sas *args) +{ + errno_t ret; + + ret = sbus_iterator_read_s(mem_ctx, iter, &args->arg0); + if (ret != EOK) { + return ret; + } + + ret = sbus_iterator_read_as(mem_ctx, iter, &args->arg1); + if (ret != EOK) { + return ret; + } + + return EOK; +} + +errno_t _sbus_ifp_invoker_write_sas + (DBusMessageIter *iter, + struct _sbus_ifp_invoker_args_sas *args) +{ + errno_t ret; + + ret = sbus_iterator_write_s(iter, args->arg0); + if (ret != EOK) { + return ret; + } + + ret = sbus_iterator_write_as(iter, args->arg1); + if (ret != EOK) { + return ret; + } + + return EOK; +} + +errno_t _sbus_ifp_invoker_read_ss + (TALLOC_CTX *mem_ctx, + DBusMessageIter *iter, + struct _sbus_ifp_invoker_args_ss *args) +{ + errno_t ret; + + ret = sbus_iterator_read_s(mem_ctx, iter, &args->arg0); + if (ret != EOK) { + return ret; + } + + ret = sbus_iterator_read_s(mem_ctx, iter, &args->arg1); + if (ret != EOK) { + return ret; + } + + return EOK; +} + +errno_t _sbus_ifp_invoker_write_ss + (DBusMessageIter *iter, + struct _sbus_ifp_invoker_args_ss *args) +{ + errno_t ret; + + ret = sbus_iterator_write_s(iter, args->arg0); + if (ret != EOK) { + return ret; + } + + ret = sbus_iterator_write_s(iter, args->arg1); + if (ret != EOK) { + return ret; + } + + return EOK; +} + +errno_t _sbus_ifp_invoker_read_ssu + (TALLOC_CTX *mem_ctx, + DBusMessageIter *iter, + struct _sbus_ifp_invoker_args_ssu *args) +{ + errno_t ret; + + ret = sbus_iterator_read_s(mem_ctx, iter, &args->arg0); + if (ret != EOK) { + return ret; + } + + ret = sbus_iterator_read_s(mem_ctx, iter, &args->arg1); + if (ret != EOK) { + return ret; + } + + ret = sbus_iterator_read_u(iter, &args->arg2); + if (ret != EOK) { + return ret; + } + + return EOK; +} + +errno_t _sbus_ifp_invoker_write_ssu + (DBusMessageIter *iter, + struct _sbus_ifp_invoker_args_ssu *args) +{ + errno_t ret; + + ret = sbus_iterator_write_s(iter, args->arg0); + if (ret != EOK) { + return ret; + } + + ret = sbus_iterator_write_s(iter, args->arg1); + if (ret != EOK) { + return ret; + } + + ret = sbus_iterator_write_u(iter, args->arg2); + if (ret != EOK) { + return ret; + } + + return EOK; +} + +errno_t _sbus_ifp_invoker_read_su + (TALLOC_CTX *mem_ctx, + DBusMessageIter *iter, + struct _sbus_ifp_invoker_args_su *args) +{ + errno_t ret; + + ret = sbus_iterator_read_s(mem_ctx, iter, &args->arg0); + if (ret != EOK) { + return ret; + } + + ret = sbus_iterator_read_u(iter, &args->arg1); + if (ret != EOK) { + return ret; + } + + return EOK; +} + +errno_t _sbus_ifp_invoker_write_su + (DBusMessageIter *iter, + struct _sbus_ifp_invoker_args_su *args) +{ + errno_t ret; + + ret = sbus_iterator_write_s(iter, args->arg0); + if (ret != EOK) { + return ret; + } + + ret = sbus_iterator_write_u(iter, args->arg1); + if (ret != EOK) { + return ret; + } + + return EOK; +} + +errno_t _sbus_ifp_invoker_read_u + (TALLOC_CTX *mem_ctx, + DBusMessageIter *iter, + struct _sbus_ifp_invoker_args_u *args) +{ + errno_t ret; + + ret = sbus_iterator_read_u(iter, &args->arg0); + if (ret != EOK) { + return ret; + } + + return EOK; +} + +errno_t _sbus_ifp_invoker_write_u + (DBusMessageIter *iter, + struct _sbus_ifp_invoker_args_u *args) +{ + errno_t ret; + + ret = sbus_iterator_write_u(iter, args->arg0); + if (ret != EOK) { + return ret; + } + + return EOK; +} diff --git a/src/responder/ifp/ifp_iface/sbus_ifp_arguments.h b/src/responder/ifp/ifp_iface/sbus_ifp_arguments.h new file mode 100644 index 0000000..4b88b78 --- /dev/null +++ b/src/responder/ifp/ifp_iface/sbus_ifp_arguments.h @@ -0,0 +1,201 @@ +/* + Generated by sbus code generator + + Copyright (C) 2017 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 _SBUS_IFP_ARGUMENTS_H_ +#define _SBUS_IFP_ARGUMENTS_H_ + +#include <errno.h> +#include <stdint.h> +#include <talloc.h> +#include <stdbool.h> +#include <dbus/dbus.h> + +#include "responder/ifp/ifp_iface/ifp_iface_types.h" + +struct _sbus_ifp_invoker_args_ao { + const char ** arg0; +}; + +errno_t +_sbus_ifp_invoker_read_ao + (TALLOC_CTX *mem_ctx, + DBusMessageIter *iter, + struct _sbus_ifp_invoker_args_ao *args); + +errno_t +_sbus_ifp_invoker_write_ao + (DBusMessageIter *iter, + struct _sbus_ifp_invoker_args_ao *args); + +struct _sbus_ifp_invoker_args_as { + const char ** arg0; +}; + +errno_t +_sbus_ifp_invoker_read_as + (TALLOC_CTX *mem_ctx, + DBusMessageIter *iter, + struct _sbus_ifp_invoker_args_as *args); + +errno_t +_sbus_ifp_invoker_write_as + (DBusMessageIter *iter, + struct _sbus_ifp_invoker_args_as *args); + +struct _sbus_ifp_invoker_args_b { + bool arg0; +}; + +errno_t +_sbus_ifp_invoker_read_b + (TALLOC_CTX *mem_ctx, + DBusMessageIter *iter, + struct _sbus_ifp_invoker_args_b *args); + +errno_t +_sbus_ifp_invoker_write_b + (DBusMessageIter *iter, + struct _sbus_ifp_invoker_args_b *args); + +struct _sbus_ifp_invoker_args_ifp_extra { + hash_table_t * arg0; +}; + +errno_t +_sbus_ifp_invoker_read_ifp_extra + (TALLOC_CTX *mem_ctx, + DBusMessageIter *iter, + struct _sbus_ifp_invoker_args_ifp_extra *args); + +errno_t +_sbus_ifp_invoker_write_ifp_extra + (DBusMessageIter *iter, + struct _sbus_ifp_invoker_args_ifp_extra *args); + +struct _sbus_ifp_invoker_args_o { + const char * arg0; +}; + +errno_t +_sbus_ifp_invoker_read_o + (TALLOC_CTX *mem_ctx, + DBusMessageIter *iter, + struct _sbus_ifp_invoker_args_o *args); + +errno_t +_sbus_ifp_invoker_write_o + (DBusMessageIter *iter, + struct _sbus_ifp_invoker_args_o *args); + +struct _sbus_ifp_invoker_args_s { + const char * arg0; +}; + +errno_t +_sbus_ifp_invoker_read_s + (TALLOC_CTX *mem_ctx, + DBusMessageIter *iter, + struct _sbus_ifp_invoker_args_s *args); + +errno_t +_sbus_ifp_invoker_write_s + (DBusMessageIter *iter, + struct _sbus_ifp_invoker_args_s *args); + +struct _sbus_ifp_invoker_args_sas { + const char * arg0; + const char ** arg1; +}; + +errno_t +_sbus_ifp_invoker_read_sas + (TALLOC_CTX *mem_ctx, + DBusMessageIter *iter, + struct _sbus_ifp_invoker_args_sas *args); + +errno_t +_sbus_ifp_invoker_write_sas + (DBusMessageIter *iter, + struct _sbus_ifp_invoker_args_sas *args); + +struct _sbus_ifp_invoker_args_ss { + const char * arg0; + const char * arg1; +}; + +errno_t +_sbus_ifp_invoker_read_ss + (TALLOC_CTX *mem_ctx, + DBusMessageIter *iter, + struct _sbus_ifp_invoker_args_ss *args); + +errno_t +_sbus_ifp_invoker_write_ss + (DBusMessageIter *iter, + struct _sbus_ifp_invoker_args_ss *args); + +struct _sbus_ifp_invoker_args_ssu { + const char * arg0; + const char * arg1; + uint32_t arg2; +}; + +errno_t +_sbus_ifp_invoker_read_ssu + (TALLOC_CTX *mem_ctx, + DBusMessageIter *iter, + struct _sbus_ifp_invoker_args_ssu *args); + +errno_t +_sbus_ifp_invoker_write_ssu + (DBusMessageIter *iter, + struct _sbus_ifp_invoker_args_ssu *args); + +struct _sbus_ifp_invoker_args_su { + const char * arg0; + uint32_t arg1; +}; + +errno_t +_sbus_ifp_invoker_read_su + (TALLOC_CTX *mem_ctx, + DBusMessageIter *iter, + struct _sbus_ifp_invoker_args_su *args); + +errno_t +_sbus_ifp_invoker_write_su + (DBusMessageIter *iter, + struct _sbus_ifp_invoker_args_su *args); + +struct _sbus_ifp_invoker_args_u { + uint32_t arg0; +}; + +errno_t +_sbus_ifp_invoker_read_u + (TALLOC_CTX *mem_ctx, + DBusMessageIter *iter, + struct _sbus_ifp_invoker_args_u *args); + +errno_t +_sbus_ifp_invoker_write_u + (DBusMessageIter *iter, + struct _sbus_ifp_invoker_args_u *args); + +#endif /* _SBUS_IFP_ARGUMENTS_H_ */ diff --git a/src/responder/ifp/ifp_iface/sbus_ifp_client_async.c b/src/responder/ifp/ifp_iface/sbus_ifp_client_async.c new file mode 100644 index 0000000..792061c --- /dev/null +++ b/src/responder/ifp/ifp_iface/sbus_ifp_client_async.c @@ -0,0 +1,30 @@ +/* + Generated by sbus code generator + + Copyright (C) 2017 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 <errno.h> +#include <talloc.h> +#include <tevent.h> +#include <dbus/dbus.h> + +#include "sbus/sbus_private.h" +#include "sbus/interface/sbus_iterator_readers.h" +#include "sbus/interface_dbus/sbus_dbus_client_async.h" +#include "responder/ifp/ifp_iface/sbus_ifp_arguments.h" +#include "responder/ifp/ifp_iface/sbus_ifp_keygens.h" +#include "responder/ifp/ifp_iface/sbus_ifp_client_properties.h" diff --git a/src/responder/ifp/ifp_iface/sbus_ifp_client_async.h b/src/responder/ifp/ifp_iface/sbus_ifp_client_async.h new file mode 100644 index 0000000..eb7844b --- /dev/null +++ b/src/responder/ifp/ifp_iface/sbus_ifp_client_async.h @@ -0,0 +1,31 @@ +/* + Generated by sbus code generator + + Copyright (C) 2017 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 _SBUS_IFP_CLIENT_ASYNC_H_ +#define _SBUS_IFP_CLIENT_ASYNC_H_ + +#include <errno.h> +#include <talloc.h> +#include <tevent.h> + +#include "sbus/sbus.h" +#include "responder/ifp/ifp_iface/sbus_ifp_client_properties.h" +#include "responder/ifp/ifp_iface/ifp_iface_types.h" + +#endif /* _SBUS_IFP_CLIENT_ASYNC_H_ */ diff --git a/src/responder/ifp/ifp_iface/sbus_ifp_client_properties.h b/src/responder/ifp/ifp_iface/sbus_ifp_client_properties.h new file mode 100644 index 0000000..deb3ade --- /dev/null +++ b/src/responder/ifp/ifp_iface/sbus_ifp_client_properties.h @@ -0,0 +1,180 @@ +/* + Generated by sbus code generator + + Copyright (C) 2017 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 _SBUS_IFP_CLIENT_PROPERTIES_H_ +#define _SBUS_IFP_CLIENT_PROPERTIES_H_ + +#include <stdint.h> +#include <stdbool.h> + +#include "responder/ifp/ifp_iface/ifp_iface_types.h" + +struct sbus_all_ifp_components { + struct { + bool is_set; + uint32_t value; + } debug_level; + struct { + bool is_set; + bool value; + } enabled; + struct { + bool is_set; + const char * value; + } name; + struct { + bool is_set; + const char ** value; + } providers; + struct { + bool is_set; + const char * value; + } type; +}; + +struct sbus_all_ifp_domains { + struct { + bool is_set; + const char ** value; + } backup_servers; + struct { + bool is_set; + bool value; + } enumerable; + struct { + bool is_set; + const char * value; + } forest; + struct { + bool is_set; + const char * value; + } fully_qualified_name_format; + struct { + bool is_set; + const char * value; + } login_format; + struct { + bool is_set; + uint32_t value; + } max_id; + struct { + bool is_set; + uint32_t value; + } min_id; + struct { + bool is_set; + const char * value; + } name; + struct { + bool is_set; + const char * value; + } parent_domain; + struct { + bool is_set; + const char ** value; + } primary_servers; + struct { + bool is_set; + const char * value; + } provider; + struct { + bool is_set; + const char * value; + } realm; + struct { + bool is_set; + bool value; + } subdomain; + struct { + bool is_set; + bool value; + } use_fully_qualified_names; +}; + +struct sbus_all_ifp_group { + struct { + bool is_set; + uint32_t value; + } gidNumber; + struct { + bool is_set; + const char ** value; + } groups; + struct { + bool is_set; + const char * value; + } name; + struct { + bool is_set; + const char * value; + } uniqueID; + struct { + bool is_set; + const char ** value; + } users; +}; + +struct sbus_all_ifp_user { + struct { + bool is_set; + const char * value; + } domain; + struct { + bool is_set; + const char * value; + } domainname; + struct { + bool is_set; + hash_table_t * value; + } extraAttributes; + struct { + bool is_set; + const char * value; + } gecos; + struct { + bool is_set; + uint32_t value; + } gidNumber; + struct { + bool is_set; + const char ** value; + } groups; + struct { + bool is_set; + const char * value; + } homeDirectory; + struct { + bool is_set; + const char * value; + } loginShell; + struct { + bool is_set; + const char * value; + } name; + struct { + bool is_set; + uint32_t value; + } uidNumber; + struct { + bool is_set; + const char * value; + } uniqueID; +}; + +#endif /* _SBUS_IFP_CLIENT_PROPERTIES_H_ */ diff --git a/src/responder/ifp/ifp_iface/sbus_ifp_client_sync.c b/src/responder/ifp/ifp_iface/sbus_ifp_client_sync.c new file mode 100644 index 0000000..e450233 --- /dev/null +++ b/src/responder/ifp/ifp_iface/sbus_ifp_client_sync.c @@ -0,0 +1,2304 @@ +/* + Generated by sbus code generator + + Copyright (C) 2017 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 <errno.h> +#include <talloc.h> +#include <dbus/dbus.h> + +#include "sbus/sbus_sync.h" +#include "sbus/sbus_sync_private.h" +#include "sbus/sbus_message.h" +#include "sbus/interface/sbus_iterator_readers.h" +#include "sbus/interface_dbus/sbus_dbus_client_sync.h" +#include "responder/ifp/ifp_iface/sbus_ifp_arguments.h" +#include "responder/ifp/ifp_iface/sbus_ifp_client_properties.h" + +static errno_t +sbus_method_in__out_ + (struct sbus_sync_connection *conn, + const char *bus, + const char *path, + const char *iface, + const char *method) +{ + TALLOC_CTX *tmp_ctx; + DBusMessage *reply; + errno_t ret; + + tmp_ctx = talloc_new(NULL); + if (tmp_ctx == NULL) { + DEBUG(SSSDBG_FATAL_FAILURE, "Out of memory!\n"); + return ENOMEM; + } + + + ret = sbus_sync_call_method(tmp_ctx, conn, NULL, NULL, + bus, path, iface, method, NULL, &reply); + if (ret != EOK) { + goto done; + } + + ret = EOK; + +done: + talloc_free(tmp_ctx); + + return ret; +} + +static errno_t +sbus_method_in__out_ao + (TALLOC_CTX *mem_ctx, + struct sbus_sync_connection *conn, + const char *bus, + const char *path, + const char *iface, + const char *method, + const char *** _arg0) +{ + TALLOC_CTX *tmp_ctx; + struct _sbus_ifp_invoker_args_ao *out; + DBusMessage *reply; + errno_t ret; + + tmp_ctx = talloc_new(NULL); + if (tmp_ctx == NULL) { + DEBUG(SSSDBG_FATAL_FAILURE, "Out of memory!\n"); + return ENOMEM; + } + + out = talloc_zero(tmp_ctx, struct _sbus_ifp_invoker_args_ao); + if (out == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, + "Unable to allocate space for output parameters!\n"); + ret = ENOMEM; + goto done; + } + + + ret = sbus_sync_call_method(tmp_ctx, conn, NULL, NULL, + bus, path, iface, method, NULL, &reply); + if (ret != EOK) { + goto done; + } + + ret = sbus_read_output(out, reply, (sbus_invoker_reader_fn)_sbus_ifp_invoker_read_ao, out); + if (ret != EOK) { + goto done; + } + + *_arg0 = talloc_steal(mem_ctx, out->arg0); + + ret = EOK; + +done: + talloc_free(tmp_ctx); + + return ret; +} + +static errno_t +sbus_method_in__out_as + (TALLOC_CTX *mem_ctx, + struct sbus_sync_connection *conn, + const char *bus, + const char *path, + const char *iface, + const char *method, + const char *** _arg0) +{ + TALLOC_CTX *tmp_ctx; + struct _sbus_ifp_invoker_args_as *out; + DBusMessage *reply; + errno_t ret; + + tmp_ctx = talloc_new(NULL); + if (tmp_ctx == NULL) { + DEBUG(SSSDBG_FATAL_FAILURE, "Out of memory!\n"); + return ENOMEM; + } + + out = talloc_zero(tmp_ctx, struct _sbus_ifp_invoker_args_as); + if (out == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, + "Unable to allocate space for output parameters!\n"); + ret = ENOMEM; + goto done; + } + + + ret = sbus_sync_call_method(tmp_ctx, conn, NULL, NULL, + bus, path, iface, method, NULL, &reply); + if (ret != EOK) { + goto done; + } + + ret = sbus_read_output(out, reply, (sbus_invoker_reader_fn)_sbus_ifp_invoker_read_as, out); + if (ret != EOK) { + goto done; + } + + *_arg0 = talloc_steal(mem_ctx, out->arg0); + + ret = EOK; + +done: + talloc_free(tmp_ctx); + + return ret; +} + +static errno_t +sbus_method_in__out_b + (struct sbus_sync_connection *conn, + const char *bus, + const char *path, + const char *iface, + const char *method, + bool* _arg0) +{ + TALLOC_CTX *tmp_ctx; + struct _sbus_ifp_invoker_args_b *out; + DBusMessage *reply; + errno_t ret; + + tmp_ctx = talloc_new(NULL); + if (tmp_ctx == NULL) { + DEBUG(SSSDBG_FATAL_FAILURE, "Out of memory!\n"); + return ENOMEM; + } + + out = talloc_zero(tmp_ctx, struct _sbus_ifp_invoker_args_b); + if (out == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, + "Unable to allocate space for output parameters!\n"); + ret = ENOMEM; + goto done; + } + + + ret = sbus_sync_call_method(tmp_ctx, conn, NULL, NULL, + bus, path, iface, method, NULL, &reply); + if (ret != EOK) { + goto done; + } + + ret = sbus_read_output(out, reply, (sbus_invoker_reader_fn)_sbus_ifp_invoker_read_b, out); + if (ret != EOK) { + goto done; + } + + *_arg0 = out->arg0; + + ret = EOK; + +done: + talloc_free(tmp_ctx); + + return ret; +} + +static errno_t +sbus_method_in__out_o + (TALLOC_CTX *mem_ctx, + struct sbus_sync_connection *conn, + const char *bus, + const char *path, + const char *iface, + const char *method, + const char ** _arg0) +{ + TALLOC_CTX *tmp_ctx; + struct _sbus_ifp_invoker_args_o *out; + DBusMessage *reply; + errno_t ret; + + tmp_ctx = talloc_new(NULL); + if (tmp_ctx == NULL) { + DEBUG(SSSDBG_FATAL_FAILURE, "Out of memory!\n"); + return ENOMEM; + } + + out = talloc_zero(tmp_ctx, struct _sbus_ifp_invoker_args_o); + if (out == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, + "Unable to allocate space for output parameters!\n"); + ret = ENOMEM; + goto done; + } + + + ret = sbus_sync_call_method(tmp_ctx, conn, NULL, NULL, + bus, path, iface, method, NULL, &reply); + if (ret != EOK) { + goto done; + } + + ret = sbus_read_output(out, reply, (sbus_invoker_reader_fn)_sbus_ifp_invoker_read_o, out); + if (ret != EOK) { + goto done; + } + + *_arg0 = talloc_steal(mem_ctx, out->arg0); + + ret = EOK; + +done: + talloc_free(tmp_ctx); + + return ret; +} + +static errno_t +sbus_method_in_s_out_ao + (TALLOC_CTX *mem_ctx, + struct sbus_sync_connection *conn, + const char *bus, + const char *path, + const char *iface, + const char *method, + const char * arg0, + const char *** _arg0) +{ + TALLOC_CTX *tmp_ctx; + struct _sbus_ifp_invoker_args_s in; + struct _sbus_ifp_invoker_args_ao *out; + DBusMessage *reply; + errno_t ret; + + tmp_ctx = talloc_new(NULL); + if (tmp_ctx == NULL) { + DEBUG(SSSDBG_FATAL_FAILURE, "Out of memory!\n"); + return ENOMEM; + } + + out = talloc_zero(tmp_ctx, struct _sbus_ifp_invoker_args_ao); + if (out == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, + "Unable to allocate space for output parameters!\n"); + ret = ENOMEM; + goto done; + } + + in.arg0 = arg0; + + ret = sbus_sync_call_method(tmp_ctx, conn, NULL, + (sbus_invoker_writer_fn)_sbus_ifp_invoker_write_s, + bus, path, iface, method, &in, &reply); + if (ret != EOK) { + goto done; + } + + ret = sbus_read_output(out, reply, (sbus_invoker_reader_fn)_sbus_ifp_invoker_read_ao, out); + if (ret != EOK) { + goto done; + } + + *_arg0 = talloc_steal(mem_ctx, out->arg0); + + ret = EOK; + +done: + talloc_free(tmp_ctx); + + return ret; +} + +static errno_t +sbus_method_in_s_out_as + (TALLOC_CTX *mem_ctx, + struct sbus_sync_connection *conn, + const char *bus, + const char *path, + const char *iface, + const char *method, + const char * arg0, + const char *** _arg0) +{ + TALLOC_CTX *tmp_ctx; + struct _sbus_ifp_invoker_args_s in; + struct _sbus_ifp_invoker_args_as *out; + DBusMessage *reply; + errno_t ret; + + tmp_ctx = talloc_new(NULL); + if (tmp_ctx == NULL) { + DEBUG(SSSDBG_FATAL_FAILURE, "Out of memory!\n"); + return ENOMEM; + } + + out = talloc_zero(tmp_ctx, struct _sbus_ifp_invoker_args_as); + if (out == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, + "Unable to allocate space for output parameters!\n"); + ret = ENOMEM; + goto done; + } + + in.arg0 = arg0; + + ret = sbus_sync_call_method(tmp_ctx, conn, NULL, + (sbus_invoker_writer_fn)_sbus_ifp_invoker_write_s, + bus, path, iface, method, &in, &reply); + if (ret != EOK) { + goto done; + } + + ret = sbus_read_output(out, reply, (sbus_invoker_reader_fn)_sbus_ifp_invoker_read_as, out); + if (ret != EOK) { + goto done; + } + + *_arg0 = talloc_steal(mem_ctx, out->arg0); + + ret = EOK; + +done: + talloc_free(tmp_ctx); + + return ret; +} + +static errno_t +sbus_method_in_s_out_o + (TALLOC_CTX *mem_ctx, + struct sbus_sync_connection *conn, + const char *bus, + const char *path, + const char *iface, + const char *method, + const char * arg0, + const char ** _arg0) +{ + TALLOC_CTX *tmp_ctx; + struct _sbus_ifp_invoker_args_s in; + struct _sbus_ifp_invoker_args_o *out; + DBusMessage *reply; + errno_t ret; + + tmp_ctx = talloc_new(NULL); + if (tmp_ctx == NULL) { + DEBUG(SSSDBG_FATAL_FAILURE, "Out of memory!\n"); + return ENOMEM; + } + + out = talloc_zero(tmp_ctx, struct _sbus_ifp_invoker_args_o); + if (out == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, + "Unable to allocate space for output parameters!\n"); + ret = ENOMEM; + goto done; + } + + in.arg0 = arg0; + + ret = sbus_sync_call_method(tmp_ctx, conn, NULL, + (sbus_invoker_writer_fn)_sbus_ifp_invoker_write_s, + bus, path, iface, method, &in, &reply); + if (ret != EOK) { + goto done; + } + + ret = sbus_read_output(out, reply, (sbus_invoker_reader_fn)_sbus_ifp_invoker_read_o, out); + if (ret != EOK) { + goto done; + } + + *_arg0 = talloc_steal(mem_ctx, out->arg0); + + ret = EOK; + +done: + talloc_free(tmp_ctx); + + return ret; +} + +static errno_t +sbus_method_in_s_out_s + (TALLOC_CTX *mem_ctx, + struct sbus_sync_connection *conn, + const char *bus, + const char *path, + const char *iface, + const char *method, + const char * arg0, + const char ** _arg0) +{ + TALLOC_CTX *tmp_ctx; + struct _sbus_ifp_invoker_args_s in; + struct _sbus_ifp_invoker_args_s *out; + DBusMessage *reply; + errno_t ret; + + tmp_ctx = talloc_new(NULL); + if (tmp_ctx == NULL) { + DEBUG(SSSDBG_FATAL_FAILURE, "Out of memory!\n"); + return ENOMEM; + } + + out = talloc_zero(tmp_ctx, struct _sbus_ifp_invoker_args_s); + if (out == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, + "Unable to allocate space for output parameters!\n"); + ret = ENOMEM; + goto done; + } + + in.arg0 = arg0; + + ret = sbus_sync_call_method(tmp_ctx, conn, NULL, + (sbus_invoker_writer_fn)_sbus_ifp_invoker_write_s, + bus, path, iface, method, &in, &reply); + if (ret != EOK) { + goto done; + } + + ret = sbus_read_output(out, reply, (sbus_invoker_reader_fn)_sbus_ifp_invoker_read_s, out); + if (ret != EOK) { + goto done; + } + + *_arg0 = talloc_steal(mem_ctx, out->arg0); + + ret = EOK; + +done: + talloc_free(tmp_ctx); + + return ret; +} + +static errno_t +sbus_method_in_sas_out_raw + (TALLOC_CTX *mem_ctx, + struct sbus_sync_connection *conn, + const char *bus, + const char *path, + const char *iface, + const char *method, + const char * arg0, + const char ** arg1, + DBusMessage **_reply) +{ + TALLOC_CTX *tmp_ctx; + struct _sbus_ifp_invoker_args_sas in; + DBusMessage *reply; + errno_t ret; + + tmp_ctx = talloc_new(NULL); + if (tmp_ctx == NULL) { + DEBUG(SSSDBG_FATAL_FAILURE, "Out of memory!\n"); + return ENOMEM; + } + + in.arg0 = arg0; + in.arg1 = arg1; + + ret = sbus_sync_call_method(tmp_ctx, conn, NULL, + (sbus_invoker_writer_fn)_sbus_ifp_invoker_write_sas, + bus, path, iface, method, &in, &reply); + if (ret != EOK) { + goto done; + } + + /* Bounded reference cannot be unreferenced with dbus_message_unref. + * For that reason we do not allow NULL memory context as it would + * result in leaking the message memory. */ + if (mem_ctx == NULL) { + ret = EINVAL; + goto done; + } + + ret = sbus_message_bound_steal(mem_ctx, reply); + if (ret != EOK) { + DEBUG(SSSDBG_CRIT_FAILURE, "Unable to steal message [%d]: %s\n", + ret, sss_strerror(ret)); + goto done; + } + + *_reply = reply; + + ret = EOK; + +done: + talloc_free(tmp_ctx); + + return ret; +} + +static errno_t +sbus_method_in_ss_out_o + (TALLOC_CTX *mem_ctx, + struct sbus_sync_connection *conn, + const char *bus, + const char *path, + const char *iface, + const char *method, + const char * arg0, + const char * arg1, + const char ** _arg0) +{ + TALLOC_CTX *tmp_ctx; + struct _sbus_ifp_invoker_args_ss in; + struct _sbus_ifp_invoker_args_o *out; + DBusMessage *reply; + errno_t ret; + + tmp_ctx = talloc_new(NULL); + if (tmp_ctx == NULL) { + DEBUG(SSSDBG_FATAL_FAILURE, "Out of memory!\n"); + return ENOMEM; + } + + out = talloc_zero(tmp_ctx, struct _sbus_ifp_invoker_args_o); + if (out == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, + "Unable to allocate space for output parameters!\n"); + ret = ENOMEM; + goto done; + } + + in.arg0 = arg0; + in.arg1 = arg1; + + ret = sbus_sync_call_method(tmp_ctx, conn, NULL, + (sbus_invoker_writer_fn)_sbus_ifp_invoker_write_ss, + bus, path, iface, method, &in, &reply); + if (ret != EOK) { + goto done; + } + + ret = sbus_read_output(out, reply, (sbus_invoker_reader_fn)_sbus_ifp_invoker_read_o, out); + if (ret != EOK) { + goto done; + } + + *_arg0 = talloc_steal(mem_ctx, out->arg0); + + ret = EOK; + +done: + talloc_free(tmp_ctx); + + return ret; +} + +static errno_t +sbus_method_in_ssu_out_ao + (TALLOC_CTX *mem_ctx, + struct sbus_sync_connection *conn, + const char *bus, + const char *path, + const char *iface, + const char *method, + const char * arg0, + const char * arg1, + uint32_t arg2, + const char *** _arg0) +{ + TALLOC_CTX *tmp_ctx; + struct _sbus_ifp_invoker_args_ssu in; + struct _sbus_ifp_invoker_args_ao *out; + DBusMessage *reply; + errno_t ret; + + tmp_ctx = talloc_new(NULL); + if (tmp_ctx == NULL) { + DEBUG(SSSDBG_FATAL_FAILURE, "Out of memory!\n"); + return ENOMEM; + } + + out = talloc_zero(tmp_ctx, struct _sbus_ifp_invoker_args_ao); + if (out == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, + "Unable to allocate space for output parameters!\n"); + ret = ENOMEM; + goto done; + } + + in.arg0 = arg0; + in.arg1 = arg1; + in.arg2 = arg2; + + ret = sbus_sync_call_method(tmp_ctx, conn, NULL, + (sbus_invoker_writer_fn)_sbus_ifp_invoker_write_ssu, + bus, path, iface, method, &in, &reply); + if (ret != EOK) { + goto done; + } + + ret = sbus_read_output(out, reply, (sbus_invoker_reader_fn)_sbus_ifp_invoker_read_ao, out); + if (ret != EOK) { + goto done; + } + + *_arg0 = talloc_steal(mem_ctx, out->arg0); + + ret = EOK; + +done: + talloc_free(tmp_ctx); + + return ret; +} + +static errno_t +sbus_method_in_su_out_ao + (TALLOC_CTX *mem_ctx, + struct sbus_sync_connection *conn, + const char *bus, + const char *path, + const char *iface, + const char *method, + const char * arg0, + uint32_t arg1, + const char *** _arg0) +{ + TALLOC_CTX *tmp_ctx; + struct _sbus_ifp_invoker_args_su in; + struct _sbus_ifp_invoker_args_ao *out; + DBusMessage *reply; + errno_t ret; + + tmp_ctx = talloc_new(NULL); + if (tmp_ctx == NULL) { + DEBUG(SSSDBG_FATAL_FAILURE, "Out of memory!\n"); + return ENOMEM; + } + + out = talloc_zero(tmp_ctx, struct _sbus_ifp_invoker_args_ao); + if (out == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, + "Unable to allocate space for output parameters!\n"); + ret = ENOMEM; + goto done; + } + + in.arg0 = arg0; + in.arg1 = arg1; + + ret = sbus_sync_call_method(tmp_ctx, conn, NULL, + (sbus_invoker_writer_fn)_sbus_ifp_invoker_write_su, + bus, path, iface, method, &in, &reply); + if (ret != EOK) { + goto done; + } + + ret = sbus_read_output(out, reply, (sbus_invoker_reader_fn)_sbus_ifp_invoker_read_ao, out); + if (ret != EOK) { + goto done; + } + + *_arg0 = talloc_steal(mem_ctx, out->arg0); + + ret = EOK; + +done: + talloc_free(tmp_ctx); + + return ret; +} + +static errno_t +sbus_method_in_u_out_o + (TALLOC_CTX *mem_ctx, + struct sbus_sync_connection *conn, + const char *bus, + const char *path, + const char *iface, + const char *method, + uint32_t arg0, + const char ** _arg0) +{ + TALLOC_CTX *tmp_ctx; + struct _sbus_ifp_invoker_args_u in; + struct _sbus_ifp_invoker_args_o *out; + DBusMessage *reply; + errno_t ret; + + tmp_ctx = talloc_new(NULL); + if (tmp_ctx == NULL) { + DEBUG(SSSDBG_FATAL_FAILURE, "Out of memory!\n"); + return ENOMEM; + } + + out = talloc_zero(tmp_ctx, struct _sbus_ifp_invoker_args_o); + if (out == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, + "Unable to allocate space for output parameters!\n"); + ret = ENOMEM; + goto done; + } + + in.arg0 = arg0; + + ret = sbus_sync_call_method(tmp_ctx, conn, NULL, + (sbus_invoker_writer_fn)_sbus_ifp_invoker_write_u, + bus, path, iface, method, &in, &reply); + if (ret != EOK) { + goto done; + } + + ret = sbus_read_output(out, reply, (sbus_invoker_reader_fn)_sbus_ifp_invoker_read_o, out); + if (ret != EOK) { + goto done; + } + + *_arg0 = talloc_steal(mem_ctx, out->arg0); + + ret = EOK; + +done: + talloc_free(tmp_ctx); + + return ret; +} + +errno_t +sbus_call_ifp_FindBackendByName + (TALLOC_CTX *mem_ctx, + struct sbus_sync_connection *conn, + const char *busname, + const char *object_path, + const char * arg_name, + const char ** _arg_backend) +{ + return sbus_method_in_s_out_o(mem_ctx, conn, + busname, object_path, "org.freedesktop.sssd.infopipe", "FindBackendByName", arg_name, + _arg_backend); +} + +errno_t +sbus_call_ifp_FindDomainByName + (TALLOC_CTX *mem_ctx, + struct sbus_sync_connection *conn, + const char *busname, + const char *object_path, + const char * arg_name, + const char ** _arg_domain) +{ + return sbus_method_in_s_out_o(mem_ctx, conn, + busname, object_path, "org.freedesktop.sssd.infopipe", "FindDomainByName", arg_name, + _arg_domain); +} + +errno_t +sbus_call_ifp_FindMonitor + (TALLOC_CTX *mem_ctx, + struct sbus_sync_connection *conn, + const char *busname, + const char *object_path, + const char ** _arg_monitor) +{ + return sbus_method_in__out_o(mem_ctx, conn, + busname, object_path, "org.freedesktop.sssd.infopipe", "FindMonitor", + _arg_monitor); +} + +errno_t +sbus_call_ifp_FindResponderByName + (TALLOC_CTX *mem_ctx, + struct sbus_sync_connection *conn, + const char *busname, + const char *object_path, + const char * arg_name, + const char ** _arg_responder) +{ + return sbus_method_in_s_out_o(mem_ctx, conn, + busname, object_path, "org.freedesktop.sssd.infopipe", "FindResponderByName", arg_name, + _arg_responder); +} + +errno_t +sbus_call_ifp_GetUserAttr + (TALLOC_CTX *mem_ctx, + struct sbus_sync_connection *conn, + const char *busname, + const char *object_path, + const char * arg_user, + const char ** arg_attr, + DBusMessage **_reply) +{ + return sbus_method_in_sas_out_raw(mem_ctx, conn, + busname, object_path, "org.freedesktop.sssd.infopipe", "GetUserAttr", arg_user, arg_attr, + _reply); +} + +errno_t +sbus_call_ifp_GetUserGroups + (TALLOC_CTX *mem_ctx, + struct sbus_sync_connection *conn, + const char *busname, + const char *object_path, + const char * arg_user, + const char *** _arg_values) +{ + return sbus_method_in_s_out_as(mem_ctx, conn, + busname, object_path, "org.freedesktop.sssd.infopipe", "GetUserGroups", arg_user, + _arg_values); +} + +errno_t +sbus_call_ifp_ListBackends + (TALLOC_CTX *mem_ctx, + struct sbus_sync_connection *conn, + const char *busname, + const char *object_path, + const char *** _arg_backends) +{ + return sbus_method_in__out_ao(mem_ctx, conn, + busname, object_path, "org.freedesktop.sssd.infopipe", "ListBackends", + _arg_backends); +} + +errno_t +sbus_call_ifp_ListComponents + (TALLOC_CTX *mem_ctx, + struct sbus_sync_connection *conn, + const char *busname, + const char *object_path, + const char *** _arg_components) +{ + return sbus_method_in__out_ao(mem_ctx, conn, + busname, object_path, "org.freedesktop.sssd.infopipe", "ListComponents", + _arg_components); +} + +errno_t +sbus_call_ifp_ListDomains + (TALLOC_CTX *mem_ctx, + struct sbus_sync_connection *conn, + const char *busname, + const char *object_path, + const char *** _arg_domain) +{ + return sbus_method_in__out_ao(mem_ctx, conn, + busname, object_path, "org.freedesktop.sssd.infopipe", "ListDomains", + _arg_domain); +} + +errno_t +sbus_call_ifp_ListResponders + (TALLOC_CTX *mem_ctx, + struct sbus_sync_connection *conn, + const char *busname, + const char *object_path, + const char *** _arg_responders) +{ + return sbus_method_in__out_ao(mem_ctx, conn, + busname, object_path, "org.freedesktop.sssd.infopipe", "ListResponders", + _arg_responders); +} + +errno_t +sbus_call_ifp_Ping + (TALLOC_CTX *mem_ctx, + struct sbus_sync_connection *conn, + const char *busname, + const char *object_path, + const char * arg_ping, + const char ** _arg_pong) +{ + return sbus_method_in_s_out_s(mem_ctx, conn, + busname, object_path, "org.freedesktop.sssd.infopipe", "Ping", arg_ping, + _arg_pong); +} + +errno_t +sbus_call_ifp_cache_List + (TALLOC_CTX *mem_ctx, + struct sbus_sync_connection *conn, + const char *busname, + const char *object_path, + const char *** _arg_result) +{ + return sbus_method_in__out_ao(mem_ctx, conn, + busname, object_path, "org.freedesktop.sssd.infopipe.Cache", "List", + _arg_result); +} + +errno_t +sbus_call_ifp_cache_ListByDomain + (TALLOC_CTX *mem_ctx, + struct sbus_sync_connection *conn, + const char *busname, + const char *object_path, + const char * arg_domain_name, + const char *** _arg_result) +{ + return sbus_method_in_s_out_ao(mem_ctx, conn, + busname, object_path, "org.freedesktop.sssd.infopipe.Cache", "ListByDomain", arg_domain_name, + _arg_result); +} + +errno_t +sbus_call_ifp_cache_object_Remove + (struct sbus_sync_connection *conn, + const char *busname, + const char *object_path, + bool* _arg_result) +{ + return sbus_method_in__out_b(conn, + busname, object_path, "org.freedesktop.sssd.infopipe.Cache.Object", "Remove", + _arg_result); +} + +errno_t +sbus_call_ifp_cache_object_Store + (struct sbus_sync_connection *conn, + const char *busname, + const char *object_path, + bool* _arg_result) +{ + return sbus_method_in__out_b(conn, + busname, object_path, "org.freedesktop.sssd.infopipe.Cache.Object", "Store", + _arg_result); +} + +errno_t +sbus_call_ifp_domain_ActiveServer + (TALLOC_CTX *mem_ctx, + struct sbus_sync_connection *conn, + const char *busname, + const char *object_path, + const char * arg_service, + const char ** _arg_server) +{ + return sbus_method_in_s_out_s(mem_ctx, conn, + busname, object_path, "org.freedesktop.sssd.infopipe.Domains.Domain", "ActiveServer", arg_service, + _arg_server); +} + +errno_t +sbus_call_ifp_domain_IsOnline + (struct sbus_sync_connection *conn, + const char *busname, + const char *object_path, + bool* _arg_status) +{ + return sbus_method_in__out_b(conn, + busname, object_path, "org.freedesktop.sssd.infopipe.Domains.Domain", "IsOnline", + _arg_status); +} + +errno_t +sbus_call_ifp_domain_ListServers + (TALLOC_CTX *mem_ctx, + struct sbus_sync_connection *conn, + const char *busname, + const char *object_path, + const char * arg_service_name, + const char *** _arg_servers) +{ + return sbus_method_in_s_out_as(mem_ctx, conn, + busname, object_path, "org.freedesktop.sssd.infopipe.Domains.Domain", "ListServers", arg_service_name, + _arg_servers); +} + +errno_t +sbus_call_ifp_domain_ListServices + (TALLOC_CTX *mem_ctx, + struct sbus_sync_connection *conn, + const char *busname, + const char *object_path, + const char *** _arg_services) +{ + return sbus_method_in__out_as(mem_ctx, conn, + busname, object_path, "org.freedesktop.sssd.infopipe.Domains.Domain", "ListServices", + _arg_services); +} + +errno_t +sbus_call_ifp_domain_RefreshAccessRules + (struct sbus_sync_connection *conn, + const char *busname, + const char *object_path) +{ + return sbus_method_in__out_(conn, + busname, object_path, "org.freedesktop.sssd.infopipe.Domains.Domain", "RefreshAccessRules"); +} + +errno_t +sbus_call_ifp_groups_FindByID + (TALLOC_CTX *mem_ctx, + struct sbus_sync_connection *conn, + const char *busname, + const char *object_path, + uint32_t arg_id, + const char ** _arg_result) +{ + return sbus_method_in_u_out_o(mem_ctx, conn, + busname, object_path, "org.freedesktop.sssd.infopipe.Groups", "FindByID", arg_id, + _arg_result); +} + +errno_t +sbus_call_ifp_groups_FindByName + (TALLOC_CTX *mem_ctx, + struct sbus_sync_connection *conn, + const char *busname, + const char *object_path, + const char * arg_name, + const char ** _arg_result) +{ + return sbus_method_in_s_out_o(mem_ctx, conn, + busname, object_path, "org.freedesktop.sssd.infopipe.Groups", "FindByName", arg_name, + _arg_result); +} + +errno_t +sbus_call_ifp_groups_ListByDomainAndName + (TALLOC_CTX *mem_ctx, + struct sbus_sync_connection *conn, + const char *busname, + const char *object_path, + const char * arg_domain_name, + const char * arg_name_filter, + uint32_t arg_limit, + const char *** _arg_result) +{ + return sbus_method_in_ssu_out_ao(mem_ctx, conn, + busname, object_path, "org.freedesktop.sssd.infopipe.Groups", "ListByDomainAndName", arg_domain_name, arg_name_filter, arg_limit, + _arg_result); +} + +errno_t +sbus_call_ifp_groups_ListByName + (TALLOC_CTX *mem_ctx, + struct sbus_sync_connection *conn, + const char *busname, + const char *object_path, + const char * arg_name_filter, + uint32_t arg_limit, + const char *** _arg_result) +{ + return sbus_method_in_su_out_ao(mem_ctx, conn, + busname, object_path, "org.freedesktop.sssd.infopipe.Groups", "ListByName", arg_name_filter, arg_limit, + _arg_result); +} + +errno_t +sbus_call_ifp_group_UpdateMemberList + (struct sbus_sync_connection *conn, + const char *busname, + const char *object_path) +{ + return sbus_method_in__out_(conn, + busname, object_path, "org.freedesktop.sssd.infopipe.Groups.Group", "UpdateMemberList"); +} + +errno_t +sbus_call_ifp_users_FindByCertificate + (TALLOC_CTX *mem_ctx, + struct sbus_sync_connection *conn, + const char *busname, + const char *object_path, + const char * arg_pem_cert, + const char ** _arg_result) +{ + return sbus_method_in_s_out_o(mem_ctx, conn, + busname, object_path, "org.freedesktop.sssd.infopipe.Users", "FindByCertificate", arg_pem_cert, + _arg_result); +} + +errno_t +sbus_call_ifp_users_FindByID + (TALLOC_CTX *mem_ctx, + struct sbus_sync_connection *conn, + const char *busname, + const char *object_path, + uint32_t arg_id, + const char ** _arg_result) +{ + return sbus_method_in_u_out_o(mem_ctx, conn, + busname, object_path, "org.freedesktop.sssd.infopipe.Users", "FindByID", arg_id, + _arg_result); +} + +errno_t +sbus_call_ifp_users_FindByName + (TALLOC_CTX *mem_ctx, + struct sbus_sync_connection *conn, + const char *busname, + const char *object_path, + const char * arg_name, + const char ** _arg_result) +{ + return sbus_method_in_s_out_o(mem_ctx, conn, + busname, object_path, "org.freedesktop.sssd.infopipe.Users", "FindByName", arg_name, + _arg_result); +} + +errno_t +sbus_call_ifp_users_FindByNameAndCertificate + (TALLOC_CTX *mem_ctx, + struct sbus_sync_connection *conn, + const char *busname, + const char *object_path, + const char * arg_name, + const char * arg_pem_cert, + const char ** _arg_result) +{ + return sbus_method_in_ss_out_o(mem_ctx, conn, + busname, object_path, "org.freedesktop.sssd.infopipe.Users", "FindByNameAndCertificate", arg_name, arg_pem_cert, + _arg_result); +} + +errno_t +sbus_call_ifp_users_FindByValidCertificate + (TALLOC_CTX *mem_ctx, + struct sbus_sync_connection *conn, + const char *busname, + const char *object_path, + const char * arg_pem_cert, + const char ** _arg_result) +{ + return sbus_method_in_s_out_o(mem_ctx, conn, + busname, object_path, "org.freedesktop.sssd.infopipe.Users", "FindByValidCertificate", arg_pem_cert, + _arg_result); +} + +errno_t +sbus_call_ifp_users_ListByAttr + (TALLOC_CTX *mem_ctx, + struct sbus_sync_connection *conn, + const char *busname, + const char *object_path, + const char * arg_attribute, + const char * arg_attr_filter, + uint32_t arg_limit, + const char *** _arg_result) +{ + return sbus_method_in_ssu_out_ao(mem_ctx, conn, + busname, object_path, "org.freedesktop.sssd.infopipe.Users", "ListByAttr", arg_attribute, arg_attr_filter, arg_limit, + _arg_result); +} + +errno_t +sbus_call_ifp_users_ListByCertificate + (TALLOC_CTX *mem_ctx, + struct sbus_sync_connection *conn, + const char *busname, + const char *object_path, + const char * arg_pem_cert, + uint32_t arg_limit, + const char *** _arg_result) +{ + return sbus_method_in_su_out_ao(mem_ctx, conn, + busname, object_path, "org.freedesktop.sssd.infopipe.Users", "ListByCertificate", arg_pem_cert, arg_limit, + _arg_result); +} + +errno_t +sbus_call_ifp_users_ListByDomainAndName + (TALLOC_CTX *mem_ctx, + struct sbus_sync_connection *conn, + const char *busname, + const char *object_path, + const char * arg_domain_name, + const char * arg_name_filter, + uint32_t arg_limit, + const char *** _arg_result) +{ + return sbus_method_in_ssu_out_ao(mem_ctx, conn, + busname, object_path, "org.freedesktop.sssd.infopipe.Users", "ListByDomainAndName", arg_domain_name, arg_name_filter, arg_limit, + _arg_result); +} + +errno_t +sbus_call_ifp_users_ListByName + (TALLOC_CTX *mem_ctx, + struct sbus_sync_connection *conn, + const char *busname, + const char *object_path, + const char * arg_name_filter, + uint32_t arg_limit, + const char *** _arg_result) +{ + return sbus_method_in_su_out_ao(mem_ctx, conn, + busname, object_path, "org.freedesktop.sssd.infopipe.Users", "ListByName", arg_name_filter, arg_limit, + _arg_result); +} + +errno_t +sbus_call_ifp_user_UpdateGroupsList + (struct sbus_sync_connection *conn, + const char *busname, + const char *object_path) +{ + return sbus_method_in__out_(conn, + busname, object_path, "org.freedesktop.sssd.infopipe.Users.User", "UpdateGroupsList"); +} + +static errno_t +sbus_get_ao + (TALLOC_CTX *mem_ctx, + struct sbus_sync_connection *conn, + const char *bus, + const char *path, + const char *iface, + const char *property, + const char *** _value) +{ + TALLOC_CTX *tmp_ctx; + struct _sbus_ifp_invoker_args_ao *out; + sbus_value_reader_fn reader; + sbus_value_reader_talloc_fn reader_talloc; + DBusMessage *reply; + errno_t ret; + + tmp_ctx = talloc_new(NULL); + if (tmp_ctx == NULL) { + DEBUG(SSSDBG_FATAL_FAILURE, "Out of memory!\n"); + return ENOMEM; + } + + out = talloc_zero(tmp_ctx, struct _sbus_ifp_invoker_args_ao); + if (out == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, + "Unable to allocate space for output parameters!\n"); + ret = ENOMEM; + goto done; + } + + ret = sbus_call_DBusProperties_Get(tmp_ctx, conn, + bus, path, iface, property, &reply); + if (ret != EOK) { + goto done; + } + + reader = NULL; + reader_talloc = (sbus_value_reader_talloc_fn)sbus_iterator_read_ao; + ret = sbus_parse_get_message(out, reader, reader_talloc, reply, &out->arg0); + if (ret != EOK) { + goto done; + } + + *_value = talloc_steal(mem_ctx, out->arg0); + + ret = EOK; + +done: + talloc_free(tmp_ctx); + + return ret; +} + +static errno_t +sbus_get_as + (TALLOC_CTX *mem_ctx, + struct sbus_sync_connection *conn, + const char *bus, + const char *path, + const char *iface, + const char *property, + const char *** _value) +{ + TALLOC_CTX *tmp_ctx; + struct _sbus_ifp_invoker_args_as *out; + sbus_value_reader_fn reader; + sbus_value_reader_talloc_fn reader_talloc; + DBusMessage *reply; + errno_t ret; + + tmp_ctx = talloc_new(NULL); + if (tmp_ctx == NULL) { + DEBUG(SSSDBG_FATAL_FAILURE, "Out of memory!\n"); + return ENOMEM; + } + + out = talloc_zero(tmp_ctx, struct _sbus_ifp_invoker_args_as); + if (out == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, + "Unable to allocate space for output parameters!\n"); + ret = ENOMEM; + goto done; + } + + ret = sbus_call_DBusProperties_Get(tmp_ctx, conn, + bus, path, iface, property, &reply); + if (ret != EOK) { + goto done; + } + + reader = NULL; + reader_talloc = (sbus_value_reader_talloc_fn)sbus_iterator_read_as; + ret = sbus_parse_get_message(out, reader, reader_talloc, reply, &out->arg0); + if (ret != EOK) { + goto done; + } + + *_value = talloc_steal(mem_ctx, out->arg0); + + ret = EOK; + +done: + talloc_free(tmp_ctx); + + return ret; +} + +static errno_t +sbus_get_b + (struct sbus_sync_connection *conn, + const char *bus, + const char *path, + const char *iface, + const char *property, + bool* _value) +{ + TALLOC_CTX *tmp_ctx; + struct _sbus_ifp_invoker_args_b *out; + sbus_value_reader_fn reader; + sbus_value_reader_talloc_fn reader_talloc; + DBusMessage *reply; + errno_t ret; + + tmp_ctx = talloc_new(NULL); + if (tmp_ctx == NULL) { + DEBUG(SSSDBG_FATAL_FAILURE, "Out of memory!\n"); + return ENOMEM; + } + + out = talloc_zero(tmp_ctx, struct _sbus_ifp_invoker_args_b); + if (out == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, + "Unable to allocate space for output parameters!\n"); + ret = ENOMEM; + goto done; + } + + ret = sbus_call_DBusProperties_Get(tmp_ctx, conn, + bus, path, iface, property, &reply); + if (ret != EOK) { + goto done; + } + + reader = (sbus_value_reader_fn)sbus_iterator_read_b; + reader_talloc = NULL; + ret = sbus_parse_get_message(out, reader, reader_talloc, reply, &out->arg0); + if (ret != EOK) { + goto done; + } + + *_value = out->arg0; + + ret = EOK; + +done: + talloc_free(tmp_ctx); + + return ret; +} + +static errno_t +sbus_get_ifp_extra + (TALLOC_CTX *mem_ctx, + struct sbus_sync_connection *conn, + const char *bus, + const char *path, + const char *iface, + const char *property, + hash_table_t ** _value) +{ + TALLOC_CTX *tmp_ctx; + struct _sbus_ifp_invoker_args_ifp_extra *out; + sbus_value_reader_fn reader; + sbus_value_reader_talloc_fn reader_talloc; + DBusMessage *reply; + errno_t ret; + + tmp_ctx = talloc_new(NULL); + if (tmp_ctx == NULL) { + DEBUG(SSSDBG_FATAL_FAILURE, "Out of memory!\n"); + return ENOMEM; + } + + out = talloc_zero(tmp_ctx, struct _sbus_ifp_invoker_args_ifp_extra); + if (out == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, + "Unable to allocate space for output parameters!\n"); + ret = ENOMEM; + goto done; + } + + ret = sbus_call_DBusProperties_Get(tmp_ctx, conn, + bus, path, iface, property, &reply); + if (ret != EOK) { + goto done; + } + + reader = NULL; + reader_talloc = (sbus_value_reader_talloc_fn)sbus_iterator_read_ifp_extra; + ret = sbus_parse_get_message(out, reader, reader_talloc, reply, &out->arg0); + if (ret != EOK) { + goto done; + } + + *_value = talloc_steal(mem_ctx, out->arg0); + + ret = EOK; + +done: + talloc_free(tmp_ctx); + + return ret; +} + +static errno_t +sbus_get_o + (TALLOC_CTX *mem_ctx, + struct sbus_sync_connection *conn, + const char *bus, + const char *path, + const char *iface, + const char *property, + const char ** _value) +{ + TALLOC_CTX *tmp_ctx; + struct _sbus_ifp_invoker_args_o *out; + sbus_value_reader_fn reader; + sbus_value_reader_talloc_fn reader_talloc; + DBusMessage *reply; + errno_t ret; + + tmp_ctx = talloc_new(NULL); + if (tmp_ctx == NULL) { + DEBUG(SSSDBG_FATAL_FAILURE, "Out of memory!\n"); + return ENOMEM; + } + + out = talloc_zero(tmp_ctx, struct _sbus_ifp_invoker_args_o); + if (out == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, + "Unable to allocate space for output parameters!\n"); + ret = ENOMEM; + goto done; + } + + ret = sbus_call_DBusProperties_Get(tmp_ctx, conn, + bus, path, iface, property, &reply); + if (ret != EOK) { + goto done; + } + + reader = NULL; + reader_talloc = (sbus_value_reader_talloc_fn)sbus_iterator_read_o; + ret = sbus_parse_get_message(out, reader, reader_talloc, reply, &out->arg0); + if (ret != EOK) { + goto done; + } + + *_value = talloc_steal(mem_ctx, out->arg0); + + ret = EOK; + +done: + talloc_free(tmp_ctx); + + return ret; +} + +static errno_t +sbus_get_s + (TALLOC_CTX *mem_ctx, + struct sbus_sync_connection *conn, + const char *bus, + const char *path, + const char *iface, + const char *property, + const char ** _value) +{ + TALLOC_CTX *tmp_ctx; + struct _sbus_ifp_invoker_args_s *out; + sbus_value_reader_fn reader; + sbus_value_reader_talloc_fn reader_talloc; + DBusMessage *reply; + errno_t ret; + + tmp_ctx = talloc_new(NULL); + if (tmp_ctx == NULL) { + DEBUG(SSSDBG_FATAL_FAILURE, "Out of memory!\n"); + return ENOMEM; + } + + out = talloc_zero(tmp_ctx, struct _sbus_ifp_invoker_args_s); + if (out == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, + "Unable to allocate space for output parameters!\n"); + ret = ENOMEM; + goto done; + } + + ret = sbus_call_DBusProperties_Get(tmp_ctx, conn, + bus, path, iface, property, &reply); + if (ret != EOK) { + goto done; + } + + reader = NULL; + reader_talloc = (sbus_value_reader_talloc_fn)sbus_iterator_read_s; + ret = sbus_parse_get_message(out, reader, reader_talloc, reply, &out->arg0); + if (ret != EOK) { + goto done; + } + + *_value = talloc_steal(mem_ctx, out->arg0); + + ret = EOK; + +done: + talloc_free(tmp_ctx); + + return ret; +} + +static errno_t +sbus_get_u + (struct sbus_sync_connection *conn, + const char *bus, + const char *path, + const char *iface, + const char *property, + uint32_t* _value) +{ + TALLOC_CTX *tmp_ctx; + struct _sbus_ifp_invoker_args_u *out; + sbus_value_reader_fn reader; + sbus_value_reader_talloc_fn reader_talloc; + DBusMessage *reply; + errno_t ret; + + tmp_ctx = talloc_new(NULL); + if (tmp_ctx == NULL) { + DEBUG(SSSDBG_FATAL_FAILURE, "Out of memory!\n"); + return ENOMEM; + } + + out = talloc_zero(tmp_ctx, struct _sbus_ifp_invoker_args_u); + if (out == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, + "Unable to allocate space for output parameters!\n"); + ret = ENOMEM; + goto done; + } + + ret = sbus_call_DBusProperties_Get(tmp_ctx, conn, + bus, path, iface, property, &reply); + if (ret != EOK) { + goto done; + } + + reader = (sbus_value_reader_fn)sbus_iterator_read_u; + reader_talloc = NULL; + ret = sbus_parse_get_message(out, reader, reader_talloc, reply, &out->arg0); + if (ret != EOK) { + goto done; + } + + *_value = out->arg0; + + ret = EOK; + +done: + talloc_free(tmp_ctx); + + return ret; +} + +errno_t +sbus_get_ifp_components_debug_level + (struct sbus_sync_connection *conn, + const char *busname, + const char *object_path, + uint32_t* _value) +{ + return sbus_get_u(conn, busname, object_path, + "org.freedesktop.sssd.infopipe.Components", "debug_level", _value); +} + +errno_t +sbus_get_ifp_components_enabled + (struct sbus_sync_connection *conn, + const char *busname, + const char *object_path, + bool* _value) +{ + return sbus_get_b(conn, busname, object_path, + "org.freedesktop.sssd.infopipe.Components", "enabled", _value); +} + +errno_t +sbus_get_ifp_components_name + (TALLOC_CTX *mem_ctx, + struct sbus_sync_connection *conn, + const char *busname, + const char *object_path, + const char ** _value) +{ + return sbus_get_s(mem_ctx, conn, busname, object_path, + "org.freedesktop.sssd.infopipe.Components", "name", _value); +} + +errno_t +sbus_get_ifp_components_providers + (TALLOC_CTX *mem_ctx, + struct sbus_sync_connection *conn, + const char *busname, + const char *object_path, + const char *** _value) +{ + return sbus_get_as(mem_ctx, conn, busname, object_path, + "org.freedesktop.sssd.infopipe.Components", "providers", _value); +} + +errno_t +sbus_get_ifp_components_type + (TALLOC_CTX *mem_ctx, + struct sbus_sync_connection *conn, + const char *busname, + const char *object_path, + const char ** _value) +{ + return sbus_get_s(mem_ctx, conn, busname, object_path, + "org.freedesktop.sssd.infopipe.Components", "type", _value); +} + +errno_t +sbus_get_ifp_domains_backup_servers + (TALLOC_CTX *mem_ctx, + struct sbus_sync_connection *conn, + const char *busname, + const char *object_path, + const char *** _value) +{ + return sbus_get_as(mem_ctx, conn, busname, object_path, + "org.freedesktop.sssd.infopipe.Domains", "backup_servers", _value); +} + +errno_t +sbus_get_ifp_domains_enumerable + (struct sbus_sync_connection *conn, + const char *busname, + const char *object_path, + bool* _value) +{ + return sbus_get_b(conn, busname, object_path, + "org.freedesktop.sssd.infopipe.Domains", "enumerable", _value); +} + +errno_t +sbus_get_ifp_domains_forest + (TALLOC_CTX *mem_ctx, + struct sbus_sync_connection *conn, + const char *busname, + const char *object_path, + const char ** _value) +{ + return sbus_get_s(mem_ctx, conn, busname, object_path, + "org.freedesktop.sssd.infopipe.Domains", "forest", _value); +} + +errno_t +sbus_get_ifp_domains_fully_qualified_name_format + (TALLOC_CTX *mem_ctx, + struct sbus_sync_connection *conn, + const char *busname, + const char *object_path, + const char ** _value) +{ + return sbus_get_s(mem_ctx, conn, busname, object_path, + "org.freedesktop.sssd.infopipe.Domains", "fully_qualified_name_format", _value); +} + +errno_t +sbus_get_ifp_domains_login_format + (TALLOC_CTX *mem_ctx, + struct sbus_sync_connection *conn, + const char *busname, + const char *object_path, + const char ** _value) +{ + return sbus_get_s(mem_ctx, conn, busname, object_path, + "org.freedesktop.sssd.infopipe.Domains", "login_format", _value); +} + +errno_t +sbus_get_ifp_domains_max_id + (struct sbus_sync_connection *conn, + const char *busname, + const char *object_path, + uint32_t* _value) +{ + return sbus_get_u(conn, busname, object_path, + "org.freedesktop.sssd.infopipe.Domains", "max_id", _value); +} + +errno_t +sbus_get_ifp_domains_min_id + (struct sbus_sync_connection *conn, + const char *busname, + const char *object_path, + uint32_t* _value) +{ + return sbus_get_u(conn, busname, object_path, + "org.freedesktop.sssd.infopipe.Domains", "min_id", _value); +} + +errno_t +sbus_get_ifp_domains_name + (TALLOC_CTX *mem_ctx, + struct sbus_sync_connection *conn, + const char *busname, + const char *object_path, + const char ** _value) +{ + return sbus_get_s(mem_ctx, conn, busname, object_path, + "org.freedesktop.sssd.infopipe.Domains", "name", _value); +} + +errno_t +sbus_get_ifp_domains_parent_domain + (TALLOC_CTX *mem_ctx, + struct sbus_sync_connection *conn, + const char *busname, + const char *object_path, + const char ** _value) +{ + return sbus_get_o(mem_ctx, conn, busname, object_path, + "org.freedesktop.sssd.infopipe.Domains", "parent_domain", _value); +} + +errno_t +sbus_get_ifp_domains_primary_servers + (TALLOC_CTX *mem_ctx, + struct sbus_sync_connection *conn, + const char *busname, + const char *object_path, + const char *** _value) +{ + return sbus_get_as(mem_ctx, conn, busname, object_path, + "org.freedesktop.sssd.infopipe.Domains", "primary_servers", _value); +} + +errno_t +sbus_get_ifp_domains_provider + (TALLOC_CTX *mem_ctx, + struct sbus_sync_connection *conn, + const char *busname, + const char *object_path, + const char ** _value) +{ + return sbus_get_s(mem_ctx, conn, busname, object_path, + "org.freedesktop.sssd.infopipe.Domains", "provider", _value); +} + +errno_t +sbus_get_ifp_domains_realm + (TALLOC_CTX *mem_ctx, + struct sbus_sync_connection *conn, + const char *busname, + const char *object_path, + const char ** _value) +{ + return sbus_get_s(mem_ctx, conn, busname, object_path, + "org.freedesktop.sssd.infopipe.Domains", "realm", _value); +} + +errno_t +sbus_get_ifp_domains_subdomain + (struct sbus_sync_connection *conn, + const char *busname, + const char *object_path, + bool* _value) +{ + return sbus_get_b(conn, busname, object_path, + "org.freedesktop.sssd.infopipe.Domains", "subdomain", _value); +} + +errno_t +sbus_get_ifp_domains_use_fully_qualified_names + (struct sbus_sync_connection *conn, + const char *busname, + const char *object_path, + bool* _value) +{ + return sbus_get_b(conn, busname, object_path, + "org.freedesktop.sssd.infopipe.Domains", "use_fully_qualified_names", _value); +} + +errno_t +sbus_get_ifp_group_gidNumber + (struct sbus_sync_connection *conn, + const char *busname, + const char *object_path, + uint32_t* _value) +{ + return sbus_get_u(conn, busname, object_path, + "org.freedesktop.sssd.infopipe.Groups.Group", "gidNumber", _value); +} + +errno_t +sbus_get_ifp_group_groups + (TALLOC_CTX *mem_ctx, + struct sbus_sync_connection *conn, + const char *busname, + const char *object_path, + const char *** _value) +{ + return sbus_get_ao(mem_ctx, conn, busname, object_path, + "org.freedesktop.sssd.infopipe.Groups.Group", "groups", _value); +} + +errno_t +sbus_get_ifp_group_name + (TALLOC_CTX *mem_ctx, + struct sbus_sync_connection *conn, + const char *busname, + const char *object_path, + const char ** _value) +{ + return sbus_get_s(mem_ctx, conn, busname, object_path, + "org.freedesktop.sssd.infopipe.Groups.Group", "name", _value); +} + +errno_t +sbus_get_ifp_group_uniqueID + (TALLOC_CTX *mem_ctx, + struct sbus_sync_connection *conn, + const char *busname, + const char *object_path, + const char ** _value) +{ + return sbus_get_s(mem_ctx, conn, busname, object_path, + "org.freedesktop.sssd.infopipe.Groups.Group", "uniqueID", _value); +} + +errno_t +sbus_get_ifp_group_users + (TALLOC_CTX *mem_ctx, + struct sbus_sync_connection *conn, + const char *busname, + const char *object_path, + const char *** _value) +{ + return sbus_get_ao(mem_ctx, conn, busname, object_path, + "org.freedesktop.sssd.infopipe.Groups.Group", "users", _value); +} + +errno_t +sbus_get_ifp_user_domain + (TALLOC_CTX *mem_ctx, + struct sbus_sync_connection *conn, + const char *busname, + const char *object_path, + const char ** _value) +{ + return sbus_get_o(mem_ctx, conn, busname, object_path, + "org.freedesktop.sssd.infopipe.Users.User", "domain", _value); +} + +errno_t +sbus_get_ifp_user_domainname + (TALLOC_CTX *mem_ctx, + struct sbus_sync_connection *conn, + const char *busname, + const char *object_path, + const char ** _value) +{ + return sbus_get_s(mem_ctx, conn, busname, object_path, + "org.freedesktop.sssd.infopipe.Users.User", "domainname", _value); +} + +errno_t +sbus_get_ifp_user_extraAttributes + (TALLOC_CTX *mem_ctx, + struct sbus_sync_connection *conn, + const char *busname, + const char *object_path, + hash_table_t ** _value) +{ + return sbus_get_ifp_extra(mem_ctx, conn, busname, object_path, + "org.freedesktop.sssd.infopipe.Users.User", "extraAttributes", _value); +} + +errno_t +sbus_get_ifp_user_gecos + (TALLOC_CTX *mem_ctx, + struct sbus_sync_connection *conn, + const char *busname, + const char *object_path, + const char ** _value) +{ + return sbus_get_s(mem_ctx, conn, busname, object_path, + "org.freedesktop.sssd.infopipe.Users.User", "gecos", _value); +} + +errno_t +sbus_get_ifp_user_gidNumber + (struct sbus_sync_connection *conn, + const char *busname, + const char *object_path, + uint32_t* _value) +{ + return sbus_get_u(conn, busname, object_path, + "org.freedesktop.sssd.infopipe.Users.User", "gidNumber", _value); +} + +errno_t +sbus_get_ifp_user_groups + (TALLOC_CTX *mem_ctx, + struct sbus_sync_connection *conn, + const char *busname, + const char *object_path, + const char *** _value) +{ + return sbus_get_ao(mem_ctx, conn, busname, object_path, + "org.freedesktop.sssd.infopipe.Users.User", "groups", _value); +} + +errno_t +sbus_get_ifp_user_homeDirectory + (TALLOC_CTX *mem_ctx, + struct sbus_sync_connection *conn, + const char *busname, + const char *object_path, + const char ** _value) +{ + return sbus_get_s(mem_ctx, conn, busname, object_path, + "org.freedesktop.sssd.infopipe.Users.User", "homeDirectory", _value); +} + +errno_t +sbus_get_ifp_user_loginShell + (TALLOC_CTX *mem_ctx, + struct sbus_sync_connection *conn, + const char *busname, + const char *object_path, + const char ** _value) +{ + return sbus_get_s(mem_ctx, conn, busname, object_path, + "org.freedesktop.sssd.infopipe.Users.User", "loginShell", _value); +} + +errno_t +sbus_get_ifp_user_name + (TALLOC_CTX *mem_ctx, + struct sbus_sync_connection *conn, + const char *busname, + const char *object_path, + const char ** _value) +{ + return sbus_get_s(mem_ctx, conn, busname, object_path, + "org.freedesktop.sssd.infopipe.Users.User", "name", _value); +} + +errno_t +sbus_get_ifp_user_uidNumber + (struct sbus_sync_connection *conn, + const char *busname, + const char *object_path, + uint32_t* _value) +{ + return sbus_get_u(conn, busname, object_path, + "org.freedesktop.sssd.infopipe.Users.User", "uidNumber", _value); +} + +errno_t +sbus_get_ifp_user_uniqueID + (TALLOC_CTX *mem_ctx, + struct sbus_sync_connection *conn, + const char *busname, + const char *object_path, + const char ** _value) +{ + return sbus_get_s(mem_ctx, conn, busname, object_path, + "org.freedesktop.sssd.infopipe.Users.User", "uniqueID", _value); +} + +errno_t +sbus_getall_ifp_components + (TALLOC_CTX *mem_ctx, + struct sbus_sync_connection *conn, + const char *busname, + const char *object_path, + struct sbus_all_ifp_components **_properties) +{ + TALLOC_CTX *tmp_ctx; + struct sbus_all_ifp_components *properties; + DBusMessage *reply; + errno_t ret; + + tmp_ctx = talloc_new(NULL); + if (tmp_ctx == NULL) { + DEBUG(SSSDBG_FATAL_FAILURE, "Out of memory!\n"); + return ENOMEM; + } + + properties = talloc_zero(tmp_ctx, struct sbus_all_ifp_components); + if (properties == NULL) { + ret = ENOMEM; + goto done; + } + + struct sbus_parse_getall_table table[] = { + {"debug_level", (sbus_value_reader_fn)sbus_iterator_read_u, NULL, + &properties->debug_level.value, &properties->debug_level.is_set}, + {"enabled", (sbus_value_reader_fn)sbus_iterator_read_b, NULL, + &properties->enabled.value, &properties->enabled.is_set}, + {"name", NULL, (sbus_value_reader_talloc_fn)sbus_iterator_read_s, + &properties->name.value, &properties->name.is_set}, + {"providers", NULL, (sbus_value_reader_talloc_fn)sbus_iterator_read_as, + &properties->providers.value, &properties->providers.is_set}, + {"type", NULL, (sbus_value_reader_talloc_fn)sbus_iterator_read_s, + &properties->type.value, &properties->type.is_set}, + {NULL, NULL, NULL, NULL, NULL} + }; + + ret = sbus_call_DBusProperties_GetAll(tmp_ctx, conn, + busname, object_path, "org.freedesktop.sssd.infopipe.Components", &reply); + if (ret != EOK) { + goto done; + } + + ret = sbus_parse_getall_message(properties, table, reply); + if (ret != EOK) { + goto done; + } + + *_properties = talloc_steal(mem_ctx, properties); + + ret = EOK; + +done: + talloc_free(tmp_ctx); + + return ret; +} + +errno_t +sbus_getall_ifp_domains + (TALLOC_CTX *mem_ctx, + struct sbus_sync_connection *conn, + const char *busname, + const char *object_path, + struct sbus_all_ifp_domains **_properties) +{ + TALLOC_CTX *tmp_ctx; + struct sbus_all_ifp_domains *properties; + DBusMessage *reply; + errno_t ret; + + tmp_ctx = talloc_new(NULL); + if (tmp_ctx == NULL) { + DEBUG(SSSDBG_FATAL_FAILURE, "Out of memory!\n"); + return ENOMEM; + } + + properties = talloc_zero(tmp_ctx, struct sbus_all_ifp_domains); + if (properties == NULL) { + ret = ENOMEM; + goto done; + } + + struct sbus_parse_getall_table table[] = { + {"enumerable", (sbus_value_reader_fn)sbus_iterator_read_b, NULL, + &properties->enumerable.value, &properties->enumerable.is_set}, + {"max_id", (sbus_value_reader_fn)sbus_iterator_read_u, NULL, + &properties->max_id.value, &properties->max_id.is_set}, + {"min_id", (sbus_value_reader_fn)sbus_iterator_read_u, NULL, + &properties->min_id.value, &properties->min_id.is_set}, + {"subdomain", (sbus_value_reader_fn)sbus_iterator_read_b, NULL, + &properties->subdomain.value, &properties->subdomain.is_set}, + {"use_fully_qualified_names", (sbus_value_reader_fn)sbus_iterator_read_b, NULL, + &properties->use_fully_qualified_names.value, &properties->use_fully_qualified_names.is_set}, + {"backup_servers", NULL, (sbus_value_reader_talloc_fn)sbus_iterator_read_as, + &properties->backup_servers.value, &properties->backup_servers.is_set}, + {"forest", NULL, (sbus_value_reader_talloc_fn)sbus_iterator_read_s, + &properties->forest.value, &properties->forest.is_set}, + {"fully_qualified_name_format", NULL, (sbus_value_reader_talloc_fn)sbus_iterator_read_s, + &properties->fully_qualified_name_format.value, &properties->fully_qualified_name_format.is_set}, + {"login_format", NULL, (sbus_value_reader_talloc_fn)sbus_iterator_read_s, + &properties->login_format.value, &properties->login_format.is_set}, + {"name", NULL, (sbus_value_reader_talloc_fn)sbus_iterator_read_s, + &properties->name.value, &properties->name.is_set}, + {"parent_domain", NULL, (sbus_value_reader_talloc_fn)sbus_iterator_read_o, + &properties->parent_domain.value, &properties->parent_domain.is_set}, + {"primary_servers", NULL, (sbus_value_reader_talloc_fn)sbus_iterator_read_as, + &properties->primary_servers.value, &properties->primary_servers.is_set}, + {"provider", NULL, (sbus_value_reader_talloc_fn)sbus_iterator_read_s, + &properties->provider.value, &properties->provider.is_set}, + {"realm", NULL, (sbus_value_reader_talloc_fn)sbus_iterator_read_s, + &properties->realm.value, &properties->realm.is_set}, + {NULL, NULL, NULL, NULL, NULL} + }; + + ret = sbus_call_DBusProperties_GetAll(tmp_ctx, conn, + busname, object_path, "org.freedesktop.sssd.infopipe.Domains", &reply); + if (ret != EOK) { + goto done; + } + + ret = sbus_parse_getall_message(properties, table, reply); + if (ret != EOK) { + goto done; + } + + *_properties = talloc_steal(mem_ctx, properties); + + ret = EOK; + +done: + talloc_free(tmp_ctx); + + return ret; +} + +errno_t +sbus_getall_ifp_group + (TALLOC_CTX *mem_ctx, + struct sbus_sync_connection *conn, + const char *busname, + const char *object_path, + struct sbus_all_ifp_group **_properties) +{ + TALLOC_CTX *tmp_ctx; + struct sbus_all_ifp_group *properties; + DBusMessage *reply; + errno_t ret; + + tmp_ctx = talloc_new(NULL); + if (tmp_ctx == NULL) { + DEBUG(SSSDBG_FATAL_FAILURE, "Out of memory!\n"); + return ENOMEM; + } + + properties = talloc_zero(tmp_ctx, struct sbus_all_ifp_group); + if (properties == NULL) { + ret = ENOMEM; + goto done; + } + + struct sbus_parse_getall_table table[] = { + {"gidNumber", (sbus_value_reader_fn)sbus_iterator_read_u, NULL, + &properties->gidNumber.value, &properties->gidNumber.is_set}, + {"groups", NULL, (sbus_value_reader_talloc_fn)sbus_iterator_read_ao, + &properties->groups.value, &properties->groups.is_set}, + {"name", NULL, (sbus_value_reader_talloc_fn)sbus_iterator_read_s, + &properties->name.value, &properties->name.is_set}, + {"uniqueID", NULL, (sbus_value_reader_talloc_fn)sbus_iterator_read_s, + &properties->uniqueID.value, &properties->uniqueID.is_set}, + {"users", NULL, (sbus_value_reader_talloc_fn)sbus_iterator_read_ao, + &properties->users.value, &properties->users.is_set}, + {NULL, NULL, NULL, NULL, NULL} + }; + + ret = sbus_call_DBusProperties_GetAll(tmp_ctx, conn, + busname, object_path, "org.freedesktop.sssd.infopipe.Groups.Group", &reply); + if (ret != EOK) { + goto done; + } + + ret = sbus_parse_getall_message(properties, table, reply); + if (ret != EOK) { + goto done; + } + + *_properties = talloc_steal(mem_ctx, properties); + + ret = EOK; + +done: + talloc_free(tmp_ctx); + + return ret; +} + +errno_t +sbus_getall_ifp_user + (TALLOC_CTX *mem_ctx, + struct sbus_sync_connection *conn, + const char *busname, + const char *object_path, + struct sbus_all_ifp_user **_properties) +{ + TALLOC_CTX *tmp_ctx; + struct sbus_all_ifp_user *properties; + DBusMessage *reply; + errno_t ret; + + tmp_ctx = talloc_new(NULL); + if (tmp_ctx == NULL) { + DEBUG(SSSDBG_FATAL_FAILURE, "Out of memory!\n"); + return ENOMEM; + } + + properties = talloc_zero(tmp_ctx, struct sbus_all_ifp_user); + if (properties == NULL) { + ret = ENOMEM; + goto done; + } + + struct sbus_parse_getall_table table[] = { + {"gidNumber", (sbus_value_reader_fn)sbus_iterator_read_u, NULL, + &properties->gidNumber.value, &properties->gidNumber.is_set}, + {"uidNumber", (sbus_value_reader_fn)sbus_iterator_read_u, NULL, + &properties->uidNumber.value, &properties->uidNumber.is_set}, + {"domain", NULL, (sbus_value_reader_talloc_fn)sbus_iterator_read_o, + &properties->domain.value, &properties->domain.is_set}, + {"domainname", NULL, (sbus_value_reader_talloc_fn)sbus_iterator_read_s, + &properties->domainname.value, &properties->domainname.is_set}, + {"extraAttributes", NULL, (sbus_value_reader_talloc_fn)sbus_iterator_read_ifp_extra, + &properties->extraAttributes.value, &properties->extraAttributes.is_set}, + {"gecos", NULL, (sbus_value_reader_talloc_fn)sbus_iterator_read_s, + &properties->gecos.value, &properties->gecos.is_set}, + {"groups", NULL, (sbus_value_reader_talloc_fn)sbus_iterator_read_ao, + &properties->groups.value, &properties->groups.is_set}, + {"homeDirectory", NULL, (sbus_value_reader_talloc_fn)sbus_iterator_read_s, + &properties->homeDirectory.value, &properties->homeDirectory.is_set}, + {"loginShell", NULL, (sbus_value_reader_talloc_fn)sbus_iterator_read_s, + &properties->loginShell.value, &properties->loginShell.is_set}, + {"name", NULL, (sbus_value_reader_talloc_fn)sbus_iterator_read_s, + &properties->name.value, &properties->name.is_set}, + {"uniqueID", NULL, (sbus_value_reader_talloc_fn)sbus_iterator_read_s, + &properties->uniqueID.value, &properties->uniqueID.is_set}, + {NULL, NULL, NULL, NULL, NULL} + }; + + ret = sbus_call_DBusProperties_GetAll(tmp_ctx, conn, + busname, object_path, "org.freedesktop.sssd.infopipe.Users.User", &reply); + if (ret != EOK) { + goto done; + } + + ret = sbus_parse_getall_message(properties, table, reply); + if (ret != EOK) { + goto done; + } + + *_properties = talloc_steal(mem_ctx, properties); + + ret = EOK; + +done: + talloc_free(tmp_ctx); + + return ret; +} diff --git a/src/responder/ifp/ifp_iface/sbus_ifp_client_sync.h b/src/responder/ifp/ifp_iface/sbus_ifp_client_sync.h new file mode 100644 index 0000000..b5455e9 --- /dev/null +++ b/src/responder/ifp/ifp_iface/sbus_ifp_client_sync.h @@ -0,0 +1,637 @@ +/* + Generated by sbus code generator + + Copyright (C) 2017 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 _SBUS_IFP_CLIENT_SYNC_H_ +#define _SBUS_IFP_CLIENT_SYNC_H_ + +#include <errno.h> +#include <talloc.h> +#include <tevent.h> + +#include "sbus/sbus_sync.h" +#include "responder/ifp/ifp_iface/sbus_ifp_client_properties.h" +#include "responder/ifp/ifp_iface/ifp_iface_types.h" + +errno_t +sbus_call_ifp_FindBackendByName + (TALLOC_CTX *mem_ctx, + struct sbus_sync_connection *conn, + const char *busname, + const char *object_path, + const char * arg_name, + const char ** _arg_backend); + +errno_t +sbus_call_ifp_FindDomainByName + (TALLOC_CTX *mem_ctx, + struct sbus_sync_connection *conn, + const char *busname, + const char *object_path, + const char * arg_name, + const char ** _arg_domain); + +errno_t +sbus_call_ifp_FindMonitor + (TALLOC_CTX *mem_ctx, + struct sbus_sync_connection *conn, + const char *busname, + const char *object_path, + const char ** _arg_monitor); + +errno_t +sbus_call_ifp_FindResponderByName + (TALLOC_CTX *mem_ctx, + struct sbus_sync_connection *conn, + const char *busname, + const char *object_path, + const char * arg_name, + const char ** _arg_responder); + +errno_t +sbus_call_ifp_GetUserAttr + (TALLOC_CTX *mem_ctx, + struct sbus_sync_connection *conn, + const char *busname, + const char *object_path, + const char * arg_user, + const char ** arg_attr, + DBusMessage **_reply); + +errno_t +sbus_call_ifp_GetUserGroups + (TALLOC_CTX *mem_ctx, + struct sbus_sync_connection *conn, + const char *busname, + const char *object_path, + const char * arg_user, + const char *** _arg_values); + +errno_t +sbus_call_ifp_ListBackends + (TALLOC_CTX *mem_ctx, + struct sbus_sync_connection *conn, + const char *busname, + const char *object_path, + const char *** _arg_backends); + +errno_t +sbus_call_ifp_ListComponents + (TALLOC_CTX *mem_ctx, + struct sbus_sync_connection *conn, + const char *busname, + const char *object_path, + const char *** _arg_components); + +errno_t +sbus_call_ifp_ListDomains + (TALLOC_CTX *mem_ctx, + struct sbus_sync_connection *conn, + const char *busname, + const char *object_path, + const char *** _arg_domain); + +errno_t +sbus_call_ifp_ListResponders + (TALLOC_CTX *mem_ctx, + struct sbus_sync_connection *conn, + const char *busname, + const char *object_path, + const char *** _arg_responders); + +errno_t +sbus_call_ifp_Ping + (TALLOC_CTX *mem_ctx, + struct sbus_sync_connection *conn, + const char *busname, + const char *object_path, + const char * arg_ping, + const char ** _arg_pong); + +errno_t +sbus_call_ifp_cache_List + (TALLOC_CTX *mem_ctx, + struct sbus_sync_connection *conn, + const char *busname, + const char *object_path, + const char *** _arg_result); + +errno_t +sbus_call_ifp_cache_ListByDomain + (TALLOC_CTX *mem_ctx, + struct sbus_sync_connection *conn, + const char *busname, + const char *object_path, + const char * arg_domain_name, + const char *** _arg_result); + +errno_t +sbus_call_ifp_cache_object_Remove + (struct sbus_sync_connection *conn, + const char *busname, + const char *object_path, + bool* _arg_result); + +errno_t +sbus_call_ifp_cache_object_Store + (struct sbus_sync_connection *conn, + const char *busname, + const char *object_path, + bool* _arg_result); + +errno_t +sbus_call_ifp_domain_ActiveServer + (TALLOC_CTX *mem_ctx, + struct sbus_sync_connection *conn, + const char *busname, + const char *object_path, + const char * arg_service, + const char ** _arg_server); + +errno_t +sbus_call_ifp_domain_IsOnline + (struct sbus_sync_connection *conn, + const char *busname, + const char *object_path, + bool* _arg_status); + +errno_t +sbus_call_ifp_domain_ListServers + (TALLOC_CTX *mem_ctx, + struct sbus_sync_connection *conn, + const char *busname, + const char *object_path, + const char * arg_service_name, + const char *** _arg_servers); + +errno_t +sbus_call_ifp_domain_ListServices + (TALLOC_CTX *mem_ctx, + struct sbus_sync_connection *conn, + const char *busname, + const char *object_path, + const char *** _arg_services); + +errno_t +sbus_call_ifp_domain_RefreshAccessRules + (struct sbus_sync_connection *conn, + const char *busname, + const char *object_path); + +errno_t +sbus_call_ifp_groups_FindByID + (TALLOC_CTX *mem_ctx, + struct sbus_sync_connection *conn, + const char *busname, + const char *object_path, + uint32_t arg_id, + const char ** _arg_result); + +errno_t +sbus_call_ifp_groups_FindByName + (TALLOC_CTX *mem_ctx, + struct sbus_sync_connection *conn, + const char *busname, + const char *object_path, + const char * arg_name, + const char ** _arg_result); + +errno_t +sbus_call_ifp_groups_ListByDomainAndName + (TALLOC_CTX *mem_ctx, + struct sbus_sync_connection *conn, + const char *busname, + const char *object_path, + const char * arg_domain_name, + const char * arg_name_filter, + uint32_t arg_limit, + const char *** _arg_result); + +errno_t +sbus_call_ifp_groups_ListByName + (TALLOC_CTX *mem_ctx, + struct sbus_sync_connection *conn, + const char *busname, + const char *object_path, + const char * arg_name_filter, + uint32_t arg_limit, + const char *** _arg_result); + +errno_t +sbus_call_ifp_group_UpdateMemberList + (struct sbus_sync_connection *conn, + const char *busname, + const char *object_path); + +errno_t +sbus_call_ifp_users_FindByCertificate + (TALLOC_CTX *mem_ctx, + struct sbus_sync_connection *conn, + const char *busname, + const char *object_path, + const char * arg_pem_cert, + const char ** _arg_result); + +errno_t +sbus_call_ifp_users_FindByID + (TALLOC_CTX *mem_ctx, + struct sbus_sync_connection *conn, + const char *busname, + const char *object_path, + uint32_t arg_id, + const char ** _arg_result); + +errno_t +sbus_call_ifp_users_FindByName + (TALLOC_CTX *mem_ctx, + struct sbus_sync_connection *conn, + const char *busname, + const char *object_path, + const char * arg_name, + const char ** _arg_result); + +errno_t +sbus_call_ifp_users_FindByNameAndCertificate + (TALLOC_CTX *mem_ctx, + struct sbus_sync_connection *conn, + const char *busname, + const char *object_path, + const char * arg_name, + const char * arg_pem_cert, + const char ** _arg_result); + +errno_t +sbus_call_ifp_users_FindByValidCertificate + (TALLOC_CTX *mem_ctx, + struct sbus_sync_connection *conn, + const char *busname, + const char *object_path, + const char * arg_pem_cert, + const char ** _arg_result); + +errno_t +sbus_call_ifp_users_ListByAttr + (TALLOC_CTX *mem_ctx, + struct sbus_sync_connection *conn, + const char *busname, + const char *object_path, + const char * arg_attribute, + const char * arg_attr_filter, + uint32_t arg_limit, + const char *** _arg_result); + +errno_t +sbus_call_ifp_users_ListByCertificate + (TALLOC_CTX *mem_ctx, + struct sbus_sync_connection *conn, + const char *busname, + const char *object_path, + const char * arg_pem_cert, + uint32_t arg_limit, + const char *** _arg_result); + +errno_t +sbus_call_ifp_users_ListByDomainAndName + (TALLOC_CTX *mem_ctx, + struct sbus_sync_connection *conn, + const char *busname, + const char *object_path, + const char * arg_domain_name, + const char * arg_name_filter, + uint32_t arg_limit, + const char *** _arg_result); + +errno_t +sbus_call_ifp_users_ListByName + (TALLOC_CTX *mem_ctx, + struct sbus_sync_connection *conn, + const char *busname, + const char *object_path, + const char * arg_name_filter, + uint32_t arg_limit, + const char *** _arg_result); + +errno_t +sbus_call_ifp_user_UpdateGroupsList + (struct sbus_sync_connection *conn, + const char *busname, + const char *object_path); + +errno_t +sbus_get_ifp_components_debug_level + (struct sbus_sync_connection *conn, + const char *busname, + const char *object_path, + uint32_t* _value); + +errno_t +sbus_get_ifp_components_enabled + (struct sbus_sync_connection *conn, + const char *busname, + const char *object_path, + bool* _value); + +errno_t +sbus_get_ifp_components_name + (TALLOC_CTX *mem_ctx, + struct sbus_sync_connection *conn, + const char *busname, + const char *object_path, + const char ** _value); + +errno_t +sbus_get_ifp_components_providers + (TALLOC_CTX *mem_ctx, + struct sbus_sync_connection *conn, + const char *busname, + const char *object_path, + const char *** _value); + +errno_t +sbus_get_ifp_components_type + (TALLOC_CTX *mem_ctx, + struct sbus_sync_connection *conn, + const char *busname, + const char *object_path, + const char ** _value); + +errno_t +sbus_get_ifp_domains_backup_servers + (TALLOC_CTX *mem_ctx, + struct sbus_sync_connection *conn, + const char *busname, + const char *object_path, + const char *** _value); + +errno_t +sbus_get_ifp_domains_enumerable + (struct sbus_sync_connection *conn, + const char *busname, + const char *object_path, + bool* _value); + +errno_t +sbus_get_ifp_domains_forest + (TALLOC_CTX *mem_ctx, + struct sbus_sync_connection *conn, + const char *busname, + const char *object_path, + const char ** _value); + +errno_t +sbus_get_ifp_domains_fully_qualified_name_format + (TALLOC_CTX *mem_ctx, + struct sbus_sync_connection *conn, + const char *busname, + const char *object_path, + const char ** _value); + +errno_t +sbus_get_ifp_domains_login_format + (TALLOC_CTX *mem_ctx, + struct sbus_sync_connection *conn, + const char *busname, + const char *object_path, + const char ** _value); + +errno_t +sbus_get_ifp_domains_max_id + (struct sbus_sync_connection *conn, + const char *busname, + const char *object_path, + uint32_t* _value); + +errno_t +sbus_get_ifp_domains_min_id + (struct sbus_sync_connection *conn, + const char *busname, + const char *object_path, + uint32_t* _value); + +errno_t +sbus_get_ifp_domains_name + (TALLOC_CTX *mem_ctx, + struct sbus_sync_connection *conn, + const char *busname, + const char *object_path, + const char ** _value); + +errno_t +sbus_get_ifp_domains_parent_domain + (TALLOC_CTX *mem_ctx, + struct sbus_sync_connection *conn, + const char *busname, + const char *object_path, + const char ** _value); + +errno_t +sbus_get_ifp_domains_primary_servers + (TALLOC_CTX *mem_ctx, + struct sbus_sync_connection *conn, + const char *busname, + const char *object_path, + const char *** _value); + +errno_t +sbus_get_ifp_domains_provider + (TALLOC_CTX *mem_ctx, + struct sbus_sync_connection *conn, + const char *busname, + const char *object_path, + const char ** _value); + +errno_t +sbus_get_ifp_domains_realm + (TALLOC_CTX *mem_ctx, + struct sbus_sync_connection *conn, + const char *busname, + const char *object_path, + const char ** _value); + +errno_t +sbus_get_ifp_domains_subdomain + (struct sbus_sync_connection *conn, + const char *busname, + const char *object_path, + bool* _value); + +errno_t +sbus_get_ifp_domains_use_fully_qualified_names + (struct sbus_sync_connection *conn, + const char *busname, + const char *object_path, + bool* _value); + +errno_t +sbus_get_ifp_group_gidNumber + (struct sbus_sync_connection *conn, + const char *busname, + const char *object_path, + uint32_t* _value); + +errno_t +sbus_get_ifp_group_groups + (TALLOC_CTX *mem_ctx, + struct sbus_sync_connection *conn, + const char *busname, + const char *object_path, + const char *** _value); + +errno_t +sbus_get_ifp_group_name + (TALLOC_CTX *mem_ctx, + struct sbus_sync_connection *conn, + const char *busname, + const char *object_path, + const char ** _value); + +errno_t +sbus_get_ifp_group_uniqueID + (TALLOC_CTX *mem_ctx, + struct sbus_sync_connection *conn, + const char *busname, + const char *object_path, + const char ** _value); + +errno_t +sbus_get_ifp_group_users + (TALLOC_CTX *mem_ctx, + struct sbus_sync_connection *conn, + const char *busname, + const char *object_path, + const char *** _value); + +errno_t +sbus_get_ifp_user_domain + (TALLOC_CTX *mem_ctx, + struct sbus_sync_connection *conn, + const char *busname, + const char *object_path, + const char ** _value); + +errno_t +sbus_get_ifp_user_domainname + (TALLOC_CTX *mem_ctx, + struct sbus_sync_connection *conn, + const char *busname, + const char *object_path, + const char ** _value); + +errno_t +sbus_get_ifp_user_extraAttributes + (TALLOC_CTX *mem_ctx, + struct sbus_sync_connection *conn, + const char *busname, + const char *object_path, + hash_table_t ** _value); + +errno_t +sbus_get_ifp_user_gecos + (TALLOC_CTX *mem_ctx, + struct sbus_sync_connection *conn, + const char *busname, + const char *object_path, + const char ** _value); + +errno_t +sbus_get_ifp_user_gidNumber + (struct sbus_sync_connection *conn, + const char *busname, + const char *object_path, + uint32_t* _value); + +errno_t +sbus_get_ifp_user_groups + (TALLOC_CTX *mem_ctx, + struct sbus_sync_connection *conn, + const char *busname, + const char *object_path, + const char *** _value); + +errno_t +sbus_get_ifp_user_homeDirectory + (TALLOC_CTX *mem_ctx, + struct sbus_sync_connection *conn, + const char *busname, + const char *object_path, + const char ** _value); + +errno_t +sbus_get_ifp_user_loginShell + (TALLOC_CTX *mem_ctx, + struct sbus_sync_connection *conn, + const char *busname, + const char *object_path, + const char ** _value); + +errno_t +sbus_get_ifp_user_name + (TALLOC_CTX *mem_ctx, + struct sbus_sync_connection *conn, + const char *busname, + const char *object_path, + const char ** _value); + +errno_t +sbus_get_ifp_user_uidNumber + (struct sbus_sync_connection *conn, + const char *busname, + const char *object_path, + uint32_t* _value); + +errno_t +sbus_get_ifp_user_uniqueID + (TALLOC_CTX *mem_ctx, + struct sbus_sync_connection *conn, + const char *busname, + const char *object_path, + const char ** _value); + +errno_t +sbus_getall_ifp_components + (TALLOC_CTX *mem_ctx, + struct sbus_sync_connection *conn, + const char *busname, + const char *object_path, + struct sbus_all_ifp_components **_properties); + +errno_t +sbus_getall_ifp_domains + (TALLOC_CTX *mem_ctx, + struct sbus_sync_connection *conn, + const char *busname, + const char *object_path, + struct sbus_all_ifp_domains **_properties); + +errno_t +sbus_getall_ifp_group + (TALLOC_CTX *mem_ctx, + struct sbus_sync_connection *conn, + const char *busname, + const char *object_path, + struct sbus_all_ifp_group **_properties); + +errno_t +sbus_getall_ifp_user + (TALLOC_CTX *mem_ctx, + struct sbus_sync_connection *conn, + const char *busname, + const char *object_path, + struct sbus_all_ifp_user **_properties); + +#endif /* _SBUS_IFP_CLIENT_SYNC_H_ */ diff --git a/src/responder/ifp/ifp_iface/sbus_ifp_interface.h b/src/responder/ifp/ifp_iface/sbus_ifp_interface.h new file mode 100644 index 0000000..0faac69 --- /dev/null +++ b/src/responder/ifp/ifp_iface/sbus_ifp_interface.h @@ -0,0 +1,2083 @@ +/* + Generated by sbus code generator + + Copyright (C) 2017 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 _SBUS_IFP_INTERFACE_H_ +#define _SBUS_IFP_INTERFACE_H_ + +#include "sbus/sbus_interface_declarations.h" +#include "responder/ifp/ifp_iface/sbus_ifp_invokers.h" +#include "responder/ifp/ifp_iface/sbus_ifp_symbols.h" +#include "responder/ifp/ifp_iface/sbus_ifp_keygens.h" + +/* Interface: org.freedesktop.sssd.infopipe */ +#define SBUS_IFACE_org_freedesktop_sssd_infopipe(methods, signals, properties) ({ \ + sbus_interface("org.freedesktop.sssd.infopipe", NULL, \ + (methods), (signals), (properties)); \ +}) + +/* Method: org.freedesktop.sssd.infopipe.FindBackendByName */ +#define SBUS_METHOD_SYNC_org_freedesktop_sssd_infopipe_FindBackendByName(handler, data) ({ \ + SBUS_CHECK_SYNC((handler), (data), const char *, const char **); \ + sbus_method_sync("FindBackendByName", \ + &_sbus_ifp_args_org_freedesktop_sssd_infopipe_FindBackendByName, \ + NULL, \ + _sbus_ifp_invoke_in_s_out_o_send, \ + _sbus_ifp_key_s_0, \ + (handler), (data)); \ +}) + +#define SBUS_METHOD_ASYNC_org_freedesktop_sssd_infopipe_FindBackendByName(handler_send, handler_recv, data) ({ \ + SBUS_CHECK_SEND((handler_send), (data), const char *); \ + SBUS_CHECK_RECV((handler_recv), const char **); \ + sbus_method_async("FindBackendByName", \ + &_sbus_ifp_args_org_freedesktop_sssd_infopipe_FindBackendByName, \ + NULL, \ + _sbus_ifp_invoke_in_s_out_o_send, \ + _sbus_ifp_key_s_0, \ + (handler_send), (handler_recv), (data)); \ +}) + +/* Method: org.freedesktop.sssd.infopipe.FindDomainByName */ +#define SBUS_METHOD_SYNC_org_freedesktop_sssd_infopipe_FindDomainByName(handler, data) ({ \ + SBUS_CHECK_SYNC((handler), (data), const char *, const char **); \ + sbus_method_sync("FindDomainByName", \ + &_sbus_ifp_args_org_freedesktop_sssd_infopipe_FindDomainByName, \ + NULL, \ + _sbus_ifp_invoke_in_s_out_o_send, \ + _sbus_ifp_key_s_0, \ + (handler), (data)); \ +}) + +#define SBUS_METHOD_ASYNC_org_freedesktop_sssd_infopipe_FindDomainByName(handler_send, handler_recv, data) ({ \ + SBUS_CHECK_SEND((handler_send), (data), const char *); \ + SBUS_CHECK_RECV((handler_recv), const char **); \ + sbus_method_async("FindDomainByName", \ + &_sbus_ifp_args_org_freedesktop_sssd_infopipe_FindDomainByName, \ + NULL, \ + _sbus_ifp_invoke_in_s_out_o_send, \ + _sbus_ifp_key_s_0, \ + (handler_send), (handler_recv), (data)); \ +}) + +/* Method: org.freedesktop.sssd.infopipe.FindMonitor */ +#define SBUS_METHOD_SYNC_org_freedesktop_sssd_infopipe_FindMonitor(handler, data) ({ \ + SBUS_CHECK_SYNC((handler), (data), const char **); \ + sbus_method_sync("FindMonitor", \ + &_sbus_ifp_args_org_freedesktop_sssd_infopipe_FindMonitor, \ + NULL, \ + _sbus_ifp_invoke_in__out_o_send, \ + _sbus_ifp_key_, \ + (handler), (data)); \ +}) + +#define SBUS_METHOD_ASYNC_org_freedesktop_sssd_infopipe_FindMonitor(handler_send, handler_recv, data) ({ \ + SBUS_CHECK_SEND((handler_send), (data)); \ + SBUS_CHECK_RECV((handler_recv), const char **); \ + sbus_method_async("FindMonitor", \ + &_sbus_ifp_args_org_freedesktop_sssd_infopipe_FindMonitor, \ + NULL, \ + _sbus_ifp_invoke_in__out_o_send, \ + _sbus_ifp_key_, \ + (handler_send), (handler_recv), (data)); \ +}) + +/* Method: org.freedesktop.sssd.infopipe.FindResponderByName */ +#define SBUS_METHOD_SYNC_org_freedesktop_sssd_infopipe_FindResponderByName(handler, data) ({ \ + SBUS_CHECK_SYNC((handler), (data), const char *, const char **); \ + sbus_method_sync("FindResponderByName", \ + &_sbus_ifp_args_org_freedesktop_sssd_infopipe_FindResponderByName, \ + NULL, \ + _sbus_ifp_invoke_in_s_out_o_send, \ + _sbus_ifp_key_s_0, \ + (handler), (data)); \ +}) + +#define SBUS_METHOD_ASYNC_org_freedesktop_sssd_infopipe_FindResponderByName(handler_send, handler_recv, data) ({ \ + SBUS_CHECK_SEND((handler_send), (data), const char *); \ + SBUS_CHECK_RECV((handler_recv), const char **); \ + sbus_method_async("FindResponderByName", \ + &_sbus_ifp_args_org_freedesktop_sssd_infopipe_FindResponderByName, \ + NULL, \ + _sbus_ifp_invoke_in_s_out_o_send, \ + _sbus_ifp_key_s_0, \ + (handler_send), (handler_recv), (data)); \ +}) + +/* Method: org.freedesktop.sssd.infopipe.GetUserAttr */ +#define SBUS_METHOD_SYNC_org_freedesktop_sssd_infopipe_GetUserAttr(handler, data) ({ \ + SBUS_CHECK_SYNC((handler), (data), const char *, const char **, DBusMessageIter *); \ + sbus_method_sync("GetUserAttr", \ + &_sbus_ifp_args_org_freedesktop_sssd_infopipe_GetUserAttr, \ + NULL, \ + _sbus_ifp_invoke_in_sas_out_raw_send, \ + NULL, \ + (handler), (data)); \ +}) + +#define SBUS_METHOD_ASYNC_org_freedesktop_sssd_infopipe_GetUserAttr(handler_send, handler_recv, data) ({ \ + SBUS_CHECK_SEND((handler_send), (data), const char *, const char **, DBusMessageIter *); \ + SBUS_CHECK_RECV((handler_recv)); \ + sbus_method_async("GetUserAttr", \ + &_sbus_ifp_args_org_freedesktop_sssd_infopipe_GetUserAttr, \ + NULL, \ + _sbus_ifp_invoke_in_sas_out_raw_send, \ + NULL, \ + (handler_send), (handler_recv), (data)); \ +}) + +/* Method: org.freedesktop.sssd.infopipe.GetUserGroups */ +#define SBUS_METHOD_SYNC_org_freedesktop_sssd_infopipe_GetUserGroups(handler, data) ({ \ + SBUS_CHECK_SYNC((handler), (data), const char *, const char ***); \ + sbus_method_sync("GetUserGroups", \ + &_sbus_ifp_args_org_freedesktop_sssd_infopipe_GetUserGroups, \ + NULL, \ + _sbus_ifp_invoke_in_s_out_as_send, \ + _sbus_ifp_key_s_0, \ + (handler), (data)); \ +}) + +#define SBUS_METHOD_ASYNC_org_freedesktop_sssd_infopipe_GetUserGroups(handler_send, handler_recv, data) ({ \ + SBUS_CHECK_SEND((handler_send), (data), const char *); \ + SBUS_CHECK_RECV((handler_recv), const char ***); \ + sbus_method_async("GetUserGroups", \ + &_sbus_ifp_args_org_freedesktop_sssd_infopipe_GetUserGroups, \ + NULL, \ + _sbus_ifp_invoke_in_s_out_as_send, \ + _sbus_ifp_key_s_0, \ + (handler_send), (handler_recv), (data)); \ +}) + +/* Method: org.freedesktop.sssd.infopipe.ListBackends */ +#define SBUS_METHOD_SYNC_org_freedesktop_sssd_infopipe_ListBackends(handler, data) ({ \ + SBUS_CHECK_SYNC((handler), (data), const char ***); \ + sbus_method_sync("ListBackends", \ + &_sbus_ifp_args_org_freedesktop_sssd_infopipe_ListBackends, \ + NULL, \ + _sbus_ifp_invoke_in__out_ao_send, \ + _sbus_ifp_key_, \ + (handler), (data)); \ +}) + +#define SBUS_METHOD_ASYNC_org_freedesktop_sssd_infopipe_ListBackends(handler_send, handler_recv, data) ({ \ + SBUS_CHECK_SEND((handler_send), (data)); \ + SBUS_CHECK_RECV((handler_recv), const char ***); \ + sbus_method_async("ListBackends", \ + &_sbus_ifp_args_org_freedesktop_sssd_infopipe_ListBackends, \ + NULL, \ + _sbus_ifp_invoke_in__out_ao_send, \ + _sbus_ifp_key_, \ + (handler_send), (handler_recv), (data)); \ +}) + +/* Method: org.freedesktop.sssd.infopipe.ListComponents */ +#define SBUS_METHOD_SYNC_org_freedesktop_sssd_infopipe_ListComponents(handler, data) ({ \ + SBUS_CHECK_SYNC((handler), (data), const char ***); \ + sbus_method_sync("ListComponents", \ + &_sbus_ifp_args_org_freedesktop_sssd_infopipe_ListComponents, \ + NULL, \ + _sbus_ifp_invoke_in__out_ao_send, \ + _sbus_ifp_key_, \ + (handler), (data)); \ +}) + +#define SBUS_METHOD_ASYNC_org_freedesktop_sssd_infopipe_ListComponents(handler_send, handler_recv, data) ({ \ + SBUS_CHECK_SEND((handler_send), (data)); \ + SBUS_CHECK_RECV((handler_recv), const char ***); \ + sbus_method_async("ListComponents", \ + &_sbus_ifp_args_org_freedesktop_sssd_infopipe_ListComponents, \ + NULL, \ + _sbus_ifp_invoke_in__out_ao_send, \ + _sbus_ifp_key_, \ + (handler_send), (handler_recv), (data)); \ +}) + +/* Method: org.freedesktop.sssd.infopipe.ListDomains */ +#define SBUS_METHOD_SYNC_org_freedesktop_sssd_infopipe_ListDomains(handler, data) ({ \ + SBUS_CHECK_SYNC((handler), (data), const char ***); \ + sbus_method_sync("ListDomains", \ + &_sbus_ifp_args_org_freedesktop_sssd_infopipe_ListDomains, \ + NULL, \ + _sbus_ifp_invoke_in__out_ao_send, \ + _sbus_ifp_key_, \ + (handler), (data)); \ +}) + +#define SBUS_METHOD_ASYNC_org_freedesktop_sssd_infopipe_ListDomains(handler_send, handler_recv, data) ({ \ + SBUS_CHECK_SEND((handler_send), (data)); \ + SBUS_CHECK_RECV((handler_recv), const char ***); \ + sbus_method_async("ListDomains", \ + &_sbus_ifp_args_org_freedesktop_sssd_infopipe_ListDomains, \ + NULL, \ + _sbus_ifp_invoke_in__out_ao_send, \ + _sbus_ifp_key_, \ + (handler_send), (handler_recv), (data)); \ +}) + +/* Method: org.freedesktop.sssd.infopipe.ListResponders */ +#define SBUS_METHOD_SYNC_org_freedesktop_sssd_infopipe_ListResponders(handler, data) ({ \ + SBUS_CHECK_SYNC((handler), (data), const char ***); \ + sbus_method_sync("ListResponders", \ + &_sbus_ifp_args_org_freedesktop_sssd_infopipe_ListResponders, \ + NULL, \ + _sbus_ifp_invoke_in__out_ao_send, \ + _sbus_ifp_key_, \ + (handler), (data)); \ +}) + +#define SBUS_METHOD_ASYNC_org_freedesktop_sssd_infopipe_ListResponders(handler_send, handler_recv, data) ({ \ + SBUS_CHECK_SEND((handler_send), (data)); \ + SBUS_CHECK_RECV((handler_recv), const char ***); \ + sbus_method_async("ListResponders", \ + &_sbus_ifp_args_org_freedesktop_sssd_infopipe_ListResponders, \ + NULL, \ + _sbus_ifp_invoke_in__out_ao_send, \ + _sbus_ifp_key_, \ + (handler_send), (handler_recv), (data)); \ +}) + +/* Method: org.freedesktop.sssd.infopipe.Ping */ +#define SBUS_METHOD_SYNC_org_freedesktop_sssd_infopipe_Ping(handler, data) ({ \ + SBUS_CHECK_SYNC((handler), (data), const char *, const char **); \ + sbus_method_sync("Ping", \ + &_sbus_ifp_args_org_freedesktop_sssd_infopipe_Ping, \ + NULL, \ + _sbus_ifp_invoke_in_s_out_s_send, \ + _sbus_ifp_key_s_0, \ + (handler), (data)); \ +}) + +#define SBUS_METHOD_ASYNC_org_freedesktop_sssd_infopipe_Ping(handler_send, handler_recv, data) ({ \ + SBUS_CHECK_SEND((handler_send), (data), const char *); \ + SBUS_CHECK_RECV((handler_recv), const char **); \ + sbus_method_async("Ping", \ + &_sbus_ifp_args_org_freedesktop_sssd_infopipe_Ping, \ + NULL, \ + _sbus_ifp_invoke_in_s_out_s_send, \ + _sbus_ifp_key_s_0, \ + (handler_send), (handler_recv), (data)); \ +}) + +/* Interface: org.freedesktop.sssd.infopipe.Cache */ +#define SBUS_IFACE_org_freedesktop_sssd_infopipe_Cache(methods, signals, properties) ({ \ + sbus_interface("org.freedesktop.sssd.infopipe.Cache", NULL, \ + (methods), (signals), (properties)); \ +}) + +/* Method: org.freedesktop.sssd.infopipe.Cache.List */ +#define SBUS_METHOD_SYNC_org_freedesktop_sssd_infopipe_Cache_List(handler, data) ({ \ + SBUS_CHECK_SYNC((handler), (data), const char ***); \ + sbus_method_sync("List", \ + &_sbus_ifp_args_org_freedesktop_sssd_infopipe_Cache_List, \ + NULL, \ + _sbus_ifp_invoke_in__out_ao_send, \ + _sbus_ifp_key_, \ + (handler), (data)); \ +}) + +#define SBUS_METHOD_ASYNC_org_freedesktop_sssd_infopipe_Cache_List(handler_send, handler_recv, data) ({ \ + SBUS_CHECK_SEND((handler_send), (data)); \ + SBUS_CHECK_RECV((handler_recv), const char ***); \ + sbus_method_async("List", \ + &_sbus_ifp_args_org_freedesktop_sssd_infopipe_Cache_List, \ + NULL, \ + _sbus_ifp_invoke_in__out_ao_send, \ + _sbus_ifp_key_, \ + (handler_send), (handler_recv), (data)); \ +}) + +/* Method: org.freedesktop.sssd.infopipe.Cache.ListByDomain */ +#define SBUS_METHOD_SYNC_org_freedesktop_sssd_infopipe_Cache_ListByDomain(handler, data) ({ \ + SBUS_CHECK_SYNC((handler), (data), const char *, const char ***); \ + sbus_method_sync("ListByDomain", \ + &_sbus_ifp_args_org_freedesktop_sssd_infopipe_Cache_ListByDomain, \ + NULL, \ + _sbus_ifp_invoke_in_s_out_ao_send, \ + _sbus_ifp_key_s_0, \ + (handler), (data)); \ +}) + +#define SBUS_METHOD_ASYNC_org_freedesktop_sssd_infopipe_Cache_ListByDomain(handler_send, handler_recv, data) ({ \ + SBUS_CHECK_SEND((handler_send), (data), const char *); \ + SBUS_CHECK_RECV((handler_recv), const char ***); \ + sbus_method_async("ListByDomain", \ + &_sbus_ifp_args_org_freedesktop_sssd_infopipe_Cache_ListByDomain, \ + NULL, \ + _sbus_ifp_invoke_in_s_out_ao_send, \ + _sbus_ifp_key_s_0, \ + (handler_send), (handler_recv), (data)); \ +}) + +/* Interface: org.freedesktop.sssd.infopipe.Cache.Object */ +#define SBUS_IFACE_org_freedesktop_sssd_infopipe_Cache_Object(methods, signals, properties) ({ \ + sbus_interface("org.freedesktop.sssd.infopipe.Cache.Object", NULL, \ + (methods), (signals), (properties)); \ +}) + +/* Method: org.freedesktop.sssd.infopipe.Cache.Object.Remove */ +#define SBUS_METHOD_SYNC_org_freedesktop_sssd_infopipe_Cache_Object_Remove(handler, data) ({ \ + SBUS_CHECK_SYNC((handler), (data), bool*); \ + sbus_method_sync("Remove", \ + &_sbus_ifp_args_org_freedesktop_sssd_infopipe_Cache_Object_Remove, \ + NULL, \ + _sbus_ifp_invoke_in__out_b_send, \ + _sbus_ifp_key_, \ + (handler), (data)); \ +}) + +#define SBUS_METHOD_ASYNC_org_freedesktop_sssd_infopipe_Cache_Object_Remove(handler_send, handler_recv, data) ({ \ + SBUS_CHECK_SEND((handler_send), (data)); \ + SBUS_CHECK_RECV((handler_recv), bool*); \ + sbus_method_async("Remove", \ + &_sbus_ifp_args_org_freedesktop_sssd_infopipe_Cache_Object_Remove, \ + NULL, \ + _sbus_ifp_invoke_in__out_b_send, \ + _sbus_ifp_key_, \ + (handler_send), (handler_recv), (data)); \ +}) + +/* Method: org.freedesktop.sssd.infopipe.Cache.Object.Store */ +#define SBUS_METHOD_SYNC_org_freedesktop_sssd_infopipe_Cache_Object_Store(handler, data) ({ \ + SBUS_CHECK_SYNC((handler), (data), bool*); \ + sbus_method_sync("Store", \ + &_sbus_ifp_args_org_freedesktop_sssd_infopipe_Cache_Object_Store, \ + NULL, \ + _sbus_ifp_invoke_in__out_b_send, \ + _sbus_ifp_key_, \ + (handler), (data)); \ +}) + +#define SBUS_METHOD_ASYNC_org_freedesktop_sssd_infopipe_Cache_Object_Store(handler_send, handler_recv, data) ({ \ + SBUS_CHECK_SEND((handler_send), (data)); \ + SBUS_CHECK_RECV((handler_recv), bool*); \ + sbus_method_async("Store", \ + &_sbus_ifp_args_org_freedesktop_sssd_infopipe_Cache_Object_Store, \ + NULL, \ + _sbus_ifp_invoke_in__out_b_send, \ + _sbus_ifp_key_, \ + (handler_send), (handler_recv), (data)); \ +}) + +/* Interface: org.freedesktop.sssd.infopipe.Components */ +#define SBUS_IFACE_org_freedesktop_sssd_infopipe_Components(methods, signals, properties) ({ \ + sbus_interface("org.freedesktop.sssd.infopipe.Components", NULL, \ + (methods), (signals), (properties)); \ +}) + +/* Property: org.freedesktop.sssd.infopipe.Components.debug_level */ +#define SBUS_GETTER_SYNC_org_freedesktop_sssd_infopipe_Components_debug_level(handler, data) ({ \ + SBUS_CHECK_SYNC((handler), (data), uint32_t*); \ + sbus_property_sync("debug_level", "u", SBUS_PROPERTY_READABLE, \ + NULL, \ + _sbus_ifp_invoke_in__out_u_send, \ + (handler), (data)); \ +}) + +#define SBUS_GETTER_ASYNC_org_freedesktop_sssd_infopipe_Components_debug_level(handler_send, handler_recv, data) ({ \ + SBUS_CHECK_SEND((handler_send), (data)); \ + SBUS_CHECK_RECV((handler_recv), uint32_t*); \ + sbus_property_async("debug_level", "u", SBUS_PROPERTY_READABLE, \ + NULL, \ + _sbus_ifp_invoke_in__out_u_send, \ + (handler_send), (handler_recv), (data)); \ +}) + +#define SBUS_SETTER_SYNC_org_freedesktop_sssd_infopipe_Components_debug_level(handler, data) ({\ + SBUS_CHECK_SYNC((handler), (data)); \ + sbus_property_sync("debug_level", "u", SBUS_PROPERTY_WRITABLE, \ + NULL, \ + _sbus_ifp_invoke_in__out__send, \ + (handler), (data)); \ +}) + +#define SBUS_SETTER_ASYNC_org_freedesktop_sssd_infopipe_Components_debug_level(handler_send, handler_recv, data) ({ \ + SBUS_CHECK_SEND((handler_send), (data)); \ + SBUS_CHECK_RECV((handler_recv)); \ + sbus_property_async("debug_level", "u", SBUS_PROPERTY_WRITABLE, \ + NULL, \ + _sbus_ifp_invoke_in__out__send, \ + (handler_send), (handler_recv), (data)); \ +}) + +/* Property: org.freedesktop.sssd.infopipe.Components.enabled */ +#define SBUS_GETTER_SYNC_org_freedesktop_sssd_infopipe_Components_enabled(handler, data) ({ \ + SBUS_CHECK_SYNC((handler), (data), bool*); \ + sbus_property_sync("enabled", "b", SBUS_PROPERTY_READABLE, \ + NULL, \ + _sbus_ifp_invoke_in__out_b_send, \ + (handler), (data)); \ +}) + +#define SBUS_GETTER_ASYNC_org_freedesktop_sssd_infopipe_Components_enabled(handler_send, handler_recv, data) ({ \ + SBUS_CHECK_SEND((handler_send), (data)); \ + SBUS_CHECK_RECV((handler_recv), bool*); \ + sbus_property_async("enabled", "b", SBUS_PROPERTY_READABLE, \ + NULL, \ + _sbus_ifp_invoke_in__out_b_send, \ + (handler_send), (handler_recv), (data)); \ +}) + +#define SBUS_SETTER_SYNC_org_freedesktop_sssd_infopipe_Components_enabled(handler, data) ({\ + SBUS_CHECK_SYNC((handler), (data)); \ + sbus_property_sync("enabled", "b", SBUS_PROPERTY_WRITABLE, \ + NULL, \ + _sbus_ifp_invoke_in__out__send, \ + (handler), (data)); \ +}) + +#define SBUS_SETTER_ASYNC_org_freedesktop_sssd_infopipe_Components_enabled(handler_send, handler_recv, data) ({ \ + SBUS_CHECK_SEND((handler_send), (data)); \ + SBUS_CHECK_RECV((handler_recv)); \ + sbus_property_async("enabled", "b", SBUS_PROPERTY_WRITABLE, \ + NULL, \ + _sbus_ifp_invoke_in__out__send, \ + (handler_send), (handler_recv), (data)); \ +}) + +/* Property: org.freedesktop.sssd.infopipe.Components.name */ +#define SBUS_GETTER_SYNC_org_freedesktop_sssd_infopipe_Components_name(handler, data) ({ \ + SBUS_CHECK_SYNC((handler), (data), const char **); \ + sbus_property_sync("name", "s", SBUS_PROPERTY_READABLE, \ + NULL, \ + _sbus_ifp_invoke_in__out_s_send, \ + (handler), (data)); \ +}) + +#define SBUS_GETTER_ASYNC_org_freedesktop_sssd_infopipe_Components_name(handler_send, handler_recv, data) ({ \ + SBUS_CHECK_SEND((handler_send), (data)); \ + SBUS_CHECK_RECV((handler_recv), const char **); \ + sbus_property_async("name", "s", SBUS_PROPERTY_READABLE, \ + NULL, \ + _sbus_ifp_invoke_in__out_s_send, \ + (handler_send), (handler_recv), (data)); \ +}) + +#define SBUS_SETTER_SYNC_org_freedesktop_sssd_infopipe_Components_name(handler, data) ({\ + SBUS_CHECK_SYNC((handler), (data)); \ + sbus_property_sync("name", "s", SBUS_PROPERTY_WRITABLE, \ + NULL, \ + _sbus_ifp_invoke_in__out__send, \ + (handler), (data)); \ +}) + +#define SBUS_SETTER_ASYNC_org_freedesktop_sssd_infopipe_Components_name(handler_send, handler_recv, data) ({ \ + SBUS_CHECK_SEND((handler_send), (data)); \ + SBUS_CHECK_RECV((handler_recv)); \ + sbus_property_async("name", "s", SBUS_PROPERTY_WRITABLE, \ + NULL, \ + _sbus_ifp_invoke_in__out__send, \ + (handler_send), (handler_recv), (data)); \ +}) + +/* Property: org.freedesktop.sssd.infopipe.Components.providers */ +#define SBUS_GETTER_SYNC_org_freedesktop_sssd_infopipe_Components_providers(handler, data) ({ \ + SBUS_CHECK_SYNC((handler), (data), const char ***); \ + sbus_property_sync("providers", "as", SBUS_PROPERTY_READABLE, \ + NULL, \ + _sbus_ifp_invoke_in__out_as_send, \ + (handler), (data)); \ +}) + +#define SBUS_GETTER_ASYNC_org_freedesktop_sssd_infopipe_Components_providers(handler_send, handler_recv, data) ({ \ + SBUS_CHECK_SEND((handler_send), (data)); \ + SBUS_CHECK_RECV((handler_recv), const char ***); \ + sbus_property_async("providers", "as", SBUS_PROPERTY_READABLE, \ + NULL, \ + _sbus_ifp_invoke_in__out_as_send, \ + (handler_send), (handler_recv), (data)); \ +}) + +#define SBUS_SETTER_SYNC_org_freedesktop_sssd_infopipe_Components_providers(handler, data) ({\ + SBUS_CHECK_SYNC((handler), (data)); \ + sbus_property_sync("providers", "as", SBUS_PROPERTY_WRITABLE, \ + NULL, \ + _sbus_ifp_invoke_in__out__send, \ + (handler), (data)); \ +}) + +#define SBUS_SETTER_ASYNC_org_freedesktop_sssd_infopipe_Components_providers(handler_send, handler_recv, data) ({ \ + SBUS_CHECK_SEND((handler_send), (data)); \ + SBUS_CHECK_RECV((handler_recv)); \ + sbus_property_async("providers", "as", SBUS_PROPERTY_WRITABLE, \ + NULL, \ + _sbus_ifp_invoke_in__out__send, \ + (handler_send), (handler_recv), (data)); \ +}) + +/* Property: org.freedesktop.sssd.infopipe.Components.type */ +#define SBUS_GETTER_SYNC_org_freedesktop_sssd_infopipe_Components_type(handler, data) ({ \ + SBUS_CHECK_SYNC((handler), (data), const char **); \ + sbus_property_sync("type", "s", SBUS_PROPERTY_READABLE, \ + NULL, \ + _sbus_ifp_invoke_in__out_s_send, \ + (handler), (data)); \ +}) + +#define SBUS_GETTER_ASYNC_org_freedesktop_sssd_infopipe_Components_type(handler_send, handler_recv, data) ({ \ + SBUS_CHECK_SEND((handler_send), (data)); \ + SBUS_CHECK_RECV((handler_recv), const char **); \ + sbus_property_async("type", "s", SBUS_PROPERTY_READABLE, \ + NULL, \ + _sbus_ifp_invoke_in__out_s_send, \ + (handler_send), (handler_recv), (data)); \ +}) + +#define SBUS_SETTER_SYNC_org_freedesktop_sssd_infopipe_Components_type(handler, data) ({\ + SBUS_CHECK_SYNC((handler), (data)); \ + sbus_property_sync("type", "s", SBUS_PROPERTY_WRITABLE, \ + NULL, \ + _sbus_ifp_invoke_in__out__send, \ + (handler), (data)); \ +}) + +#define SBUS_SETTER_ASYNC_org_freedesktop_sssd_infopipe_Components_type(handler_send, handler_recv, data) ({ \ + SBUS_CHECK_SEND((handler_send), (data)); \ + SBUS_CHECK_RECV((handler_recv)); \ + sbus_property_async("type", "s", SBUS_PROPERTY_WRITABLE, \ + NULL, \ + _sbus_ifp_invoke_in__out__send, \ + (handler_send), (handler_recv), (data)); \ +}) + +/* Interface: org.freedesktop.sssd.infopipe.Domains */ +#define SBUS_IFACE_org_freedesktop_sssd_infopipe_Domains(methods, signals, properties) ({ \ + sbus_interface("org.freedesktop.sssd.infopipe.Domains", NULL, \ + (methods), (signals), (properties)); \ +}) + +/* Property: org.freedesktop.sssd.infopipe.Domains.backup_servers */ +#define SBUS_GETTER_SYNC_org_freedesktop_sssd_infopipe_Domains_backup_servers(handler, data) ({ \ + SBUS_CHECK_SYNC((handler), (data), const char ***); \ + sbus_property_sync("backup_servers", "as", SBUS_PROPERTY_READABLE, \ + NULL, \ + _sbus_ifp_invoke_in__out_as_send, \ + (handler), (data)); \ +}) + +#define SBUS_GETTER_ASYNC_org_freedesktop_sssd_infopipe_Domains_backup_servers(handler_send, handler_recv, data) ({ \ + SBUS_CHECK_SEND((handler_send), (data)); \ + SBUS_CHECK_RECV((handler_recv), const char ***); \ + sbus_property_async("backup_servers", "as", SBUS_PROPERTY_READABLE, \ + NULL, \ + _sbus_ifp_invoke_in__out_as_send, \ + (handler_send), (handler_recv), (data)); \ +}) + +#define SBUS_SETTER_SYNC_org_freedesktop_sssd_infopipe_Domains_backup_servers(handler, data) ({\ + SBUS_CHECK_SYNC((handler), (data)); \ + sbus_property_sync("backup_servers", "as", SBUS_PROPERTY_WRITABLE, \ + NULL, \ + _sbus_ifp_invoke_in__out__send, \ + (handler), (data)); \ +}) + +#define SBUS_SETTER_ASYNC_org_freedesktop_sssd_infopipe_Domains_backup_servers(handler_send, handler_recv, data) ({ \ + SBUS_CHECK_SEND((handler_send), (data)); \ + SBUS_CHECK_RECV((handler_recv)); \ + sbus_property_async("backup_servers", "as", SBUS_PROPERTY_WRITABLE, \ + NULL, \ + _sbus_ifp_invoke_in__out__send, \ + (handler_send), (handler_recv), (data)); \ +}) + +/* Property: org.freedesktop.sssd.infopipe.Domains.enumerable */ +#define SBUS_GETTER_SYNC_org_freedesktop_sssd_infopipe_Domains_enumerable(handler, data) ({ \ + SBUS_CHECK_SYNC((handler), (data), bool*); \ + sbus_property_sync("enumerable", "b", SBUS_PROPERTY_READABLE, \ + NULL, \ + _sbus_ifp_invoke_in__out_b_send, \ + (handler), (data)); \ +}) + +#define SBUS_GETTER_ASYNC_org_freedesktop_sssd_infopipe_Domains_enumerable(handler_send, handler_recv, data) ({ \ + SBUS_CHECK_SEND((handler_send), (data)); \ + SBUS_CHECK_RECV((handler_recv), bool*); \ + sbus_property_async("enumerable", "b", SBUS_PROPERTY_READABLE, \ + NULL, \ + _sbus_ifp_invoke_in__out_b_send, \ + (handler_send), (handler_recv), (data)); \ +}) + +#define SBUS_SETTER_SYNC_org_freedesktop_sssd_infopipe_Domains_enumerable(handler, data) ({\ + SBUS_CHECK_SYNC((handler), (data)); \ + sbus_property_sync("enumerable", "b", SBUS_PROPERTY_WRITABLE, \ + NULL, \ + _sbus_ifp_invoke_in__out__send, \ + (handler), (data)); \ +}) + +#define SBUS_SETTER_ASYNC_org_freedesktop_sssd_infopipe_Domains_enumerable(handler_send, handler_recv, data) ({ \ + SBUS_CHECK_SEND((handler_send), (data)); \ + SBUS_CHECK_RECV((handler_recv)); \ + sbus_property_async("enumerable", "b", SBUS_PROPERTY_WRITABLE, \ + NULL, \ + _sbus_ifp_invoke_in__out__send, \ + (handler_send), (handler_recv), (data)); \ +}) + +/* Property: org.freedesktop.sssd.infopipe.Domains.forest */ +#define SBUS_GETTER_SYNC_org_freedesktop_sssd_infopipe_Domains_forest(handler, data) ({ \ + SBUS_CHECK_SYNC((handler), (data), const char **); \ + sbus_property_sync("forest", "s", SBUS_PROPERTY_READABLE, \ + NULL, \ + _sbus_ifp_invoke_in__out_s_send, \ + (handler), (data)); \ +}) + +#define SBUS_GETTER_ASYNC_org_freedesktop_sssd_infopipe_Domains_forest(handler_send, handler_recv, data) ({ \ + SBUS_CHECK_SEND((handler_send), (data)); \ + SBUS_CHECK_RECV((handler_recv), const char **); \ + sbus_property_async("forest", "s", SBUS_PROPERTY_READABLE, \ + NULL, \ + _sbus_ifp_invoke_in__out_s_send, \ + (handler_send), (handler_recv), (data)); \ +}) + +#define SBUS_SETTER_SYNC_org_freedesktop_sssd_infopipe_Domains_forest(handler, data) ({\ + SBUS_CHECK_SYNC((handler), (data)); \ + sbus_property_sync("forest", "s", SBUS_PROPERTY_WRITABLE, \ + NULL, \ + _sbus_ifp_invoke_in__out__send, \ + (handler), (data)); \ +}) + +#define SBUS_SETTER_ASYNC_org_freedesktop_sssd_infopipe_Domains_forest(handler_send, handler_recv, data) ({ \ + SBUS_CHECK_SEND((handler_send), (data)); \ + SBUS_CHECK_RECV((handler_recv)); \ + sbus_property_async("forest", "s", SBUS_PROPERTY_WRITABLE, \ + NULL, \ + _sbus_ifp_invoke_in__out__send, \ + (handler_send), (handler_recv), (data)); \ +}) + +/* Property: org.freedesktop.sssd.infopipe.Domains.fully_qualified_name_format */ +#define SBUS_GETTER_SYNC_org_freedesktop_sssd_infopipe_Domains_fully_qualified_name_format(handler, data) ({ \ + SBUS_CHECK_SYNC((handler), (data), const char **); \ + sbus_property_sync("fully_qualified_name_format", "s", SBUS_PROPERTY_READABLE, \ + NULL, \ + _sbus_ifp_invoke_in__out_s_send, \ + (handler), (data)); \ +}) + +#define SBUS_GETTER_ASYNC_org_freedesktop_sssd_infopipe_Domains_fully_qualified_name_format(handler_send, handler_recv, data) ({ \ + SBUS_CHECK_SEND((handler_send), (data)); \ + SBUS_CHECK_RECV((handler_recv), const char **); \ + sbus_property_async("fully_qualified_name_format", "s", SBUS_PROPERTY_READABLE, \ + NULL, \ + _sbus_ifp_invoke_in__out_s_send, \ + (handler_send), (handler_recv), (data)); \ +}) + +#define SBUS_SETTER_SYNC_org_freedesktop_sssd_infopipe_Domains_fully_qualified_name_format(handler, data) ({\ + SBUS_CHECK_SYNC((handler), (data)); \ + sbus_property_sync("fully_qualified_name_format", "s", SBUS_PROPERTY_WRITABLE, \ + NULL, \ + _sbus_ifp_invoke_in__out__send, \ + (handler), (data)); \ +}) + +#define SBUS_SETTER_ASYNC_org_freedesktop_sssd_infopipe_Domains_fully_qualified_name_format(handler_send, handler_recv, data) ({ \ + SBUS_CHECK_SEND((handler_send), (data)); \ + SBUS_CHECK_RECV((handler_recv)); \ + sbus_property_async("fully_qualified_name_format", "s", SBUS_PROPERTY_WRITABLE, \ + NULL, \ + _sbus_ifp_invoke_in__out__send, \ + (handler_send), (handler_recv), (data)); \ +}) + +/* Property: org.freedesktop.sssd.infopipe.Domains.login_format */ +#define SBUS_GETTER_SYNC_org_freedesktop_sssd_infopipe_Domains_login_format(handler, data) ({ \ + SBUS_CHECK_SYNC((handler), (data), const char **); \ + sbus_property_sync("login_format", "s", SBUS_PROPERTY_READABLE, \ + NULL, \ + _sbus_ifp_invoke_in__out_s_send, \ + (handler), (data)); \ +}) + +#define SBUS_GETTER_ASYNC_org_freedesktop_sssd_infopipe_Domains_login_format(handler_send, handler_recv, data) ({ \ + SBUS_CHECK_SEND((handler_send), (data)); \ + SBUS_CHECK_RECV((handler_recv), const char **); \ + sbus_property_async("login_format", "s", SBUS_PROPERTY_READABLE, \ + NULL, \ + _sbus_ifp_invoke_in__out_s_send, \ + (handler_send), (handler_recv), (data)); \ +}) + +#define SBUS_SETTER_SYNC_org_freedesktop_sssd_infopipe_Domains_login_format(handler, data) ({\ + SBUS_CHECK_SYNC((handler), (data)); \ + sbus_property_sync("login_format", "s", SBUS_PROPERTY_WRITABLE, \ + NULL, \ + _sbus_ifp_invoke_in__out__send, \ + (handler), (data)); \ +}) + +#define SBUS_SETTER_ASYNC_org_freedesktop_sssd_infopipe_Domains_login_format(handler_send, handler_recv, data) ({ \ + SBUS_CHECK_SEND((handler_send), (data)); \ + SBUS_CHECK_RECV((handler_recv)); \ + sbus_property_async("login_format", "s", SBUS_PROPERTY_WRITABLE, \ + NULL, \ + _sbus_ifp_invoke_in__out__send, \ + (handler_send), (handler_recv), (data)); \ +}) + +/* Property: org.freedesktop.sssd.infopipe.Domains.max_id */ +#define SBUS_GETTER_SYNC_org_freedesktop_sssd_infopipe_Domains_max_id(handler, data) ({ \ + SBUS_CHECK_SYNC((handler), (data), uint32_t*); \ + sbus_property_sync("max_id", "u", SBUS_PROPERTY_READABLE, \ + NULL, \ + _sbus_ifp_invoke_in__out_u_send, \ + (handler), (data)); \ +}) + +#define SBUS_GETTER_ASYNC_org_freedesktop_sssd_infopipe_Domains_max_id(handler_send, handler_recv, data) ({ \ + SBUS_CHECK_SEND((handler_send), (data)); \ + SBUS_CHECK_RECV((handler_recv), uint32_t*); \ + sbus_property_async("max_id", "u", SBUS_PROPERTY_READABLE, \ + NULL, \ + _sbus_ifp_invoke_in__out_u_send, \ + (handler_send), (handler_recv), (data)); \ +}) + +#define SBUS_SETTER_SYNC_org_freedesktop_sssd_infopipe_Domains_max_id(handler, data) ({\ + SBUS_CHECK_SYNC((handler), (data)); \ + sbus_property_sync("max_id", "u", SBUS_PROPERTY_WRITABLE, \ + NULL, \ + _sbus_ifp_invoke_in__out__send, \ + (handler), (data)); \ +}) + +#define SBUS_SETTER_ASYNC_org_freedesktop_sssd_infopipe_Domains_max_id(handler_send, handler_recv, data) ({ \ + SBUS_CHECK_SEND((handler_send), (data)); \ + SBUS_CHECK_RECV((handler_recv)); \ + sbus_property_async("max_id", "u", SBUS_PROPERTY_WRITABLE, \ + NULL, \ + _sbus_ifp_invoke_in__out__send, \ + (handler_send), (handler_recv), (data)); \ +}) + +/* Property: org.freedesktop.sssd.infopipe.Domains.min_id */ +#define SBUS_GETTER_SYNC_org_freedesktop_sssd_infopipe_Domains_min_id(handler, data) ({ \ + SBUS_CHECK_SYNC((handler), (data), uint32_t*); \ + sbus_property_sync("min_id", "u", SBUS_PROPERTY_READABLE, \ + NULL, \ + _sbus_ifp_invoke_in__out_u_send, \ + (handler), (data)); \ +}) + +#define SBUS_GETTER_ASYNC_org_freedesktop_sssd_infopipe_Domains_min_id(handler_send, handler_recv, data) ({ \ + SBUS_CHECK_SEND((handler_send), (data)); \ + SBUS_CHECK_RECV((handler_recv), uint32_t*); \ + sbus_property_async("min_id", "u", SBUS_PROPERTY_READABLE, \ + NULL, \ + _sbus_ifp_invoke_in__out_u_send, \ + (handler_send), (handler_recv), (data)); \ +}) + +#define SBUS_SETTER_SYNC_org_freedesktop_sssd_infopipe_Domains_min_id(handler, data) ({\ + SBUS_CHECK_SYNC((handler), (data)); \ + sbus_property_sync("min_id", "u", SBUS_PROPERTY_WRITABLE, \ + NULL, \ + _sbus_ifp_invoke_in__out__send, \ + (handler), (data)); \ +}) + +#define SBUS_SETTER_ASYNC_org_freedesktop_sssd_infopipe_Domains_min_id(handler_send, handler_recv, data) ({ \ + SBUS_CHECK_SEND((handler_send), (data)); \ + SBUS_CHECK_RECV((handler_recv)); \ + sbus_property_async("min_id", "u", SBUS_PROPERTY_WRITABLE, \ + NULL, \ + _sbus_ifp_invoke_in__out__send, \ + (handler_send), (handler_recv), (data)); \ +}) + +/* Property: org.freedesktop.sssd.infopipe.Domains.name */ +#define SBUS_GETTER_SYNC_org_freedesktop_sssd_infopipe_Domains_name(handler, data) ({ \ + SBUS_CHECK_SYNC((handler), (data), const char **); \ + sbus_property_sync("name", "s", SBUS_PROPERTY_READABLE, \ + NULL, \ + _sbus_ifp_invoke_in__out_s_send, \ + (handler), (data)); \ +}) + +#define SBUS_GETTER_ASYNC_org_freedesktop_sssd_infopipe_Domains_name(handler_send, handler_recv, data) ({ \ + SBUS_CHECK_SEND((handler_send), (data)); \ + SBUS_CHECK_RECV((handler_recv), const char **); \ + sbus_property_async("name", "s", SBUS_PROPERTY_READABLE, \ + NULL, \ + _sbus_ifp_invoke_in__out_s_send, \ + (handler_send), (handler_recv), (data)); \ +}) + +#define SBUS_SETTER_SYNC_org_freedesktop_sssd_infopipe_Domains_name(handler, data) ({\ + SBUS_CHECK_SYNC((handler), (data)); \ + sbus_property_sync("name", "s", SBUS_PROPERTY_WRITABLE, \ + NULL, \ + _sbus_ifp_invoke_in__out__send, \ + (handler), (data)); \ +}) + +#define SBUS_SETTER_ASYNC_org_freedesktop_sssd_infopipe_Domains_name(handler_send, handler_recv, data) ({ \ + SBUS_CHECK_SEND((handler_send), (data)); \ + SBUS_CHECK_RECV((handler_recv)); \ + sbus_property_async("name", "s", SBUS_PROPERTY_WRITABLE, \ + NULL, \ + _sbus_ifp_invoke_in__out__send, \ + (handler_send), (handler_recv), (data)); \ +}) + +/* Property: org.freedesktop.sssd.infopipe.Domains.parent_domain */ +#define SBUS_GETTER_SYNC_org_freedesktop_sssd_infopipe_Domains_parent_domain(handler, data) ({ \ + SBUS_CHECK_SYNC((handler), (data), const char **); \ + sbus_property_sync("parent_domain", "o", SBUS_PROPERTY_READABLE, \ + NULL, \ + _sbus_ifp_invoke_in__out_o_send, \ + (handler), (data)); \ +}) + +#define SBUS_GETTER_ASYNC_org_freedesktop_sssd_infopipe_Domains_parent_domain(handler_send, handler_recv, data) ({ \ + SBUS_CHECK_SEND((handler_send), (data)); \ + SBUS_CHECK_RECV((handler_recv), const char **); \ + sbus_property_async("parent_domain", "o", SBUS_PROPERTY_READABLE, \ + NULL, \ + _sbus_ifp_invoke_in__out_o_send, \ + (handler_send), (handler_recv), (data)); \ +}) + +#define SBUS_SETTER_SYNC_org_freedesktop_sssd_infopipe_Domains_parent_domain(handler, data) ({\ + SBUS_CHECK_SYNC((handler), (data)); \ + sbus_property_sync("parent_domain", "o", SBUS_PROPERTY_WRITABLE, \ + NULL, \ + _sbus_ifp_invoke_in__out__send, \ + (handler), (data)); \ +}) + +#define SBUS_SETTER_ASYNC_org_freedesktop_sssd_infopipe_Domains_parent_domain(handler_send, handler_recv, data) ({ \ + SBUS_CHECK_SEND((handler_send), (data)); \ + SBUS_CHECK_RECV((handler_recv)); \ + sbus_property_async("parent_domain", "o", SBUS_PROPERTY_WRITABLE, \ + NULL, \ + _sbus_ifp_invoke_in__out__send, \ + (handler_send), (handler_recv), (data)); \ +}) + +/* Property: org.freedesktop.sssd.infopipe.Domains.primary_servers */ +#define SBUS_GETTER_SYNC_org_freedesktop_sssd_infopipe_Domains_primary_servers(handler, data) ({ \ + SBUS_CHECK_SYNC((handler), (data), const char ***); \ + sbus_property_sync("primary_servers", "as", SBUS_PROPERTY_READABLE, \ + NULL, \ + _sbus_ifp_invoke_in__out_as_send, \ + (handler), (data)); \ +}) + +#define SBUS_GETTER_ASYNC_org_freedesktop_sssd_infopipe_Domains_primary_servers(handler_send, handler_recv, data) ({ \ + SBUS_CHECK_SEND((handler_send), (data)); \ + SBUS_CHECK_RECV((handler_recv), const char ***); \ + sbus_property_async("primary_servers", "as", SBUS_PROPERTY_READABLE, \ + NULL, \ + _sbus_ifp_invoke_in__out_as_send, \ + (handler_send), (handler_recv), (data)); \ +}) + +#define SBUS_SETTER_SYNC_org_freedesktop_sssd_infopipe_Domains_primary_servers(handler, data) ({\ + SBUS_CHECK_SYNC((handler), (data)); \ + sbus_property_sync("primary_servers", "as", SBUS_PROPERTY_WRITABLE, \ + NULL, \ + _sbus_ifp_invoke_in__out__send, \ + (handler), (data)); \ +}) + +#define SBUS_SETTER_ASYNC_org_freedesktop_sssd_infopipe_Domains_primary_servers(handler_send, handler_recv, data) ({ \ + SBUS_CHECK_SEND((handler_send), (data)); \ + SBUS_CHECK_RECV((handler_recv)); \ + sbus_property_async("primary_servers", "as", SBUS_PROPERTY_WRITABLE, \ + NULL, \ + _sbus_ifp_invoke_in__out__send, \ + (handler_send), (handler_recv), (data)); \ +}) + +/* Property: org.freedesktop.sssd.infopipe.Domains.provider */ +#define SBUS_GETTER_SYNC_org_freedesktop_sssd_infopipe_Domains_provider(handler, data) ({ \ + SBUS_CHECK_SYNC((handler), (data), const char **); \ + sbus_property_sync("provider", "s", SBUS_PROPERTY_READABLE, \ + NULL, \ + _sbus_ifp_invoke_in__out_s_send, \ + (handler), (data)); \ +}) + +#define SBUS_GETTER_ASYNC_org_freedesktop_sssd_infopipe_Domains_provider(handler_send, handler_recv, data) ({ \ + SBUS_CHECK_SEND((handler_send), (data)); \ + SBUS_CHECK_RECV((handler_recv), const char **); \ + sbus_property_async("provider", "s", SBUS_PROPERTY_READABLE, \ + NULL, \ + _sbus_ifp_invoke_in__out_s_send, \ + (handler_send), (handler_recv), (data)); \ +}) + +#define SBUS_SETTER_SYNC_org_freedesktop_sssd_infopipe_Domains_provider(handler, data) ({\ + SBUS_CHECK_SYNC((handler), (data)); \ + sbus_property_sync("provider", "s", SBUS_PROPERTY_WRITABLE, \ + NULL, \ + _sbus_ifp_invoke_in__out__send, \ + (handler), (data)); \ +}) + +#define SBUS_SETTER_ASYNC_org_freedesktop_sssd_infopipe_Domains_provider(handler_send, handler_recv, data) ({ \ + SBUS_CHECK_SEND((handler_send), (data)); \ + SBUS_CHECK_RECV((handler_recv)); \ + sbus_property_async("provider", "s", SBUS_PROPERTY_WRITABLE, \ + NULL, \ + _sbus_ifp_invoke_in__out__send, \ + (handler_send), (handler_recv), (data)); \ +}) + +/* Property: org.freedesktop.sssd.infopipe.Domains.realm */ +#define SBUS_GETTER_SYNC_org_freedesktop_sssd_infopipe_Domains_realm(handler, data) ({ \ + SBUS_CHECK_SYNC((handler), (data), const char **); \ + sbus_property_sync("realm", "s", SBUS_PROPERTY_READABLE, \ + NULL, \ + _sbus_ifp_invoke_in__out_s_send, \ + (handler), (data)); \ +}) + +#define SBUS_GETTER_ASYNC_org_freedesktop_sssd_infopipe_Domains_realm(handler_send, handler_recv, data) ({ \ + SBUS_CHECK_SEND((handler_send), (data)); \ + SBUS_CHECK_RECV((handler_recv), const char **); \ + sbus_property_async("realm", "s", SBUS_PROPERTY_READABLE, \ + NULL, \ + _sbus_ifp_invoke_in__out_s_send, \ + (handler_send), (handler_recv), (data)); \ +}) + +#define SBUS_SETTER_SYNC_org_freedesktop_sssd_infopipe_Domains_realm(handler, data) ({\ + SBUS_CHECK_SYNC((handler), (data)); \ + sbus_property_sync("realm", "s", SBUS_PROPERTY_WRITABLE, \ + NULL, \ + _sbus_ifp_invoke_in__out__send, \ + (handler), (data)); \ +}) + +#define SBUS_SETTER_ASYNC_org_freedesktop_sssd_infopipe_Domains_realm(handler_send, handler_recv, data) ({ \ + SBUS_CHECK_SEND((handler_send), (data)); \ + SBUS_CHECK_RECV((handler_recv)); \ + sbus_property_async("realm", "s", SBUS_PROPERTY_WRITABLE, \ + NULL, \ + _sbus_ifp_invoke_in__out__send, \ + (handler_send), (handler_recv), (data)); \ +}) + +/* Property: org.freedesktop.sssd.infopipe.Domains.subdomain */ +#define SBUS_GETTER_SYNC_org_freedesktop_sssd_infopipe_Domains_subdomain(handler, data) ({ \ + SBUS_CHECK_SYNC((handler), (data), bool*); \ + sbus_property_sync("subdomain", "b", SBUS_PROPERTY_READABLE, \ + NULL, \ + _sbus_ifp_invoke_in__out_b_send, \ + (handler), (data)); \ +}) + +#define SBUS_GETTER_ASYNC_org_freedesktop_sssd_infopipe_Domains_subdomain(handler_send, handler_recv, data) ({ \ + SBUS_CHECK_SEND((handler_send), (data)); \ + SBUS_CHECK_RECV((handler_recv), bool*); \ + sbus_property_async("subdomain", "b", SBUS_PROPERTY_READABLE, \ + NULL, \ + _sbus_ifp_invoke_in__out_b_send, \ + (handler_send), (handler_recv), (data)); \ +}) + +#define SBUS_SETTER_SYNC_org_freedesktop_sssd_infopipe_Domains_subdomain(handler, data) ({\ + SBUS_CHECK_SYNC((handler), (data)); \ + sbus_property_sync("subdomain", "b", SBUS_PROPERTY_WRITABLE, \ + NULL, \ + _sbus_ifp_invoke_in__out__send, \ + (handler), (data)); \ +}) + +#define SBUS_SETTER_ASYNC_org_freedesktop_sssd_infopipe_Domains_subdomain(handler_send, handler_recv, data) ({ \ + SBUS_CHECK_SEND((handler_send), (data)); \ + SBUS_CHECK_RECV((handler_recv)); \ + sbus_property_async("subdomain", "b", SBUS_PROPERTY_WRITABLE, \ + NULL, \ + _sbus_ifp_invoke_in__out__send, \ + (handler_send), (handler_recv), (data)); \ +}) + +/* Property: org.freedesktop.sssd.infopipe.Domains.use_fully_qualified_names */ +#define SBUS_GETTER_SYNC_org_freedesktop_sssd_infopipe_Domains_use_fully_qualified_names(handler, data) ({ \ + SBUS_CHECK_SYNC((handler), (data), bool*); \ + sbus_property_sync("use_fully_qualified_names", "b", SBUS_PROPERTY_READABLE, \ + NULL, \ + _sbus_ifp_invoke_in__out_b_send, \ + (handler), (data)); \ +}) + +#define SBUS_GETTER_ASYNC_org_freedesktop_sssd_infopipe_Domains_use_fully_qualified_names(handler_send, handler_recv, data) ({ \ + SBUS_CHECK_SEND((handler_send), (data)); \ + SBUS_CHECK_RECV((handler_recv), bool*); \ + sbus_property_async("use_fully_qualified_names", "b", SBUS_PROPERTY_READABLE, \ + NULL, \ + _sbus_ifp_invoke_in__out_b_send, \ + (handler_send), (handler_recv), (data)); \ +}) + +#define SBUS_SETTER_SYNC_org_freedesktop_sssd_infopipe_Domains_use_fully_qualified_names(handler, data) ({\ + SBUS_CHECK_SYNC((handler), (data)); \ + sbus_property_sync("use_fully_qualified_names", "b", SBUS_PROPERTY_WRITABLE, \ + NULL, \ + _sbus_ifp_invoke_in__out__send, \ + (handler), (data)); \ +}) + +#define SBUS_SETTER_ASYNC_org_freedesktop_sssd_infopipe_Domains_use_fully_qualified_names(handler_send, handler_recv, data) ({ \ + SBUS_CHECK_SEND((handler_send), (data)); \ + SBUS_CHECK_RECV((handler_recv)); \ + sbus_property_async("use_fully_qualified_names", "b", SBUS_PROPERTY_WRITABLE, \ + NULL, \ + _sbus_ifp_invoke_in__out__send, \ + (handler_send), (handler_recv), (data)); \ +}) + +/* Interface: org.freedesktop.sssd.infopipe.Domains.Domain */ +#define SBUS_IFACE_org_freedesktop_sssd_infopipe_Domains_Domain(methods, signals, properties) ({ \ + sbus_interface("org.freedesktop.sssd.infopipe.Domains.Domain", NULL, \ + (methods), (signals), (properties)); \ +}) + +/* Method: org.freedesktop.sssd.infopipe.Domains.Domain.ActiveServer */ +#define SBUS_METHOD_SYNC_org_freedesktop_sssd_infopipe_Domains_Domain_ActiveServer(handler, data) ({ \ + SBUS_CHECK_SYNC((handler), (data), const char *, const char **); \ + sbus_method_sync("ActiveServer", \ + &_sbus_ifp_args_org_freedesktop_sssd_infopipe_Domains_Domain_ActiveServer, \ + NULL, \ + _sbus_ifp_invoke_in_s_out_s_send, \ + _sbus_ifp_key_s_0, \ + (handler), (data)); \ +}) + +#define SBUS_METHOD_ASYNC_org_freedesktop_sssd_infopipe_Domains_Domain_ActiveServer(handler_send, handler_recv, data) ({ \ + SBUS_CHECK_SEND((handler_send), (data), const char *); \ + SBUS_CHECK_RECV((handler_recv), const char **); \ + sbus_method_async("ActiveServer", \ + &_sbus_ifp_args_org_freedesktop_sssd_infopipe_Domains_Domain_ActiveServer, \ + NULL, \ + _sbus_ifp_invoke_in_s_out_s_send, \ + _sbus_ifp_key_s_0, \ + (handler_send), (handler_recv), (data)); \ +}) + +/* Method: org.freedesktop.sssd.infopipe.Domains.Domain.IsOnline */ +#define SBUS_METHOD_SYNC_org_freedesktop_sssd_infopipe_Domains_Domain_IsOnline(handler, data) ({ \ + SBUS_CHECK_SYNC((handler), (data), bool*); \ + sbus_method_sync("IsOnline", \ + &_sbus_ifp_args_org_freedesktop_sssd_infopipe_Domains_Domain_IsOnline, \ + NULL, \ + _sbus_ifp_invoke_in__out_b_send, \ + _sbus_ifp_key_, \ + (handler), (data)); \ +}) + +#define SBUS_METHOD_ASYNC_org_freedesktop_sssd_infopipe_Domains_Domain_IsOnline(handler_send, handler_recv, data) ({ \ + SBUS_CHECK_SEND((handler_send), (data)); \ + SBUS_CHECK_RECV((handler_recv), bool*); \ + sbus_method_async("IsOnline", \ + &_sbus_ifp_args_org_freedesktop_sssd_infopipe_Domains_Domain_IsOnline, \ + NULL, \ + _sbus_ifp_invoke_in__out_b_send, \ + _sbus_ifp_key_, \ + (handler_send), (handler_recv), (data)); \ +}) + +/* Method: org.freedesktop.sssd.infopipe.Domains.Domain.ListServers */ +#define SBUS_METHOD_SYNC_org_freedesktop_sssd_infopipe_Domains_Domain_ListServers(handler, data) ({ \ + SBUS_CHECK_SYNC((handler), (data), const char *, const char ***); \ + sbus_method_sync("ListServers", \ + &_sbus_ifp_args_org_freedesktop_sssd_infopipe_Domains_Domain_ListServers, \ + NULL, \ + _sbus_ifp_invoke_in_s_out_as_send, \ + _sbus_ifp_key_s_0, \ + (handler), (data)); \ +}) + +#define SBUS_METHOD_ASYNC_org_freedesktop_sssd_infopipe_Domains_Domain_ListServers(handler_send, handler_recv, data) ({ \ + SBUS_CHECK_SEND((handler_send), (data), const char *); \ + SBUS_CHECK_RECV((handler_recv), const char ***); \ + sbus_method_async("ListServers", \ + &_sbus_ifp_args_org_freedesktop_sssd_infopipe_Domains_Domain_ListServers, \ + NULL, \ + _sbus_ifp_invoke_in_s_out_as_send, \ + _sbus_ifp_key_s_0, \ + (handler_send), (handler_recv), (data)); \ +}) + +/* Method: org.freedesktop.sssd.infopipe.Domains.Domain.ListServices */ +#define SBUS_METHOD_SYNC_org_freedesktop_sssd_infopipe_Domains_Domain_ListServices(handler, data) ({ \ + SBUS_CHECK_SYNC((handler), (data), const char ***); \ + sbus_method_sync("ListServices", \ + &_sbus_ifp_args_org_freedesktop_sssd_infopipe_Domains_Domain_ListServices, \ + NULL, \ + _sbus_ifp_invoke_in__out_as_send, \ + _sbus_ifp_key_, \ + (handler), (data)); \ +}) + +#define SBUS_METHOD_ASYNC_org_freedesktop_sssd_infopipe_Domains_Domain_ListServices(handler_send, handler_recv, data) ({ \ + SBUS_CHECK_SEND((handler_send), (data)); \ + SBUS_CHECK_RECV((handler_recv), const char ***); \ + sbus_method_async("ListServices", \ + &_sbus_ifp_args_org_freedesktop_sssd_infopipe_Domains_Domain_ListServices, \ + NULL, \ + _sbus_ifp_invoke_in__out_as_send, \ + _sbus_ifp_key_, \ + (handler_send), (handler_recv), (data)); \ +}) + +/* Method: org.freedesktop.sssd.infopipe.Domains.Domain.RefreshAccessRules */ +#define SBUS_METHOD_SYNC_org_freedesktop_sssd_infopipe_Domains_Domain_RefreshAccessRules(handler, data) ({ \ + SBUS_CHECK_SYNC((handler), (data)); \ + sbus_method_sync("RefreshAccessRules", \ + &_sbus_ifp_args_org_freedesktop_sssd_infopipe_Domains_Domain_RefreshAccessRules, \ + NULL, \ + _sbus_ifp_invoke_in__out__send, \ + _sbus_ifp_key_, \ + (handler), (data)); \ +}) + +#define SBUS_METHOD_ASYNC_org_freedesktop_sssd_infopipe_Domains_Domain_RefreshAccessRules(handler_send, handler_recv, data) ({ \ + SBUS_CHECK_SEND((handler_send), (data)); \ + SBUS_CHECK_RECV((handler_recv)); \ + sbus_method_async("RefreshAccessRules", \ + &_sbus_ifp_args_org_freedesktop_sssd_infopipe_Domains_Domain_RefreshAccessRules, \ + NULL, \ + _sbus_ifp_invoke_in__out__send, \ + _sbus_ifp_key_, \ + (handler_send), (handler_recv), (data)); \ +}) + +/* Interface: org.freedesktop.sssd.infopipe.Groups */ +#define SBUS_IFACE_org_freedesktop_sssd_infopipe_Groups(methods, signals, properties) ({ \ + sbus_interface("org.freedesktop.sssd.infopipe.Groups", NULL, \ + (methods), (signals), (properties)); \ +}) + +/* Method: org.freedesktop.sssd.infopipe.Groups.FindByID */ +#define SBUS_METHOD_SYNC_org_freedesktop_sssd_infopipe_Groups_FindByID(handler, data) ({ \ + SBUS_CHECK_SYNC((handler), (data), uint32_t, const char **); \ + sbus_method_sync("FindByID", \ + &_sbus_ifp_args_org_freedesktop_sssd_infopipe_Groups_FindByID, \ + NULL, \ + _sbus_ifp_invoke_in_u_out_o_send, \ + _sbus_ifp_key_u_0, \ + (handler), (data)); \ +}) + +#define SBUS_METHOD_ASYNC_org_freedesktop_sssd_infopipe_Groups_FindByID(handler_send, handler_recv, data) ({ \ + SBUS_CHECK_SEND((handler_send), (data), uint32_t); \ + SBUS_CHECK_RECV((handler_recv), const char **); \ + sbus_method_async("FindByID", \ + &_sbus_ifp_args_org_freedesktop_sssd_infopipe_Groups_FindByID, \ + NULL, \ + _sbus_ifp_invoke_in_u_out_o_send, \ + _sbus_ifp_key_u_0, \ + (handler_send), (handler_recv), (data)); \ +}) + +/* Method: org.freedesktop.sssd.infopipe.Groups.FindByName */ +#define SBUS_METHOD_SYNC_org_freedesktop_sssd_infopipe_Groups_FindByName(handler, data) ({ \ + SBUS_CHECK_SYNC((handler), (data), const char *, const char **); \ + sbus_method_sync("FindByName", \ + &_sbus_ifp_args_org_freedesktop_sssd_infopipe_Groups_FindByName, \ + NULL, \ + _sbus_ifp_invoke_in_s_out_o_send, \ + _sbus_ifp_key_s_0, \ + (handler), (data)); \ +}) + +#define SBUS_METHOD_ASYNC_org_freedesktop_sssd_infopipe_Groups_FindByName(handler_send, handler_recv, data) ({ \ + SBUS_CHECK_SEND((handler_send), (data), const char *); \ + SBUS_CHECK_RECV((handler_recv), const char **); \ + sbus_method_async("FindByName", \ + &_sbus_ifp_args_org_freedesktop_sssd_infopipe_Groups_FindByName, \ + NULL, \ + _sbus_ifp_invoke_in_s_out_o_send, \ + _sbus_ifp_key_s_0, \ + (handler_send), (handler_recv), (data)); \ +}) + +/* Method: org.freedesktop.sssd.infopipe.Groups.ListByDomainAndName */ +#define SBUS_METHOD_SYNC_org_freedesktop_sssd_infopipe_Groups_ListByDomainAndName(handler, data) ({ \ + SBUS_CHECK_SYNC((handler), (data), const char *, const char *, uint32_t, const char ***); \ + sbus_method_sync("ListByDomainAndName", \ + &_sbus_ifp_args_org_freedesktop_sssd_infopipe_Groups_ListByDomainAndName, \ + NULL, \ + _sbus_ifp_invoke_in_ssu_out_ao_send, \ + _sbus_ifp_key_ssu_0_1_2, \ + (handler), (data)); \ +}) + +#define SBUS_METHOD_ASYNC_org_freedesktop_sssd_infopipe_Groups_ListByDomainAndName(handler_send, handler_recv, data) ({ \ + SBUS_CHECK_SEND((handler_send), (data), const char *, const char *, uint32_t); \ + SBUS_CHECK_RECV((handler_recv), const char ***); \ + sbus_method_async("ListByDomainAndName", \ + &_sbus_ifp_args_org_freedesktop_sssd_infopipe_Groups_ListByDomainAndName, \ + NULL, \ + _sbus_ifp_invoke_in_ssu_out_ao_send, \ + _sbus_ifp_key_ssu_0_1_2, \ + (handler_send), (handler_recv), (data)); \ +}) + +/* Method: org.freedesktop.sssd.infopipe.Groups.ListByName */ +#define SBUS_METHOD_SYNC_org_freedesktop_sssd_infopipe_Groups_ListByName(handler, data) ({ \ + SBUS_CHECK_SYNC((handler), (data), const char *, uint32_t, const char ***); \ + sbus_method_sync("ListByName", \ + &_sbus_ifp_args_org_freedesktop_sssd_infopipe_Groups_ListByName, \ + NULL, \ + _sbus_ifp_invoke_in_su_out_ao_send, \ + _sbus_ifp_key_su_0_1, \ + (handler), (data)); \ +}) + +#define SBUS_METHOD_ASYNC_org_freedesktop_sssd_infopipe_Groups_ListByName(handler_send, handler_recv, data) ({ \ + SBUS_CHECK_SEND((handler_send), (data), const char *, uint32_t); \ + SBUS_CHECK_RECV((handler_recv), const char ***); \ + sbus_method_async("ListByName", \ + &_sbus_ifp_args_org_freedesktop_sssd_infopipe_Groups_ListByName, \ + NULL, \ + _sbus_ifp_invoke_in_su_out_ao_send, \ + _sbus_ifp_key_su_0_1, \ + (handler_send), (handler_recv), (data)); \ +}) + +/* Interface: org.freedesktop.sssd.infopipe.Groups.Group */ +#define SBUS_IFACE_org_freedesktop_sssd_infopipe_Groups_Group(methods, signals, properties) ({ \ + sbus_interface("org.freedesktop.sssd.infopipe.Groups.Group", NULL, \ + (methods), (signals), (properties)); \ +}) + +/* Method: org.freedesktop.sssd.infopipe.Groups.Group.UpdateMemberList */ +#define SBUS_METHOD_SYNC_org_freedesktop_sssd_infopipe_Groups_Group_UpdateMemberList(handler, data) ({ \ + SBUS_CHECK_SYNC((handler), (data)); \ + sbus_method_sync("UpdateMemberList", \ + &_sbus_ifp_args_org_freedesktop_sssd_infopipe_Groups_Group_UpdateMemberList, \ + NULL, \ + _sbus_ifp_invoke_in__out__send, \ + _sbus_ifp_key_, \ + (handler), (data)); \ +}) + +#define SBUS_METHOD_ASYNC_org_freedesktop_sssd_infopipe_Groups_Group_UpdateMemberList(handler_send, handler_recv, data) ({ \ + SBUS_CHECK_SEND((handler_send), (data)); \ + SBUS_CHECK_RECV((handler_recv)); \ + sbus_method_async("UpdateMemberList", \ + &_sbus_ifp_args_org_freedesktop_sssd_infopipe_Groups_Group_UpdateMemberList, \ + NULL, \ + _sbus_ifp_invoke_in__out__send, \ + _sbus_ifp_key_, \ + (handler_send), (handler_recv), (data)); \ +}) + +/* Property: org.freedesktop.sssd.infopipe.Groups.Group.gidNumber */ +#define SBUS_GETTER_SYNC_org_freedesktop_sssd_infopipe_Groups_Group_gidNumber(handler, data) ({ \ + SBUS_CHECK_SYNC((handler), (data), uint32_t*); \ + sbus_property_sync("gidNumber", "u", SBUS_PROPERTY_READABLE, \ + NULL, \ + _sbus_ifp_invoke_in__out_u_send, \ + (handler), (data)); \ +}) + +#define SBUS_GETTER_ASYNC_org_freedesktop_sssd_infopipe_Groups_Group_gidNumber(handler_send, handler_recv, data) ({ \ + SBUS_CHECK_SEND((handler_send), (data)); \ + SBUS_CHECK_RECV((handler_recv), uint32_t*); \ + sbus_property_async("gidNumber", "u", SBUS_PROPERTY_READABLE, \ + NULL, \ + _sbus_ifp_invoke_in__out_u_send, \ + (handler_send), (handler_recv), (data)); \ +}) + +#define SBUS_SETTER_SYNC_org_freedesktop_sssd_infopipe_Groups_Group_gidNumber(handler, data) ({\ + SBUS_CHECK_SYNC((handler), (data)); \ + sbus_property_sync("gidNumber", "u", SBUS_PROPERTY_WRITABLE, \ + NULL, \ + _sbus_ifp_invoke_in__out__send, \ + (handler), (data)); \ +}) + +#define SBUS_SETTER_ASYNC_org_freedesktop_sssd_infopipe_Groups_Group_gidNumber(handler_send, handler_recv, data) ({ \ + SBUS_CHECK_SEND((handler_send), (data)); \ + SBUS_CHECK_RECV((handler_recv)); \ + sbus_property_async("gidNumber", "u", SBUS_PROPERTY_WRITABLE, \ + NULL, \ + _sbus_ifp_invoke_in__out__send, \ + (handler_send), (handler_recv), (data)); \ +}) + +/* Property: org.freedesktop.sssd.infopipe.Groups.Group.groups */ +#define SBUS_GETTER_SYNC_org_freedesktop_sssd_infopipe_Groups_Group_groups(handler, data) ({ \ + SBUS_CHECK_SYNC((handler), (data), const char ***); \ + sbus_property_sync("groups", "ao", SBUS_PROPERTY_READABLE, \ + NULL, \ + _sbus_ifp_invoke_in__out_ao_send, \ + (handler), (data)); \ +}) + +#define SBUS_GETTER_ASYNC_org_freedesktop_sssd_infopipe_Groups_Group_groups(handler_send, handler_recv, data) ({ \ + SBUS_CHECK_SEND((handler_send), (data)); \ + SBUS_CHECK_RECV((handler_recv), const char ***); \ + sbus_property_async("groups", "ao", SBUS_PROPERTY_READABLE, \ + NULL, \ + _sbus_ifp_invoke_in__out_ao_send, \ + (handler_send), (handler_recv), (data)); \ +}) + +#define SBUS_SETTER_SYNC_org_freedesktop_sssd_infopipe_Groups_Group_groups(handler, data) ({\ + SBUS_CHECK_SYNC((handler), (data)); \ + sbus_property_sync("groups", "ao", SBUS_PROPERTY_WRITABLE, \ + NULL, \ + _sbus_ifp_invoke_in__out__send, \ + (handler), (data)); \ +}) + +#define SBUS_SETTER_ASYNC_org_freedesktop_sssd_infopipe_Groups_Group_groups(handler_send, handler_recv, data) ({ \ + SBUS_CHECK_SEND((handler_send), (data)); \ + SBUS_CHECK_RECV((handler_recv)); \ + sbus_property_async("groups", "ao", SBUS_PROPERTY_WRITABLE, \ + NULL, \ + _sbus_ifp_invoke_in__out__send, \ + (handler_send), (handler_recv), (data)); \ +}) + +/* Property: org.freedesktop.sssd.infopipe.Groups.Group.name */ +#define SBUS_GETTER_SYNC_org_freedesktop_sssd_infopipe_Groups_Group_name(handler, data) ({ \ + SBUS_CHECK_SYNC((handler), (data), const char **); \ + sbus_property_sync("name", "s", SBUS_PROPERTY_READABLE, \ + NULL, \ + _sbus_ifp_invoke_in__out_s_send, \ + (handler), (data)); \ +}) + +#define SBUS_GETTER_ASYNC_org_freedesktop_sssd_infopipe_Groups_Group_name(handler_send, handler_recv, data) ({ \ + SBUS_CHECK_SEND((handler_send), (data)); \ + SBUS_CHECK_RECV((handler_recv), const char **); \ + sbus_property_async("name", "s", SBUS_PROPERTY_READABLE, \ + NULL, \ + _sbus_ifp_invoke_in__out_s_send, \ + (handler_send), (handler_recv), (data)); \ +}) + +#define SBUS_SETTER_SYNC_org_freedesktop_sssd_infopipe_Groups_Group_name(handler, data) ({\ + SBUS_CHECK_SYNC((handler), (data)); \ + sbus_property_sync("name", "s", SBUS_PROPERTY_WRITABLE, \ + NULL, \ + _sbus_ifp_invoke_in__out__send, \ + (handler), (data)); \ +}) + +#define SBUS_SETTER_ASYNC_org_freedesktop_sssd_infopipe_Groups_Group_name(handler_send, handler_recv, data) ({ \ + SBUS_CHECK_SEND((handler_send), (data)); \ + SBUS_CHECK_RECV((handler_recv)); \ + sbus_property_async("name", "s", SBUS_PROPERTY_WRITABLE, \ + NULL, \ + _sbus_ifp_invoke_in__out__send, \ + (handler_send), (handler_recv), (data)); \ +}) + +/* Property: org.freedesktop.sssd.infopipe.Groups.Group.uniqueID */ +#define SBUS_GETTER_SYNC_org_freedesktop_sssd_infopipe_Groups_Group_uniqueID(handler, data) ({ \ + SBUS_CHECK_SYNC((handler), (data), const char **); \ + sbus_property_sync("uniqueID", "s", SBUS_PROPERTY_READABLE, \ + NULL, \ + _sbus_ifp_invoke_in__out_s_send, \ + (handler), (data)); \ +}) + +#define SBUS_GETTER_ASYNC_org_freedesktop_sssd_infopipe_Groups_Group_uniqueID(handler_send, handler_recv, data) ({ \ + SBUS_CHECK_SEND((handler_send), (data)); \ + SBUS_CHECK_RECV((handler_recv), const char **); \ + sbus_property_async("uniqueID", "s", SBUS_PROPERTY_READABLE, \ + NULL, \ + _sbus_ifp_invoke_in__out_s_send, \ + (handler_send), (handler_recv), (data)); \ +}) + +#define SBUS_SETTER_SYNC_org_freedesktop_sssd_infopipe_Groups_Group_uniqueID(handler, data) ({\ + SBUS_CHECK_SYNC((handler), (data)); \ + sbus_property_sync("uniqueID", "s", SBUS_PROPERTY_WRITABLE, \ + NULL, \ + _sbus_ifp_invoke_in__out__send, \ + (handler), (data)); \ +}) + +#define SBUS_SETTER_ASYNC_org_freedesktop_sssd_infopipe_Groups_Group_uniqueID(handler_send, handler_recv, data) ({ \ + SBUS_CHECK_SEND((handler_send), (data)); \ + SBUS_CHECK_RECV((handler_recv)); \ + sbus_property_async("uniqueID", "s", SBUS_PROPERTY_WRITABLE, \ + NULL, \ + _sbus_ifp_invoke_in__out__send, \ + (handler_send), (handler_recv), (data)); \ +}) + +/* Property: org.freedesktop.sssd.infopipe.Groups.Group.users */ +#define SBUS_GETTER_SYNC_org_freedesktop_sssd_infopipe_Groups_Group_users(handler, data) ({ \ + SBUS_CHECK_SYNC((handler), (data), const char ***); \ + sbus_property_sync("users", "ao", SBUS_PROPERTY_READABLE, \ + NULL, \ + _sbus_ifp_invoke_in__out_ao_send, \ + (handler), (data)); \ +}) + +#define SBUS_GETTER_ASYNC_org_freedesktop_sssd_infopipe_Groups_Group_users(handler_send, handler_recv, data) ({ \ + SBUS_CHECK_SEND((handler_send), (data)); \ + SBUS_CHECK_RECV((handler_recv), const char ***); \ + sbus_property_async("users", "ao", SBUS_PROPERTY_READABLE, \ + NULL, \ + _sbus_ifp_invoke_in__out_ao_send, \ + (handler_send), (handler_recv), (data)); \ +}) + +#define SBUS_SETTER_SYNC_org_freedesktop_sssd_infopipe_Groups_Group_users(handler, data) ({\ + SBUS_CHECK_SYNC((handler), (data)); \ + sbus_property_sync("users", "ao", SBUS_PROPERTY_WRITABLE, \ + NULL, \ + _sbus_ifp_invoke_in__out__send, \ + (handler), (data)); \ +}) + +#define SBUS_SETTER_ASYNC_org_freedesktop_sssd_infopipe_Groups_Group_users(handler_send, handler_recv, data) ({ \ + SBUS_CHECK_SEND((handler_send), (data)); \ + SBUS_CHECK_RECV((handler_recv)); \ + sbus_property_async("users", "ao", SBUS_PROPERTY_WRITABLE, \ + NULL, \ + _sbus_ifp_invoke_in__out__send, \ + (handler_send), (handler_recv), (data)); \ +}) + +/* Interface: org.freedesktop.sssd.infopipe.Users */ +#define SBUS_IFACE_org_freedesktop_sssd_infopipe_Users(methods, signals, properties) ({ \ + sbus_interface("org.freedesktop.sssd.infopipe.Users", NULL, \ + (methods), (signals), (properties)); \ +}) + +/* Method: org.freedesktop.sssd.infopipe.Users.FindByCertificate */ +#define SBUS_METHOD_SYNC_org_freedesktop_sssd_infopipe_Users_FindByCertificate(handler, data) ({ \ + SBUS_CHECK_SYNC((handler), (data), const char *, const char **); \ + sbus_method_sync("FindByCertificate", \ + &_sbus_ifp_args_org_freedesktop_sssd_infopipe_Users_FindByCertificate, \ + NULL, \ + _sbus_ifp_invoke_in_s_out_o_send, \ + NULL, \ + (handler), (data)); \ +}) + +#define SBUS_METHOD_ASYNC_org_freedesktop_sssd_infopipe_Users_FindByCertificate(handler_send, handler_recv, data) ({ \ + SBUS_CHECK_SEND((handler_send), (data), const char *); \ + SBUS_CHECK_RECV((handler_recv), const char **); \ + sbus_method_async("FindByCertificate", \ + &_sbus_ifp_args_org_freedesktop_sssd_infopipe_Users_FindByCertificate, \ + NULL, \ + _sbus_ifp_invoke_in_s_out_o_send, \ + NULL, \ + (handler_send), (handler_recv), (data)); \ +}) + +/* Method: org.freedesktop.sssd.infopipe.Users.FindByID */ +#define SBUS_METHOD_SYNC_org_freedesktop_sssd_infopipe_Users_FindByID(handler, data) ({ \ + SBUS_CHECK_SYNC((handler), (data), uint32_t, const char **); \ + sbus_method_sync("FindByID", \ + &_sbus_ifp_args_org_freedesktop_sssd_infopipe_Users_FindByID, \ + NULL, \ + _sbus_ifp_invoke_in_u_out_o_send, \ + _sbus_ifp_key_u_0, \ + (handler), (data)); \ +}) + +#define SBUS_METHOD_ASYNC_org_freedesktop_sssd_infopipe_Users_FindByID(handler_send, handler_recv, data) ({ \ + SBUS_CHECK_SEND((handler_send), (data), uint32_t); \ + SBUS_CHECK_RECV((handler_recv), const char **); \ + sbus_method_async("FindByID", \ + &_sbus_ifp_args_org_freedesktop_sssd_infopipe_Users_FindByID, \ + NULL, \ + _sbus_ifp_invoke_in_u_out_o_send, \ + _sbus_ifp_key_u_0, \ + (handler_send), (handler_recv), (data)); \ +}) + +/* Method: org.freedesktop.sssd.infopipe.Users.FindByName */ +#define SBUS_METHOD_SYNC_org_freedesktop_sssd_infopipe_Users_FindByName(handler, data) ({ \ + SBUS_CHECK_SYNC((handler), (data), const char *, const char **); \ + sbus_method_sync("FindByName", \ + &_sbus_ifp_args_org_freedesktop_sssd_infopipe_Users_FindByName, \ + NULL, \ + _sbus_ifp_invoke_in_s_out_o_send, \ + _sbus_ifp_key_s_0, \ + (handler), (data)); \ +}) + +#define SBUS_METHOD_ASYNC_org_freedesktop_sssd_infopipe_Users_FindByName(handler_send, handler_recv, data) ({ \ + SBUS_CHECK_SEND((handler_send), (data), const char *); \ + SBUS_CHECK_RECV((handler_recv), const char **); \ + sbus_method_async("FindByName", \ + &_sbus_ifp_args_org_freedesktop_sssd_infopipe_Users_FindByName, \ + NULL, \ + _sbus_ifp_invoke_in_s_out_o_send, \ + _sbus_ifp_key_s_0, \ + (handler_send), (handler_recv), (data)); \ +}) + +/* Method: org.freedesktop.sssd.infopipe.Users.FindByNameAndCertificate */ +#define SBUS_METHOD_SYNC_org_freedesktop_sssd_infopipe_Users_FindByNameAndCertificate(handler, data) ({ \ + SBUS_CHECK_SYNC((handler), (data), const char *, const char *, const char **); \ + sbus_method_sync("FindByNameAndCertificate", \ + &_sbus_ifp_args_org_freedesktop_sssd_infopipe_Users_FindByNameAndCertificate, \ + NULL, \ + _sbus_ifp_invoke_in_ss_out_o_send, \ + NULL, \ + (handler), (data)); \ +}) + +#define SBUS_METHOD_ASYNC_org_freedesktop_sssd_infopipe_Users_FindByNameAndCertificate(handler_send, handler_recv, data) ({ \ + SBUS_CHECK_SEND((handler_send), (data), const char *, const char *); \ + SBUS_CHECK_RECV((handler_recv), const char **); \ + sbus_method_async("FindByNameAndCertificate", \ + &_sbus_ifp_args_org_freedesktop_sssd_infopipe_Users_FindByNameAndCertificate, \ + NULL, \ + _sbus_ifp_invoke_in_ss_out_o_send, \ + NULL, \ + (handler_send), (handler_recv), (data)); \ +}) + +/* Method: org.freedesktop.sssd.infopipe.Users.FindByValidCertificate */ +#define SBUS_METHOD_SYNC_org_freedesktop_sssd_infopipe_Users_FindByValidCertificate(handler, data) ({ \ + SBUS_CHECK_SYNC((handler), (data), const char *, const char **); \ + sbus_method_sync("FindByValidCertificate", \ + &_sbus_ifp_args_org_freedesktop_sssd_infopipe_Users_FindByValidCertificate, \ + NULL, \ + _sbus_ifp_invoke_in_s_out_o_send, \ + NULL, \ + (handler), (data)); \ +}) + +#define SBUS_METHOD_ASYNC_org_freedesktop_sssd_infopipe_Users_FindByValidCertificate(handler_send, handler_recv, data) ({ \ + SBUS_CHECK_SEND((handler_send), (data), const char *); \ + SBUS_CHECK_RECV((handler_recv), const char **); \ + sbus_method_async("FindByValidCertificate", \ + &_sbus_ifp_args_org_freedesktop_sssd_infopipe_Users_FindByValidCertificate, \ + NULL, \ + _sbus_ifp_invoke_in_s_out_o_send, \ + NULL, \ + (handler_send), (handler_recv), (data)); \ +}) + +/* Method: org.freedesktop.sssd.infopipe.Users.ListByAttr */ +#define SBUS_METHOD_SYNC_org_freedesktop_sssd_infopipe_Users_ListByAttr(handler, data) ({ \ + SBUS_CHECK_SYNC((handler), (data), const char *, const char *, uint32_t, const char ***); \ + sbus_method_sync("ListByAttr", \ + &_sbus_ifp_args_org_freedesktop_sssd_infopipe_Users_ListByAttr, \ + NULL, \ + _sbus_ifp_invoke_in_ssu_out_ao_send, \ + _sbus_ifp_key_ssu_0_1_2, \ + (handler), (data)); \ +}) + +#define SBUS_METHOD_ASYNC_org_freedesktop_sssd_infopipe_Users_ListByAttr(handler_send, handler_recv, data) ({ \ + SBUS_CHECK_SEND((handler_send), (data), const char *, const char *, uint32_t); \ + SBUS_CHECK_RECV((handler_recv), const char ***); \ + sbus_method_async("ListByAttr", \ + &_sbus_ifp_args_org_freedesktop_sssd_infopipe_Users_ListByAttr, \ + NULL, \ + _sbus_ifp_invoke_in_ssu_out_ao_send, \ + _sbus_ifp_key_ssu_0_1_2, \ + (handler_send), (handler_recv), (data)); \ +}) + +/* Method: org.freedesktop.sssd.infopipe.Users.ListByCertificate */ +#define SBUS_METHOD_SYNC_org_freedesktop_sssd_infopipe_Users_ListByCertificate(handler, data) ({ \ + SBUS_CHECK_SYNC((handler), (data), const char *, uint32_t, const char ***); \ + sbus_method_sync("ListByCertificate", \ + &_sbus_ifp_args_org_freedesktop_sssd_infopipe_Users_ListByCertificate, \ + NULL, \ + _sbus_ifp_invoke_in_su_out_ao_send, \ + NULL, \ + (handler), (data)); \ +}) + +#define SBUS_METHOD_ASYNC_org_freedesktop_sssd_infopipe_Users_ListByCertificate(handler_send, handler_recv, data) ({ \ + SBUS_CHECK_SEND((handler_send), (data), const char *, uint32_t); \ + SBUS_CHECK_RECV((handler_recv), const char ***); \ + sbus_method_async("ListByCertificate", \ + &_sbus_ifp_args_org_freedesktop_sssd_infopipe_Users_ListByCertificate, \ + NULL, \ + _sbus_ifp_invoke_in_su_out_ao_send, \ + NULL, \ + (handler_send), (handler_recv), (data)); \ +}) + +/* Method: org.freedesktop.sssd.infopipe.Users.ListByDomainAndName */ +#define SBUS_METHOD_SYNC_org_freedesktop_sssd_infopipe_Users_ListByDomainAndName(handler, data) ({ \ + SBUS_CHECK_SYNC((handler), (data), const char *, const char *, uint32_t, const char ***); \ + sbus_method_sync("ListByDomainAndName", \ + &_sbus_ifp_args_org_freedesktop_sssd_infopipe_Users_ListByDomainAndName, \ + NULL, \ + _sbus_ifp_invoke_in_ssu_out_ao_send, \ + _sbus_ifp_key_ssu_0_1_2, \ + (handler), (data)); \ +}) + +#define SBUS_METHOD_ASYNC_org_freedesktop_sssd_infopipe_Users_ListByDomainAndName(handler_send, handler_recv, data) ({ \ + SBUS_CHECK_SEND((handler_send), (data), const char *, const char *, uint32_t); \ + SBUS_CHECK_RECV((handler_recv), const char ***); \ + sbus_method_async("ListByDomainAndName", \ + &_sbus_ifp_args_org_freedesktop_sssd_infopipe_Users_ListByDomainAndName, \ + NULL, \ + _sbus_ifp_invoke_in_ssu_out_ao_send, \ + _sbus_ifp_key_ssu_0_1_2, \ + (handler_send), (handler_recv), (data)); \ +}) + +/* Method: org.freedesktop.sssd.infopipe.Users.ListByName */ +#define SBUS_METHOD_SYNC_org_freedesktop_sssd_infopipe_Users_ListByName(handler, data) ({ \ + SBUS_CHECK_SYNC((handler), (data), const char *, uint32_t, const char ***); \ + sbus_method_sync("ListByName", \ + &_sbus_ifp_args_org_freedesktop_sssd_infopipe_Users_ListByName, \ + NULL, \ + _sbus_ifp_invoke_in_su_out_ao_send, \ + _sbus_ifp_key_su_0_1, \ + (handler), (data)); \ +}) + +#define SBUS_METHOD_ASYNC_org_freedesktop_sssd_infopipe_Users_ListByName(handler_send, handler_recv, data) ({ \ + SBUS_CHECK_SEND((handler_send), (data), const char *, uint32_t); \ + SBUS_CHECK_RECV((handler_recv), const char ***); \ + sbus_method_async("ListByName", \ + &_sbus_ifp_args_org_freedesktop_sssd_infopipe_Users_ListByName, \ + NULL, \ + _sbus_ifp_invoke_in_su_out_ao_send, \ + _sbus_ifp_key_su_0_1, \ + (handler_send), (handler_recv), (data)); \ +}) + +/* Interface: org.freedesktop.sssd.infopipe.Users.User */ +#define SBUS_IFACE_org_freedesktop_sssd_infopipe_Users_User(methods, signals, properties) ({ \ + sbus_interface("org.freedesktop.sssd.infopipe.Users.User", NULL, \ + (methods), (signals), (properties)); \ +}) + +/* Method: org.freedesktop.sssd.infopipe.Users.User.UpdateGroupsList */ +#define SBUS_METHOD_SYNC_org_freedesktop_sssd_infopipe_Users_User_UpdateGroupsList(handler, data) ({ \ + SBUS_CHECK_SYNC((handler), (data)); \ + sbus_method_sync("UpdateGroupsList", \ + &_sbus_ifp_args_org_freedesktop_sssd_infopipe_Users_User_UpdateGroupsList, \ + NULL, \ + _sbus_ifp_invoke_in__out__send, \ + _sbus_ifp_key_, \ + (handler), (data)); \ +}) + +#define SBUS_METHOD_ASYNC_org_freedesktop_sssd_infopipe_Users_User_UpdateGroupsList(handler_send, handler_recv, data) ({ \ + SBUS_CHECK_SEND((handler_send), (data)); \ + SBUS_CHECK_RECV((handler_recv)); \ + sbus_method_async("UpdateGroupsList", \ + &_sbus_ifp_args_org_freedesktop_sssd_infopipe_Users_User_UpdateGroupsList, \ + NULL, \ + _sbus_ifp_invoke_in__out__send, \ + _sbus_ifp_key_, \ + (handler_send), (handler_recv), (data)); \ +}) + +/* Property: org.freedesktop.sssd.infopipe.Users.User.domain */ +#define SBUS_GETTER_SYNC_org_freedesktop_sssd_infopipe_Users_User_domain(handler, data) ({ \ + SBUS_CHECK_SYNC((handler), (data), const char **); \ + sbus_property_sync("domain", "o", SBUS_PROPERTY_READABLE, \ + NULL, \ + _sbus_ifp_invoke_in__out_o_send, \ + (handler), (data)); \ +}) + +#define SBUS_GETTER_ASYNC_org_freedesktop_sssd_infopipe_Users_User_domain(handler_send, handler_recv, data) ({ \ + SBUS_CHECK_SEND((handler_send), (data)); \ + SBUS_CHECK_RECV((handler_recv), const char **); \ + sbus_property_async("domain", "o", SBUS_PROPERTY_READABLE, \ + NULL, \ + _sbus_ifp_invoke_in__out_o_send, \ + (handler_send), (handler_recv), (data)); \ +}) + +#define SBUS_SETTER_SYNC_org_freedesktop_sssd_infopipe_Users_User_domain(handler, data) ({\ + SBUS_CHECK_SYNC((handler), (data)); \ + sbus_property_sync("domain", "o", SBUS_PROPERTY_WRITABLE, \ + NULL, \ + _sbus_ifp_invoke_in__out__send, \ + (handler), (data)); \ +}) + +#define SBUS_SETTER_ASYNC_org_freedesktop_sssd_infopipe_Users_User_domain(handler_send, handler_recv, data) ({ \ + SBUS_CHECK_SEND((handler_send), (data)); \ + SBUS_CHECK_RECV((handler_recv)); \ + sbus_property_async("domain", "o", SBUS_PROPERTY_WRITABLE, \ + NULL, \ + _sbus_ifp_invoke_in__out__send, \ + (handler_send), (handler_recv), (data)); \ +}) + +/* Property: org.freedesktop.sssd.infopipe.Users.User.domainname */ +#define SBUS_GETTER_SYNC_org_freedesktop_sssd_infopipe_Users_User_domainname(handler, data) ({ \ + SBUS_CHECK_SYNC((handler), (data), const char **); \ + sbus_property_sync("domainname", "s", SBUS_PROPERTY_READABLE, \ + NULL, \ + _sbus_ifp_invoke_in__out_s_send, \ + (handler), (data)); \ +}) + +#define SBUS_GETTER_ASYNC_org_freedesktop_sssd_infopipe_Users_User_domainname(handler_send, handler_recv, data) ({ \ + SBUS_CHECK_SEND((handler_send), (data)); \ + SBUS_CHECK_RECV((handler_recv), const char **); \ + sbus_property_async("domainname", "s", SBUS_PROPERTY_READABLE, \ + NULL, \ + _sbus_ifp_invoke_in__out_s_send, \ + (handler_send), (handler_recv), (data)); \ +}) + +#define SBUS_SETTER_SYNC_org_freedesktop_sssd_infopipe_Users_User_domainname(handler, data) ({\ + SBUS_CHECK_SYNC((handler), (data)); \ + sbus_property_sync("domainname", "s", SBUS_PROPERTY_WRITABLE, \ + NULL, \ + _sbus_ifp_invoke_in__out__send, \ + (handler), (data)); \ +}) + +#define SBUS_SETTER_ASYNC_org_freedesktop_sssd_infopipe_Users_User_domainname(handler_send, handler_recv, data) ({ \ + SBUS_CHECK_SEND((handler_send), (data)); \ + SBUS_CHECK_RECV((handler_recv)); \ + sbus_property_async("domainname", "s", SBUS_PROPERTY_WRITABLE, \ + NULL, \ + _sbus_ifp_invoke_in__out__send, \ + (handler_send), (handler_recv), (data)); \ +}) + +/* Property: org.freedesktop.sssd.infopipe.Users.User.extraAttributes */ +#define SBUS_GETTER_SYNC_org_freedesktop_sssd_infopipe_Users_User_extraAttributes(handler, data) ({ \ + SBUS_CHECK_SYNC((handler), (data), hash_table_t **); \ + sbus_property_sync("extraAttributes", "a{sas}", SBUS_PROPERTY_READABLE, \ + NULL, \ + _sbus_ifp_invoke_in__out_ifp_extra_send, \ + (handler), (data)); \ +}) + +#define SBUS_GETTER_ASYNC_org_freedesktop_sssd_infopipe_Users_User_extraAttributes(handler_send, handler_recv, data) ({ \ + SBUS_CHECK_SEND((handler_send), (data)); \ + SBUS_CHECK_RECV((handler_recv), hash_table_t **); \ + sbus_property_async("extraAttributes", "a{sas}", SBUS_PROPERTY_READABLE, \ + NULL, \ + _sbus_ifp_invoke_in__out_ifp_extra_send, \ + (handler_send), (handler_recv), (data)); \ +}) + +#define SBUS_SETTER_SYNC_org_freedesktop_sssd_infopipe_Users_User_extraAttributes(handler, data) ({\ + SBUS_CHECK_SYNC((handler), (data)); \ + sbus_property_sync("extraAttributes", "a{sas}", SBUS_PROPERTY_WRITABLE, \ + NULL, \ + _sbus_ifp_invoke_in__out__send, \ + (handler), (data)); \ +}) + +#define SBUS_SETTER_ASYNC_org_freedesktop_sssd_infopipe_Users_User_extraAttributes(handler_send, handler_recv, data) ({ \ + SBUS_CHECK_SEND((handler_send), (data)); \ + SBUS_CHECK_RECV((handler_recv)); \ + sbus_property_async("extraAttributes", "a{sas}", SBUS_PROPERTY_WRITABLE, \ + NULL, \ + _sbus_ifp_invoke_in__out__send, \ + (handler_send), (handler_recv), (data)); \ +}) + +/* Property: org.freedesktop.sssd.infopipe.Users.User.gecos */ +#define SBUS_GETTER_SYNC_org_freedesktop_sssd_infopipe_Users_User_gecos(handler, data) ({ \ + SBUS_CHECK_SYNC((handler), (data), const char **); \ + sbus_property_sync("gecos", "s", SBUS_PROPERTY_READABLE, \ + NULL, \ + _sbus_ifp_invoke_in__out_s_send, \ + (handler), (data)); \ +}) + +#define SBUS_GETTER_ASYNC_org_freedesktop_sssd_infopipe_Users_User_gecos(handler_send, handler_recv, data) ({ \ + SBUS_CHECK_SEND((handler_send), (data)); \ + SBUS_CHECK_RECV((handler_recv), const char **); \ + sbus_property_async("gecos", "s", SBUS_PROPERTY_READABLE, \ + NULL, \ + _sbus_ifp_invoke_in__out_s_send, \ + (handler_send), (handler_recv), (data)); \ +}) + +#define SBUS_SETTER_SYNC_org_freedesktop_sssd_infopipe_Users_User_gecos(handler, data) ({\ + SBUS_CHECK_SYNC((handler), (data)); \ + sbus_property_sync("gecos", "s", SBUS_PROPERTY_WRITABLE, \ + NULL, \ + _sbus_ifp_invoke_in__out__send, \ + (handler), (data)); \ +}) + +#define SBUS_SETTER_ASYNC_org_freedesktop_sssd_infopipe_Users_User_gecos(handler_send, handler_recv, data) ({ \ + SBUS_CHECK_SEND((handler_send), (data)); \ + SBUS_CHECK_RECV((handler_recv)); \ + sbus_property_async("gecos", "s", SBUS_PROPERTY_WRITABLE, \ + NULL, \ + _sbus_ifp_invoke_in__out__send, \ + (handler_send), (handler_recv), (data)); \ +}) + +/* Property: org.freedesktop.sssd.infopipe.Users.User.gidNumber */ +#define SBUS_GETTER_SYNC_org_freedesktop_sssd_infopipe_Users_User_gidNumber(handler, data) ({ \ + SBUS_CHECK_SYNC((handler), (data), uint32_t*); \ + sbus_property_sync("gidNumber", "u", SBUS_PROPERTY_READABLE, \ + NULL, \ + _sbus_ifp_invoke_in__out_u_send, \ + (handler), (data)); \ +}) + +#define SBUS_GETTER_ASYNC_org_freedesktop_sssd_infopipe_Users_User_gidNumber(handler_send, handler_recv, data) ({ \ + SBUS_CHECK_SEND((handler_send), (data)); \ + SBUS_CHECK_RECV((handler_recv), uint32_t*); \ + sbus_property_async("gidNumber", "u", SBUS_PROPERTY_READABLE, \ + NULL, \ + _sbus_ifp_invoke_in__out_u_send, \ + (handler_send), (handler_recv), (data)); \ +}) + +#define SBUS_SETTER_SYNC_org_freedesktop_sssd_infopipe_Users_User_gidNumber(handler, data) ({\ + SBUS_CHECK_SYNC((handler), (data)); \ + sbus_property_sync("gidNumber", "u", SBUS_PROPERTY_WRITABLE, \ + NULL, \ + _sbus_ifp_invoke_in__out__send, \ + (handler), (data)); \ +}) + +#define SBUS_SETTER_ASYNC_org_freedesktop_sssd_infopipe_Users_User_gidNumber(handler_send, handler_recv, data) ({ \ + SBUS_CHECK_SEND((handler_send), (data)); \ + SBUS_CHECK_RECV((handler_recv)); \ + sbus_property_async("gidNumber", "u", SBUS_PROPERTY_WRITABLE, \ + NULL, \ + _sbus_ifp_invoke_in__out__send, \ + (handler_send), (handler_recv), (data)); \ +}) + +/* Property: org.freedesktop.sssd.infopipe.Users.User.groups */ +#define SBUS_GETTER_SYNC_org_freedesktop_sssd_infopipe_Users_User_groups(handler, data) ({ \ + SBUS_CHECK_SYNC((handler), (data), const char ***); \ + sbus_property_sync("groups", "ao", SBUS_PROPERTY_READABLE, \ + NULL, \ + _sbus_ifp_invoke_in__out_ao_send, \ + (handler), (data)); \ +}) + +#define SBUS_GETTER_ASYNC_org_freedesktop_sssd_infopipe_Users_User_groups(handler_send, handler_recv, data) ({ \ + SBUS_CHECK_SEND((handler_send), (data)); \ + SBUS_CHECK_RECV((handler_recv), const char ***); \ + sbus_property_async("groups", "ao", SBUS_PROPERTY_READABLE, \ + NULL, \ + _sbus_ifp_invoke_in__out_ao_send, \ + (handler_send), (handler_recv), (data)); \ +}) + +#define SBUS_SETTER_SYNC_org_freedesktop_sssd_infopipe_Users_User_groups(handler, data) ({\ + SBUS_CHECK_SYNC((handler), (data)); \ + sbus_property_sync("groups", "ao", SBUS_PROPERTY_WRITABLE, \ + NULL, \ + _sbus_ifp_invoke_in__out__send, \ + (handler), (data)); \ +}) + +#define SBUS_SETTER_ASYNC_org_freedesktop_sssd_infopipe_Users_User_groups(handler_send, handler_recv, data) ({ \ + SBUS_CHECK_SEND((handler_send), (data)); \ + SBUS_CHECK_RECV((handler_recv)); \ + sbus_property_async("groups", "ao", SBUS_PROPERTY_WRITABLE, \ + NULL, \ + _sbus_ifp_invoke_in__out__send, \ + (handler_send), (handler_recv), (data)); \ +}) + +/* Property: org.freedesktop.sssd.infopipe.Users.User.homeDirectory */ +#define SBUS_GETTER_SYNC_org_freedesktop_sssd_infopipe_Users_User_homeDirectory(handler, data) ({ \ + SBUS_CHECK_SYNC((handler), (data), const char **); \ + sbus_property_sync("homeDirectory", "s", SBUS_PROPERTY_READABLE, \ + NULL, \ + _sbus_ifp_invoke_in__out_s_send, \ + (handler), (data)); \ +}) + +#define SBUS_GETTER_ASYNC_org_freedesktop_sssd_infopipe_Users_User_homeDirectory(handler_send, handler_recv, data) ({ \ + SBUS_CHECK_SEND((handler_send), (data)); \ + SBUS_CHECK_RECV((handler_recv), const char **); \ + sbus_property_async("homeDirectory", "s", SBUS_PROPERTY_READABLE, \ + NULL, \ + _sbus_ifp_invoke_in__out_s_send, \ + (handler_send), (handler_recv), (data)); \ +}) + +#define SBUS_SETTER_SYNC_org_freedesktop_sssd_infopipe_Users_User_homeDirectory(handler, data) ({\ + SBUS_CHECK_SYNC((handler), (data)); \ + sbus_property_sync("homeDirectory", "s", SBUS_PROPERTY_WRITABLE, \ + NULL, \ + _sbus_ifp_invoke_in__out__send, \ + (handler), (data)); \ +}) + +#define SBUS_SETTER_ASYNC_org_freedesktop_sssd_infopipe_Users_User_homeDirectory(handler_send, handler_recv, data) ({ \ + SBUS_CHECK_SEND((handler_send), (data)); \ + SBUS_CHECK_RECV((handler_recv)); \ + sbus_property_async("homeDirectory", "s", SBUS_PROPERTY_WRITABLE, \ + NULL, \ + _sbus_ifp_invoke_in__out__send, \ + (handler_send), (handler_recv), (data)); \ +}) + +/* Property: org.freedesktop.sssd.infopipe.Users.User.loginShell */ +#define SBUS_GETTER_SYNC_org_freedesktop_sssd_infopipe_Users_User_loginShell(handler, data) ({ \ + SBUS_CHECK_SYNC((handler), (data), const char **); \ + sbus_property_sync("loginShell", "s", SBUS_PROPERTY_READABLE, \ + NULL, \ + _sbus_ifp_invoke_in__out_s_send, \ + (handler), (data)); \ +}) + +#define SBUS_GETTER_ASYNC_org_freedesktop_sssd_infopipe_Users_User_loginShell(handler_send, handler_recv, data) ({ \ + SBUS_CHECK_SEND((handler_send), (data)); \ + SBUS_CHECK_RECV((handler_recv), const char **); \ + sbus_property_async("loginShell", "s", SBUS_PROPERTY_READABLE, \ + NULL, \ + _sbus_ifp_invoke_in__out_s_send, \ + (handler_send), (handler_recv), (data)); \ +}) + +#define SBUS_SETTER_SYNC_org_freedesktop_sssd_infopipe_Users_User_loginShell(handler, data) ({\ + SBUS_CHECK_SYNC((handler), (data)); \ + sbus_property_sync("loginShell", "s", SBUS_PROPERTY_WRITABLE, \ + NULL, \ + _sbus_ifp_invoke_in__out__send, \ + (handler), (data)); \ +}) + +#define SBUS_SETTER_ASYNC_org_freedesktop_sssd_infopipe_Users_User_loginShell(handler_send, handler_recv, data) ({ \ + SBUS_CHECK_SEND((handler_send), (data)); \ + SBUS_CHECK_RECV((handler_recv)); \ + sbus_property_async("loginShell", "s", SBUS_PROPERTY_WRITABLE, \ + NULL, \ + _sbus_ifp_invoke_in__out__send, \ + (handler_send), (handler_recv), (data)); \ +}) + +/* Property: org.freedesktop.sssd.infopipe.Users.User.name */ +#define SBUS_GETTER_SYNC_org_freedesktop_sssd_infopipe_Users_User_name(handler, data) ({ \ + SBUS_CHECK_SYNC((handler), (data), const char **); \ + sbus_property_sync("name", "s", SBUS_PROPERTY_READABLE, \ + NULL, \ + _sbus_ifp_invoke_in__out_s_send, \ + (handler), (data)); \ +}) + +#define SBUS_GETTER_ASYNC_org_freedesktop_sssd_infopipe_Users_User_name(handler_send, handler_recv, data) ({ \ + SBUS_CHECK_SEND((handler_send), (data)); \ + SBUS_CHECK_RECV((handler_recv), const char **); \ + sbus_property_async("name", "s", SBUS_PROPERTY_READABLE, \ + NULL, \ + _sbus_ifp_invoke_in__out_s_send, \ + (handler_send), (handler_recv), (data)); \ +}) + +#define SBUS_SETTER_SYNC_org_freedesktop_sssd_infopipe_Users_User_name(handler, data) ({\ + SBUS_CHECK_SYNC((handler), (data)); \ + sbus_property_sync("name", "s", SBUS_PROPERTY_WRITABLE, \ + NULL, \ + _sbus_ifp_invoke_in__out__send, \ + (handler), (data)); \ +}) + +#define SBUS_SETTER_ASYNC_org_freedesktop_sssd_infopipe_Users_User_name(handler_send, handler_recv, data) ({ \ + SBUS_CHECK_SEND((handler_send), (data)); \ + SBUS_CHECK_RECV((handler_recv)); \ + sbus_property_async("name", "s", SBUS_PROPERTY_WRITABLE, \ + NULL, \ + _sbus_ifp_invoke_in__out__send, \ + (handler_send), (handler_recv), (data)); \ +}) + +/* Property: org.freedesktop.sssd.infopipe.Users.User.uidNumber */ +#define SBUS_GETTER_SYNC_org_freedesktop_sssd_infopipe_Users_User_uidNumber(handler, data) ({ \ + SBUS_CHECK_SYNC((handler), (data), uint32_t*); \ + sbus_property_sync("uidNumber", "u", SBUS_PROPERTY_READABLE, \ + NULL, \ + _sbus_ifp_invoke_in__out_u_send, \ + (handler), (data)); \ +}) + +#define SBUS_GETTER_ASYNC_org_freedesktop_sssd_infopipe_Users_User_uidNumber(handler_send, handler_recv, data) ({ \ + SBUS_CHECK_SEND((handler_send), (data)); \ + SBUS_CHECK_RECV((handler_recv), uint32_t*); \ + sbus_property_async("uidNumber", "u", SBUS_PROPERTY_READABLE, \ + NULL, \ + _sbus_ifp_invoke_in__out_u_send, \ + (handler_send), (handler_recv), (data)); \ +}) + +#define SBUS_SETTER_SYNC_org_freedesktop_sssd_infopipe_Users_User_uidNumber(handler, data) ({\ + SBUS_CHECK_SYNC((handler), (data)); \ + sbus_property_sync("uidNumber", "u", SBUS_PROPERTY_WRITABLE, \ + NULL, \ + _sbus_ifp_invoke_in__out__send, \ + (handler), (data)); \ +}) + +#define SBUS_SETTER_ASYNC_org_freedesktop_sssd_infopipe_Users_User_uidNumber(handler_send, handler_recv, data) ({ \ + SBUS_CHECK_SEND((handler_send), (data)); \ + SBUS_CHECK_RECV((handler_recv)); \ + sbus_property_async("uidNumber", "u", SBUS_PROPERTY_WRITABLE, \ + NULL, \ + _sbus_ifp_invoke_in__out__send, \ + (handler_send), (handler_recv), (data)); \ +}) + +/* Property: org.freedesktop.sssd.infopipe.Users.User.uniqueID */ +#define SBUS_GETTER_SYNC_org_freedesktop_sssd_infopipe_Users_User_uniqueID(handler, data) ({ \ + SBUS_CHECK_SYNC((handler), (data), const char **); \ + sbus_property_sync("uniqueID", "s", SBUS_PROPERTY_READABLE, \ + NULL, \ + _sbus_ifp_invoke_in__out_s_send, \ + (handler), (data)); \ +}) + +#define SBUS_GETTER_ASYNC_org_freedesktop_sssd_infopipe_Users_User_uniqueID(handler_send, handler_recv, data) ({ \ + SBUS_CHECK_SEND((handler_send), (data)); \ + SBUS_CHECK_RECV((handler_recv), const char **); \ + sbus_property_async("uniqueID", "s", SBUS_PROPERTY_READABLE, \ + NULL, \ + _sbus_ifp_invoke_in__out_s_send, \ + (handler_send), (handler_recv), (data)); \ +}) + +#define SBUS_SETTER_SYNC_org_freedesktop_sssd_infopipe_Users_User_uniqueID(handler, data) ({\ + SBUS_CHECK_SYNC((handler), (data)); \ + sbus_property_sync("uniqueID", "s", SBUS_PROPERTY_WRITABLE, \ + NULL, \ + _sbus_ifp_invoke_in__out__send, \ + (handler), (data)); \ +}) + +#define SBUS_SETTER_ASYNC_org_freedesktop_sssd_infopipe_Users_User_uniqueID(handler_send, handler_recv, data) ({ \ + SBUS_CHECK_SEND((handler_send), (data)); \ + SBUS_CHECK_RECV((handler_recv)); \ + sbus_property_async("uniqueID", "s", SBUS_PROPERTY_WRITABLE, \ + NULL, \ + _sbus_ifp_invoke_in__out__send, \ + (handler_send), (handler_recv), (data)); \ +}) + +#endif /* _SBUS_IFP_INTERFACE_H_ */ diff --git a/src/responder/ifp/ifp_iface/sbus_ifp_invokers.c b/src/responder/ifp/ifp_iface/sbus_ifp_invokers.c new file mode 100644 index 0000000..a2db826 --- /dev/null +++ b/src/responder/ifp/ifp_iface/sbus_ifp_invokers.c @@ -0,0 +1,3004 @@ +/* + Generated by sbus code generator + + Copyright (C) 2017 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 <errno.h> +#include <talloc.h> +#include <tevent.h> +#include <dbus/dbus.h> + +#include "sbus/sbus_private.h" +#include "sbus/sbus_interface_declarations.h" +#include "responder/ifp/ifp_iface/sbus_ifp_arguments.h" +#include "responder/ifp/ifp_iface/sbus_ifp_invokers.h" + +static errno_t +sbus_invoker_schedule(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + void *handler, + void *private_data) +{ + /* Schedule invoker as a timed event so it is processed after other + * event types. This will give dispatcher a chance to catch more + * messages before this invoker is triggered and therefore it will + * allow to potentially chain more request into one, especially for + * synchronous handlers. */ + + struct tevent_timer *te; + struct timeval tv; + + tv = tevent_timeval_current_ofs(0, 5); + te = tevent_add_timer(ev, mem_ctx, tv, handler, private_data); + if (te == NULL) { + /* There is not enough memory to create a timer. We can't do + * anything about it. */ + DEBUG(SSSDBG_OP_FAILURE, "Could not add invoker event!\n"); + return ENOMEM; + } + + return EOK; +} + +struct _sbus_ifp_invoke_in__out__state { + struct { + enum sbus_handler_type type; + void *data; + errno_t (*sync)(TALLOC_CTX *, struct sbus_request *, void *); + struct tevent_req * (*send)(TALLOC_CTX *, struct tevent_context *, struct sbus_request *, void *); + errno_t (*recv)(TALLOC_CTX *, struct tevent_req *); + } handler; + + struct sbus_request *sbus_req; + DBusMessageIter *read_iterator; + DBusMessageIter *write_iterator; +}; + +static void +_sbus_ifp_invoke_in__out__step + (struct tevent_context *ev, + struct tevent_timer *te, + struct timeval tv, + void *private_data); + +static void +_sbus_ifp_invoke_in__out__done + (struct tevent_req *subreq); + +struct tevent_req * +_sbus_ifp_invoke_in__out__send + (TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct sbus_request *sbus_req, + sbus_invoker_keygen keygen, + const struct sbus_handler *handler, + DBusMessageIter *read_iterator, + DBusMessageIter *write_iterator, + const char **_key) +{ + struct _sbus_ifp_invoke_in__out__state *state; + struct tevent_req *req; + const char *key; + errno_t ret; + + req = tevent_req_create(mem_ctx, &state, struct _sbus_ifp_invoke_in__out__state); + if (req == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "Unable to create tevent request!\n"); + return NULL; + } + + state->handler.type = handler->type; + state->handler.data = handler->data; + state->handler.sync = handler->sync; + state->handler.send = handler->async_send; + state->handler.recv = handler->async_recv; + + state->sbus_req = sbus_req; + state->read_iterator = read_iterator; + state->write_iterator = write_iterator; + + ret = sbus_invoker_schedule(state, ev, _sbus_ifp_invoke_in__out__step, req); + if (ret != EOK) { + goto done; + } + + ret = sbus_request_key(state, keygen, sbus_req, NULL, &key); + if (ret != EOK) { + goto done; + } + + if (_key != NULL) { + *_key = talloc_steal(mem_ctx, key); + } + + ret = EAGAIN; + +done: + if (ret != EAGAIN) { + tevent_req_error(req, ret); + tevent_req_post(req, ev); + } + + return req; +} + +static void _sbus_ifp_invoke_in__out__step + (struct tevent_context *ev, + struct tevent_timer *te, + struct timeval tv, + void *private_data) +{ + struct _sbus_ifp_invoke_in__out__state *state; + struct tevent_req *subreq; + struct tevent_req *req; + errno_t ret; + + req = talloc_get_type(private_data, struct tevent_req); + state = tevent_req_data(req, struct _sbus_ifp_invoke_in__out__state); + + switch (state->handler.type) { + case SBUS_HANDLER_SYNC: + if (state->handler.sync == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "Bug: sync handler is not specified!\n"); + ret = ERR_INTERNAL; + goto done; + } + + ret = state->handler.sync(state, state->sbus_req, state->handler.data); + if (ret != EOK) { + goto done; + } + + goto done; + case SBUS_HANDLER_ASYNC: + if (state->handler.send == NULL || state->handler.recv == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "Bug: async handler is not specified!\n"); + ret = ERR_INTERNAL; + goto done; + } + + subreq = state->handler.send(state, ev, state->sbus_req, state->handler.data); + if (subreq == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "Unable to create subrequest!\n"); + ret = ENOMEM; + goto done; + } + + tevent_req_set_callback(subreq, _sbus_ifp_invoke_in__out__done, req); + ret = EAGAIN; + goto done; + } + + ret = ERR_INTERNAL; + +done: + if (ret == EOK) { + tevent_req_done(req); + } else if (ret != EAGAIN) { + tevent_req_error(req, ret); + } +} + +static void _sbus_ifp_invoke_in__out__done(struct tevent_req *subreq) +{ + struct _sbus_ifp_invoke_in__out__state *state; + struct tevent_req *req; + errno_t ret; + + req = tevent_req_callback_data(subreq, struct tevent_req); + state = tevent_req_data(req, struct _sbus_ifp_invoke_in__out__state); + + ret = state->handler.recv(state, subreq); + talloc_zfree(subreq); + if (ret != EOK) { + tevent_req_error(req, ret); + return; + } + + tevent_req_done(req); + return; +} + +struct _sbus_ifp_invoke_in__out_ao_state { + struct _sbus_ifp_invoker_args_ao out; + struct { + enum sbus_handler_type type; + void *data; + errno_t (*sync)(TALLOC_CTX *, struct sbus_request *, void *, const char ***); + struct tevent_req * (*send)(TALLOC_CTX *, struct tevent_context *, struct sbus_request *, void *); + errno_t (*recv)(TALLOC_CTX *, struct tevent_req *, const char ***); + } handler; + + struct sbus_request *sbus_req; + DBusMessageIter *read_iterator; + DBusMessageIter *write_iterator; +}; + +static void +_sbus_ifp_invoke_in__out_ao_step + (struct tevent_context *ev, + struct tevent_timer *te, + struct timeval tv, + void *private_data); + +static void +_sbus_ifp_invoke_in__out_ao_done + (struct tevent_req *subreq); + +struct tevent_req * +_sbus_ifp_invoke_in__out_ao_send + (TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct sbus_request *sbus_req, + sbus_invoker_keygen keygen, + const struct sbus_handler *handler, + DBusMessageIter *read_iterator, + DBusMessageIter *write_iterator, + const char **_key) +{ + struct _sbus_ifp_invoke_in__out_ao_state *state; + struct tevent_req *req; + const char *key; + errno_t ret; + + req = tevent_req_create(mem_ctx, &state, struct _sbus_ifp_invoke_in__out_ao_state); + if (req == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "Unable to create tevent request!\n"); + return NULL; + } + + state->handler.type = handler->type; + state->handler.data = handler->data; + state->handler.sync = handler->sync; + state->handler.send = handler->async_send; + state->handler.recv = handler->async_recv; + + state->sbus_req = sbus_req; + state->read_iterator = read_iterator; + state->write_iterator = write_iterator; + + ret = sbus_invoker_schedule(state, ev, _sbus_ifp_invoke_in__out_ao_step, req); + if (ret != EOK) { + goto done; + } + + ret = sbus_request_key(state, keygen, sbus_req, NULL, &key); + if (ret != EOK) { + goto done; + } + + if (_key != NULL) { + *_key = talloc_steal(mem_ctx, key); + } + + ret = EAGAIN; + +done: + if (ret != EAGAIN) { + tevent_req_error(req, ret); + tevent_req_post(req, ev); + } + + return req; +} + +static void _sbus_ifp_invoke_in__out_ao_step + (struct tevent_context *ev, + struct tevent_timer *te, + struct timeval tv, + void *private_data) +{ + struct _sbus_ifp_invoke_in__out_ao_state *state; + struct tevent_req *subreq; + struct tevent_req *req; + errno_t ret; + + req = talloc_get_type(private_data, struct tevent_req); + state = tevent_req_data(req, struct _sbus_ifp_invoke_in__out_ao_state); + + switch (state->handler.type) { + case SBUS_HANDLER_SYNC: + if (state->handler.sync == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "Bug: sync handler is not specified!\n"); + ret = ERR_INTERNAL; + goto done; + } + + ret = state->handler.sync(state, state->sbus_req, state->handler.data, &state->out.arg0); + if (ret != EOK) { + goto done; + } + + ret = _sbus_ifp_invoker_write_ao(state->write_iterator, &state->out); + goto done; + case SBUS_HANDLER_ASYNC: + if (state->handler.send == NULL || state->handler.recv == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "Bug: async handler is not specified!\n"); + ret = ERR_INTERNAL; + goto done; + } + + subreq = state->handler.send(state, ev, state->sbus_req, state->handler.data); + if (subreq == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "Unable to create subrequest!\n"); + ret = ENOMEM; + goto done; + } + + tevent_req_set_callback(subreq, _sbus_ifp_invoke_in__out_ao_done, req); + ret = EAGAIN; + goto done; + } + + ret = ERR_INTERNAL; + +done: + if (ret == EOK) { + tevent_req_done(req); + } else if (ret != EAGAIN) { + tevent_req_error(req, ret); + } +} + +static void _sbus_ifp_invoke_in__out_ao_done(struct tevent_req *subreq) +{ + struct _sbus_ifp_invoke_in__out_ao_state *state; + struct tevent_req *req; + errno_t ret; + + req = tevent_req_callback_data(subreq, struct tevent_req); + state = tevent_req_data(req, struct _sbus_ifp_invoke_in__out_ao_state); + + ret = state->handler.recv(state, subreq, &state->out.arg0); + talloc_zfree(subreq); + if (ret != EOK) { + tevent_req_error(req, ret); + return; + } + + ret = _sbus_ifp_invoker_write_ao(state->write_iterator, &state->out); + if (ret != EOK) { + tevent_req_error(req, ret); + return; + } + + tevent_req_done(req); + return; +} + +struct _sbus_ifp_invoke_in__out_as_state { + struct _sbus_ifp_invoker_args_as out; + struct { + enum sbus_handler_type type; + void *data; + errno_t (*sync)(TALLOC_CTX *, struct sbus_request *, void *, const char ***); + struct tevent_req * (*send)(TALLOC_CTX *, struct tevent_context *, struct sbus_request *, void *); + errno_t (*recv)(TALLOC_CTX *, struct tevent_req *, const char ***); + } handler; + + struct sbus_request *sbus_req; + DBusMessageIter *read_iterator; + DBusMessageIter *write_iterator; +}; + +static void +_sbus_ifp_invoke_in__out_as_step + (struct tevent_context *ev, + struct tevent_timer *te, + struct timeval tv, + void *private_data); + +static void +_sbus_ifp_invoke_in__out_as_done + (struct tevent_req *subreq); + +struct tevent_req * +_sbus_ifp_invoke_in__out_as_send + (TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct sbus_request *sbus_req, + sbus_invoker_keygen keygen, + const struct sbus_handler *handler, + DBusMessageIter *read_iterator, + DBusMessageIter *write_iterator, + const char **_key) +{ + struct _sbus_ifp_invoke_in__out_as_state *state; + struct tevent_req *req; + const char *key; + errno_t ret; + + req = tevent_req_create(mem_ctx, &state, struct _sbus_ifp_invoke_in__out_as_state); + if (req == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "Unable to create tevent request!\n"); + return NULL; + } + + state->handler.type = handler->type; + state->handler.data = handler->data; + state->handler.sync = handler->sync; + state->handler.send = handler->async_send; + state->handler.recv = handler->async_recv; + + state->sbus_req = sbus_req; + state->read_iterator = read_iterator; + state->write_iterator = write_iterator; + + ret = sbus_invoker_schedule(state, ev, _sbus_ifp_invoke_in__out_as_step, req); + if (ret != EOK) { + goto done; + } + + ret = sbus_request_key(state, keygen, sbus_req, NULL, &key); + if (ret != EOK) { + goto done; + } + + if (_key != NULL) { + *_key = talloc_steal(mem_ctx, key); + } + + ret = EAGAIN; + +done: + if (ret != EAGAIN) { + tevent_req_error(req, ret); + tevent_req_post(req, ev); + } + + return req; +} + +static void _sbus_ifp_invoke_in__out_as_step + (struct tevent_context *ev, + struct tevent_timer *te, + struct timeval tv, + void *private_data) +{ + struct _sbus_ifp_invoke_in__out_as_state *state; + struct tevent_req *subreq; + struct tevent_req *req; + errno_t ret; + + req = talloc_get_type(private_data, struct tevent_req); + state = tevent_req_data(req, struct _sbus_ifp_invoke_in__out_as_state); + + switch (state->handler.type) { + case SBUS_HANDLER_SYNC: + if (state->handler.sync == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "Bug: sync handler is not specified!\n"); + ret = ERR_INTERNAL; + goto done; + } + + ret = state->handler.sync(state, state->sbus_req, state->handler.data, &state->out.arg0); + if (ret != EOK) { + goto done; + } + + ret = _sbus_ifp_invoker_write_as(state->write_iterator, &state->out); + goto done; + case SBUS_HANDLER_ASYNC: + if (state->handler.send == NULL || state->handler.recv == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "Bug: async handler is not specified!\n"); + ret = ERR_INTERNAL; + goto done; + } + + subreq = state->handler.send(state, ev, state->sbus_req, state->handler.data); + if (subreq == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "Unable to create subrequest!\n"); + ret = ENOMEM; + goto done; + } + + tevent_req_set_callback(subreq, _sbus_ifp_invoke_in__out_as_done, req); + ret = EAGAIN; + goto done; + } + + ret = ERR_INTERNAL; + +done: + if (ret == EOK) { + tevent_req_done(req); + } else if (ret != EAGAIN) { + tevent_req_error(req, ret); + } +} + +static void _sbus_ifp_invoke_in__out_as_done(struct tevent_req *subreq) +{ + struct _sbus_ifp_invoke_in__out_as_state *state; + struct tevent_req *req; + errno_t ret; + + req = tevent_req_callback_data(subreq, struct tevent_req); + state = tevent_req_data(req, struct _sbus_ifp_invoke_in__out_as_state); + + ret = state->handler.recv(state, subreq, &state->out.arg0); + talloc_zfree(subreq); + if (ret != EOK) { + tevent_req_error(req, ret); + return; + } + + ret = _sbus_ifp_invoker_write_as(state->write_iterator, &state->out); + if (ret != EOK) { + tevent_req_error(req, ret); + return; + } + + tevent_req_done(req); + return; +} + +struct _sbus_ifp_invoke_in__out_b_state { + struct _sbus_ifp_invoker_args_b out; + struct { + enum sbus_handler_type type; + void *data; + errno_t (*sync)(TALLOC_CTX *, struct sbus_request *, void *, bool*); + struct tevent_req * (*send)(TALLOC_CTX *, struct tevent_context *, struct sbus_request *, void *); + errno_t (*recv)(TALLOC_CTX *, struct tevent_req *, bool*); + } handler; + + struct sbus_request *sbus_req; + DBusMessageIter *read_iterator; + DBusMessageIter *write_iterator; +}; + +static void +_sbus_ifp_invoke_in__out_b_step + (struct tevent_context *ev, + struct tevent_timer *te, + struct timeval tv, + void *private_data); + +static void +_sbus_ifp_invoke_in__out_b_done + (struct tevent_req *subreq); + +struct tevent_req * +_sbus_ifp_invoke_in__out_b_send + (TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct sbus_request *sbus_req, + sbus_invoker_keygen keygen, + const struct sbus_handler *handler, + DBusMessageIter *read_iterator, + DBusMessageIter *write_iterator, + const char **_key) +{ + struct _sbus_ifp_invoke_in__out_b_state *state; + struct tevent_req *req; + const char *key; + errno_t ret; + + req = tevent_req_create(mem_ctx, &state, struct _sbus_ifp_invoke_in__out_b_state); + if (req == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "Unable to create tevent request!\n"); + return NULL; + } + + state->handler.type = handler->type; + state->handler.data = handler->data; + state->handler.sync = handler->sync; + state->handler.send = handler->async_send; + state->handler.recv = handler->async_recv; + + state->sbus_req = sbus_req; + state->read_iterator = read_iterator; + state->write_iterator = write_iterator; + + ret = sbus_invoker_schedule(state, ev, _sbus_ifp_invoke_in__out_b_step, req); + if (ret != EOK) { + goto done; + } + + ret = sbus_request_key(state, keygen, sbus_req, NULL, &key); + if (ret != EOK) { + goto done; + } + + if (_key != NULL) { + *_key = talloc_steal(mem_ctx, key); + } + + ret = EAGAIN; + +done: + if (ret != EAGAIN) { + tevent_req_error(req, ret); + tevent_req_post(req, ev); + } + + return req; +} + +static void _sbus_ifp_invoke_in__out_b_step + (struct tevent_context *ev, + struct tevent_timer *te, + struct timeval tv, + void *private_data) +{ + struct _sbus_ifp_invoke_in__out_b_state *state; + struct tevent_req *subreq; + struct tevent_req *req; + errno_t ret; + + req = talloc_get_type(private_data, struct tevent_req); + state = tevent_req_data(req, struct _sbus_ifp_invoke_in__out_b_state); + + switch (state->handler.type) { + case SBUS_HANDLER_SYNC: + if (state->handler.sync == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "Bug: sync handler is not specified!\n"); + ret = ERR_INTERNAL; + goto done; + } + + ret = state->handler.sync(state, state->sbus_req, state->handler.data, &state->out.arg0); + if (ret != EOK) { + goto done; + } + + ret = _sbus_ifp_invoker_write_b(state->write_iterator, &state->out); + goto done; + case SBUS_HANDLER_ASYNC: + if (state->handler.send == NULL || state->handler.recv == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "Bug: async handler is not specified!\n"); + ret = ERR_INTERNAL; + goto done; + } + + subreq = state->handler.send(state, ev, state->sbus_req, state->handler.data); + if (subreq == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "Unable to create subrequest!\n"); + ret = ENOMEM; + goto done; + } + + tevent_req_set_callback(subreq, _sbus_ifp_invoke_in__out_b_done, req); + ret = EAGAIN; + goto done; + } + + ret = ERR_INTERNAL; + +done: + if (ret == EOK) { + tevent_req_done(req); + } else if (ret != EAGAIN) { + tevent_req_error(req, ret); + } +} + +static void _sbus_ifp_invoke_in__out_b_done(struct tevent_req *subreq) +{ + struct _sbus_ifp_invoke_in__out_b_state *state; + struct tevent_req *req; + errno_t ret; + + req = tevent_req_callback_data(subreq, struct tevent_req); + state = tevent_req_data(req, struct _sbus_ifp_invoke_in__out_b_state); + + ret = state->handler.recv(state, subreq, &state->out.arg0); + talloc_zfree(subreq); + if (ret != EOK) { + tevent_req_error(req, ret); + return; + } + + ret = _sbus_ifp_invoker_write_b(state->write_iterator, &state->out); + if (ret != EOK) { + tevent_req_error(req, ret); + return; + } + + tevent_req_done(req); + return; +} + +struct _sbus_ifp_invoke_in__out_ifp_extra_state { + struct _sbus_ifp_invoker_args_ifp_extra out; + struct { + enum sbus_handler_type type; + void *data; + errno_t (*sync)(TALLOC_CTX *, struct sbus_request *, void *, hash_table_t **); + struct tevent_req * (*send)(TALLOC_CTX *, struct tevent_context *, struct sbus_request *, void *); + errno_t (*recv)(TALLOC_CTX *, struct tevent_req *, hash_table_t **); + } handler; + + struct sbus_request *sbus_req; + DBusMessageIter *read_iterator; + DBusMessageIter *write_iterator; +}; + +static void +_sbus_ifp_invoke_in__out_ifp_extra_step + (struct tevent_context *ev, + struct tevent_timer *te, + struct timeval tv, + void *private_data); + +static void +_sbus_ifp_invoke_in__out_ifp_extra_done + (struct tevent_req *subreq); + +struct tevent_req * +_sbus_ifp_invoke_in__out_ifp_extra_send + (TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct sbus_request *sbus_req, + sbus_invoker_keygen keygen, + const struct sbus_handler *handler, + DBusMessageIter *read_iterator, + DBusMessageIter *write_iterator, + const char **_key) +{ + struct _sbus_ifp_invoke_in__out_ifp_extra_state *state; + struct tevent_req *req; + const char *key; + errno_t ret; + + req = tevent_req_create(mem_ctx, &state, struct _sbus_ifp_invoke_in__out_ifp_extra_state); + if (req == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "Unable to create tevent request!\n"); + return NULL; + } + + state->handler.type = handler->type; + state->handler.data = handler->data; + state->handler.sync = handler->sync; + state->handler.send = handler->async_send; + state->handler.recv = handler->async_recv; + + state->sbus_req = sbus_req; + state->read_iterator = read_iterator; + state->write_iterator = write_iterator; + + ret = sbus_invoker_schedule(state, ev, _sbus_ifp_invoke_in__out_ifp_extra_step, req); + if (ret != EOK) { + goto done; + } + + ret = sbus_request_key(state, keygen, sbus_req, NULL, &key); + if (ret != EOK) { + goto done; + } + + if (_key != NULL) { + *_key = talloc_steal(mem_ctx, key); + } + + ret = EAGAIN; + +done: + if (ret != EAGAIN) { + tevent_req_error(req, ret); + tevent_req_post(req, ev); + } + + return req; +} + +static void _sbus_ifp_invoke_in__out_ifp_extra_step + (struct tevent_context *ev, + struct tevent_timer *te, + struct timeval tv, + void *private_data) +{ + struct _sbus_ifp_invoke_in__out_ifp_extra_state *state; + struct tevent_req *subreq; + struct tevent_req *req; + errno_t ret; + + req = talloc_get_type(private_data, struct tevent_req); + state = tevent_req_data(req, struct _sbus_ifp_invoke_in__out_ifp_extra_state); + + switch (state->handler.type) { + case SBUS_HANDLER_SYNC: + if (state->handler.sync == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "Bug: sync handler is not specified!\n"); + ret = ERR_INTERNAL; + goto done; + } + + ret = state->handler.sync(state, state->sbus_req, state->handler.data, &state->out.arg0); + if (ret != EOK) { + goto done; + } + + ret = _sbus_ifp_invoker_write_ifp_extra(state->write_iterator, &state->out); + goto done; + case SBUS_HANDLER_ASYNC: + if (state->handler.send == NULL || state->handler.recv == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "Bug: async handler is not specified!\n"); + ret = ERR_INTERNAL; + goto done; + } + + subreq = state->handler.send(state, ev, state->sbus_req, state->handler.data); + if (subreq == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "Unable to create subrequest!\n"); + ret = ENOMEM; + goto done; + } + + tevent_req_set_callback(subreq, _sbus_ifp_invoke_in__out_ifp_extra_done, req); + ret = EAGAIN; + goto done; + } + + ret = ERR_INTERNAL; + +done: + if (ret == EOK) { + tevent_req_done(req); + } else if (ret != EAGAIN) { + tevent_req_error(req, ret); + } +} + +static void _sbus_ifp_invoke_in__out_ifp_extra_done(struct tevent_req *subreq) +{ + struct _sbus_ifp_invoke_in__out_ifp_extra_state *state; + struct tevent_req *req; + errno_t ret; + + req = tevent_req_callback_data(subreq, struct tevent_req); + state = tevent_req_data(req, struct _sbus_ifp_invoke_in__out_ifp_extra_state); + + ret = state->handler.recv(state, subreq, &state->out.arg0); + talloc_zfree(subreq); + if (ret != EOK) { + tevent_req_error(req, ret); + return; + } + + ret = _sbus_ifp_invoker_write_ifp_extra(state->write_iterator, &state->out); + if (ret != EOK) { + tevent_req_error(req, ret); + return; + } + + tevent_req_done(req); + return; +} + +struct _sbus_ifp_invoke_in__out_o_state { + struct _sbus_ifp_invoker_args_o out; + struct { + enum sbus_handler_type type; + void *data; + errno_t (*sync)(TALLOC_CTX *, struct sbus_request *, void *, const char **); + struct tevent_req * (*send)(TALLOC_CTX *, struct tevent_context *, struct sbus_request *, void *); + errno_t (*recv)(TALLOC_CTX *, struct tevent_req *, const char **); + } handler; + + struct sbus_request *sbus_req; + DBusMessageIter *read_iterator; + DBusMessageIter *write_iterator; +}; + +static void +_sbus_ifp_invoke_in__out_o_step + (struct tevent_context *ev, + struct tevent_timer *te, + struct timeval tv, + void *private_data); + +static void +_sbus_ifp_invoke_in__out_o_done + (struct tevent_req *subreq); + +struct tevent_req * +_sbus_ifp_invoke_in__out_o_send + (TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct sbus_request *sbus_req, + sbus_invoker_keygen keygen, + const struct sbus_handler *handler, + DBusMessageIter *read_iterator, + DBusMessageIter *write_iterator, + const char **_key) +{ + struct _sbus_ifp_invoke_in__out_o_state *state; + struct tevent_req *req; + const char *key; + errno_t ret; + + req = tevent_req_create(mem_ctx, &state, struct _sbus_ifp_invoke_in__out_o_state); + if (req == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "Unable to create tevent request!\n"); + return NULL; + } + + state->handler.type = handler->type; + state->handler.data = handler->data; + state->handler.sync = handler->sync; + state->handler.send = handler->async_send; + state->handler.recv = handler->async_recv; + + state->sbus_req = sbus_req; + state->read_iterator = read_iterator; + state->write_iterator = write_iterator; + + ret = sbus_invoker_schedule(state, ev, _sbus_ifp_invoke_in__out_o_step, req); + if (ret != EOK) { + goto done; + } + + ret = sbus_request_key(state, keygen, sbus_req, NULL, &key); + if (ret != EOK) { + goto done; + } + + if (_key != NULL) { + *_key = talloc_steal(mem_ctx, key); + } + + ret = EAGAIN; + +done: + if (ret != EAGAIN) { + tevent_req_error(req, ret); + tevent_req_post(req, ev); + } + + return req; +} + +static void _sbus_ifp_invoke_in__out_o_step + (struct tevent_context *ev, + struct tevent_timer *te, + struct timeval tv, + void *private_data) +{ + struct _sbus_ifp_invoke_in__out_o_state *state; + struct tevent_req *subreq; + struct tevent_req *req; + errno_t ret; + + req = talloc_get_type(private_data, struct tevent_req); + state = tevent_req_data(req, struct _sbus_ifp_invoke_in__out_o_state); + + switch (state->handler.type) { + case SBUS_HANDLER_SYNC: + if (state->handler.sync == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "Bug: sync handler is not specified!\n"); + ret = ERR_INTERNAL; + goto done; + } + + ret = state->handler.sync(state, state->sbus_req, state->handler.data, &state->out.arg0); + if (ret != EOK) { + goto done; + } + + ret = _sbus_ifp_invoker_write_o(state->write_iterator, &state->out); + goto done; + case SBUS_HANDLER_ASYNC: + if (state->handler.send == NULL || state->handler.recv == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "Bug: async handler is not specified!\n"); + ret = ERR_INTERNAL; + goto done; + } + + subreq = state->handler.send(state, ev, state->sbus_req, state->handler.data); + if (subreq == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "Unable to create subrequest!\n"); + ret = ENOMEM; + goto done; + } + + tevent_req_set_callback(subreq, _sbus_ifp_invoke_in__out_o_done, req); + ret = EAGAIN; + goto done; + } + + ret = ERR_INTERNAL; + +done: + if (ret == EOK) { + tevent_req_done(req); + } else if (ret != EAGAIN) { + tevent_req_error(req, ret); + } +} + +static void _sbus_ifp_invoke_in__out_o_done(struct tevent_req *subreq) +{ + struct _sbus_ifp_invoke_in__out_o_state *state; + struct tevent_req *req; + errno_t ret; + + req = tevent_req_callback_data(subreq, struct tevent_req); + state = tevent_req_data(req, struct _sbus_ifp_invoke_in__out_o_state); + + ret = state->handler.recv(state, subreq, &state->out.arg0); + talloc_zfree(subreq); + if (ret != EOK) { + tevent_req_error(req, ret); + return; + } + + ret = _sbus_ifp_invoker_write_o(state->write_iterator, &state->out); + if (ret != EOK) { + tevent_req_error(req, ret); + return; + } + + tevent_req_done(req); + return; +} + +struct _sbus_ifp_invoke_in__out_s_state { + struct _sbus_ifp_invoker_args_s out; + struct { + enum sbus_handler_type type; + void *data; + errno_t (*sync)(TALLOC_CTX *, struct sbus_request *, void *, const char **); + struct tevent_req * (*send)(TALLOC_CTX *, struct tevent_context *, struct sbus_request *, void *); + errno_t (*recv)(TALLOC_CTX *, struct tevent_req *, const char **); + } handler; + + struct sbus_request *sbus_req; + DBusMessageIter *read_iterator; + DBusMessageIter *write_iterator; +}; + +static void +_sbus_ifp_invoke_in__out_s_step + (struct tevent_context *ev, + struct tevent_timer *te, + struct timeval tv, + void *private_data); + +static void +_sbus_ifp_invoke_in__out_s_done + (struct tevent_req *subreq); + +struct tevent_req * +_sbus_ifp_invoke_in__out_s_send + (TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct sbus_request *sbus_req, + sbus_invoker_keygen keygen, + const struct sbus_handler *handler, + DBusMessageIter *read_iterator, + DBusMessageIter *write_iterator, + const char **_key) +{ + struct _sbus_ifp_invoke_in__out_s_state *state; + struct tevent_req *req; + const char *key; + errno_t ret; + + req = tevent_req_create(mem_ctx, &state, struct _sbus_ifp_invoke_in__out_s_state); + if (req == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "Unable to create tevent request!\n"); + return NULL; + } + + state->handler.type = handler->type; + state->handler.data = handler->data; + state->handler.sync = handler->sync; + state->handler.send = handler->async_send; + state->handler.recv = handler->async_recv; + + state->sbus_req = sbus_req; + state->read_iterator = read_iterator; + state->write_iterator = write_iterator; + + ret = sbus_invoker_schedule(state, ev, _sbus_ifp_invoke_in__out_s_step, req); + if (ret != EOK) { + goto done; + } + + ret = sbus_request_key(state, keygen, sbus_req, NULL, &key); + if (ret != EOK) { + goto done; + } + + if (_key != NULL) { + *_key = talloc_steal(mem_ctx, key); + } + + ret = EAGAIN; + +done: + if (ret != EAGAIN) { + tevent_req_error(req, ret); + tevent_req_post(req, ev); + } + + return req; +} + +static void _sbus_ifp_invoke_in__out_s_step + (struct tevent_context *ev, + struct tevent_timer *te, + struct timeval tv, + void *private_data) +{ + struct _sbus_ifp_invoke_in__out_s_state *state; + struct tevent_req *subreq; + struct tevent_req *req; + errno_t ret; + + req = talloc_get_type(private_data, struct tevent_req); + state = tevent_req_data(req, struct _sbus_ifp_invoke_in__out_s_state); + + switch (state->handler.type) { + case SBUS_HANDLER_SYNC: + if (state->handler.sync == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "Bug: sync handler is not specified!\n"); + ret = ERR_INTERNAL; + goto done; + } + + ret = state->handler.sync(state, state->sbus_req, state->handler.data, &state->out.arg0); + if (ret != EOK) { + goto done; + } + + ret = _sbus_ifp_invoker_write_s(state->write_iterator, &state->out); + goto done; + case SBUS_HANDLER_ASYNC: + if (state->handler.send == NULL || state->handler.recv == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "Bug: async handler is not specified!\n"); + ret = ERR_INTERNAL; + goto done; + } + + subreq = state->handler.send(state, ev, state->sbus_req, state->handler.data); + if (subreq == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "Unable to create subrequest!\n"); + ret = ENOMEM; + goto done; + } + + tevent_req_set_callback(subreq, _sbus_ifp_invoke_in__out_s_done, req); + ret = EAGAIN; + goto done; + } + + ret = ERR_INTERNAL; + +done: + if (ret == EOK) { + tevent_req_done(req); + } else if (ret != EAGAIN) { + tevent_req_error(req, ret); + } +} + +static void _sbus_ifp_invoke_in__out_s_done(struct tevent_req *subreq) +{ + struct _sbus_ifp_invoke_in__out_s_state *state; + struct tevent_req *req; + errno_t ret; + + req = tevent_req_callback_data(subreq, struct tevent_req); + state = tevent_req_data(req, struct _sbus_ifp_invoke_in__out_s_state); + + ret = state->handler.recv(state, subreq, &state->out.arg0); + talloc_zfree(subreq); + if (ret != EOK) { + tevent_req_error(req, ret); + return; + } + + ret = _sbus_ifp_invoker_write_s(state->write_iterator, &state->out); + if (ret != EOK) { + tevent_req_error(req, ret); + return; + } + + tevent_req_done(req); + return; +} + +struct _sbus_ifp_invoke_in__out_u_state { + struct _sbus_ifp_invoker_args_u out; + struct { + enum sbus_handler_type type; + void *data; + errno_t (*sync)(TALLOC_CTX *, struct sbus_request *, void *, uint32_t*); + struct tevent_req * (*send)(TALLOC_CTX *, struct tevent_context *, struct sbus_request *, void *); + errno_t (*recv)(TALLOC_CTX *, struct tevent_req *, uint32_t*); + } handler; + + struct sbus_request *sbus_req; + DBusMessageIter *read_iterator; + DBusMessageIter *write_iterator; +}; + +static void +_sbus_ifp_invoke_in__out_u_step + (struct tevent_context *ev, + struct tevent_timer *te, + struct timeval tv, + void *private_data); + +static void +_sbus_ifp_invoke_in__out_u_done + (struct tevent_req *subreq); + +struct tevent_req * +_sbus_ifp_invoke_in__out_u_send + (TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct sbus_request *sbus_req, + sbus_invoker_keygen keygen, + const struct sbus_handler *handler, + DBusMessageIter *read_iterator, + DBusMessageIter *write_iterator, + const char **_key) +{ + struct _sbus_ifp_invoke_in__out_u_state *state; + struct tevent_req *req; + const char *key; + errno_t ret; + + req = tevent_req_create(mem_ctx, &state, struct _sbus_ifp_invoke_in__out_u_state); + if (req == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "Unable to create tevent request!\n"); + return NULL; + } + + state->handler.type = handler->type; + state->handler.data = handler->data; + state->handler.sync = handler->sync; + state->handler.send = handler->async_send; + state->handler.recv = handler->async_recv; + + state->sbus_req = sbus_req; + state->read_iterator = read_iterator; + state->write_iterator = write_iterator; + + ret = sbus_invoker_schedule(state, ev, _sbus_ifp_invoke_in__out_u_step, req); + if (ret != EOK) { + goto done; + } + + ret = sbus_request_key(state, keygen, sbus_req, NULL, &key); + if (ret != EOK) { + goto done; + } + + if (_key != NULL) { + *_key = talloc_steal(mem_ctx, key); + } + + ret = EAGAIN; + +done: + if (ret != EAGAIN) { + tevent_req_error(req, ret); + tevent_req_post(req, ev); + } + + return req; +} + +static void _sbus_ifp_invoke_in__out_u_step + (struct tevent_context *ev, + struct tevent_timer *te, + struct timeval tv, + void *private_data) +{ + struct _sbus_ifp_invoke_in__out_u_state *state; + struct tevent_req *subreq; + struct tevent_req *req; + errno_t ret; + + req = talloc_get_type(private_data, struct tevent_req); + state = tevent_req_data(req, struct _sbus_ifp_invoke_in__out_u_state); + + switch (state->handler.type) { + case SBUS_HANDLER_SYNC: + if (state->handler.sync == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "Bug: sync handler is not specified!\n"); + ret = ERR_INTERNAL; + goto done; + } + + ret = state->handler.sync(state, state->sbus_req, state->handler.data, &state->out.arg0); + if (ret != EOK) { + goto done; + } + + ret = _sbus_ifp_invoker_write_u(state->write_iterator, &state->out); + goto done; + case SBUS_HANDLER_ASYNC: + if (state->handler.send == NULL || state->handler.recv == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "Bug: async handler is not specified!\n"); + ret = ERR_INTERNAL; + goto done; + } + + subreq = state->handler.send(state, ev, state->sbus_req, state->handler.data); + if (subreq == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "Unable to create subrequest!\n"); + ret = ENOMEM; + goto done; + } + + tevent_req_set_callback(subreq, _sbus_ifp_invoke_in__out_u_done, req); + ret = EAGAIN; + goto done; + } + + ret = ERR_INTERNAL; + +done: + if (ret == EOK) { + tevent_req_done(req); + } else if (ret != EAGAIN) { + tevent_req_error(req, ret); + } +} + +static void _sbus_ifp_invoke_in__out_u_done(struct tevent_req *subreq) +{ + struct _sbus_ifp_invoke_in__out_u_state *state; + struct tevent_req *req; + errno_t ret; + + req = tevent_req_callback_data(subreq, struct tevent_req); + state = tevent_req_data(req, struct _sbus_ifp_invoke_in__out_u_state); + + ret = state->handler.recv(state, subreq, &state->out.arg0); + talloc_zfree(subreq); + if (ret != EOK) { + tevent_req_error(req, ret); + return; + } + + ret = _sbus_ifp_invoker_write_u(state->write_iterator, &state->out); + if (ret != EOK) { + tevent_req_error(req, ret); + return; + } + + tevent_req_done(req); + return; +} + +struct _sbus_ifp_invoke_in_s_out_ao_state { + struct _sbus_ifp_invoker_args_s *in; + struct _sbus_ifp_invoker_args_ao out; + struct { + enum sbus_handler_type type; + void *data; + errno_t (*sync)(TALLOC_CTX *, struct sbus_request *, void *, const char *, const char ***); + struct tevent_req * (*send)(TALLOC_CTX *, struct tevent_context *, struct sbus_request *, void *, const char *); + errno_t (*recv)(TALLOC_CTX *, struct tevent_req *, const char ***); + } handler; + + struct sbus_request *sbus_req; + DBusMessageIter *read_iterator; + DBusMessageIter *write_iterator; +}; + +static void +_sbus_ifp_invoke_in_s_out_ao_step + (struct tevent_context *ev, + struct tevent_timer *te, + struct timeval tv, + void *private_data); + +static void +_sbus_ifp_invoke_in_s_out_ao_done + (struct tevent_req *subreq); + +struct tevent_req * +_sbus_ifp_invoke_in_s_out_ao_send + (TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct sbus_request *sbus_req, + sbus_invoker_keygen keygen, + const struct sbus_handler *handler, + DBusMessageIter *read_iterator, + DBusMessageIter *write_iterator, + const char **_key) +{ + struct _sbus_ifp_invoke_in_s_out_ao_state *state; + struct tevent_req *req; + const char *key; + errno_t ret; + + req = tevent_req_create(mem_ctx, &state, struct _sbus_ifp_invoke_in_s_out_ao_state); + if (req == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "Unable to create tevent request!\n"); + return NULL; + } + + state->handler.type = handler->type; + state->handler.data = handler->data; + state->handler.sync = handler->sync; + state->handler.send = handler->async_send; + state->handler.recv = handler->async_recv; + + state->sbus_req = sbus_req; + state->read_iterator = read_iterator; + state->write_iterator = write_iterator; + + state->in = talloc_zero(state, struct _sbus_ifp_invoker_args_s); + if (state->in == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, + "Unable to allocate space for input parameters!\n"); + ret = ENOMEM; + goto done; + } + + ret = _sbus_ifp_invoker_read_s(state, read_iterator, state->in); + if (ret != EOK) { + goto done; + } + + ret = sbus_invoker_schedule(state, ev, _sbus_ifp_invoke_in_s_out_ao_step, req); + if (ret != EOK) { + goto done; + } + + ret = sbus_request_key(state, keygen, sbus_req, state->in, &key); + if (ret != EOK) { + goto done; + } + + if (_key != NULL) { + *_key = talloc_steal(mem_ctx, key); + } + + ret = EAGAIN; + +done: + if (ret != EAGAIN) { + tevent_req_error(req, ret); + tevent_req_post(req, ev); + } + + return req; +} + +static void _sbus_ifp_invoke_in_s_out_ao_step + (struct tevent_context *ev, + struct tevent_timer *te, + struct timeval tv, + void *private_data) +{ + struct _sbus_ifp_invoke_in_s_out_ao_state *state; + struct tevent_req *subreq; + struct tevent_req *req; + errno_t ret; + + req = talloc_get_type(private_data, struct tevent_req); + state = tevent_req_data(req, struct _sbus_ifp_invoke_in_s_out_ao_state); + + switch (state->handler.type) { + case SBUS_HANDLER_SYNC: + if (state->handler.sync == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "Bug: sync handler is not specified!\n"); + ret = ERR_INTERNAL; + goto done; + } + + ret = state->handler.sync(state, state->sbus_req, state->handler.data, state->in->arg0, &state->out.arg0); + if (ret != EOK) { + goto done; + } + + ret = _sbus_ifp_invoker_write_ao(state->write_iterator, &state->out); + goto done; + case SBUS_HANDLER_ASYNC: + if (state->handler.send == NULL || state->handler.recv == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "Bug: async handler is not specified!\n"); + ret = ERR_INTERNAL; + goto done; + } + + subreq = state->handler.send(state, ev, state->sbus_req, state->handler.data, state->in->arg0); + if (subreq == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "Unable to create subrequest!\n"); + ret = ENOMEM; + goto done; + } + + tevent_req_set_callback(subreq, _sbus_ifp_invoke_in_s_out_ao_done, req); + ret = EAGAIN; + goto done; + } + + ret = ERR_INTERNAL; + +done: + if (ret == EOK) { + tevent_req_done(req); + } else if (ret != EAGAIN) { + tevent_req_error(req, ret); + } +} + +static void _sbus_ifp_invoke_in_s_out_ao_done(struct tevent_req *subreq) +{ + struct _sbus_ifp_invoke_in_s_out_ao_state *state; + struct tevent_req *req; + errno_t ret; + + req = tevent_req_callback_data(subreq, struct tevent_req); + state = tevent_req_data(req, struct _sbus_ifp_invoke_in_s_out_ao_state); + + ret = state->handler.recv(state, subreq, &state->out.arg0); + talloc_zfree(subreq); + if (ret != EOK) { + tevent_req_error(req, ret); + return; + } + + ret = _sbus_ifp_invoker_write_ao(state->write_iterator, &state->out); + if (ret != EOK) { + tevent_req_error(req, ret); + return; + } + + tevent_req_done(req); + return; +} + +struct _sbus_ifp_invoke_in_s_out_as_state { + struct _sbus_ifp_invoker_args_s *in; + struct _sbus_ifp_invoker_args_as out; + struct { + enum sbus_handler_type type; + void *data; + errno_t (*sync)(TALLOC_CTX *, struct sbus_request *, void *, const char *, const char ***); + struct tevent_req * (*send)(TALLOC_CTX *, struct tevent_context *, struct sbus_request *, void *, const char *); + errno_t (*recv)(TALLOC_CTX *, struct tevent_req *, const char ***); + } handler; + + struct sbus_request *sbus_req; + DBusMessageIter *read_iterator; + DBusMessageIter *write_iterator; +}; + +static void +_sbus_ifp_invoke_in_s_out_as_step + (struct tevent_context *ev, + struct tevent_timer *te, + struct timeval tv, + void *private_data); + +static void +_sbus_ifp_invoke_in_s_out_as_done + (struct tevent_req *subreq); + +struct tevent_req * +_sbus_ifp_invoke_in_s_out_as_send + (TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct sbus_request *sbus_req, + sbus_invoker_keygen keygen, + const struct sbus_handler *handler, + DBusMessageIter *read_iterator, + DBusMessageIter *write_iterator, + const char **_key) +{ + struct _sbus_ifp_invoke_in_s_out_as_state *state; + struct tevent_req *req; + const char *key; + errno_t ret; + + req = tevent_req_create(mem_ctx, &state, struct _sbus_ifp_invoke_in_s_out_as_state); + if (req == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "Unable to create tevent request!\n"); + return NULL; + } + + state->handler.type = handler->type; + state->handler.data = handler->data; + state->handler.sync = handler->sync; + state->handler.send = handler->async_send; + state->handler.recv = handler->async_recv; + + state->sbus_req = sbus_req; + state->read_iterator = read_iterator; + state->write_iterator = write_iterator; + + state->in = talloc_zero(state, struct _sbus_ifp_invoker_args_s); + if (state->in == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, + "Unable to allocate space for input parameters!\n"); + ret = ENOMEM; + goto done; + } + + ret = _sbus_ifp_invoker_read_s(state, read_iterator, state->in); + if (ret != EOK) { + goto done; + } + + ret = sbus_invoker_schedule(state, ev, _sbus_ifp_invoke_in_s_out_as_step, req); + if (ret != EOK) { + goto done; + } + + ret = sbus_request_key(state, keygen, sbus_req, state->in, &key); + if (ret != EOK) { + goto done; + } + + if (_key != NULL) { + *_key = talloc_steal(mem_ctx, key); + } + + ret = EAGAIN; + +done: + if (ret != EAGAIN) { + tevent_req_error(req, ret); + tevent_req_post(req, ev); + } + + return req; +} + +static void _sbus_ifp_invoke_in_s_out_as_step + (struct tevent_context *ev, + struct tevent_timer *te, + struct timeval tv, + void *private_data) +{ + struct _sbus_ifp_invoke_in_s_out_as_state *state; + struct tevent_req *subreq; + struct tevent_req *req; + errno_t ret; + + req = talloc_get_type(private_data, struct tevent_req); + state = tevent_req_data(req, struct _sbus_ifp_invoke_in_s_out_as_state); + + switch (state->handler.type) { + case SBUS_HANDLER_SYNC: + if (state->handler.sync == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "Bug: sync handler is not specified!\n"); + ret = ERR_INTERNAL; + goto done; + } + + ret = state->handler.sync(state, state->sbus_req, state->handler.data, state->in->arg0, &state->out.arg0); + if (ret != EOK) { + goto done; + } + + ret = _sbus_ifp_invoker_write_as(state->write_iterator, &state->out); + goto done; + case SBUS_HANDLER_ASYNC: + if (state->handler.send == NULL || state->handler.recv == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "Bug: async handler is not specified!\n"); + ret = ERR_INTERNAL; + goto done; + } + + subreq = state->handler.send(state, ev, state->sbus_req, state->handler.data, state->in->arg0); + if (subreq == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "Unable to create subrequest!\n"); + ret = ENOMEM; + goto done; + } + + tevent_req_set_callback(subreq, _sbus_ifp_invoke_in_s_out_as_done, req); + ret = EAGAIN; + goto done; + } + + ret = ERR_INTERNAL; + +done: + if (ret == EOK) { + tevent_req_done(req); + } else if (ret != EAGAIN) { + tevent_req_error(req, ret); + } +} + +static void _sbus_ifp_invoke_in_s_out_as_done(struct tevent_req *subreq) +{ + struct _sbus_ifp_invoke_in_s_out_as_state *state; + struct tevent_req *req; + errno_t ret; + + req = tevent_req_callback_data(subreq, struct tevent_req); + state = tevent_req_data(req, struct _sbus_ifp_invoke_in_s_out_as_state); + + ret = state->handler.recv(state, subreq, &state->out.arg0); + talloc_zfree(subreq); + if (ret != EOK) { + tevent_req_error(req, ret); + return; + } + + ret = _sbus_ifp_invoker_write_as(state->write_iterator, &state->out); + if (ret != EOK) { + tevent_req_error(req, ret); + return; + } + + tevent_req_done(req); + return; +} + +struct _sbus_ifp_invoke_in_s_out_o_state { + struct _sbus_ifp_invoker_args_s *in; + struct _sbus_ifp_invoker_args_o out; + struct { + enum sbus_handler_type type; + void *data; + errno_t (*sync)(TALLOC_CTX *, struct sbus_request *, void *, const char *, const char **); + struct tevent_req * (*send)(TALLOC_CTX *, struct tevent_context *, struct sbus_request *, void *, const char *); + errno_t (*recv)(TALLOC_CTX *, struct tevent_req *, const char **); + } handler; + + struct sbus_request *sbus_req; + DBusMessageIter *read_iterator; + DBusMessageIter *write_iterator; +}; + +static void +_sbus_ifp_invoke_in_s_out_o_step + (struct tevent_context *ev, + struct tevent_timer *te, + struct timeval tv, + void *private_data); + +static void +_sbus_ifp_invoke_in_s_out_o_done + (struct tevent_req *subreq); + +struct tevent_req * +_sbus_ifp_invoke_in_s_out_o_send + (TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct sbus_request *sbus_req, + sbus_invoker_keygen keygen, + const struct sbus_handler *handler, + DBusMessageIter *read_iterator, + DBusMessageIter *write_iterator, + const char **_key) +{ + struct _sbus_ifp_invoke_in_s_out_o_state *state; + struct tevent_req *req; + const char *key; + errno_t ret; + + req = tevent_req_create(mem_ctx, &state, struct _sbus_ifp_invoke_in_s_out_o_state); + if (req == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "Unable to create tevent request!\n"); + return NULL; + } + + state->handler.type = handler->type; + state->handler.data = handler->data; + state->handler.sync = handler->sync; + state->handler.send = handler->async_send; + state->handler.recv = handler->async_recv; + + state->sbus_req = sbus_req; + state->read_iterator = read_iterator; + state->write_iterator = write_iterator; + + state->in = talloc_zero(state, struct _sbus_ifp_invoker_args_s); + if (state->in == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, + "Unable to allocate space for input parameters!\n"); + ret = ENOMEM; + goto done; + } + + ret = _sbus_ifp_invoker_read_s(state, read_iterator, state->in); + if (ret != EOK) { + goto done; + } + + ret = sbus_invoker_schedule(state, ev, _sbus_ifp_invoke_in_s_out_o_step, req); + if (ret != EOK) { + goto done; + } + + ret = sbus_request_key(state, keygen, sbus_req, state->in, &key); + if (ret != EOK) { + goto done; + } + + if (_key != NULL) { + *_key = talloc_steal(mem_ctx, key); + } + + ret = EAGAIN; + +done: + if (ret != EAGAIN) { + tevent_req_error(req, ret); + tevent_req_post(req, ev); + } + + return req; +} + +static void _sbus_ifp_invoke_in_s_out_o_step + (struct tevent_context *ev, + struct tevent_timer *te, + struct timeval tv, + void *private_data) +{ + struct _sbus_ifp_invoke_in_s_out_o_state *state; + struct tevent_req *subreq; + struct tevent_req *req; + errno_t ret; + + req = talloc_get_type(private_data, struct tevent_req); + state = tevent_req_data(req, struct _sbus_ifp_invoke_in_s_out_o_state); + + switch (state->handler.type) { + case SBUS_HANDLER_SYNC: + if (state->handler.sync == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "Bug: sync handler is not specified!\n"); + ret = ERR_INTERNAL; + goto done; + } + + ret = state->handler.sync(state, state->sbus_req, state->handler.data, state->in->arg0, &state->out.arg0); + if (ret != EOK) { + goto done; + } + + ret = _sbus_ifp_invoker_write_o(state->write_iterator, &state->out); + goto done; + case SBUS_HANDLER_ASYNC: + if (state->handler.send == NULL || state->handler.recv == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "Bug: async handler is not specified!\n"); + ret = ERR_INTERNAL; + goto done; + } + + subreq = state->handler.send(state, ev, state->sbus_req, state->handler.data, state->in->arg0); + if (subreq == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "Unable to create subrequest!\n"); + ret = ENOMEM; + goto done; + } + + tevent_req_set_callback(subreq, _sbus_ifp_invoke_in_s_out_o_done, req); + ret = EAGAIN; + goto done; + } + + ret = ERR_INTERNAL; + +done: + if (ret == EOK) { + tevent_req_done(req); + } else if (ret != EAGAIN) { + tevent_req_error(req, ret); + } +} + +static void _sbus_ifp_invoke_in_s_out_o_done(struct tevent_req *subreq) +{ + struct _sbus_ifp_invoke_in_s_out_o_state *state; + struct tevent_req *req; + errno_t ret; + + req = tevent_req_callback_data(subreq, struct tevent_req); + state = tevent_req_data(req, struct _sbus_ifp_invoke_in_s_out_o_state); + + ret = state->handler.recv(state, subreq, &state->out.arg0); + talloc_zfree(subreq); + if (ret != EOK) { + tevent_req_error(req, ret); + return; + } + + ret = _sbus_ifp_invoker_write_o(state->write_iterator, &state->out); + if (ret != EOK) { + tevent_req_error(req, ret); + return; + } + + tevent_req_done(req); + return; +} + +struct _sbus_ifp_invoke_in_s_out_s_state { + struct _sbus_ifp_invoker_args_s *in; + struct _sbus_ifp_invoker_args_s out; + struct { + enum sbus_handler_type type; + void *data; + errno_t (*sync)(TALLOC_CTX *, struct sbus_request *, void *, const char *, const char **); + struct tevent_req * (*send)(TALLOC_CTX *, struct tevent_context *, struct sbus_request *, void *, const char *); + errno_t (*recv)(TALLOC_CTX *, struct tevent_req *, const char **); + } handler; + + struct sbus_request *sbus_req; + DBusMessageIter *read_iterator; + DBusMessageIter *write_iterator; +}; + +static void +_sbus_ifp_invoke_in_s_out_s_step + (struct tevent_context *ev, + struct tevent_timer *te, + struct timeval tv, + void *private_data); + +static void +_sbus_ifp_invoke_in_s_out_s_done + (struct tevent_req *subreq); + +struct tevent_req * +_sbus_ifp_invoke_in_s_out_s_send + (TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct sbus_request *sbus_req, + sbus_invoker_keygen keygen, + const struct sbus_handler *handler, + DBusMessageIter *read_iterator, + DBusMessageIter *write_iterator, + const char **_key) +{ + struct _sbus_ifp_invoke_in_s_out_s_state *state; + struct tevent_req *req; + const char *key; + errno_t ret; + + req = tevent_req_create(mem_ctx, &state, struct _sbus_ifp_invoke_in_s_out_s_state); + if (req == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "Unable to create tevent request!\n"); + return NULL; + } + + state->handler.type = handler->type; + state->handler.data = handler->data; + state->handler.sync = handler->sync; + state->handler.send = handler->async_send; + state->handler.recv = handler->async_recv; + + state->sbus_req = sbus_req; + state->read_iterator = read_iterator; + state->write_iterator = write_iterator; + + state->in = talloc_zero(state, struct _sbus_ifp_invoker_args_s); + if (state->in == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, + "Unable to allocate space for input parameters!\n"); + ret = ENOMEM; + goto done; + } + + ret = _sbus_ifp_invoker_read_s(state, read_iterator, state->in); + if (ret != EOK) { + goto done; + } + + ret = sbus_invoker_schedule(state, ev, _sbus_ifp_invoke_in_s_out_s_step, req); + if (ret != EOK) { + goto done; + } + + ret = sbus_request_key(state, keygen, sbus_req, state->in, &key); + if (ret != EOK) { + goto done; + } + + if (_key != NULL) { + *_key = talloc_steal(mem_ctx, key); + } + + ret = EAGAIN; + +done: + if (ret != EAGAIN) { + tevent_req_error(req, ret); + tevent_req_post(req, ev); + } + + return req; +} + +static void _sbus_ifp_invoke_in_s_out_s_step + (struct tevent_context *ev, + struct tevent_timer *te, + struct timeval tv, + void *private_data) +{ + struct _sbus_ifp_invoke_in_s_out_s_state *state; + struct tevent_req *subreq; + struct tevent_req *req; + errno_t ret; + + req = talloc_get_type(private_data, struct tevent_req); + state = tevent_req_data(req, struct _sbus_ifp_invoke_in_s_out_s_state); + + switch (state->handler.type) { + case SBUS_HANDLER_SYNC: + if (state->handler.sync == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "Bug: sync handler is not specified!\n"); + ret = ERR_INTERNAL; + goto done; + } + + ret = state->handler.sync(state, state->sbus_req, state->handler.data, state->in->arg0, &state->out.arg0); + if (ret != EOK) { + goto done; + } + + ret = _sbus_ifp_invoker_write_s(state->write_iterator, &state->out); + goto done; + case SBUS_HANDLER_ASYNC: + if (state->handler.send == NULL || state->handler.recv == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "Bug: async handler is not specified!\n"); + ret = ERR_INTERNAL; + goto done; + } + + subreq = state->handler.send(state, ev, state->sbus_req, state->handler.data, state->in->arg0); + if (subreq == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "Unable to create subrequest!\n"); + ret = ENOMEM; + goto done; + } + + tevent_req_set_callback(subreq, _sbus_ifp_invoke_in_s_out_s_done, req); + ret = EAGAIN; + goto done; + } + + ret = ERR_INTERNAL; + +done: + if (ret == EOK) { + tevent_req_done(req); + } else if (ret != EAGAIN) { + tevent_req_error(req, ret); + } +} + +static void _sbus_ifp_invoke_in_s_out_s_done(struct tevent_req *subreq) +{ + struct _sbus_ifp_invoke_in_s_out_s_state *state; + struct tevent_req *req; + errno_t ret; + + req = tevent_req_callback_data(subreq, struct tevent_req); + state = tevent_req_data(req, struct _sbus_ifp_invoke_in_s_out_s_state); + + ret = state->handler.recv(state, subreq, &state->out.arg0); + talloc_zfree(subreq); + if (ret != EOK) { + tevent_req_error(req, ret); + return; + } + + ret = _sbus_ifp_invoker_write_s(state->write_iterator, &state->out); + if (ret != EOK) { + tevent_req_error(req, ret); + return; + } + + tevent_req_done(req); + return; +} + +struct _sbus_ifp_invoke_in_sas_out_raw_state { + struct _sbus_ifp_invoker_args_sas *in; + struct { + enum sbus_handler_type type; + void *data; + errno_t (*sync)(TALLOC_CTX *, struct sbus_request *, void *, const char *, const char **, DBusMessageIter *); + struct tevent_req * (*send)(TALLOC_CTX *, struct tevent_context *, struct sbus_request *, void *, const char *, const char **, DBusMessageIter *); + errno_t (*recv)(TALLOC_CTX *, struct tevent_req *); + } handler; + + struct sbus_request *sbus_req; + DBusMessageIter *read_iterator; + DBusMessageIter *write_iterator; +}; + +static void +_sbus_ifp_invoke_in_sas_out_raw_step + (struct tevent_context *ev, + struct tevent_timer *te, + struct timeval tv, + void *private_data); + +static void +_sbus_ifp_invoke_in_sas_out_raw_done + (struct tevent_req *subreq); + +struct tevent_req * +_sbus_ifp_invoke_in_sas_out_raw_send + (TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct sbus_request *sbus_req, + sbus_invoker_keygen keygen, + const struct sbus_handler *handler, + DBusMessageIter *read_iterator, + DBusMessageIter *write_iterator, + const char **_key) +{ + struct _sbus_ifp_invoke_in_sas_out_raw_state *state; + struct tevent_req *req; + const char *key; + errno_t ret; + + req = tevent_req_create(mem_ctx, &state, struct _sbus_ifp_invoke_in_sas_out_raw_state); + if (req == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "Unable to create tevent request!\n"); + return NULL; + } + + state->handler.type = handler->type; + state->handler.data = handler->data; + state->handler.sync = handler->sync; + state->handler.send = handler->async_send; + state->handler.recv = handler->async_recv; + + state->sbus_req = sbus_req; + state->read_iterator = read_iterator; + state->write_iterator = write_iterator; + + state->in = talloc_zero(state, struct _sbus_ifp_invoker_args_sas); + if (state->in == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, + "Unable to allocate space for input parameters!\n"); + ret = ENOMEM; + goto done; + } + + ret = _sbus_ifp_invoker_read_sas(state, read_iterator, state->in); + if (ret != EOK) { + goto done; + } + + ret = sbus_invoker_schedule(state, ev, _sbus_ifp_invoke_in_sas_out_raw_step, req); + if (ret != EOK) { + goto done; + } + + ret = sbus_request_key(state, keygen, sbus_req, state->in, &key); + if (ret != EOK) { + goto done; + } + + if (_key != NULL) { + *_key = talloc_steal(mem_ctx, key); + } + + ret = EAGAIN; + +done: + if (ret != EAGAIN) { + tevent_req_error(req, ret); + tevent_req_post(req, ev); + } + + return req; +} + +static void _sbus_ifp_invoke_in_sas_out_raw_step + (struct tevent_context *ev, + struct tevent_timer *te, + struct timeval tv, + void *private_data) +{ + struct _sbus_ifp_invoke_in_sas_out_raw_state *state; + struct tevent_req *subreq; + struct tevent_req *req; + errno_t ret; + + req = talloc_get_type(private_data, struct tevent_req); + state = tevent_req_data(req, struct _sbus_ifp_invoke_in_sas_out_raw_state); + + switch (state->handler.type) { + case SBUS_HANDLER_SYNC: + if (state->handler.sync == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "Bug: sync handler is not specified!\n"); + ret = ERR_INTERNAL; + goto done; + } + + ret = state->handler.sync(state, state->sbus_req, state->handler.data, state->in->arg0, state->in->arg1, state->write_iterator); + if (ret != EOK) { + goto done; + } + + goto done; + case SBUS_HANDLER_ASYNC: + if (state->handler.send == NULL || state->handler.recv == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "Bug: async handler is not specified!\n"); + ret = ERR_INTERNAL; + goto done; + } + + subreq = state->handler.send(state, ev, state->sbus_req, state->handler.data, state->in->arg0, state->in->arg1, state->write_iterator); + if (subreq == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "Unable to create subrequest!\n"); + ret = ENOMEM; + goto done; + } + + tevent_req_set_callback(subreq, _sbus_ifp_invoke_in_sas_out_raw_done, req); + ret = EAGAIN; + goto done; + } + + ret = ERR_INTERNAL; + +done: + if (ret == EOK) { + tevent_req_done(req); + } else if (ret != EAGAIN) { + tevent_req_error(req, ret); + } +} + +static void _sbus_ifp_invoke_in_sas_out_raw_done(struct tevent_req *subreq) +{ + struct _sbus_ifp_invoke_in_sas_out_raw_state *state; + struct tevent_req *req; + errno_t ret; + + req = tevent_req_callback_data(subreq, struct tevent_req); + state = tevent_req_data(req, struct _sbus_ifp_invoke_in_sas_out_raw_state); + + ret = state->handler.recv(state, subreq); + talloc_zfree(subreq); + if (ret != EOK) { + tevent_req_error(req, ret); + return; + } + + tevent_req_done(req); + return; +} + +struct _sbus_ifp_invoke_in_ss_out_o_state { + struct _sbus_ifp_invoker_args_ss *in; + struct _sbus_ifp_invoker_args_o out; + struct { + enum sbus_handler_type type; + void *data; + errno_t (*sync)(TALLOC_CTX *, struct sbus_request *, void *, const char *, const char *, const char **); + struct tevent_req * (*send)(TALLOC_CTX *, struct tevent_context *, struct sbus_request *, void *, const char *, const char *); + errno_t (*recv)(TALLOC_CTX *, struct tevent_req *, const char **); + } handler; + + struct sbus_request *sbus_req; + DBusMessageIter *read_iterator; + DBusMessageIter *write_iterator; +}; + +static void +_sbus_ifp_invoke_in_ss_out_o_step + (struct tevent_context *ev, + struct tevent_timer *te, + struct timeval tv, + void *private_data); + +static void +_sbus_ifp_invoke_in_ss_out_o_done + (struct tevent_req *subreq); + +struct tevent_req * +_sbus_ifp_invoke_in_ss_out_o_send + (TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct sbus_request *sbus_req, + sbus_invoker_keygen keygen, + const struct sbus_handler *handler, + DBusMessageIter *read_iterator, + DBusMessageIter *write_iterator, + const char **_key) +{ + struct _sbus_ifp_invoke_in_ss_out_o_state *state; + struct tevent_req *req; + const char *key; + errno_t ret; + + req = tevent_req_create(mem_ctx, &state, struct _sbus_ifp_invoke_in_ss_out_o_state); + if (req == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "Unable to create tevent request!\n"); + return NULL; + } + + state->handler.type = handler->type; + state->handler.data = handler->data; + state->handler.sync = handler->sync; + state->handler.send = handler->async_send; + state->handler.recv = handler->async_recv; + + state->sbus_req = sbus_req; + state->read_iterator = read_iterator; + state->write_iterator = write_iterator; + + state->in = talloc_zero(state, struct _sbus_ifp_invoker_args_ss); + if (state->in == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, + "Unable to allocate space for input parameters!\n"); + ret = ENOMEM; + goto done; + } + + ret = _sbus_ifp_invoker_read_ss(state, read_iterator, state->in); + if (ret != EOK) { + goto done; + } + + ret = sbus_invoker_schedule(state, ev, _sbus_ifp_invoke_in_ss_out_o_step, req); + if (ret != EOK) { + goto done; + } + + ret = sbus_request_key(state, keygen, sbus_req, state->in, &key); + if (ret != EOK) { + goto done; + } + + if (_key != NULL) { + *_key = talloc_steal(mem_ctx, key); + } + + ret = EAGAIN; + +done: + if (ret != EAGAIN) { + tevent_req_error(req, ret); + tevent_req_post(req, ev); + } + + return req; +} + +static void _sbus_ifp_invoke_in_ss_out_o_step + (struct tevent_context *ev, + struct tevent_timer *te, + struct timeval tv, + void *private_data) +{ + struct _sbus_ifp_invoke_in_ss_out_o_state *state; + struct tevent_req *subreq; + struct tevent_req *req; + errno_t ret; + + req = talloc_get_type(private_data, struct tevent_req); + state = tevent_req_data(req, struct _sbus_ifp_invoke_in_ss_out_o_state); + + switch (state->handler.type) { + case SBUS_HANDLER_SYNC: + if (state->handler.sync == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "Bug: sync handler is not specified!\n"); + ret = ERR_INTERNAL; + goto done; + } + + ret = state->handler.sync(state, state->sbus_req, state->handler.data, state->in->arg0, state->in->arg1, &state->out.arg0); + if (ret != EOK) { + goto done; + } + + ret = _sbus_ifp_invoker_write_o(state->write_iterator, &state->out); + goto done; + case SBUS_HANDLER_ASYNC: + if (state->handler.send == NULL || state->handler.recv == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "Bug: async handler is not specified!\n"); + ret = ERR_INTERNAL; + goto done; + } + + subreq = state->handler.send(state, ev, state->sbus_req, state->handler.data, state->in->arg0, state->in->arg1); + if (subreq == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "Unable to create subrequest!\n"); + ret = ENOMEM; + goto done; + } + + tevent_req_set_callback(subreq, _sbus_ifp_invoke_in_ss_out_o_done, req); + ret = EAGAIN; + goto done; + } + + ret = ERR_INTERNAL; + +done: + if (ret == EOK) { + tevent_req_done(req); + } else if (ret != EAGAIN) { + tevent_req_error(req, ret); + } +} + +static void _sbus_ifp_invoke_in_ss_out_o_done(struct tevent_req *subreq) +{ + struct _sbus_ifp_invoke_in_ss_out_o_state *state; + struct tevent_req *req; + errno_t ret; + + req = tevent_req_callback_data(subreq, struct tevent_req); + state = tevent_req_data(req, struct _sbus_ifp_invoke_in_ss_out_o_state); + + ret = state->handler.recv(state, subreq, &state->out.arg0); + talloc_zfree(subreq); + if (ret != EOK) { + tevent_req_error(req, ret); + return; + } + + ret = _sbus_ifp_invoker_write_o(state->write_iterator, &state->out); + if (ret != EOK) { + tevent_req_error(req, ret); + return; + } + + tevent_req_done(req); + return; +} + +struct _sbus_ifp_invoke_in_ssu_out_ao_state { + struct _sbus_ifp_invoker_args_ssu *in; + struct _sbus_ifp_invoker_args_ao out; + struct { + enum sbus_handler_type type; + void *data; + errno_t (*sync)(TALLOC_CTX *, struct sbus_request *, void *, const char *, const char *, uint32_t, const char ***); + struct tevent_req * (*send)(TALLOC_CTX *, struct tevent_context *, struct sbus_request *, void *, const char *, const char *, uint32_t); + errno_t (*recv)(TALLOC_CTX *, struct tevent_req *, const char ***); + } handler; + + struct sbus_request *sbus_req; + DBusMessageIter *read_iterator; + DBusMessageIter *write_iterator; +}; + +static void +_sbus_ifp_invoke_in_ssu_out_ao_step + (struct tevent_context *ev, + struct tevent_timer *te, + struct timeval tv, + void *private_data); + +static void +_sbus_ifp_invoke_in_ssu_out_ao_done + (struct tevent_req *subreq); + +struct tevent_req * +_sbus_ifp_invoke_in_ssu_out_ao_send + (TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct sbus_request *sbus_req, + sbus_invoker_keygen keygen, + const struct sbus_handler *handler, + DBusMessageIter *read_iterator, + DBusMessageIter *write_iterator, + const char **_key) +{ + struct _sbus_ifp_invoke_in_ssu_out_ao_state *state; + struct tevent_req *req; + const char *key; + errno_t ret; + + req = tevent_req_create(mem_ctx, &state, struct _sbus_ifp_invoke_in_ssu_out_ao_state); + if (req == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "Unable to create tevent request!\n"); + return NULL; + } + + state->handler.type = handler->type; + state->handler.data = handler->data; + state->handler.sync = handler->sync; + state->handler.send = handler->async_send; + state->handler.recv = handler->async_recv; + + state->sbus_req = sbus_req; + state->read_iterator = read_iterator; + state->write_iterator = write_iterator; + + state->in = talloc_zero(state, struct _sbus_ifp_invoker_args_ssu); + if (state->in == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, + "Unable to allocate space for input parameters!\n"); + ret = ENOMEM; + goto done; + } + + ret = _sbus_ifp_invoker_read_ssu(state, read_iterator, state->in); + if (ret != EOK) { + goto done; + } + + ret = sbus_invoker_schedule(state, ev, _sbus_ifp_invoke_in_ssu_out_ao_step, req); + if (ret != EOK) { + goto done; + } + + ret = sbus_request_key(state, keygen, sbus_req, state->in, &key); + if (ret != EOK) { + goto done; + } + + if (_key != NULL) { + *_key = talloc_steal(mem_ctx, key); + } + + ret = EAGAIN; + +done: + if (ret != EAGAIN) { + tevent_req_error(req, ret); + tevent_req_post(req, ev); + } + + return req; +} + +static void _sbus_ifp_invoke_in_ssu_out_ao_step + (struct tevent_context *ev, + struct tevent_timer *te, + struct timeval tv, + void *private_data) +{ + struct _sbus_ifp_invoke_in_ssu_out_ao_state *state; + struct tevent_req *subreq; + struct tevent_req *req; + errno_t ret; + + req = talloc_get_type(private_data, struct tevent_req); + state = tevent_req_data(req, struct _sbus_ifp_invoke_in_ssu_out_ao_state); + + switch (state->handler.type) { + case SBUS_HANDLER_SYNC: + if (state->handler.sync == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "Bug: sync handler is not specified!\n"); + ret = ERR_INTERNAL; + goto done; + } + + ret = state->handler.sync(state, state->sbus_req, state->handler.data, state->in->arg0, state->in->arg1, state->in->arg2, &state->out.arg0); + if (ret != EOK) { + goto done; + } + + ret = _sbus_ifp_invoker_write_ao(state->write_iterator, &state->out); + goto done; + case SBUS_HANDLER_ASYNC: + if (state->handler.send == NULL || state->handler.recv == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "Bug: async handler is not specified!\n"); + ret = ERR_INTERNAL; + goto done; + } + + subreq = state->handler.send(state, ev, state->sbus_req, state->handler.data, state->in->arg0, state->in->arg1, state->in->arg2); + if (subreq == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "Unable to create subrequest!\n"); + ret = ENOMEM; + goto done; + } + + tevent_req_set_callback(subreq, _sbus_ifp_invoke_in_ssu_out_ao_done, req); + ret = EAGAIN; + goto done; + } + + ret = ERR_INTERNAL; + +done: + if (ret == EOK) { + tevent_req_done(req); + } else if (ret != EAGAIN) { + tevent_req_error(req, ret); + } +} + +static void _sbus_ifp_invoke_in_ssu_out_ao_done(struct tevent_req *subreq) +{ + struct _sbus_ifp_invoke_in_ssu_out_ao_state *state; + struct tevent_req *req; + errno_t ret; + + req = tevent_req_callback_data(subreq, struct tevent_req); + state = tevent_req_data(req, struct _sbus_ifp_invoke_in_ssu_out_ao_state); + + ret = state->handler.recv(state, subreq, &state->out.arg0); + talloc_zfree(subreq); + if (ret != EOK) { + tevent_req_error(req, ret); + return; + } + + ret = _sbus_ifp_invoker_write_ao(state->write_iterator, &state->out); + if (ret != EOK) { + tevent_req_error(req, ret); + return; + } + + tevent_req_done(req); + return; +} + +struct _sbus_ifp_invoke_in_su_out_ao_state { + struct _sbus_ifp_invoker_args_su *in; + struct _sbus_ifp_invoker_args_ao out; + struct { + enum sbus_handler_type type; + void *data; + errno_t (*sync)(TALLOC_CTX *, struct sbus_request *, void *, const char *, uint32_t, const char ***); + struct tevent_req * (*send)(TALLOC_CTX *, struct tevent_context *, struct sbus_request *, void *, const char *, uint32_t); + errno_t (*recv)(TALLOC_CTX *, struct tevent_req *, const char ***); + } handler; + + struct sbus_request *sbus_req; + DBusMessageIter *read_iterator; + DBusMessageIter *write_iterator; +}; + +static void +_sbus_ifp_invoke_in_su_out_ao_step + (struct tevent_context *ev, + struct tevent_timer *te, + struct timeval tv, + void *private_data); + +static void +_sbus_ifp_invoke_in_su_out_ao_done + (struct tevent_req *subreq); + +struct tevent_req * +_sbus_ifp_invoke_in_su_out_ao_send + (TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct sbus_request *sbus_req, + sbus_invoker_keygen keygen, + const struct sbus_handler *handler, + DBusMessageIter *read_iterator, + DBusMessageIter *write_iterator, + const char **_key) +{ + struct _sbus_ifp_invoke_in_su_out_ao_state *state; + struct tevent_req *req; + const char *key; + errno_t ret; + + req = tevent_req_create(mem_ctx, &state, struct _sbus_ifp_invoke_in_su_out_ao_state); + if (req == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "Unable to create tevent request!\n"); + return NULL; + } + + state->handler.type = handler->type; + state->handler.data = handler->data; + state->handler.sync = handler->sync; + state->handler.send = handler->async_send; + state->handler.recv = handler->async_recv; + + state->sbus_req = sbus_req; + state->read_iterator = read_iterator; + state->write_iterator = write_iterator; + + state->in = talloc_zero(state, struct _sbus_ifp_invoker_args_su); + if (state->in == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, + "Unable to allocate space for input parameters!\n"); + ret = ENOMEM; + goto done; + } + + ret = _sbus_ifp_invoker_read_su(state, read_iterator, state->in); + if (ret != EOK) { + goto done; + } + + ret = sbus_invoker_schedule(state, ev, _sbus_ifp_invoke_in_su_out_ao_step, req); + if (ret != EOK) { + goto done; + } + + ret = sbus_request_key(state, keygen, sbus_req, state->in, &key); + if (ret != EOK) { + goto done; + } + + if (_key != NULL) { + *_key = talloc_steal(mem_ctx, key); + } + + ret = EAGAIN; + +done: + if (ret != EAGAIN) { + tevent_req_error(req, ret); + tevent_req_post(req, ev); + } + + return req; +} + +static void _sbus_ifp_invoke_in_su_out_ao_step + (struct tevent_context *ev, + struct tevent_timer *te, + struct timeval tv, + void *private_data) +{ + struct _sbus_ifp_invoke_in_su_out_ao_state *state; + struct tevent_req *subreq; + struct tevent_req *req; + errno_t ret; + + req = talloc_get_type(private_data, struct tevent_req); + state = tevent_req_data(req, struct _sbus_ifp_invoke_in_su_out_ao_state); + + switch (state->handler.type) { + case SBUS_HANDLER_SYNC: + if (state->handler.sync == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "Bug: sync handler is not specified!\n"); + ret = ERR_INTERNAL; + goto done; + } + + ret = state->handler.sync(state, state->sbus_req, state->handler.data, state->in->arg0, state->in->arg1, &state->out.arg0); + if (ret != EOK) { + goto done; + } + + ret = _sbus_ifp_invoker_write_ao(state->write_iterator, &state->out); + goto done; + case SBUS_HANDLER_ASYNC: + if (state->handler.send == NULL || state->handler.recv == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "Bug: async handler is not specified!\n"); + ret = ERR_INTERNAL; + goto done; + } + + subreq = state->handler.send(state, ev, state->sbus_req, state->handler.data, state->in->arg0, state->in->arg1); + if (subreq == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "Unable to create subrequest!\n"); + ret = ENOMEM; + goto done; + } + + tevent_req_set_callback(subreq, _sbus_ifp_invoke_in_su_out_ao_done, req); + ret = EAGAIN; + goto done; + } + + ret = ERR_INTERNAL; + +done: + if (ret == EOK) { + tevent_req_done(req); + } else if (ret != EAGAIN) { + tevent_req_error(req, ret); + } +} + +static void _sbus_ifp_invoke_in_su_out_ao_done(struct tevent_req *subreq) +{ + struct _sbus_ifp_invoke_in_su_out_ao_state *state; + struct tevent_req *req; + errno_t ret; + + req = tevent_req_callback_data(subreq, struct tevent_req); + state = tevent_req_data(req, struct _sbus_ifp_invoke_in_su_out_ao_state); + + ret = state->handler.recv(state, subreq, &state->out.arg0); + talloc_zfree(subreq); + if (ret != EOK) { + tevent_req_error(req, ret); + return; + } + + ret = _sbus_ifp_invoker_write_ao(state->write_iterator, &state->out); + if (ret != EOK) { + tevent_req_error(req, ret); + return; + } + + tevent_req_done(req); + return; +} + +struct _sbus_ifp_invoke_in_u_out_o_state { + struct _sbus_ifp_invoker_args_u *in; + struct _sbus_ifp_invoker_args_o out; + struct { + enum sbus_handler_type type; + void *data; + errno_t (*sync)(TALLOC_CTX *, struct sbus_request *, void *, uint32_t, const char **); + struct tevent_req * (*send)(TALLOC_CTX *, struct tevent_context *, struct sbus_request *, void *, uint32_t); + errno_t (*recv)(TALLOC_CTX *, struct tevent_req *, const char **); + } handler; + + struct sbus_request *sbus_req; + DBusMessageIter *read_iterator; + DBusMessageIter *write_iterator; +}; + +static void +_sbus_ifp_invoke_in_u_out_o_step + (struct tevent_context *ev, + struct tevent_timer *te, + struct timeval tv, + void *private_data); + +static void +_sbus_ifp_invoke_in_u_out_o_done + (struct tevent_req *subreq); + +struct tevent_req * +_sbus_ifp_invoke_in_u_out_o_send + (TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct sbus_request *sbus_req, + sbus_invoker_keygen keygen, + const struct sbus_handler *handler, + DBusMessageIter *read_iterator, + DBusMessageIter *write_iterator, + const char **_key) +{ + struct _sbus_ifp_invoke_in_u_out_o_state *state; + struct tevent_req *req; + const char *key; + errno_t ret; + + req = tevent_req_create(mem_ctx, &state, struct _sbus_ifp_invoke_in_u_out_o_state); + if (req == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "Unable to create tevent request!\n"); + return NULL; + } + + state->handler.type = handler->type; + state->handler.data = handler->data; + state->handler.sync = handler->sync; + state->handler.send = handler->async_send; + state->handler.recv = handler->async_recv; + + state->sbus_req = sbus_req; + state->read_iterator = read_iterator; + state->write_iterator = write_iterator; + + state->in = talloc_zero(state, struct _sbus_ifp_invoker_args_u); + if (state->in == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, + "Unable to allocate space for input parameters!\n"); + ret = ENOMEM; + goto done; + } + + ret = _sbus_ifp_invoker_read_u(state, read_iterator, state->in); + if (ret != EOK) { + goto done; + } + + ret = sbus_invoker_schedule(state, ev, _sbus_ifp_invoke_in_u_out_o_step, req); + if (ret != EOK) { + goto done; + } + + ret = sbus_request_key(state, keygen, sbus_req, state->in, &key); + if (ret != EOK) { + goto done; + } + + if (_key != NULL) { + *_key = talloc_steal(mem_ctx, key); + } + + ret = EAGAIN; + +done: + if (ret != EAGAIN) { + tevent_req_error(req, ret); + tevent_req_post(req, ev); + } + + return req; +} + +static void _sbus_ifp_invoke_in_u_out_o_step + (struct tevent_context *ev, + struct tevent_timer *te, + struct timeval tv, + void *private_data) +{ + struct _sbus_ifp_invoke_in_u_out_o_state *state; + struct tevent_req *subreq; + struct tevent_req *req; + errno_t ret; + + req = talloc_get_type(private_data, struct tevent_req); + state = tevent_req_data(req, struct _sbus_ifp_invoke_in_u_out_o_state); + + switch (state->handler.type) { + case SBUS_HANDLER_SYNC: + if (state->handler.sync == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "Bug: sync handler is not specified!\n"); + ret = ERR_INTERNAL; + goto done; + } + + ret = state->handler.sync(state, state->sbus_req, state->handler.data, state->in->arg0, &state->out.arg0); + if (ret != EOK) { + goto done; + } + + ret = _sbus_ifp_invoker_write_o(state->write_iterator, &state->out); + goto done; + case SBUS_HANDLER_ASYNC: + if (state->handler.send == NULL || state->handler.recv == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "Bug: async handler is not specified!\n"); + ret = ERR_INTERNAL; + goto done; + } + + subreq = state->handler.send(state, ev, state->sbus_req, state->handler.data, state->in->arg0); + if (subreq == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "Unable to create subrequest!\n"); + ret = ENOMEM; + goto done; + } + + tevent_req_set_callback(subreq, _sbus_ifp_invoke_in_u_out_o_done, req); + ret = EAGAIN; + goto done; + } + + ret = ERR_INTERNAL; + +done: + if (ret == EOK) { + tevent_req_done(req); + } else if (ret != EAGAIN) { + tevent_req_error(req, ret); + } +} + +static void _sbus_ifp_invoke_in_u_out_o_done(struct tevent_req *subreq) +{ + struct _sbus_ifp_invoke_in_u_out_o_state *state; + struct tevent_req *req; + errno_t ret; + + req = tevent_req_callback_data(subreq, struct tevent_req); + state = tevent_req_data(req, struct _sbus_ifp_invoke_in_u_out_o_state); + + ret = state->handler.recv(state, subreq, &state->out.arg0); + talloc_zfree(subreq); + if (ret != EOK) { + tevent_req_error(req, ret); + return; + } + + ret = _sbus_ifp_invoker_write_o(state->write_iterator, &state->out); + if (ret != EOK) { + tevent_req_error(req, ret); + return; + } + + tevent_req_done(req); + return; +} diff --git a/src/responder/ifp/ifp_iface/sbus_ifp_invokers.h b/src/responder/ifp/ifp_iface/sbus_ifp_invokers.h new file mode 100644 index 0000000..12d8f22 --- /dev/null +++ b/src/responder/ifp/ifp_iface/sbus_ifp_invokers.h @@ -0,0 +1,60 @@ +/* + Generated by sbus code generator + + Copyright (C) 2017 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 _SBUS_IFP_INVOKERS_H_ +#define _SBUS_IFP_INVOKERS_H_ + +#include <talloc.h> +#include <tevent.h> +#include <dbus/dbus.h> + +#include "sbus/sbus_interface_declarations.h" +#include "sbus/sbus_request.h" + +#define _sbus_ifp_declare_invoker(input, output) \ + struct tevent_req * \ + _sbus_ifp_invoke_in_ ## input ## _out_ ## output ## _send \ + (TALLOC_CTX *mem_ctx, \ + struct tevent_context *ev, \ + struct sbus_request *sbus_req, \ + sbus_invoker_keygen keygen, \ + const struct sbus_handler *handler, \ + DBusMessageIter *read_iterator, \ + DBusMessageIter *write_iterator, \ + const char **_key) + +_sbus_ifp_declare_invoker(, ); +_sbus_ifp_declare_invoker(, ao); +_sbus_ifp_declare_invoker(, as); +_sbus_ifp_declare_invoker(, b); +_sbus_ifp_declare_invoker(, ifp_extra); +_sbus_ifp_declare_invoker(, o); +_sbus_ifp_declare_invoker(, s); +_sbus_ifp_declare_invoker(, u); +_sbus_ifp_declare_invoker(s, ao); +_sbus_ifp_declare_invoker(s, as); +_sbus_ifp_declare_invoker(s, o); +_sbus_ifp_declare_invoker(s, s); +_sbus_ifp_declare_invoker(sas, raw); +_sbus_ifp_declare_invoker(ss, o); +_sbus_ifp_declare_invoker(ssu, ao); +_sbus_ifp_declare_invoker(su, ao); +_sbus_ifp_declare_invoker(u, o); + +#endif /* _SBUS_IFP_INVOKERS_H_ */ diff --git a/src/responder/ifp/ifp_iface/sbus_ifp_keygens.c b/src/responder/ifp/ifp_iface/sbus_ifp_keygens.c new file mode 100644 index 0000000..0f2f4ae --- /dev/null +++ b/src/responder/ifp/ifp_iface/sbus_ifp_keygens.c @@ -0,0 +1,107 @@ +/* + Generated by sbus code generator + + Copyright (C) 2017 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 <inttypes.h> +#include <talloc.h> + +#include "sbus/sbus_request.h" +#include "responder/ifp/ifp_iface/sbus_ifp_arguments.h" +#include "responder/ifp/ifp_iface/sbus_ifp_keygens.h" + +const char * +_sbus_ifp_key_ + (TALLOC_CTX *mem_ctx, + struct sbus_request *sbus_req) +{ + if (sbus_req->sender == NULL) { + return talloc_asprintf(mem_ctx, "-:%u:%s.%s:%s", + sbus_req->type, sbus_req->interface, sbus_req->member, sbus_req->path); + } + + return talloc_asprintf(mem_ctx, "%"PRIi64":%u:%s.%s:%s", + sbus_req->sender->uid, sbus_req->type, sbus_req->interface, sbus_req->member, sbus_req->path); +} + +const char * +_sbus_ifp_key_s_0 + (TALLOC_CTX *mem_ctx, + struct sbus_request *sbus_req, + struct _sbus_ifp_invoker_args_s *args) +{ + if (sbus_req->sender == NULL) { + return talloc_asprintf(mem_ctx, "-:%u:%s.%s:%s:%s", + sbus_req->type, sbus_req->interface, sbus_req->member, + sbus_req->path, args->arg0); + } + + return talloc_asprintf(mem_ctx, "%"PRIi64":%u:%s.%s:%s:%s", + sbus_req->sender->uid, sbus_req->type, sbus_req->interface, sbus_req->member, + sbus_req->path, args->arg0); +} + +const char * +_sbus_ifp_key_ssu_0_1_2 + (TALLOC_CTX *mem_ctx, + struct sbus_request *sbus_req, + struct _sbus_ifp_invoker_args_ssu *args) +{ + if (sbus_req->sender == NULL) { + return talloc_asprintf(mem_ctx, "-:%u:%s.%s:%s:%s:%s:%" PRIu32 "", + sbus_req->type, sbus_req->interface, sbus_req->member, + sbus_req->path, args->arg0, args->arg1, args->arg2); + } + + return talloc_asprintf(mem_ctx, "%"PRIi64":%u:%s.%s:%s:%s:%s:%" PRIu32 "", + sbus_req->sender->uid, sbus_req->type, sbus_req->interface, sbus_req->member, + sbus_req->path, args->arg0, args->arg1, args->arg2); +} + +const char * +_sbus_ifp_key_su_0_1 + (TALLOC_CTX *mem_ctx, + struct sbus_request *sbus_req, + struct _sbus_ifp_invoker_args_su *args) +{ + if (sbus_req->sender == NULL) { + return talloc_asprintf(mem_ctx, "-:%u:%s.%s:%s:%s:%" PRIu32 "", + sbus_req->type, sbus_req->interface, sbus_req->member, + sbus_req->path, args->arg0, args->arg1); + } + + return talloc_asprintf(mem_ctx, "%"PRIi64":%u:%s.%s:%s:%s:%" PRIu32 "", + sbus_req->sender->uid, sbus_req->type, sbus_req->interface, sbus_req->member, + sbus_req->path, args->arg0, args->arg1); +} + +const char * +_sbus_ifp_key_u_0 + (TALLOC_CTX *mem_ctx, + struct sbus_request *sbus_req, + struct _sbus_ifp_invoker_args_u *args) +{ + if (sbus_req->sender == NULL) { + return talloc_asprintf(mem_ctx, "-:%u:%s.%s:%s:%" PRIu32 "", + sbus_req->type, sbus_req->interface, sbus_req->member, + sbus_req->path, args->arg0); + } + + return talloc_asprintf(mem_ctx, "%"PRIi64":%u:%s.%s:%s:%" PRIu32 "", + sbus_req->sender->uid, sbus_req->type, sbus_req->interface, sbus_req->member, + sbus_req->path, args->arg0); +} diff --git a/src/responder/ifp/ifp_iface/sbus_ifp_keygens.h b/src/responder/ifp/ifp_iface/sbus_ifp_keygens.h new file mode 100644 index 0000000..a0e5fb2 --- /dev/null +++ b/src/responder/ifp/ifp_iface/sbus_ifp_keygens.h @@ -0,0 +1,57 @@ +/* + Generated by sbus code generator + + Copyright (C) 2017 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 _SBUS_IFP_KEYGENS_H_ +#define _SBUS_IFP_KEYGENS_H_ + +#include <talloc.h> + +#include "sbus/sbus_request.h" +#include "responder/ifp/ifp_iface/sbus_ifp_arguments.h" + +const char * +_sbus_ifp_key_ + (TALLOC_CTX *mem_ctx, + struct sbus_request *sbus_req); + +const char * +_sbus_ifp_key_s_0 + (TALLOC_CTX *mem_ctx, + struct sbus_request *sbus_req, + struct _sbus_ifp_invoker_args_s *args); + +const char * +_sbus_ifp_key_ssu_0_1_2 + (TALLOC_CTX *mem_ctx, + struct sbus_request *sbus_req, + struct _sbus_ifp_invoker_args_ssu *args); + +const char * +_sbus_ifp_key_su_0_1 + (TALLOC_CTX *mem_ctx, + struct sbus_request *sbus_req, + struct _sbus_ifp_invoker_args_su *args); + +const char * +_sbus_ifp_key_u_0 + (TALLOC_CTX *mem_ctx, + struct sbus_request *sbus_req, + struct _sbus_ifp_invoker_args_u *args); + +#endif /* _SBUS_IFP_KEYGENS_H_ */ diff --git a/src/responder/ifp/ifp_iface/sbus_ifp_server.h b/src/responder/ifp/ifp_iface/sbus_ifp_server.h new file mode 100644 index 0000000..4f65ea6 --- /dev/null +++ b/src/responder/ifp/ifp_iface/sbus_ifp_server.h @@ -0,0 +1,27 @@ +/* + Generated by sbus code generator + + Copyright (C) 2017 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 _SBUS_IFP_SERVER_H_ +#define _SBUS_IFP_SERVER_H_ + +#include "sbus/sbus.h" +#include "sbus/sbus_interface.h" +#include "responder/ifp/ifp_iface/sbus_ifp_interface.h" + +#endif /* _SBUS_IFP_SERVER_H_ */ diff --git a/src/responder/ifp/ifp_iface/sbus_ifp_symbols.c b/src/responder/ifp/ifp_iface/sbus_ifp_symbols.c new file mode 100644 index 0000000..a861fbc --- /dev/null +++ b/src/responder/ifp/ifp_iface/sbus_ifp_symbols.c @@ -0,0 +1,436 @@ +/* + Generated by sbus code generator + + Copyright (C) 2017 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 "sbus/sbus_interface_declarations.h" +#include "responder/ifp/ifp_iface/sbus_ifp_symbols.h" + +const struct sbus_method_arguments +_sbus_ifp_args_org_freedesktop_sssd_infopipe_FindBackendByName = { + .input = (const struct sbus_argument[]){ + {.type = "s", .name = "name"}, + {NULL} + }, + .output = (const struct sbus_argument[]){ + {.type = "o", .name = "backend"}, + {NULL} + } +}; + +const struct sbus_method_arguments +_sbus_ifp_args_org_freedesktop_sssd_infopipe_FindDomainByName = { + .input = (const struct sbus_argument[]){ + {.type = "s", .name = "name"}, + {NULL} + }, + .output = (const struct sbus_argument[]){ + {.type = "o", .name = "domain"}, + {NULL} + } +}; + +const struct sbus_method_arguments +_sbus_ifp_args_org_freedesktop_sssd_infopipe_FindMonitor = { + .input = (const struct sbus_argument[]){ + {NULL} + }, + .output = (const struct sbus_argument[]){ + {.type = "o", .name = "monitor"}, + {NULL} + } +}; + +const struct sbus_method_arguments +_sbus_ifp_args_org_freedesktop_sssd_infopipe_FindResponderByName = { + .input = (const struct sbus_argument[]){ + {.type = "s", .name = "name"}, + {NULL} + }, + .output = (const struct sbus_argument[]){ + {.type = "o", .name = "responder"}, + {NULL} + } +}; + +const struct sbus_method_arguments +_sbus_ifp_args_org_freedesktop_sssd_infopipe_GetUserAttr = { + .input = (const struct sbus_argument[]){ + {.type = "s", .name = "user"}, + {.type = "as", .name = "attr"}, + {NULL} + }, + .output = (const struct sbus_argument[]){ + {.type = "a{sv}", .name = "values"}, + {NULL} + } +}; + +const struct sbus_method_arguments +_sbus_ifp_args_org_freedesktop_sssd_infopipe_GetUserGroups = { + .input = (const struct sbus_argument[]){ + {.type = "s", .name = "user"}, + {NULL} + }, + .output = (const struct sbus_argument[]){ + {.type = "as", .name = "values"}, + {NULL} + } +}; + +const struct sbus_method_arguments +_sbus_ifp_args_org_freedesktop_sssd_infopipe_ListBackends = { + .input = (const struct sbus_argument[]){ + {NULL} + }, + .output = (const struct sbus_argument[]){ + {.type = "ao", .name = "backends"}, + {NULL} + } +}; + +const struct sbus_method_arguments +_sbus_ifp_args_org_freedesktop_sssd_infopipe_ListComponents = { + .input = (const struct sbus_argument[]){ + {NULL} + }, + .output = (const struct sbus_argument[]){ + {.type = "ao", .name = "components"}, + {NULL} + } +}; + +const struct sbus_method_arguments +_sbus_ifp_args_org_freedesktop_sssd_infopipe_ListDomains = { + .input = (const struct sbus_argument[]){ + {NULL} + }, + .output = (const struct sbus_argument[]){ + {.type = "ao", .name = "domain"}, + {NULL} + } +}; + +const struct sbus_method_arguments +_sbus_ifp_args_org_freedesktop_sssd_infopipe_ListResponders = { + .input = (const struct sbus_argument[]){ + {NULL} + }, + .output = (const struct sbus_argument[]){ + {.type = "ao", .name = "responders"}, + {NULL} + } +}; + +const struct sbus_method_arguments +_sbus_ifp_args_org_freedesktop_sssd_infopipe_Ping = { + .input = (const struct sbus_argument[]){ + {.type = "s", .name = "ping"}, + {NULL} + }, + .output = (const struct sbus_argument[]){ + {.type = "s", .name = "pong"}, + {NULL} + } +}; + +const struct sbus_method_arguments +_sbus_ifp_args_org_freedesktop_sssd_infopipe_Cache_List = { + .input = (const struct sbus_argument[]){ + {NULL} + }, + .output = (const struct sbus_argument[]){ + {.type = "ao", .name = "result"}, + {NULL} + } +}; + +const struct sbus_method_arguments +_sbus_ifp_args_org_freedesktop_sssd_infopipe_Cache_ListByDomain = { + .input = (const struct sbus_argument[]){ + {.type = "s", .name = "domain_name"}, + {NULL} + }, + .output = (const struct sbus_argument[]){ + {.type = "ao", .name = "result"}, + {NULL} + } +}; + +const struct sbus_method_arguments +_sbus_ifp_args_org_freedesktop_sssd_infopipe_Cache_Object_Remove = { + .input = (const struct sbus_argument[]){ + {NULL} + }, + .output = (const struct sbus_argument[]){ + {.type = "b", .name = "result"}, + {NULL} + } +}; + +const struct sbus_method_arguments +_sbus_ifp_args_org_freedesktop_sssd_infopipe_Cache_Object_Store = { + .input = (const struct sbus_argument[]){ + {NULL} + }, + .output = (const struct sbus_argument[]){ + {.type = "b", .name = "result"}, + {NULL} + } +}; + +const struct sbus_method_arguments +_sbus_ifp_args_org_freedesktop_sssd_infopipe_Domains_Domain_ActiveServer = { + .input = (const struct sbus_argument[]){ + {.type = "s", .name = "service"}, + {NULL} + }, + .output = (const struct sbus_argument[]){ + {.type = "s", .name = "server"}, + {NULL} + } +}; + +const struct sbus_method_arguments +_sbus_ifp_args_org_freedesktop_sssd_infopipe_Domains_Domain_IsOnline = { + .input = (const struct sbus_argument[]){ + {NULL} + }, + .output = (const struct sbus_argument[]){ + {.type = "b", .name = "status"}, + {NULL} + } +}; + +const struct sbus_method_arguments +_sbus_ifp_args_org_freedesktop_sssd_infopipe_Domains_Domain_ListServers = { + .input = (const struct sbus_argument[]){ + {.type = "s", .name = "service_name"}, + {NULL} + }, + .output = (const struct sbus_argument[]){ + {.type = "as", .name = "servers"}, + {NULL} + } +}; + +const struct sbus_method_arguments +_sbus_ifp_args_org_freedesktop_sssd_infopipe_Domains_Domain_ListServices = { + .input = (const struct sbus_argument[]){ + {NULL} + }, + .output = (const struct sbus_argument[]){ + {.type = "as", .name = "services"}, + {NULL} + } +}; + +const struct sbus_method_arguments +_sbus_ifp_args_org_freedesktop_sssd_infopipe_Domains_Domain_RefreshAccessRules = { + .input = (const struct sbus_argument[]){ + {NULL} + }, + .output = (const struct sbus_argument[]){ + {NULL} + } +}; + +const struct sbus_method_arguments +_sbus_ifp_args_org_freedesktop_sssd_infopipe_Groups_FindByID = { + .input = (const struct sbus_argument[]){ + {.type = "u", .name = "id"}, + {NULL} + }, + .output = (const struct sbus_argument[]){ + {.type = "o", .name = "result"}, + {NULL} + } +}; + +const struct sbus_method_arguments +_sbus_ifp_args_org_freedesktop_sssd_infopipe_Groups_FindByName = { + .input = (const struct sbus_argument[]){ + {.type = "s", .name = "name"}, + {NULL} + }, + .output = (const struct sbus_argument[]){ + {.type = "o", .name = "result"}, + {NULL} + } +}; + +const struct sbus_method_arguments +_sbus_ifp_args_org_freedesktop_sssd_infopipe_Groups_ListByDomainAndName = { + .input = (const struct sbus_argument[]){ + {.type = "s", .name = "domain_name"}, + {.type = "s", .name = "name_filter"}, + {.type = "u", .name = "limit"}, + {NULL} + }, + .output = (const struct sbus_argument[]){ + {.type = "ao", .name = "result"}, + {NULL} + } +}; + +const struct sbus_method_arguments +_sbus_ifp_args_org_freedesktop_sssd_infopipe_Groups_ListByName = { + .input = (const struct sbus_argument[]){ + {.type = "s", .name = "name_filter"}, + {.type = "u", .name = "limit"}, + {NULL} + }, + .output = (const struct sbus_argument[]){ + {.type = "ao", .name = "result"}, + {NULL} + } +}; + +const struct sbus_method_arguments +_sbus_ifp_args_org_freedesktop_sssd_infopipe_Groups_Group_UpdateMemberList = { + .input = (const struct sbus_argument[]){ + {NULL} + }, + .output = (const struct sbus_argument[]){ + {NULL} + } +}; + +const struct sbus_method_arguments +_sbus_ifp_args_org_freedesktop_sssd_infopipe_Users_FindByCertificate = { + .input = (const struct sbus_argument[]){ + {.type = "s", .name = "pem_cert"}, + {NULL} + }, + .output = (const struct sbus_argument[]){ + {.type = "o", .name = "result"}, + {NULL} + } +}; + +const struct sbus_method_arguments +_sbus_ifp_args_org_freedesktop_sssd_infopipe_Users_FindByID = { + .input = (const struct sbus_argument[]){ + {.type = "u", .name = "id"}, + {NULL} + }, + .output = (const struct sbus_argument[]){ + {.type = "o", .name = "result"}, + {NULL} + } +}; + +const struct sbus_method_arguments +_sbus_ifp_args_org_freedesktop_sssd_infopipe_Users_FindByName = { + .input = (const struct sbus_argument[]){ + {.type = "s", .name = "name"}, + {NULL} + }, + .output = (const struct sbus_argument[]){ + {.type = "o", .name = "result"}, + {NULL} + } +}; + +const struct sbus_method_arguments +_sbus_ifp_args_org_freedesktop_sssd_infopipe_Users_FindByNameAndCertificate = { + .input = (const struct sbus_argument[]){ + {.type = "s", .name = "name"}, + {.type = "s", .name = "pem_cert"}, + {NULL} + }, + .output = (const struct sbus_argument[]){ + {.type = "o", .name = "result"}, + {NULL} + } +}; + +const struct sbus_method_arguments +_sbus_ifp_args_org_freedesktop_sssd_infopipe_Users_FindByValidCertificate = { + .input = (const struct sbus_argument[]){ + {.type = "s", .name = "pem_cert"}, + {NULL} + }, + .output = (const struct sbus_argument[]){ + {.type = "o", .name = "result"}, + {NULL} + } +}; + +const struct sbus_method_arguments +_sbus_ifp_args_org_freedesktop_sssd_infopipe_Users_ListByAttr = { + .input = (const struct sbus_argument[]){ + {.type = "s", .name = "attribute"}, + {.type = "s", .name = "attr_filter"}, + {.type = "u", .name = "limit"}, + {NULL} + }, + .output = (const struct sbus_argument[]){ + {.type = "ao", .name = "result"}, + {NULL} + } +}; + +const struct sbus_method_arguments +_sbus_ifp_args_org_freedesktop_sssd_infopipe_Users_ListByCertificate = { + .input = (const struct sbus_argument[]){ + {.type = "s", .name = "pem_cert"}, + {.type = "u", .name = "limit"}, + {NULL} + }, + .output = (const struct sbus_argument[]){ + {.type = "ao", .name = "result"}, + {NULL} + } +}; + +const struct sbus_method_arguments +_sbus_ifp_args_org_freedesktop_sssd_infopipe_Users_ListByDomainAndName = { + .input = (const struct sbus_argument[]){ + {.type = "s", .name = "domain_name"}, + {.type = "s", .name = "name_filter"}, + {.type = "u", .name = "limit"}, + {NULL} + }, + .output = (const struct sbus_argument[]){ + {.type = "ao", .name = "result"}, + {NULL} + } +}; + +const struct sbus_method_arguments +_sbus_ifp_args_org_freedesktop_sssd_infopipe_Users_ListByName = { + .input = (const struct sbus_argument[]){ + {.type = "s", .name = "name_filter"}, + {.type = "u", .name = "limit"}, + {NULL} + }, + .output = (const struct sbus_argument[]){ + {.type = "ao", .name = "result"}, + {NULL} + } +}; + +const struct sbus_method_arguments +_sbus_ifp_args_org_freedesktop_sssd_infopipe_Users_User_UpdateGroupsList = { + .input = (const struct sbus_argument[]){ + {NULL} + }, + .output = (const struct sbus_argument[]){ + {NULL} + } +}; diff --git a/src/responder/ifp/ifp_iface/sbus_ifp_symbols.h b/src/responder/ifp/ifp_iface/sbus_ifp_symbols.h new file mode 100644 index 0000000..f433fa7 --- /dev/null +++ b/src/responder/ifp/ifp_iface/sbus_ifp_symbols.h @@ -0,0 +1,130 @@ +/* + Generated by sbus code generator + + Copyright (C) 2017 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 _SBUS_IFP_SYMBOLS_H_ +#define _SBUS_IFP_SYMBOLS_H_ + +#include "sbus/sbus_interface_declarations.h" + +extern const struct sbus_method_arguments +_sbus_ifp_args_org_freedesktop_sssd_infopipe_FindBackendByName; + +extern const struct sbus_method_arguments +_sbus_ifp_args_org_freedesktop_sssd_infopipe_FindDomainByName; + +extern const struct sbus_method_arguments +_sbus_ifp_args_org_freedesktop_sssd_infopipe_FindMonitor; + +extern const struct sbus_method_arguments +_sbus_ifp_args_org_freedesktop_sssd_infopipe_FindResponderByName; + +extern const struct sbus_method_arguments +_sbus_ifp_args_org_freedesktop_sssd_infopipe_GetUserAttr; + +extern const struct sbus_method_arguments +_sbus_ifp_args_org_freedesktop_sssd_infopipe_GetUserGroups; + +extern const struct sbus_method_arguments +_sbus_ifp_args_org_freedesktop_sssd_infopipe_ListBackends; + +extern const struct sbus_method_arguments +_sbus_ifp_args_org_freedesktop_sssd_infopipe_ListComponents; + +extern const struct sbus_method_arguments +_sbus_ifp_args_org_freedesktop_sssd_infopipe_ListDomains; + +extern const struct sbus_method_arguments +_sbus_ifp_args_org_freedesktop_sssd_infopipe_ListResponders; + +extern const struct sbus_method_arguments +_sbus_ifp_args_org_freedesktop_sssd_infopipe_Ping; + +extern const struct sbus_method_arguments +_sbus_ifp_args_org_freedesktop_sssd_infopipe_Cache_List; + +extern const struct sbus_method_arguments +_sbus_ifp_args_org_freedesktop_sssd_infopipe_Cache_ListByDomain; + +extern const struct sbus_method_arguments +_sbus_ifp_args_org_freedesktop_sssd_infopipe_Cache_Object_Remove; + +extern const struct sbus_method_arguments +_sbus_ifp_args_org_freedesktop_sssd_infopipe_Cache_Object_Store; + +extern const struct sbus_method_arguments +_sbus_ifp_args_org_freedesktop_sssd_infopipe_Domains_Domain_ActiveServer; + +extern const struct sbus_method_arguments +_sbus_ifp_args_org_freedesktop_sssd_infopipe_Domains_Domain_IsOnline; + +extern const struct sbus_method_arguments +_sbus_ifp_args_org_freedesktop_sssd_infopipe_Domains_Domain_ListServers; + +extern const struct sbus_method_arguments +_sbus_ifp_args_org_freedesktop_sssd_infopipe_Domains_Domain_ListServices; + +extern const struct sbus_method_arguments +_sbus_ifp_args_org_freedesktop_sssd_infopipe_Domains_Domain_RefreshAccessRules; + +extern const struct sbus_method_arguments +_sbus_ifp_args_org_freedesktop_sssd_infopipe_Groups_FindByID; + +extern const struct sbus_method_arguments +_sbus_ifp_args_org_freedesktop_sssd_infopipe_Groups_FindByName; + +extern const struct sbus_method_arguments +_sbus_ifp_args_org_freedesktop_sssd_infopipe_Groups_ListByDomainAndName; + +extern const struct sbus_method_arguments +_sbus_ifp_args_org_freedesktop_sssd_infopipe_Groups_ListByName; + +extern const struct sbus_method_arguments +_sbus_ifp_args_org_freedesktop_sssd_infopipe_Groups_Group_UpdateMemberList; + +extern const struct sbus_method_arguments +_sbus_ifp_args_org_freedesktop_sssd_infopipe_Users_FindByCertificate; + +extern const struct sbus_method_arguments +_sbus_ifp_args_org_freedesktop_sssd_infopipe_Users_FindByID; + +extern const struct sbus_method_arguments +_sbus_ifp_args_org_freedesktop_sssd_infopipe_Users_FindByName; + +extern const struct sbus_method_arguments +_sbus_ifp_args_org_freedesktop_sssd_infopipe_Users_FindByNameAndCertificate; + +extern const struct sbus_method_arguments +_sbus_ifp_args_org_freedesktop_sssd_infopipe_Users_FindByValidCertificate; + +extern const struct sbus_method_arguments +_sbus_ifp_args_org_freedesktop_sssd_infopipe_Users_ListByAttr; + +extern const struct sbus_method_arguments +_sbus_ifp_args_org_freedesktop_sssd_infopipe_Users_ListByCertificate; + +extern const struct sbus_method_arguments +_sbus_ifp_args_org_freedesktop_sssd_infopipe_Users_ListByDomainAndName; + +extern const struct sbus_method_arguments +_sbus_ifp_args_org_freedesktop_sssd_infopipe_Users_ListByName; + +extern const struct sbus_method_arguments +_sbus_ifp_args_org_freedesktop_sssd_infopipe_Users_User_UpdateGroupsList; + +#endif /* _SBUS_IFP_SYMBOLS_H_ */ diff --git a/src/responder/ifp/ifp_iface_nodes.c b/src/responder/ifp/ifp_iface_nodes.c new file mode 100644 index 0000000..18e5374 --- /dev/null +++ b/src/responder/ifp/ifp_iface_nodes.c @@ -0,0 +1,166 @@ +/* + Authors: + Pavel Březina <pbrezina@redhat.com> + + Copyright (C) 2015 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 "responder/ifp/ifp_users.h" +#include "responder/ifp/ifp_groups.h" +#include "responder/ifp/ifp_cache.h" +#include "responder/ifp/ifp_domains.h" +#include "responder/ifp/ifp_iface/ifp_iface_async.h" + +static errno_t +nodes_ifp(TALLOC_CTX *mem_ctx, + const char *path, + struct ifp_ctx *ctx, + const char ***_nodes) +{ + static const char *nodes[] = {"Users", "Groups", "Domains", NULL}; + + *_nodes = nodes; + + return EOK; +} + +static errno_t +nodes_cached_objects(TALLOC_CTX *mem_ctx, + struct ifp_ctx *ifp_ctx, + enum ifp_cache_type type, + const char *prefix, + const char ***_nodes) +{ + TALLOC_CTX *tmp_ctx; + const char **paths; + const char **nodes; + const char *node; + int num_paths; + errno_t ret; + int i; + + tmp_ctx = talloc_new(NULL); + if (tmp_ctx == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "talloc_new() failed\n"); + return ENOMEM; + } + + ret = ifp_cache_list_domains(tmp_ctx, ifp_ctx->rctx->domains, type, &paths); + if (ret != EOK) { + DEBUG(SSSDBG_CRIT_FAILURE, "Unable to obtain cache objects list " + "[%d]: %s\n", ret, sss_strerror(ret)); + goto done; + } + + num_paths = talloc_array_length(paths) - 1; + nodes = talloc_zero_array(tmp_ctx, const char *, num_paths + 1); + if (nodes == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "talloc_zero_array() failed\n"); + ret = ENOMEM; + goto done; + } + + for (i = 0; i < num_paths; i++) { + node = sbus_opath_strip_prefix(paths[i], prefix); + nodes[i] = talloc_strdup(nodes, node); + if (nodes[i] == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "talloc_strdup() failed\n"); + ret = ENOMEM; + goto done; + } + } + + *_nodes = talloc_steal(mem_ctx, nodes); + + ret = EOK; + +done: + talloc_free(tmp_ctx); + return ret; +} + +static errno_t +nodes_users(TALLOC_CTX *mem_ctx, + const char *path, + struct ifp_ctx *ctx, + const char ***_nodes) +{ + return nodes_cached_objects(mem_ctx, ctx, IFP_CACHE_USER, + IFP_PATH_USERS "/", _nodes); +} + +static errno_t +nodes_groups(TALLOC_CTX *mem_ctx, + const char *path, + struct ifp_ctx *ctx, + const char ***_nodes) +{ + return nodes_cached_objects(mem_ctx, ctx, IFP_CACHE_GROUP, + IFP_PATH_GROUPS "/", _nodes); +} + +static errno_t +nodes_domains(TALLOC_CTX *mem_ctx, + const char *path, + struct ifp_ctx *ctx, + const char ***_nodes) +{ + struct sss_domain_info *domain; + const char **nodes; + size_t count; + + count = 0; + domain = ctx->rctx->domains; + do { + count++; + } while ((domain = get_next_domain(domain, SSS_GND_ALL_DOMAINS)) != NULL); + + nodes = talloc_zero_array(mem_ctx, const char *, count + 1); + if (nodes == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "talloc_zero_array() failed\n"); + return ENOMEM; + } + + count = 0; + domain = ctx->rctx->domains; + do { + nodes[count] = sbus_opath_escape(nodes, domain->name); + if (nodes[count] == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "sbus_opath_escape_part() failed\n"); + talloc_free(nodes); + return ENOMEM; + } + + count++; + } while ((domain = get_next_domain(domain, SSS_GND_ALL_DOMAINS)) != NULL); + + *_nodes = nodes; + + return EOK; +} + +errno_t +ifp_register_nodes(struct ifp_ctx *ctx, struct sbus_connection *conn) +{ + struct sbus_node nodes[] = SBUS_NODES( + SBUS_NODE_SYNC(IFP_PATH, nodes_ifp, ctx), + SBUS_NODE_SYNC(IFP_PATH_USERS, nodes_users, ctx), + SBUS_NODE_SYNC(IFP_PATH_GROUPS, nodes_groups, ctx), + SBUS_NODE_SYNC(IFP_PATH_DOMAINS, nodes_domains, ctx) + ); + + return sbus_router_add_node_map(conn, nodes); +} diff --git a/src/responder/ifp/ifp_private.h b/src/responder/ifp/ifp_private.h new file mode 100644 index 0000000..e9a9d3a --- /dev/null +++ b/src/responder/ifp/ifp_private.h @@ -0,0 +1,137 @@ +/* + Authors: + Jakub Hrozek <jhrozek@redhat.com> + Stephen Gallagher <sgallagh@redhat.com> + + Copyright (C) 2013 Red Hat + + InfoPipe responder: A private header + + 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 _IFPSRV_PRIVATE_H_ +#define _IFPSRV_PRIVATE_H_ + +#include <talloc.h> +#include <tevent.h> +#include <stdint.h> +#include <ldb.h> + +#include "util/util.h" +#include "confdb/confdb.h" +#include "responder/common/responder.h" +#include "responder/common/negcache.h" +#include "responder/ifp/ifp_iface/ifp_iface_async.h" + +struct ifp_ctx { + struct resp_ctx *rctx; + struct sss_names_ctx *snctx; + + struct sbus_connection *sysbus; + const char **user_whitelist; + uint32_t wildcard_limit; +}; + +errno_t +ifp_access_check(struct sbus_request *sbus_req, + struct ifp_ctx *ifp_ctx); + +errno_t ifp_register_sbus_interface(struct sbus_connection *conn, + struct ifp_ctx *ifp_ctx); + +errno_t +ifp_register_nodes(struct ifp_ctx *ctx, struct sbus_connection *conn); + +errno_t +ifp_ping(TALLOC_CTX *mem_ctx, + struct sbus_request *sbus_req, + struct ifp_ctx *ctx, + const char *ping, + const char **_pong); + +struct tevent_req * +ifp_get_user_attr_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct sbus_request *sbus_req, + struct ifp_ctx *ctx, + const char *name, + const char **attrs, + DBusMessageIter *write_iter); + +errno_t +ifp_get_user_attr_recv(TALLOC_CTX *mem_ctx, struct tevent_req *req); + +struct tevent_req * +ifp_user_get_groups_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct sbus_request *sbus_req, + struct ifp_ctx *ctx, + const char *name); + +errno_t +ifp_user_get_groups_recv(TALLOC_CTX *mem_ctx, + struct tevent_req *req, + const char ***_groupnames); + +/* == Utility functions == */ + +errno_t ifp_add_value_to_dict(DBusMessageIter *iter_dict, + const char *key, + const char *value); + +errno_t ifp_add_ldb_el_to_dict(DBusMessageIter *iter_dict, + struct ldb_message_element *el); +const char ** +ifp_parse_user_attr_list(TALLOC_CTX *mem_ctx, const char *conf_str); + +const char ** +ifp_get_user_extra_attributes(TALLOC_CTX *mem_ctx, struct ifp_ctx *ifp_ctx); + +bool ifp_attr_allowed(const char *whitelist[], const char *attr); +bool ifp_is_user_attr_allowed(struct ifp_ctx *ifp_ctx, const char *attr); + +/* Used for list calls */ +struct ifp_list_ctx { + const char *attr; + const char *filter; + uint32_t limit; + + struct sss_domain_info *dom; + struct ifp_ctx *ctx; + + const char **paths; + size_t paths_max; + size_t path_count; +}; + +struct ifp_list_ctx *ifp_list_ctx_new(TALLOC_CTX *mem_ctx, + struct ifp_ctx *ctx, + const char *attr, + const char *filter, + uint32_t limit); + +errno_t ifp_list_ctx_remaining_capacity(struct ifp_list_ctx *list_ctx, + size_t entries, + size_t *_capacity); + +errno_t ifp_ldb_el_output_name(struct resp_ctx *rctx, + struct ldb_message *msg, + const char *el_name, + struct sss_domain_info *dom); + +char *ifp_format_name_attr(TALLOC_CTX *mem_ctx, struct ifp_ctx *ifp_ctx, + const char *in_name, struct sss_domain_info *dom); + +#endif /* _IFPSRV_PRIVATE_H_ */ diff --git a/src/responder/ifp/ifp_users.c b/src/responder/ifp/ifp_users.c new file mode 100644 index 0000000..7acd46e --- /dev/null +++ b/src/responder/ifp/ifp_users.c @@ -0,0 +1,2040 @@ +/* + Authors: + Pavel Březina <pbrezina@redhat.com> + + Copyright (C) 2015 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 <talloc.h> +#include <tevent.h> +#include <string.h> + +#include "db/sysdb.h" +#include "util/util.h" +#include "util/strtonum.h" +#include "util/cert.h" +#include "util/child_common.h" +#include "util/crypto/sss_crypto.h" +#include "responder/common/responder.h" +#include "responder/common/cache_req/cache_req.h" +#include "responder/ifp/ifp_users.h" +#include "responder/ifp/ifp_groups.h" +#include "responder/ifp/ifp_cache.h" +#include "responder/ifp/ifp_iface/ifp_iface_async.h" + +char * ifp_users_build_path_from_msg(TALLOC_CTX *mem_ctx, + struct sss_domain_info *domain, + struct ldb_message *msg) +{ + const char *key = NULL; + + switch (domain->type) { + case DOM_TYPE_APPLICATION: + key = ldb_msg_find_attr_as_string(msg, SYSDB_NAME, NULL); + break; + case DOM_TYPE_POSIX: + key = ldb_msg_find_attr_as_string(msg, SYSDB_UIDNUM, NULL); + break; + } + + + if (key == NULL) { + return NULL; + } + + return sbus_opath_compose(mem_ctx, IFP_PATH_USERS, domain->name, key); +} + +static errno_t ifp_users_decompose_path(TALLOC_CTX *mem_ctx, + struct sss_domain_info *domains, + const char *path, + struct sss_domain_info **_domain, + char **_key) +{ + char **parts = NULL; + struct sss_domain_info *domain; + errno_t ret; + + ret = sbus_opath_decompose_expected(NULL, path, IFP_PATH_USERS, 2, &parts); + if (ret != EOK) { + return ret; + } + + domain = find_domain_by_name(domains, parts[0], false); + if (domain == NULL) { + ret = ERR_DOMAIN_NOT_FOUND; + goto done; + } + + *_domain = domain; + *_key = talloc_steal(mem_ctx, parts[1]); + +done: + talloc_free(parts); + return ret; +} + +static int ifp_users_list_copy(struct ifp_list_ctx *list_ctx, + struct sss_domain_info *domain, + struct ldb_result *result) +{ + size_t copy_count, i; + errno_t ret; + + ret = ifp_list_ctx_remaining_capacity(list_ctx, result->count, ©_count); + if (ret != EOK) { + goto done; + } + + for (i = 0; i < copy_count; i++) { + list_ctx->paths[list_ctx->path_count + i] = \ + ifp_users_build_path_from_msg(list_ctx->paths, + domain, + result->msgs[i]); + if (list_ctx->paths[list_ctx->path_count + i] == NULL) { + ret = ENOMEM; + goto done; + } + } + + list_ctx->path_count += copy_count; + ret = EOK; + +done: + return ret; +} + +struct ifp_users_find_by_name_state { + const char *path; +}; + +static void ifp_users_find_by_name_done(struct tevent_req *subreq); + +struct tevent_req * +ifp_users_find_by_name_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct sbus_request *sbus_req, + struct ifp_ctx *ctx, + const char *name) +{ + struct ifp_users_find_by_name_state *state; + struct tevent_req *subreq; + struct tevent_req *req; + errno_t ret; + + req = tevent_req_create(mem_ctx, &state, + struct ifp_users_find_by_name_state); + if (req == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "Unable to create tevent request!\n"); + return NULL; + } + + subreq = cache_req_user_by_name_send(state, ctx->rctx->ev, ctx->rctx, + ctx->rctx->ncache, 0, + CACHE_REQ_ANY_DOM, NULL, + name); + if (subreq == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "Unable to create subrequest!\n"); + ret = ENOMEM; + goto done; + } + + tevent_req_set_callback(subreq, ifp_users_find_by_name_done, req); + + ret = EAGAIN; + +done: + if (ret != EAGAIN) { + tevent_req_error(req, ret); + tevent_req_post(req, ev); + } + + return req; +} + +static void ifp_users_find_by_name_done(struct tevent_req *subreq) +{ + struct ifp_users_find_by_name_state *state; + struct cache_req_result *result; + struct tevent_req *req; + errno_t ret; + + req = tevent_req_callback_data(subreq, struct tevent_req); + state = tevent_req_data(req, struct ifp_users_find_by_name_state); + + ret = cache_req_user_by_name_recv(state, subreq, &result); + talloc_zfree(subreq); + if (ret != EOK) { + DEBUG(SSSDBG_MINOR_FAILURE, "Unable to find user [%d]: %s\n", + ret, sss_strerror(ret)); + tevent_req_error(req, ret); + return; + } + + state->path = ifp_users_build_path_from_msg(state, result->domain, + result->msgs[0]); + if (state->path == NULL) { + tevent_req_error(req, ENOMEM); + return; + } + + tevent_req_done(req); + return; +} + +errno_t +ifp_users_find_by_name_recv(TALLOC_CTX *mem_ctx, + struct tevent_req *req, + const char **_path) +{ + struct ifp_users_find_by_name_state *state; + state = tevent_req_data(req, struct ifp_users_find_by_name_state); + + TEVENT_REQ_RETURN_ON_ERROR(req); + + *_path = talloc_steal(mem_ctx, state->path); + + return EOK; +} + +struct ifp_users_find_by_id_state { + const char *path; +}; + +static void ifp_users_find_by_id_done(struct tevent_req *subreq); + +struct tevent_req * +ifp_users_find_by_id_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct sbus_request *sbus_req, + struct ifp_ctx *ctx, + uint32_t id) +{ + struct ifp_users_find_by_id_state *state; + struct tevent_req *subreq; + struct tevent_req *req; + errno_t ret; + + req = tevent_req_create(mem_ctx, &state, struct ifp_users_find_by_id_state); + if (req == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "Unable to create tevent request!\n"); + return NULL; + } + + subreq = cache_req_user_by_id_send(state, ctx->rctx->ev, ctx->rctx, + ctx->rctx->ncache, 0, NULL, id); + if (subreq == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "Unable to create subrequest!\n"); + ret = ENOMEM; + goto done; + } + + tevent_req_set_callback(subreq, ifp_users_find_by_id_done, req); + + ret = EAGAIN; + +done: + if (ret != EAGAIN) { + tevent_req_error(req, ret); + tevent_req_post(req, ev); + } + + return req; +} + +static void ifp_users_find_by_id_done(struct tevent_req *subreq) +{ + struct ifp_users_find_by_id_state *state; + struct cache_req_result *result; + struct tevent_req *req; + errno_t ret; + + req = tevent_req_callback_data(subreq, struct tevent_req); + state = tevent_req_data(req, struct ifp_users_find_by_id_state); + + ret = cache_req_user_by_id_recv(state, subreq, &result); + talloc_zfree(subreq); + if (ret != EOK) { + DEBUG(SSSDBG_MINOR_FAILURE, "Unable to find user [%d]: %s\n", + ret, sss_strerror(ret)); + tevent_req_error(req, ret); + return; + } + + state->path = ifp_users_build_path_from_msg(state, result->domain, + result->msgs[0]); + if (state->path == NULL) { + tevent_req_error(req, ENOMEM); + return; + } + + tevent_req_done(req); + return; +} + +errno_t +ifp_users_find_by_id_recv(TALLOC_CTX *mem_ctx, + struct tevent_req *req, + const char **_path) +{ + struct ifp_users_find_by_id_state *state; + state = tevent_req_data(req, struct ifp_users_find_by_id_state); + + TEVENT_REQ_RETURN_ON_ERROR(req); + + *_path = talloc_steal(mem_ctx, state->path); + + return EOK; +} + +struct ifp_users_find_by_cert_state { + const char *path; +}; + +static void ifp_users_find_by_cert_done(struct tevent_req *subreq); + +struct tevent_req * +ifp_users_find_by_cert_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct sbus_request *sbus_req, + struct ifp_ctx *ctx, + const char *pem_cert) +{ + struct ifp_users_find_by_cert_state *state; + struct tevent_req *subreq; + struct tevent_req *req; + char *derb64; + errno_t ret; + + req = tevent_req_create(mem_ctx, &state, struct ifp_users_find_by_cert_state); + if (req == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "Unable to create tevent request!\n"); + return NULL; + } + + ret = sss_cert_pem_to_derb64(state, pem_cert, &derb64); + if (ret != EOK) { + DEBUG(SSSDBG_OP_FAILURE, "sss_cert_pem_to_derb64 failed.\n"); + goto done; + } + + subreq = cache_req_user_by_cert_send(state, ctx->rctx->ev, ctx->rctx, + ctx->rctx->ncache, 0, CACHE_REQ_ANY_DOM, + NULL, derb64); + if (subreq == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "Unable to create subrequest!\n"); + ret = ENOMEM; + goto done; + } + + tevent_req_set_callback(subreq, ifp_users_find_by_cert_done, req); + + ret = EAGAIN; + +done: + if (ret != EAGAIN) { + tevent_req_error(req, ret); + tevent_req_post(req, ev); + } + + return req; +} + +static void ifp_users_find_by_cert_done(struct tevent_req *subreq) +{ + struct ifp_users_find_by_cert_state *state; + struct cache_req_result *result; + struct tevent_req *req; + errno_t ret; + + req = tevent_req_callback_data(subreq, struct tevent_req); + state = tevent_req_data(req, struct ifp_users_find_by_cert_state); + + ret = cache_req_user_by_cert_recv(state, subreq, &result); + talloc_zfree(subreq); + if (ret != EOK) { + DEBUG(SSSDBG_MINOR_FAILURE, "Unable to find user [%d]: %s\n", + ret, sss_strerror(ret)); + tevent_req_error(req, ret); + return; + } + + if (result->count > 1) { + DEBUG(SSSDBG_CRIT_FAILURE, "More than one user found. " + "Use ListByCertificate to get all.\n"); + tevent_req_error(req, EINVAL); + return; + } + + state->path = ifp_users_build_path_from_msg(state, result->domain, + result->msgs[0]); + if (state->path == NULL) { + tevent_req_error(req, ENOMEM); + return; + } + + tevent_req_done(req); + return; +} + +errno_t +ifp_users_find_by_cert_recv(TALLOC_CTX *mem_ctx, + struct tevent_req *req, + const char **_path) +{ + struct ifp_users_find_by_cert_state *state; + state = tevent_req_data(req, struct ifp_users_find_by_cert_state); + + TEVENT_REQ_RETURN_ON_ERROR(req); + + *_path = talloc_steal(mem_ctx, state->path); + + return EOK; +} + +struct ifp_users_list_by_cert_state { + struct ifp_ctx *ifp_ctx; + struct ifp_list_ctx *list_ctx; + char *derb64; +}; + +static errno_t ifp_users_list_by_cert_step(struct tevent_req *req); +static void ifp_users_list_by_cert_done(struct tevent_req *subreq); + +struct tevent_req * +ifp_users_list_by_cert_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct sbus_request *sbus_req, + struct ifp_ctx *ctx, + const char *pem_cert, + uint32_t limit) +{ + struct ifp_users_list_by_cert_state *state; + struct tevent_req *req; + errno_t ret; + + req = tevent_req_create(mem_ctx, &state, struct ifp_users_list_by_cert_state); + if (req == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "Unable to create tevent request!\n"); + return NULL; + } + + ret = sss_cert_pem_to_derb64(state, pem_cert, &state->derb64); + if (ret != EOK) { + DEBUG(SSSDBG_OP_FAILURE, "sss_cert_pem_to_derb64 failed.\n"); + goto done; + } + + state->ifp_ctx = ctx; + state->list_ctx = ifp_list_ctx_new(state, ctx, NULL, state->derb64, limit); + if (state->list_ctx == NULL) { + ret = ENOMEM; + goto done; + } + + ret = ifp_users_list_by_cert_step(req); + +done: + if (ret == EOK) { + tevent_req_done(req); + tevent_req_post(req, ev); + } else if (ret != EAGAIN) { + tevent_req_error(req, ret); + tevent_req_post(req, ev); + } + + return req; +} + +static errno_t +ifp_users_list_by_cert_step(struct tevent_req *req) +{ + struct ifp_users_list_by_cert_state *state; + struct tevent_req *subreq; + + state = tevent_req_data(req, struct ifp_users_list_by_cert_state); + + if (state->list_ctx->dom == NULL) { + return EOK; + } + + subreq = cache_req_user_by_cert_send(state->list_ctx, + state->ifp_ctx->rctx->ev, + state->ifp_ctx->rctx, + state->ifp_ctx->rctx->ncache, + 0, + CACHE_REQ_ANY_DOM, + state->list_ctx->dom->name, + state->list_ctx->filter); + if (subreq == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "Unable to create subrequest!\n"); + return ENOMEM; + } + + tevent_req_set_callback(subreq, ifp_users_list_by_cert_done, req); + + state->list_ctx->dom = get_next_domain(state->list_ctx->dom, + SSS_GND_DESCEND); + + return EAGAIN; +} + +static void ifp_users_list_by_cert_done(struct tevent_req *subreq) +{ + struct ifp_users_list_by_cert_state *state; + struct cache_req_result *result; + struct tevent_req *req; + errno_t ret; + + req = tevent_req_callback_data(subreq, struct tevent_req); + state = tevent_req_data(req, struct ifp_users_list_by_cert_state); + + ret = cache_req_user_by_cert_recv(state, subreq, &result); + talloc_zfree(subreq); + if (ret == EOK) { + ret = ifp_users_list_copy(state->list_ctx, result->domain, + result->ldb_result); + if (ret != EOK) { + DEBUG(SSSDBG_CRIT_FAILURE, "Failed to copy domain result\n"); + tevent_req_error(req, ret); + return; + } + } else if (ret != ENOENT) { + DEBUG(SSSDBG_MINOR_FAILURE, "Unable to list groups [%d]: %s\n", + ret, sss_strerror(ret)); + tevent_req_error(req, ret); + return; + } + + ret = ifp_users_list_by_cert_step(req); + if (ret == EOK) { + tevent_req_done(req); + } else if (ret != EAGAIN) { + tevent_req_error(req, ret); + } +} + +errno_t +ifp_users_list_by_cert_recv(TALLOC_CTX *mem_ctx, + struct tevent_req *req, + const char ***_paths) +{ + struct ifp_users_list_by_cert_state *state; + state = tevent_req_data(req, struct ifp_users_list_by_cert_state); + + TEVENT_REQ_RETURN_ON_ERROR(req); + + *_paths = talloc_steal(mem_ctx, state->list_ctx->paths); + + return EOK; +} + +struct ifp_users_find_by_name_and_cert_state { + struct ifp_ctx *ifp_ctx; + struct ifp_list_ctx *list_ctx; + const char *name; + const char *pem_cert; + char *derb64; + + const char *user_opath; +}; + +static void ifp_users_find_by_name_and_cert_name_done(struct tevent_req *subreq); +static errno_t ifp_users_find_by_name_and_cert_step(struct tevent_req *req); +static void ifp_users_find_by_name_and_cert_done(struct tevent_req *subreq); + +struct tevent_req * +ifp_users_find_by_name_and_cert_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct sbus_request *sbus_req, + struct ifp_ctx *ctx, + const char *name, + const char *pem_cert) +{ + struct ifp_users_find_by_name_and_cert_state *state; + struct tevent_req *subreq; + struct tevent_req *req; + errno_t ret; + + req = tevent_req_create(mem_ctx, &state, struct ifp_users_find_by_name_and_cert_state); + if (req == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "Unable to create tevent request!\n"); + return NULL; + } + + state->ifp_ctx = ctx; + + if (!SBUS_REQ_STRING_IS_EMPTY(name)) { + state->name = talloc_strdup(state, name); + if (state->name == NULL) { + ret = ENOMEM; + goto done; + } + } + + if (!SBUS_REQ_STRING_IS_EMPTY(pem_cert)) { + state->pem_cert = talloc_strdup(state, pem_cert); + if (state->pem_cert == NULL) { + ret = ENOMEM; + goto done; + } + + ret = sss_cert_pem_to_derb64(state, pem_cert, &state->derb64); + if (ret != EOK) { + DEBUG(SSSDBG_OP_FAILURE, "sss_cert_pem_to_derb64 failed.\n"); + goto done; + } + + /* FIXME: if unlimted searches with limit=0 will work please replace + * 100 with 0. */ + state->list_ctx = ifp_list_ctx_new(state, ctx, NULL, state->derb64, 100); + if (state->list_ctx == NULL) { + ret = ENOMEM; + goto done; + } + } + + if (state->name == NULL && state->pem_cert == NULL) { + DEBUG(SSSDBG_OP_FAILURE, "Empty arguments!\n"); + ret = EINVAL; + goto done; + } + + if (state->name != NULL) { + subreq = cache_req_user_by_name_send(state, ctx->rctx->ev, ctx->rctx, + ctx->rctx->ncache, 0, + CACHE_REQ_ANY_DOM, + NULL, state->name); + if (subreq == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "Unable to create subrequest!\n"); + ret = ENOMEM; + goto done; + } + + tevent_req_set_callback(subreq, ifp_users_find_by_name_and_cert_name_done, req); + } else { + ret = ifp_users_find_by_name_and_cert_step(req); + goto done; + } + + ret = EAGAIN; + +done: + if (ret == EOK) { + tevent_req_done(req); + tevent_req_post(req, ev); + } else if (ret != EAGAIN) { + tevent_req_error(req, ret); + tevent_req_post(req, ev); + } + + return req; +} + +static void ifp_users_find_by_name_and_cert_name_done(struct tevent_req *subreq) +{ + struct ifp_users_find_by_name_and_cert_state *state; + struct cache_req_result *result; + struct tevent_req *req; + errno_t ret; + + req = tevent_req_callback_data(subreq, struct tevent_req); + state = tevent_req_data(req, struct ifp_users_find_by_name_and_cert_state); + + ret = cache_req_user_by_name_recv(state, subreq, &result); + talloc_zfree(subreq); + if (ret != EOK) { + tevent_req_error(req, ret); + return; + } + + state->user_opath = ifp_users_build_path_from_msg(state, + result->domain, + result->msgs[0]); + if (state->user_opath == NULL) { + tevent_req_error(req, ENOMEM); + return; + } + + ret = ifp_users_find_by_name_and_cert_step(req); + if (ret == EOK) { + tevent_req_done(req); + } else if (ret != EAGAIN) { + tevent_req_error(req, ret); + } + + return; +} + +static errno_t +ifp_users_find_by_name_and_cert_step(struct tevent_req *req) +{ + struct ifp_users_find_by_name_and_cert_state *state; + struct tevent_req *subreq; + + state = tevent_req_data(req, struct ifp_users_find_by_name_and_cert_state); + + if (state->list_ctx == NULL) { + if (state->name == NULL) { + return EINVAL; + } + + /* Nothing to search for. */ + return EOK; + } + + /* No more domains to try. */ + if (state->list_ctx->dom == NULL) { + return EOK; + } + + subreq = cache_req_user_by_cert_send(state->list_ctx, + state->ifp_ctx->rctx->ev, + state->ifp_ctx->rctx, + state->ifp_ctx->rctx->ncache, + 0, + CACHE_REQ_ANY_DOM, + state->list_ctx->dom->name, + state->list_ctx->filter); + if (subreq == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "Unable to create subrequest!\n"); + return ENOMEM; + } + + tevent_req_set_callback(subreq, ifp_users_find_by_name_and_cert_done, req); + + state->list_ctx->dom = get_next_domain(state->list_ctx->dom, + SSS_GND_DESCEND); + + return EAGAIN; +} + +static void ifp_users_find_by_name_and_cert_done(struct tevent_req *subreq) +{ + struct ifp_users_find_by_name_and_cert_state *state; + struct cache_req_result *result; + struct tevent_req *req; + errno_t ret; + + req = tevent_req_callback_data(subreq, struct tevent_req); + state = tevent_req_data(req, struct ifp_users_find_by_name_and_cert_state); + + ret = cache_req_user_by_cert_recv(state, subreq, &result); + talloc_zfree(subreq); + if (ret == EOK) { + ret = ifp_users_list_copy(state->list_ctx, result->domain, + result->ldb_result); + if (ret != EOK) { + DEBUG(SSSDBG_CRIT_FAILURE, "Failed to copy domain result\n"); + tevent_req_error(req, ret); + return; + } + } else if (ret != ENOENT) { + DEBUG(SSSDBG_MINOR_FAILURE, "Unable to list groups [%d]: %s\n", + ret, sss_strerror(ret)); + tevent_req_error(req, ret); + return; + } + + ret = ifp_users_find_by_name_and_cert_step(req); + if (ret == EOK) { + tevent_req_done(req); + } else if (ret != EAGAIN) { + tevent_req_error(req, ret); + } + + return; +} + +errno_t +ifp_users_find_by_name_and_cert_recv(TALLOC_CTX *mem_ctx, + struct tevent_req *req, + const char **_path) +{ + struct ifp_users_find_by_name_and_cert_state *state; + size_t c; + + state = tevent_req_data(req, struct ifp_users_find_by_name_and_cert_state); + + TEVENT_REQ_RETURN_ON_ERROR(req); + + /* If no name was given check if there is only one user mapped to the + * certificate and return its object path. Either no or more than one + * mapped users are errors in this case. + * The case where a given name could not be found is already handled in + * ifp_users_find_by_name_and_cert_name_done(). */ + if (state->user_opath == NULL) { + if (state->list_ctx == NULL || state->list_ctx->path_count == 0) { + return ENOENT; + } else if (state->list_ctx->path_count == 1) { + *_path = talloc_steal(mem_ctx, state->list_ctx->paths[0]); + return EOK; + } else { + return EEXIST; + } + } + + /* If there was no certificate given just return the object path of the + * user found by name. If a certificate was given an no mapped user was + * found return an error. */ + if (state->pem_cert == NULL) { + *_path = talloc_steal(mem_ctx, state->user_opath); + return EOK; + } else { + for (c = 0; c < state->list_ctx->path_count; c++) { + if (strcmp(state->user_opath, state->list_ctx->paths[c]) == 0) { + *_path = talloc_steal(mem_ctx, state->user_opath); + return EOK; + } + } + } + + return ENOENT; +} + +struct ifp_users_list_by_attr_state { + struct ifp_ctx *ifp_ctx; + struct ifp_list_ctx *list_ctx; +}; + +static errno_t ifp_users_list_by_attr_step(struct tevent_req *req); +static void ifp_users_list_by_attr_done(struct tevent_req *subreq); + +struct tevent_req * +ifp_users_list_by_attr_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct sbus_request *sbus_req, + struct ifp_ctx *ctx, + const char *attr, + const char *filter, + uint32_t limit) +{ + struct ifp_users_list_by_attr_state *state; + struct tevent_req *req; + errno_t ret; + + req = tevent_req_create(mem_ctx, &state, struct ifp_users_list_by_attr_state); + if (req == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "Unable to create tevent request!\n"); + return NULL; + } + + state->ifp_ctx = ctx; + state->list_ctx = ifp_list_ctx_new(state, ctx, attr, filter, limit); + if (state->list_ctx == NULL) { + ret = ENOMEM; + goto done; + } + + ret = ifp_users_list_by_attr_step(req); + +done: + if (ret == EOK) { + tevent_req_done(req); + tevent_req_post(req, ev); + } else if (ret != EAGAIN) { + tevent_req_error(req, ret); + tevent_req_post(req, ev); + } + + return req; +} + +static errno_t +ifp_users_list_by_attr_step(struct tevent_req *req) +{ + struct ifp_users_list_by_attr_state *state; + struct tevent_req *subreq; + + state = tevent_req_data(req, struct ifp_users_list_by_attr_state); + + if (state->list_ctx->dom == NULL) { + return EOK; + } + + subreq = cache_req_user_by_filter_send(state->list_ctx, + state->ifp_ctx->rctx->ev, + state->ifp_ctx->rctx, + CACHE_REQ_ANY_DOM, + state->list_ctx->dom->name, + state->list_ctx->attr, + state->list_ctx->filter); + if (subreq == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "Unable to create subrequest!\n"); + return ENOMEM; + } + + tevent_req_set_callback(subreq, ifp_users_list_by_attr_done, req); + + state->list_ctx->dom = get_next_domain(state->list_ctx->dom, + SSS_GND_DESCEND); + + return EAGAIN; +} + +static void ifp_users_list_by_attr_done(struct tevent_req *subreq) +{ + struct ifp_users_list_by_attr_state *state; + struct cache_req_result *result; + struct tevent_req *req; + errno_t ret; + + req = tevent_req_callback_data(subreq, struct tevent_req); + state = tevent_req_data(req, struct ifp_users_list_by_attr_state); + + ret = cache_req_user_by_name_recv(state, subreq, &result); + talloc_zfree(subreq); + if (ret == EOK) { + ret = ifp_users_list_copy(state->list_ctx, result->domain, + result->ldb_result); + if (ret != EOK) { + DEBUG(SSSDBG_CRIT_FAILURE, "Failed to copy domain result\n"); + tevent_req_error(req, ret); + return; + } + } else if (ret != ENOENT) { + DEBUG(SSSDBG_MINOR_FAILURE, "Unable to list users [%d]: %s\n", + ret, sss_strerror(ret)); + tevent_req_error(req, ret); + return; + } + + ret = ifp_users_list_by_attr_step(req); + if (ret == EOK) { + tevent_req_done(req); + } else if (ret != EAGAIN) { + tevent_req_error(req, ret); + } +} + +errno_t +ifp_users_list_by_attr_recv(TALLOC_CTX *mem_ctx, + struct tevent_req *req, + const char ***_paths) +{ + struct ifp_users_list_by_attr_state *state; + state = tevent_req_data(req, struct ifp_users_list_by_attr_state); + + TEVENT_REQ_RETURN_ON_ERROR(req); + + *_paths = talloc_steal(mem_ctx, state->list_ctx->paths); + + return EOK; +} + +struct ifp_users_list_by_domain_and_name_state { + struct ifp_list_ctx *list_ctx; +}; + +static void ifp_users_list_by_domain_and_name_done(struct tevent_req *subreq); + +struct tevent_req * +ifp_users_list_by_domain_and_name_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct sbus_request *sbus_req, + struct ifp_ctx *ctx, + const char *domain, + const char *filter, + uint32_t limit) +{ + struct ifp_users_list_by_domain_and_name_state *state; + struct tevent_req *subreq; + struct tevent_req *req; + errno_t ret; + + req = tevent_req_create(mem_ctx, &state, struct ifp_users_list_by_domain_and_name_state); + if (req == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "Unable to create tevent request!\n"); + return NULL; + } + + state->list_ctx = ifp_list_ctx_new(state, ctx, NULL, filter, limit); + if (state->list_ctx == NULL) { + ret = ENOMEM; + goto done; + } + + subreq = cache_req_user_by_filter_send(state->list_ctx, ctx->rctx->ev, + ctx->rctx, CACHE_REQ_ANY_DOM, + domain, NULL, filter); + if (subreq == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "Unable to create subrequest!\n"); + ret = ENOMEM; + goto done; + } + + tevent_req_set_callback(subreq, ifp_users_list_by_domain_and_name_done, req); + + ret = EAGAIN; + +done: + if (ret != EAGAIN) { + tevent_req_error(req, ret); + tevent_req_post(req, ev); + } + + return req; +} + +static void ifp_users_list_by_domain_and_name_done(struct tevent_req *subreq) +{ + struct ifp_users_list_by_domain_and_name_state *state; + struct cache_req_result *result; + struct tevent_req *req; + errno_t ret; + + req = tevent_req_callback_data(subreq, struct tevent_req); + state = tevent_req_data(req, struct ifp_users_list_by_domain_and_name_state); + + ret = cache_req_user_by_name_recv(state, subreq, &result); + talloc_zfree(subreq); + if (ret != EOK) { + tevent_req_error(req, ret); + return; + } + + ret = ifp_users_list_copy(state->list_ctx, result->domain, + result->ldb_result); + if (ret != EOK) { + DEBUG(SSSDBG_CRIT_FAILURE, "Failed to copy domain result\n"); + tevent_req_error(req, ret); + return; + } + + tevent_req_done(req); + return; +} + +errno_t +ifp_users_list_by_domain_and_name_recv(TALLOC_CTX *mem_ctx, + struct tevent_req *req, + const char ***_paths) +{ + struct ifp_users_list_by_domain_and_name_state *state; + state = tevent_req_data(req, struct ifp_users_list_by_domain_and_name_state); + + TEVENT_REQ_RETURN_ON_ERROR(req); + + *_paths = talloc_steal(mem_ctx, state->list_ctx->paths); + + return EOK; +} + +struct ifp_users_find_by_valid_cert_state { + struct ifp_ctx *ifp_ctx; + struct tevent_context *ev; + const char *logfile; + int timeout; + char *ca_db; + char *verify_opts; + char *derb64; + const char **extra_args; + const char *path; + + struct sss_child_ctx_old *child_ctx; + struct child_io_fds *io; +}; + +static errno_t p11_child_exec(struct tevent_req *req); +static void +ifp_users_find_by_valid_cert_step(int child_status, + struct tevent_signal *sige, + void *pvt); +static void ifp_users_find_by_valid_cert_done(struct tevent_req *subreq); + +struct tevent_req * +ifp_users_find_by_valid_cert_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct sbus_request *sbus_req, + struct ifp_ctx *ctx, + const char *pem_cert) +{ + struct tevent_req *req; + struct ifp_users_find_by_valid_cert_state *state; + size_t arg_c = 0; + int ret; + + req = tevent_req_create(mem_ctx, &state, struct ifp_users_find_by_valid_cert_state); + if (req == NULL) { + return NULL; + } + + state->ifp_ctx = ctx; + + ret = confdb_get_string(ctx->rctx->cdb, state, + CONFDB_IFP_CONF_ENTRY, CONFDB_SSH_CA_DB, + CONFDB_DEFAULT_SSH_CA_DB, &state->ca_db); + if (ret != EOK) { + DEBUG(SSSDBG_FATAL_FAILURE, "Error reading CA DB from confdb (%d) [%s]\n", + ret, strerror(ret)); + goto done; + } + + ret = confdb_get_int(ctx->rctx->cdb, CONFDB_IFP_CONF_ENTRY, + CONFDB_PAM_P11_CHILD_TIMEOUT, -1, + &state->timeout); + if (ret != EOK || state->timeout == -1) { + /* check pam configuration as well or use default */ + ret = confdb_get_int(ctx->rctx->cdb, CONFDB_PAM_CONF_ENTRY, + CONFDB_PAM_P11_CHILD_TIMEOUT, + P11_CHILD_TIMEOUT_DEFAULT, + &state->timeout); + if (ret != EOK) { + DEBUG(SSSDBG_CRIT_FAILURE, + "Failed to read p11_child_timeout from confdb: [%d]: %s\n", + ret, sss_strerror(ret)); + goto done; + } + } + + ret = confdb_get_string(ctx->rctx->cdb, state, CONFDB_MONITOR_CONF_ENTRY, + CONFDB_MONITOR_CERT_VERIFICATION, NULL, + &state->verify_opts); + if (ret != EOK) { + DEBUG(SSSDBG_CRIT_FAILURE, + "Failed to read '"CONFDB_MONITOR_CERT_VERIFICATION"' from confdb: [%d]: %s\n", + ret, sss_strerror(ret)); + goto done; + } + + state->ev = ev; + state->logfile = P11_CHILD_LOG_FILE; + state->io = talloc(state, struct child_io_fds); + if (state->io == NULL) { + DEBUG(SSSDBG_OP_FAILURE, "talloc failed.\n"); + ret = ENOMEM; + goto done; + } + state->io->write_to_child_fd = -1; + state->io->read_from_child_fd = -1; + talloc_set_destructor((void *) state->io, child_io_destructor); + + ret = sss_cert_pem_to_derb64(state, pem_cert, &state->derb64); + if (ret != EOK) { + DEBUG(SSSDBG_OP_FAILURE, "sss_cert_pem_to_derb64 failed.\n"); + goto done; + } + + state->extra_args = talloc_zero_array(state, const char *, 8); + if (state->extra_args == NULL) { + DEBUG(SSSDBG_OP_FAILURE, "talloc_zero_array failed.\n"); + ret = ENOMEM; + goto done; + } + state->extra_args[arg_c++] = state->derb64; + state->extra_args[arg_c++] = "--certificate"; + state->extra_args[arg_c++] = state->ca_db; + state->extra_args[arg_c++] = "--ca_db"; + if (state->verify_opts != NULL) { + state->extra_args[arg_c++] = state->verify_opts; + state->extra_args[arg_c++] = "--verify"; + } + state->extra_args[arg_c++] = "--verification"; + + ret = p11_child_exec(req); + +done: + if (ret == EOK) { + tevent_req_done(req); + tevent_req_post(req, ev); + } else if (ret != EAGAIN) { + tevent_req_error(req, ret); + tevent_req_post(req, ev); + } + + return req; +} + +static errno_t p11_child_exec(struct tevent_req *req) +{ + struct ifp_users_find_by_valid_cert_state *state; + int pipefd_from_child[2] = PIPE_INIT; + int pipefd_to_child[2] = PIPE_INIT; + pid_t child_pid; + struct timeval tv; + bool endtime; + int ret; + + state = tevent_req_data(req, struct ifp_users_find_by_valid_cert_state); + + ret = pipe(pipefd_from_child); + if (ret == -1) { + ret = errno; + DEBUG(SSSDBG_CRIT_FAILURE, + "pipe failed [%d][%s].\n", ret, strerror(ret)); + goto done; + } + ret = pipe(pipefd_to_child); + if (ret == -1) { + ret = errno; + DEBUG(SSSDBG_CRIT_FAILURE, + "pipe failed [%d][%s].\n", ret, strerror(ret)); + goto done; + } + + child_pid = fork(); + if (child_pid == 0) { /* child */ + exec_child_ex(state, pipefd_to_child, pipefd_from_child, + P11_CHILD_PATH, state->logfile, state->extra_args, + false, STDIN_FILENO, STDOUT_FILENO); + /* We should never get here */ + ret = errno; + DEBUG(SSSDBG_CRIT_FAILURE, "BUG: Could not exec p11 child\n"); + return ret; + } else if (child_pid > 0) { /* parent */ + state->io->read_from_child_fd = pipefd_from_child[0]; + PIPE_FD_CLOSE(pipefd_from_child[1]); + sss_fd_nonblocking(state->io->read_from_child_fd); + + state->io->write_to_child_fd = pipefd_to_child[1]; + PIPE_FD_CLOSE(pipefd_to_child[0]); + sss_fd_nonblocking(state->io->write_to_child_fd); + + /* Set up SIGCHLD handler */ + ret = child_handler_setup(state->ev, child_pid, + ifp_users_find_by_valid_cert_step, + req, &state->child_ctx); + if (ret != EOK) { + DEBUG(SSSDBG_OP_FAILURE, "Could not set up child handlers [%d]: %s\n", + ret, sss_strerror(ret)); + ret = ERR_P11_CHILD; + goto done; + } + + /* Set up timeout handler */ + tv = tevent_timeval_current_ofs(state->timeout, 0); + endtime = tevent_req_set_endtime(req, state->ev, tv); + if (endtime == false) { + ret = ERR_P11_CHILD; + goto done; + } + /* Now either wait for the timeout to fire or the child to finish */ + } else { /* error */ + ret = errno; + DEBUG(SSSDBG_CRIT_FAILURE, "fork failed [%d][%s].\n", + ret, sss_strerror(ret)); + goto done; + } + + return EAGAIN; + +done: + if (ret != EOK) { + PIPE_CLOSE(pipefd_from_child); + PIPE_CLOSE(pipefd_to_child); + } + + return ret; +} + +static void +ifp_users_find_by_valid_cert_step(int child_status, + struct tevent_signal *sige, + void *pvt) +{ + struct tevent_req *subreq; + struct tevent_req *req = talloc_get_type(pvt, struct tevent_req); + struct ifp_users_find_by_valid_cert_state *state; + errno_t ret; + + state = tevent_req_data(req, struct ifp_users_find_by_valid_cert_state); + + PIPE_FD_CLOSE(state->io->read_from_child_fd); + PIPE_FD_CLOSE(state->io->write_to_child_fd); + + if (WIFEXITED(child_status)) { + if (WEXITSTATUS(child_status) == CA_DB_NOT_FOUND_EXIT_CODE) { + DEBUG(SSSDBG_OP_FAILURE, + P11_CHILD_PATH " failed [%d]: [%s].\n", + ERR_CA_DB_NOT_FOUND, sss_strerror(ERR_CA_DB_NOT_FOUND)); + tevent_req_error(req, ERR_CA_DB_NOT_FOUND); + return; + } else if (WEXITSTATUS(child_status) != 0) { + DEBUG(SSSDBG_OP_FAILURE, + P11_CHILD_PATH " failed with status [%d]. Check p11_child" + " logs for more information.\n", + WEXITSTATUS(child_status)); + tevent_req_error(req, ERR_INVALID_CERT); + return; + } + } else if (WIFSIGNALED(child_status)) { + DEBUG(SSSDBG_OP_FAILURE, + P11_CHILD_PATH " was terminated by signal [%d]. Check p11_child" + " logs for more information.\n", + WTERMSIG(child_status)); + tevent_req_error(req, ECHILD); + return; + } + + DEBUG(SSSDBG_TRACE_LIBS, "Certificate [%s] is valid.\n", + state->extra_args[0]); + + subreq = cache_req_user_by_cert_send(state, state->ifp_ctx->rctx->ev, + state->ifp_ctx->rctx, + state->ifp_ctx->rctx->ncache, 0, + CACHE_REQ_ANY_DOM, NULL, + state->derb64); + if (subreq == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "Unable to create subrequest!\n"); + ret = ENOMEM; + goto done; + } + + tevent_req_set_callback(subreq, ifp_users_find_by_valid_cert_done, req); + + ret = EAGAIN; + +done: + if (ret != EAGAIN) { + tevent_req_error(req, ret); + tevent_req_post(req, state->ifp_ctx->rctx->ev); + } + + return; +} + +static void ifp_users_find_by_valid_cert_done(struct tevent_req *subreq) +{ + struct ifp_users_find_by_valid_cert_state *state; + struct cache_req_result *result; + struct tevent_req *req; + errno_t ret; + + req = tevent_req_callback_data(subreq, struct tevent_req); + state = tevent_req_data(req, struct ifp_users_find_by_valid_cert_state); + + ret = cache_req_user_by_cert_recv(state, subreq, &result); + talloc_zfree(subreq); + if (ret != EOK) { + DEBUG(SSSDBG_MINOR_FAILURE, "Unable to find user [%d]: %s\n", + ret, sss_strerror(ret)); + tevent_req_error(req, ret); + return; + } + + if (result->count > 1) { + DEBUG(SSSDBG_CRIT_FAILURE, "More than one user found. " + "Use ListByCertificate to get all.\n"); + tevent_req_error(req, EINVAL); + return; + } + + state->path = ifp_users_build_path_from_msg(state, result->domain, + result->msgs[0]); + if (state->path == NULL) { + tevent_req_error(req, ENOMEM); + return; + } + + tevent_req_done(req); + return; +} + +errno_t +ifp_users_find_by_valid_cert_recv(TALLOC_CTX *mem_ctx, + struct tevent_req *req, + const char **_path) +{ + struct ifp_users_find_by_valid_cert_state *state; + + state = tevent_req_data(req, struct ifp_users_find_by_valid_cert_state); + + TEVENT_REQ_RETURN_ON_ERROR(req); + + *_path = talloc_steal(mem_ctx, state->path); + + return EOK; +} + +static errno_t +ifp_users_get_from_cache(TALLOC_CTX *mem_ctx, + struct sss_domain_info *domain, + const char *key, + struct ldb_message **_user) +{ + struct ldb_result *user_res = NULL; + errno_t ret; + uid_t uid; + char *endptr; + + switch (domain->type) { + case DOM_TYPE_POSIX: + uid = strtouint32(key, &endptr, 10); + if ((errno != 0) || *endptr || (key == endptr)) { + ret = errno ? errno : EINVAL; + DEBUG(SSSDBG_CRIT_FAILURE, "Invalid UID value\n"); + goto done; + } + + ret = sysdb_getpwuid_with_views(mem_ctx, domain, uid, &user_res); + if (ret == EOK && user_res->count == 0) { + *_user = NULL; + ret = ENOENT; + goto done; + } else if (ret != EOK) { + DEBUG(SSSDBG_CRIT_FAILURE, "Unable to lookup user %u@%s [%d]: %s\n", + uid, domain->name, ret, sss_strerror(ret)); + goto done; + } + break; + case DOM_TYPE_APPLICATION: + ret = sysdb_getpwnam_with_views(mem_ctx, domain, key, &user_res); + if (ret == EOK && user_res->count == 0) { + *_user = NULL; + ret = ENOENT; + goto done; + } else if (ret != EOK) { + DEBUG(SSSDBG_CRIT_FAILURE, "Unable to lookup user %s@%s [%d]: %s\n", + key, domain->name, ret, sss_strerror(ret)); + goto done; + } + break; + } + + if (user_res->count > 1) { + DEBUG(SSSDBG_CRIT_FAILURE, "More users matched by the single key\n"); + ret = EIO; + goto done; + } + + *_user = talloc_steal(mem_ctx, user_res->msgs[0]); + + ret = EOK; + +done: + talloc_free(user_res); + + return ret; +} + +static errno_t +ifp_users_user_get(TALLOC_CTX *mem_ctx, + struct sbus_request *sbus_req, + struct ifp_ctx *ifp_ctx, + struct sss_domain_info **_domain, + struct ldb_message **_user) +{ + struct sss_domain_info *domain; + char *key; + errno_t ret; + + ret = ifp_users_decompose_path(NULL, + ifp_ctx->rctx->domains, sbus_req->path, + &domain, &key); + if (ret != EOK) { + DEBUG(SSSDBG_CRIT_FAILURE, "Unable to decompose object path" + "[%s] [%d]: %s\n", sbus_req->path, ret, sss_strerror(ret)); + return ret; + } + + if (_user != NULL) { + ret = ifp_users_get_from_cache(mem_ctx, domain, key, _user); + } + + talloc_free(key); + + if (ret == EOK || ret == ENOENT) { + if (_domain != NULL) { + *_domain = domain; + } + } else if (ret != EOK) { + DEBUG(SSSDBG_OP_FAILURE, "Unable to retrieve user from cache\n"); + } + + return ret; +} + +static errno_t +ifp_users_get_as_string(TALLOC_CTX *mem_ctx, + struct sbus_request *sbus_req, + struct ifp_ctx *ifp_ctx, + const char *attr, + const char **_out, + struct sss_domain_info **_domain) +{ + struct ldb_message *msg; + struct sss_domain_info *domain; + const char *out; + errno_t ret; + + ret = ifp_users_user_get(NULL, sbus_req, ifp_ctx, &domain, &msg); + if (ret != EOK) { + return ret; + } + + out = sss_view_ldb_msg_find_attr_as_string(domain, msg, attr, NULL); + if (out == NULL) { + talloc_free(msg); + return ENOENT; + } + + *_out = talloc_steal(mem_ctx, out); + talloc_free(msg); + + if (_domain != NULL) { + *_domain = domain; + } + + return EOK; +} + +static errno_t +ifp_users_get_name(TALLOC_CTX *mem_ctx, + struct sbus_request *sbus_req, + struct ifp_ctx *ifp_ctx, + const char *attr, + const char **_out) +{ + struct sss_domain_info *domain; + const char *in_name; + const char *out; + errno_t ret; + + ret = ifp_users_get_as_string(NULL, sbus_req, ifp_ctx, attr, + &in_name, &domain); + if (ret != EOK) { + return ret; + } + + out = ifp_format_name_attr(mem_ctx, ifp_ctx, in_name, domain); + talloc_free(discard_const(in_name)); + if (out == NULL) { + return ENOMEM; + } + + *_out = out; + + return EOK; +} + +static errno_t +ifp_users_get_as_uint32(struct sbus_request *sbus_req, + struct ifp_ctx *ifp_ctx, + const char *attr, + uint32_t *_out) +{ + struct ldb_message *msg; + struct sss_domain_info *domain; + errno_t ret; + + ret = ifp_users_user_get(NULL, sbus_req, ifp_ctx, &domain, &msg); + if (ret != EOK) { + return ret; + } + + *_out = sss_view_ldb_msg_find_attr_as_uint64(domain, msg, attr, 0); + talloc_free(msg); + + return EOK; +} + +struct ifp_users_user_update_groups_list_state { + int dummy; +}; + +static void ifp_users_user_update_groups_list_done(struct tevent_req *subreq); + +struct tevent_req * +ifp_users_user_update_groups_list_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct sbus_request *sbus_req, + struct ifp_ctx *ctx) +{ + struct ifp_users_user_update_groups_list_state *state; + struct tevent_req *subreq; + struct tevent_req *req; + struct sss_domain_info *domain; + struct ldb_message *user; + const char *username; + errno_t ret; + + req = tevent_req_create(mem_ctx, &state, struct ifp_users_user_update_groups_list_state); + if (req == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "Unable to create tevent request!\n"); + return NULL; + } + + ret = ifp_users_user_get(state, sbus_req, ctx, &domain, &user); + if (ret != EOK) { + goto done; + } + + username = ldb_msg_find_attr_as_string(user, SYSDB_NAME, NULL); + if (username == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "User name is empty!\n"); + ret = ERR_INTERNAL; + goto done; + } + + subreq = cache_req_initgr_by_name_send(state, ctx->rctx->ev, ctx->rctx, + ctx->rctx->ncache, 0, + CACHE_REQ_ANY_DOM, domain->name, + username); + if (subreq == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "Unable to create subrequest!\n"); + ret = ENOMEM; + goto done; + } + + tevent_req_set_callback(subreq, ifp_users_user_update_groups_list_done, req); + + ret = EAGAIN; + +done: + if (ret != EAGAIN) { + tevent_req_error(req, ret); + tevent_req_post(req, ev); + } + + return req; +} + +static void ifp_users_user_update_groups_list_done(struct tevent_req *subreq) +{ + struct ifp_users_user_update_groups_list_state *state; + struct tevent_req *req; + errno_t ret; + + req = tevent_req_callback_data(subreq, struct tevent_req); + state = tevent_req_data(req, struct ifp_users_user_update_groups_list_state); + + ret = cache_req_initgr_by_name_recv(state, subreq, NULL); + talloc_zfree(subreq); + if (ret != EOK) { + tevent_req_error(req, ret); + return; + } + + tevent_req_done(req); + return; +} + +errno_t +ifp_users_user_update_groups_list_recv(struct tevent_req *req) +{ + TEVENT_REQ_RETURN_ON_ERROR(req); + + return EOK; +} + +errno_t +ifp_users_user_get_name(TALLOC_CTX *mem_ctx, + struct sbus_request *sbus_req, + struct ifp_ctx *ctx, + const char **_out) +{ + return ifp_users_get_name(mem_ctx, sbus_req, ctx, SYSDB_NAME, _out); +} + +errno_t +ifp_users_user_get_uid_number(TALLOC_CTX *mem_ctx, + struct sbus_request *sbus_req, + struct ifp_ctx *ctx, + uint32_t *_out) +{ + return ifp_users_get_as_uint32(sbus_req, ctx, SYSDB_UIDNUM, _out); +} + +errno_t +ifp_users_user_get_gid_number(TALLOC_CTX *mem_ctx, + struct sbus_request *sbus_req, + struct ifp_ctx *ctx, + uint32_t *_out) +{ + return ifp_users_get_as_uint32(sbus_req, ctx, SYSDB_GIDNUM, _out); +} + +errno_t +ifp_users_user_get_gecos(TALLOC_CTX *mem_ctx, + struct sbus_request *sbus_req, + struct ifp_ctx *ctx, + const char **_out) +{ + return ifp_users_get_as_string(mem_ctx, sbus_req, ctx, SYSDB_GECOS, _out, NULL); +} + +errno_t +ifp_users_user_get_home_directory(TALLOC_CTX *mem_ctx, + struct sbus_request *sbus_req, + struct ifp_ctx *ctx, + const char **_out) +{ + return ifp_users_get_as_string(mem_ctx, sbus_req, ctx, SYSDB_HOMEDIR, _out, NULL); +} + +errno_t +ifp_users_user_get_login_shell(TALLOC_CTX *mem_ctx, + struct sbus_request *sbus_req, + struct ifp_ctx *ctx, + const char **_out) +{ + return ifp_users_get_as_string(mem_ctx, sbus_req, ctx, SYSDB_SHELL, _out, NULL); +} + +errno_t +ifp_users_user_get_unique_id(TALLOC_CTX *mem_ctx, + struct sbus_request *sbus_req, + struct ifp_ctx *ctx, + const char **_out) +{ + return ifp_users_get_as_string(mem_ctx, sbus_req, ctx, SYSDB_UUID, _out, NULL); +} + +errno_t +ifp_users_user_get_groups(TALLOC_CTX *mem_ctx, + struct sbus_request *sbus_req, + struct ifp_ctx *ifp_ctx, + const char ***_out) +{ + TALLOC_CTX *tmp_ctx; + struct sss_domain_info *domain; + const char *username; + struct ldb_message *user; + struct ldb_result *res; + const char **out; + int num_groups; + gid_t gid; + errno_t ret; + int i; + + tmp_ctx = talloc_new(NULL); + if (tmp_ctx == NULL) { + DEBUG(SSSDBG_FATAL_FAILURE, "Out of memory!\n"); + return ENOMEM; + } + + ret = ifp_users_user_get(tmp_ctx, sbus_req, ifp_ctx, &domain, &user); + if (ret != EOK) { + return ret; + } + + username = ldb_msg_find_attr_as_string(user, SYSDB_NAME, NULL); + if (username == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "User name is empty!\n"); + return ERR_INTERNAL; + } + + /* Run initgroups. */ + ret = sysdb_initgroups_with_views(tmp_ctx, domain, username, &res); + if (ret != EOK) { + DEBUG(SSSDBG_CRIT_FAILURE, "Unable to get groups for %s@%s [%d]: %s\n", + username, domain->name, ret, sss_strerror(ret)); + goto done; + } + + if (res->count == 0) { + *_out = NULL; + ret = EOK; + goto done; + } + + out = talloc_zero_array(tmp_ctx, const char *, res->count + 1); + if (out == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "talloc_zero_array() failed\n"); + ret = ENOMEM; + goto done; + } + + num_groups = 0; + for (i = 0; i < res->count; i++) { + gid = sss_view_ldb_msg_find_attr_as_uint64(domain, res->msgs[i], + SYSDB_GIDNUM, 0); + if (gid == 0 && domain->type == DOM_TYPE_POSIX) { + continue; + } + + out[num_groups] = ifp_groups_build_path_from_msg(out, + domain, + res->msgs[i]); + if (out[num_groups] == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "ifp_groups_build_path() failed\n"); + ret = ENOMEM; + goto done; + } + + num_groups++; + } + + *_out = talloc_steal(mem_ctx, out); + + ret = EOK; + +done: + talloc_free(tmp_ctx); + return ret; +} + +errno_t +ifp_users_user_get_domainname(TALLOC_CTX *mem_ctx, + struct sbus_request *sbus_req, + struct ifp_ctx *ifp_ctx, + const char **_out) +{ + struct sss_domain_info *domain; + errno_t ret; + + ret = ifp_users_user_get(mem_ctx, sbus_req, ifp_ctx, &domain, NULL); + if (ret != EOK) { + return ret; + } + + *_out = domain->name; + + return EOK; +} + +errno_t +ifp_users_user_get_domain(TALLOC_CTX *mem_ctx, + struct sbus_request *sbus_req, + struct ifp_ctx *ctx, + const char **_out) +{ + const char *name; + const char *out; + errno_t ret; + + ret = ifp_users_user_get_domainname(NULL, sbus_req, ctx, &name); + if (ret != EOK) { + return ret; + } + + out = sbus_opath_compose(mem_ctx, IFP_PATH_DOMAINS, name); + if (out == NULL) { + return ENOMEM; + } + + *_out = out; + + return EOK; +} + +errno_t +ifp_users_user_get_extra_attributes(TALLOC_CTX *mem_ctx, + struct sbus_request *sbus_req, + struct ifp_ctx *ifp_ctx, + hash_table_t **_out) +{ + TALLOC_CTX *tmp_ctx; + struct sss_domain_info *domain; + struct ldb_message *base_user; + const char *name; + struct ldb_message **user; + struct ldb_message_element *el; + struct ldb_dn *basedn; + size_t count; + const char *filter; + const char **extra; + hash_table_t *table; + hash_key_t key; + hash_value_t value; + const char **values; + errno_t ret; + int hret; + int i; + + tmp_ctx = talloc_new(NULL); + if (tmp_ctx == NULL) { + DEBUG(SSSDBG_FATAL_FAILURE, "Out of memory!\n"); + return ENOMEM; + } + + extra = ifp_get_user_extra_attributes(tmp_ctx, ifp_ctx); + if (extra == NULL || extra[0] == NULL) { + DEBUG(SSSDBG_TRACE_ALL, "No extra attributes to return\n"); + *_out = NULL; + ret = EOK; + goto done; + } + + ret = ifp_users_user_get(tmp_ctx, sbus_req, ifp_ctx, &domain, &base_user); + if (ret != EOK) { + goto done; + } + + basedn = sysdb_user_base_dn(tmp_ctx, domain); + if (basedn == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "sysdb_user_base_dn() failed\n"); + ret = ENOMEM; + goto done; + } + + name = ldb_msg_find_attr_as_string(base_user, SYSDB_NAME, NULL); + if (name == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "A user with no name\n"); + ret = ERR_INTERNAL; + goto done; + } + + filter = talloc_asprintf(tmp_ctx, "(&(%s=%s)(%s=%s))", + SYSDB_OBJECTCATEGORY, SYSDB_USER_CLASS, + SYSDB_NAME, name); + if (filter == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "talloc_asprintf() failed\n"); + ret = ENOMEM; + goto done; + } + + ret = sysdb_search_entry(tmp_ctx, domain->sysdb, basedn, + LDB_SCOPE_SUBTREE, filter, + extra, &count, &user); + if (ret != EOK) { + DEBUG(SSSDBG_CRIT_FAILURE, "Unable to lookup user [%d]: %s\n", + ret, sss_strerror(ret)); + goto done; + } + + if (count == 0) { + DEBUG(SSSDBG_TRACE_FUNC, "User %s not found!\n", name); + ret = ENOENT; + goto done; + } else if (count > 1) { + DEBUG(SSSDBG_CRIT_FAILURE, "More than one entry found!\n"); + ret = ERR_INTERNAL; + goto done; + } + + ret = sss_hash_create(tmp_ctx, 0, &table); + if (ret != EOK) { + DEBUG(SSSDBG_CRIT_FAILURE, "Unable to create hash table!\n"); + goto done; + } + + /* Read each extra attribute. */ + for (i = 0; extra[i] != NULL; i++) { + el = ldb_msg_find_element(user[0], extra[i]); + if (el == NULL) { + DEBUG(SSSDBG_TRACE_ALL, "Attribute %s not found, skipping...\n", + extra[i]); + continue; + } + + values = sss_ldb_el_to_string_list(table, el); + if (values == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "sss_ldb_el_to_string_list() failed\n"); + ret = ENOMEM; + goto done; + } + + key.type = HASH_KEY_STRING; + key.str = talloc_strdup(table, extra[i]); + if (key.str == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "talloc_strdup() failed\n"); + ret = ENOMEM; + goto done; + } + + value.type = HASH_VALUE_PTR; + value.ptr = values; + + hret = hash_enter(table, &key, &value); + if (hret != HASH_SUCCESS) { + DEBUG(SSSDBG_CRIT_FAILURE, "Unable to insert entry " + "into hash table: %d\n", hret); + ret = EIO; + goto done; + } + } + + *_out = talloc_steal(mem_ctx, table); + + ret = EOK; + +done: + talloc_free(tmp_ctx); + + return ret; +} + +errno_t +ifp_cache_list_user(TALLOC_CTX *mem_ctx, + struct sbus_request *sbus_req, + struct ifp_ctx *ctx, + const char ***_out) +{ + return ifp_cache_list(mem_ctx, ctx, IFP_CACHE_USER, _out); +} + +errno_t +ifp_cache_list_by_domain_user(TALLOC_CTX *mem_ctx, + struct sbus_request *sbus_req, + struct ifp_ctx *ctx, + const char *domain, + const char ***_out) +{ + return ifp_cache_list_by_domain(mem_ctx, ctx, domain, IFP_CACHE_USER, _out); +} + +errno_t +ifp_cache_object_store_user(TALLOC_CTX *mem_ctx, + struct sbus_request *sbus_req, + struct ifp_ctx *ctx, + bool *_result) +{ + struct sss_domain_info *domain; + struct ldb_message *user; + errno_t ret; + + ret = ifp_users_user_get(NULL, sbus_req, ctx, &domain, &user); + if (ret != EOK) { + return ret; + } + + ret = ifp_cache_object_store(domain, user->dn); + talloc_free(user); + + if (ret == EOK) { + *_result = true; + } + + return ret; +} + +errno_t +ifp_cache_object_remove_user(TALLOC_CTX *mem_ctx, + struct sbus_request *sbus_req, + struct ifp_ctx *ctx, + bool *_result) +{ + struct sss_domain_info *domain; + struct ldb_message *user; + errno_t ret; + + ret = ifp_users_user_get(NULL, sbus_req, ctx, &domain, &user); + if (ret != EOK) { + return ret; + } + + ret = ifp_cache_object_remove(domain, user->dn); + talloc_free(user); + + if (ret == EOK) { + *_result = true; + } + + return ret; +} + +struct tevent_req * +ifp_users_list_by_name_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct sbus_request *sbus_req, + struct ifp_ctx *ctx, + const char *filter, + uint32_t limit) +{ + return ifp_users_list_by_attr_send(mem_ctx, ev, sbus_req, ctx, NULL, + filter, limit); +} diff --git a/src/responder/ifp/ifp_users.h b/src/responder/ifp/ifp_users.h new file mode 100644 index 0000000..f0f725c --- /dev/null +++ b/src/responder/ifp/ifp_users.h @@ -0,0 +1,254 @@ +/* + Authors: + Pavel Březina <pbrezina@redhat.com> + + Copyright (C) 2015 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_USERS_H_ +#define IFP_USERS_H_ + +#include "responder/ifp/ifp_private.h" + +/* Utility functions */ + +char * ifp_users_build_path_from_msg(TALLOC_CTX *mem_ctx, + struct sss_domain_info *domain, + struct ldb_message *msg); + +/* org.freedesktop.sssd.infopipe.Users */ + +struct tevent_req * +ifp_users_find_by_name_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct sbus_request *sbus_req, + struct ifp_ctx *ctx, + const char *name); + +errno_t +ifp_users_find_by_name_recv(TALLOC_CTX *mem_ctx, + struct tevent_req *req, + const char **_path); + +struct tevent_req * +ifp_users_find_by_id_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct sbus_request *sbus_req, + struct ifp_ctx *ctx, + uint32_t id); + +errno_t +ifp_users_find_by_id_recv(TALLOC_CTX *mem_ctx, + struct tevent_req *req, + const char **_path); + +struct tevent_req * +ifp_users_find_by_cert_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct sbus_request *sbus_req, + struct ifp_ctx *ctx, + const char *pem_cert); + +errno_t +ifp_users_find_by_cert_recv(TALLOC_CTX *mem_ctx, + struct tevent_req *req, + const char **_path); + +struct tevent_req * +ifp_users_list_by_cert_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct sbus_request *sbus_req, + struct ifp_ctx *ctx, + const char *pem_cert, + uint32_t limit); + +errno_t +ifp_users_list_by_cert_recv(TALLOC_CTX *mem_ctx, + struct tevent_req *req, + const char ***_paths); + +struct tevent_req * +ifp_users_find_by_name_and_cert_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct sbus_request *sbus_req, + struct ifp_ctx *ctx, + const char *name, + const char *pem_cert); + +errno_t +ifp_users_find_by_name_and_cert_recv(TALLOC_CTX *mem_ctx, + struct tevent_req *req, + const char **_path); + +struct tevent_req * +ifp_users_list_by_name_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct sbus_request *sbus_req, + struct ifp_ctx *ctx, + const char *filter, + uint32_t limit); + +errno_t +ifp_users_list_by_attr_recv(TALLOC_CTX *mem_ctx, + struct tevent_req *req, + const char ***_paths); + +struct tevent_req * +ifp_users_list_by_domain_and_name_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct sbus_request *sbus_req, + struct ifp_ctx *ctx, + const char *domain, + const char *filter, + uint32_t limit); + +errno_t +ifp_users_list_by_domain_and_name_recv(TALLOC_CTX *mem_ctx, + struct tevent_req *req, + const char ***_paths); + +struct tevent_req * +ifp_users_find_by_valid_cert_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct sbus_request *sbus_req, + struct ifp_ctx *ctx, + const char *pem_cert); + +errno_t +ifp_users_find_by_valid_cert_recv(TALLOC_CTX *mem_ctx, + struct tevent_req *req, + const char **_path); + +/* org.freedesktop.sssd.infopipe.Users.User */ + +struct tevent_req * +ifp_users_user_update_groups_list_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct sbus_request *sbus_req, + struct ifp_ctx *ctx); + +errno_t +ifp_users_user_update_groups_list_recv(struct tevent_req *req); + +errno_t +ifp_users_user_get_name(TALLOC_CTX *mem_ctx, + struct sbus_request *sbus_req, + struct ifp_ctx *ctx, + const char **_out); + +errno_t +ifp_users_user_get_uid_number(TALLOC_CTX *mem_ctx, + struct sbus_request *sbus_req, + struct ifp_ctx *ctx, + uint32_t *_out); + +errno_t +ifp_users_user_get_gid_number(TALLOC_CTX *mem_ctx, + struct sbus_request *sbus_req, + struct ifp_ctx *ctx, + uint32_t *_out); + +errno_t +ifp_users_user_get_gecos(TALLOC_CTX *mem_ctx, + struct sbus_request *sbus_req, + struct ifp_ctx *ctx, + const char **_out); + +errno_t +ifp_users_user_get_home_directory(TALLOC_CTX *mem_ctx, + struct sbus_request *sbus_req, + struct ifp_ctx *ctx, + const char **_out); + +errno_t +ifp_users_user_get_login_shell(TALLOC_CTX *mem_ctx, + struct sbus_request *sbus_req, + struct ifp_ctx *ctx, + const char **_out); + +errno_t +ifp_users_user_get_unique_id(TALLOC_CTX *mem_ctx, + struct sbus_request *sbus_req, + struct ifp_ctx *ctx, + const char **_out); + +errno_t +ifp_users_user_get_groups(TALLOC_CTX *mem_ctx, + struct sbus_request *sbus_req, + struct ifp_ctx *ifp_ctx, + const char ***_out); + +errno_t +ifp_users_user_get_domain(TALLOC_CTX *mem_ctx, + struct sbus_request *sbus_req, + struct ifp_ctx *ctx, + const char **_out); + +errno_t +ifp_users_user_get_domainname(TALLOC_CTX *mem_ctx, + struct sbus_request *sbus_req, + struct ifp_ctx *ifp_ctx, + const char **_out); + +errno_t +ifp_users_user_get_extra_attributes(TALLOC_CTX *mem_ctx, + struct sbus_request *sbus_req, + struct ifp_ctx *ifp_ctx, + hash_table_t **_out); + +/* org.freedesktop.sssd.infopipe.Cache */ + +errno_t +ifp_cache_list_user(TALLOC_CTX *mem_ctx, + struct sbus_request *sbus_req, + struct ifp_ctx *ctx, + const char ***_out); + +errno_t +ifp_cache_list_by_domain_user(TALLOC_CTX *mem_ctx, + struct sbus_request *sbus_req, + struct ifp_ctx *ctx, + const char *domain, + const char ***_out); + +/* org.freedesktop.sssd.infopipe.Cache.Object */ + +errno_t +ifp_cache_object_store_user(TALLOC_CTX *mem_ctx, + struct sbus_request *sbus_req, + struct ifp_ctx *ctx, + bool *_result); + +errno_t +ifp_cache_object_remove_user(TALLOC_CTX *mem_ctx, + struct sbus_request *sbus_req, + struct ifp_ctx *ctx, + bool *_result); + +struct tevent_req * +ifp_users_list_by_attr_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct sbus_request *sbus_req, + struct ifp_ctx *ctx, + const char *attr, + const char *filter, + uint32_t limit); + +errno_t +ifp_users_list_by_attr_recv(TALLOC_CTX *mem_ctx, + struct tevent_req *req, + const char ***_paths); +#endif /* IFP_USERS_H_ */ diff --git a/src/responder/ifp/ifpsrv.c b/src/responder/ifp/ifpsrv.c new file mode 100644 index 0000000..aaf8325 --- /dev/null +++ b/src/responder/ifp/ifpsrv.c @@ -0,0 +1,363 @@ +/* + Authors: + Jakub Hrozek <jhrozek@redhat.com> + + Copyright (C) 2013 Red Hat + + InfoPipe responder: the responder server + + 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 <stdio.h> +#include <unistd.h> +#include <fcntl.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <sys/socket.h> +#include <sys/un.h> +#include <string.h> +#include <sys/time.h> +#include <errno.h> +#include <popt.h> +#include <dbus/dbus.h> + +#include "util/util.h" +#include "util/strtonum.h" +#include "confdb/confdb.h" +#include "responder/ifp/ifp_private.h" +#include "responder/ifp/ifp_domains.h" +#include "responder/ifp/ifp_components.h" +#include "responder/ifp/ifp_iface/ifp_iface_async.h" +#include "sss_iface/sss_iface_async.h" + +#define DEFAULT_ALLOWED_UIDS "0" + +struct sss_cmd_table *get_ifp_cmds(void) +{ + static struct sss_cmd_table ifp_cmds[] = { + { SSS_GET_VERSION, sss_cmd_get_version }, + { SSS_CLI_NULL, NULL} + }; + + return ifp_cmds; +} + +static errno_t +sysbus_init(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + const char *dbus_name, + struct ifp_ctx *ifp_ctx, + struct sbus_connection **_sysbus) +{ + struct sbus_connection *sysbus; + errno_t ret; + + sysbus = sbus_connect_system(mem_ctx, ev, dbus_name, + &ifp_ctx->rctx->last_request_time); + if (sysbus == NULL) { + DEBUG(SSSDBG_FATAL_FAILURE, "Unable to connect to system bus!\n"); + return ERR_NO_SYSBUS; + } + + sbus_connection_set_access_check(sysbus, ifp_access_check, ifp_ctx); + + ret = ifp_register_sbus_interface(sysbus, ifp_ctx); + if (ret != EOK) { + DEBUG(SSSDBG_FATAL_FAILURE, "Could not register interfaces\n"); + goto done; + } + + ret = ifp_register_nodes(ifp_ctx, sysbus); + if (ret != EOK) { + DEBUG(SSSDBG_FATAL_FAILURE, "Could not register nodes factories\n"); + goto done; + } + + *_sysbus = sysbus; + + ret = EOK; + +done: + if (ret != EOK) { + talloc_free(sysbus); + } + + return ret; +} + +static errno_t +ifp_sysbus_reconnect(TALLOC_CTX *mem_ctx, + struct sbus_request *sbus_req, + struct ifp_ctx *ifp_ctx) +{ + errno_t ret; + + DEBUG(SSSDBG_TRACE_FUNC, "Attempting to reconnect to the system bus\n"); + + if (ifp_ctx->sysbus != NULL) { + DEBUG(SSSDBG_TRACE_LIBS, "Already connected to sysbus\n"); + return EOK; + } + + /* Connect to the D-BUS system bus and set up methods */ + ret = sysbus_init(ifp_ctx, ifp_ctx->rctx->ev, IFP_BUS, + ifp_ctx, &ifp_ctx->sysbus); + if (ret == ERR_NO_SYSBUS) { + DEBUG(SSSDBG_MINOR_FAILURE, + "The system bus is not available..\n"); + return ret; + } else if (ret != EOK) { + DEBUG(SSSDBG_CRIT_FAILURE, + "Failed to connect to the system message bus\n"); + return ret; + } + + DEBUG(SSSDBG_TRACE_LIBS, "Reconnected to the system bus!\n"); + + return EOK; +} + +static errno_t +ifp_register_service_iface(struct ifp_ctx *ifp_ctx, + struct resp_ctx *rctx) +{ + errno_t ret; + + SBUS_INTERFACE(iface_svc, + sssd_service, + SBUS_METHODS( + SBUS_SYNC(METHOD, sssd_service, rotateLogs, responder_logrotate, rctx), + SBUS_SYNC(METHOD, sssd_service, sysbusReconnect, ifp_sysbus_reconnect, ifp_ctx) + ), + SBUS_SIGNALS(SBUS_NO_SIGNALS), + SBUS_PROPERTIES( + SBUS_SYNC(GETTER, sssd_service, debug_level, generic_get_debug_level, NULL), + SBUS_SYNC(SETTER, sssd_service, debug_level, generic_set_debug_level, NULL) + ) + ); + + ret = sbus_connection_add_path(rctx->mon_conn, SSS_BUS_PATH, &iface_svc); + if (ret != EOK) { + DEBUG(SSSDBG_FATAL_FAILURE, "Unable to register service interface" + "[%d]: %s\n", ret, sss_strerror(ret)); + } + + return ret; +} + +int ifp_process_init(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct confdb_ctx *cdb) +{ + struct resp_ctx *rctx; + struct sss_cmd_table *ifp_cmds; + struct ifp_ctx *ifp_ctx; + int ret; + char *uid_str; + char *attr_list_str; + char *wildcard_limit_str; + char *endptr; + + ifp_cmds = get_ifp_cmds(); + ret = sss_process_init(mem_ctx, ev, cdb, + ifp_cmds, + NULL, -1, NULL, -1, + CONFDB_IFP_CONF_ENTRY, + SSS_BUS_IFP, SSS_IFP_SBUS_SERVICE_NAME, + sss_connection_setup, + &rctx); + if (ret != EOK) { + DEBUG(SSSDBG_FATAL_FAILURE, "sss_process_init() failed\n"); + return ret; + } + + ifp_ctx = talloc_zero(rctx, struct ifp_ctx); + if (ifp_ctx == NULL) { + DEBUG(SSSDBG_FATAL_FAILURE, "fatal error initializing ifp_ctx\n"); + ret = ENOMEM; + goto fail; + } + + ifp_ctx->rctx = rctx; + ifp_ctx->rctx->pvt_ctx = ifp_ctx; + + ret = sss_names_init_from_args(ifp_ctx, + SSS_DEFAULT_RE, + "%1$s@%2$s", &ifp_ctx->snctx); + if (ret != EOK) { + DEBUG(SSSDBG_FATAL_FAILURE, "fatal error initializing regex data\n"); + goto fail; + } + + ret = confdb_get_string(ifp_ctx->rctx->cdb, ifp_ctx->rctx, + CONFDB_IFP_CONF_ENTRY, CONFDB_SERVICE_ALLOWED_UIDS, + DEFAULT_ALLOWED_UIDS, &uid_str); + if (ret != EOK) { + DEBUG(SSSDBG_FATAL_FAILURE, "Failed to get allowed UIDs.\n"); + goto fail; + } + + ret = csv_string_to_uid_array(ifp_ctx->rctx, uid_str, + &ifp_ctx->rctx->allowed_uids_count, + &ifp_ctx->rctx->allowed_uids); + talloc_free(uid_str); + if (ret != EOK) { + DEBUG(SSSDBG_FATAL_FAILURE, "Failed to set allowed UIDs.\n"); + goto fail; + } + + ret = confdb_get_string(ifp_ctx->rctx->cdb, ifp_ctx->rctx, + CONFDB_IFP_CONF_ENTRY, CONFDB_IFP_USER_ATTR_LIST, + NULL, &attr_list_str); + if (ret != EOK) { + DEBUG(SSSDBG_FATAL_FAILURE, "Failed to get user attribute list.\n"); + goto fail; + } + + ifp_ctx->user_whitelist = ifp_parse_user_attr_list(ifp_ctx, attr_list_str); + talloc_free(attr_list_str); + if (ifp_ctx->user_whitelist == NULL) { + DEBUG(SSSDBG_FATAL_FAILURE, + "Failed to parse the allowed attribute list\n"); + goto fail; + } + + /* A bit convoluted way until we have a confdb_get_uint32 */ + ret = confdb_get_string(ifp_ctx->rctx->cdb, + ifp_ctx->rctx, + CONFDB_IFP_CONF_ENTRY, + CONFDB_IFP_WILDCARD_LIMIT, + NULL, /* no limit by default */ + &wildcard_limit_str); + if (ret != EOK) { + DEBUG(SSSDBG_FATAL_FAILURE, + "Failed to retrieve limit for a wildcard search\n"); + goto fail; + } + + if (wildcard_limit_str) { + ifp_ctx->wildcard_limit = strtouint32(wildcard_limit_str, &endptr, 10); + if ((errno != 0) || *endptr || (wildcard_limit_str == endptr)) { + ret = errno ? errno : EINVAL; + goto fail; + } + } + + /* Connect to the D-BUS system bus and set up methods */ + ret = sysbus_init(ifp_ctx, ifp_ctx->rctx->ev, IFP_BUS, + ifp_ctx, &ifp_ctx->sysbus); + if (ret == ERR_NO_SYSBUS) { + DEBUG(SSSDBG_MINOR_FAILURE, + "The system bus is not available..\n"); + /* Explicitly ignore, the D-Bus daemon will start us */ + } else if (ret != EOK) { + DEBUG(SSSDBG_CRIT_FAILURE, + "Failed to connect to the system message bus\n"); + talloc_free(ifp_ctx); + return EIO; + } + + ret = schedule_get_domains_task(rctx, rctx->ev, rctx, NULL, NULL, NULL); + if (ret != EOK) { + DEBUG(SSSDBG_FATAL_FAILURE, + "schedule_get_domains_tasks failed.\n"); + goto fail; + } + + /* The responder is initialized. Now tell it to the monitor. */ + ret = sss_monitor_service_init(rctx, rctx->ev, SSS_BUS_IFP, + SSS_IFP_SBUS_SERVICE_NAME, + SSS_IFP_SBUS_SERVICE_VERSION, + MT_SVC_SERVICE, + &rctx->last_request_time, &rctx->mon_conn); + if (ret != EOK) { + DEBUG(SSSDBG_FATAL_FAILURE, "fatal error setting up message bus\n"); + goto fail; + } + + ret = ifp_register_service_iface(ifp_ctx, rctx); + if (ret != EOK) { + goto fail; + } + + DEBUG(SSSDBG_TRACE_FUNC, "InfoPipe Initialization complete\n"); + return EOK; + +fail: + talloc_free(rctx); + return ret; +} + +int main(int argc, const char *argv[]) +{ + int opt; + poptContext pc; + char *opt_logger = NULL; + struct main_context *main_ctx; + int ret; + uid_t uid = 0; + gid_t gid = 0; + + struct poptOption long_options[] = { + POPT_AUTOHELP + SSSD_MAIN_OPTS + SSSD_LOGGER_OPTS + SSSD_SERVER_OPTS(uid, gid) + SSSD_RESPONDER_OPTS + POPT_TABLEEND + }; + + /* Set debug level to invalid value so we can decide if -d 0 was used. */ + debug_level = SSSDBG_INVALID; + + umask(DFL_RSP_UMASK); + + pc = poptGetContext(argv[0], argc, argv, long_options, 0); + while((opt = poptGetNextOpt(pc)) != -1) { + switch(opt) { + default: + fprintf(stderr, "\nInvalid option %s: %s\n\n", + poptBadOption(pc, 0), poptStrerror(opt)); + poptPrintUsage(pc, stderr, 0); + return 1; + } + } + + poptFreeContext(pc); + + /* set up things like debug, signals, daemonization, etc. */ + debug_log_file = "sssd_ifp"; + DEBUG_INIT(debug_level, opt_logger); + + ret = server_setup("ifp", true, 0, 0, 0, + CONFDB_IFP_CONF_ENTRY, &main_ctx, true); + if (ret != EOK) return 2; + + ret = die_if_parent_died(); + if (ret != EOK) { + /* This is not fatal, don't return */ + DEBUG(SSSDBG_MINOR_FAILURE, + "Could not set up to exit when parent process does\n"); + } + + ret = ifp_process_init(main_ctx, + main_ctx->event_ctx, + main_ctx->confdb_ctx); + if (ret != EOK) return 3; + + /* loop on main */ + server_loop(main_ctx); + return 0; +} diff --git a/src/responder/ifp/ifpsrv_cmd.c b/src/responder/ifp/ifpsrv_cmd.c new file mode 100644 index 0000000..8cf1ec8 --- /dev/null +++ b/src/responder/ifp/ifpsrv_cmd.c @@ -0,0 +1,631 @@ +/* + Authors: + Jakub Hrozek <jhrozek@redhat.com> + + Copyright (C) 2013 Red Hat + + InfoPipe responder: the responder commands + + 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 "db/sysdb.h" + +#include "responder/ifp/ifp_private.h" +#include "responder/common/cache_req/cache_req.h" +#include "responder/ifp/ifp_iface/ifp_iface_async.h" + +struct ifp_user_get_attr_state { + const char **attrs; + struct ldb_result *res; + + enum sss_dp_acct_type search_type; + + struct sss_domain_info *dom; + + struct resp_ctx *rctx; + struct sss_nc_ctx *ncache; +}; + +static void ifp_user_get_attr_done(struct tevent_req *subreq); + +static struct tevent_req * +ifp_user_get_attr_send(TALLOC_CTX *mem_ctx, struct resp_ctx *rctx, + struct sss_nc_ctx *ncache, + enum sss_dp_acct_type search_type, + const char *input, const char **attrs) +{ + errno_t ret; + struct tevent_req *req; + struct tevent_req *subreq; + struct ifp_user_get_attr_state *state; + struct cache_req_data *data; + + req = tevent_req_create(mem_ctx, &state, struct ifp_user_get_attr_state); + if (req == NULL) { + return NULL; + } + state->attrs = attrs; + state->rctx = rctx; + state->ncache = ncache; + state->search_type = search_type; + + switch (state->search_type) { + case SSS_DP_USER: + data = cache_req_data_name(state, CACHE_REQ_USER_BY_NAME, input); + break; + case SSS_DP_INITGROUPS: + data = cache_req_data_name(state, CACHE_REQ_INITGROUPS, input); + break; + default: + DEBUG(SSSDBG_CRIT_FAILURE, "Unsupported search type [%d]!\n", + state->search_type); + ret = ERR_INTERNAL; + goto done; + } + + if (data == NULL) { + ret = ENOMEM; + goto done; + } + + /* IFP serves both POSIX and application domains. Requests that need + * to differentiate between the two must be qualified + */ + subreq = cache_req_send(state, state->rctx->ev, state->rctx, state->ncache, + 0, CACHE_REQ_ANY_DOM, NULL, data); + if (subreq == NULL) { + ret = ENOMEM; + goto done; + } + + tevent_req_set_callback(subreq, ifp_user_get_attr_done, req); + + ret = EOK; +done: + if (ret != EOK) { + tevent_req_error(req, ret); + tevent_req_post(req, rctx->ev); + } + return req; +} + +static void ifp_user_get_attr_done(struct tevent_req *subreq) +{ + struct ifp_user_get_attr_state *state = NULL; + struct tevent_req *req = NULL; + struct cache_req_result *result; + errno_t ret; + const char *fqdn; + + req = tevent_req_callback_data(subreq, struct tevent_req); + state = tevent_req_data(req, struct ifp_user_get_attr_state); + + ret = cache_req_single_domain_recv(state, subreq, &result); + talloc_zfree(subreq); + if (ret != EOK) { + tevent_req_error(req, ret); + return; + } + + state->res = talloc_steal(state, result->ldb_result); + state->dom = result->domain; + talloc_zfree(result); + + fqdn = ldb_msg_find_attr_as_string(state->res->msgs[0], SYSDB_NAME, NULL); + if (fqdn == NULL) { + tevent_req_error(req, ERR_INTERNAL); + return; + } + + if (state->search_type == SSS_DP_USER) { + /* throw away the result but keep the fqdn and perform attr search */ + fqdn = talloc_steal(state, fqdn); + talloc_zfree(state->res); + + ret = sysdb_get_user_attr_with_views(state, state->dom, fqdn, + state->attrs, &state->res); + if (ret != EOK) { + DEBUG(SSSDBG_CRIT_FAILURE, "sysdb_get_user_attr_with_views() " + "failed [%d]: %s\n", ret, sss_strerror(ret)); + tevent_req_error(req, ret); + return; + } else if (state->res->count == 0) { + tevent_req_error(req, ENOENT); + return; + } else if (state->res->count != 1) { + DEBUG(SSSDBG_CRIT_FAILURE, "sysdb_get_user_attr_with_views() " + "returned more than one result!\n"); + tevent_req_error(req, ENOENT); + return; + } + } + + tevent_req_done(req); +} + +static errno_t +ifp_user_get_attr_recv(TALLOC_CTX *mem_ctx, + struct tevent_req *req, + struct ldb_result **_res, + struct sss_domain_info **_domain) +{ + struct ifp_user_get_attr_state *state = tevent_req_data(req, + struct ifp_user_get_attr_state); + + TEVENT_REQ_RETURN_ON_ERROR(req); + + if (state->res == NULL) { + /* Did the request end with success but with no data? */ + return ENOENT; + } + + if (_res) { + *_res = talloc_steal(mem_ctx, state->res); + } + + if (_domain) { + *_domain = state->dom; + } + + return EOK; +} + +static errno_t +ifp_get_user_attr_write_reply(DBusMessageIter *iter, + const char **attrs, + struct resp_ctx *rctx, + struct sss_domain_info *domain, + struct ldb_result *res) +{ + struct ldb_message_element *el; + DBusMessageIter iter_dict; + dbus_bool_t dbret; + errno_t ret; + int ai; + + 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 EIO; + } + + if (res->count > 0) { + ret = ifp_ldb_el_output_name(rctx, res->msgs[0], SYSDB_NAME, domain); + if (ret != EOK) { + DEBUG(SSSDBG_CRIT_FAILURE, + "Cannot convert SYSDB_NAME to output format [%d]: %s\n", + ret, sss_strerror(ret)); + goto done; + } + + ret = ifp_ldb_el_output_name(rctx, res->msgs[0], SYSDB_NAME_ALIAS, domain); + if (ret != EOK) { + DEBUG(SSSDBG_CRIT_FAILURE, + "Cannot convert SYSDB_NAME_ALIAS to output format [%d]: %s\n", + ret, sss_strerror(ret)); + goto done; + } + + for (ai = 0; attrs != NULL && attrs[ai] != NULL; ai++) { + if (strcmp(attrs[ai], "domainname") == 0) { + ret = ifp_add_value_to_dict(&iter_dict, "domainname", + domain->name); + if (ret != EOK) { + DEBUG(SSSDBG_MINOR_FAILURE, + "Cannot add attribute domainname to message\n"); + continue; + } + } + + el = sss_view_ldb_msg_find_element(domain, res->msgs[0], attrs[ai]); + if (el == NULL || el->num_values == 0) { + DEBUG(SSSDBG_MINOR_FAILURE, + "Attribute %s not present or has no values\n", + attrs[ai]); + continue; + } + + ret = ifp_add_ldb_el_to_dict(&iter_dict, el); + if (ret != EOK) { + DEBUG(SSSDBG_MINOR_FAILURE, + "Cannot add attribute %s to message\n", + attrs[ai]); + continue; + } + } + } + + dbret = dbus_message_iter_close_container(iter, &iter_dict); + if (!dbret) { + ret = EIO; + goto done; + } + + ret = EOK; + +done: + if (ret != EOK) { + dbus_message_iter_abandon_container(iter, &iter_dict); + } + + return ret; +} + +struct ifp_get_user_attr_state { + const char *name; + const char **attrs; + struct resp_ctx *rctx; + + DBusMessageIter *write_iter; +}; + +static void ifp_get_user_attr_done(struct tevent_req *subreq); + +struct tevent_req * +ifp_get_user_attr_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct sbus_request *sbus_req, + struct ifp_ctx *ctx, + const char *name, + const char **attrs, + DBusMessageIter *write_iter) +{ + struct ifp_get_user_attr_state *state; + struct tevent_req *subreq; + struct tevent_req *req; + errno_t ret; + + DEBUG(SSSDBG_IMPORTANT_INFO, "GetUserAttr is deprecated, please consider " + "switching to org.freedesktop.sssd.infopipe.Users.User interface\n"); + + req = tevent_req_create(mem_ctx, &state, struct ifp_get_user_attr_state); + if (req == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "Unable to create tevent request!\n"); + return NULL; + } + + state->name = name; + state->attrs = attrs; + state->rctx = ctx->rctx; + state->write_iter = write_iter; + + DEBUG(SSSDBG_FUNC_DATA, + "Looking up attributes of user [%s] on behalf of %"PRIi64"\n", + state->name, sbus_req->sender->uid); + + subreq = ifp_user_get_attr_send(state, ctx->rctx, ctx->rctx->ncache, + SSS_DP_USER, state->name, state->attrs); + if (subreq == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "Unable to create subrequest!\n"); + ret = ENOMEM; + goto done; + } + + tevent_req_set_callback(subreq, ifp_get_user_attr_done, req); + + ret = EAGAIN; + +done: + if (ret != EAGAIN) { + tevent_req_error(req, ret); + tevent_req_post(req, ev); + } + + return req; +} + +static void ifp_get_user_attr_done(struct tevent_req *subreq) +{ + struct ifp_get_user_attr_state *state; + struct sss_domain_info *dom; + struct ldb_result *res; + struct tevent_req *req; + errno_t ret; + + req = tevent_req_callback_data(subreq, struct tevent_req); + state = tevent_req_data(req, struct ifp_get_user_attr_state); + + ret = ifp_user_get_attr_recv(state, subreq, &res, &dom); + talloc_zfree(subreq); + if (ret != EOK) { + DEBUG(SSSDBG_OP_FAILURE, "Unable to get user attributes [%d]: %s\n", + ret, sss_strerror(ret)); + tevent_req_error(req, ret); + return; + } + + ret = ifp_get_user_attr_write_reply(state->write_iter, state->attrs, + state->rctx, dom, res); + if (ret != EOK) { + DEBUG(SSSDBG_OP_FAILURE, "Unable to construct reply [%d]: %s\n", + ret, sss_strerror(ret)); + tevent_req_error(req, ret); + return; + } + + tevent_req_done(req); + return; +} + +errno_t +ifp_get_user_attr_recv(TALLOC_CTX *mem_ctx, struct tevent_req *req) +{ + TEVENT_REQ_RETURN_ON_ERROR(req); + + return EOK; +} + +static errno_t +ifp_user_get_groups_build_group_list(struct resp_ctx *rctx, + const char *name, + const char **groupnames, + int *gri) +{ + struct sized_string *group_name; + errno_t ret; + + ret = sized_domain_name(NULL, rctx, name, &group_name); + if (ret != EOK) { + DEBUG(SSSDBG_MINOR_FAILURE, + "Unable to get sized name for %s [%d]: %s\n", + name, ret, sss_strerror(ret)); + goto done; + } + + groupnames[*gri] = talloc_strndup(groupnames, + group_name->str, + group_name->len); + talloc_free(group_name); + if (groupnames[*gri] == NULL) { + DEBUG(SSSDBG_MINOR_FAILURE, "talloc_strndup failed\n"); + ret = ENOMEM; + goto done; + } + (*gri)++; + + DEBUG(SSSDBG_TRACE_FUNC, "Adding group %s\n", groupnames[*gri]); + +done: + return ret; +} + +static errno_t +ifp_user_get_groups_build_reply(TALLOC_CTX *mem_ctx, + struct resp_ctx *rctx, + struct sss_domain_info *domain, + struct ldb_result *res, + const char ***_groupnames) +{ + TALLOC_CTX *tmp_ctx = NULL; + int i, gri, num; + const char *name; + const char **groupnames; + gid_t orig_gid; + struct ldb_message *msg = NULL; + const char *attrs[] = {SYSDB_NAME, NULL}; + errno_t ret; + + tmp_ctx = talloc_new(NULL); + if (tmp_ctx == NULL) { + DEBUG(SSSDBG_OP_FAILURE, "talloc_new failed.\n"); + return ENOMEM; + } + + num = res->count; + groupnames = talloc_zero_array(mem_ctx, const char *, num + 1); + if (groupnames == NULL) { + return ENOMEM; + } + + gri = 0; + orig_gid = sss_view_ldb_msg_find_attr_as_uint64(domain, + res->msgs[0], + SYSDB_PRIMARY_GROUP_GIDNUM, 0); + ret = sysdb_search_group_by_gid(tmp_ctx, domain, orig_gid, attrs, &msg); + + /* If origPrimaryGroupGidNumber exists add it to group list */ + if(ret == EOK) { + name = ldb_msg_find_attr_as_string(msg, SYSDB_NAME, NULL); + + if (name != NULL) { + ifp_user_get_groups_build_group_list(rctx, name, groupnames, &gri); + } + } + + /* Start counting from 1 to exclude the user entry */ + for (i = 1; i < num; i++) { + name = sss_view_ldb_msg_find_attr_as_string(domain, + res->msgs[i], + SYSDB_NAME, NULL); + if (name == NULL) { + DEBUG(SSSDBG_MINOR_FAILURE, "Skipping a group with no name\n"); + continue; + } + + ifp_user_get_groups_build_group_list(rctx, name, groupnames, &gri); + } + + *_groupnames = groupnames; + + talloc_free(tmp_ctx); + return EOK; +} + +struct ifp_user_get_groups_state { + struct tevent_context *ev; + struct resp_ctx *rctx; + struct ldb_result *res; + struct sss_domain_info *domain; + const char **groupnames; +}; + +static void ifp_user_get_groups_attr_done(struct tevent_req *subreq); +static void ifp_user_get_groups_done(struct tevent_req *subreq); + +struct tevent_req * +ifp_user_get_groups_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct sbus_request *sbus_req, + struct ifp_ctx *ctx, + const char *name) +{ + const char *attrs[] = {SYSDB_MEMBEROF, NULL}; + struct ifp_user_get_groups_state *state; + struct tevent_req *subreq; + struct tevent_req *req; + errno_t ret; + + req = tevent_req_create(mem_ctx, &state, struct ifp_user_get_groups_state); + if (req == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "Unable to create tevent request!\n"); + return NULL; + } + + state->ev = ev; + state->rctx = ctx->rctx; + + DEBUG(SSSDBG_FUNC_DATA, + "Looking up groups of user [%s] on behalf of %"PRIi64"\n", + name, sbus_req->sender->uid); + + subreq = ifp_user_get_attr_send(state, ctx->rctx, ctx->rctx->ncache, + SSS_DP_INITGROUPS, name, attrs); + if (subreq == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "Unable to create subrequest!\n"); + ret = ENOMEM; + goto done; + } + + tevent_req_set_callback(subreq, ifp_user_get_groups_attr_done, req); + + ret = EAGAIN; + +done: + if (ret != EAGAIN) { + tevent_req_error(req, ret); + tevent_req_post(req, ev); + } + + return req; +} + +static void ifp_user_get_groups_attr_done(struct tevent_req *subreq) +{ + struct ifp_user_get_groups_state *state; + struct tevent_req *req; + errno_t ret; + + req = tevent_req_callback_data(subreq, struct tevent_req); + state = tevent_req_data(req, struct ifp_user_get_groups_state); + + ret = ifp_user_get_attr_recv(state, subreq, &state->res, &state->domain); + talloc_zfree(subreq); + if (ret != EOK) { + DEBUG(SSSDBG_OP_FAILURE, "Unable to get group members [%d]: %s\n", + ret, sss_strerror(ret)); + tevent_req_error(req, ret); + return; + } + + subreq = resp_resolve_group_names_send(state, state->ev, state->rctx, + state->domain, state->res); + if (subreq == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "Unable to create subrequest!\n"); + tevent_req_error(req, ENOMEM); + return; + } + + tevent_req_set_callback(subreq, ifp_user_get_groups_done, req); +} + +static void ifp_user_get_groups_done(struct tevent_req *subreq) +{ + struct ifp_user_get_groups_state *state; + struct ldb_result *res; + struct tevent_req *req; + errno_t ret; + + req = tevent_req_callback_data(subreq, struct tevent_req); + state = tevent_req_data(req, struct ifp_user_get_groups_state); + + ret = resp_resolve_group_names_recv(state, subreq, &res); + talloc_zfree(subreq); + if (ret != EOK) { + DEBUG(SSSDBG_OP_FAILURE, "Failed to resolve group names [%d]: %s\n", + ret, sss_strerror(ret)); + tevent_req_error(req, ret); + return; + } + + res = res == NULL ? state->res : res; + + ret = ifp_user_get_groups_build_reply(state, state->rctx, state->domain, + res, &state->groupnames); + if (ret != EOK) { + DEBUG(SSSDBG_OP_FAILURE, "Unable to construct reply [%d]: %s\n", + ret, sss_strerror(ret)); + tevent_req_error(req, ret); + return; + } + + tevent_req_done(req); +} + +errno_t +ifp_user_get_groups_recv(TALLOC_CTX *mem_ctx, + struct tevent_req *req, + const char ***_groupnames) +{ + struct ifp_user_get_groups_state *state; + state = tevent_req_data(req, struct ifp_user_get_groups_state); + + TEVENT_REQ_RETURN_ON_ERROR(req); + + *_groupnames = talloc_steal(mem_ctx, state->groupnames); + + return EOK; +} + +struct cli_protocol_version *register_cli_protocol_version(void) +{ + static struct cli_protocol_version ssh_cli_protocol_version[] = { + {0, NULL, NULL} + }; + + return ssh_cli_protocol_version; +} + +errno_t +ifp_ping(TALLOC_CTX *mem_ctx, + struct sbus_request *sbus_req, + struct ifp_ctx *ctx, + const char *ping, + const char **_pong) +{ + DEBUG(SSSDBG_CONF_SETTINGS, "Got request for [%s]\n", ping); + + if (strcasecmp(ping, "ping") != 0) { + DEBUG(SSSDBG_OP_FAILURE, "Ping() only accepts \"ping\" as a param\n"); + return EINVAL; + } + + *_pong = "PONG"; + + return EOK; +} diff --git a/src/responder/ifp/ifpsrv_util.c b/src/responder/ifp/ifpsrv_util.c new file mode 100644 index 0000000..c21ceef --- /dev/null +++ b/src/responder/ifp/ifpsrv_util.c @@ -0,0 +1,455 @@ +/* + Authors: + Jakub Hrozek <jhrozek@redhat.com> + Stephen Gallagher <sgallagh@redhat.com> + + Copyright (C) 2013 Red Hat + + InfoPipe responder: Utility functions + + 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 <sys/param.h> + +#include "db/sysdb.h" +#include "responder/ifp/ifp_private.h" + +#define IFP_USER_DEFAULT_ATTRS {SYSDB_NAME, SYSDB_UIDNUM, \ + SYSDB_GIDNUM, SYSDB_GECOS, \ + SYSDB_HOMEDIR, SYSDB_SHELL, \ + "groups", "domain", "domainname", \ + "extraAttributes", NULL} + +errno_t ifp_add_value_to_dict(DBusMessageIter *iter_dict, + const char *key, + const char *value) +{ + DBusMessageIter iter_dict_entry; + DBusMessageIter iter_dict_val; + DBusMessageIter iter_array; + dbus_bool_t dbret; + + if (value == NULL || key == NULL) { + return EINVAL; + } + + dbret = dbus_message_iter_open_container(iter_dict, + DBUS_TYPE_DICT_ENTRY, NULL, + &iter_dict_entry); + if (!dbret) { + return ENOMEM; + } + + /* Start by appending the key */ + dbret = dbus_message_iter_append_basic(&iter_dict_entry, + DBUS_TYPE_STRING, &key); + if (!dbret) { + return ENOMEM; + } + + dbret = dbus_message_iter_open_container(&iter_dict_entry, + DBUS_TYPE_VARIANT, + DBUS_TYPE_ARRAY_AS_STRING + DBUS_TYPE_STRING_AS_STRING, + &iter_dict_val); + if (!dbret) { + return ENOMEM; + } + + /* Open container for values */ + dbret = dbus_message_iter_open_container(&iter_dict_val, + DBUS_TYPE_ARRAY, DBUS_TYPE_STRING_AS_STRING, + &iter_array); + if (!dbret) { + return ENOMEM; + } + + dbret = dbus_message_iter_append_basic(&iter_array, + DBUS_TYPE_STRING, + &value); + if (!dbret) { + return ENOMEM; + } + + dbret = dbus_message_iter_close_container(&iter_dict_val, + &iter_array); + if (!dbret) { + return ENOMEM; + } + + dbret = dbus_message_iter_close_container(&iter_dict_entry, + &iter_dict_val); + if (!dbret) { + return ENOMEM; + } + + dbret = dbus_message_iter_close_container(iter_dict, + &iter_dict_entry); + if (!dbret) { + return ENOMEM; + } + + return EOK; +} + +errno_t ifp_add_ldb_el_to_dict(DBusMessageIter *iter_dict, + struct ldb_message_element *el) +{ + DBusMessageIter iter_dict_entry; + DBusMessageIter iter_dict_val; + DBusMessageIter iter_array; + dbus_bool_t dbret; + unsigned int i; + + if (el == NULL) { + return EINVAL; + } + + dbret = dbus_message_iter_open_container(iter_dict, + DBUS_TYPE_DICT_ENTRY, NULL, + &iter_dict_entry); + if (!dbret) { + return ENOMEM; + } + + /* Start by appending the key */ + dbret = dbus_message_iter_append_basic(&iter_dict_entry, + DBUS_TYPE_STRING, &(el->name)); + if (!dbret) { + return ENOMEM; + } + + dbret = dbus_message_iter_open_container(&iter_dict_entry, + DBUS_TYPE_VARIANT, + DBUS_TYPE_ARRAY_AS_STRING + DBUS_TYPE_STRING_AS_STRING, + &iter_dict_val); + if (!dbret) { + return ENOMEM; + } + + /* Open container for values */ + dbret = dbus_message_iter_open_container(&iter_dict_val, + DBUS_TYPE_ARRAY, DBUS_TYPE_STRING_AS_STRING, + &iter_array); + if (!dbret) { + return ENOMEM; + } + + /* Now add all the values */ + for (i = 0; i < el->num_values; i++) { + DEBUG(SSSDBG_TRACE_FUNC, "element [%s] has value [%s]\n", + el->name, (const char *) el->values[i].data); + + dbret = dbus_message_iter_append_basic(&iter_array, + DBUS_TYPE_STRING, + &(el->values[i].data)); + if (!dbret) { + return ENOMEM; + } + } + + dbret = dbus_message_iter_close_container(&iter_dict_val, + &iter_array); + if (!dbret) { + return ENOMEM; + } + + dbret = dbus_message_iter_close_container(&iter_dict_entry, + &iter_dict_val); + if (!dbret) { + return ENOMEM; + } + + dbret = dbus_message_iter_close_container(iter_dict, + &iter_dict_entry); + if (!dbret) { + return ENOMEM; + } + + return EOK; +} + + +bool +ifp_attr_allowed(const char *whitelist[], const char *attr) +{ + size_t i; + + if (whitelist == NULL) { + return false; + } + + for (i = 0; whitelist[i]; i++) { + if (strcasecmp(whitelist[i], attr) == 0) { + break; + } + } + + return (whitelist[i]) ? true : false; +} + +const char ** +ifp_parse_user_attr_list(TALLOC_CTX *mem_ctx, const char *csv) +{ + static const char *defaults[] = IFP_USER_DEFAULT_ATTRS; + + return parse_attr_list_ex(mem_ctx, csv, defaults); +} + +const char ** +ifp_get_user_extra_attributes(TALLOC_CTX *mem_ctx, struct ifp_ctx *ifp_ctx) +{ + TALLOC_CTX *tmp_ctx = NULL; + const char *std[] = IFP_USER_DEFAULT_ATTRS; + const char **whitelist = ifp_ctx->user_whitelist; + const char **extra; + bool found; + int extra_num; + int i, j; + + tmp_ctx = talloc_new(NULL); + if (tmp_ctx == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "talloc_new() failed\n"); + return NULL; + } + + for (i = 0; whitelist[i] != NULL; i++) { + /* Just count number of attributes in whitelist. */ + } + + extra = talloc_zero_array(tmp_ctx, const char *, i + 1); + if (extra == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "talloc_zero_array() failed\n"); + goto fail; + } + + extra_num = 0; + for (i = 0; whitelist[i] != NULL; i++) { + found = false; + for (j = 0; std[j] != NULL; j++) { + if (strcmp(whitelist[i], std[j]) == 0) { + found = true; + break; + } + } + + if (!found) { + extra[extra_num] = talloc_strdup(extra, whitelist[i]); + if (extra[extra_num] == NULL) { + goto fail; + } + + extra_num++; + } + } + + extra = talloc_realloc(tmp_ctx, extra, const char *, extra_num + 1); + if (extra == NULL) { + goto fail; + } + + talloc_steal(mem_ctx, extra); + talloc_free(tmp_ctx); + return extra; + +fail: + talloc_free(tmp_ctx); + return NULL; +} + +bool +ifp_is_user_attr_allowed(struct ifp_ctx *ifp_ctx, const char *attr) +{ + return ifp_attr_allowed(ifp_ctx->user_whitelist, attr); +} + +static uint32_t ifp_list_limit(struct ifp_ctx *ctx, uint32_t limit) +{ + if (limit == 0) { + return ctx->wildcard_limit; + } else if (ctx->wildcard_limit) { + return MIN(ctx->wildcard_limit, limit); + } else { + return limit; + } +} + +struct ifp_list_ctx *ifp_list_ctx_new(TALLOC_CTX *mem_ctx, + struct ifp_ctx *ctx, + const char *attr, + const char *filter, + uint32_t limit) +{ + struct ifp_list_ctx *list_ctx; + + list_ctx = talloc_zero(mem_ctx, struct ifp_list_ctx); + if (list_ctx == NULL) { + return NULL; + } + + list_ctx->limit = ifp_list_limit(ctx, limit); + list_ctx->ctx = ctx; + list_ctx->dom = ctx->rctx->domains; + list_ctx->attr = attr; + list_ctx->filter = filter; + list_ctx->paths_max = 1; + list_ctx->paths = talloc_zero_array(list_ctx, const char *, + list_ctx->paths_max + 1); + if (list_ctx->paths == NULL) { + talloc_free(list_ctx); + return NULL; + } + + return list_ctx; +} + +errno_t ifp_list_ctx_remaining_capacity(struct ifp_list_ctx *list_ctx, + size_t entries, + size_t *_capacity) +{ + size_t capacity = list_ctx->limit - list_ctx->path_count; + errno_t ret; + size_t c; + + if (list_ctx->limit == 0) { + capacity = entries; + goto immediately; + } + + if (capacity < entries) { + DEBUG(SSSDBG_MINOR_FAILURE, + "IFP list request has limit of %"PRIu32" entries but back end " + "returned %zu entries\n", list_ctx->limit, + list_ctx->path_count + entries); + } else { + capacity = entries; + } + +immediately: + list_ctx->paths_max = list_ctx->path_count + capacity; + list_ctx->paths = talloc_realloc(list_ctx, list_ctx->paths, const char *, + list_ctx->paths_max + 1); + if (list_ctx->paths == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "talloc_realloc() failed\n"); + ret = ENOMEM; + goto done; + } + for (c = list_ctx->path_count; c <= list_ctx->paths_max; c++) { + list_ctx->paths[c] = NULL; + } + + *_capacity = capacity; + ret = EOK; + +done: + return ret; +} + +errno_t ifp_ldb_el_output_name(struct resp_ctx *rctx, + struct ldb_message *msg, + const char *el_name, + struct sss_domain_info *dom) +{ + struct ldb_message_element *el; + char *in_name; + char *out_name; + errno_t ret; + char *name; + TALLOC_CTX *tmp_ctx; + + el = ldb_msg_find_element(msg, el_name); + if (el == NULL) { + return EOK; + } + + tmp_ctx = talloc_new(NULL); + if (tmp_ctx == NULL) { + return ENOMEM; + } + + for (size_t c = 0; c < el->num_values; c++) { + in_name = (char *) el->values[c].data; + ret = sss_parse_internal_fqname(tmp_ctx, in_name, &name, NULL); + if (ret != EOK) { + goto done; + } + + out_name = sss_output_name(tmp_ctx, in_name, dom->case_preserve, + rctx->override_space); + if (out_name == NULL) { + ret = EIO; + goto done; + } + + if (dom->fqnames) { + out_name = sss_tc_fqname(tmp_ctx, dom->names, dom, out_name); + if (out_name == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "sss_tc_fqname failed\n"); + ret = ENOMEM; + goto done; + } + } + + talloc_free(el->values[c].data); + el->values[c].data = (uint8_t *) talloc_steal(el->values, out_name); + el->values[c].length = strlen(out_name); + } + + ret = EOK; +done: + talloc_free(tmp_ctx); + return ret; +} + +char *ifp_format_name_attr(TALLOC_CTX *mem_ctx, struct ifp_ctx *ifp_ctx, + const char *in_name, struct sss_domain_info *dom) +{ + TALLOC_CTX *tmp_ctx; + char *out_name; + char *ret_name = NULL; + char *shortname; + errno_t ret; + + tmp_ctx = talloc_new(NULL); + if (tmp_ctx == NULL) { + return NULL; + } + + ret = sss_parse_internal_fqname(tmp_ctx, in_name, &shortname, NULL); + if (ret != EOK) { + DEBUG(SSSDBG_CRIT_FAILURE, "Unparseable name %s\n", in_name); + goto done; + } + + out_name = sss_output_name(tmp_ctx, in_name, dom->case_preserve, + ifp_ctx->rctx->override_space); + if (out_name == NULL) { + goto done; + } + + if (dom->fqnames) { + out_name = sss_tc_fqname(tmp_ctx, dom->names, dom, out_name); + if (out_name == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "sss_tc_fqname failed\n"); + goto done; + } + } + + ret_name = talloc_steal(mem_ctx, out_name); +done: + talloc_free(tmp_ctx); + return ret_name; +} diff --git a/src/responder/ifp/org.freedesktop.sssd.infopipe.conf b/src/responder/ifp/org.freedesktop.sssd.infopipe.conf new file mode 100644 index 0000000..4437fb3 --- /dev/null +++ b/src/responder/ifp/org.freedesktop.sssd.infopipe.conf @@ -0,0 +1,47 @@ +<?xml version="1.0"?> <!--*-nxml-*--> +<!DOCTYPE busconfig PUBLIC + "-//freedesktop//DTD D-BUS Bus Configuration 1.0//EN" + "http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd"> +<busconfig> + + <!-- This configuration file specifies the required security policies + for the SSSD InfoPipe to work. --> + + <!-- Only root can own (provide) the SSSD service --> + <policy user="root"> + <allow own="org.freedesktop.sssd.infopipe"/> + </policy> + + <!-- Allow all methods on the interface --> + <!-- Right now, this will be handled by a limited ACL + within the InfoPipe Daemon. --> + <policy context="default"> + <allow send_destination="org.freedesktop.sssd.infopipe" + send_interface="org.freedesktop.DBus.Introspectable"/> + + <allow send_destination="org.freedesktop.sssd.infopipe" + send_interface="org.freedesktop.DBus.Properties" + send_member="GetAll"/> + <allow send_destination="org.freedesktop.sssd.infopipe" + send_interface="org.freedesktop.DBus.Properties" + send_member="Get"/> + <allow send_destination="org.freedesktop.sssd.infopipe" + send_interface="org.freedesktop.DBus.Properties" + send_member="Set"/> + + <allow send_interface="org.freedesktop.sssd.infopipe"/> + <allow send_interface="org.freedesktop.sssd.infopipe.Domains"/> + <allow send_interface="org.freedesktop.sssd.infopipe.Domains.Domain"/> + <allow send_interface="org.freedesktop.sssd.infopipe.Users"/> + <allow send_interface="org.freedesktop.sssd.infopipe.Users.User"/> + <allow send_interface="org.freedesktop.sssd.infopipe.Groups"/> + <allow send_interface="org.freedesktop.sssd.infopipe.Groups.Group"/> + <allow send_interface="org.freedesktop.sssd.infopipe.Cache"/> + <allow send_interface="org.freedesktop.sssd.infopipe.Cache.Object"/> + </policy> + + <policy user="root"> + <allow send_interface="org.freedesktop.sssd.infopipe.Components"/> + </policy> + +</busconfig> diff --git a/src/responder/ifp/org.freedesktop.sssd.infopipe.service b/src/responder/ifp/org.freedesktop.sssd.infopipe.service new file mode 100644 index 0000000..b5d5435 --- /dev/null +++ b/src/responder/ifp/org.freedesktop.sssd.infopipe.service @@ -0,0 +1,6 @@ +[D-BUS Service] +Name=org.freedesktop.sssd.infopipe +# "sss_signal" is used to force SSSD monitor to trigger "sssd_ifp" reconnection to dbus +Exec=/usr/local/libexec/sssd/sss_signal +User=root + diff --git a/src/responder/ifp/org.freedesktop.sssd.infopipe.service.in b/src/responder/ifp/org.freedesktop.sssd.infopipe.service.in new file mode 100644 index 0000000..ca06cb1 --- /dev/null +++ b/src/responder/ifp/org.freedesktop.sssd.infopipe.service.in @@ -0,0 +1,6 @@ +[D-BUS Service] +Name=org.freedesktop.sssd.infopipe +@ifp_dbus_exec_comment@ +Exec=@ifp_exec_cmd@ +User=root +@ifp_systemdservice@ |