]> sourceware.org Git - newlib-cygwin.git/commitdiff
* security.h (cygsidlist::addfromgr): Allow duplicate entries.
authorCorinna Vinschen <corinna@vinschen.de>
Sat, 16 Apr 2005 15:21:47 +0000 (15:21 +0000)
committerCorinna Vinschen <corinna@vinschen.de>
Sat, 16 Apr 2005 15:21:47 +0000 (15:21 +0000)
(get_server_groups): Declare new function.
* security.cc (is_group_member): Simplify.
(get_server_groups): New function.
(get_initgroups_sidlist): Call get_server_groups.
(verify_token): Allow token when supplementary sids are not in
/etc/group but are in the token.
Streamline the code.
* grp.cc (initgroups32): New implementation.
(getgroups32): Handle case where the supplementary groups are set.

winsup/cygwin/ChangeLog
winsup/cygwin/grp.cc
winsup/cygwin/security.cc
winsup/cygwin/security.h

index df933c2ab57c8914056e0351f1e1c0e439d9baec..64bb229f2c7dc50240cd25724552db811149ae44 100644 (file)
@@ -1,3 +1,17 @@
+2005-04-16  Corinna Vinschen  <corinna@vinschen.de>
+           Pierre Humblet <pierre.humblet@ieee.org>
+
+       * security.h (cygsidlist::addfromgr): Allow duplicate entries.
+       (get_server_groups): Declare new function.
+       * security.cc (is_group_member): Simplify.
+       (get_server_groups): New function.
+       (get_initgroups_sidlist): Call get_server_groups.
+       (verify_token): Allow token when supplementary sids are not in
+       /etc/group but are in the token.
+       Streamline the code.
+       * grp.cc (initgroups32): New implementation.
+       (getgroups32): Handle case where the supplementary groups are set.
+
 2005-04-16  Corinna Vinschen  <corinna@vinschen.de>
 
        * environ.cc (environ_init): Don't set traverse checking as default.
index ae3c27ad21bfa6a98caaadbef54e0643dcd0436f..c82a59ffc48c3f7e3513b28affe608a78cc6fec4 100644 (file)
@@ -344,14 +344,32 @@ internal_getgroups (int gidsetsize, __gid32_t *grouplist, cygpsid * srchsid)
   __gid32_t gid;
   const char *username;
 
-  if (allow_ntsec)
+  if (!srchsid && cygheap->user.groups.issetgroups ())
     {
-      /* If impersonated, use impersonation token. */
-      if (cygheap->user.issetuid ())
-       hToken = cygheap->user.token ();
-      else
-        hToken = hProcImpToken;
+      cygsid sid;
+      for (int gidx = 0; (gr = internal_getgrent (gidx)); ++gidx)
+       if (sid.getfromgr (gr))
+         for (int pg = 0; pg < cygheap->user.groups.sgsids.count; ++pg)
+           if (sid == cygheap->user.groups.sgsids.sids[pg] &&
+               sid != well_known_world_sid)
+             {
+               if (cnt < gidsetsize)
+                 grouplist[cnt] = gr->gr_gid;
+               ++cnt;
+               if (gidsetsize && cnt > gidsetsize)
+                 goto error;
+               break;
+             }
+      return cnt;
     }
+
+
+  /* If impersonated, use impersonation token. */
+  if (cygheap->user.issetuid ())
+    hToken = cygheap->user.token ();
+  else
+    hToken = hProcImpToken;
+
   if (hToken)
     {
       if (GetTokenInformation (hToken, TokenGroups, NULL, 0, &size)
@@ -450,9 +468,32 @@ getgroups (int gidsetsize, __gid16_t *grouplist)
 extern "C" int
 initgroups32 (const char *name, __gid32_t gid)
 {
+  int ret;
   if (wincap.has_security ())
-    cygheap->user.groups.clear_supp ();
-  syscall_printf ( "0 = initgroups (%s, %u)", name, gid);
+    {
+      ret = -1;
+      struct passwd *pw = internal_getpwnam (name);
+      struct __group32 *gr = internal_getgrgid (gid);
+      cygsid usersid, grpsid;
+      if (!usersid.getfrompw (pw) || !grpsid.getfromgr (gr))
+       {
+         set_errno (EINVAL);
+         goto out;
+       }
+      cygsidlist tmp_gsids (cygsidlist_auto, 12);
+      if (!get_server_groups (tmp_gsids, usersid, pw))
+       goto out;
+      tmp_gsids += grpsid;
+      cygsidlist new_gsids (cygsidlist_alloc, tmp_gsids.count);
+      for (int i = 0; i < tmp_gsids.count; i++)
+       new_gsids.sids[i] = tmp_gsids.sids[i];
+      new_gsids.count = tmp_gsids.count;
+      cygheap->user.groups.update_supp (new_gsids);
+    }
+  ret = 0;
+
+ out:
+  syscall_printf ( "%d = initgroups (%s, %u)", ret, name, gid);
   return 0;
 }
 
index e74fd8df8822d9918d3e376312aa1e8a80e42429..e2a9426a4a11b6d137ece6593b9255b611aa5c47 100644 (file)
@@ -42,8 +42,7 @@ details. */
 
 bool allow_ntsec;
 /* allow_smbntsec is handled exclusively in path.cc (path_conv::check).
-   It's defined here because of it's strong relationship to allow_ntsec.
-   The default is TRUE to reflect the old behaviour. */
+   It's defined here because of it's strong relationship to allow_ntsec. */
 bool allow_smbntsec;
 bool allow_traverse;
 
@@ -363,7 +362,6 @@ is_group_member (WCHAR *wgroup, PSID pusersid, cygsidlist &grp_list)
   LPLOCALGROUP_MEMBERS_INFO_0 buf;
   DWORD cnt, tot;
   NET_API_STATUS ret;
-  bool retval = false;
 
   /* Members can be users or global groups */
   ret = NetLocalGroupGetMembers (NULL, wgroup, 0, (LPBYTE *) &buf,
@@ -371,14 +369,17 @@ is_group_member (WCHAR *wgroup, PSID pusersid, cygsidlist &grp_list)
   if (ret)
     return false;
 
-  for (DWORD bidx = 0; !retval && bidx < cnt; ++bidx)
+  bool retval = true;
+  for (DWORD bidx = 0; bidx < cnt; ++bidx)
     if (EqualSid (pusersid, buf[bidx].lgrmi0_sid))
-      retval = true;
+      goto done;
     else
-      for (int glidx = 0; !retval && glidx < grp_list.count; ++glidx)
+      for (int glidx = 0; glidx < grp_list.count; ++glidx)
        if (EqualSid (grp_list.sids[glidx], buf[bidx].lgrmi0_sid))
-         retval = true;
+         goto done;
 
+  retval = false;
+ done:
   NetApiBufferFree (buf);
   return retval;
 }
@@ -545,6 +546,30 @@ get_token_group_sidlist (cygsidlist &grp_list, PTOKEN_GROUPS my_grps,
     }
 }
 
+bool
+get_server_groups (cygsidlist &grp_list, PSID usersid, struct passwd *pw)
+{
+  char user[UNLEN + 1];
+  char domain[INTERNET_MAX_HOST_NAME_LENGTH + 1];
+  WCHAR wserver[INTERNET_MAX_HOST_NAME_LENGTH + 3];
+  char server[INTERNET_MAX_HOST_NAME_LENGTH + 3];
+
+  if (well_known_system_sid == usersid)
+    {
+      grp_list += well_known_admins_sid;
+      get_unix_group_sidlist (pw, grp_list);
+      return true;
+    }
+
+  grp_list += well_known_world_sid;
+  grp_list += well_known_authenticated_users_sid;
+  extract_nt_dom_user (pw, domain, user);
+  if (get_logon_server (domain, server, wserver))
+    get_user_groups (wserver, grp_list, user, domain);
+  get_unix_group_sidlist (pw, grp_list);
+  return get_user_local_groups (grp_list, usersid);
+}
+
 static bool
 get_initgroups_sidlist (cygsidlist &grp_list,
                        PSID usersid, PSID pgrpsid, struct passwd *pw,
@@ -554,26 +579,12 @@ get_initgroups_sidlist (cygsidlist &grp_list,
   grp_list += well_known_world_sid;
   grp_list += well_known_authenticated_users_sid;
   if (well_known_system_sid == usersid)
-    {
-      auth_pos = -1;
-      grp_list += well_known_admins_sid;
-      get_unix_group_sidlist (pw, grp_list);
-    }
-  else
-    {
-      char user[UNLEN + 1];
-      char domain[INTERNET_MAX_HOST_NAME_LENGTH + 1];
-      WCHAR wserver[INTERNET_MAX_HOST_NAME_LENGTH + 3];
-      char server[INTERNET_MAX_HOST_NAME_LENGTH + 3];
+    auth_pos = -1;
+   else
+     get_token_group_sidlist (grp_list, my_grps, auth_luid, auth_pos);
+  if (!get_server_groups (grp_list, usersid, pw))
+    return false;
 
-      get_token_group_sidlist (grp_list, my_grps, auth_luid, auth_pos);
-      extract_nt_dom_user (pw, domain, user);
-      if (get_logon_server (domain, server, wserver))
-       get_user_groups (wserver, grp_list, user, domain);
-      get_unix_group_sidlist (pw, grp_list);
-      if (!get_user_local_groups (grp_list, usersid))
-       return false;
-    }
   /* special_pgrp true if pgrpsid is not in normal groups */
   if ((special_pgrp = !grp_list.contains (pgrpsid)))
     grp_list += pgrpsid;
@@ -775,8 +786,7 @@ verify_token (HANDLE token, cygsid &usersid, user_groups &groups, bool *pintern)
     }
 
   PTOKEN_GROUPS my_grps;
-  bool saw_buf[NGROUPS_MAX] = {};
-  bool *saw = saw_buf, sawpg = false, ret = false;
+  bool sawpg = false, ret = false;
 
   if (!GetTokenInformation (token, TokenGroups, NULL, 0, &size) &&
       GetLastError () != ERROR_INSUFFICIENT_BUFFER)
@@ -785,40 +795,39 @@ verify_token (HANDLE token, cygsid &usersid, user_groups &groups, bool *pintern)
     debug_printf ("alloca (my_grps) failed.");
   else if (!GetTokenInformation (token, TokenGroups, my_grps, size, &size))
     debug_printf ("GetTokenInformation(my_token, TokenGroups), %E");
-  else if (!groups.issetgroups ()) /* setgroups was never called */
-    ret = sid_in_token_groups (my_grps, groups.pgsid)
-         || groups.pgsid == usersid;
-  else /* setgroups was called */
+  else
     {
-      struct __group32 *gr;
-      cygsid gsid;
-      if (groups.sgsids.count > (int) (sizeof (saw_buf) / sizeof (*saw_buf))
-         && !(saw = (bool *) calloc (groups.sgsids.count, sizeof (bool))))
-       goto done;
-
-      /* token groups found in /etc/group match the user.gsids ? */
-      for (int gidx = 0; (gr = internal_getgrent (gidx)); ++gidx)
-       if (gsid.getfromgr (gr) && sid_in_token_groups (my_grps, gsid))
-         {
-           int pos = groups.sgsids.position (gsid);
-           if (pos >= 0)
-             saw[pos] = true;
-           else if (groups.pgsid == gsid)
-             sawpg = true;
-           else if (gsid != well_known_world_sid
-                    && gsid != usersid)
+      if (groups.issetgroups ()) /* setgroups was called */
+       {
+         cygsid gsid;
+         struct __group32 *gr;
+         bool saw[groups.sgsids.count];
+         memset (saw, 0, sizeof(saw));
+
+         /* token groups found in /etc/group match the user.gsids ? */
+         for (int gidx = 0; (gr = internal_getgrent (gidx)); ++gidx)
+           if (gsid.getfromgr (gr) && sid_in_token_groups (my_grps, gsid))
+             {
+               int pos = groups.sgsids.position (gsid);
+               if (pos >= 0)
+                 saw[pos] = true;
+               else if (groups.pgsid == gsid)
+                 sawpg = true;
+               else if (gsid != well_known_world_sid
+                        && gsid != usersid)
+                 goto done;
+             }
+         /* user.sgsids groups must be in the token */
+         for (int gidx = 0; gidx < groups.sgsids.count; gidx++)
+           if (!saw[gidx] && !sid_in_token_groups (my_grps, groups.sgsids.sids[gidx]))
              goto done;
-         }
-      for (int gidx = 0; gidx < groups.sgsids.count; gidx++)
-       if (!saw[gidx])
-         goto done;
+       }
+      /* The primary group must be in the token */
       ret = sawpg
-           || groups.sgsids.contains (groups.pgsid)
-           || groups.pgsid == usersid;
+       || sid_in_token_groups (my_grps, groups.pgsid)
+       || groups.pgsid == usersid;
     }
 done:
-  if (saw != saw_buf)
-    free (saw);
   return ret;
 }
 
index 1c95d30b32e19731fd590dafbbf12ccf5824eee5..d304525a4298f528e9c79411b87256d7b2c29068 100644 (file)
@@ -148,8 +148,7 @@ public:
   BOOL add (const char *sidstr)
     { cygsid nsi (sidstr); return add (nsi); }
   BOOL addfromgr (struct __group32 *gr) /* Only with alloc */
-    { return sids[count].getfromgr (gr)
-            && (contains (sids[count]) || ++count); }
+    { return sids[count].getfromgr (gr) && ++count; }
 
   BOOL operator+= (cygsid &si) { return add (si); }
   BOOL operator+= (const char *sidstr) { return add (sidstr); }
@@ -326,6 +325,8 @@ HANDLE subauth (struct passwd *pw);
 HANDLE create_token (cygsid &usersid, user_groups &groups, struct passwd * pw);
 /* Verify an existing token */
 bool verify_token (HANDLE token, cygsid &usersid, user_groups &groups, bool *pintern = NULL);
+/* Get groups of a user */
+bool get_server_groups (cygsidlist &grp_list, PSID usersid, struct passwd *pw);
 
 /* Extract U-domain\user field from passwd entry. */
 void extract_nt_dom_user (const struct passwd *pw, char *domain, char *user);
This page took 0.044149 seconds and 5 git commands to generate.