summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJakub Hrozek <jhrozek@redhat.com>2013-06-19 10:51:19 +0200
committerJakub Hrozek <jhrozek@redhat.com>2013-06-28 22:22:20 +0200
commit3d28e0e560b787b5c57ed7327d184310342a7e38 (patch)
treed51191a9d6daec9e9d7842241946b386d52f5d1a /src
parent418e6ccd116eced7ccc75aca999a4c37c67289ba (diff)
downloadsssd-3d28e0e560b787b5c57ed7327d184310342a7e38.tar.gz
sssd-3d28e0e560b787b5c57ed7327d184310342a7e38.tar.xz
sssd-3d28e0e560b787b5c57ed7327d184310342a7e38.zip
IPA: Look up AD users directly if IPA server mode is on
https://fedorahosted.org/sssd/ticket/1962 If the ipa_server_mode is selected IPA subdomain user and group lookups are not done with the help of the extdom plugin but directly against AD using the AD ID code.
Diffstat (limited to 'src')
-rw-r--r--src/providers/ad/ad_id.c4
-rw-r--r--src/providers/ad/ad_id.h11
-rw-r--r--src/providers/ipa/ipa_common.h1
-rw-r--r--src/providers/ipa/ipa_id.c23
-rw-r--r--src/providers/ipa/ipa_id.h9
-rw-r--r--src/providers/ipa/ipa_subdomains_id.c126
6 files changed, 168 insertions, 6 deletions
diff --git a/src/providers/ad/ad_id.c b/src/providers/ad/ad_id.c
index 9c4abc8c9..48ad84259 100644
--- a/src/providers/ad/ad_id.c
+++ b/src/providers/ad/ad_id.c
@@ -38,7 +38,7 @@ struct ad_handle_acct_info_state {
static errno_t ad_handle_acct_info_step(struct tevent_req *req);
static void ad_handle_acct_info_done(struct tevent_req *subreq);
-static struct tevent_req *
+struct tevent_req *
ad_handle_acct_info_send(TALLOC_CTX *mem_ctx,
struct be_req *breq,
struct be_acct_req *ar,
@@ -152,7 +152,7 @@ ad_handle_acct_info_done(struct tevent_req *subreq)
/* Another lookup in progress */
}
-static errno_t
+errno_t
ad_handle_acct_info_recv(struct tevent_req *req,
int *_dp_error, const char **_err)
{
diff --git a/src/providers/ad/ad_id.h b/src/providers/ad/ad_id.h
index 47fc3b33b..1fd6b599a 100644
--- a/src/providers/ad/ad_id.h
+++ b/src/providers/ad/ad_id.h
@@ -26,6 +26,17 @@
void
ad_account_info_handler(struct be_req *breq);
+struct tevent_req *
+ad_handle_acct_info_send(TALLOC_CTX *mem_ctx,
+ struct be_req *breq,
+ struct be_acct_req *ar,
+ struct sdap_id_ctx *ctx,
+ struct sdap_domain *sdom,
+ struct sdap_id_conn_ctx **conn);
+errno_t
+ad_handle_acct_info_recv(struct tevent_req *req,
+ int *_dp_error, const char **_err);
+
void
ad_check_online(struct be_req *be_req);
#endif /* AD_ID_H_ */
diff --git a/src/providers/ipa/ipa_common.h b/src/providers/ipa/ipa_common.h
index 2af20e1de..1afe20dbb 100644
--- a/src/providers/ipa/ipa_common.h
+++ b/src/providers/ipa/ipa_common.h
@@ -26,6 +26,7 @@
#include "confdb/confdb.h"
#include "providers/ldap/ldap_common.h"
#include "providers/krb5/krb5_common.h"
+#include "providers/ad/ad_common.h"
struct ipa_service {
struct sdap_service *sdap;
diff --git a/src/providers/ipa/ipa_id.c b/src/providers/ipa/ipa_id.c
index b11abaa7d..6e0964400 100644
--- a/src/providers/ipa/ipa_id.c
+++ b/src/providers/ipa/ipa_id.c
@@ -83,9 +83,15 @@ void ipa_account_info_handler(struct be_req *breq)
ar = talloc_get_type(be_req_get_data(breq), struct be_acct_req);
if (strcasecmp(ar->domain, be_ctx->domain->name) != 0) {
- /* if domain names do not match, this is a subdomain case */
- req = ipa_get_subdom_acct_send(breq, be_ctx->ev, ctx, ar);
-
+ /* if domain names do not match, this is a subdomain case
+ * subdomain lookups are handled differently on the server
+ * and the client
+ */
+ if (dp_opt_get_bool(ipa_ctx->ipa_options->basic, IPA_SERVER_MODE)) {
+ req = ipa_get_ad_acct_send(breq, be_ctx->ev, ipa_ctx, breq, ar);
+ } else {
+ req = ipa_get_subdom_acct_send(breq, be_ctx->ev, ctx, ar);
+ }
} else if ((ar->entry_type & BE_REQ_TYPE_MASK) == BE_REQ_NETGROUP) {
/* netgroups are handled by a separate request function */
if (ar->filter_type != BE_FILTER_NAME) {
@@ -110,15 +116,24 @@ void ipa_account_info_handler(struct be_req *breq)
static void ipa_account_info_done(struct tevent_req *req)
{
struct be_req *breq = tevent_req_callback_data(req, struct be_req);
+ struct be_ctx *be_ctx = be_req_get_be_ctx(breq);
+ struct ipa_id_ctx *ipa_ctx;
struct be_acct_req *ar = talloc_get_type(be_req_get_data(breq),
struct be_acct_req);
const char *error_text;
int ret, dp_error;
+ ipa_ctx = talloc_get_type(be_ctx->bet_info[BET_ID].pvt_bet_data,
+ struct ipa_id_ctx);
+
if ((ar->entry_type & BE_REQ_TYPE_MASK) == BE_REQ_NETGROUP) {
ret = ipa_id_get_netgroup_recv(req, &dp_error);
} else {
- ret = ipa_get_subdom_acct_recv(req, &dp_error);
+ if (dp_opt_get_bool(ipa_ctx->ipa_options->basic, IPA_SERVER_MODE)) {
+ ret = ipa_get_ad_acct_recv(req, &dp_error);
+ } else {
+ ret = ipa_get_subdom_acct_recv(req, &dp_error);
+ }
}
talloc_zfree(req);
diff --git a/src/providers/ipa/ipa_id.h b/src/providers/ipa/ipa_id.h
index 7fa25e927..6c72f6d04 100644
--- a/src/providers/ipa/ipa_id.h
+++ b/src/providers/ipa/ipa_id.h
@@ -64,4 +64,13 @@ struct tevent_req *ipa_get_subdom_acct_send(TALLOC_CTX *memctx,
struct sdap_id_ctx *ctx,
struct be_acct_req *ar);
int ipa_get_subdom_acct_recv(struct tevent_req *req, int *dp_error_out);
+
+struct tevent_req *ipa_get_ad_acct_send(TALLOC_CTX *mem_ctx,
+ struct tevent_context *ev,
+ struct ipa_id_ctx *ipa_ctx,
+ struct be_req *be_req,
+ struct be_acct_req *ar);
+
+errno_t ipa_get_ad_acct_recv(struct tevent_req *req, int *dp_error_out);
+
#endif
diff --git a/src/providers/ipa/ipa_subdomains_id.c b/src/providers/ipa/ipa_subdomains_id.c
index dc822888f..6bf97bec0 100644
--- a/src/providers/ipa/ipa_subdomains_id.c
+++ b/src/providers/ipa/ipa_subdomains_id.c
@@ -30,6 +30,7 @@
#include "providers/ldap/ldap_common.h"
#include "providers/ldap/sdap_async.h"
#include "providers/ipa/ipa_id.h"
+#include "providers/ad/ad_id.h"
#include "providers/ipa/ipa_subdomains.h"
struct ipa_get_subdom_acct {
@@ -246,3 +247,128 @@ int ipa_get_subdom_acct_recv(struct tevent_req *req, int *dp_error_out)
return EOK;
}
+/* IPA lookup for server mode. Directly to AD. */
+struct ipa_get_ad_acct_state {
+ int dp_error;
+};
+
+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);
+
+struct tevent_req *
+ipa_get_ad_acct_send(TALLOC_CTX *mem_ctx,
+ struct tevent_context *ev,
+ struct ipa_id_ctx *ipa_ctx,
+ struct be_req *be_req,
+ struct be_acct_req *ar)
+{
+ errno_t ret;
+ 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;;
+ struct ad_id_ctx *ad_id_ctx;
+
+ req = tevent_req_create(mem_ctx, &state, struct ipa_get_ad_acct_state);
+ if (req == NULL) return NULL;
+
+ /* 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) {
+ 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);
+ if (ad_id_ctx == NULL) {
+ ret = EINVAL;
+ goto fail;
+ }
+ sdap_id_ctx = ad_id_ctx->sdap_id_ctx;
+
+ /* Currently only LDAP port for AD is used because POSIX
+ * attributes are not replicated to GC by default
+ */
+ clist = talloc_zero_array(req, struct sdap_id_conn_ctx *, 2);
+ if (clist == NULL) {
+ ret = ENOMEM;
+ goto fail;
+ }
+ clist[0] = ad_id_ctx->ldap_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);
+ if (sdom == NULL) {
+ ret = EIO;
+ goto fail;
+ }
+
+ subreq = ad_handle_acct_info_send(req, be_req, ar, sdap_id_ctx,
+ sdom, clist);
+ if (subreq == NULL) {
+ ret = ENOMEM;
+ goto fail;
+ }
+ tevent_req_set_callback(subreq, ipa_get_ad_acct_done, req);
+ return req;
+
+fail:
+ tevent_req_error(req, ret);
+ tevent_req_post(req, ev);
+ return req;
+}
+
+static struct ad_id_ctx *
+ipa_get_ad_id_ctx(struct ipa_id_ctx *ipa_ctx,
+ struct sss_domain_info *dom)
+{
+ struct ipa_ad_server_ctx *iter;
+
+ DLIST_FOR_EACH(iter, ipa_ctx->server_mode->trusts) {
+ if (iter->dom == dom) break;
+ }
+
+ return iter->ad_id_ctx;
+}
+
+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 = ad_handle_acct_info_recv(subreq, &state->dp_error, NULL);
+ talloc_zfree(subreq);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE, ("AD lookup failed: %d\n", ret));
+ tevent_req_error(req, ret);
+ return;
+ }
+
+ tevent_req_done(req);
+}
+
+errno_t
+ipa_get_ad_acct_recv(struct tevent_req *req, int *dp_error_out)
+{
+ struct ipa_get_ad_acct_state *state = tevent_req_data(req,
+ struct ipa_get_ad_acct_state);
+
+ if (dp_error_out) {
+ *dp_error_out = state->dp_error;
+ }
+
+ TEVENT_REQ_RETURN_ON_ERROR(req);
+
+ return EOK;
+}