summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/providers/ldap/sdap_async.h7
-rw-r--r--src/providers/ldap/sdap_async_initgroups.c44
-rw-r--r--src/providers/ldap/sdap_async_initgroups_ad.c136
-rw-r--r--src/providers/ldap/sdap_async_private.h1
4 files changed, 133 insertions, 55 deletions
diff --git a/src/providers/ldap/sdap_async.h b/src/providers/ldap/sdap_async.h
index af41c719..3b6aaee6 100644
--- a/src/providers/ldap/sdap_async.h
+++ b/src/providers/ldap/sdap_async.h
@@ -286,10 +286,13 @@ sdap_get_ad_tokengroups_initgroups_send(TALLOC_CTX *mem_ctx,
struct sdap_handle *sh,
const char *name,
const char *orig_dn,
- int timeout);
+ int timeout,
+ bool use_id_mapping);
errno_t
-sdap_get_ad_tokengroups_initgroups_recv(struct tevent_req *req);
+sdap_get_ad_tokengroups_initgroups_recv(struct tevent_req *req,
+ bool *_lookup_sids,
+ char ***_group_sid_list);
errno_t sdap_add_incomplete_groups(struct sysdb_ctx *sysdb,
struct sss_domain_info *domain,
diff --git a/src/providers/ldap/sdap_async_initgroups.c b/src/providers/ldap/sdap_async_initgroups.c
index e3539e91..a926dc72 100644
--- a/src/providers/ldap/sdap_async_initgroups.c
+++ b/src/providers/ldap/sdap_async_initgroups.c
@@ -2571,6 +2571,7 @@ struct tevent_req *sdap_get_initgr_send(TALLOC_CTX *memctx,
state->name = name;
state->grp_attrs = grp_attrs;
state->orig_user = NULL;
+ state->cname = NULL;
state->timeout = dp_opt_get_int(state->opts->basic, SDAP_SEARCH_TIMEOUT);
state->user_base_iter = 0;
state->user_search_bases = sdom->user_search_bases;
@@ -2665,7 +2666,6 @@ static void sdap_get_initgr_user(struct tevent_req *subreq)
int ret;
errno_t sret;
const char *orig_dn;
- const char *cname;
bool in_transaction = false;
DEBUG(9, ("Receiving info for the user\n"));
@@ -2738,7 +2738,7 @@ static void sdap_get_initgr_user(struct tevent_req *subreq)
in_transaction = false;
ret = sysdb_get_real_name(state, state->sysdb,
- state->dom, state->name, &cname);
+ state->dom, state->name, &state->cname);
if (ret != EOK) {
DEBUG(SSSDBG_OP_FAILURE, ("Cannot canonicalize username\n"));
tevent_req_error(req, ret);
@@ -2751,7 +2751,7 @@ static void sdap_get_initgr_user(struct tevent_req *subreq)
case SDAP_SCHEMA_RFC2307:
subreq = sdap_initgr_rfc2307_send(state, state->ev, state->opts,
state->sysdb, state->dom, state->sh,
- cname);
+ state->cname);
if (!subreq) {
tevent_req_error(req, ENOMEM);
return;
@@ -2769,8 +2769,7 @@ static void sdap_get_initgr_user(struct tevent_req *subreq)
return;
}
- if (state->use_id_mapping
- && state->opts->dc_functional_level >= DS_BEHAVIOR_WIN2008) {
+ if (state->opts->dc_functional_level >= DS_BEHAVIOR_WIN2008) {
/* Take advantage of AD's tokenGroups mechanism to look up all
* parent groups in a single request.
*/
@@ -2779,8 +2778,10 @@ static void sdap_get_initgr_user(struct tevent_req *subreq)
state->sysdb,
state->dom,
state->sh,
- cname, orig_dn,
- state->timeout);
+ state->cname,
+ orig_dn,
+ state->timeout,
+ state->use_id_mapping);
} else if (state->opts->support_matching_rule
&& dp_opt_get_bool(state->opts->basic,
SDAP_AD_MATCHING_RULE_INITGROUPS)) {
@@ -2792,13 +2793,17 @@ static void sdap_get_initgr_user(struct tevent_req *subreq)
state->sysdb,
state->dom,
state->sh,
- cname, orig_dn,
+ state->cname,
+ orig_dn,
state->timeout);
} else {
- subreq = sdap_initgr_rfc2307bis_send(
- state, state->ev, state->opts, state->sysdb,
- state->dom, state->sh,
- cname, orig_dn);
+ subreq = sdap_initgr_rfc2307bis_send(state, state->ev,
+ state->opts,
+ state->sysdb,
+ state->dom,
+ state->sh,
+ state->cname,
+ orig_dn);
}
if (!subreq) {
tevent_req_error(req, ENOMEM);
@@ -2852,7 +2857,8 @@ static void sdap_get_initgr_done(struct tevent_req *subreq)
char *group_sid_str;
struct sdap_options *opts = state->opts;
- DEBUG(9, ("Initgroups done\n"));
+ char **group_sid_list;
+ bool lookup_sids = false;
tmp_ctx = talloc_new(NULL);
if (!tmp_ctx) {
@@ -2867,9 +2873,8 @@ static void sdap_get_initgr_done(struct tevent_req *subreq)
case SDAP_SCHEMA_RFC2307BIS:
case SDAP_SCHEMA_AD:
- if (state->use_id_mapping
- && state->opts->dc_functional_level >= DS_BEHAVIOR_WIN2008) {
- ret = sdap_get_ad_tokengroups_initgroups_recv(subreq);
+ if (state->opts->dc_functional_level >= DS_BEHAVIOR_WIN2008) {
+ ret = sdap_get_ad_tokengroups_initgroups_recv(subreq, &lookup_sids, &group_sid_list);
}
else if (state->opts->support_matching_rule
&& dp_opt_get_bool(state->opts->basic,
@@ -2890,6 +2895,13 @@ static void sdap_get_initgr_done(struct tevent_req *subreq)
break;
}
+ if (lookup_sids) {
+ DEBUG(SSSDBG_TRACE_FUNC, ("Some of users TokenGroups not found in "
+ "cache, will perform LDAP lookup.\n"));
+ }
+
+ DEBUG(9, ("Initgroups done\n"));
+
talloc_zfree(subreq);
if (ret) {
DEBUG(9, ("Error in initgroups: [%d][%s]\n",
diff --git a/src/providers/ldap/sdap_async_initgroups_ad.c b/src/providers/ldap/sdap_async_initgroups_ad.c
index e5649a2b..8fc56c0e 100644
--- a/src/providers/ldap/sdap_async_initgroups_ad.c
+++ b/src/providers/ldap/sdap_async_initgroups_ad.c
@@ -305,6 +305,9 @@ struct sdap_ad_tokengroups_initgr_state {
struct sss_domain_info *domain;
struct sdap_handle *sh;
const char *username;
+ bool use_id_mapping;
+ bool lookup_sids;
+ char **group_sid_list;
};
static void
@@ -319,7 +322,8 @@ sdap_get_ad_tokengroups_initgroups_send(TALLOC_CTX *mem_ctx,
struct sdap_handle *sh,
const char *name,
const char *orig_dn,
- int timeout)
+ int timeout,
+ bool use_id_mapping)
{
struct tevent_req *req;
struct tevent_req *subreq;
@@ -336,6 +340,9 @@ sdap_get_ad_tokengroups_initgroups_send(TALLOC_CTX *mem_ctx,
state->domain = domain;
state->sh = sh;
state->username = name;
+ state->use_id_mapping = use_id_mapping;
+ state->lookup_sids = false;
+ state->group_sid_list = NULL;
subreq = sdap_get_generic_send(
state, state->ev, state->opts, state->sh,
@@ -359,6 +366,7 @@ sdap_get_ad_tokengroups_initgroups_lookup_done(struct tevent_req *subreq)
errno_t ret, sret;
enum idmap_error_code err;
size_t user_count, group_count, i;
+ size_t sid_count = 0;
TALLOC_CTX *tmp_ctx;
bool in_transaction = false;
char *sid_str;
@@ -442,6 +450,14 @@ sdap_get_ad_tokengroups_initgroups_lookup_done(struct tevent_req *subreq)
}
group_count = 0;
+ if (!state->use_id_mapping) {
+ state->group_sid_list = talloc_array(state, char*, el->num_values + 1);
+ if (!state->group_sid_list) {
+ ret = ENOMEM;
+ goto done;
+ }
+ }
+
for (i = 0; i < el->num_values; i++) {
/* Get the SID and convert it to a GID */
@@ -464,20 +480,29 @@ sdap_get_ad_tokengroups_initgroups_lookup_done(struct tevent_req *subreq)
DEBUG(SSSDBG_TRACE_FUNC, ("Skipping built-in object.\n"));
ret = EOK;
continue;
- } else if (ret != EOK) {
- DEBUG(SSSDBG_MINOR_FAILURE,
- ("Could not convert SID to GID: [%s]. Skipping\n",
- strerror(ret)));
- continue;
}
- DEBUG(SSSDBG_TRACE_LIBS,
- ("Processing membership GID [%lu]\n",
- gid));
+ if (state->use_id_mapping) {
+ if (ret != EOK) {
+ DEBUG(SSSDBG_MINOR_FAILURE,
+ ("Could not convert SID to GID: [%s]. Skipping\n",
+ strerror(ret)));
+ continue;
+ }
+
+ DEBUG(SSSDBG_TRACE_LIBS,
+ ("Processing membership GID [%lu]\n",
+ gid));
+
+ /* Check whether this GID already exists in the sysdb */
+ ret = sysdb_search_group_by_gid(tmp_ctx, state->sysdb, state->domain,
+ gid, attrs, &msg);
+ } else {
+ ret = sysdb_search_group_by_sid_str(tmp_ctx, state->sysdb,
+ state->domain, sid_str, attrs,
+ &msg);
+ }
- /* Check whether this GID already exists in the sysdb */
- ret = sysdb_search_group_by_gid(tmp_ctx, state->sysdb, state->domain,
- gid, attrs, &msg);
if (ret == EOK) {
group_name = ldb_msg_find_attr_as_string(msg, SYSDB_NAME, NULL);
if (!group_name) {
@@ -486,23 +511,59 @@ sdap_get_ad_tokengroups_initgroups_lookup_done(struct tevent_req *subreq)
ret = EINVAL;
goto done;
}
- } else if (ret == ENOENT) {
- /* This is a new group. For now, we will store it
- * under the name of its SID. When a direct lookup of
- * the group or its GID occurs, it will replace this
- * temporary entry.
- */
- group_name = sid_str;
- ret = sysdb_add_incomplete_group(state->sysdb,
- state->domain,
- group_name, gid,
- NULL, sid_str, false, now);
- if (ret != EOK) {
- DEBUG(SSSDBG_MINOR_FAILURE,
- ("Could not create incomplete group: [%s]\n",
- strerror(ret)));
+
+ ldap_grouplist[group_count] =
+ talloc_strdup(ldap_grouplist, group_name);
+ if (!ldap_grouplist[group_count]) {
+ ret = ENOMEM;
goto done;
}
+
+ group_count++;
+
+ } else if (ret == ENOENT) {
+ if (state->use_id_mapping) {
+ /* This is a new group. For now, we will store it
+ * under the name of its SID. When a direct lookup of
+ * the group or its GID occurs, it will replace this
+ * temporary entry.
+ */
+ group_name = sid_str;
+ ret = sysdb_add_incomplete_group(state->sysdb,
+ state->domain,
+ group_name, gid,
+ NULL, sid_str, false, now);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_MINOR_FAILURE,
+ ("Could not create incomplete group: [%s]\n",
+ strerror(ret)));
+ goto done;
+ }
+
+ ldap_grouplist[group_count] =
+ talloc_strdup(ldap_grouplist, group_name);
+ if (!ldap_grouplist[group_count]) {
+ ret = ENOMEM;
+ goto done;
+ }
+
+ group_count++;
+
+ } else {
+ DEBUG(SSSDBG_MINOR_FAILURE, ("SID [%s] not found in cache, "
+ "will be looked up\n", sid_str));
+
+ state->lookup_sids = true;
+
+ state->group_sid_list[sid_count] =
+ talloc_strdup(state, sid_str);
+ if (!state->group_sid_list[sid_count]) {
+ ret = ENOMEM;
+ goto done;
+ }
+
+ sid_count++;
+ }
} else {
/* Unexpected error */
DEBUG(SSSDBG_MINOR_FAILURE,
@@ -510,17 +571,9 @@ sdap_get_ad_tokengroups_initgroups_lookup_done(struct tevent_req *subreq)
strerror(ret)));
goto done;
}
-
- ldap_grouplist[group_count] =
- talloc_strdup(ldap_grouplist, group_name);
- if (!ldap_grouplist[group_count]) {
- ret = ENOMEM;
- goto done;
- }
-
- group_count++;
}
ldap_grouplist[group_count] = NULL;
+ state->group_sid_list[sid_count] = NULL;
/* Get the current sysdb group list for this user
* so we can update it.
@@ -582,8 +635,17 @@ done:
}
errno_t
-sdap_get_ad_tokengroups_initgroups_recv(struct tevent_req *req)
+sdap_get_ad_tokengroups_initgroups_recv(struct tevent_req *req,
+ bool *_lookup_sids,
+ char ***_group_sid_list)
{
+ struct sdap_ad_tokengroups_initgr_state *state =
+ tevent_req_data(req, struct sdap_ad_tokengroups_initgr_state);
+
TEVENT_REQ_RETURN_ON_ERROR(req);
+
+ *_lookup_sids = state->lookup_sids;
+ *_group_sid_list = state->group_sid_list;
+
return EOK;
}
diff --git a/src/providers/ldap/sdap_async_private.h b/src/providers/ldap/sdap_async_private.h
index 4d0b8652..27b8e365 100644
--- a/src/providers/ldap/sdap_async_private.h
+++ b/src/providers/ldap/sdap_async_private.h
@@ -44,6 +44,7 @@ struct sdap_get_initgr_state {
struct sdap_id_ctx *id_ctx;
struct sdap_id_conn_ctx *conn;
const char *name;
+ const char *cname;
const char **grp_attrs;
const char **user_attrs;
const char *user_base_filter;