summaryrefslogtreecommitdiffstats
path: root/src/providers/ipa/ipa_subdomains_id.c
diff options
context:
space:
mode:
authorSumit Bose <sbose@redhat.com>2013-08-19 17:15:47 +0200
committerJakub Hrozek <jhrozek@redhat.com>2013-08-28 17:30:07 +0200
commitcaee9828ee30609e9f433957dbb3d0163390a207 (patch)
tree323dc74055327b86a47e2e32ffb14a66b25a5971 /src/providers/ipa/ipa_subdomains_id.c
parentb8d0374cd23db90fce203292ff547641f62e338a (diff)
downloadsssd-caee9828ee30609e9f433957dbb3d0163390a207.tar.gz
sssd-caee9828ee30609e9f433957dbb3d0163390a207.tar.xz
sssd-caee9828ee30609e9f433957dbb3d0163390a207.zip
ipa-server-mode: add IPA group memberships to AD users
When IPA trusts an AD domain the AD user or groups can be placed into IPA groups e.g. to put AD users under the control of HBAC. Since IPA group can only have members from the IPA directory tree and the AD users and groups are not stored there a special IPA object called external group was introduced. SIDs of users and groups can be added to the external group and since the external groups are in the IPA directory tree they can be member of IPA groups. To speed things up and to remove some load from the IPA servers SSSD reads all external groups and stores them in memory for some time before rereading the data. Enhances https://fedorahosted.org/sssd/ticket/1962
Diffstat (limited to 'src/providers/ipa/ipa_subdomains_id.c')
-rw-r--r--src/providers/ipa/ipa_subdomains_id.c73
1 files changed, 65 insertions, 8 deletions
diff --git a/src/providers/ipa/ipa_subdomains_id.c b/src/providers/ipa/ipa_subdomains_id.c
index c380d159e..c29a2a304 100644
--- a/src/providers/ipa/ipa_subdomains_id.c
+++ b/src/providers/ipa/ipa_subdomains_id.c
@@ -250,8 +250,14 @@ int ipa_get_subdom_acct_recv(struct tevent_req *req, int *dp_error_out)
/* IPA lookup for server mode. Directly to AD. */
struct ipa_get_ad_acct_state {
int dp_error;
+ struct tevent_context *ev;
+ struct ipa_id_ctx *ipa_ctx;
+ struct be_req *be_req;
+ struct be_acct_req *ar;
+ struct sss_domain_info *user_dom;
};
+static void ipa_get_ad_acct_ad_part_done(struct tevent_req *subreq);
static void ipa_get_ad_acct_done(struct tevent_req *subreq);
static struct ad_id_ctx *ipa_get_ad_id_ctx(struct ipa_id_ctx *ipa_ctx,
struct sss_domain_info *dom);
@@ -267,7 +273,6 @@ ipa_get_ad_acct_send(TALLOC_CTX *mem_ctx,
struct tevent_req *req;
struct tevent_req *subreq;
struct ipa_get_ad_acct_state *state;
- struct sss_domain_info *dom;
struct sdap_domain *sdom;
struct sdap_id_conn_ctx **clist;
struct sdap_id_ctx *sdap_id_ctx;;
@@ -276,16 +281,22 @@ ipa_get_ad_acct_send(TALLOC_CTX *mem_ctx,
req = tevent_req_create(mem_ctx, &state, struct ipa_get_ad_acct_state);
if (req == NULL) return NULL;
+ state->dp_error = -1;
+ state->ev = ev;
+ state->ipa_ctx = ipa_ctx;
+ state->be_req = be_req;
+ state->ar = ar;
+
/* This can only be a subdomain request, verify subdomain */
- dom = find_subdomain_by_name(ipa_ctx->sdap_id_ctx->be->domain,
- ar->domain, true);
- if (dom == NULL) {
+ state->user_dom = find_subdomain_by_name(ipa_ctx->sdap_id_ctx->be->domain,
+ ar->domain, true);
+ if (state->user_dom == NULL) {
ret = EINVAL;
goto fail;
}
/* Let's see if this subdomain has a ad_id_ctx */
- ad_id_ctx = ipa_get_ad_id_ctx(ipa_ctx, dom);
+ ad_id_ctx = ipa_get_ad_id_ctx(ipa_ctx, state->user_dom);
if (ad_id_ctx == NULL) {
ret = EINVAL;
goto fail;
@@ -304,7 +315,7 @@ ipa_get_ad_acct_send(TALLOC_CTX *mem_ctx,
clist[1] = NULL;
/* Now we already need ad_id_ctx in particular sdap_id_conn_ctx */
- sdom = sdap_domain_get(sdap_id_ctx->opts, dom);
+ sdom = sdap_domain_get(sdap_id_ctx->opts, state->user_dom);
if (sdom == NULL) {
ret = EIO;
goto fail;
@@ -316,10 +327,11 @@ ipa_get_ad_acct_send(TALLOC_CTX *mem_ctx,
ret = ENOMEM;
goto fail;
}
- tevent_req_set_callback(subreq, ipa_get_ad_acct_done, req);
+ tevent_req_set_callback(subreq, ipa_get_ad_acct_ad_part_done, req);
return req;
fail:
+ state->dp_error = DP_ERR_FATAL;
tevent_req_error(req, ret);
tevent_req_post(req, ev);
return req;
@@ -339,7 +351,7 @@ ipa_get_ad_id_ctx(struct ipa_id_ctx *ipa_ctx,
}
static void
-ipa_get_ad_acct_done(struct tevent_req *subreq)
+ipa_get_ad_acct_ad_part_done(struct tevent_req *subreq)
{
struct tevent_req *req = tevent_req_callback_data(subreq,
struct tevent_req);
@@ -355,6 +367,51 @@ ipa_get_ad_acct_done(struct tevent_req *subreq)
return;
}
+ if ((state->ar->entry_type & BE_REQ_TYPE_MASK) != BE_REQ_INITGROUPS) {
+ tevent_req_done(req);
+ return;
+ }
+
+ /* For initgroups request we have to check IPA group memberships of AD
+ * users. */
+ subreq = ipa_get_ad_memberships_send(state, state->ev, state->ar,
+ state->ipa_ctx->server_mode,
+ state->user_dom,
+ state->ipa_ctx->sdap_id_ctx,
+ state->ipa_ctx->server_mode->realm);
+ if (subreq == NULL) {
+ ret = ENOMEM;
+ goto fail;
+ }
+ tevent_req_set_callback(subreq, ipa_get_ad_acct_done, req);
+
+ return;
+
+fail:
+ state->dp_error = DP_ERR_FATAL;
+ tevent_req_error(req, ret);
+ tevent_req_post(req, state->ev);
+ return;
+}
+
+static void
+ipa_get_ad_acct_done(struct tevent_req *subreq)
+{
+ struct tevent_req *req = tevent_req_callback_data(subreq,
+ struct tevent_req);
+ struct ipa_get_ad_acct_state *state = tevent_req_data(req,
+ struct ipa_get_ad_acct_state);
+ errno_t ret;
+
+ ret = ipa_get_ad_memberships_recv(subreq, &state->dp_error);
+ talloc_zfree(subreq);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE, ("IPA external groups lookup failed: %d\n",
+ ret));
+ tevent_req_error(req, ret);
+ return;
+ }
+
tevent_req_done(req);
}