diff options
-rw-r--r-- | source3/auth/auth_util.c | 41 | ||||
-rw-r--r-- | source3/groupdb/mapping.c | 39 | ||||
-rw-r--r-- | source3/nsswitch/winbindd_group.c | 58 | ||||
-rw-r--r-- | source3/passdb/util_sam_sid.c | 57 |
4 files changed, 109 insertions, 86 deletions
diff --git a/source3/auth/auth_util.c b/source3/auth/auth_util.c index 912432b98f..4a23593936 100644 --- a/source3/auth/auth_util.c +++ b/source3/auth/auth_util.c @@ -635,47 +635,6 @@ NT_USER_TOKEN *create_nt_token(uid_t uid, gid_t gid, int ngroups, gid_t *groups, return token; } -static void add_gid_to_array_unique(gid_t gid, gid_t **groups, int *ngroups) -{ - int i; - - if ((*ngroups) >= groups_max()) - return; - - for (i=0; i<*ngroups; i++) { - if ((*groups)[i] == gid) - return; - } - - *groups = Realloc(*groups, ((*ngroups)+1) * sizeof(gid_t)); - - if (*groups == NULL) - return; - - (*groups)[*ngroups] = gid; - *ngroups += 1; -} - -static void add_foreign_gids_from_sid(const DOM_SID *sid, gid_t **groups, - int *ngroups) -{ - DOM_SID *aliases; - int j, num_aliases; - - if (!pdb_enum_alias_memberships(sid, &aliases, &num_aliases)) - return; - - for (j=0; j<num_aliases; j++) { - gid_t gid; - - if (!NT_STATUS_IS_OK(sid_to_gid(&aliases[j], &gid))) - continue; - - add_gid_to_array_unique(gid, groups, ngroups); - } - SAFE_FREE(aliases); -} - static void add_foreign_gids(uid_t uid, gid_t gid, gid_t **groups, int *ngroups) { diff --git a/source3/groupdb/mapping.c b/source3/groupdb/mapping.c index 5eaa4e1386..c153ff258d 100644 --- a/source3/groupdb/mapping.c +++ b/source3/groupdb/mapping.c @@ -542,19 +542,6 @@ static NTSTATUS add_aliasmem(const DOM_SID *alias, const DOM_SID *member) return (result == 0 ? NT_STATUS_OK : NT_STATUS_ACCESS_DENIED); } -static BOOL add_sid_to_array(DOM_SID sid, DOM_SID **sids, int *num) -{ - *sids = Realloc(*sids, ((*num)+1) * sizeof(DOM_SID)); - - if (*sids == NULL) - return False; - - sid_copy(&((*sids)[*num]), &sid); - *num += 1; - - return True; -} - static NTSTATUS enum_aliasmem(const DOM_SID *alias, DOM_SID **sids, int *num) { GROUP_MAP map; @@ -599,7 +586,9 @@ static NTSTATUS enum_aliasmem(const DOM_SID *alias, DOM_SID **sids, int *num) if (!string_to_sid(&sid, string_sid)) continue; - if (!add_sid_to_array(sid, sids, num)) + add_sid_to_array(sid, sids, num); + + if (sids == NULL) return NT_STATUS_NO_MEMORY; } @@ -713,8 +702,16 @@ static NTSTATUS alias_memberships(const DOM_SID *sid, DOM_SID **sids, int *num) return NT_STATUS_NO_MEMORY; for (i=0; i<num_maps; i++) { - if (is_foreign_alias_member(sid, &maps[i].sid)) + + if (is_foreign_alias_member(sid, &maps[i].sid)) { + add_sid_to_array(maps[i].sid, sids, num); + + if (sids == NULL) { + SAFE_FREE(maps); + return NT_STATUS_NO_MEMORY; + } + } } SAFE_FREE(maps); @@ -722,8 +719,15 @@ static NTSTATUS alias_memberships(const DOM_SID *sid, DOM_SID **sids, int *num) return NT_STATUS_NO_MEMORY; for (i=0; i<num_maps; i++) { - if (is_foreign_alias_member(sid, &maps[i].sid)) + if (is_foreign_alias_member(sid, &maps[i].sid)) { + add_sid_to_array(maps[i].sid, sids, num); + + if (sids == NULL) { + SAFE_FREE(maps); + return NT_STATUS_NO_MEMORY; + } + } } SAFE_FREE(maps); @@ -1054,6 +1058,9 @@ BOOL get_sid_list_of_group(gid_t gid, DOM_SID **sids, int *num_sids) for (i=0; i<num_members; i++) { add_sid_to_array(members[i], sids, num_sids); + + if (sids == NULL) + return False; } } diff --git a/source3/nsswitch/winbindd_group.c b/source3/nsswitch/winbindd_group.c index 4805e628dd..90597d9b3f 100644 --- a/source3/nsswitch/winbindd_group.c +++ b/source3/nsswitch/winbindd_group.c @@ -896,6 +896,20 @@ enum winbindd_result winbindd_list_groups(struct winbindd_cli_state *state) return WINBINDD_OK; } +static void add_gids_from_sid(DOM_SID *sid, gid_t **gids, int *num) +{ + gid_t gid; + + DEBUG(10, ("Adding gids from SID: %s\n", sid_string_static(sid))); + + if (NT_STATUS_IS_OK(idmap_sid_to_gid(sid, &gid, 0))) + add_gid_to_array_unique(gid, gids, num); + + /* Add nested group memberships */ + + add_foreign_gids_from_sid(sid, gids, num); +} + /* Get user supplementary groups. This is much quicker than trying to invert the groups database. We merge the groups from the gids and other_sids info3 fields as trusted domain, universal group @@ -913,7 +927,7 @@ enum winbindd_result winbindd_getgroups(struct winbindd_cli_state *state) DOM_SID **user_grpsids; struct winbindd_domain *domain; enum winbindd_result result = WINBINDD_ERROR; - gid_t *gid_list; + gid_t *gid_list = NULL; unsigned int i; TALLOC_CTX *mem_ctx; NET_USER_INFO_3 *info3 = NULL; @@ -961,6 +975,8 @@ enum winbindd_result winbindd_getgroups(struct winbindd_cli_state *state) goto done; } + add_gids_from_sid(&user_sid, &gid_list, &num_gids); + /* Treat the info3 cache as authoritative as the lookup_usergroups() function may return cached data. */ @@ -970,7 +986,6 @@ enum winbindd_result winbindd_getgroups(struct winbindd_cli_state *state) info3->num_groups2, info3->num_other_sids)); num_groups = info3->num_other_sids + info3->num_groups2; - gid_list = calloc(sizeof(gid_t), num_groups); /* Go through each other sid and convert it to a gid */ @@ -1004,23 +1019,11 @@ enum winbindd_result winbindd_getgroups(struct winbindd_cli_state *state) continue; } - /* Map to a gid */ + add_gids_from_sid(&info3->other_sids[i].sid, + &gid_list, &num_gids); - if (!NT_STATUS_IS_OK(idmap_sid_to_gid(&info3->other_sids[i].sid, &gid_list[num_gids], 0)) ) - { - DEBUG(10, ("winbindd_getgroups: could not map sid %s to gid\n", - sid_string_static(&info3->other_sids[i].sid))); - continue; - } - - /* We've jumped through a lot of hoops to get here */ - - DEBUG(10, ("winbindd_getgroups: mapped other sid %s to " - "gid %lu\n", sid_string_static( - &info3->other_sids[i].sid), - (unsigned long)gid_list[num_gids])); - - num_gids++; + if (gid_list == NULL) + goto done; } for (i = 0; i < info3->num_groups2; i++) { @@ -1030,12 +1033,10 @@ enum winbindd_result winbindd_getgroups(struct winbindd_cli_state *state) sid_copy( &group_sid, &domain->sid ); sid_append_rid( &group_sid, info3->gids[i].g_rid ); - if (!NT_STATUS_IS_OK(idmap_sid_to_gid(&group_sid, &gid_list[num_gids], 0)) ) { - DEBUG(10, ("winbindd_getgroups: could not map sid %s to gid\n", - sid_string_static(&group_sid))); - } + add_gids_from_sid(&group_sid, &gid_list, &num_gids); - num_gids++; + if (gid_list == NULL) + goto done; } SAFE_FREE(info3); @@ -1053,12 +1054,11 @@ enum winbindd_result winbindd_getgroups(struct winbindd_cli_state *state) goto done; for (i = 0; i < num_groups; i++) { - if (!NT_STATUS_IS_OK(idmap_sid_to_gid(user_grpsids[i], &gid_list[num_gids], 0))) { - DEBUG(1, ("unable to convert group sid %s to gid\n", - sid_string_static(user_grpsids[i]))); - continue; - } - num_gids++; + add_gids_from_sid(user_grpsids[i], + &gid_list, &num_gids); + + if (gid_list == NULL) + goto done; } } diff --git a/source3/passdb/util_sam_sid.c b/source3/passdb/util_sam_sid.c index f6cc2491a8..db88ea7aea 100644 --- a/source3/passdb/util_sam_sid.c +++ b/source3/passdb/util_sam_sid.c @@ -305,3 +305,60 @@ BOOL map_name_to_wellknown_sid(DOM_SID *sid, enum SID_NAME_USE *use, const char return False; } + +void add_sid_to_array(DOM_SID sid, DOM_SID **sids, int *num) +{ + *sids = Realloc(*sids, ((*num)+1) * sizeof(DOM_SID)); + + if (*sids == NULL) + return; + + sid_copy(&((*sids)[*num]), &sid); + *num += 1; + + return; +} + +void add_gid_to_array_unique(gid_t gid, gid_t **gids, int *num) +{ + int i; + + if ((*num) >= groups_max()) + return; + + for (i=0; i<*num; i++) { + if ((*gids)[i] == gid) + return; + } + + *gids = Realloc(*gids, (*num+1) * sizeof(gid_t)); + + if (*gids == NULL) + return; + + (*gids)[*num] = gid; + *num += 1; +} + +/************************************************************************** + Augment a gid list with gids from alias memberships +***************************************************************************/ + +void add_foreign_gids_from_sid(const DOM_SID *sid, gid_t **gids, int *num) +{ + DOM_SID *aliases; + int j, num_aliases; + + if (!pdb_enum_alias_memberships(sid, &aliases, &num_aliases)) + return; + + for (j=0; j<num_aliases; j++) { + gid_t gid; + + if (!NT_STATUS_IS_OK(sid_to_gid(&aliases[j], &gid))) + continue; + + add_gid_to_array_unique(gid, gids, num); + } + SAFE_FREE(aliases); +} |