summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source3/auth/auth_util.c41
-rw-r--r--source3/groupdb/mapping.c39
-rw-r--r--source3/nsswitch/winbindd_group.c58
-rw-r--r--source3/passdb/util_sam_sid.c57
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);
+}