sdap_async_initgroups_ad.c revision 174e9ec6f88d709b6e9481ed06a322c0fc495842
/*
SSSD
Authors:
Stephen Gallagher <sgallagh@redhat.com>
Copyright (C) 2012 Red Hat
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.h"
#include "providers/ldap/ldap_common.h"
#include "providers/ldap/sdap_async_private.h"
#include "providers/ldap/sdap_idmap.h"
#include "providers/ad/ad_common.h"
#include "lib/idmap/sss_idmap.h"
struct sdap_ad_match_rule_initgr_state {
struct tevent_context *ev;
struct sdap_options *opts;
struct sss_domain_info *domain;
struct sdap_handle *sh;
const char *name;
const char *orig_dn;
const char **attrs;
int timeout;
const char *base_filter;
char *filter;
struct sysdb_attrs **groups;
struct sdap_search_base **search_bases;
};
static errno_t
static void
struct tevent_req *
struct tevent_context *ev,
struct sdap_options *opts,
struct sss_domain_info *domain,
struct sdap_handle *sh,
const char *name,
const char *orig_dn,
int timeout)
{
struct tevent_req *req;
struct sdap_ad_match_rule_initgr_state *state;
const char **filter_members;
char *sanitized_user_dn;
struct sdap_ad_match_rule_initgr_state);
/* Request all of the group attributes that we know
* about, except for 'member' because that wastes a
* lot of bandwidth here and we only really
* care about a single member (the one we already
* have).
*/
if (!filter_members) {
goto immediate;
}
"Could not build attribute map: [%s]\n",
goto immediate;
}
/* Sanitize the user DN in case we have special characters in DN */
"Could not sanitize user DN: %s\n",
goto immediate;
}
/* Craft a special filter according to
*/
state->base_filter =
"(&(%s:%s:=%s)(objectClass=%s))",
if (!state->base_filter) {
goto immediate;
}
/* Start the loop through the search bases to get all of the
* groups to which this user belongs.
*/
"sdap_get_ad_match_rule_members_next_base failed: [%s]\n",
goto immediate;
}
return req;
return req;
}
static errno_t
{
struct tevent_req *subreq;
struct sdap_ad_match_rule_initgr_state *state;
return ENOMEM;
}
"Searching for groups with base [%s]\n",
if (!subreq) {
return ENOMEM;
}
req);
return EOK;
}
static void
{
struct tevent_req *req =
struct sdap_ad_match_rule_initgr_state *state =
struct sysdb_attrs **groups;
char **sysdb_grouplist;
goto error;
}
"Search for users returned %zu results\n", count);
/* Add this batch of groups to the list */
if (count > 0) {
struct sysdb_attrs *,
return;
}
/* Copy the new groups into the list */
for (i = 0; i < count; i++) {
}
}
/* Continue checking other search bases */
/* There are more search bases to try */
goto error;
}
return;
}
/* No more search bases. Save the groups. */
"User is not a member of any group in the search bases\n");
}
/* Get the current sysdb group list for this user
* so we can update it.
*/
"Could not get the list of groups for [%s] in the sysdb: "
"[%s]\n",
goto error;
}
/* The extensibleMatch search rule eliminates the need for
* nested group searches, so we can just update the
* memberships now.
*/
"Could not store groups for user [%s]: [%s]\n",
goto error;
}
return;
}
{
return EOK;
}
struct sdap_get_ad_tokengroups_state {
struct tevent_context *ev;
struct sss_idmap_ctx *idmap_ctx;
const char *username;
char **sids;
};
static struct tevent_req *
struct tevent_context *ev,
struct sdap_options *opts,
struct sdap_handle *sh,
const char *name,
const char *orig_dn,
int timeout)
{
struct sdap_get_ad_tokengroups_state);
return NULL;
}
goto immediately;
}
goto immediately;
}
return req;
} else {
}
return req;
}
{
enum idmap_error_code err;
size_t i;
goto done;
}
if (num_users != 1) {
"More than one result on a base search!\n");
goto done;
}
/* get the list of sids from tokengroups */
goto done;
goto done;
}
goto done;
}
/* convert binary sid to string */
for (i = 0; i < el->num_values; i++) {
if (err != IDMAP_SUCCESS) {
"Could not convert binary SID to string: [%s]. Skipping\n",
continue;
}
}
/* shrink array to final number of elements */
goto done;
}
done:
return;
}
}
struct tevent_req *req,
char ***_sids)
{
}
}
return EOK;
}
static errno_t
sdap_ad_tokengroups_update_members(const char *username,
struct sss_domain_info *domain,
char **ldap_groups)
{
char **sysdb_groups = NULL;
char **add_groups = NULL;
char **del_groups = NULL;
return ENOMEM;
}
/* Get the current sysdb group list for this user so we can update it. */
username, &sysdb_groups);
goto done;
}
/* Find the differences between the sysdb and LDAP lists.
* Groups in the sysdb only must be removed. */
goto done;
}
(const char *const *) add_groups,
(const char *const *) del_groups);
goto done;
}
done:
return ret;
}
struct sdap_ad_resolve_sids_state {
struct tevent_context *ev;
struct sdap_id_ctx *id_ctx;
struct sdap_id_conn_ctx *conn;
struct sdap_options *opts;
struct sss_domain_info *domain;
char **sids;
const char *current_sid;
int index;
};
static struct tevent_req *
struct tevent_context *ev,
struct sdap_id_ctx *id_ctx,
struct sdap_id_conn_ctx *conn,
struct sdap_options *opts,
struct sss_domain_info *domain,
char **sids)
{
struct sdap_ad_resolve_sids_state);
return NULL;
}
goto immediately;
}
goto immediately;
}
return req;
} else {
}
return req;
}
{
do {
return EOK;
}
state->current_sid);
}
if (sdap_domain == NULL) {
return ERR_INTERNAL;
}
BE_FILTER_SECID, BE_ATTR_CORE, false);
return ENOMEM;
}
return EAGAIN;
}
{
int dp_error;
int sdap_error;
/* Group was not found, we will ignore the error and continue with
* next group. This may happen for example if the group is built-in,
* but a custom search base is provided. */
"Unable to resolve SID %s - will try next sid.\n",
state->current_sid);
goto done;
}
/* continue with next SID */
return;
}
done:
return;
}
}
{
return EOK;
}
struct tevent_context *ev;
struct sdap_options *opts;
struct sdap_handle *sh;
struct sdap_idmap_ctx *idmap_ctx;
struct sss_domain_info *domain;
const char *orig_dn;
int timeout;
const char *username;
struct sdap_id_op *op;
};
static void
struct tevent_context *ev,
struct sdap_options *opts,
const char *orig_dn,
int timeout,
const char *username,
struct sdap_handle *sh,
struct tevent_req *req,
static struct tevent_req *
struct tevent_context *ev,
struct sdap_options *opts,
struct sss_domain_info *domain,
struct sdap_handle *sh,
const char *name,
const char *orig_dn,
int timeout)
{
struct sdap_domain *sdom;
struct ad_id_ctx *subdom_id_ctx;
return NULL;
}
goto immediately;
}
return req;
} else {
goto immediately;
}
}
goto immediately;
}
goto immediately;
}
req);
return req;
} else {
}
return req;
}
static void
{
int ret;
int dp_error = DP_ERR_FATAL;
return;
}
return;
}
req);
return;
}
{
size_t i;
bool in_transaction = false;
goto done;
}
goto done;
}
num_groups = 0;
goto done;
}
goto done;
}
in_transaction = true;
for (i = 0; i < num_sids; i++) {
continue;
continue;
}
continue;
}
/* Check whether this GID already exists in the sysdb */
"Could not retrieve group name from sysdb\n");
goto done;
}
/* This is a new group. For now, we will store it under the name
* of its SID. When a direct lookup of the group or its GID occurs,
* it will replace this temporary entry. */
goto done;
}
} else {
/* Unexpected error */
goto done;
}
goto done;
}
num_groups++;
}
groups);
goto done;
}
goto done;
}
in_transaction = false;
done:
if (in_transaction) {
}
return;
}
}
{
return EOK;
}
struct tevent_context *ev;
struct sdap_id_ctx *id_ctx;
struct sdap_id_conn_ctx *conn;
struct sdap_options *opts;
struct sdap_handle *sh;
struct sss_domain_info *domain;
const char *orig_dn;
int timeout;
const char *username;
struct sdap_id_op *op;
char **missing_sids;
};
static void
static void
static void
static struct tevent_req *
struct tevent_context *ev,
struct sdap_id_ctx *id_ctx,
struct sdap_id_conn_ctx *conn,
struct sdap_options *opts,
struct sss_domain_info *domain,
struct sdap_handle *sh,
const char *name,
const char *orig_dn,
int timeout)
{
struct sdap_domain *sdom;
struct ad_id_ctx *subdom_id_ctx;
return NULL;
}
goto immediately;
}
return req;
} else {
goto immediately;
}
}
goto immediately;
}
goto immediately;
}
req);
return req;
} else {
}
return req;
}
static void
{
int ret;
int dp_error = DP_ERR_FATAL;
return;
}
return;
}
req);
return;
}
static errno_t
char **sids,
char ***_missing)
{
char **valid_groups = NULL;
char **missing_sids = NULL;
size_t i;
goto done;
}
num_valid_groups = 0;
if (valid_groups == NULL) {
goto done;
}
num_missing_sids = 0;
if (missing_sids == NULL) {
goto done;
}
/* For each SID check if it is already present in the cache. If yes, we
* will get name of the group and update the membership. Otherwise we need
* to remember the SID and download missing groups one by one. */
for (i = 0; i < num_sids; i++) {
continue;
}
/* skip non-posix group */
continue;
}
/* we will update membership of this group */
"Could not retrieve group name from sysdb\n");
goto done;
}
name);
goto done;
}
/* we need to download this group */
sid);
sid);
}
/* else: We have downloaded missing groups but some of them may
* remained missing because they are outside of search base. We
* will just ignore them and continue with the next group. */
} else {
goto done;
}
}
/* update membership of existing groups */
goto done;
}
/* return list of missing groups */
}
done:
return ret;
}
static void
{
goto done;
}
&state->missing_sids);
goto done;
}
/* download missing SIDs */
goto done;
}
req);
return;
done:
return;
}
}
static void
{
goto done;
}
done:
return;
}
}
{
return EOK;
}
struct sdap_ad_tokengroups_initgroups_state {
bool use_id_mapping;
struct sss_domain_info *domain;
};
struct tevent_req *
struct tevent_context *ev,
struct sdap_id_ctx *id_ctx,
struct sdap_id_conn_ctx *conn,
struct sdap_options *opts,
struct sss_domain_info *domain,
struct sdap_handle *sh,
const char *name,
const char *orig_dn,
int timeout,
bool use_id_mapping)
{
struct sdap_ad_tokengroups_initgroups_state);
return NULL;
}
timeout);
} else {
timeout);
}
goto immediately;
}
return req;
} else {
}
return req;
}
{
} else {
}
goto done;
}
done:
return;
}
}
{
return EOK;
}
struct tevent_context *ev,
struct sdap_options *opts,
const char *orig_dn,
int timeout,
const char *username,
struct sdap_handle *sh,
struct tevent_req *req,
{
/* plain LDAP provider already has a sdap_handle */
goto done;
}
goto done;
} else {
goto done;
}
done:
return ret;
}