summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/providers/ad/ad_id.c19
-rw-r--r--src/providers/ad/ad_init.c2
-rw-r--r--src/providers/ldap/sdap_async.h1
-rw-r--r--src/providers/ldap/sdap_async_groups.c62
-rw-r--r--src/providers/ldap/sdap_async_initgroups.c50
-rw-r--r--src/providers/ldap/sdap_async_initgroups_ad.c157
6 files changed, 261 insertions, 30 deletions
diff --git a/src/providers/ad/ad_id.c b/src/providers/ad/ad_id.c
index 19bc65825..cf71b172d 100644
--- a/src/providers/ad/ad_id.c
+++ b/src/providers/ad/ad_id.c
@@ -199,6 +199,8 @@ get_conn_list(struct be_req *breq, struct ad_id_ctx *ad_ctx,
case BE_REQ_USER: /* user */
case BE_REQ_BY_SECID: /* by SID */
case BE_REQ_USER_AND_GROUP: /* get SID */
+ case BE_REQ_GROUP: /* group */
+ case BE_REQ_INITGROUPS: /* init groups for user */
/* Always try GC first */
clist[0] = ad_ctx->gc_ctx;
if (IS_SUBDOMAIN(dom) == true) {
@@ -215,23 +217,6 @@ get_conn_list(struct be_req *breq, struct ad_id_ctx *ad_ctx,
*/
clist[1] = ad_ctx->ldap_ctx;
break;
-
- case BE_REQ_GROUP: /* group */
- case BE_REQ_INITGROUPS: /* init groups for user */
- if (IS_SUBDOMAIN(dom)) {
- sdom = sdap_domain_get(ad_ctx->sdap_id_ctx->opts, dom);
- if (sdom == NULL || sdom->pvt == NULL) {
- DEBUG(SSSDBG_CRIT_FAILURE, ("No ID ctx available for [%s].\n",
- dom->name));
- return NULL;
- }
- subdom_id_ctx = talloc_get_type(sdom->pvt, struct ad_id_ctx);
- clist[0] = subdom_id_ctx->ldap_ctx;
- } else {
- clist[0] = ad_ctx->ldap_ctx;
- }
- break;
-
default:
clist[0] = ad_ctx->ldap_ctx;
break;
diff --git a/src/providers/ad/ad_init.c b/src/providers/ad/ad_init.c
index d06efbd08..332bfda38 100644
--- a/src/providers/ad/ad_init.c
+++ b/src/providers/ad/ad_init.c
@@ -214,6 +214,8 @@ sssm_ad_id_init(struct be_ctx *bectx,
goto done;
}
+ ad_ctx->sdap_id_ctx->opts->sdom->pvt = ad_ctx;
+
/* Set up the ID mapping object */
ret = sdap_idmap_init(ad_ctx->sdap_id_ctx, ad_ctx->sdap_id_ctx,
&ad_ctx->sdap_id_ctx->opts->idmap_ctx);
diff --git a/src/providers/ldap/sdap_async.h b/src/providers/ldap/sdap_async.h
index f47437553..33e8708ab 100644
--- a/src/providers/ldap/sdap_async.h
+++ b/src/providers/ldap/sdap_async.h
@@ -297,6 +297,7 @@ struct tevent_req *
sdap_ad_tokengroups_initgroups_send(TALLOC_CTX *mem_ctx,
struct tevent_context *ev,
struct sdap_id_ctx *id_ctx,
+ struct sdap_id_conn_ctx *conn,
struct sdap_options *opts,
struct sysdb_ctx *sysdb,
struct sss_domain_info *domain,
diff --git a/src/providers/ldap/sdap_async_groups.c b/src/providers/ldap/sdap_async_groups.c
index 33648c5da..9eece9a6e 100644
--- a/src/providers/ldap/sdap_async_groups.c
+++ b/src/providers/ldap/sdap_async_groups.c
@@ -26,6 +26,7 @@
#include "providers/ldap/sdap_async_private.h"
#include "providers/ldap/ldap_common.h"
#include "providers/ldap/sdap_idmap.h"
+#include "providers/ad/ad_common.h"
/* ==Group-Parsing Routines=============================================== */
@@ -1540,9 +1541,13 @@ struct sdap_get_groups_state {
size_t base_iter;
struct sdap_search_base **search_bases;
+
+ struct sdap_handle *ldap_sh;
+ struct sdap_id_op *op;
};
static errno_t sdap_get_groups_next_base(struct tevent_req *req);
+static void sdap_get_groups_ldap_connect_done(struct tevent_req *subreq);
static void sdap_get_groups_process(struct tevent_req *subreq);
static void sdap_get_groups_done(struct tevent_req *subreq);
@@ -1558,7 +1563,9 @@ struct tevent_req *sdap_get_groups_send(TALLOC_CTX *memctx,
{
errno_t ret;
struct tevent_req *req;
+ struct tevent_req *subreq;
struct sdap_get_groups_state *state;
+ struct ad_id_ctx *subdom_id_ctx;
req = tevent_req_create(memctx, &state, struct sdap_get_groups_state);
if (!req) return NULL;
@@ -1586,6 +1593,30 @@ struct tevent_req *sdap_get_groups_send(TALLOC_CTX *memctx,
goto done;
}
+ /* With AD by default the Global Catalog is used for lookup. But the GC
+ * group object might not have full group membership data. To make sure we
+ * connect to an LDAP server of the group's domain. */
+ if (state->opts->schema_type == SDAP_SCHEMA_AD && sdom->pvt != NULL) {
+ subdom_id_ctx = talloc_get_type(sdom->pvt, struct ad_id_ctx);
+ state->op = sdap_id_op_create(state, subdom_id_ctx->ldap_ctx->conn_cache);
+ if (!state->op) {
+ DEBUG(2, ("sdap_id_op_create failed\n"));
+ ret = ENOMEM;
+ goto done;
+ }
+
+ subreq = sdap_id_op_connect_send(state->op, state, &ret);
+ if (subreq == NULL) {
+ ret = ENOMEM;
+ goto done;
+ }
+
+ tevent_req_set_callback(subreq,
+ sdap_get_groups_ldap_connect_done,
+ req);
+ return req;
+ }
+
ret = sdap_get_groups_next_base(req);
done:
@@ -1597,6 +1628,34 @@ done:
return req;
}
+static void sdap_get_groups_ldap_connect_done(struct tevent_req *subreq)
+{
+ struct tevent_req *req;
+ struct sdap_get_groups_state *state;
+ int ret;
+ int dp_error;
+
+ req = tevent_req_callback_data(subreq, struct tevent_req);
+ state = tevent_req_data(req, struct sdap_get_groups_state);
+
+ ret = sdap_id_op_connect_recv(subreq, &dp_error);
+ talloc_zfree(subreq);
+
+ if (ret != EOK) {
+ tevent_req_error(req, ret);
+ return;
+ }
+
+ state->ldap_sh = sdap_id_op_handle(state->op);
+
+ ret = sdap_get_groups_next_base(req);
+ if (ret != EOK) {
+ tevent_req_error(req, ret);
+ }
+
+ return;
+}
+
static errno_t sdap_get_groups_next_base(struct tevent_req *req)
{
struct tevent_req *subreq;
@@ -1617,7 +1676,8 @@ static errno_t sdap_get_groups_next_base(struct tevent_req *req)
state->search_bases[state->base_iter]->basedn));
subreq = sdap_get_generic_send(
- state, state->ev, state->opts, state->sh,
+ state, state->ev, state->opts,
+ state->ldap_sh != NULL ? state->ldap_sh : state->sh,
state->search_bases[state->base_iter]->basedn,
state->search_bases[state->base_iter]->scope,
state->filter, state->attrs,
diff --git a/src/providers/ldap/sdap_async_initgroups.c b/src/providers/ldap/sdap_async_initgroups.c
index 1b865af0a..aba7ba42d 100644
--- a/src/providers/ldap/sdap_async_initgroups.c
+++ b/src/providers/ldap/sdap_async_initgroups.c
@@ -2749,6 +2749,10 @@ static void sdap_get_initgr_user(struct tevent_req *subreq)
const char *orig_dn;
const char *cname;
bool in_transaction = false;
+ char *expected_basedn;
+ size_t expected_basedn_len;
+ size_t dn_len;
+ size_t c = 0;
DEBUG(9, ("Receiving info for the user\n"));
@@ -2788,11 +2792,50 @@ static void sdap_get_initgr_user(struct tevent_req *subreq)
} else if (count != 1) {
DEBUG(SSSDBG_OP_FAILURE,
("Expected one user entry and got %zu\n", count));
- tevent_req_error(req, EINVAL);
- return;
+
+ ret = domain_to_basedn(state, state->dom->name, &expected_basedn);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE, ("domain_to_basedn failed.\n"));
+ tevent_req_error(req, ret);
+ return;
+ }
+ expected_basedn = talloc_asprintf(state, "%s%s",
+ "cn=users,", expected_basedn);
+ if (expected_basedn == NULL) {
+ DEBUG(SSSDBG_OP_FAILURE, ("talloc_append failed.\n"));
+ tevent_req_error(req, ENOMEM);
+ return;
+ }
+
+ DEBUG(SSSDBG_TRACE_ALL, ("Expected BaseDN is [%s].\n", expected_basedn));
+ expected_basedn_len = strlen(expected_basedn);
+
+ for (c = 0; c < count; c++) {
+ ret = sysdb_attrs_get_string(usr_attrs[c], SYSDB_ORIG_DN, &orig_dn);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE, ("sysdb_attrs_get_string failed.\n"));
+ tevent_req_error(req, ret);
+ return;
+ }
+ dn_len = strlen(orig_dn);
+
+ if (dn_len > expected_basedn_len
+ && strcasecmp(orig_dn + (dn_len - expected_basedn_len),
+ expected_basedn) == 0) {
+ DEBUG(SSSDBG_TRACE_ALL,
+ ("Found matching dn [%s].\n", orig_dn));
+ break;
+ }
+ }
+
+ if (c == count) {
+ DEBUG(SSSDBG_OP_FAILURE, ("No matching DN found.\n"));
+ tevent_req_error(req, EINVAL);
+ return;
+ }
}
- state->orig_user = usr_attrs[0];
+ state->orig_user = usr_attrs[c];
ret = sysdb_transaction_start(state->sysdb);
if (ret) {
@@ -2858,6 +2901,7 @@ static void sdap_get_initgr_user(struct tevent_req *subreq)
*/
subreq = sdap_ad_tokengroups_initgroups_send(state, state->ev,
state->id_ctx,
+ state->conn,
state->opts,
state->sysdb,
state->dom,
diff --git a/src/providers/ldap/sdap_async_initgroups_ad.c b/src/providers/ldap/sdap_async_initgroups_ad.c
index f1bf77e86..8f8f0a4cc 100644
--- a/src/providers/ldap/sdap_async_initgroups_ad.c
+++ b/src/providers/ldap/sdap_async_initgroups_ad.c
@@ -25,6 +25,7 @@
#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 {
@@ -528,6 +529,7 @@ done:
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;
@@ -543,6 +545,7 @@ static struct tevent_req *
sdap_ad_resolve_sids_send(TALLOC_CTX *mem_ctx,
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)
@@ -560,6 +563,7 @@ sdap_ad_resolve_sids_send(TALLOC_CTX *mem_ctx,
state->ev = ev;
state->id_ctx = id_ctx;
+ state->conn = conn;
state->opts = opts;
state->domain = get_domains_head(domain);
state->sids = sids;
@@ -618,7 +622,7 @@ static errno_t sdap_ad_resolve_sids_step(struct tevent_req *req)
}
subreq = groups_get_send(state, state->ev, state->id_ctx, sdap_domain,
- state->id_ctx->conn, state->current_sid,
+ state->conn, state->current_sid,
BE_FILTER_SECID, BE_ATTR_CORE, false);
if (subreq == NULL) {
return ENOMEM;
@@ -673,12 +677,21 @@ static errno_t sdap_ad_resolve_sids_recv(struct tevent_req *req)
struct sdap_ad_tokengroups_initgr_mapping_state {
+ struct tevent_context *ev;
+ struct sdap_options *opts;
+ struct sdap_handle *sh;
struct sdap_idmap_ctx *idmap_ctx;
struct sysdb_ctx *sysdb;
struct sss_domain_info *domain;
+ const char *orig_dn;
+ int timeout;
const char *username;
+
+ struct sdap_id_op *op;
};
+static void
+sdap_ad_tokengroups_initgr_mapping_connect_done(struct tevent_req *subreq);
static void sdap_ad_tokengroups_initgr_mapping_done(struct tevent_req *subreq);
static struct tevent_req *
@@ -695,6 +708,8 @@ sdap_ad_tokengroups_initgr_mapping_send(TALLOC_CTX *mem_ctx,
struct sdap_ad_tokengroups_initgr_mapping_state *state = NULL;
struct tevent_req *req = NULL;
struct tevent_req *subreq = NULL;
+ struct sdap_domain *sdom;
+ struct ad_id_ctx *subdom_id_ctx;
errno_t ret;
req = tevent_req_create(mem_ctx, &state,
@@ -704,23 +719,43 @@ sdap_ad_tokengroups_initgr_mapping_send(TALLOC_CTX *mem_ctx,
return NULL;
}
+ state->ev = ev;
+ state->opts = opts;
+ state->sh = sh;
state->idmap_ctx = opts->idmap_ctx;
state->sysdb = sysdb;
state->domain = domain;
+ state->timeout = timeout;
+ state->orig_dn = orig_dn;
state->username = talloc_strdup(state, name);
if (state->username == NULL) {
ret = ENOMEM;
goto immediately;
}
- subreq = sdap_get_ad_tokengroups_send(state, ev, opts, sh, name, orig_dn,
- timeout);
+ sdom = sdap_domain_get(opts, domain);
+ if (sdom == NULL || sdom->pvt == NULL) {
+ DEBUG(SSSDBG_CRIT_FAILURE, ("No ID ctx available for [%s].\n",
+ domain->name));
+ ret = EINVAL;
+ goto immediately;
+ }
+ subdom_id_ctx = talloc_get_type(sdom->pvt, struct ad_id_ctx);
+ state->op = sdap_id_op_create(state, subdom_id_ctx->ldap_ctx->conn_cache);
+ if (!state->op) {
+ DEBUG(2, ("sdap_id_op_create failed\n"));
+ ret = ENOMEM;
+ goto immediately;
+ }
+
+ subreq = sdap_id_op_connect_send(state->op, state, &ret);
if (subreq == NULL) {
ret = ENOMEM;
goto immediately;
}
- tevent_req_set_callback(subreq, sdap_ad_tokengroups_initgr_mapping_done,
+ tevent_req_set_callback(subreq,
+ sdap_ad_tokengroups_initgr_mapping_connect_done,
req);
return req;
@@ -736,6 +771,42 @@ immediately:
return req;
}
+static void
+sdap_ad_tokengroups_initgr_mapping_connect_done(struct tevent_req *subreq)
+{
+ struct sdap_ad_tokengroups_initgr_mapping_state *state = NULL;
+ struct tevent_req *req = NULL;
+ int ret;
+ int dp_error = DP_ERR_FATAL;
+
+ req = tevent_req_callback_data(subreq, struct tevent_req);
+ state = tevent_req_data(req,
+ struct sdap_ad_tokengroups_initgr_mapping_state);
+
+
+ ret = sdap_id_op_connect_recv(subreq, &dp_error);
+ talloc_zfree(subreq);
+
+ if (ret != EOK) {
+ tevent_req_error(req, ret);
+ return;
+ }
+
+ subreq = sdap_get_ad_tokengroups_send(state, state->ev, state->opts,
+ sdap_id_op_handle(state->op),
+ state->username,
+ state->orig_dn, state->timeout);
+ if (subreq == NULL) {
+ tevent_req_error(req, ENOMEM);
+ return;
+ }
+
+ tevent_req_set_callback(subreq, sdap_ad_tokengroups_initgr_mapping_done,
+ req);
+
+ return;
+}
+
static void sdap_ad_tokengroups_initgr_mapping_done(struct tevent_req *subreq)
{
TALLOC_CTX *tmp_ctx = NULL;
@@ -896,22 +967,31 @@ static int sdap_ad_tokengroups_initgr_mapping_recv(struct tevent_req *req)
struct sdap_ad_tokengroups_initgr_posix_state {
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 sysdb_ctx *sysdb;
struct sss_domain_info *domain;
+ const char *orig_dn;
+ int timeout;
const char *username;
+
+ struct sdap_id_op *op;
};
static void
sdap_ad_tokengroups_initgr_posix_tg_done(struct tevent_req *subreq);
static void
+sdap_ad_tokengroups_initgr_posix_sids_connect_done(struct tevent_req *subreq);
+static void
sdap_ad_tokengroups_initgr_posix_sids_done(struct tevent_req *subreq);
static struct tevent_req *
sdap_ad_tokengroups_initgr_posix_send(TALLOC_CTX *mem_ctx,
struct tevent_context *ev,
struct sdap_id_ctx *id_ctx,
+ struct sdap_id_conn_ctx *conn,
struct sdap_options *opts,
struct sysdb_ctx *sysdb,
struct sss_domain_info *domain,
@@ -923,6 +1003,8 @@ sdap_ad_tokengroups_initgr_posix_send(TALLOC_CTX *mem_ctx,
struct sdap_ad_tokengroups_initgr_posix_state *state = NULL;
struct tevent_req *req = NULL;
struct tevent_req *subreq = NULL;
+ struct sdap_domain *sdom;
+ struct ad_id_ctx *subdom_id_ctx;
errno_t ret;
req = tevent_req_create(mem_ctx, &state,
@@ -934,23 +1016,42 @@ sdap_ad_tokengroups_initgr_posix_send(TALLOC_CTX *mem_ctx,
state->ev = ev;
state->id_ctx = id_ctx;
+ state->conn = conn;
state->opts = opts;
+ state->sh = sh;
state->sysdb = sysdb;
state->domain = domain;
+ state->orig_dn = orig_dn;
+ state->timeout = timeout;
state->username = talloc_strdup(state, name);
if (state->username == NULL) {
ret = ENOMEM;
goto immediately;
}
- subreq = sdap_get_ad_tokengroups_send(state, ev, opts, sh, name, orig_dn,
- timeout);
+ sdom = sdap_domain_get(opts, domain);
+ if (sdom == NULL || sdom->pvt == NULL) {
+ DEBUG(SSSDBG_CRIT_FAILURE, ("No ID ctx available for [%s].\n",
+ domain->name));
+ ret = EINVAL;
+ goto immediately;
+ }
+ subdom_id_ctx = talloc_get_type(sdom->pvt, struct ad_id_ctx);
+ state->op = sdap_id_op_create(state, subdom_id_ctx->ldap_ctx->conn_cache);
+ if (!state->op) {
+ DEBUG(2, ("sdap_id_op_create failed\n"));
+ ret = ENOMEM;
+ goto immediately;
+ }
+
+ subreq = sdap_id_op_connect_send(state->op, state, &ret);
if (subreq == NULL) {
ret = ENOMEM;
goto immediately;
}
- tevent_req_set_callback(subreq, sdap_ad_tokengroups_initgr_posix_tg_done,
+ tevent_req_set_callback(subreq,
+ sdap_ad_tokengroups_initgr_posix_sids_connect_done,
req);
return req;
@@ -967,6 +1068,42 @@ immediately:
}
static void
+sdap_ad_tokengroups_initgr_posix_sids_connect_done(struct tevent_req *subreq)
+{
+ struct sdap_ad_tokengroups_initgr_posix_state *state = NULL;
+ struct tevent_req *req = NULL;
+ int ret;
+ int dp_error = DP_ERR_FATAL;
+
+ req = tevent_req_callback_data(subreq, struct tevent_req);
+ state = tevent_req_data(req,
+ struct sdap_ad_tokengroups_initgr_posix_state);
+
+
+ ret = sdap_id_op_connect_recv(subreq, &dp_error);
+ talloc_zfree(subreq);
+
+ if (ret != EOK) {
+ tevent_req_error(req, ret);
+ return;
+ }
+
+ subreq = sdap_get_ad_tokengroups_send(state, state->ev, state->opts,
+ sdap_id_op_handle(state->op),
+ state->username, state->orig_dn,
+ state->timeout);
+ if (subreq == NULL) {
+ tevent_req_error(req, ENOMEM);
+ return;
+ }
+
+ tevent_req_set_callback(subreq, sdap_ad_tokengroups_initgr_posix_tg_done,
+ req);
+
+ return;
+}
+
+static void
sdap_ad_tokengroups_initgr_posix_tg_done(struct tevent_req *subreq)
{
TALLOC_CTX *tmp_ctx = NULL;
@@ -1089,6 +1226,7 @@ sdap_ad_tokengroups_initgr_posix_tg_done(struct tevent_req *subreq)
/* download missing SIDs */
missing_sids = talloc_steal(state, missing_sids);
subreq = sdap_ad_resolve_sids_send(state, state->ev, state->id_ctx,
+ state->conn,
state->opts, state->domain,
missing_sids);
if (subreq == NULL) {
@@ -1154,6 +1292,7 @@ struct tevent_req *
sdap_ad_tokengroups_initgroups_send(TALLOC_CTX *mem_ctx,
struct tevent_context *ev,
struct sdap_id_ctx *id_ctx,
+ struct sdap_id_conn_ctx *conn,
struct sdap_options *opts,
struct sysdb_ctx *sysdb,
struct sss_domain_info *domain,
@@ -1184,8 +1323,8 @@ sdap_ad_tokengroups_initgroups_send(TALLOC_CTX *mem_ctx,
name, orig_dn,
timeout);
} else {
- subreq = sdap_ad_tokengroups_initgr_posix_send(state, ev, id_ctx, opts,
- sysdb, domain, sh,
+ subreq = sdap_ad_tokengroups_initgr_posix_send(state, ev, id_ctx, conn,
+ opts, sysdb, domain, sh,
name, orig_dn,
timeout);
}