|
|
6cf099 |
From fe9a0097970d12ff261b7417f9e57db95957ab24 Mon Sep 17 00:00:00 2001
|
|
|
6cf099 |
From: Jakub Hrozek <jhrozek@redhat.com>
|
|
|
6cf099 |
Date: Wed, 17 Jun 2015 13:39:43 +0200
|
|
|
6cf099 |
Subject: [PATCH 12/13] IFP: Add wildcard requests
|
|
|
6cf099 |
MIME-Version: 1.0
|
|
|
6cf099 |
Content-Type: text/plain; charset=UTF-8
|
|
|
6cf099 |
Content-Transfer-Encoding: 8bit
|
|
|
6cf099 |
|
|
|
6cf099 |
Resolves:
|
|
|
6cf099 |
https://fedorahosted.org/sssd/ticket/2553
|
|
|
6cf099 |
|
|
|
6cf099 |
Can be used as:
|
|
|
6cf099 |
|
|
|
6cf099 |
dbus-send --print-reply --system --dest=org.freedesktop.sssd.infopipe \
|
|
|
6cf099 |
/org/freedesktop/sssd/infopipe/Users \
|
|
|
6cf099 |
org.freedesktop.sssd.infopipe.Users.ListByName \
|
|
|
6cf099 |
string:r\* uint32:10
|
|
|
6cf099 |
|
|
|
6cf099 |
dbus-send --print-reply --system --dest=org.freedesktop.sssd.infopipe \
|
|
|
6cf099 |
/org/freedesktop/sssd/infopipe/Groups \
|
|
|
6cf099 |
org.freedesktop.sssd.infopipe.Groups.ListByName \
|
|
|
6cf099 |
string:r\* uint32:10
|
|
|
6cf099 |
|
|
|
6cf099 |
dbus-send --print-reply --system --dest=org.freedesktop.sssd.infopipe \
|
|
|
6cf099 |
/org/freedesktop/sssd/infopipe/Users \
|
|
|
6cf099 |
org.freedesktop.sssd.infopipe.Users.ListByDomainAndName \
|
|
|
6cf099 |
string:ipaldap string:r\* uint32:10
|
|
|
6cf099 |
|
|
|
6cf099 |
dbus-send --print-reply --system --dest=org.freedesktop.sssd.infopipe \
|
|
|
6cf099 |
/org/freedesktop/sssd/infopipe/Groups \
|
|
|
6cf099 |
org.freedesktop.sssd.infopipe.Groups.ListByDomainAndName \
|
|
|
6cf099 |
string:ipaldap string:r\* uint32:10
|
|
|
6cf099 |
|
|
|
6cf099 |
By default the wildcard_limit is unset, that is, the request will return
|
|
|
6cf099 |
all cached entries that match.
|
|
|
6cf099 |
|
|
|
6cf099 |
Reviewed-by: Pavel Březina <pbrezina@redhat.com>
|
|
|
6cf099 |
---
|
|
|
6cf099 |
src/confdb/confdb.h | 1 +
|
|
|
6cf099 |
src/man/sssd-ifp.5.xml | 15 ++++
|
|
|
6cf099 |
src/responder/ifp/ifp_groups.c | 175 ++++++++++++++++++++++++++++++++++++++
|
|
|
6cf099 |
src/responder/ifp/ifp_private.h | 22 +++++
|
|
|
6cf099 |
src/responder/ifp/ifp_users.c | 184 ++++++++++++++++++++++++++++++++++++++++
|
|
|
6cf099 |
src/responder/ifp/ifpsrv.c | 23 +++++
|
|
|
6cf099 |
src/responder/ifp/ifpsrv_util.c | 52 ++++++++++++
|
|
|
6cf099 |
7 files changed, 472 insertions(+)
|
|
|
6cf099 |
|
|
|
6cf099 |
diff --git a/src/confdb/confdb.h b/src/confdb/confdb.h
|
|
|
6cf099 |
index b2ec2e0b98a9be2d50009df524a1072e9b1c15c7..36df6aea268cc5c82696f20b1a65963350d5e100 100644
|
|
|
6cf099 |
--- a/src/confdb/confdb.h
|
|
|
6cf099 |
+++ b/src/confdb/confdb.h
|
|
|
6cf099 |
@@ -140,6 +140,7 @@
|
|
|
6cf099 |
/* InfoPipe */
|
|
|
6cf099 |
#define CONFDB_IFP_CONF_ENTRY "config/ifp"
|
|
|
6cf099 |
#define CONFDB_IFP_USER_ATTR_LIST "user_attributes"
|
|
|
6cf099 |
+#define CONFDB_IFP_WILDCARD_LIMIT "wildcard_limit"
|
|
|
6cf099 |
|
|
|
6cf099 |
/* Domains */
|
|
|
6cf099 |
#define CONFDB_DOMAIN_PATH_TMPL "config/domain/%s"
|
|
|
6cf099 |
diff --git a/src/man/sssd-ifp.5.xml b/src/man/sssd-ifp.5.xml
|
|
|
6cf099 |
index 867c117edccc3c000f7d9e8456298b72ebcdf693..da247f89dd2d9d08e0b1591d4c89f52197b278df 100644
|
|
|
6cf099 |
--- a/src/man/sssd-ifp.5.xml
|
|
|
6cf099 |
+++ b/src/man/sssd-ifp.5.xml
|
|
|
6cf099 |
@@ -131,6 +131,21 @@ user_attributes = +telephoneNumber, -loginShell
|
|
|
6cf099 |
</para>
|
|
|
6cf099 |
</listitem>
|
|
|
6cf099 |
</varlistentry>
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ <varlistentry>
|
|
|
6cf099 |
+ <term>wildcart_limit (integer)</term>
|
|
|
6cf099 |
+ <listitem>
|
|
|
6cf099 |
+ <para>
|
|
|
6cf099 |
+ Specifies an upper limit on the number of entries
|
|
|
6cf099 |
+ that are downloaded during a wildcard lookup that
|
|
|
6cf099 |
+ overrides caller-supplied limit.
|
|
|
6cf099 |
+ </para>
|
|
|
6cf099 |
+ <para>
|
|
|
6cf099 |
+ Default: 0 (let the caller set an upper limit)
|
|
|
6cf099 |
+ </para>
|
|
|
6cf099 |
+ </listitem>
|
|
|
6cf099 |
+ </varlistentry>
|
|
|
6cf099 |
+
|
|
|
6cf099 |
</variablelist>
|
|
|
6cf099 |
</refsect1>
|
|
|
6cf099 |
|
|
|
6cf099 |
diff --git a/src/responder/ifp/ifp_groups.c b/src/responder/ifp/ifp_groups.c
|
|
|
6cf099 |
index 1b581b568f14362a47b4a80eb55d2de8eb936ae3..3060035924026641cc245f2a1970db9e2646e11c 100644
|
|
|
6cf099 |
--- a/src/responder/ifp/ifp_groups.c
|
|
|
6cf099 |
+++ b/src/responder/ifp/ifp_groups.c
|
|
|
6cf099 |
@@ -81,6 +81,27 @@ done:
|
|
|
6cf099 |
return ret;
|
|
|
6cf099 |
}
|
|
|
6cf099 |
|
|
|
6cf099 |
+static int ifp_groups_list_copy(struct ifp_list_ctx *list_ctx,
|
|
|
6cf099 |
+ struct ldb_result *result)
|
|
|
6cf099 |
+{
|
|
|
6cf099 |
+ size_t copy_count, i;
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ copy_count = ifp_list_ctx_remaining_capacity(list_ctx, result->count);
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ for (i = 0; i < copy_count; i++) {
|
|
|
6cf099 |
+ list_ctx->paths[list_ctx->path_count + i] = \
|
|
|
6cf099 |
+ ifp_groups_build_path_from_msg(list_ctx->paths,
|
|
|
6cf099 |
+ list_ctx->dom,
|
|
|
6cf099 |
+ result->msgs[i]);
|
|
|
6cf099 |
+ if (list_ctx->paths[list_ctx->path_count + i] == NULL) {
|
|
|
6cf099 |
+ return ENOMEM;
|
|
|
6cf099 |
+ }
|
|
|
6cf099 |
+ }
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ list_ctx->path_count += copy_count;
|
|
|
6cf099 |
+ return EOK;
|
|
|
6cf099 |
+}
|
|
|
6cf099 |
+
|
|
|
6cf099 |
static void ifp_groups_find_by_name_done(struct tevent_req *req);
|
|
|
6cf099 |
|
|
|
6cf099 |
int ifp_groups_find_by_name(struct sbus_request *sbus_req,
|
|
|
6cf099 |
@@ -221,23 +242,177 @@ done:
|
|
|
6cf099 |
return;
|
|
|
6cf099 |
}
|
|
|
6cf099 |
|
|
|
6cf099 |
+static int ifp_groups_list_by_name_step(struct ifp_list_ctx *list_ctx);
|
|
|
6cf099 |
+static void ifp_groups_list_by_name_done(struct tevent_req *req);
|
|
|
6cf099 |
+static void ifp_groups_list_by_name_reply(struct ifp_list_ctx *list_ctx);
|
|
|
6cf099 |
+
|
|
|
6cf099 |
int ifp_groups_list_by_name(struct sbus_request *sbus_req,
|
|
|
6cf099 |
void *data,
|
|
|
6cf099 |
const char *filter,
|
|
|
6cf099 |
uint32_t limit)
|
|
|
6cf099 |
{
|
|
|
6cf099 |
+ struct ifp_ctx *ctx;
|
|
|
6cf099 |
+ struct ifp_list_ctx *list_ctx;
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ ctx = talloc_get_type(data, struct ifp_ctx);
|
|
|
6cf099 |
+ if (ctx == NULL) {
|
|
|
6cf099 |
+ DEBUG(SSSDBG_CRIT_FAILURE, "Invalid pointer!\n");
|
|
|
6cf099 |
+ return ERR_INTERNAL;
|
|
|
6cf099 |
+ }
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ list_ctx = ifp_list_ctx_new(sbus_req, ctx, filter, limit);
|
|
|
6cf099 |
+ if (list_ctx == NULL) {
|
|
|
6cf099 |
+ return ENOMEM;
|
|
|
6cf099 |
+ }
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ return ifp_groups_list_by_name_step(list_ctx);
|
|
|
6cf099 |
+}
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+static int ifp_groups_list_by_name_step(struct ifp_list_ctx *list_ctx)
|
|
|
6cf099 |
+{
|
|
|
6cf099 |
+ struct tevent_req *req;
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ req = cache_req_group_by_filter_send(list_ctx,
|
|
|
6cf099 |
+ list_ctx->ctx->rctx->ev,
|
|
|
6cf099 |
+ list_ctx->ctx->rctx,
|
|
|
6cf099 |
+ list_ctx->dom->name,
|
|
|
6cf099 |
+ list_ctx->filter);
|
|
|
6cf099 |
+ if (req == NULL) {
|
|
|
6cf099 |
+ return ENOMEM;
|
|
|
6cf099 |
+ }
|
|
|
6cf099 |
+ tevent_req_set_callback(req,
|
|
|
6cf099 |
+ ifp_groups_list_by_name_done, list_ctx);
|
|
|
6cf099 |
+
|
|
|
6cf099 |
return EOK;
|
|
|
6cf099 |
}
|
|
|
6cf099 |
|
|
|
6cf099 |
+static void ifp_groups_list_by_name_done(struct tevent_req *req)
|
|
|
6cf099 |
+{
|
|
|
6cf099 |
+ DBusError *error;
|
|
|
6cf099 |
+ struct ifp_list_ctx *list_ctx;
|
|
|
6cf099 |
+ struct sbus_request *sbus_req;
|
|
|
6cf099 |
+ struct ldb_result *result;
|
|
|
6cf099 |
+ struct sss_domain_info *domain;
|
|
|
6cf099 |
+ errno_t ret;
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ list_ctx = tevent_req_callback_data(req, struct ifp_list_ctx);
|
|
|
6cf099 |
+ sbus_req = list_ctx->sbus_req;
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ ret = cache_req_group_by_name_recv(sbus_req, req, &result, &domain, NULL);
|
|
|
6cf099 |
+ talloc_zfree(req);
|
|
|
6cf099 |
+ if (ret != EOK && ret != ENOENT) {
|
|
|
6cf099 |
+ error = sbus_error_new(sbus_req, DBUS_ERROR_FAILED, "Failed to fetch "
|
|
|
6cf099 |
+ "groups by filter [%d]: %s\n", ret, sss_strerror(ret));
|
|
|
6cf099 |
+ sbus_request_fail_and_finish(sbus_req, error);
|
|
|
6cf099 |
+ return;
|
|
|
6cf099 |
+ }
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ ret = ifp_groups_list_copy(list_ctx, result);
|
|
|
6cf099 |
+ if (ret != EOK) {
|
|
|
6cf099 |
+ error = sbus_error_new(sbus_req, SBUS_ERROR_INTERNAL,
|
|
|
6cf099 |
+ "Failed to copy domain result");
|
|
|
6cf099 |
+ sbus_request_fail_and_finish(sbus_req, error);
|
|
|
6cf099 |
+ return;
|
|
|
6cf099 |
+ }
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ list_ctx->dom = get_next_domain(list_ctx->dom, true);
|
|
|
6cf099 |
+ if (list_ctx->dom == NULL) {
|
|
|
6cf099 |
+ return ifp_groups_list_by_name_reply(list_ctx);
|
|
|
6cf099 |
+ }
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ ret = ifp_groups_list_by_name_step(list_ctx);
|
|
|
6cf099 |
+ if (ret != EOK) {
|
|
|
6cf099 |
+ error = sbus_error_new(sbus_req, SBUS_ERROR_INTERNAL,
|
|
|
6cf099 |
+ "Failed to start next-domain search");
|
|
|
6cf099 |
+ sbus_request_fail_and_finish(sbus_req, error);
|
|
|
6cf099 |
+ return;
|
|
|
6cf099 |
+ }
|
|
|
6cf099 |
+}
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+static void ifp_groups_list_by_name_reply(struct ifp_list_ctx *list_ctx)
|
|
|
6cf099 |
+{
|
|
|
6cf099 |
+ iface_ifp_groups_ListByDomainAndName_finish(list_ctx->sbus_req,
|
|
|
6cf099 |
+ list_ctx->paths,
|
|
|
6cf099 |
+ list_ctx->path_count);
|
|
|
6cf099 |
+}
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+static void ifp_groups_list_by_domain_and_name_done(struct tevent_req *req);
|
|
|
6cf099 |
+
|
|
|
6cf099 |
int ifp_groups_list_by_domain_and_name(struct sbus_request *sbus_req,
|
|
|
6cf099 |
void *data,
|
|
|
6cf099 |
const char *domain,
|
|
|
6cf099 |
const char *filter,
|
|
|
6cf099 |
uint32_t limit)
|
|
|
6cf099 |
{
|
|
|
6cf099 |
+ struct tevent_req *req;
|
|
|
6cf099 |
+ struct ifp_ctx *ctx;
|
|
|
6cf099 |
+ struct ifp_list_ctx *list_ctx;
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ ctx = talloc_get_type(data, struct ifp_ctx);
|
|
|
6cf099 |
+ if (ctx == NULL) {
|
|
|
6cf099 |
+ DEBUG(SSSDBG_CRIT_FAILURE, "Invalid pointer!\n");
|
|
|
6cf099 |
+ return ERR_INTERNAL;
|
|
|
6cf099 |
+ }
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ list_ctx = ifp_list_ctx_new(sbus_req, ctx, filter, limit);
|
|
|
6cf099 |
+ if (list_ctx == NULL) {
|
|
|
6cf099 |
+ return ENOMEM;
|
|
|
6cf099 |
+ }
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ req = cache_req_group_by_filter_send(list_ctx, ctx->rctx->ev, ctx->rctx,
|
|
|
6cf099 |
+ domain, filter);
|
|
|
6cf099 |
+ if (req == NULL) {
|
|
|
6cf099 |
+ return ENOMEM;
|
|
|
6cf099 |
+ }
|
|
|
6cf099 |
+ tevent_req_set_callback(req,
|
|
|
6cf099 |
+ ifp_groups_list_by_domain_and_name_done, list_ctx);
|
|
|
6cf099 |
+
|
|
|
6cf099 |
return EOK;
|
|
|
6cf099 |
}
|
|
|
6cf099 |
|
|
|
6cf099 |
+static void ifp_groups_list_by_domain_and_name_done(struct tevent_req *req)
|
|
|
6cf099 |
+{
|
|
|
6cf099 |
+ DBusError *error;
|
|
|
6cf099 |
+ struct ifp_list_ctx *list_ctx;
|
|
|
6cf099 |
+ struct sbus_request *sbus_req;
|
|
|
6cf099 |
+ struct ldb_result *result;
|
|
|
6cf099 |
+ struct sss_domain_info *domain;
|
|
|
6cf099 |
+ errno_t ret;
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ list_ctx = tevent_req_callback_data(req, struct ifp_list_ctx);
|
|
|
6cf099 |
+ sbus_req = list_ctx->sbus_req;
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ ret = cache_req_user_by_name_recv(sbus_req, req, &result, &domain, NULL);
|
|
|
6cf099 |
+ talloc_zfree(req);
|
|
|
6cf099 |
+ if (ret == ENOENT) {
|
|
|
6cf099 |
+ error = sbus_error_new(sbus_req, SBUS_ERROR_NOT_FOUND,
|
|
|
6cf099 |
+ "User not found by filter");
|
|
|
6cf099 |
+ goto done;
|
|
|
6cf099 |
+ } else if (ret != EOK) {
|
|
|
6cf099 |
+ error = sbus_error_new(sbus_req, DBUS_ERROR_FAILED, "Failed to fetch "
|
|
|
6cf099 |
+ "groups by filter [%d]: %s\n", ret, sss_strerror(ret));
|
|
|
6cf099 |
+ goto done;
|
|
|
6cf099 |
+ }
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ ret = ifp_groups_list_copy(list_ctx, result);
|
|
|
6cf099 |
+ if (ret != EOK) {
|
|
|
6cf099 |
+ error = sbus_error_new(sbus_req, SBUS_ERROR_INTERNAL,
|
|
|
6cf099 |
+ "Failed to copy domain result");
|
|
|
6cf099 |
+ goto done;
|
|
|
6cf099 |
+ }
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+done:
|
|
|
6cf099 |
+ if (ret != EOK) {
|
|
|
6cf099 |
+ sbus_request_fail_and_finish(sbus_req, error);
|
|
|
6cf099 |
+ return;
|
|
|
6cf099 |
+ }
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ iface_ifp_groups_ListByDomainAndName_finish(sbus_req,
|
|
|
6cf099 |
+ list_ctx->paths,
|
|
|
6cf099 |
+ list_ctx->path_count);
|
|
|
6cf099 |
+ return;
|
|
|
6cf099 |
+}
|
|
|
6cf099 |
+
|
|
|
6cf099 |
static errno_t
|
|
|
6cf099 |
ifp_groups_group_get(struct sbus_request *sbus_req,
|
|
|
6cf099 |
void *data,
|
|
|
6cf099 |
diff --git a/src/responder/ifp/ifp_private.h b/src/responder/ifp/ifp_private.h
|
|
|
6cf099 |
index 304e4dc535aac4215cf318a0bea845c161c5f079..43519de6fef3033f1e47cecb787d6b02dc9c6e56 100644
|
|
|
6cf099 |
--- a/src/responder/ifp/ifp_private.h
|
|
|
6cf099 |
+++ b/src/responder/ifp/ifp_private.h
|
|
|
6cf099 |
@@ -44,6 +44,7 @@ struct ifp_ctx {
|
|
|
6cf099 |
|
|
|
6cf099 |
struct sysbus_ctx *sysbus;
|
|
|
6cf099 |
const char **user_whitelist;
|
|
|
6cf099 |
+ uint32_t wildcard_limit;
|
|
|
6cf099 |
};
|
|
|
6cf099 |
|
|
|
6cf099 |
errno_t ifp_register_sbus_interface(struct sbus_connection *conn,
|
|
|
6cf099 |
@@ -84,4 +85,25 @@ ifp_get_user_extra_attributes(TALLOC_CTX *mem_ctx, struct ifp_ctx *ifp_ctx);
|
|
|
6cf099 |
bool ifp_attr_allowed(const char *whitelist[], const char *attr);
|
|
|
6cf099 |
bool ifp_is_user_attr_allowed(struct ifp_ctx *ifp_ctx, const char *attr);
|
|
|
6cf099 |
|
|
|
6cf099 |
+/* Used for list calls */
|
|
|
6cf099 |
+struct ifp_list_ctx {
|
|
|
6cf099 |
+ struct sbus_request *sbus_req;
|
|
|
6cf099 |
+ const char *filter;
|
|
|
6cf099 |
+ uint32_t limit;
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ struct sss_domain_info *dom;
|
|
|
6cf099 |
+ struct ifp_ctx *ctx;
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ const char **paths;
|
|
|
6cf099 |
+ size_t path_count;
|
|
|
6cf099 |
+};
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+struct ifp_list_ctx *ifp_list_ctx_new(struct sbus_request *sbus_req,
|
|
|
6cf099 |
+ struct ifp_ctx *ctx,
|
|
|
6cf099 |
+ const char *filter,
|
|
|
6cf099 |
+ uint32_t limit);
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+size_t ifp_list_ctx_remaining_capacity(struct ifp_list_ctx *list_ctx,
|
|
|
6cf099 |
+ size_t entries);
|
|
|
6cf099 |
+
|
|
|
6cf099 |
#endif /* _IFPSRV_PRIVATE_H_ */
|
|
|
6cf099 |
diff --git a/src/responder/ifp/ifp_users.c b/src/responder/ifp/ifp_users.c
|
|
|
6cf099 |
index 2ec74c30b348ac5f2b84cdc8e2dd406fd44a7da3..effefdc0435d794206dbe7358c61d2ea47760361 100644
|
|
|
6cf099 |
--- a/src/responder/ifp/ifp_users.c
|
|
|
6cf099 |
+++ b/src/responder/ifp/ifp_users.c
|
|
|
6cf099 |
@@ -309,23 +309,207 @@ done:
|
|
|
6cf099 |
return;
|
|
|
6cf099 |
}
|
|
|
6cf099 |
|
|
|
6cf099 |
+static int ifp_users_list_copy(struct ifp_list_ctx *list_ctx,
|
|
|
6cf099 |
+ struct ldb_result *result)
|
|
|
6cf099 |
+{
|
|
|
6cf099 |
+ size_t copy_count, i;
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ copy_count = ifp_list_ctx_remaining_capacity(list_ctx, result->count);
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ for (i = 0; i < copy_count; i++) {
|
|
|
6cf099 |
+ list_ctx->paths[list_ctx->path_count + i] = \
|
|
|
6cf099 |
+ ifp_users_build_path_from_msg(list_ctx->paths,
|
|
|
6cf099 |
+ list_ctx->dom,
|
|
|
6cf099 |
+ result->msgs[i]);
|
|
|
6cf099 |
+ if (list_ctx->paths[list_ctx->path_count + i] == NULL) {
|
|
|
6cf099 |
+ return ENOMEM;
|
|
|
6cf099 |
+ }
|
|
|
6cf099 |
+ }
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ list_ctx->path_count += copy_count;
|
|
|
6cf099 |
+ return EOK;
|
|
|
6cf099 |
+}
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+static int ifp_users_list_by_name_step(struct ifp_list_ctx *list_ctx);
|
|
|
6cf099 |
+static void ifp_users_list_by_name_done(struct tevent_req *req);
|
|
|
6cf099 |
+static void ifp_users_list_by_name_reply(struct ifp_list_ctx *list_ctx);
|
|
|
6cf099 |
+
|
|
|
6cf099 |
int ifp_users_list_by_name(struct sbus_request *sbus_req,
|
|
|
6cf099 |
void *data,
|
|
|
6cf099 |
const char *filter,
|
|
|
6cf099 |
uint32_t limit)
|
|
|
6cf099 |
{
|
|
|
6cf099 |
+ struct ifp_ctx *ctx;
|
|
|
6cf099 |
+ struct ifp_list_ctx *list_ctx;
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ ctx = talloc_get_type(data, struct ifp_ctx);
|
|
|
6cf099 |
+ if (ctx == NULL) {
|
|
|
6cf099 |
+ DEBUG(SSSDBG_CRIT_FAILURE, "Invalid pointer!\n");
|
|
|
6cf099 |
+ return ERR_INTERNAL;
|
|
|
6cf099 |
+ }
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ list_ctx = ifp_list_ctx_new(sbus_req, ctx, filter, limit);
|
|
|
6cf099 |
+ if (list_ctx == NULL) {
|
|
|
6cf099 |
+ return ENOMEM;
|
|
|
6cf099 |
+ }
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ return ifp_users_list_by_name_step(list_ctx);
|
|
|
6cf099 |
+}
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+static int ifp_users_list_by_name_step(struct ifp_list_ctx *list_ctx)
|
|
|
6cf099 |
+{
|
|
|
6cf099 |
+ struct tevent_req *req;
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ req = cache_req_user_by_filter_send(list_ctx,
|
|
|
6cf099 |
+ list_ctx->ctx->rctx->ev,
|
|
|
6cf099 |
+ list_ctx->ctx->rctx,
|
|
|
6cf099 |
+ list_ctx->dom->name,
|
|
|
6cf099 |
+ list_ctx->filter);
|
|
|
6cf099 |
+ if (req == NULL) {
|
|
|
6cf099 |
+ return ENOMEM;
|
|
|
6cf099 |
+ }
|
|
|
6cf099 |
+ tevent_req_set_callback(req,
|
|
|
6cf099 |
+ ifp_users_list_by_name_done, list_ctx);
|
|
|
6cf099 |
+
|
|
|
6cf099 |
return EOK;
|
|
|
6cf099 |
}
|
|
|
6cf099 |
|
|
|
6cf099 |
+static void ifp_users_list_by_name_done(struct tevent_req *req)
|
|
|
6cf099 |
+{
|
|
|
6cf099 |
+ DBusError *error;
|
|
|
6cf099 |
+ struct ifp_list_ctx *list_ctx;
|
|
|
6cf099 |
+ struct sbus_request *sbus_req;
|
|
|
6cf099 |
+ struct ldb_result *result;
|
|
|
6cf099 |
+ struct sss_domain_info *domain;
|
|
|
6cf099 |
+ errno_t ret;
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ list_ctx = tevent_req_callback_data(req, struct ifp_list_ctx);
|
|
|
6cf099 |
+ sbus_req = list_ctx->sbus_req;
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ ret = cache_req_user_by_name_recv(sbus_req, req, &result, &domain, NULL);
|
|
|
6cf099 |
+ talloc_zfree(req);
|
|
|
6cf099 |
+ if (ret != EOK && ret != ENOENT) {
|
|
|
6cf099 |
+ error = sbus_error_new(sbus_req, DBUS_ERROR_FAILED, "Failed to fetch "
|
|
|
6cf099 |
+ "users by filter [%d]: %s\n", ret, sss_strerror(ret));
|
|
|
6cf099 |
+ sbus_request_fail_and_finish(sbus_req, error);
|
|
|
6cf099 |
+ return;
|
|
|
6cf099 |
+ }
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ ret = ifp_users_list_copy(list_ctx, result);
|
|
|
6cf099 |
+ if (ret != EOK) {
|
|
|
6cf099 |
+ error = sbus_error_new(sbus_req, SBUS_ERROR_INTERNAL,
|
|
|
6cf099 |
+ "Failed to copy domain result");
|
|
|
6cf099 |
+ sbus_request_fail_and_finish(sbus_req, error);
|
|
|
6cf099 |
+ return;
|
|
|
6cf099 |
+ }
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ list_ctx->dom = get_next_domain(list_ctx->dom, true);
|
|
|
6cf099 |
+ if (list_ctx->dom == NULL) {
|
|
|
6cf099 |
+ return ifp_users_list_by_name_reply(list_ctx);
|
|
|
6cf099 |
+ }
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ ret = ifp_users_list_by_name_step(list_ctx);
|
|
|
6cf099 |
+ if (ret != EOK) {
|
|
|
6cf099 |
+ error = sbus_error_new(sbus_req, SBUS_ERROR_INTERNAL,
|
|
|
6cf099 |
+ "Failed to start next-domain search");
|
|
|
6cf099 |
+ sbus_request_fail_and_finish(sbus_req, error);
|
|
|
6cf099 |
+ return;
|
|
|
6cf099 |
+ }
|
|
|
6cf099 |
+}
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+static void ifp_users_list_by_name_reply(struct ifp_list_ctx *list_ctx)
|
|
|
6cf099 |
+{
|
|
|
6cf099 |
+ iface_ifp_users_ListByName_finish(list_ctx->sbus_req,
|
|
|
6cf099 |
+ list_ctx->paths,
|
|
|
6cf099 |
+ list_ctx->path_count);
|
|
|
6cf099 |
+}
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+static void ifp_users_list_by_domain_and_name_done(struct tevent_req *req);
|
|
|
6cf099 |
+
|
|
|
6cf099 |
int ifp_users_list_by_domain_and_name(struct sbus_request *sbus_req,
|
|
|
6cf099 |
void *data,
|
|
|
6cf099 |
const char *domain,
|
|
|
6cf099 |
const char *filter,
|
|
|
6cf099 |
uint32_t limit)
|
|
|
6cf099 |
{
|
|
|
6cf099 |
+ struct tevent_req *req;
|
|
|
6cf099 |
+ struct ifp_ctx *ctx;
|
|
|
6cf099 |
+ struct ifp_list_ctx *list_ctx;
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ ctx = talloc_get_type(data, struct ifp_ctx);
|
|
|
6cf099 |
+ if (ctx == NULL) {
|
|
|
6cf099 |
+ DEBUG(SSSDBG_CRIT_FAILURE, "Invalid pointer!\n");
|
|
|
6cf099 |
+ return ERR_INTERNAL;
|
|
|
6cf099 |
+ }
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ list_ctx = ifp_list_ctx_new(sbus_req, ctx, filter, limit);
|
|
|
6cf099 |
+ if (list_ctx == NULL) {
|
|
|
6cf099 |
+ return ENOMEM;
|
|
|
6cf099 |
+ }
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ req = cache_req_user_by_filter_send(list_ctx, ctx->rctx->ev, ctx->rctx,
|
|
|
6cf099 |
+ domain, filter);
|
|
|
6cf099 |
+ if (req == NULL) {
|
|
|
6cf099 |
+ return ENOMEM;
|
|
|
6cf099 |
+ }
|
|
|
6cf099 |
+ tevent_req_set_callback(req,
|
|
|
6cf099 |
+ ifp_users_list_by_domain_and_name_done, list_ctx);
|
|
|
6cf099 |
+
|
|
|
6cf099 |
return EOK;
|
|
|
6cf099 |
}
|
|
|
6cf099 |
|
|
|
6cf099 |
+static void ifp_users_list_by_domain_and_name_done(struct tevent_req *req)
|
|
|
6cf099 |
+{
|
|
|
6cf099 |
+ DBusError *error;
|
|
|
6cf099 |
+ struct ifp_list_ctx *list_ctx;
|
|
|
6cf099 |
+ struct sbus_request *sbus_req;
|
|
|
6cf099 |
+ struct ldb_result *result;
|
|
|
6cf099 |
+ struct sss_domain_info *domain;
|
|
|
6cf099 |
+ errno_t ret;
|
|
|
6cf099 |
+ size_t copy_count, i;
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ list_ctx = tevent_req_callback_data(req, struct ifp_list_ctx);
|
|
|
6cf099 |
+ sbus_req = list_ctx->sbus_req;
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ ret = cache_req_user_by_name_recv(sbus_req, req, &result, &domain, NULL);
|
|
|
6cf099 |
+ talloc_zfree(req);
|
|
|
6cf099 |
+ if (ret == ENOENT) {
|
|
|
6cf099 |
+ error = sbus_error_new(sbus_req, SBUS_ERROR_NOT_FOUND,
|
|
|
6cf099 |
+ "User not found by filter");
|
|
|
6cf099 |
+ goto done;
|
|
|
6cf099 |
+ } else if (ret != EOK) {
|
|
|
6cf099 |
+ error = sbus_error_new(sbus_req, DBUS_ERROR_FAILED, "Failed to fetch "
|
|
|
6cf099 |
+ "users by filter [%d]: %s\n", ret, sss_strerror(ret));
|
|
|
6cf099 |
+ goto done;
|
|
|
6cf099 |
+ }
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ copy_count = ifp_list_ctx_remaining_capacity(list_ctx, result->count);
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ for (i = 0; i < copy_count; i++) {
|
|
|
6cf099 |
+ list_ctx->paths[i] = ifp_users_build_path_from_msg(list_ctx->paths,
|
|
|
6cf099 |
+ list_ctx->dom,
|
|
|
6cf099 |
+ result->msgs[i]);
|
|
|
6cf099 |
+ if (list_ctx->paths[i] == NULL) {
|
|
|
6cf099 |
+ error = sbus_error_new(sbus_req, SBUS_ERROR_INTERNAL,
|
|
|
6cf099 |
+ "Failed to compose object path");
|
|
|
6cf099 |
+ goto done;
|
|
|
6cf099 |
+ }
|
|
|
6cf099 |
+ }
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ list_ctx->path_count += copy_count;
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+done:
|
|
|
6cf099 |
+ if (ret != EOK) {
|
|
|
6cf099 |
+ sbus_request_fail_and_finish(sbus_req, error);
|
|
|
6cf099 |
+ return;
|
|
|
6cf099 |
+ }
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ iface_ifp_users_ListByDomainAndName_finish(sbus_req,
|
|
|
6cf099 |
+ list_ctx->paths,
|
|
|
6cf099 |
+ list_ctx->path_count);
|
|
|
6cf099 |
+ return;
|
|
|
6cf099 |
+}
|
|
|
6cf099 |
+
|
|
|
6cf099 |
static errno_t
|
|
|
6cf099 |
ifp_users_user_get(struct sbus_request *sbus_req,
|
|
|
6cf099 |
struct ifp_ctx *ifp_ctx,
|
|
|
6cf099 |
diff --git a/src/responder/ifp/ifpsrv.c b/src/responder/ifp/ifpsrv.c
|
|
|
6cf099 |
index 631bcd266d7e06154dbf1f37f9f439119b2b8944..cdc411faa330dc2c063e52abe63cd68dbe16a5d9 100644
|
|
|
6cf099 |
--- a/src/responder/ifp/ifpsrv.c
|
|
|
6cf099 |
+++ b/src/responder/ifp/ifpsrv.c
|
|
|
6cf099 |
@@ -34,6 +34,7 @@
|
|
|
6cf099 |
#include <dbus/dbus.h>
|
|
|
6cf099 |
|
|
|
6cf099 |
#include "util/util.h"
|
|
|
6cf099 |
+#include "util/strtonum.h"
|
|
|
6cf099 |
#include "sbus/sssd_dbus.h"
|
|
|
6cf099 |
#include "monitor/monitor_interfaces.h"
|
|
|
6cf099 |
#include "confdb/confdb.h"
|
|
|
6cf099 |
@@ -228,6 +229,7 @@ int ifp_process_init(TALLOC_CTX *mem_ctx,
|
|
|
6cf099 |
int max_retries;
|
|
|
6cf099 |
char *uid_str;
|
|
|
6cf099 |
char *attr_list_str;
|
|
|
6cf099 |
+ char *wildcard_limit_str;
|
|
|
6cf099 |
|
|
|
6cf099 |
ifp_cmds = get_ifp_cmds();
|
|
|
6cf099 |
ret = sss_process_init(mem_ctx, ev, cdb,
|
|
|
6cf099 |
@@ -321,6 +323,27 @@ int ifp_process_init(TALLOC_CTX *mem_ctx,
|
|
|
6cf099 |
goto fail;
|
|
|
6cf099 |
}
|
|
|
6cf099 |
|
|
|
6cf099 |
+ /* A bit convoluted way until we have a confdb_get_uint32 */
|
|
|
6cf099 |
+ ret = confdb_get_string(ifp_ctx->rctx->cdb,
|
|
|
6cf099 |
+ ifp_ctx->rctx,
|
|
|
6cf099 |
+ CONFDB_IFP_CONF_ENTRY,
|
|
|
6cf099 |
+ CONFDB_IFP_WILDCARD_LIMIT,
|
|
|
6cf099 |
+ NULL, /* no limit by default */
|
|
|
6cf099 |
+ &wildcard_limit_str);
|
|
|
6cf099 |
+ if (ret != EOK) {
|
|
|
6cf099 |
+ DEBUG(SSSDBG_FATAL_FAILURE,
|
|
|
6cf099 |
+ "Failed to retrieve limit for a wildcard search\n");
|
|
|
6cf099 |
+ goto fail;
|
|
|
6cf099 |
+ }
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ if (wildcard_limit_str) {
|
|
|
6cf099 |
+ ifp_ctx->wildcard_limit = strtouint32(wildcard_limit_str, NULL, 10);
|
|
|
6cf099 |
+ if (errno != 0) {
|
|
|
6cf099 |
+ ret = errno;
|
|
|
6cf099 |
+ goto fail;
|
|
|
6cf099 |
+ }
|
|
|
6cf099 |
+ }
|
|
|
6cf099 |
+
|
|
|
6cf099 |
for (iter = ifp_ctx->rctx->be_conns; iter; iter = iter->next) {
|
|
|
6cf099 |
sbus_reconnect_init(iter->conn, max_retries,
|
|
|
6cf099 |
ifp_dp_reconnect_init, iter);
|
|
|
6cf099 |
diff --git a/src/responder/ifp/ifpsrv_util.c b/src/responder/ifp/ifpsrv_util.c
|
|
|
6cf099 |
index 674165ee4901115c9e17458a75fdb3536b6468c2..3b02fd06f5227e4ffc3d40ffb20fed981c5028a7 100644
|
|
|
6cf099 |
--- a/src/responder/ifp/ifpsrv_util.c
|
|
|
6cf099 |
+++ b/src/responder/ifp/ifpsrv_util.c
|
|
|
6cf099 |
@@ -21,6 +21,8 @@
|
|
|
6cf099 |
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
6cf099 |
*/
|
|
|
6cf099 |
|
|
|
6cf099 |
+#include <sys/param.h>
|
|
|
6cf099 |
+
|
|
|
6cf099 |
#include "db/sysdb.h"
|
|
|
6cf099 |
#include "responder/ifp/ifp_private.h"
|
|
|
6cf099 |
|
|
|
6cf099 |
@@ -269,3 +271,53 @@ ifp_is_user_attr_allowed(struct ifp_ctx *ifp_ctx, const char *attr)
|
|
|
6cf099 |
{
|
|
|
6cf099 |
return ifp_attr_allowed(ifp_ctx->user_whitelist, attr);
|
|
|
6cf099 |
}
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+static uint32_t ifp_list_limit(struct ifp_ctx *ctx, uint32_t limit)
|
|
|
6cf099 |
+{
|
|
|
6cf099 |
+ if (ctx->wildcard_limit) {
|
|
|
6cf099 |
+ return MIN(ctx->wildcard_limit, limit);
|
|
|
6cf099 |
+ } else {
|
|
|
6cf099 |
+ return limit;
|
|
|
6cf099 |
+ }
|
|
|
6cf099 |
+}
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+struct ifp_list_ctx *ifp_list_ctx_new(struct sbus_request *sbus_req,
|
|
|
6cf099 |
+ struct ifp_ctx *ctx,
|
|
|
6cf099 |
+ const char *filter,
|
|
|
6cf099 |
+ uint32_t limit)
|
|
|
6cf099 |
+{
|
|
|
6cf099 |
+ struct ifp_list_ctx *list_ctx;
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ list_ctx = talloc_zero(sbus_req, struct ifp_list_ctx);
|
|
|
6cf099 |
+ if (list_ctx == NULL) {
|
|
|
6cf099 |
+ return NULL;
|
|
|
6cf099 |
+ }
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ list_ctx->sbus_req = sbus_req;
|
|
|
6cf099 |
+ list_ctx->limit = ifp_list_limit(ctx, limit);
|
|
|
6cf099 |
+ list_ctx->ctx = ctx;
|
|
|
6cf099 |
+ list_ctx->dom = ctx->rctx->domains;
|
|
|
6cf099 |
+ list_ctx->filter = filter;
|
|
|
6cf099 |
+ list_ctx->paths = talloc_zero_array(list_ctx, const char *, limit);
|
|
|
6cf099 |
+ if (list_ctx->paths == NULL) {
|
|
|
6cf099 |
+ talloc_free(list_ctx);
|
|
|
6cf099 |
+ return NULL;
|
|
|
6cf099 |
+ }
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ return list_ctx;
|
|
|
6cf099 |
+}
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+size_t ifp_list_ctx_remaining_capacity(struct ifp_list_ctx *list_ctx,
|
|
|
6cf099 |
+ size_t entries)
|
|
|
6cf099 |
+{
|
|
|
6cf099 |
+ size_t capacity = list_ctx->limit - list_ctx->path_count;
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ if (capacity < entries) {
|
|
|
6cf099 |
+ DEBUG(SSSDBG_MINOR_FAILURE,
|
|
|
6cf099 |
+ "IFP list request has limit of %"PRIu32" entries but back end "
|
|
|
6cf099 |
+ "returned %zu entries\n", list_ctx->limit, entries);
|
|
|
6cf099 |
+ return capacity;
|
|
|
6cf099 |
+ } else {
|
|
|
6cf099 |
+ return entries;
|
|
|
6cf099 |
+ }
|
|
|
6cf099 |
+}
|
|
|
6cf099 |
--
|
|
|
6cf099 |
2.4.3
|
|
|
6cf099 |
|