From c747b0c875785ce693f70b50bdda0237c4b04e35 Mon Sep 17 00:00:00 2001 From: Pavel Březina Date: Thu, 15 Jan 2015 13:52:31 +0100 Subject: IFP: add org.freedesktop.sssd.infopipe.Users Example calls: dbus-send --print-reply --system --dest=org.freedesktop.sssd.infopipe /org/freedesktop/sssd/infopipe/Users org.freedesktop.sssd.infopipe.Users.FindByName string:user-1 method return sender=:1.159 -> dest=:1.160 reply_serial=2 object path "/org/freedesktop/sssd/infopipe/Users/LDAP_2ePB/10001" dbus-send --print-reply --system --dest=org.freedesktop.sssd.infopipe /org/freedesktop/sssd/infopipe/Users org.freedesktop.sssd.infopipe.Users.FindByID uint32:10001 method return sender=:1.159 -> dest=:1.163 reply_serial=2 object path "/org/freedesktop/sssd/infopipe/Users/LDAP_2ePB/1000 Resolves: https://fedorahosted.org/sssd/ticket/2150 Reviewed-by: Jakub Hrozek --- src/responder/ifp/ifp_iface.c | 10 + src/responder/ifp/ifp_iface.xml | 24 +++ src/responder/ifp/ifp_iface_generated.c | 168 +++++++++++++++++ src/responder/ifp/ifp_iface_generated.h | 31 ++++ src/responder/ifp/ifp_users.c | 202 +++++++++++++++++++++ src/responder/ifp/ifp_users.h | 57 ++++++ .../ifp/org.freedesktop.sssd.infopipe.conf | 1 + 7 files changed, 493 insertions(+) create mode 100644 src/responder/ifp/ifp_users.c create mode 100644 src/responder/ifp/ifp_users.h (limited to 'src/responder') diff --git a/src/responder/ifp/ifp_iface.c b/src/responder/ifp/ifp_iface.c index c82a2e65d..753bad126 100644 --- a/src/responder/ifp/ifp_iface.c +++ b/src/responder/ifp/ifp_iface.c @@ -24,6 +24,7 @@ #include "responder/ifp/ifp_iface_generated.h" #include "responder/ifp/ifp_domains.h" #include "responder/ifp/ifp_components.h" +#include "responder/ifp/ifp_users.h" struct iface_ifp iface_ifp = { { &iface_ifp_meta, 0 }, @@ -76,6 +77,14 @@ struct iface_ifp_domains iface_ifp_domains = { .get_parent_domain = ifp_dom_get_parent_domain }; +struct iface_ifp_users iface_ifp_users = { + { &iface_ifp_users_meta, 0 }, + .FindByName = ifp_users_find_by_name, + .FindByID = ifp_users_find_by_id, + .ListByName = ifp_users_list_by_name, + .ListByDomainAndName = ifp_users_list_by_domain_and_name +}; + struct iface_map { const char *path; struct sbus_vtable *vtable; @@ -85,6 +94,7 @@ static struct iface_map iface_map[] = { { IFP_PATH, &iface_ifp.vtable }, { IFP_PATH_DOMAINS_TREE, &iface_ifp_domains.vtable }, { IFP_PATH_COMPONENTS_TREE, &iface_ifp_components.vtable }, + { IFP_PATH_USERS, &iface_ifp_users.vtable }, { NULL, NULL }, }; diff --git a/src/responder/ifp/ifp_iface.xml b/src/responder/ifp/ifp_iface.xml index 81d4dbf8b..d0c835949 100644 --- a/src/responder/ifp/ifp_iface.xml +++ b/src/responder/ifp/ifp_iface.xml @@ -101,4 +101,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/responder/ifp/ifp_iface_generated.c b/src/responder/ifp/ifp_iface_generated.c index 9c00a8c59..40a416bc4 100644 --- a/src/responder/ifp/ifp_iface_generated.c +++ b/src/responder/ifp/ifp_iface_generated.c @@ -12,6 +12,12 @@ static int invoke_s_method(struct sbus_request *dbus_req, void *function_ptr); /* invokes a handler with a 'u' DBus signature */ static int invoke_u_method(struct sbus_request *dbus_req, void *function_ptr); +/* invokes a handler with a 'su' DBus signature */ +static int invoke_su_method(struct sbus_request *dbus_req, void *function_ptr); + +/* invokes a handler with a 'ssu' DBus signature */ +static int invoke_ssu_method(struct sbus_request *dbus_req, void *function_ptr); + /* arguments for org.freedesktop.sssd.infopipe.ListComponents */ const struct sbus_arg_meta iface_ifp_ListComponents__out[] = { { "components", "ao" }, @@ -525,6 +531,149 @@ const struct sbus_interface_meta iface_ifp_domains_meta = { 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" }, + { NULL, } +}; + +/* arguments for org.freedesktop.sssd.infopipe.Users.FindByName */ +const struct sbus_arg_meta iface_ifp_users_FindByName__out[] = { + { "result", "o" }, + { NULL, } +}; + +int iface_ifp_users_FindByName_finish(struct sbus_request *req, const char *arg_result) +{ + return sbus_request_return_and_finish(req, + DBUS_TYPE_OBJECT_PATH, &arg_result, + DBUS_TYPE_INVALID); +} + +/* arguments for org.freedesktop.sssd.infopipe.Users.FindByID */ +const struct sbus_arg_meta iface_ifp_users_FindByID__in[] = { + { "id", "u" }, + { NULL, } +}; + +/* arguments for org.freedesktop.sssd.infopipe.Users.FindByID */ +const struct sbus_arg_meta iface_ifp_users_FindByID__out[] = { + { "result", "o" }, + { NULL, } +}; + +int iface_ifp_users_FindByID_finish(struct sbus_request *req, const char *arg_result) +{ + return sbus_request_return_and_finish(req, + DBUS_TYPE_OBJECT_PATH, &arg_result, + DBUS_TYPE_INVALID); +} + +/* arguments for org.freedesktop.sssd.infopipe.Users.ListByName */ +const struct sbus_arg_meta iface_ifp_users_ListByName__in[] = { + { "name_filter", "s" }, + { "limit", "u" }, + { NULL, } +}; + +/* arguments for org.freedesktop.sssd.infopipe.Users.ListByName */ +const struct sbus_arg_meta iface_ifp_users_ListByName__out[] = { + { "result", "ao" }, + { NULL, } +}; + +int iface_ifp_users_ListByName_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.Users.ListByDomainAndName */ +const struct sbus_arg_meta iface_ifp_users_ListByDomainAndName__in[] = { + { "domain_name", "s" }, + { "name_filter", "s" }, + { "limit", "u" }, + { NULL, } +}; + +/* arguments for org.freedesktop.sssd.infopipe.Users.ListByDomainAndName */ +const struct sbus_arg_meta iface_ifp_users_ListByDomainAndName__out[] = { + { "result", "ao" }, + { NULL, } +}; + +int iface_ifp_users_ListByDomainAndName_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.Users */ +const struct sbus_method_meta iface_ifp_users__methods[] = { + { + "FindByName", /* name */ + iface_ifp_users_FindByName__in, + iface_ifp_users_FindByName__out, + offsetof(struct iface_ifp_users, FindByName), + invoke_s_method, + }, + { + "FindByID", /* name */ + iface_ifp_users_FindByID__in, + iface_ifp_users_FindByID__out, + offsetof(struct iface_ifp_users, FindByID), + invoke_u_method, + }, + { + "ListByName", /* name */ + iface_ifp_users_ListByName__in, + iface_ifp_users_ListByName__out, + offsetof(struct iface_ifp_users, ListByName), + invoke_su_method, + }, + { + "ListByDomainAndName", /* name */ + iface_ifp_users_ListByDomainAndName__in, + iface_ifp_users_ListByDomainAndName__out, + offsetof(struct iface_ifp_users, ListByDomainAndName), + invoke_ssu_method, + }, + { NULL, } +}; + +/* interface info for org.freedesktop.sssd.infopipe.Users */ +const struct sbus_interface_meta iface_ifp_users_meta = { + "org.freedesktop.sssd.infopipe.Users", /* name */ + iface_ifp_users__methods, + NULL, /* no signals */ + NULL, /* no properties */ + sbus_invoke_get_all, /* GetAll invoker */ +}; + +/* invokes a handler with a 'ssu' DBus signature */ +static int invoke_ssu_method(struct sbus_request *dbus_req, void *function_ptr) +{ + const char * arg_0; + const char * arg_1; + uint32_t arg_2; + int (*handler)(struct sbus_request *, void *, const char *, const char *, uint32_t) = function_ptr; + + if (!sbus_request_parse_or_finish(dbus_req, + DBUS_TYPE_STRING, &arg_0, + DBUS_TYPE_STRING, &arg_1, + DBUS_TYPE_UINT32, &arg_2, + DBUS_TYPE_INVALID)) { + return EOK; /* request handled */ + } + + return (handler)(dbus_req, dbus_req->intf->handler_data, + arg_0, + arg_1, + arg_2); +} + /* invokes a handler with a 's' DBus signature */ static int invoke_s_method(struct sbus_request *dbus_req, void *function_ptr) { @@ -556,3 +705,22 @@ static int invoke_u_method(struct sbus_request *dbus_req, void *function_ptr) return (handler)(dbus_req, dbus_req->intf->handler_data, arg_0); } + +/* invokes a handler with a 'su' DBus signature */ +static int invoke_su_method(struct sbus_request *dbus_req, void *function_ptr) +{ + const char * arg_0; + uint32_t arg_1; + int (*handler)(struct sbus_request *, void *, const char *, uint32_t) = function_ptr; + + if (!sbus_request_parse_or_finish(dbus_req, + DBUS_TYPE_STRING, &arg_0, + DBUS_TYPE_UINT32, &arg_1, + DBUS_TYPE_INVALID)) { + return EOK; /* request handled */ + } + + return (handler)(dbus_req, dbus_req->intf->handler_data, + arg_0, + arg_1); +} diff --git a/src/responder/ifp/ifp_iface_generated.h b/src/responder/ifp/ifp_iface_generated.h index e2f5a7eaf..83ac75b06 100644 --- a/src/responder/ifp/ifp_iface_generated.h +++ b/src/responder/ifp/ifp_iface_generated.h @@ -54,6 +54,13 @@ #define IFACE_IFP_DOMAINS_SUBDOMAIN "subdomain" #define IFACE_IFP_DOMAINS_PARENT_DOMAIN "parent_domain" +/* constants for org.freedesktop.sssd.infopipe.Users */ +#define IFACE_IFP_USERS "org.freedesktop.sssd.infopipe.Users" +#define IFACE_IFP_USERS_FINDBYNAME "FindByName" +#define IFACE_IFP_USERS_FINDBYID "FindByID" +#define IFACE_IFP_USERS_LISTBYNAME "ListByName" +#define IFACE_IFP_USERS_LISTBYDOMAINANDNAME "ListByDomainAndName" + /* ------------------------------------------------------------------------ * DBus handlers * @@ -160,6 +167,27 @@ struct iface_ifp_domains { void (*get_parent_domain)(struct sbus_request *, void *data, const char * *); }; +/* vtable for org.freedesktop.sssd.infopipe.Users */ +struct iface_ifp_users { + struct sbus_vtable vtable; /* derive from sbus_vtable */ + int (*FindByName)(struct sbus_request *req, void *data, const char *arg_name); + int (*FindByID)(struct sbus_request *req, void *data, uint32_t arg_id); + int (*ListByName)(struct sbus_request *req, void *data, const char *arg_name_filter, uint32_t arg_limit); + int (*ListByDomainAndName)(struct sbus_request *req, void *data, const char *arg_domain_name, const char *arg_name_filter, uint32_t arg_limit); +}; + +/* finish function for FindByName */ +int iface_ifp_users_FindByName_finish(struct sbus_request *req, const char *arg_result); + +/* finish function for FindByID */ +int iface_ifp_users_FindByID_finish(struct sbus_request *req, const char *arg_result); + +/* finish function for ListByName */ +int iface_ifp_users_ListByName_finish(struct sbus_request *req, const char *arg_result[], int len_result); + +/* finish function for ListByDomainAndName */ +int iface_ifp_users_ListByDomainAndName_finish(struct sbus_request *req, const char *arg_result[], int len_result); + /* ------------------------------------------------------------------------ * DBus Interface Metadata * @@ -179,4 +207,7 @@ 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.Users */ +extern const struct sbus_interface_meta iface_ifp_users_meta; + #endif /* __IFP_IFACE_XML__ */ diff --git a/src/responder/ifp/ifp_users.c b/src/responder/ifp/ifp_users.c new file mode 100644 index 000000000..04fabf77b --- /dev/null +++ b/src/responder/ifp/ifp_users.c @@ -0,0 +1,202 @@ +/* + 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 + +#include "db/sysdb.h" +#include "util/util.h" +#include "sbus/sssd_dbus_errors.h" +#include "responder/common/responder.h" +#include "responder/common/responder_cache_req.h" +#include "responder/ifp/ifp_users.h" + +char * ifp_users_build_path_from_msg(TALLOC_CTX *mem_ctx, + struct sss_domain_info *domain, + struct ldb_message *msg) +{ + const char *uid; + + uid = ldb_msg_find_attr_as_string(msg, SYSDB_UIDNUM, NULL); + + if (uid == NULL) { + return NULL; + } + + return sbus_opath_compose(mem_ctx, IFP_PATH_USERS, domain->name, uid); +} + +static void ifp_users_find_by_name_done(struct tevent_req *req); + +int ifp_users_find_by_name(struct sbus_request *sbus_req, + void *data, + const char *name) +{ + struct ifp_ctx *ctx; + struct tevent_req *req; + + ctx = talloc_get_type(data, struct ifp_ctx); + if (ctx == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "Invalid pointer!\n"); + return ERR_INTERNAL; + } + + req = cache_req_user_by_name_send(sbus_req, ctx->rctx->ev, ctx->rctx, + ctx->ncache, ctx->neg_timeout, 0, + NULL, name); + if (req == NULL) { + return ENOMEM; + } + + tevent_req_set_callback(req, ifp_users_find_by_name_done, sbus_req); + + return EOK; +} + +static void +ifp_users_find_by_name_done(struct tevent_req *req) +{ + DBusError *error; + struct sbus_request *sbus_req; + struct sss_domain_info *domain; + struct ldb_result *result; + char *object_path; + errno_t ret; + + sbus_req = tevent_req_callback_data(req, struct sbus_request); + + ret = cache_req_user_by_name_recv(sbus_req, req, &result, &domain, NULL); + talloc_zfree(req); + if (ret == ENOENT) { + error = sbus_error_new(sbus_req, SBUS_ERROR_NOT_FOUND, + "User not found"); + goto done; + } else if (ret != EOK) { + error = sbus_error_new(sbus_req, DBUS_ERROR_FAILED, "Failed to fetch " + "user [%d]: %s\n", ret, sss_strerror(ret)); + goto done; + } + + object_path = ifp_users_build_path_from_msg(sbus_req, domain, + result->msgs[0]); + if (object_path == NULL) { + error = sbus_error_new(sbus_req, SBUS_ERROR_INTERNAL, + "Failed to compose object path"); + goto done; + } + + ret = EOK; + +done: + if (ret != EOK) { + sbus_request_fail_and_finish(sbus_req, error); + return; + } + + iface_ifp_users_FindByName_finish(sbus_req, object_path); + return; +} + +static void ifp_users_find_by_id_done(struct tevent_req *req); + +int ifp_users_find_by_id(struct sbus_request *sbus_req, + void *data, + uint32_t id) +{ + struct ifp_ctx *ctx; + struct tevent_req *req; + + ctx = talloc_get_type(data, struct ifp_ctx); + if (ctx == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "Invalid pointer!\n"); + return ERR_INTERNAL; + } + + req = cache_req_user_by_id_send(sbus_req, ctx->rctx->ev, ctx->rctx, + ctx->ncache, ctx->neg_timeout, 0, + NULL, id); + if (req == NULL) { + return ENOMEM; + } + + tevent_req_set_callback(req, ifp_users_find_by_id_done, sbus_req); + + return EOK; +} + +static void +ifp_users_find_by_id_done(struct tevent_req *req) +{ + DBusError *error; + struct sbus_request *sbus_req; + struct sss_domain_info *domain; + struct ldb_result *result; + char *object_path; + errno_t ret; + + sbus_req = tevent_req_callback_data(req, struct sbus_request); + + ret = cache_req_user_by_id_recv(sbus_req, req, &result, &domain); + talloc_zfree(req); + if (ret == ENOENT) { + error = sbus_error_new(sbus_req, SBUS_ERROR_NOT_FOUND, + "User not found"); + goto done; + } else if (ret != EOK) { + error = sbus_error_new(sbus_req, DBUS_ERROR_FAILED, "Failed to fetch " + "user [%d]: %s\n", ret, sss_strerror(ret)); + goto done; + } + + object_path = ifp_users_build_path_from_msg(sbus_req, domain, + result->msgs[0]); + if (object_path == NULL) { + error = sbus_error_new(sbus_req, SBUS_ERROR_INTERNAL, + "Failed to compose object path"); + goto done; + } + +done: + if (ret != EOK) { + sbus_request_fail_and_finish(sbus_req, error); + return; + } + + iface_ifp_users_FindByID_finish(sbus_req, object_path); + return; +} + +int ifp_users_list_by_name(struct sbus_request *sbus_req, + void *data, + const char *filter, + uint32_t limit) +{ + return EOK; +} + +int ifp_users_list_by_domain_and_name(struct sbus_request *sbus_req, + void *data, + const char *domain, + const char *filter, + uint32_t limit) +{ + return EOK; +} diff --git a/src/responder/ifp/ifp_users.h b/src/responder/ifp/ifp_users.h new file mode 100644 index 000000000..a0a079f48 --- /dev/null +++ b/src/responder/ifp/ifp_users.h @@ -0,0 +1,57 @@ +/* + 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_USERS_H_ +#define IFP_USERS_H_ + +#include "responder/ifp/ifp_iface_generated.h" +#include "responder/ifp/ifp_private.h" + +#define IFP_PATH_USERS "/org/freedesktop/sssd/infopipe/Users" +#define IFP_PATH_USERS_TREE IFP_PATH_USERS SBUS_SUBTREE_SUFFIX + +/* 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 */ + +int ifp_users_find_by_name(struct sbus_request *sbus_req, + void *data, + const char *name); + +int ifp_users_find_by_id(struct sbus_request *sbus_req, + void *data, + uint32_t id); + +int ifp_users_list_by_name(struct sbus_request *sbus_req, + void *data, + const char *filter, + uint32_t limit); + +int ifp_users_list_by_domain_and_name(struct sbus_request *sbus_req, + void *data, + const char *domain, + const char *filter, + uint32_t limit); + +#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 a6f379afc..195e73aa9 100644 --- a/src/responder/ifp/org.freedesktop.sssd.infopipe.conf +++ b/src/responder/ifp/org.freedesktop.sssd.infopipe.conf @@ -30,6 +30,7 @@ send_member="Set"/> + -- cgit