Add aliases to winbindd_getgroups().
authorVolker Lendecke <vlendec@samba.org>
Mon, 1 Mar 2004 13:02:06 +0000 (13:02 +0000)
committerVolker Lendecke <vlendec@samba.org>
Mon, 1 Mar 2004 13:02:06 +0000 (13:02 +0000)
su - WINDOWS\\vl

now includes the locally defined aliases I'm member of.

Next will be getent group.

Volker
(This used to be commit 52dae45684317ac8ac529017607bb5787dda7c50)

source3/auth/auth_util.c
source3/groupdb/mapping.c
source3/nsswitch/winbindd_group.c
source3/passdb/util_sam_sid.c

index 912432b98f89a2608167f6a01972b5718bcefb35..4a23593936a521c67ca61d26323d930c0ffbd94a 100644 (file)
@@ -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)
 {
index 5eaa4e1386fe402ba92d95dcb9eac29a91855abe..c153ff258d5c682c024327ac0123dcfed5b81718 100644 (file)
@@ -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;
                }
        }
 
index 4805e628dd800fc0c592eab48640df5b673cffd9..90597d9b3fc8fa9ddc5eb093ac3e5a500c600d2d 100644 (file)
@@ -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;
                }
        }
 
index f6cc2491a8b1169a590f9f2d583e0950295040b9..db88ea7aeae9d1812f896f7d4ca3ac827003dfc7 100644 (file)
@@ -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);
+}