ipa_subdomains_ext_groups.c revision 3d29430867cf92b2d71afa95abb679711231117c
/*
SSSD
IPA Identity Backend Module for sub-domains - evaluate external group
memberships
Authors:
Sumit Bose <sbose@redhat.com>
Copyright (C) 2013 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/ldap_common.h"
#include "providers/ldap/sdap_async.h"
#include "providers/ipa/ipa_subdomains.h"
#define IPA_EXT_GROUPS_FILTER "objectClass=ipaexternalgroup"
struct ipa_ext_groups {
};
struct sysdb_attrs **reply,
{
int ret;
size_t g;
size_t s;
size_t m;
const char **ext_sids;
const char **mof;
goto done;
}
if (ret != HASH_SUCCESS) {
goto done;
}
for (g = 0; g < reply_count; g++) {
/* no external members, try next external group. */
continue;
"sysdb_attrs_get_string_array failed.\n");
goto done;
}
/* no IPA groups, try next external group. */
continue;
"sysdb_attrs_get_string_array failed.\n");
goto done;
}
/* hash_lookup does not modify key.str. */
if (ret == HASH_SUCCESS) {
goto done;
}
/* hash_enter does not modify m_key.str. */
if (ret != HASH_SUCCESS) {
goto done;
}
}
} else if (ret == HASH_ERROR_KEY_NOT_FOUND) {
if (ret != HASH_SUCCESS) {
goto done;
}
if (ret != HASH_SUCCESS) {
goto done;
}
/* hash_enter does not modify m_key.str. */
if (ret != HASH_SUCCESS) {
goto done;
}
}
} else {
goto done;
}
}
}
done:
} else {
}
return ret;
}
const char *user_name,
struct sss_domain_info *user_dom,
char ***_groups)
{
int ret;
struct ldb_result *result;
size_t c;
const char *sid;
struct hash_iter_context_t *iter;
return ENOMEM;
}
goto done;
}
goto done;
}
if (ret != HASH_SUCCESS) {
goto done;
}
/* The IPA external domains can have references to group and user SIDs.
* This means that we not only want to look up the group SIDs but the SID
* of the user (first element of result) as well. */
NULL);
continue;
}
if (ret == HASH_ERROR_KEY_NOT_FOUND) {
sid);
} else if (ret == HASH_SUCCESS) {
goto done;
}
if (ret != HASH_SUCCESS) {
}
}
} else {
sid);
}
}
if (g_count == 0) {
goto done;
}
goto done;
}
goto done;
}
c = 0;
goto done;
}
c++;
}
goto done;
}
done:
return ret;
}
struct sss_domain_info *user_dom,
struct sss_domain_info *group_dom,
char **groups,
bool *missing_groups)
{
size_t c;
struct sysdb_attrs *user_attrs;
struct ldb_message **msgs;
char *subfilter;
int ret;
*missing_groups = false;
return ENOMEM;
}
if (groups[c][0] == '\0') {
continue;
}
goto done;
}
&msgs_count, &msgs);
groups[c]);
*missing_groups = true;
continue;
} else {
goto done;
}
}
/* TODO? Do we have to remove members as well? I think not because the AD
* query before removes all memberships. */
goto done;
}
if (user_attrs == NULL) {
goto done;
}
groups[c]);
goto done;
}
goto done;
}
/* mark group as already processed */
groups[c][0] = '\0';
}
done:
return ret;
}
struct tevent_context *ev,
struct sdap_id_ctx *sdap_id_ctx,
struct sss_domain_info *user_dom,
char **groups,
struct sss_domain_info *group_dom);
struct get_ad_membership_state {
struct tevent_context *ev;
struct ipa_server_mode_ctx *server_mode;
struct sdap_id_op *sdap_op;
struct sdap_id_ctx *sdap_id_ctx;
char *user_name;
struct sss_domain_info *user_dom;
int dp_error;
const char *domain;
struct sysdb_attrs **reply;
};
int *dp_error_out);
struct tevent_context *ev,
struct dp_id_data *ar,
struct ipa_server_mode_ctx *server_mode,
struct sss_domain_info *user_dom,
struct sdap_id_ctx *sdap_id_ctx,
const char *domain)
{
int ret;
struct tevent_req *req;
struct tevent_req *subreq;
struct get_ad_membership_state *state;
return NULL;
}
goto done;
}
goto done;
}
goto done;
}
struct ipa_ext_groups);
goto done;
}
}
goto done;
return req;
} else {
goto done;
}
}
goto done;
}
return req;
done:
} else {
}
return req;
}
{
struct tevent_req);
struct get_ad_membership_state);
int ret;
char *basedn;
"No IPA server is available, going offline\n");
} else {
"Failed to connect to IPA server: [%d](%s)\n",
}
goto fail;
}
goto fail;
}
false);
goto fail;
}
return;
fail:
return;
}
{
struct tevent_req);
struct get_ad_membership_state);
int ret;
return;
}
state->reply_count);
goto fail;
}
/* Do we have to make the update timeout configurable? */
return;
return;
} else {
goto fail;
}
fail:
return;
}
{
struct get_ad_membership_state);
int ret;
struct tevent_req *subreq;
goto fail;
}
return EOK;
}
goto fail;
}
return EAGAIN;
fail:
return ret;
}
{
struct tevent_req);
struct get_ad_membership_state);
int ret;
return;
}
return;
}
{
struct get_ad_membership_state);
if (dp_error_out) {
}
return EOK;
}
struct add_ad_membership_state {
struct tevent_context *ev;
struct sdap_id_ctx *sdap_id_ctx;
struct sdap_id_op *sdap_op;
struct sss_domain_info *user_dom;
struct sss_domain_info *group_dom;
char **groups;
int dp_error;
struct sdap_domain *group_sdom;
};
struct tevent_context *ev,
struct sdap_id_ctx *sdap_id_ctx,
struct sss_domain_info *user_dom,
char **groups,
struct sss_domain_info *group_dom)
{
int ret;
struct tevent_req *req;
struct tevent_req *subreq;
struct add_ad_membership_state *state;
bool missing_groups = false;
return NULL;
}
goto done;
}
goto done;
}
if (!missing_groups) {
goto done;
}
goto done;
}
goto done;
}
return req;
done:
} else {
}
return req;
}
{
struct tevent_req);
struct add_ad_membership_state);
int ret;
"No IPA server is available, going offline\n");
} else {
"Failed to connect to IPA server: [%d](%s)\n",
}
return;
}
}
{
struct add_ad_membership_state);
struct tevent_req *subreq;
int ret;
bool missing_groups;
const char *fq_name;
char *tmp_str;
}
goto fail;
}
if (missing_groups) {
"memberships even after all groups "
"have been looked up on the LDAP "
"server.\n");
}
return;
}
goto fail;
}
goto fail;
}
/* keep using val->data if sss_create_internal_fqname() fails */
}
}
/* TODO: here is would be useful for have a filter type like BE_FILTER_DN to
* directly fetch the group with the corresponding DN. */
false, false);
goto fail;
}
return;
fail:
}
{
struct tevent_req);
struct add_ad_membership_state);
int ret;
return;
}
}
int *dp_error_out)
{
struct add_ad_membership_state);
if (dp_error_out) {
}
return EOK;
}
static errno_t
struct sss_domain_info *domain,
const char *sid_str,
enum sysdb_member_type *_member_type,
struct ldb_message **_msg)
{
const char *attrs[] = { SYSDB_NAME,
NULL };
char *sanitized_sid = NULL;
return ENOMEM;
}
/* In theory SID shouldn't contain any special LDAP characters, but let's
* be paranoid
*/
goto done;
}
}
}
switch (ret) {
case EOK:
break;
case ENOENT:
"Could not find %s in sysdb", sid_str);
break;
default:
"Error looking for %s in sysdb [%d]: %s\n",
break;
}
done:
return ret;
}
static errno_t
struct sss_domain_info *member_dom,
const char *ext_member,
enum sysdb_member_type *_member_type,
struct sysdb_attrs **_member)
{
struct ldb_message *msg;
struct sysdb_attrs **members;
return ENOMEM;
}
_member_type, &msg);
"Error looking up sid %s: [%d]: %s\n",
goto done;
}
"Could not convert result to sysdb_attrs [%d]: %s\n",
goto done;
}
/* Return the member both expired and valid */
goto done;
}
done:
return ret;
}
/* For the IPA external member resolution, we expect a SID as the input.
* since nothing else can be a group member.
*/
struct ipa_ext_member_state {
const char *ext_member;
struct sss_domain_info *dom;
enum sysdb_member_type member_type;
struct sysdb_attrs *member;
};
struct tevent_context *ev,
const char *ext_member,
void *pvt)
{
struct ipa_id_ctx *ipa_ctx;
struct ipa_ext_member_state *state;
struct tevent_req *req;
struct tevent_req *subreq;
struct dp_id_data *ar;
return NULL;
}
goto immediate;
}
"Cannot find domain of SID [%s]\n", ext_member);
goto immediate;
}
"external member %s already cached\n", ext_member);
goto immediate;
}
"Cannot create the account request for [%s]\n", ext_member);
goto immediate;
}
goto immediate;
}
return req;
} else {
}
return req;
}
{
struct tevent_req);
struct ipa_ext_member_state);
struct ldb_message *msg;
struct sysdb_attrs **members;
struct dp_reply_std *reply;
return;
"Cannot refresh data from DP: %u,%u: %s\n",
return;
}
&state->member_type,
&msg);
"Could not find %s in sysdb [%d]: %s\n",
return;
}
"Could not convert result to sysdb_attrs [%d]: %s\n",
return;
}
}
struct tevent_req *req,
enum sysdb_member_type *_member_type,
struct sss_domain_info **_dom,
struct sysdb_attrs **_member)
{
struct ipa_ext_member_state);
if (_member_type != NULL) {
}
if (_dom) {
}
}
return EOK;
}