Skip to content

Commit

Permalink
DBUS: Add ListByAttr(attr, filter, limit)
Browse files Browse the repository at this point in the history
Extended ListByName()'s mechanics to handle an attribute passed
as parameters instead of forcing "name." ListByName() will pass "name."

Created a dbus function ListByAttr() using ListByName()'s mechanics
but passing the attribute requested by the user.

Resolves: #6020

:feature: Introduced the dbus function
          org.freedesktop.sssd.infopipe.Users.ListByAttr(attr, value, limit)
          listing upto limit users matching the filter attr=value.
  • Loading branch information
aplopez committed Oct 4, 2022
1 parent 0198f64 commit 786b4ac
Show file tree
Hide file tree
Showing 21 changed files with 302 additions and 93 deletions.
6 changes: 4 additions & 2 deletions src/db/sysdb.h
Original file line number Diff line number Diff line change
Expand Up @@ -809,7 +809,8 @@ int sysdb_enumpwent(TALLOC_CTX *mem_ctx,

int sysdb_enumpwent_filter(TALLOC_CTX *mem_ctx,
struct sss_domain_info *domain,
const char *name_filter,
const char *attr,
const char *attr_filter,
const char *addtl_filter,
struct ldb_result **res);

Expand All @@ -819,7 +820,8 @@ int sysdb_enumpwent_with_views(TALLOC_CTX *mem_ctx,

int sysdb_enumpwent_filter_with_views(TALLOC_CTX *mem_ctx,
struct sss_domain_info *domain,
const char *name_filter,
const char *attr,
const char *attr_filter,
const char *addtl_filter,
struct ldb_result **res);

Expand Down
106 changes: 62 additions & 44 deletions src/db/sysdb_search.c
Original file line number Diff line number Diff line change
Expand Up @@ -527,7 +527,8 @@ errno_t sysdb_getpwuid_with_views(TALLOC_CTX *mem_ctx,

static char *enum_filter(TALLOC_CTX *mem_ctx,
const char *base_filter,
const char *name_filter,
const char *attr,
const char *attr_filter,
const char *addtl_filter)
{
char *filter;
Expand All @@ -538,14 +539,14 @@ static char *enum_filter(TALLOC_CTX *mem_ctx,
return NULL;
}

if (name_filter == NULL && addtl_filter == NULL) {
if ((attr == NULL || attr_filter == NULL) && addtl_filter == NULL) {
filter = talloc_strdup(tmp_ctx, base_filter);
} else {
filter = talloc_asprintf(tmp_ctx, "(&%s", base_filter);

if (filter != NULL && name_filter != NULL) {
if (filter != NULL && attr != NULL && attr_filter != NULL) {
filter = talloc_asprintf_append(filter, "(%s=%s)",
SYSDB_NAME, name_filter);
attr, attr_filter);
}

if (filter != NULL && addtl_filter != NULL) {
Expand Down Expand Up @@ -793,8 +794,12 @@ static errno_t sysdb_enum_dn_filter(TALLOC_CTX *mem_ctx,
return ENOMEM;
}

dn_filter = talloc_asprintf(tmp_ctx, "(&(%s=%s)(|", SYSDB_NAME,
name_filter);
if (name_filter == NULL) {
dn_filter = talloc_asprintf(tmp_ctx, "(|");
} else {
dn_filter = talloc_asprintf(tmp_ctx, "(&(%s=%s)(|", SYSDB_NAME,
name_filter);
}
if (dn_filter == NULL) {
ret = ENOMEM;
goto done;
Expand All @@ -812,7 +817,7 @@ static errno_t sysdb_enum_dn_filter(TALLOC_CTX *mem_ctx,
}
}

dn_filter = talloc_asprintf_append(dn_filter, "))");
dn_filter = talloc_asprintf_append(dn_filter, (name_filter == NULL ? ")" : "))"));
if (dn_filter == NULL) {
ret = ENOMEM;
goto done;
Expand All @@ -828,7 +833,8 @@ static errno_t sysdb_enum_dn_filter(TALLOC_CTX *mem_ctx,

int sysdb_enumpwent_filter(TALLOC_CTX *mem_ctx,
struct sss_domain_info *domain,
const char *name_filter,
const char *attr,
const char *attr_filter,
const char *addtl_filter,
struct ldb_result **_res)
{
Expand All @@ -840,7 +846,7 @@ int sysdb_enumpwent_filter(TALLOC_CTX *mem_ctx,
struct ldb_dn *base_dn;
struct ldb_result *res;
struct ldb_result ts_res;
struct ldb_result *ts_cache_res;
struct ldb_result *ts_cache_res = NULL;
int ret;

tmp_ctx = talloc_new(NULL);
Expand All @@ -854,38 +860,46 @@ int sysdb_enumpwent_filter(TALLOC_CTX *mem_ctx,
goto done;
}

ts_filter = enum_filter(tmp_ctx, SYSDB_PWENT_FILTER,
NULL, addtl_filter);
if (ts_filter == NULL) {
ret = ENOMEM;
goto done;
}
DEBUG(SSSDBG_TRACE_LIBS, "Searching timestamp cache with [%s]\n", ts_filter);
/* Do not look for the user's attribute in the timestamp db as it could
* not be present. Only look for the name. */
if (attr == NULL || strcmp(attr, SYSDB_NAME) == 0) {
ts_filter = enum_filter(tmp_ctx, SYSDB_PWENT_FILTER,
NULL, NULL, addtl_filter);
if (ts_filter == NULL) {
ret = ENOMEM;
goto done;
}
DEBUG(SSSDBG_TRACE_LIBS, "Searching timestamp cache with [%s]\n",
ts_filter);

ret = sysdb_search_ts_users(tmp_ctx, domain, ts_filter,
sysdb_ts_cache_attrs,
&ts_res);
if (ret == ERR_NO_TS) {
ret = ENOENT;
}
ret = sysdb_search_ts_users(tmp_ctx, domain, ts_filter,
sysdb_ts_cache_attrs,
&ts_res);
if (ret == ERR_NO_TS) {
ret = ENOENT;
}

if (ret != EOK && ret != ENOENT) {
goto done;
}
if (ret != EOK && ret != ENOENT) {
goto done;
}

ret = sysdb_enum_dn_filter(tmp_ctx, &ts_res, name_filter, &dn_filter);
if (ret != EOK) {
goto done;
}
ret = sysdb_enum_dn_filter(tmp_ctx, &ts_res, attr_filter, &dn_filter);
if (ret != EOK) {
goto done;
}

ret = sysdb_search_ts_matches(tmp_ctx, domain->sysdb, attrs, &ts_res,
dn_filter, &ts_cache_res);
if (ret != EOK && ret != ENOENT) {
goto done;
DEBUG(SSSDBG_TRACE_LIBS, "Searching timestamp entries with [%s]\n",
dn_filter);

ret = sysdb_search_ts_matches(tmp_ctx, domain->sysdb, attrs, &ts_res,
dn_filter, &ts_cache_res);
if (ret != EOK && ret != ENOENT) {
goto done;
}
}

filter = enum_filter(tmp_ctx, SYSDB_PWENT_FILTER,
name_filter, addtl_filter);
attr, attr_filter, addtl_filter);
if (filter == NULL) {
ret = ENOMEM;
goto done;
Expand All @@ -907,10 +921,12 @@ int sysdb_enumpwent_filter(TALLOC_CTX *mem_ctx,
ret = EOK;
}

res = sss_merge_ldb_results(res, ts_cache_res);
if (res == NULL) {
ret = ENOMEM;
goto done;
if (ts_cache_res != NULL) {
res = sss_merge_ldb_results(res, ts_cache_res);
if (res == NULL) {
ret = ENOMEM;
goto done;
}
}

*_res = talloc_steal(mem_ctx, res);
Expand All @@ -924,12 +940,13 @@ int sysdb_enumpwent(TALLOC_CTX *mem_ctx,
struct sss_domain_info *domain,
struct ldb_result **_res)
{
return sysdb_enumpwent_filter(mem_ctx, domain, NULL, 0, _res);
return sysdb_enumpwent_filter(mem_ctx, domain, NULL, NULL, NULL, _res);
}

int sysdb_enumpwent_filter_with_views(TALLOC_CTX *mem_ctx,
struct sss_domain_info *domain,
const char *name_filter,
const char *attr,
const char *attr_filter,
const char *addtl_filter,
struct ldb_result **_res)
{
Expand All @@ -944,7 +961,8 @@ int sysdb_enumpwent_filter_with_views(TALLOC_CTX *mem_ctx,
return ENOMEM;
}

ret = sysdb_enumpwent_filter(tmp_ctx, domain, name_filter, addtl_filter, &res);
ret = sysdb_enumpwent_filter(tmp_ctx, domain, attr, attr_filter,
addtl_filter, &res);
if (ret != EOK) {
DEBUG(SSSDBG_OP_FAILURE, "sysdb_enumpwent failed.\n");
goto done;
Expand Down Expand Up @@ -974,7 +992,7 @@ int sysdb_enumpwent_with_views(TALLOC_CTX *mem_ctx,
struct sss_domain_info *domain,
struct ldb_result **_res)
{
return sysdb_enumpwent_filter_with_views(mem_ctx, domain, NULL, NULL, _res);
return sysdb_enumpwent_filter_with_views(mem_ctx, domain, NULL, NULL, NULL, _res);
}

/* groups */
Expand Down Expand Up @@ -1459,7 +1477,7 @@ int sysdb_enumgrent_filter(TALLOC_CTX *mem_ctx,
}

ts_filter = enum_filter(tmp_ctx, base_filter,
NULL, addtl_filter);
NULL, NULL, addtl_filter);
if (ts_filter == NULL) {
ret = ENOMEM;
goto done;
Expand Down Expand Up @@ -1489,7 +1507,7 @@ int sysdb_enumgrent_filter(TALLOC_CTX *mem_ctx,
}

filter = enum_filter(tmp_ctx, base_filter,
name_filter, addtl_filter);
SYSDB_NAME, name_filter, addtl_filter);
if (filter == NULL) {
ret = ENOMEM;
goto done;
Expand Down
7 changes: 7 additions & 0 deletions src/responder/common/cache_req/cache_req.h
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,12 @@ enum cache_req_behavior {

struct cache_req_data;

struct cache_req_data *
cache_req_data_attr(TALLOC_CTX *mem_ctx,
enum cache_req_type type,
const char *attr,
const char *filter);

struct cache_req_data *
cache_req_data_name(TALLOC_CTX *mem_ctx,
enum cache_req_type type,
Expand Down Expand Up @@ -367,6 +373,7 @@ cache_req_user_by_filter_send(TALLOC_CTX *mem_ctx,
struct resp_ctx *rctx,
enum cache_req_dom_type req_dom_type,
const char *domain,
const char *attr,
const char *filter);

#define cache_req_user_by_filter_recv(mem_ctx, req, _result) \
Expand Down
18 changes: 17 additions & 1 deletion src/responder/common/cache_req/cache_req_data.c
Original file line number Diff line number Diff line change
Expand Up @@ -83,10 +83,12 @@ cache_req_data_create(TALLOC_CTX *mem_ctx,
data->svc.name = &data->name;

switch (type) {
case CACHE_REQ_USER_BY_FILTER:
data->name.attr = input->name.attr;
/* Fallthrough */
case CACHE_REQ_USER_BY_NAME:
case CACHE_REQ_USER_BY_UPN:
case CACHE_REQ_GROUP_BY_NAME:
case CACHE_REQ_USER_BY_FILTER:
case CACHE_REQ_GROUP_BY_FILTER:
case CACHE_REQ_INITGROUPS:
case CACHE_REQ_INITGROUPS_BY_UPN:
Expand Down Expand Up @@ -298,6 +300,20 @@ cache_req_data_name_attrs(TALLOC_CTX *mem_ctx,
return cache_req_data_create(mem_ctx, type, &input);
}

struct cache_req_data *
cache_req_data_attr(TALLOC_CTX *mem_ctx,
enum cache_req_type type,
const char *attr,
const char *filter)
{
struct cache_req_data input = {0};

input.name.input = filter;
input.name.attr = attr;

return cache_req_data_create(mem_ctx, type, &input);
}

struct cache_req_data *
cache_req_data_id(TALLOC_CTX *mem_ctx,
enum cache_req_type type,
Expand Down
5 changes: 3 additions & 2 deletions src/responder/common/cache_req/cache_req_private.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,13 +61,14 @@ struct cache_req {
};

/**
* Structure to hold the input strings that
* should be parsed into name and domain parts.
* Structure to hold the information the user passed as parameter
* and some strings after processing this information.
*/
struct cache_req_parsed_name {
const char *input; /* Original input. */
const char *name; /* Parsed name or UPN. */
const char *lookup; /* Converted per domain rules. */
const char *attr; /* Attribute name when looking for an attribute */
};

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,14 +84,17 @@ cache_req_user_by_filter_lookup(TALLOC_CTX *mem_ctx,
struct ldb_result **_result)
{
char *recent_filter;
const char *attr = (data->name.attr == NULL ? SYSDB_NAME : data->name.attr);
errno_t ret;

/* The "files" provider updates the record if /etc/passwd or /etc/group
* is touched. It does not perform any per-request update.
* Therefore the last update flag is not updated if no file was touched
* and we cannot use this optimization.
* Neither it is possible to use it when asking for a non-"name" attribute
* as it could not be present in the timestamp cache.
*/
if (is_files_provider(domain)) {
if (is_files_provider(domain) || data->name.attr != NULL) {
recent_filter = NULL;
} else {
recent_filter = talloc_asprintf(mem_ctx, "(%s>=%lu)", SYSDB_LAST_UPDATE,
Expand All @@ -101,7 +104,8 @@ cache_req_user_by_filter_lookup(TALLOC_CTX *mem_ctx,
}
}

ret = sysdb_enumpwent_filter_with_views(mem_ctx, domain, data->name.lookup,
ret = sysdb_enumpwent_filter_with_views(mem_ctx, domain,
attr, data->name.lookup,
recent_filter, _result);
talloc_free(recent_filter);

Expand Down Expand Up @@ -155,11 +159,12 @@ cache_req_user_by_filter_send(TALLOC_CTX *mem_ctx,
struct resp_ctx *rctx,
enum cache_req_dom_type req_dom_type,
const char *domain,
const char *attr,
const char *filter)
{
struct cache_req_data *data;

data = cache_req_data_name(mem_ctx, CACHE_REQ_USER_BY_FILTER, filter);
data = cache_req_data_attr(mem_ctx, CACHE_REQ_USER_BY_FILTER, attr, filter);
if (data == NULL) {
return NULL;
}
Expand Down
4 changes: 2 additions & 2 deletions src/responder/ifp/ifp_groups.c
Original file line number Diff line number Diff line change
Expand Up @@ -322,7 +322,7 @@ ifp_groups_list_by_name_send(TALLOC_CTX *mem_ctx,
}

state->ifp_ctx = ctx;
state->list_ctx = ifp_list_ctx_new(state, ctx, filter, limit);
state->list_ctx = ifp_list_ctx_new(state, ctx, NULL, filter, limit);
if (state->list_ctx == NULL) {
ret = ENOMEM;
goto done;
Expand Down Expand Up @@ -449,7 +449,7 @@ ifp_groups_list_by_domain_and_name_send(TALLOC_CTX *mem_ctx,
return NULL;
}

state->list_ctx = ifp_list_ctx_new(state, ctx, filter, limit);
state->list_ctx = ifp_list_ctx_new(state, ctx, NULL, filter, limit);
if (state->list_ctx == NULL) {
ret = ENOMEM;
goto done;
Expand Down
5 changes: 3 additions & 2 deletions src/responder/ifp/ifp_iface/ifp_iface.c
Original file line number Diff line number Diff line change
Expand Up @@ -152,9 +152,10 @@ ifp_register_sbus_interface(struct sbus_connection *conn,
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_name_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, 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)
Expand Down
6 changes: 6 additions & 0 deletions src/responder/ifp/ifp_iface/ifp_iface.xml
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,12 @@
<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">
Expand Down

0 comments on commit 786b4ac

Please sign in to comment.