OSDN Git Service

* autoload.cc (DsGetDcNameW): Replace DsGetDcNameA.
authorcorinna <corinna>
Wed, 9 Jul 2008 11:58:38 +0000 (11:58 +0000)
committercorinna <corinna>
Wed, 9 Jul 2008 11:58:38 +0000 (11:58 +0000)
* dcrt0.cc (child_info_spawn::handle_spawn): Drop artificial
supplementary group list from calling setgroups in parent.
* grp.cc (internal_getgroups): Drop 9x-only code.  Reformat.
* sec_auth.cc (get_logon_server): Do everything in WCHAR only.
(get_user_groups): Ditto.  Use wlogonserver in LookupAccountNameW
calls, too.
(is_group_member): Get logon server as first argument and use in call
to NetLocalGroupGetMembers.
(get_user_local_groups): Get logon server as first argument and use in
calls to NetLocalGroupEnum and LookupAccountNameW.  Revamp to work
more correctly in domain environments.
(get_server_groups): Accommodate aforementioned changed function calls.
* security.h (get_logon_server): Change prototype accordingly.
* uinfo.cc (cygheap_user::env_logsrv): Accommodate changed
get_logon_server call.

winsup/cygwin/ChangeLog
winsup/cygwin/autoload.cc
winsup/cygwin/dcrt0.cc
winsup/cygwin/grp.cc
winsup/cygwin/sec_auth.cc
winsup/cygwin/security.h
winsup/cygwin/uinfo.cc

index 6b7e0ed..61d3675 100644 (file)
@@ -1,5 +1,24 @@
 2008-07-09  Corinna Vinschen  <corinna@vinschen.de>
 
+       * autoload.cc (DsGetDcNameW): Replace DsGetDcNameA.
+       * dcrt0.cc (child_info_spawn::handle_spawn): Drop artificial
+       supplementary group list from calling setgroups in parent.
+       * grp.cc (internal_getgroups): Drop 9x-only code.  Reformat.
+       * sec_auth.cc (get_logon_server): Do everything in WCHAR only.
+       (get_user_groups): Ditto.  Use wlogonserver in LookupAccountNameW
+       calls, too.
+       (is_group_member): Get logon server as first argument and use in call
+       to NetLocalGroupGetMembers.
+       (get_user_local_groups): Get logon server as first argument and use in
+       calls to NetLocalGroupEnum and LookupAccountNameW.  Revamp to work
+       more correctly in domain environments.
+       (get_server_groups): Accommodate aforementioned changed function calls.
+       * security.h (get_logon_server): Change prototype accordingly.
+       * uinfo.cc (cygheap_user::env_logsrv): Accommodate changed
+       get_logon_server call.
+
+2008-07-09  Corinna Vinschen  <corinna@vinschen.de>
+
        * grp.cc (internal_getgroups): Also add integrity-enabled groups.
 
 2008-07-09  Corinna Vinschen  <corinna@vinschen.de>
index f9f02f2..80228e2 100644 (file)
@@ -302,7 +302,7 @@ wsock_init ()
 LoadDLLprime (ws2_32, _wsock_init)
 
 /* 127 == ERROR_PROC_NOT_FOUND */
-LoadDLLfuncEx2 (DsGetDcNameA, 24, netapi32, 1, 127)
+LoadDLLfuncEx2 (DsGetDcNameW, 24, netapi32, 1, 127)
 LoadDLLfunc (NetApiBufferFree, 4, netapi32)
 LoadDLLfuncEx (NetGetAnyDCName, 12, netapi32, 1)
 LoadDLLfuncEx (NetGetDCName, 12, netapi32, 1)
index e0fa5b5..dddb97f 100644 (file)
@@ -671,6 +671,7 @@ child_info_spawn::handle_spawn ()
     cygheap->fdtab.move_fd (__stdin, 0);
   if (__stdout >= 0)
     cygheap->fdtab.move_fd (__stdout, 1);
+  cygheap->user.groups.clear_supp ();
 
   ready (true);
 
index 37a0fcd..f38888e 100644 (file)
@@ -331,8 +331,6 @@ internal_getgroups (int gidsetsize, __gid32_t *grouplist, cygpsid * srchsid)
   DWORD size;
   int cnt = 0;
   struct __group32 *gr;
-  __gid32_t gid;
-  const char *username;
 
   if (!srchsid && cygheap->user.groups.issetgroups ())
     {
@@ -340,8 +338,8 @@ internal_getgroups (int gidsetsize, __gid32_t *grouplist, cygpsid * srchsid)
       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 (sid == cygheap->user.groups.sgsids.sids[pg]
+               && sid != well_known_world_sid)
              {
                if (cnt < gidsetsize)
                  grouplist[cnt] = gr->gr_gid;
@@ -360,67 +358,41 @@ internal_getgroups (int gidsetsize, __gid32_t *grouplist, cygpsid * srchsid)
   else
     hToken = hProcToken;
 
-  if (hToken)
+  if (GetTokenInformation (hToken, TokenGroups, NULL, 0, &size)
+      || GetLastError () == ERROR_INSUFFICIENT_BUFFER)
     {
-      if (GetTokenInformation (hToken, TokenGroups, NULL, 0, &size)
-         || GetLastError () == ERROR_INSUFFICIENT_BUFFER)
+      PTOKEN_GROUPS groups = (PTOKEN_GROUPS) alloca (size);
+
+      if (GetTokenInformation (hToken, TokenGroups, groups, size, &size))
        {
-         PTOKEN_GROUPS groups = (PTOKEN_GROUPS) alloca (size);
+         cygsid sid;
 
-         if (GetTokenInformation (hToken, TokenGroups, groups, size, &size))
+         if (srchsid)
            {
-             cygsid sid;
-
-             if (srchsid)
-               {
-                 for (DWORD pg = 0; pg < groups->GroupCount; ++pg)
-                   if ((cnt = (*srchsid == groups->Groups[pg].Sid)))
-                     break;
-               }
-             else
-               for (int gidx = 0; (gr = internal_getgrent (gidx)); ++gidx)
-                 if (sid.getfromgr (gr))
-                   for (DWORD pg = 0; pg < groups->GroupCount; ++pg)
-                     if (sid == groups->Groups[pg].Sid
-                         && (groups->Groups[pg].Attributes
-                             & (SE_GROUP_ENABLED | SE_GROUP_INTEGRITY_ENABLED))
-                         && sid != well_known_world_sid)
-                       {
-                         if (cnt < gidsetsize)
-                           grouplist[cnt] = gr->gr_gid;
-                         ++cnt;
-                         if (gidsetsize && cnt > gidsetsize)
-                           goto error;
-                         break;
-                       }
+             for (DWORD pg = 0; pg < groups->GroupCount; ++pg)
+               if ((cnt = (*srchsid == groups->Groups[pg].Sid)))
+                 break;
            }
+         else
+           for (int gidx = 0; (gr = internal_getgrent (gidx)); ++gidx)
+             if (sid.getfromgr (gr))
+               for (DWORD pg = 0; pg < groups->GroupCount; ++pg)
+                 if (sid == groups->Groups[pg].Sid
+                     && (groups->Groups[pg].Attributes
+                         & (SE_GROUP_ENABLED | SE_GROUP_INTEGRITY_ENABLED))
+                     && sid != well_known_world_sid)
+                   {
+                     if (cnt < gidsetsize)
+                       grouplist[cnt] = gr->gr_gid;
+                     ++cnt;
+                     if (gidsetsize && cnt > gidsetsize)
+                       goto error;
+                     break;
+                   }
        }
-      else
-       debug_printf ("%d = GetTokenInformation(NULL) %E", size);
-      return cnt;
     }
-
-  gid = myself->gid;
-  username = cygheap->user.name ();
-  for (int gidx = 0; (gr = internal_getgrent (gidx)); ++gidx)
-    if (gid == gr->gr_gid)
-      {
-       if (cnt < gidsetsize)
-         grouplist[cnt] = gr->gr_gid;
-       ++cnt;
-       if (gidsetsize && cnt > gidsetsize)
-         goto error;
-      }
-    else if (gr->gr_mem)
-      for (int gi = 0; gr->gr_mem[gi]; ++gi)
-       if (strcasematch (username, gr->gr_mem[gi]))
-         {
-           if (cnt < gidsetsize)
-             grouplist[cnt] = gr->gr_gid;
-           ++cnt;
-           if (gidsetsize && cnt > gidsetsize)
-             goto error;
-         }
+  else
+    debug_printf ("%d = GetTokenInformation(NULL) %E", size);
   return cnt;
 
 error:
index f78b865..b2f1fe7 100644 (file)
@@ -11,6 +11,7 @@ details. */
 
 #include "winsup.h"
 #include <stdlib.h>
+#include <wchar.h>
 #include <wininet.h>
 #include <ntsecapi.h>
 #include <dsgetdc.h>
@@ -166,52 +167,43 @@ close_local_policy (LSA_HANDLE &lsa)
 }
 
 bool
-get_logon_server (const char *domain, char *server, WCHAR *wserver,
-                 bool rediscovery)
+get_logon_server (PWCHAR wdomain, WCHAR *wserver, bool rediscovery)
 {
   DWORD dret;
-  PDOMAIN_CONTROLLER_INFOA pci;
+  PDOMAIN_CONTROLLER_INFOW pci;
   WCHAR *buf;
   DWORD size = INTERNET_MAX_HOST_NAME_LENGTH + 1;
-  WCHAR wdomain[size];
 
   /* Empty domain is interpreted as local system */
-  if ((GetComputerName (server + 2, &size)) &&
-      (strcasematch (domain, server + 2) || !domain[0]))
+  if ((GetComputerNameW (wserver + 2, &size)) &&
+      (!wcscasecmp (wdomain, wserver + 2) || !wdomain[0]))
     {
-      server[0] = server[1] = '\\';
-      if (wserver)
-       sys_mbstowcs (wserver, INTERNET_MAX_HOST_NAME_LENGTH + 1, server);
+      wserver[0] = wserver[1] = L'\\';
       return true;
     }
 
   /* Try to get any available domain controller for this domain */
-  dret = DsGetDcNameA (NULL, domain, NULL, NULL,
+  dret = DsGetDcNameW (NULL, wdomain, NULL, NULL,
                       rediscovery ? DS_FORCE_REDISCOVERY : 0, &pci);
   if (dret == ERROR_SUCCESS)
     {
-      strcpy (server, pci->DomainControllerName);
-      sys_mbstowcs (wserver, INTERNET_MAX_HOST_NAME_LENGTH + 1, server);
+      wcscpy (wserver, pci->DomainControllerName);
       NetApiBufferFree (pci);
-      debug_printf ("DC: rediscovery: %d, server: %s", rediscovery, server);
+      debug_printf ("DC: rediscovery: %d, server: %W", rediscovery, wserver);
       return true;
     }
   else if (dret == ERROR_PROC_NOT_FOUND)
     {
       /* NT4 w/o DSClient */
-      sys_mbstowcs (wdomain, INTERNET_MAX_HOST_NAME_LENGTH + 1, domain);
       if (rediscovery)
        dret = NetGetAnyDCName (NULL, wdomain, (LPBYTE *) &buf);
       else
        dret = NetGetDCName (NULL, wdomain, (LPBYTE *) &buf);
       if (dret == NERR_Success)
        {
-         sys_wcstombs (server, INTERNET_MAX_HOST_NAME_LENGTH + 1, buf);
-         if (wserver)
-           for (WCHAR *ptr1 = buf; (*wserver++ = *ptr1++);)
-             ;
+         wcscpy (wserver, buf);
          NetApiBufferFree (buf);
-         debug_printf ("NT: rediscovery: %d, server: %s", rediscovery, server);
+         debug_printf ("NT: rediscovery: %d, server: %W", rediscovery, wserver);
          return true;
        }
     }
@@ -220,12 +212,10 @@ get_logon_server (const char *domain, char *server, WCHAR *wserver,
 }
 
 static bool
-get_user_groups (WCHAR *wlogonserver, cygsidlist &grp_list, char *user,
-                char *domain)
+get_user_groups (WCHAR *wlogonserver, cygsidlist &grp_list,
+                PWCHAR wuser, PWCHAR wdomain)
 {
-  char dgroup[INTERNET_MAX_HOST_NAME_LENGTH + GNLEN + 2];
-  WCHAR wuser[UNLEN + 1];
-  sys_mbstowcs (wuser, UNLEN + 1, user);
+  WCHAR dgroup[INTERNET_MAX_HOST_NAME_LENGTH + GNLEN + 2];
   LPGROUP_USERS_INFO_0 buf;
   DWORD cnt, tot, len;
   NET_API_STATUS ret;
@@ -240,26 +230,26 @@ get_user_groups (WCHAR *wlogonserver, cygsidlist &grp_list, char *user,
       return ret == NERR_UserNotFound;
     }
 
-  len = strlen (domain);
-  strcpy (dgroup, domain);
-  dgroup[len++] = '\\';
+  len = wcslen (wdomain);
+  wcscpy (dgroup, wdomain);
+  dgroup[len++] = L'\\';
 
   for (DWORD i = 0; i < cnt; ++i)
     {
       cygsid gsid;
       DWORD glen = MAX_SID_LEN;
-      char domain[INTERNET_MAX_HOST_NAME_LENGTH + 1];
+      WCHAR domain[INTERNET_MAX_HOST_NAME_LENGTH + 1];
       DWORD dlen = sizeof (domain);
       SID_NAME_USE use = SidTypeInvalid;
 
-      sys_wcstombs (dgroup + len, GNLEN + 1, buf[i].grui0_name);
-      if (!LookupAccountName (NULL, dgroup, gsid, &glen, domain, &dlen, &use))
+      wcscpy (dgroup + len, buf[i].grui0_name);
+      if (!LookupAccountNameW (wlogonserver, dgroup, gsid, &glen,
+                              domain, &dlen, &use))
        debug_printf ("LookupAccountName(%s), %E", dgroup);
       else if (legal_sid_type (use))
        grp_list += gsid;
       else
-       debug_printf ("Global group %s invalid. Domain: %s Use: %d",
-                     dgroup, domain, use);
+       debug_printf ("Global group %s invalid. Use: %d", dgroup, use);
     }
 
   NetApiBufferFree (buf);
@@ -267,14 +257,15 @@ get_user_groups (WCHAR *wlogonserver, cygsidlist &grp_list, char *user,
 }
 
 static bool
-is_group_member (WCHAR *wgroup, PSID pusersid, cygsidlist &grp_list)
+is_group_member (PWCHAR wlogonserver, PWCHAR wgroup, PSID pusersid,
+                cygsidlist &grp_list)
 {
   LPLOCALGROUP_MEMBERS_INFO_1 buf;
   DWORD cnt, tot;
   NET_API_STATUS ret;
 
   /* Members can be users or global groups */
-  ret = NetLocalGroupGetMembers (NULL, wgroup, 1, (LPBYTE *) &buf,
+  ret = NetLocalGroupGetMembers (wlogonserver, wgroup, 1, (LPBYTE *) &buf,
                                 MAX_PREFERRED_LENGTH, &cnt, &tot, NULL);
   if (ret)
     return false;
@@ -310,13 +301,14 @@ is_group_member (WCHAR *wgroup, PSID pusersid, cygsidlist &grp_list)
 }
 
 static bool
-get_user_local_groups (cygsidlist &grp_list, PSID pusersid)
+get_user_local_groups (PWCHAR wlogonserver, PWCHAR wdomain,
+                      cygsidlist &grp_list, PSID pusersid)
 {
   LPLOCALGROUP_INFO_0 buf;
   DWORD cnt, tot;
   NET_API_STATUS ret;
 
-  ret = NetLocalGroupEnum (NULL, 0, (LPBYTE *) &buf,
+  ret = NetLocalGroupEnum (wlogonserver, 0, (LPBYTE *) &buf,
                           MAX_PREFERRED_LENGTH, &cnt, &tot, NULL);
   if (ret)
     {
@@ -324,42 +316,43 @@ get_user_local_groups (cygsidlist &grp_list, PSID pusersid)
       return false;
     }
 
-  char bgroup[INTERNET_MAX_HOST_NAME_LENGTH + GNLEN + 2];
-  char lgroup[INTERNET_MAX_HOST_NAME_LENGTH + GNLEN + 2];
-  DWORD blen, llen;
+  WCHAR domlocal_grp[INTERNET_MAX_HOST_NAME_LENGTH + GNLEN + 2];
+  WCHAR builtin_grp[sizeof ("BUILTIN\\") + GNLEN + 2];
+  PWCHAR dg_ptr, bg_ptr;
   SID_NAME_USE use;
 
-  blen = llen = INTERNET_MAX_HOST_NAME_LENGTH + 1;
-  if (!LookupAccountSid (NULL, well_known_admins_sid, lgroup, &llen, bgroup, &blen, &use)
-      || !GetComputerNameA (lgroup, &(llen = INTERNET_MAX_HOST_NAME_LENGTH + 1)))
-    {
-      __seterrno ();
-      return false;
-    }
-  bgroup[blen++] = lgroup[llen++] = '\\';
+  dg_ptr = wcpcpy (domlocal_grp, wdomain);
+  *dg_ptr++ = L'\\';
+  bg_ptr = wcpcpy (builtin_grp, L"BUILTIN\\");
 
   for (DWORD i = 0; i < cnt; ++i)
-    if (is_group_member (buf[i].lgrpi0_name, pusersid, grp_list))
+    if (is_group_member (wlogonserver, buf[i].lgrpi0_name, pusersid, grp_list))
       {
        cygsid gsid;
        DWORD glen = MAX_SID_LEN;
-       char domain[INTERNET_MAX_HOST_NAME_LENGTH + 1];
-       DWORD dlen = sizeof (domain);
+       WCHAR dom[INTERNET_MAX_HOST_NAME_LENGTH + 1];
+       DWORD domlen = sizeof (dom);
+       bool builtin = false;
 
        use = SidTypeInvalid;
-       sys_wcstombs (bgroup + blen, GNLEN + 1, buf[i].lgrpi0_name);
-       if (!LookupAccountName (NULL, bgroup, gsid, &glen, domain, &dlen, &use))
+       wcscpy (dg_ptr, buf[i].lgrpi0_name);
+       if (!LookupAccountNameW (wlogonserver, domlocal_grp, gsid, &glen,
+                                dom, &domlen, &use))
          {
            if (GetLastError () != ERROR_NONE_MAPPED)
-             debug_printf ("LookupAccountName(%s), %E", bgroup);
-           strcpy (lgroup + llen, bgroup + blen);
-           if (!LookupAccountName (NULL, lgroup, gsid, &glen,
-                                   domain, &dlen, &use))
-             debug_printf ("LookupAccountName(%s), %E", lgroup);
+             debug_printf ("LookupAccountName(%W), %E", domlocal_grp);
+           wcscpy (bg_ptr, dg_ptr);
+           if (!LookupAccountNameW (wlogonserver, builtin_grp, gsid, &glen,
+                                    dom, &domlen, &use))
+             debug_printf ("LookupAccountName(%W), %E", builtin_grp);
+           builtin = true;
          }
        if (!legal_sid_type (use))
-         debug_printf ("Rejecting local %s. use: %d", bgroup + blen, use);
-       grp_list *= gsid;
+         debug_printf ("Rejecting local %W. use: %d", dg_ptr, use);
+       else if (builtin)
+         grp_list *= gsid;
+       else
+         grp_list += gsid;
       }
   NetApiBufferFree (buf);
   return true;
@@ -439,9 +432,10 @@ bool
 get_server_groups (cygsidlist &grp_list, PSID usersid, struct passwd *pw)
 {
   char user[UNLEN + 1];
+  WCHAR wuser[UNLEN + 1];
   char domain[INTERNET_MAX_HOST_NAME_LENGTH + 1];
+  WCHAR wdomain[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)
     {
@@ -453,11 +447,13 @@ get_server_groups (cygsidlist &grp_list, PSID usersid, struct passwd *pw)
   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, false)
-      && !get_user_groups (wserver, grp_list, user, domain)
-      && get_logon_server (domain, server, wserver, true))
-    get_user_groups (wserver, grp_list, user, domain);
-  if (get_user_local_groups (grp_list, usersid))
+  sys_mbstowcs (wdomain, INTERNET_MAX_HOST_NAME_LENGTH + 1, domain);
+  sys_mbstowcs (wuser, UNLEN + 1, user);
+  if (get_logon_server (wdomain, wserver, false)
+      && !get_user_groups (wserver, grp_list, wuser, wdomain)
+      && get_logon_server (wdomain, wserver, true))
+    get_user_groups (wserver, grp_list, wuser, wdomain);
+  if (get_user_local_groups (wserver, wdomain, grp_list, usersid))
     {
       get_unix_group_sidlist (pw, grp_list);
       return true;
index 1eb81b3..93524ce 100644 (file)
@@ -380,8 +380,7 @@ 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);
 /* Get default logonserver for a domain. */
-bool get_logon_server (const char * domain, char * server, WCHAR *wserver,
-                      bool rediscovery);
+bool get_logon_server (PWCHAR domain, PWCHAR wserver, bool rediscovery);
 
 /* sec_helper.cc: Security helper functions. */
 int set_privilege (HANDLE token, DWORD privilege, bool enable);
index c18ad8e..8a4b86d 100644 (file)
@@ -369,10 +369,12 @@ cygheap_user::env_logsrv (const char *name, size_t namelen)
   if (!mydomain || ascii_strcasematch (myname, "SYSTEM"))
     return almost_null;
 
-  char logsrv[INTERNET_MAX_HOST_NAME_LENGTH + 3];
+  WCHAR wdomain[INTERNET_MAX_HOST_NAME_LENGTH + 1];
+  WCHAR wlogsrv[INTERNET_MAX_HOST_NAME_LENGTH + 3];
+  sys_mbstowcs (wdomain, INTERNET_MAX_HOST_NAME_LENGTH + 1, mydomain);
   cfree_and_set (plogsrv, almost_null);
-  if (get_logon_server (mydomain, logsrv, NULL, false))
-    plogsrv = cstrdup (logsrv);
+  if (get_logon_server (wdomain, wlogsrv, false))
+    sys_wcstombs_alloc (&plogsrv, HEAP_STR, wlogsrv);
   return plogsrv;
 }