summaryrefslogtreecommitdiff
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
parent418e6ccd116eced7ccc75aca999a4c37c67289ba (diff)
downloadsssd-3d28e0e560b787b5c57ed7327d184310342a7e38.tar.gz
sssd-3d28e0e560b787b5c57ed7327d184310342a7e38.tar.bz2
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.
-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 9c4abc8c..48ad8425 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 47fc3b33..1fd6b599 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 2af20e1d..1afe20db 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 b11abaa7..6e096440 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 7fa25e92..6c72f6d0 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 dc822888..6bf97bec 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;
+}