OSDN Git Service

* cygheap.h (cygheap_user): Reorg to accommodate environment caching.
authorcgf <cgf>
Sat, 29 Jun 2002 02:36:08 +0000 (02:36 +0000)
committercgf <cgf>
Sat, 29 Jun 2002 02:36:08 +0000 (02:36 +0000)
(cygheap_user::logsrv): New method.
(cygheap_user::winname): Ditto.
(cygheap_user::domain): Ditto.
(cygheap_user::test_uid): Ditto.
* cygheap.cc (cygheap_user::set_name): Reflect name "pwinname" name change.
* environ.cc (getwinenveq): New function.
(spenv::from_cygheap): Change arguments.
(spenv::retrieve): Ditto for call.  Use getwinenveq to retrieve info from
environment.  Always return value from cygwin environment, if it exists.
* environ.h (getwinenveq): Declare.
* uinfo.cc (cygheap_user::ontherange): Use logsrv() rather than env_logsrv().
(cygheap_user::test_uid): Define new method.
(cygheap_user::env_logsrv): Accept environment arguments.  Use test_uid to find
info.
(cygheap_user::env_domain): Ditto.
(cygheap_user::env_userprofile): Ditto.
(cygheap_user::env_homepath): Ditto.
(cygheap_user::env_homedrive): Ditto.
(cygheap_user::env_name): Ditto.

winsup/cygwin/ChangeLog
winsup/cygwin/cygheap.cc
winsup/cygwin/cygheap.h
winsup/cygwin/environ.cc
winsup/cygwin/environ.h
winsup/cygwin/uinfo.cc

index 9be9d16..0152f46 100644 (file)
@@ -1,3 +1,29 @@
+2002-06-28  Christopher Faylor  <cgf@redhat.com>
+
+       * cygheap.h (cygheap_user): Reorg to accommodate environment caching.
+       (cygheap_user::logsrv): New method.
+       (cygheap_user::winname): Ditto.
+       (cygheap_user::domain): Ditto.
+       (cygheap_user::test_uid): Ditto.
+       * cygheap.cc (cygheap_user::set_name): Reflect name "pwinname" name
+       change.
+       * environ.cc (getwinenveq): New function.
+       (spenv::from_cygheap): Change arguments.
+       (spenv::retrieve): Ditto for call.  Use getwinenveq to retrieve info
+       from environment.  Always return value from cygwin environment, if it
+       exists.
+       * environ.h (getwinenveq): Declare.
+       * uinfo.cc (cygheap_user::ontherange): Use logsrv() rather than
+       env_logsrv().
+       (cygheap_user::test_uid): Define new method.
+       (cygheap_user::env_logsrv): Accept environment arguments.  Use test_uid
+       to find info.
+       (cygheap_user::env_domain): Ditto.
+       (cygheap_user::env_userprofile): Ditto.
+       (cygheap_user::env_homepath): Ditto.
+       (cygheap_user::env_homedrive): Ditto.
+       (cygheap_user::env_name): Ditto.
+
 2002-06-27  Christopher Faylor  <cgf@redhat.com>
 
        * cygheap.cc (cfree_and_set): New function.
index 2cf7e20..f74a97a 100644 (file)
@@ -465,7 +465,7 @@ cygheap_user::set_name (const char *new_name)
   cfree_and_set (homepath);
   cfree_and_set (plogsrv);
   cfree_and_set (pdomain);
-  cfree_and_set (winname);
+  cfree_and_set (pwinname);
 }
 
 BOOL
index e2fcaec..63585d9 100644 (file)
@@ -93,6 +93,7 @@ enum homebodies
 };
 
 struct passwd;
+
 class cygheap_user
 {
   /* Extendend user information.
@@ -103,7 +104,7 @@ class cygheap_user
   char  *pdomain;       /* Logon domain of the user */
   char  *homedrive;    /* User's home drive */
   char  *homepath;     /* User's home path */
-  char  *winname;      /* User's name as far as Windows knows it */
+  char  *pwinname;     /* User's name as far as Windows knows it */
   char  *puserprof;    /* User profile */
   PSID   psid;          /* buffer for user's SID */
   PSID   orig_psid;     /* Remains intact even after impersonation */
@@ -134,13 +135,25 @@ public:
   void set_name (const char *new_name);
   const char *name () const { return pname; }
 
-  const char *env_logsrv ();
-  const char *env_homepath ();
-  const char *env_homedrive ();
-  const char *env_userprofile ();
-  const char *env_domain ();
-  const char *env_name ();
+  const char *env_logsrv (const char *, size_t);
+  const char *env_homepath (const char *, size_t);
+  const char *env_homedrive (const char *, size_t);
+  const char *env_userprofile (const char *, size_t);
+  const char *env_domain (const char *, size_t);
+  const char *env_name (const char *, size_t);
 
+  const char *logsrv ()
+  {
+    return env_logsrv ("LOGONSERVER=", sizeof ("LOGONSERVER=") - 1);
+  }
+  const char *winname ()
+  {
+    return env_name ("USERNAME=", sizeof ("USERNAME=") - 1);
+  }
+  const char *domain ()
+  {
+    return env_domain ("USERDOMAIN=", sizeof ("USERDOMAIN=") - 1);
+  }
   BOOL set_sid (PSID new_sid);
   BOOL set_orig_sid ();
   PSID sid () const { return psid; }
@@ -150,6 +163,8 @@ public:
   {
     return impersonated && token != INVALID_HANDLE_VALUE;
   }
+  const char *cygheap_user::test_uid (char *&, const char *, size_t)
+    __attribute__ ((regparm (3)));
 };
 
 /* cwd cache stuff.  */
index 052398a..ae7268f 100644 (file)
@@ -750,11 +750,43 @@ env_sort (const void *a, const void *b)
   return strcmp (*p, *q);
 }
 
+char * __stdcall
+getwinenveq (const char *name, size_t namelen, int x)
+{
+  char dum[1];
+  char name0[namelen - 1];
+  memcpy (name0, name, namelen - 1);
+  name0[namelen - 1] = '\0';
+  int totlen = GetEnvironmentVariable (name0, dum, 0);
+  if (totlen > 0)
+    {
+      totlen++;
+      if (x == HEAP_1_STR)
+       totlen += namelen;
+      else
+       namelen = 0;
+      char *p = (char *) cmalloc ((cygheap_types) x, totlen);
+      if (namelen)
+       strcpy (p, name);
+      if (GetEnvironmentVariable (name0, p + namelen, totlen))
+       {
+         debug_printf ("using value from GetEnvironmentVariable for '%s'",
+                       name0);
+         return p;
+       }
+      else
+       cfree (p);
+    }
+
+  debug_printf ("warning: %s not present in environment", name);
+  return NULL;
+}
+
 struct spenv
 {
   const char *name;
   size_t namelen;
-  const char * (cygheap_user::*from_cygheap) ();
+  const char * (cygheap_user::*from_cygheap) (const char *, size_t);
   char *retrieve (bool, const char * const = NULL)
     __attribute__ ((regparm (3)));
 };
@@ -785,28 +817,15 @@ spenv::retrieve (bool no_envblock, const char *const envname)
   if (from_cygheap)
     {
       const char *p;
-      if (cygheap->user.issetuid ())
-       debug_printf ("calculating for setuid");
-      else
+      if (envname)
        {
-         debug_printf ("calculating for non-setuid");
-         if (!envname)
-           {
-             debug_printf ("not adding %s to windows environment", name);
-             return NULL;              /* No need to force these into the
-                                          environment */
-           }
-
-         if (no_envblock)
-           {
-             debug_printf ("duping existing value for '%s'", name);
-             return cstrdup1 (envname);/* Don't really care what it's set to
+         debug_printf ("duping existing value for '%s'", name);
+         return cstrdup1 (envname);    /* Don't really care what it's set to
                                           if we're calling a cygwin program */
-           }
        }
 
       /* Calculate (potentially) value for given environment variable.  */
-      p = (cygheap->user.*from_cygheap) ();
+      p = (cygheap->user.*from_cygheap) (name, namelen);
       if (!p || (no_envblock && !envname))
        return env_dontadd;
       char *s = (char *) cmalloc (HEAP_1_STR, namelen + strlen (p) + 1);
@@ -819,24 +838,7 @@ spenv::retrieve (bool no_envblock, const char *const envname)
   if (envname)
     return cstrdup1 (envname);
 
-  char dum[1];
-  int vallen = GetEnvironmentVariable (name, dum, 0);
-  if (vallen > 0)
-    {
-      char *p = (char *) cmalloc (HEAP_1_STR, namelen + ++vallen);
-      strcpy (p, name);
-      if (GetEnvironmentVariable (name, p + namelen, vallen))
-       {
-         debug_printf ("using value from GetEnvironmentVariable for '%s'",
-                       envname);
-         return p;
-       }
-      else
-       cfree (p);
-    }
-
-  debug_printf ("warning: %s not present in environment", name);
-  return NULL;
+  return getwinenveq (name, namelen, HEAP_1_STR);
 }
 
 #define SPENVS_SIZE (sizeof (spenvs) / sizeof (spenvs[0]))
index ebccc53..1a616b2 100644 (file)
@@ -35,6 +35,8 @@ struct win_env
 
 win_env * __stdcall getwinenv (const char *name, const char *posix = NULL)
   __attribute__ ((regparm (3)));
+char * __stdcall getwinenveq (const char *name, size_t len, int)
+  __attribute__ ((regparm (3)));
 
 void __stdcall update_envptrs ();
 extern char **__cygwin_environ, ***main_environ;
index effcd59..5326ce4 100644 (file)
@@ -28,6 +28,7 @@ details. */
 #include "cygheap.h"
 #include "registry.h"
 #include "child_info.h"
+#include "environ.h"
 
 void
 internal_getlogin (cygheap_user &user)
@@ -199,6 +200,7 @@ cygheap_user::ontherange (homebodies what, struct passwd *pw)
   char *newhomepath = NULL;
 
 
+  debug_printf ("what %d, pw %p", what, pw);
   if (what == CH_HOME)
     {
       char *p;
@@ -232,7 +234,7 @@ cygheap_user::ontherange (homebodies what, struct passwd *pw)
        }
     }
 
-  if (homepath == NULL && newhomepath == NULL)
+  if (what != CH_HOME && homepath == NULL && newhomepath == NULL)
     {
       if (!pw)
        pw = getpwnam (name ());
@@ -241,12 +243,12 @@ cygheap_user::ontherange (homebodies what, struct passwd *pw)
       else
        {
          homepath_env_buf[0] = homepath_env_buf[1] = '\0';
-         if (env_logsrv ())
+         if (logsrv ())
            {
              WCHAR wlogsrv[INTERNET_MAX_HOST_NAME_LENGTH + 3];
-             sys_mbstowcs (wlogsrv, env_logsrv (),
+             sys_mbstowcs (wlogsrv, logsrv (),
                            sizeof (wlogsrv) / sizeof(*wlogsrv));
-            sys_mbstowcs (wuser, env_name (), sizeof (wuser) / sizeof (*wuser));
+            sys_mbstowcs (wuser, winname (), sizeof (wuser) / sizeof (*wuser));
              if (!(ret = NetUserGetInfo (wlogsrv, wuser, 3,(LPBYTE *)&ui)))
                {
                  char *p;
@@ -302,25 +304,35 @@ cygheap_user::ontherange (homebodies what, struct passwd *pw)
 }
 
 const char *
-cygheap_user::env_logsrv ()
+cygheap_user::test_uid (char *&what, const char *name, size_t namelen)
 {
-  if (plogsrv)
+  if (what)
+    return what;
+  if (orig_uid == myself->uid)
+    what = getwinenveq (name, namelen, HEAP_STR) ?: almost_null;
+  return what;
+}
+
+const char *
+cygheap_user::env_logsrv (const char *name, size_t namelen)
+{
+  if (test_uid (plogsrv, name, namelen))
     return plogsrv;
 
-  if (!env_domain () || strcasematch (env_name (), "SYSTEM"))
+  if (!domain () || strcasematch (winname (), "SYSTEM"))
     return NULL;
 
   char logsrv[INTERNET_MAX_HOST_NAME_LENGTH + 3];
   cfree_and_set (plogsrv, almost_null);
-  if (get_logon_server (env_domain (), logsrv, NULL))
+  if (get_logon_server (domain (), logsrv, NULL))
     plogsrv = cstrdup (logsrv);
   return plogsrv;
 }
 
 const char *
-cygheap_user::env_domain ()
+cygheap_user::env_domain (const char *name, size_t namelen)
 {
-  if (pdomain)
+  if (test_uid (pdomain, name, namelen))
     return pdomain;
 
   char username[UNLEN + 1];
@@ -329,26 +341,29 @@ cygheap_user::env_domain ()
   DWORD dlen = sizeof (userdomain);
   SID_NAME_USE use;
 
-  cfree_and_set (winname, almost_null);
+  cfree_and_set (pwinname, almost_null);
   cfree_and_set (pdomain, almost_null);
   if (!LookupAccountSid (NULL, sid (), username, &ulen,
                         userdomain, &dlen, &use))
     __seterrno ();
   else
     {
-      winname = cstrdup (username);
+      pwinname = cstrdup (username);
       pdomain = cstrdup (userdomain);
     }
   return pdomain;
 }
 
 const char *
-cygheap_user::env_userprofile ()
+cygheap_user::env_userprofile (const char *name, size_t namelen)
 {
+  if (test_uid (puserprof, name, namelen))
+    return puserprof;
+
   char userprofile_env_buf[MAX_PATH + 1];
   cfree_and_set (puserprof, almost_null);
   /* FIXME: Should this just be setting a puserprofile like everything else? */
-  if (!strcasematch (env_name (), "SYSTEM")
+  if (!strcasematch (winname (), "SYSTEM")
       && get_registry_hive_path (sid (), userprofile_env_buf))
     puserprof = cstrdup (userprofile_env_buf);
 
@@ -356,20 +371,21 @@ cygheap_user::env_userprofile ()
 }
 
 const char *
-cygheap_user::env_homepath ()
+cygheap_user::env_homepath (const char *name, size_t namelen)
 {
   return ontherange (CH_HOMEPATH);
 }
 
 const char *
-cygheap_user::env_homedrive ()
+cygheap_user::env_homedrive (const char *name, size_t namelen)
 {
   return ontherange (CH_HOMEDRIVE);
 }
 
 const char *
-cygheap_user::env_name ()
+cygheap_user::env_name (const char *name, size_t namelen)
 {
-  (void) env_domain ();
-  return winname;
+  if (!test_uid (pwinname, name, namelen))
+    (void) domain ();
+  return pwinname;
 }