* 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.
This commit is contained in:
Christopher Faylor 2002-06-29 02:36:08 +00:00
parent 2d5eb17ee3
commit 094d519311
6 changed files with 124 additions and 63 deletions

View 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> 2002-06-27 Christopher Faylor <cgf@redhat.com>
* cygheap.cc (cfree_and_set): New function. * cygheap.cc (cfree_and_set): New function.

View File

@ -465,7 +465,7 @@ cygheap_user::set_name (const char *new_name)
cfree_and_set (homepath); cfree_and_set (homepath);
cfree_and_set (plogsrv); cfree_and_set (plogsrv);
cfree_and_set (pdomain); cfree_and_set (pdomain);
cfree_and_set (winname); cfree_and_set (pwinname);
} }
BOOL BOOL

View File

@ -93,6 +93,7 @@ enum homebodies
}; };
struct passwd; struct passwd;
class cygheap_user class cygheap_user
{ {
/* Extendend user information. /* Extendend user information.
@ -103,7 +104,7 @@ class cygheap_user
char *pdomain; /* Logon domain of the user */ char *pdomain; /* Logon domain of the user */
char *homedrive; /* User's home drive */ char *homedrive; /* User's home drive */
char *homepath; /* User's home path */ 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 */ char *puserprof; /* User profile */
PSID psid; /* buffer for user's SID */ PSID psid; /* buffer for user's SID */
PSID orig_psid; /* Remains intact even after impersonation */ PSID orig_psid; /* Remains intact even after impersonation */
@ -134,13 +135,25 @@ public:
void set_name (const char *new_name); void set_name (const char *new_name);
const char *name () const { return pname; } const char *name () const { return pname; }
const char *env_logsrv (); const char *env_logsrv (const char *, size_t);
const char *env_homepath (); const char *env_homepath (const char *, size_t);
const char *env_homedrive (); const char *env_homedrive (const char *, size_t);
const char *env_userprofile (); const char *env_userprofile (const char *, size_t);
const char *env_domain (); const char *env_domain (const char *, size_t);
const char *env_name (); 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_sid (PSID new_sid);
BOOL set_orig_sid (); BOOL set_orig_sid ();
PSID sid () const { return psid; } PSID sid () const { return psid; }
@ -150,6 +163,8 @@ public:
{ {
return impersonated && token != INVALID_HANDLE_VALUE; return impersonated && token != INVALID_HANDLE_VALUE;
} }
const char *cygheap_user::test_uid (char *&, const char *, size_t)
__attribute__ ((regparm (3)));
}; };
/* cwd cache stuff. */ /* cwd cache stuff. */

View File

@ -750,11 +750,43 @@ env_sort (const void *a, const void *b)
return strcmp (*p, *q); 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 struct spenv
{ {
const char *name; const char *name;
size_t namelen; 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) char *retrieve (bool, const char * const = NULL)
__attribute__ ((regparm (3))); __attribute__ ((regparm (3)));
}; };
@ -785,28 +817,15 @@ spenv::retrieve (bool no_envblock, const char *const envname)
if (from_cygheap) if (from_cygheap)
{ {
const char *p; const char *p;
if (cygheap->user.issetuid ()) if (envname)
debug_printf ("calculating for setuid");
else
{ {
debug_printf ("calculating for non-setuid"); debug_printf ("duping existing value for '%s'", name);
if (!envname) return cstrdup1 (envname); /* Don't really care what it's set to
{
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
if we're calling a cygwin program */ if we're calling a cygwin program */
}
} }
/* Calculate (potentially) value for given environment variable. */ /* Calculate (potentially) value for given environment variable. */
p = (cygheap->user.*from_cygheap) (); p = (cygheap->user.*from_cygheap) (name, namelen);
if (!p || (no_envblock && !envname)) if (!p || (no_envblock && !envname))
return env_dontadd; return env_dontadd;
char *s = (char *) cmalloc (HEAP_1_STR, namelen + strlen (p) + 1); 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) if (envname)
return cstrdup1 (envname); return cstrdup1 (envname);
char dum[1]; return getwinenveq (name, namelen, HEAP_1_STR);
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;
} }
#define SPENVS_SIZE (sizeof (spenvs) / sizeof (spenvs[0])) #define SPENVS_SIZE (sizeof (spenvs) / sizeof (spenvs[0]))

View File

@ -35,6 +35,8 @@ struct win_env
win_env * __stdcall getwinenv (const char *name, const char *posix = NULL) win_env * __stdcall getwinenv (const char *name, const char *posix = NULL)
__attribute__ ((regparm (3))); __attribute__ ((regparm (3)));
char * __stdcall getwinenveq (const char *name, size_t len, int)
__attribute__ ((regparm (3)));
void __stdcall update_envptrs (); void __stdcall update_envptrs ();
extern char **__cygwin_environ, ***main_environ; extern char **__cygwin_environ, ***main_environ;

View File

@ -28,6 +28,7 @@ details. */
#include "cygheap.h" #include "cygheap.h"
#include "registry.h" #include "registry.h"
#include "child_info.h" #include "child_info.h"
#include "environ.h"
void void
internal_getlogin (cygheap_user &user) internal_getlogin (cygheap_user &user)
@ -199,6 +200,7 @@ cygheap_user::ontherange (homebodies what, struct passwd *pw)
char *newhomepath = NULL; char *newhomepath = NULL;
debug_printf ("what %d, pw %p", what, pw);
if (what == CH_HOME) if (what == CH_HOME)
{ {
char *p; 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) if (!pw)
pw = getpwnam (name ()); pw = getpwnam (name ());
@ -241,12 +243,12 @@ cygheap_user::ontherange (homebodies what, struct passwd *pw)
else else
{ {
homepath_env_buf[0] = homepath_env_buf[1] = '\0'; homepath_env_buf[0] = homepath_env_buf[1] = '\0';
if (env_logsrv ()) if (logsrv ())
{ {
WCHAR wlogsrv[INTERNET_MAX_HOST_NAME_LENGTH + 3]; WCHAR wlogsrv[INTERNET_MAX_HOST_NAME_LENGTH + 3];
sys_mbstowcs (wlogsrv, env_logsrv (), sys_mbstowcs (wlogsrv, logsrv (),
sizeof (wlogsrv) / sizeof(*wlogsrv)); 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))) if (!(ret = NetUserGetInfo (wlogsrv, wuser, 3,(LPBYTE *)&ui)))
{ {
char *p; char *p;
@ -302,25 +304,35 @@ cygheap_user::ontherange (homebodies what, struct passwd *pw)
} }
const char * 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; return plogsrv;
if (!env_domain () || strcasematch (env_name (), "SYSTEM")) if (!domain () || strcasematch (winname (), "SYSTEM"))
return NULL; return NULL;
char logsrv[INTERNET_MAX_HOST_NAME_LENGTH + 3]; char logsrv[INTERNET_MAX_HOST_NAME_LENGTH + 3];
cfree_and_set (plogsrv, almost_null); cfree_and_set (plogsrv, almost_null);
if (get_logon_server (env_domain (), logsrv, NULL)) if (get_logon_server (domain (), logsrv, NULL))
plogsrv = cstrdup (logsrv); plogsrv = cstrdup (logsrv);
return plogsrv; return plogsrv;
} }
const char * 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; return pdomain;
char username[UNLEN + 1]; char username[UNLEN + 1];
@ -329,26 +341,29 @@ cygheap_user::env_domain ()
DWORD dlen = sizeof (userdomain); DWORD dlen = sizeof (userdomain);
SID_NAME_USE use; SID_NAME_USE use;
cfree_and_set (winname, almost_null); cfree_and_set (pwinname, almost_null);
cfree_and_set (pdomain, almost_null); cfree_and_set (pdomain, almost_null);
if (!LookupAccountSid (NULL, sid (), username, &ulen, if (!LookupAccountSid (NULL, sid (), username, &ulen,
userdomain, &dlen, &use)) userdomain, &dlen, &use))
__seterrno (); __seterrno ();
else else
{ {
winname = cstrdup (username); pwinname = cstrdup (username);
pdomain = cstrdup (userdomain); pdomain = cstrdup (userdomain);
} }
return pdomain; return pdomain;
} }
const char * 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]; char userprofile_env_buf[MAX_PATH + 1];
cfree_and_set (puserprof, almost_null); cfree_and_set (puserprof, almost_null);
/* FIXME: Should this just be setting a puserprofile like everything else? */ /* 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)) && get_registry_hive_path (sid (), userprofile_env_buf))
puserprof = cstrdup (userprofile_env_buf); puserprof = cstrdup (userprofile_env_buf);
@ -356,20 +371,21 @@ cygheap_user::env_userprofile ()
} }
const char * const char *
cygheap_user::env_homepath () cygheap_user::env_homepath (const char *name, size_t namelen)
{ {
return ontherange (CH_HOMEPATH); return ontherange (CH_HOMEPATH);
} }
const char * const char *
cygheap_user::env_homedrive () cygheap_user::env_homedrive (const char *name, size_t namelen)
{ {
return ontherange (CH_HOMEDRIVE); return ontherange (CH_HOMEDRIVE);
} }
const char * const char *
cygheap_user::env_name () cygheap_user::env_name (const char *name, size_t namelen)
{ {
(void) env_domain (); if (!test_uid (pwinname, name, namelen))
return winname; (void) domain ();
return pwinname;
} }