sdap_async_initgroups.c revision 5ff7a765434ed0b4d37564ade26d7761d06f81c3
/*
SSSD
Async LDAP Helper routines - initgroups operation
Copyright (C) Simo Sorce <ssorce@redhat.com> - 2009
Copyright (C) 2010, Ralf Haferkamp <rhafer@suse.de>, Novell Inc.
Copyright (C) Jan Zeleny <jzeleny@redhat.com> - 2011
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 "providers/ldap/sdap_async_private.h"
#include "providers/ldap/ldap_common.h"
#include "providers/ldap/sdap_idmap.h"
#include "providers/ldap/sdap_users.h"
/* ==Save-fake-group-list=====================================*/
struct sss_domain_info *domain,
struct sdap_options *opts,
char **groupnames,
struct sysdb_attrs **ldap_groups,
int ldap_groups_count)
{
struct ldb_message *msg;
const char *groupname;
const char *original_dn;
char **missing;
int ret;
bool in_transaction = false;
bool posix;
bool use_id_mapping;
bool need_filter;
char *tmp_name;
/* There are no groups in LDAP but we should add user to groups ?? */
if (ldap_groups_count == 0) return EOK;
if (!missing) {
goto done;
}
mi = 0;
for (i=0; groupnames[i]; i++) {
"Failed to format original name [%s]\n", groupnames[i]);
goto done;
}
&msg);
continue;
"need to add a fake entry\n",
mi++;
continue;
goto done;
}
}
/* All groups are cached, nothing to do */
if (mi == 0) {
goto done;
}
"Cannot start sysdb transaction [%d]: %s\n",
goto done;
}
in_transaction = true;
for (i=0; missing[i]; i++) {
/* The group is not in sysdb, need to add a fake entry */
"The group has no name attribute\n");
goto done;
}
posix = true;
&sid_str);
if (use_id_mapping) {
"while id-mapping.\n",
goto done;
}
"Mapping group [%s] objectSID to unix ID\n", groupname);
"Group [%s] has objectSID [%s]\n",
/* Convert the SID into a UNIX group ID */
&gid);
"Group [%s] has mapped gid [%lu]\n",
} else {
posix = false;
gid = 0;
"Group [%s] cannot be mapped. "
"Treating as a non-POSIX group\n",
}
} else {
&gid);
"Marking group %s as non-posix and setting GID=0!\n",
gid = 0;
posix = false;
} else if (ret) {
"The GID attribute is malformed\n");
goto done;
}
}
&original_dn);
if (ret) {
"The group has no original DN\n");
original_dn = NULL;
}
"Failed to retrieve UUID [%d][%s].\n",
}
"uniqueIDstr",
&uuid);
if (ret) {
"The group has no UUID\n");
}
groupname, &need_filter);
goto done;
}
if (need_filter) {
posix = false;
gid = 0;
}
"Adding fake group %s to sysdb\n", groupname);
goto done;
}
break;
}
}
if (ai == ldap_groups_count) {
"Group %s not present in LDAP\n", missing[i]);
goto done;
}
}
goto done;
}
in_transaction = false;
done:
if (in_transaction) {
}
}
return ret;
}
struct sss_domain_info *domain,
struct sdap_options *opts,
const char *name,
enum sysdb_member_type type,
char **sysdb_grouplist,
struct sysdb_attrs **ldap_groups,
int ldap_groups_count)
{
char **ldap_grouplist = NULL;
char **add_groups;
char **del_groups;
bool in_transaction = false;
if (ldap_groups_count == 0) {
/* No groups for this user in LDAP.
* We need to ensure that there are no groups
* in the sysdb either.
*/
} else {
"sysdb_attrs_primary_name_list failed [%d]: %s\n",
goto done;
}
}
/* Find the differences between the sysdb and LDAP lists
* Groups in the sysdb only must be removed.
*/
goto done;
}
in_transaction = true;
/* Add fake entries for any groups the user should be added as
* member of but that are not cached in sysdb
*/
if (add_groups && add_groups[0]) {
goto done;
}
}
(const char *const *) add_groups,
(const char *const *) del_groups);
goto done;
}
goto done;
}
in_transaction = false;
done:
if (in_transaction) {
}
}
return ret;
}
/* ==Initgr-call-(groups-a-user-is-member-of)-RFC2307===================== */
struct sdap_initgr_rfc2307_state {
struct tevent_context *ev;
struct sss_domain_info *domain;
struct sdap_options *opts;
struct sdap_handle *sh;
const char **attrs;
const char *name;
const char *base_filter;
const char *orig_dn;
char *filter;
int timeout;
struct sysdb_attrs **ldap_groups;
struct sdap_search_base **search_bases;
};
struct tevent_context *ev,
struct sdap_options *opts,
struct sss_domain_info *domain,
struct sdap_handle *sh,
const char *name)
{
struct tevent_req *req;
struct sdap_initgr_rfc2307_state *state;
const char **attr_filter;
char *clean_name;
char *oc_list;
state->ldap_groups_count = 0;
if (!state->search_bases) {
"Initgroups lookup request without a group search base\n");
goto done;
}
return NULL;
}
if (!attr_filter) {
return NULL;
}
return NULL;
}
return NULL;
}
goto done;
}
"(&(%s=%s)(%s)(%s=*)(&(%s=*)(!(%s=0))))",
if (!state->base_filter) {
return NULL;
}
done:
}
return req;
}
{
struct tevent_req *subreq;
struct sdap_initgr_rfc2307_state *state;
return ENOMEM;
}
"Searching for groups with base [%s]\n",
true);
if (!subreq) {
return ENOMEM;
}
return EOK;
}
{
struct tevent_req *req;
struct sdap_initgr_rfc2307_state *state;
struct sysdb_attrs **ldap_groups;
char **sysdb_grouplist = NULL;
int ret;
int i;
if (ret) {
return;
}
/* Add this batch of groups to the list */
if (count > 0) {
state->ldap_groups =
struct sysdb_attrs *,
if (!state->ldap_groups) {
return;
}
/* Copy the new groups into the list.
*/
for (i = 0; i < count; i++) {
}
}
/* Check for additional search bases, and iterate
* through again.
*/
}
return;
}
/* Search for all groups for which this user is a member */
return;
}
/* There are no nested groups here so we can just update the
* memberships */
return;
}
}
{
return EOK;
}
static errno_t
struct sss_domain_info *domain,
struct sdap_options *opts,
struct sysdb_attrs **groups,
unsigned long count)
{
char **groupnamelist = NULL;
bool in_transaction = false;
if (count > 0) {
"sysdb_attrs_primary_name_list failed [%d]: %s\n",
goto done;
}
}
goto done;
}
in_transaction = true;
goto done;
}
goto done;
}
in_transaction = false;
done:
if (in_transaction) {
}
}
return ret;
}
struct membership_diff {
struct membership_diff *prev;
struct membership_diff *next;
const char *name;
char **add;
char **del;
};
static errno_t
char **ldap_parent_names, char **sysdb_parent_names,
struct membership_diff **_mdiff)
{
struct membership_diff *mdiff;
char **add_groups;
char **del_groups;
if (!tmp_ctx) {
goto done;
}
if (!mdiff) {
goto done;
}
goto done;
}
/* Find the differences between the sysdb and ldap lists
* Groups in ldap only must be added to the sysdb;
* groups in the sysdb only must be removed.
*/
goto done;
}
done:
return ret;
}
/* ==Initgr-call-(groups-a-user-is-member-of)-nested-groups=============== */
struct sdap_initgr_nested_state {
struct tevent_context *ev;
struct sdap_options *opts;
struct sss_domain_info *dom;
struct sdap_handle *sh;
struct sysdb_attrs *user;
const char *username;
const char *orig_dn;
const char **grp_attrs;
struct ldb_message_element *memberof;
char *filter;
char **group_dns;
int cur;
struct sysdb_attrs **groups;
int groups_cur;
};
struct tevent_context *ev,
struct sdap_options *opts,
struct sss_domain_info *dom,
struct sdap_handle *sh,
struct sysdb_attrs *user,
const char **grp_attrs)
{
struct tevent_req *req;
struct sdap_initgr_nested_state *state;
int deref_threshold;
goto immediate;
}
/* We can't find any groups for this user, so we'll
* have to assume there aren't any. Just return
* success here.
*/
goto immediate;
}
goto immediate;
}
state->groups_cur = 0;
} else {
}
return req;
} else {
}
return req;
}
{
int i;
struct tevent_req *subreq;
struct sdap_initgr_nested_state *state;
char *oc_list;
return ENOMEM;
}
return ENOMEM;
}
}
return ENOMEM;
}
return ENOMEM;
}
false);
if (!subreq) {
return ENOMEM;
}
return EAGAIN;
}
{
struct tevent_req *subreq;
struct sdap_attr_map_info *maps;
const int num_maps = 1;
const char **sdap_attrs;
int timeout;
struct sdap_initgr_nested_state *state;
if (!subreq) {
goto fail;
}
return EAGAIN;
fail:
return ret;
}
{
struct tevent_req *req;
struct sdap_initgr_nested_state *state;
size_t i;
struct sdap_deref_attrs **deref_result;
&deref_result);
} else {
}
}
return;
return;
/* Nothing could be dereferenced. Done. */
return;
}
for (i=0; i < num_results; i++) {
deref_result[i]->attrs);
}
}
{
struct tevent_req *req;
struct sdap_initgr_nested_state *state;
struct sysdb_attrs **groups;
int ret;
if (ret) {
return;
}
if (count == 1) {
groups[0]);
state->groups_cur++;
} else {
"Search for group %s, returned %zu results. Skipping\n",
}
/* note that state->memberof->num_values is the count of original
* memberOf which might not be only groups, but permissions, etc.
* Use state->groups_cur for group index cap */
false);
if (!subreq) {
return;
}
} else {
}
}
static errno_t
static errno_t
static errno_t
{
struct sdap_initgr_nested_state *state;
bool in_transaction = false;
goto fail;
}
in_transaction = true;
/* save the groups if they are not already */
goto fail;
}
/* save the group memberships */
"Could not save group memberships [%d]: %s\n",
goto fail;
}
/* save the user memberships */
"Could not save user memberships [%d]: %s\n",
goto fail;
}
goto fail;
}
in_transaction = false;
return;
fail:
if (in_transaction) {
}
}
return;
}
static errno_t
{
state->groups_cur);
}
static errno_t
struct sdap_options *opts,
struct sss_domain_info *dom,
struct sysdb_attrs *group,
struct sysdb_attrs **all_groups,
int groups_count,
struct membership_diff **mdiff);
struct sysdb_attrs *attrs,
struct sysdb_attrs **groups,
int ngroups,
struct sysdb_attrs ***_direct_parents,
int *_ndirect);
static errno_t
{
int i, tret;
bool in_transaction = false;
/* Compute the diffs first in order to keep the transaction as small
* as possible
*/
for (i=0; i < state->groups_cur; i++) {
&miter);
if (ret) {
"Could not compute memberships for group %d [%d]: %s\n",
goto done;
}
}
goto done;
}
in_transaction = true;
goto done;
}
}
goto done;
}
in_transaction = false;
done:
if (in_transaction) {
}
}
return ret;
}
static errno_t
{
int tret;
const char *orig_dn;
char **sysdb_parent_name_list = NULL;
char **ldap_parent_name_list = NULL;
int nparents;
struct sysdb_attrs **ldap_parentlist;
struct ldb_message_element *el;
int i, mi;
char **add_groups;
char **del_groups;
bool in_transaction = false;
if (!tmp_ctx) {
goto done;
}
/* Get direct LDAP parents */
goto done;
}
if (!ldap_parentlist) {
goto done;
}
nparents = 0;
for (i=0; i < state->groups_cur ; i++) {
if (ret) {
"A group with no members during initgroups?\n");
goto done;
}
continue;
}
nparents++;
}
}
"The user %s is a direct member of %d LDAP groups\n",
if (nparents == 0) {
} else {
"sysdb_attrs_primary_name_list failed [%d]: %s\n",
goto done;
}
}
if (ret) {
"Could not get direct sysdb parents for %s: %d [%s]\n",
goto done;
}
goto done;
}
goto done;
}
in_transaction = true;
(const char *const *) add_groups,
(const char *const *) del_groups);
"Could not update sysdb memberships for %s: %d [%s]\n",
goto done;
}
goto done;
}
in_transaction = false;
done:
if (in_transaction) {
}
}
return ret;
}
static errno_t
struct sdap_options *opts,
struct sss_domain_info *dom,
struct sysdb_attrs *group,
struct sysdb_attrs **all_groups,
int groups_count,
struct membership_diff **_mdiff)
{
struct membership_diff *mdiff;
const char *group_name;
struct sysdb_attrs **ldap_parentlist;
int parents_count;
char **ldap_parent_names_list = NULL;
char **sysdb_parents_names_list = NULL;
if (!tmp_ctx) {
goto done;
}
/* Get direct sysdb parents */
goto done;
}
if (ret) {
"Could not get direct sysdb parents for %s: %d [%s]\n",
goto done;
}
/* For each group, filter only parents from full set */
goto done;
}
"The group %s is a direct member of %d LDAP groups\n",
if (parents_count > 0) {
"sysdb_attrs_primary_name_list failed [%d]: %s\n",
goto done;
}
}
"Could not build membership diff for %s [%d]: %s\n",
goto done;
}
done:
return ret;
}
struct sysdb_attrs *attrs,
struct sysdb_attrs **groups,
int ngroups,
struct sysdb_attrs ***_direct_parents,
int *_ndirect)
{
struct ldb_message_element *member;
int i, mi;
int ret;
const char *orig_dn;
int ndirect;
struct sysdb_attrs **direct_groups;
ngroups + 1);
if (!direct_groups) {
goto done;
}
ndirect = 0;
goto done;
}
"Looking up direct parents for group [%s]\n", orig_dn);
/* FIXME - Filter only parents from full set to avoid searching
* through all members of huge groups. That requires asking for memberOf
* with the group LDAP search
*/
/* Filter only direct parents from the list of all groups */
for (i=0; i < ngroups; i++) {
if (ret) {
"A group with no members during initgroups?\n");
continue;
}
continue;
}
ndirect++;
}
}
done:
return ret;
}
{
return EOK;
}
/* ==Initgr-call-(groups-a-user-is-member-of)-RFC2307-BIS================= */
struct sdap_initgr_rfc2307bis_state {
struct tevent_context *ev;
struct sdap_options *opts;
struct sss_domain_info *dom;
struct sdap_handle *sh;
const char *name;
char *base_filter;
char *filter;
const char **attrs;
const char *orig_dn;
int timeout;
struct sdap_search_base **search_bases;
struct sysdb_attrs **direct_groups;
};
struct sdap_nested_group {
struct sysdb_attrs *group;
struct sysdb_attrs **ldap_parents;
};
struct sdap_initgr_rfc2307bis_state *state);
struct tevent_req *rfc2307bis_nested_groups_send(
struct sdap_search_base **search_bases,
static struct tevent_req *sdap_initgr_rfc2307bis_send(
struct tevent_context *ev,
struct sdap_options *opts,
struct sdap_domain *sdom,
struct sdap_handle *sh,
const char *name,
const char *orig_dn)
{
struct tevent_req *req;
struct sdap_initgr_rfc2307bis_state *state;
const char **attr_filter;
char *clean_orig_dn;
bool use_id_mapping;
char *oc_list;
state->num_direct_parents = 0;
if (!state->search_bases) {
"Initgroups lookup request without a group search base\n");
goto done;
}
return NULL;
}
if (!attr_filter) {
goto done;
}
goto done;
}
state->base_filter =
"(&(%s=%s)(%s)(%s=*)",
if (!state->base_filter) {
goto done;
}
if (use_id_mapping) {
/* When mapping IDs or looking for SIDs, we don't want to limit
* ourselves to groups with a GID value. But there must be a SID to map
* from.
*/
"(%s=*))",
} else {
}
if (!state->base_filter) {
return NULL;
}
done:
}
return req;
}
{
struct tevent_req *subreq;
struct sdap_initgr_rfc2307bis_state *state;
return ENOMEM;
}
"Searching for parent groups for user [%s] with base [%s]\n",
true);
if (!subreq) {
return ENOMEM;
}
return EOK;
}
{
struct tevent_req *req;
struct sdap_initgr_rfc2307bis_state *state;
struct sysdb_attrs **ldap_groups;
size_t i;
int ret;
&count,
&ldap_groups);
if (ret) {
return;
}
/* Add this batch of groups to the list */
if (count > 0) {
struct sysdb_attrs *,
if (!state->direct_groups) {
return;
}
/* Copy the new groups into the list.
*/
for (i = 0; i < count; i++) {
}
}
/* Check for additional search bases, and iterate
* through again.
*/
}
return;
}
if (state->num_direct_parents == 0) {
/* Start a transaction to look up the groups in the sysdb
* and update them with LDAP data
*/
} else {
}
return;
}
state->group_hash, 0);
if (!subreq) {
return;
}
}
static errno_t
static errno_t
{
struct tevent_req *req =
struct sdap_initgr_rfc2307bis_state *state =
bool in_transaction = false;
return;
}
goto fail;
}
in_transaction = true;
/* save the groups if they are not cached */
"Could not save groups memberships [%d]\n", ret);
goto fail;
}
/* save the group membership */
"Could not save group memberships [%d]\n", ret);
goto fail;
}
/* save the user memberships */
"Could not save user memberships [%d]\n", ret);
goto fail;
}
goto fail;
}
in_transaction = false;
return;
fail:
if (in_transaction) {
}
}
return;
}
{
return EOK;
}
struct rfc2307bis_group_memberships_state {
struct sdap_options *opts;
struct sss_domain_info *dom;
struct membership_diff *memberships;
int ret;
};
static errno_t
{
unsigned long count;
int hret, i;
struct sdap_nested_group *gr;
if (hret != HASH_SUCCESS) {
goto done;
}
if (!groups) {
goto done;
}
for (i = 0; i < count; i++) {
struct sdap_nested_group);
}
goto done;
}
done:
return ret;
}
static errno_t
{
int hret;
struct membership_diff *iter;
struct membership_diff *iter_start;
struct membership_diff *iter_tmp;
bool in_transaction = false;
int num_added;
int i;
int grp_count;
struct rfc2307bis_group_memberships_state);
if (!membership_state) {
goto done;
}
if (hret != HASH_SUCCESS) {
goto done;
}
goto done;
}
in_transaction = true;
/* Create a copy of iter->add array but do not include groups outside
* nesting limit. This array must be NULL terminated.
*/
goto done;
}
num_added = 0;
for (i = 0; i < grp_count; i++) {
num_added++;
break;
}
}
}
if (num_added == 0) {
} else {
}
(const char *const *) add,
goto done;
}
}
goto done;
}
in_transaction = false;
done:
if (in_transaction) {
}
}
return ret;
}
static bool
{
user_data, struct rfc2307bis_group_memberships_state);
struct sdap_nested_group *group;
char *group_name;
char **sysdb_parents_names_list;
char **ldap_parents_names_list = NULL;
struct membership_diff *mdiff;
if (!tmp_ctx) {
goto done;
}
if (ret) {
"Could not get direct sysdb parents for %s: %d [%s]\n",
goto done;
}
if (group->parents_count > 0) {
goto done;
}
}
"Could not build membership diff for %s [%d]: %s\n",
goto done;
}
done:
}
struct sdap_initgr_rfc2307bis_state *state)
{
char **ldap_grouplist;
char **sysdb_parent_name_list;
char **add_groups;
char **del_groups;
bool in_transaction = false;
size_t c;
char *tmp_str;
if(!tmp_ctx) {
return ENOMEM;
}
goto error;
}
in_transaction = true;
if (ret) {
"Could not get direct sysdb parents for %s: %d [%s]\n",
goto error;
}
if (state->num_direct_parents == 0) {
}
else {
goto error;
}
for (c = 0; ldap_grouplist[c] != NULL; c++) {
goto error;
}
ldap_grouplist[c] = tmp_str;
}
}
}
/* Find the differences between the sysdb and ldap lists
* Groups in ldap only must be added to the sysdb;
* groups in the sysdb only must be removed.
*/
goto error;
}
(const char *const *)add_groups,
(const char *const *)del_groups);
goto error;
}
goto error;
}
in_transaction = false;
return EOK;
if (in_transaction) {
}
}
return ret;
}
struct sdap_rfc2307bis_nested_ctx {
struct tevent_context *ev;
struct sdap_options *opts;
struct sss_domain_info *dom;
struct sdap_handle *sh;
int timeout;
const char *base_filter;
char *filter;
const char *orig_dn;
const char **attrs;
struct sysdb_attrs **groups;
struct sdap_nested_group **processed_groups;
const char *primary_name;
struct sysdb_handle *handle;
struct sdap_search_base **search_bases;
};
struct tevent_req *rfc2307bis_nested_groups_send(
struct sdap_search_base **search_bases,
{
struct tevent_req *req;
struct sdap_rfc2307bis_nested_ctx *state;
"About to process %zu groups in nesting level %zu\n",
struct sdap_rfc2307bis_nested_ctx);
if ((num_groups == 0) ||
/* No parent groups to process or too deep*/
goto done;
}
state->group_iter = 0;
if (!state->search_bases) {
"Initgroups nested lookup request "
"without a group search base\n");
goto done;
}
struct sdap_nested_group *,
state->num_groups);
goto done;
}
/* This group had already been looked up. Continue to
* another group in the same level
*/
state->group_iter++;
continue;
} else {
goto done;
}
}
done:
/* All parent groups were already processed */
}
/* EAGAIN means a lookup is in progress */
return req;
}
{
const char **attr_filter;
char *clean_orig_dn;
struct sdap_rfc2307bis_nested_ctx *state =
char *oc_list;
if (!tmp_ctx) {
goto done;
}
goto done;
}
goto done;
}
if (ret == HASH_SUCCESS) {
goto done;
}
/* Need to try to find parent groups for this group. */
goto done;
}
/* this steal doesn't change much now, but will be helpful later on
* if we steal the whole processed_group on the hash table */
/* Get any parent groups for this group */
goto done;
}
if (!attr_filter) {
goto done;
}
goto done;
}
goto done;
}
goto done;
}
state, "(&(%s=%s)(%s)(%s=*))",
if (!state->base_filter) {
goto done;
}
/* Still processing parent groups */
done:
return ret;
}
{
struct tevent_req *subreq;
struct sdap_rfc2307bis_nested_ctx *state;
return ENOMEM;
}
"Searching for parent groups of group [%s] with base [%s]\n",
true);
if (!subreq) {
return ENOMEM;
}
req);
return EOK;
}
static void
struct sdap_rfc2307bis_nested_ctx *state)
{
state->group_iter++;
/* Looking up parent groups.. */
return;
return;
}
/* EOK means this group has already been processed
* in another nesting level */
state->group_iter++;
}
/* All groups processed. Done. */
}
}
{
struct tevent_req *req =
struct sdap_rfc2307bis_nested_ctx *state =
size_t i;
struct sysdb_attrs **ldap_groups;
struct sdap_nested_group *ngr;
int hret;
&count,
&ldap_groups);
if (ret) {
return;
}
/* Add this batch of groups to the list */
if (count > 0) {
ngr->ldap_parents =
struct sysdb_attrs *,
if (!ngr->ldap_parents) {
return;
}
/* Copy the new groups into the list.
* They're allocated on 'state' so we need to move them
* onto ldap_parents so that the data won't disappear when
* we finish this nesting level.
*/
for (i = 0; i < count; i++) {
}
"Total of %zu direct parents after this iteration\n",
ngr->parents_count);
}
/* Check for additional search bases, and iterate
* through again.
*/
}
return;
}
/* Reset the base iterator for future lookups */
/* Save the group into the hash table */
return;
}
/* Steal the nested group entry on the group_hash context so it can
* outlive this request */
if (hret != HASH_SUCCESS) {
return;
}
if (ngr->parents_count == 0) {
/* No parent groups for this group in LDAP
* Move on to the next group
*/
return;
}
/* Otherwise, recurse into the groups */
if (!subreq) {
return;
}
}
{
return EOK;
}
{
struct tevent_req *req =
struct sdap_rfc2307bis_nested_ctx *state =
return;
}
}
/* ==Initgr-call-(groups-a-user-is-member-of)============================= */
struct sdap_get_initgr_state {
struct tevent_context *ev;
struct sdap_options *opts;
struct sss_domain_info *dom;
struct sdap_domain *sdom;
struct sdap_handle *sh;
struct sdap_id_ctx *id_ctx;
struct sdap_id_conn_ctx *conn;
const char *name;
const char **grp_attrs;
const char **user_attrs;
char *user_base_filter;
char *filter;
int timeout;
struct sysdb_attrs *orig_user;
struct sdap_search_base **user_search_bases;
bool use_id_mapping;
};
struct tevent_context *ev,
struct sdap_domain *sdom,
struct sdap_handle *sh,
struct sdap_id_ctx *id_ctx,
struct sdap_id_conn_ctx *conn,
const char *name,
int name_type,
const char *extra_value,
const char **grp_attrs)
{
struct tevent_req *req;
struct sdap_get_initgr_state *state;
int ret;
char *clean_name;
bool use_id_mapping;
const char *search_attr;
state->user_base_iter = 0;
if (!state->user_search_bases) {
"Initgroups lookup request without a user search base\n");
goto done;
}
return NULL;
}
} else {
switch (name_type) {
case BE_FILTER_SECID:
break;
case BE_FILTER_UUID:
break;
default:
}
}
if (!state->user_base_filter) {
return NULL;
}
if (use_id_mapping) {
/* When mapping IDs or looking for SIDs, we don't want to limit
* ourselves to users with a UID value. But there must be a SID to map
* from.
*/
"(%s=*))",
} else {
/* When not ID-mapping, make sure there is a non-NULL UID */
"(&(%s=*)(!(%s=0))))",
}
if (!state->user_base_filter) {
return NULL;
}
if (ret) {
return NULL;
}
done:
}
return req;
}
{
struct tevent_req *subreq;
struct sdap_get_initgr_state *state;
return ENOMEM;
}
"Searching for users with base [%s]\n",
false);
if (!subreq) {
return ENOMEM;
}
return EOK;
}
{
struct tevent_req);
struct sdap_get_initgr_state);
struct sysdb_attrs **usr_attrs;
int ret;
const char *orig_dn;
const char *cname;
bool in_transaction = false;
if (ret) {
return;
}
if (count == 0) {
/* No users found in this search */
state->user_base_iter++;
/* There are more search bases to try */
}
return;
}
/* fallback to fetch a local user if required */
SDAP_RFC2307_FALLBACK_TO_LOCAL_USERS) == true)) {
} else {
}
return;
}
} else if (count == 1) {
} else if (count != 1) {
"Expected one user entry and got %zu\n", count);
"try_to_find_expected_dn failed. No matching DN found.\n");
return;
}
}
if (ret) {
goto fail;
}
in_transaction = true;
NULL, 0);
if (ret) {
goto fail;
}
if (ret) {
goto fail;
}
in_transaction = false;
return;
}
case SDAP_SCHEMA_RFC2307:
cname);
if (!subreq) {
return;
}
break;
case SDAP_SCHEMA_RFC2307BIS:
case SDAP_SCHEMA_AD:
&orig_dn);
return;
}
/* Take advantage of AD's tokenGroups mechanism to look up all
* parent groups in a single request.
*/
/* Take advantage of AD's extensibleMatch filter to look up
* all parent groups in a single request.
*/
} else {
}
if (!subreq) {
return;
}
break;
case SDAP_SCHEMA_IPA_V1:
if (!subreq) {
return;
}
return;
default:
return;
}
return;
fail:
if (in_transaction) {
}
}
}
{
struct tevent_req);
struct sdap_get_initgr_state);
int ret;
char *gid;
char *sid_str;
char *dom_sid_str;
char *group_sid_str;
struct ldb_message *msg;
if (!tmp_ctx) {
return;
}
case SDAP_SCHEMA_RFC2307:
break;
case SDAP_SCHEMA_RFC2307BIS:
case SDAP_SCHEMA_AD:
}
} else {
}
break;
case SDAP_SCHEMA_IPA_V1:
break;
default:
break;
}
if (ret) {
goto done;
}
/* We also need to update the user's primary group, since
* the user may not be an explicit member of that group
*/
if (state->use_id_mapping) {
"Mapping primary group to unix ID\n");
/* The primary group ID is just the RID part of the objectSID
* of the group. Generate the GID by adding this to the domain
* SID value.
*/
/* Get the user SID so we can extract the domain SID
* from it.
*/
&sid_str);
/* Get the domain SID from the user SID */
&dom_sid_str);
"Could not parse domain SID from [%s]\n", sid_str);
goto done;
}
&primary_gid);
"no primary group ID provided\n");
goto done;
}
/* Add the RID to the end */
(unsigned long)primary_gid);
if (!group_sid_str) {
goto done;
}
/* Convert the SID into a UNIX group ID */
&primary_gid);
} else {
&primary_gid);
goto done;
}
}
&msg);
"Primary group already cached, nothing to do.\n");
goto done;
} else {
goto done;
}
false);
if (!subreq) {
goto done;
}
}
return;
done:
} else {
}
return;
}
{
struct tevent_req *req =
return;
}
}
{
return EOK;
}
struct sss_domain_info *domain,
const char *name,
char ***grouplist,
bool get_dn)
{
const char *attrs[2];
struct ldb_message *msg;
struct ldb_message_element *groups;
char **sysdb_grouplist = NULL;
unsigned int i;
attrs[0] = SYSDB_MEMBEROF;
"Error searching user [%s] by name: [%s]\n",
goto done;
}
/* No groups for this user in sysdb currently */
} else {
if (!sysdb_grouplist) {
goto done;
}
if (get_dn) {
/* Get distinguish name */
for (i=0; i < groups->num_values; i++) {
if (sysdb_grouplist[i] == NULL) {
goto done;
}
}
} else {
/* Get a list of the groups by groupname only */
for (i=0; i < groups->num_values; i++) {
&sysdb_grouplist[i]);
"Could not determine group name from [%s]: [%s]\n",
goto done;
}
}
}
}
done:
return ret;
}
struct sss_domain_info *domain,
const char *name,
char ***grouplist)
{
}
struct sss_domain_info *domain,
const char *name,
char ***grouplist)
{
}