From d3c82d0170d6d7407549afdadd08aa7e11aeb9a2 Mon Sep 17 00:00:00 2001 From: Pavel Březina Date: Tue, 2 Jun 2015 11:12:15 +0200 Subject: IFP: Implement org.freedesktop.sssd.infopipe.Cache[.Object] Resolves: https://fedorahosted.org/sssd/ticket/2338 Example use: $ dbus-send --print-reply --system \ --dest=org.freedesktop.sssd.infopipe \ /org/freedesktop/sssd/infopipe/Users \ org.freedesktop.sssd.infopipe.Users.FindByName \ string:admin object path "/org/freedesktop/sssd/infopipe/Users/ipaldap/397400000" $ dbus-send --print-reply --system \ --dest=org.freedesktop.sssd.infopipe \ /org/freedesktop/sssd/infopipe/Users \ org.freedesktop.sssd.infopipe.Cache.List array [ ] $ dbus-send --print-reply --system \ --dest=org.freedesktop.sssd.infopipe \ /org/freedesktop/sssd/infopipe/Users/ipaldap/397400000 \ org.freedesktop.sssd.infopipe.Cache.Object.Store boolean true $ dbus-send --print-reply --system \ --dest=org.freedesktop.sssd.infopipe \ /org/freedesktop/sssd/infopipe/Users \ org.freedesktop.sssd.infopipe.Cache.List array [ object path "/org/freedesktop/sssd/infopipe/Users/ipaldap/397400000" ] $ dbus-send --print-reply --system \ --dest=org.freedesktop.sssd.infopipe \ /org/freedesktop/sssd/infopipe/Users/ipaldap/397400000 \ org.freedesktop.sssd.infopipe.Cache.Object.Remove boolean true $ dbus-send --print-reply --system \ --dest=org.freedesktop.sssd.infopipe \ /org/freedesktop/sssd/infopipe/Users \ org.freedesktop.sssd.infopipe.Cache.List array [ ] Reviewed-by: Jakub Hrozek --- Makefile.am | 2 + src/db/sysdb.h | 1 + src/responder/ifp/ifp_cache.c | 306 +++++++++++++++++++++ src/responder/ifp/ifp_cache.h | 53 ++++ src/responder/ifp/ifp_groups.c | 52 ++++ src/responder/ifp/ifp_groups.h | 17 ++ src/responder/ifp/ifp_iface.c | 28 ++ src/responder/ifp/ifp_iface.xml | 23 ++ src/responder/ifp/ifp_iface_generated.c | 116 ++++++++ src/responder/ifp/ifp_iface_generated.h | 42 +++ src/responder/ifp/ifp_users.c | 52 ++++ src/responder/ifp/ifp_users.h | 17 ++ .../ifp/org.freedesktop.sssd.infopipe.conf | 2 + 13 files changed, 711 insertions(+) create mode 100644 src/responder/ifp/ifp_cache.c create mode 100644 src/responder/ifp/ifp_cache.h diff --git a/Makefile.am b/Makefile.am index c21c1f3e9..bad92e060 100644 --- a/Makefile.am +++ b/Makefile.am @@ -552,6 +552,7 @@ dist_noinst_HEADERS = \ src/responder/ifp/ifp_components.h \ src/responder/ifp/ifp_users.h \ src/responder/ifp/ifp_groups.h \ + src/responder/ifp/ifp_cache.h \ src/sbus/sbus_client.h \ src/sbus/sssd_dbus.h \ src/sbus/sssd_dbus_meta.h \ @@ -1106,6 +1107,7 @@ sssd_ifp_SOURCES = \ src/responder/ifp/ifp_components.c \ src/responder/ifp/ifp_users.c \ src/responder/ifp/ifp_groups.c \ + src/responder/ifp/ifp_cache.c \ $(SSSD_UTIL_OBJ) \ $(SSSD_RESPONDER_OBJ) sssd_ifp_CFLAGS = \ diff --git a/src/db/sysdb.h b/src/db/sysdb.h index f667977ed..63cfa5f7d 100644 --- a/src/db/sysdb.h +++ b/src/db/sysdb.h @@ -91,6 +91,7 @@ #define SYSDB_LAST_UPDATE "lastUpdate" #define SYSDB_CACHE_EXPIRE "dataExpireTimestamp" #define SYSDB_INITGR_EXPIRE "initgrExpireTimestamp" +#define SYSDB_IFP_CACHED "ifpCached" #define SYSDB_AUTHORIZED_SERVICE "authorizedService" #define SYSDB_AUTHORIZED_HOST "authorizedHost" diff --git a/src/responder/ifp/ifp_cache.c b/src/responder/ifp/ifp_cache.c new file mode 100644 index 000000000..35d51ab2c --- /dev/null +++ b/src/responder/ifp/ifp_cache.c @@ -0,0 +1,306 @@ +/* + Authors: + Pavel Březina + + 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 . +*/ + +#include +#include + +#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" +#include "responder/ifp/ifp_iface_generated.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; + + 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; + + 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, + int *_num_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_OBJECTCLASS, 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, + "(&(objectClass=%s)(%s=TRUE))", class, + SYSDB_IFP_CACHED); + if (ldb_ret != LDB_SUCCESS) { + DEBUG(SSSDBG_CRIT_FAILURE, "Unable to search the cache\n"); + ret = sysdb_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); + *_num_paths = result->count; + + ret = EOK; + +done: + talloc_free(tmp_ctx); + return ret; +} + +int ifp_cache_list(struct sbus_request *sbus_req, + void *data, + enum ifp_cache_type type) +{ + DBusError *error; + struct sss_domain_info *domain; + struct ifp_ctx *ifp_ctx; + const char **tmp_paths; + int num_tmp_paths; + const char **paths; + int num_paths; + errno_t ret; + + ifp_ctx = talloc_get_type(data, struct ifp_ctx); + if (ifp_ctx == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "Invalid pointer!\n"); + return ERR_INTERNAL; + } + + domain = ifp_ctx->rctx->domains; + num_paths = 0; + paths = NULL; + while (domain != NULL) { + ret = ifp_cache_get_cached_objects(sbus_req, type, domain, + &tmp_paths, &num_tmp_paths); + if (ret != EOK) { + error = sbus_error_new(sbus_req, DBUS_ERROR_FAILED, + "Unable to build object list [%d]: %s\n", + ret, sss_strerror(ret)); + return sbus_request_fail_and_finish(sbus_req, error); + } + + ret = add_strings_lists(sbus_req, paths, tmp_paths, false, + discard_const(&paths)); + if (ret != EOK) { + error = sbus_error_new(sbus_req, DBUS_ERROR_FAILED, + "Unable to build object list [%d]: %s\n", + ret, sss_strerror(ret)); + return sbus_request_fail_and_finish(sbus_req, error); + } + + num_paths += num_tmp_paths; + + domain = get_next_domain(domain, true); + } + + iface_ifp_cache_List_finish(sbus_req, paths, num_paths); + + return EOK; +} + +int ifp_cache_list_by_domain(struct sbus_request *sbus_req, + void *data, + const char *domainname, + enum ifp_cache_type type) +{ + DBusError *error; + struct sss_domain_info *domain; + struct ifp_ctx *ifp_ctx; + const char **paths; + int num_paths; + errno_t ret; + + ifp_ctx = talloc_get_type(data, struct ifp_ctx); + if (ifp_ctx == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "Invalid pointer!\n"); + return ERR_INTERNAL; + } + + domain = find_domain_by_name(ifp_ctx->rctx->domains, domainname, true); + if (domain == NULL) { + error = sbus_error_new(sbus_req, DBUS_ERROR_FAILED, "Unknown domain"); + return sbus_request_fail_and_finish(sbus_req, error); + } + + ret = ifp_cache_get_cached_objects(sbus_req, type, domain, + &paths, &num_paths); + if (ret != EOK) { + error = sbus_error_new(sbus_req, DBUS_ERROR_FAILED, "Unable to build " + "object list [%d]: %s\n", ret, sss_strerror(ret)); + return sbus_request_fail_and_finish(sbus_req, error); + } + + iface_ifp_cache_ListByDomain_finish(sbus_req, paths, num_paths); + + return EOK; +} + +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; +} + +int ifp_cache_object_store(struct sbus_request *sbus_req, + struct sss_domain_info *domain, + struct ldb_dn *dn) +{ + errno_t ret; + + ret = ifp_cache_object_set(domain, dn, true); + + if (ret == EOK) { + iface_ifp_cache_object_Store_finish(sbus_req, true); + } else { + iface_ifp_cache_object_Store_finish(sbus_req, false); + } + + return EOK; +} + +int ifp_cache_object_remove(struct sbus_request *sbus_req, + struct sss_domain_info *domain, + struct ldb_dn *dn) +{ + errno_t ret; + + ret = ifp_cache_object_set(domain, dn, false); + + if (ret == EOK) { + iface_ifp_cache_object_Remove_finish(sbus_req, true); + } else { + iface_ifp_cache_object_Remove_finish(sbus_req, false); + } + + return EOK; +} diff --git a/src/responder/ifp/ifp_cache.h b/src/responder/ifp/ifp_cache.h new file mode 100644 index 000000000..56e90bb9c --- /dev/null +++ b/src/responder/ifp/ifp_cache.h @@ -0,0 +1,53 @@ +/* + Authors: + Pavel Březina + + 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 . +*/ + +#ifndef IFP_CACHE_H_ +#define IFP_CACHE_H_ + +#include "responder/common/responder.h" +#include "responder/ifp/ifp_iface_generated.h" + +/* org.freedesktop-sssd-infopipe.Cache */ + +enum ifp_cache_type { + IFP_CACHE_USER, + IFP_CACHE_GROUP +}; + +int ifp_cache_list(struct sbus_request *sbus_req, + void *data, + enum ifp_cache_type type); + +int ifp_cache_list_by_domain(struct sbus_request *sbus_req, + void *data, + const char *domain, + enum ifp_cache_type type); + +/* org.freedesktop-sssd-infopipe.Cache.Object */ + +int ifp_cache_object_store(struct sbus_request *sbus_req, + struct sss_domain_info *domain, + struct ldb_dn *dn); + +int ifp_cache_object_remove(struct sbus_request *sbus_req, + struct sss_domain_info *domain, + struct ldb_dn *dn); + +#endif /* IFP_CACHE_H_ */ diff --git a/src/responder/ifp/ifp_groups.c b/src/responder/ifp/ifp_groups.c index f1f86ce1a..1b581b568 100644 --- a/src/responder/ifp/ifp_groups.c +++ b/src/responder/ifp/ifp_groups.c @@ -29,6 +29,7 @@ #include "responder/common/responder_cache_req.h" #include "responder/ifp/ifp_groups.h" #include "responder/ifp/ifp_users.h" +#include "responder/ifp/ifp_cache.h" char * ifp_groups_build_path_from_msg(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, @@ -720,3 +721,54 @@ void ifp_groups_group_get_groups(struct sbus_request *sbus_req, DEBUG(SSSDBG_CRIT_FAILURE, "Unable to acquire groups members\n"); } } + +int ifp_cache_list_group(struct sbus_request *sbus_req, + void *data) +{ + return ifp_cache_list(sbus_req, data, IFP_CACHE_GROUP); +} + +int ifp_cache_list_by_domain_group(struct sbus_request *sbus_req, + void *data, + const char *domain) +{ + return ifp_cache_list_by_domain(sbus_req, data, domain, IFP_CACHE_GROUP); +} + +int ifp_cache_object_store_group(struct sbus_request *sbus_req, + void *data) +{ + DBusError *error; + struct sss_domain_info *domain; + struct ldb_message *group; + errno_t ret; + + ret = ifp_groups_group_get(sbus_req, data, NULL, &domain, &group); + if (ret != EOK) { + error = sbus_error_new(sbus_req, DBUS_ERROR_FAILED, "Failed to fetch " + "group [%d]: %s\n", ret, sss_strerror(ret)); + return sbus_request_fail_and_finish(sbus_req, error); + } + + /* The request is finished inside. */ + return ifp_cache_object_store(sbus_req, domain, group->dn); +} + +int ifp_cache_object_remove_group(struct sbus_request *sbus_req, + void *data) +{ + DBusError *error; + struct sss_domain_info *domain; + struct ldb_message *group; + errno_t ret; + + ret = ifp_groups_group_get(sbus_req, data, NULL, &domain, &group); + if (ret != EOK) { + error = sbus_error_new(sbus_req, DBUS_ERROR_FAILED, "Failed to fetch " + "group [%d]: %s\n", ret, sss_strerror(ret)); + return sbus_request_fail_and_finish(sbus_req, error); + } + + /* The request is finished inside. */ + return ifp_cache_object_remove(sbus_req, domain, group->dn); +} diff --git a/src/responder/ifp/ifp_groups.h b/src/responder/ifp/ifp_groups.h index 0474ca44f..09c5a1c88 100644 --- a/src/responder/ifp/ifp_groups.h +++ b/src/responder/ifp/ifp_groups.h @@ -77,4 +77,21 @@ void ifp_groups_group_get_groups(struct sbus_request *sbus_req, const char ***_out, int *_size); +/* org.freedesktop.sssd.infopipe.Cache */ + +int ifp_cache_list_group(struct sbus_request *sbus_req, + void *data); + +int ifp_cache_list_by_domain_group(struct sbus_request *sbus_req, + void *data, + const char *domain); + +/* org.freedesktop.sssd.infopipe.Cache.Object */ + +int ifp_cache_object_store_group(struct sbus_request *sbus_req, + void *data); + +int ifp_cache_object_remove_group(struct sbus_request *sbus_req, + void *data); + #endif /* IFP_GROUPS_H_ */ diff --git a/src/responder/ifp/ifp_iface.c b/src/responder/ifp/ifp_iface.c index ce987b607..015c66dc5 100644 --- a/src/responder/ifp/ifp_iface.c +++ b/src/responder/ifp/ifp_iface.c @@ -116,6 +116,30 @@ struct iface_ifp_groups_group iface_ifp_groups_group = { .get_groups = ifp_groups_group_get_groups }; +struct iface_ifp_cache iface_ifp_cache_user = { + { &iface_ifp_cache_meta, 0 }, + .List = ifp_cache_list_user, + .ListByDomain = ifp_cache_list_by_domain_user +}; + +struct iface_ifp_cache_object iface_ifp_cache_object_user = { + { &iface_ifp_cache_object_meta, 0 }, + .Store = ifp_cache_object_store_user, + .Remove = ifp_cache_object_remove_user +}; + +struct iface_ifp_cache iface_ifp_cache_group = { + { &iface_ifp_cache_meta, 0 }, + .List = ifp_cache_list_group, + .ListByDomain = ifp_cache_list_by_domain_group +}; + +struct iface_ifp_cache_object iface_ifp_cache_object_group = { + { &iface_ifp_cache_object_meta, 0 }, + .Store = ifp_cache_object_store_group, + .Remove = ifp_cache_object_remove_group +}; + struct iface_map { const char *path; struct sbus_vtable *vtable; @@ -126,9 +150,13 @@ static struct iface_map iface_map[] = { { IFP_PATH_DOMAINS_TREE, &iface_ifp_domains.vtable }, { IFP_PATH_COMPONENTS_TREE, &iface_ifp_components.vtable }, { IFP_PATH_USERS, &iface_ifp_users.vtable }, + { IFP_PATH_USERS, &iface_ifp_cache_user.vtable }, { IFP_PATH_USERS_TREE, &iface_ifp_users_user.vtable }, + { IFP_PATH_USERS_TREE, &iface_ifp_cache_object_user.vtable }, { IFP_PATH_GROUPS, &iface_ifp_groups.vtable }, + { IFP_PATH_GROUPS, &iface_ifp_cache_group.vtable }, { IFP_PATH_GROUPS_TREE, &iface_ifp_groups_group.vtable }, + { IFP_PATH_GROUPS_TREE, &iface_ifp_cache_object_group.vtable }, { NULL, NULL }, }; diff --git a/src/responder/ifp/ifp_iface.xml b/src/responder/ifp/ifp_iface.xml index fbd3d3f5a..628692af6 100644 --- a/src/responder/ifp/ifp_iface.xml +++ b/src/responder/ifp/ifp_iface.xml @@ -102,6 +102,29 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/responder/ifp/ifp_iface_generated.c b/src/responder/ifp/ifp_iface_generated.c index ff00be8ea..8255cbea7 100644 --- a/src/responder/ifp/ifp_iface_generated.c +++ b/src/responder/ifp/ifp_iface_generated.c @@ -531,6 +531,122 @@ const struct sbus_interface_meta iface_ifp_domains_meta = { sbus_invoke_get_all, /* GetAll invoker */ }; +/* arguments for org.freedesktop.sssd.infopipe.Cache.List */ +const struct sbus_arg_meta iface_ifp_cache_List__out[] = { + { "result", "ao" }, + { NULL, } +}; + +int iface_ifp_cache_List_finish(struct sbus_request *req, const char *arg_result[], int len_result) +{ + return sbus_request_return_and_finish(req, + DBUS_TYPE_ARRAY, DBUS_TYPE_OBJECT_PATH, &arg_result, len_result, + DBUS_TYPE_INVALID); +} + +/* arguments for org.freedesktop.sssd.infopipe.Cache.ListByDomain */ +const struct sbus_arg_meta iface_ifp_cache_ListByDomain__in[] = { + { "domain_name", "s" }, + { NULL, } +}; + +/* arguments for org.freedesktop.sssd.infopipe.Cache.ListByDomain */ +const struct sbus_arg_meta iface_ifp_cache_ListByDomain__out[] = { + { "result", "ao" }, + { NULL, } +}; + +int iface_ifp_cache_ListByDomain_finish(struct sbus_request *req, const char *arg_result[], int len_result) +{ + return sbus_request_return_and_finish(req, + DBUS_TYPE_ARRAY, DBUS_TYPE_OBJECT_PATH, &arg_result, len_result, + DBUS_TYPE_INVALID); +} + +/* methods for org.freedesktop.sssd.infopipe.Cache */ +const struct sbus_method_meta iface_ifp_cache__methods[] = { + { + "List", /* name */ + NULL, /* no in_args */ + iface_ifp_cache_List__out, + offsetof(struct iface_ifp_cache, List), + NULL, /* no invoker */ + }, + { + "ListByDomain", /* name */ + iface_ifp_cache_ListByDomain__in, + iface_ifp_cache_ListByDomain__out, + offsetof(struct iface_ifp_cache, ListByDomain), + invoke_s_method, + }, + { NULL, } +}; + +/* interface info for org.freedesktop.sssd.infopipe.Cache */ +const struct sbus_interface_meta iface_ifp_cache_meta = { + "org.freedesktop.sssd.infopipe.Cache", /* name */ + iface_ifp_cache__methods, + NULL, /* no signals */ + NULL, /* no properties */ + sbus_invoke_get_all, /* GetAll invoker */ +}; + +/* arguments for org.freedesktop.sssd.infopipe.Cache.Object.Store */ +const struct sbus_arg_meta iface_ifp_cache_object_Store__out[] = { + { "result", "b" }, + { NULL, } +}; + +int iface_ifp_cache_object_Store_finish(struct sbus_request *req, bool arg_result) +{ + dbus_bool_t cast_result = arg_result; + return sbus_request_return_and_finish(req, + DBUS_TYPE_BOOLEAN, &cast_result, + DBUS_TYPE_INVALID); +} + +/* arguments for org.freedesktop.sssd.infopipe.Cache.Object.Remove */ +const struct sbus_arg_meta iface_ifp_cache_object_Remove__out[] = { + { "result", "b" }, + { NULL, } +}; + +int iface_ifp_cache_object_Remove_finish(struct sbus_request *req, bool arg_result) +{ + dbus_bool_t cast_result = arg_result; + return sbus_request_return_and_finish(req, + DBUS_TYPE_BOOLEAN, &cast_result, + DBUS_TYPE_INVALID); +} + +/* methods for org.freedesktop.sssd.infopipe.Cache.Object */ +const struct sbus_method_meta iface_ifp_cache_object__methods[] = { + { + "Store", /* name */ + NULL, /* no in_args */ + iface_ifp_cache_object_Store__out, + offsetof(struct iface_ifp_cache_object, Store), + NULL, /* no invoker */ + }, + { + "Remove", /* name */ + NULL, /* no in_args */ + iface_ifp_cache_object_Remove__out, + offsetof(struct iface_ifp_cache_object, Remove), + NULL, /* no invoker */ + }, + { NULL, } +}; + +/* interface info for org.freedesktop.sssd.infopipe.Cache.Object */ +const struct sbus_interface_meta iface_ifp_cache_object_meta = { + "org.freedesktop.sssd.infopipe.Cache.Object", /* name */ + iface_ifp_cache_object__methods, + NULL, /* no signals */ + NULL, /* no properties */ + sbus_invoke_get_all, /* GetAll invoker */ +}; + /* arguments for org.freedesktop.sssd.infopipe.Users.FindByName */ const struct sbus_arg_meta iface_ifp_users_FindByName__in[] = { { "name", "s" }, diff --git a/src/responder/ifp/ifp_iface_generated.h b/src/responder/ifp/ifp_iface_generated.h index 1bd2a448f..d2e5cdd3a 100644 --- a/src/responder/ifp/ifp_iface_generated.h +++ b/src/responder/ifp/ifp_iface_generated.h @@ -54,6 +54,16 @@ #define IFACE_IFP_DOMAINS_SUBDOMAIN "subdomain" #define IFACE_IFP_DOMAINS_PARENT_DOMAIN "parent_domain" +/* constants for org.freedesktop.sssd.infopipe.Cache */ +#define IFACE_IFP_CACHE "org.freedesktop.sssd.infopipe.Cache" +#define IFACE_IFP_CACHE_LIST "List" +#define IFACE_IFP_CACHE_LISTBYDOMAIN "ListByDomain" + +/* constants for org.freedesktop.sssd.infopipe.Cache.Object */ +#define IFACE_IFP_CACHE_OBJECT "org.freedesktop.sssd.infopipe.Cache.Object" +#define IFACE_IFP_CACHE_OBJECT_STORE "Store" +#define IFACE_IFP_CACHE_OBJECT_REMOVE "Remove" + /* constants for org.freedesktop.sssd.infopipe.Users */ #define IFACE_IFP_USERS "org.freedesktop.sssd.infopipe.Users" #define IFACE_IFP_USERS_FINDBYNAME "FindByName" @@ -194,6 +204,32 @@ struct iface_ifp_domains { void (*get_parent_domain)(struct sbus_request *, void *data, const char **); }; +/* vtable for org.freedesktop.sssd.infopipe.Cache */ +struct iface_ifp_cache { + struct sbus_vtable vtable; /* derive from sbus_vtable */ + int (*List)(struct sbus_request *req, void *data); + int (*ListByDomain)(struct sbus_request *req, void *data, const char *arg_domain_name); +}; + +/* finish function for List */ +int iface_ifp_cache_List_finish(struct sbus_request *req, const char *arg_result[], int len_result); + +/* finish function for ListByDomain */ +int iface_ifp_cache_ListByDomain_finish(struct sbus_request *req, const char *arg_result[], int len_result); + +/* vtable for org.freedesktop.sssd.infopipe.Cache.Object */ +struct iface_ifp_cache_object { + struct sbus_vtable vtable; /* derive from sbus_vtable */ + int (*Store)(struct sbus_request *req, void *data); + int (*Remove)(struct sbus_request *req, void *data); +}; + +/* finish function for Store */ +int iface_ifp_cache_object_Store_finish(struct sbus_request *req, bool arg_result); + +/* finish function for Remove */ +int iface_ifp_cache_object_Remove_finish(struct sbus_request *req, bool arg_result); + /* vtable for org.freedesktop.sssd.infopipe.Users */ struct iface_ifp_users { struct sbus_vtable vtable; /* derive from sbus_vtable */ @@ -285,6 +321,12 @@ extern const struct sbus_interface_meta iface_ifp_components_meta; /* interface info for org.freedesktop.sssd.infopipe.Domains */ extern const struct sbus_interface_meta iface_ifp_domains_meta; +/* interface info for org.freedesktop.sssd.infopipe.Cache */ +extern const struct sbus_interface_meta iface_ifp_cache_meta; + +/* interface info for org.freedesktop.sssd.infopipe.Cache.Object */ +extern const struct sbus_interface_meta iface_ifp_cache_object_meta; + /* interface info for org.freedesktop.sssd.infopipe.Users */ extern const struct sbus_interface_meta iface_ifp_users_meta; diff --git a/src/responder/ifp/ifp_users.c b/src/responder/ifp/ifp_users.c index 26c1aa696..fa6f47f0d 100644 --- a/src/responder/ifp/ifp_users.c +++ b/src/responder/ifp/ifp_users.c @@ -30,6 +30,7 @@ #include "responder/common/responder_cache_req.h" #include "responder/ifp/ifp_users.h" #include "responder/ifp/ifp_groups.h" +#include "responder/ifp/ifp_cache.h" char * ifp_users_build_path_from_msg(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, @@ -659,3 +660,54 @@ void ifp_users_user_get_extra_attributes(struct sbus_request *sbus_req, *_out = table; } + +int ifp_cache_list_user(struct sbus_request *sbus_req, + void *data) +{ + return ifp_cache_list(sbus_req, data, IFP_CACHE_USER); +} + +int ifp_cache_list_by_domain_user(struct sbus_request *sbus_req, + void *data, + const char *domain) +{ + return ifp_cache_list_by_domain(sbus_req, data, domain, IFP_CACHE_USER); +} + +int ifp_cache_object_store_user(struct sbus_request *sbus_req, + void *data) +{ + DBusError *error; + struct sss_domain_info *domain; + struct ldb_message *user; + errno_t ret; + + ret = ifp_users_user_get(sbus_req, data, NULL, &domain, &user); + if (ret != EOK) { + error = sbus_error_new(sbus_req, DBUS_ERROR_FAILED, "Failed to fetch " + "user [%d]: %s\n", ret, sss_strerror(ret)); + return sbus_request_fail_and_finish(sbus_req, error); + } + + /* The request is finished inside. */ + return ifp_cache_object_store(sbus_req, domain, user->dn); +} + +int ifp_cache_object_remove_user(struct sbus_request *sbus_req, + void *data) +{ + DBusError *error; + struct sss_domain_info *domain; + struct ldb_message *user; + errno_t ret; + + ret = ifp_users_user_get(sbus_req, data, NULL, &domain, &user); + if (ret != EOK) { + error = sbus_error_new(sbus_req, DBUS_ERROR_FAILED, "Failed to fetch " + "user [%d]: %s\n", ret, sss_strerror(ret)); + return sbus_request_fail_and_finish(sbus_req, error); + } + + /* The request is finished inside. */ + return ifp_cache_object_remove(sbus_req, domain, user->dn); +} diff --git a/src/responder/ifp/ifp_users.h b/src/responder/ifp/ifp_users.h index 7027ef14e..4da0a7347 100644 --- a/src/responder/ifp/ifp_users.h +++ b/src/responder/ifp/ifp_users.h @@ -92,4 +92,21 @@ void ifp_users_user_get_extra_attributes(struct sbus_request *sbus_req, void *data, hash_table_t **_out); +/* org.freedesktop.sssd.infopipe.Cache */ + +int ifp_cache_list_user(struct sbus_request *sbus_req, + void *data); + +int ifp_cache_list_by_domain_user(struct sbus_request *sbus_req, + void *data, + const char *domain); + +/* org.freedesktop.sssd.infopipe.Cache.Object */ + +int ifp_cache_object_store_user(struct sbus_request *sbus_req, + void *data); + +int ifp_cache_object_remove_user(struct sbus_request *sbus_req, + void *data); + #endif /* IFP_USERS_H_ */ diff --git a/src/responder/ifp/org.freedesktop.sssd.infopipe.conf b/src/responder/ifp/org.freedesktop.sssd.infopipe.conf index b8df49350..398f303f7 100644 --- a/src/responder/ifp/org.freedesktop.sssd.infopipe.conf +++ b/src/responder/ifp/org.freedesktop.sssd.infopipe.conf @@ -34,6 +34,8 @@ + + -- cgit