summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLukas Slebodnik <lslebodn@redhat.com>2014-08-25 10:18:51 +0200
committerJakub Hrozek <jhrozek@redhat.com>2014-08-26 17:34:38 +0200
commite513bf73d6e9ab9ff55a518dd3f91b47b24b6cfa (patch)
treea79e6aa352f883d27e94ff49669d81f76bd29b60
parent599c5f1cf430224c848cd11a144aebe49c815766 (diff)
downloadsssd-e513bf73d6e9ab9ff55a518dd3f91b47b24b6cfa.tar.gz
sssd-e513bf73d6e9ab9ff55a518dd3f91b47b24b6cfa.tar.xz
sssd-e513bf73d6e9ab9ff55a518dd3f91b47b24b6cfa.zip
SDAP: Update groups for user just once.
The function sdap_ad_tokengroups_update_members finds the differences between list of groups from sysdb and list of groups from LDAP (input argument). For each new group, connections are created between user and group. The other connections are removed. The problem was that in some cases function sdap_ad_tokengroups_update_members was called twice (sdap_ad_tokengroups_initgr_posix_tg_done and sdap_ad_tokengroups_initgr_posix_sids_done). The first call created connection between user and groups resolved from tokengroups and the second call update groups from missing SIDs, but previously created connections were removed. The worst case was when there weren't any missing groups. This behaviour caused missing groups in some cases (for users in child ad domain) This patch join array of groups obtained from token group and array of groups obtained from missing SIDs. The function sdap_ad_tokengroups_update_members is called just once with single array. Resolves: https://fedorahosted.org/sssd/ticket/2407 Reviewed-by: Jakub Hrozek <jhrozek@redhat.com> (cherry picked from commit 99f53d551a1db5d8023b4271eb691d554257624c)
-rw-r--r--src/providers/ldap/sdap_async_initgroups_ad.c98
1 files changed, 78 insertions, 20 deletions
diff --git a/src/providers/ldap/sdap_async_initgroups_ad.c b/src/providers/ldap/sdap_async_initgroups_ad.c
index acddbcaf3..9b07507bf 100644
--- a/src/providers/ldap/sdap_async_initgroups_ad.c
+++ b/src/providers/ldap/sdap_async_initgroups_ad.c
@@ -1005,6 +1005,8 @@ struct sdap_ad_tokengroups_initgr_posix_state {
struct sdap_id_op *op;
char **missing_sids;
size_t num_missing_sids;
+ char **cached_groups;
+ size_t num_cached_groups;
};
static void
@@ -1138,12 +1140,14 @@ sdap_ad_tokengroups_initgr_posix_sids_connect_done(struct tevent_req *subreq)
}
static errno_t
-sdap_ad_tokengroups_update_posix_members(TALLOC_CTX *mem_ctx,
+sdap_ad_tokengroups_get_posix_members(TALLOC_CTX *mem_ctx,
struct sdap_ad_tokengroups_initgr_posix_state *state,
size_t num_sids,
char **sids,
size_t *_num_missing,
- char ***_missing)
+ char ***_missing,
+ size_t *_num_valid,
+ char ***_valid_groups)
{
TALLOC_CTX *tmp_ctx = NULL;
struct sss_domain_info *domain = NULL;
@@ -1243,22 +1247,18 @@ sdap_ad_tokengroups_update_posix_members(TALLOC_CTX *mem_ctx,
valid_groups[num_valid_groups] = NULL;
missing_sids[num_missing_sids] = NULL;
- /* update membership of existing groups */
- ret = sdap_ad_tokengroups_update_members(state, state->username,
- state->sysdb, state->domain,
- valid_groups);
- if (ret != EOK) {
- DEBUG(SSSDBG_MINOR_FAILURE, "Membership update failed [%d]: %s\n",
- ret, strerror(ret));
- goto done;
- }
-
/* return list of missing groups */
if (_missing != NULL) {
*_missing = talloc_steal(mem_ctx, missing_sids);
*_num_missing = num_missing_sids;
}
+ /* return list of missing groups */
+ if (_valid_groups != NULL) {
+ *_valid_groups = talloc_steal(mem_ctx, valid_groups);
+ *_num_valid = num_valid_groups;
+ }
+
ret = EOK;
done:
@@ -1286,10 +1286,12 @@ sdap_ad_tokengroups_initgr_posix_tg_done(struct tevent_req *subreq)
goto done;
}
- ret = sdap_ad_tokengroups_update_posix_members(state, state,
- num_sids, sids,
- &state->num_missing_sids,
- &state->missing_sids);
+ ret = sdap_ad_tokengroups_get_posix_members(state, state,
+ num_sids, sids,
+ &state->num_missing_sids,
+ &state->missing_sids,
+ &state->num_cached_groups,
+ &state->cached_groups);
if (ret != EOK) {
goto done;
}
@@ -1318,12 +1320,18 @@ done:
tevent_req_done(req);
}
+static char **concatenate_string_array(TALLOC_CTX *mem_ctx,
+ char **arr1, size_t len1,
+ char **arr2, size_t len2);
+
static void
sdap_ad_tokengroups_initgr_posix_sids_done(struct tevent_req *subreq)
{
struct sdap_ad_tokengroups_initgr_posix_state *state = NULL;
struct tevent_req *req = NULL;
errno_t ret;
+ char **cached_groups;
+ size_t num_cached_groups;
req = tevent_req_callback_data(subreq, struct tevent_req);
state = tevent_req_data(req, struct sdap_ad_tokengroups_initgr_posix_state);
@@ -1336,10 +1344,39 @@ sdap_ad_tokengroups_initgr_posix_sids_done(struct tevent_req *subreq)
goto done;
}
- ret = sdap_ad_tokengroups_update_posix_members(state, state,
- state->num_missing_sids,
- state->missing_sids,
- NULL, NULL);
+ ret = sdap_ad_tokengroups_get_posix_members(state, state,
+ state->num_missing_sids,
+ state->missing_sids,
+ NULL, NULL,
+ &num_cached_groups,
+ &cached_groups);
+ if (ret != EOK){
+ DEBUG(SSSDBG_MINOR_FAILURE,
+ "sdap_ad_tokengroups_get_posix_members failed [%d]: %s\n",
+ ret, strerror(ret));
+ goto done;
+ }
+
+ state->cached_groups = concatenate_string_array(state,
+ state->cached_groups,
+ state->num_cached_groups,
+ cached_groups,
+ num_cached_groups);
+ if (state->cached_groups == NULL) {
+ ret = ENOMEM;
+ goto done;
+ }
+
+ /* update membership of existing groups */
+ ret = sdap_ad_tokengroups_update_members(state,
+ state->username,
+ state->sysdb, state->domain,
+ state->cached_groups);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_MINOR_FAILURE, "Membership update failed [%d]: %s\n",
+ ret, strerror(ret));
+ goto done;
+ }
done:
if (ret != EOK) {
@@ -1350,6 +1387,27 @@ done:
tevent_req_done(req);
}
+static char **concatenate_string_array(TALLOC_CTX *mem_ctx,
+ char **arr1, size_t len1,
+ char **arr2, size_t len2)
+{
+ size_t i, j;
+ size_t new_size = len1 + len2;
+ char ** string_array = talloc_realloc(mem_ctx, arr1, char *, new_size + 1);
+ if (string_array == NULL) {
+ return NULL;
+ }
+
+ for (i=len1, j=0; i < new_size; ++i,++j) {
+ string_array[i] = talloc_steal(string_array,
+ arr2[j]);
+ }
+
+ string_array[i] = NULL;
+
+ return string_array;
+}
+
static errno_t sdap_ad_tokengroups_initgr_posix_recv(struct tevent_req *req)
{
TEVENT_REQ_RETURN_ON_ERROR(req);