* cygheap.cc (cygheap_user::set_logsrv): Remove.

(cygheap_user::set_domain): Ditto.
* cygheap.h (cygheap_user::set_logsrv): Remove declaration.
(cygheap_user::set_domain): Ditto.
(cygheap_user::env_domain): Declare new method.
(cygheap_user::env_name): Ditto.
* environ.cc (spenvs): Add two environment variables.
* spawn.cc (spawn_guts): Call build_env after RevertToSelf.  Always set
ciresrv.mount_h.
(cygheap_user::ontherange): Recalculate homedrive/homepath if they are empty.
Use env_logsrv to get logon server.
(cygheap_user::env_logsrv): Calculate server name here rather than relying on
it having been previously calculated.
(cygheap_user::env_domain): Ditto for domain name.
(cygheap-user::env_name): New method.
* syscalls.cc (seteuid32): Do not get or set the environment.  Do not call
LookupAccountSid nor internal_getlogin.  Set cygheap->user name and sid from
the passwd entry.
* uinfo.cc (uinfo_init): Only call internal_getlogin when starting from a non
Cygwin process and use the values returned in user.
(internal_getlogin): Simplify to case where starting from a non Cygwin process.
Store return values in user and return void.  Do not set the Windows default
environment.
* dcrt0.cc (dll_crt0_1): Call uinfo_init only when needed.  Do not set
myself->uid nor reset user.sid.
* spawn.cc (spawn_guts): Get the sid from cygheap->user.  Always
RevertToSelf().  Don't set uid in impersonated case.
* cygheap.cc (cygheap_user::set_sid): Do not set orig_sig.
(cygheap_user::set_orig_sid): New.
* cygheap.h: Declare cygheap_user::set_sid.
* winsup.h: Add argument to uinfo_init().
This commit is contained in:
Christopher Faylor 2002-06-14 18:01:21 +00:00
parent 470e8c460d
commit 9a771b2961
8 changed files with 163 additions and 264 deletions

View File

@ -1,3 +1,40 @@
2002-06-14 Christopher Faylor <cgf@redhat.com>
* cygheap.cc (cygheap_user::set_logsrv): Remove.
(cygheap_user::set_domain): Ditto.
* cygheap.h (cygheap_user::set_logsrv): Remove declaration.
(cygheap_user::set_domain): Ditto.
(cygheap_user::env_domain): Declare new method.
(cygheap_user::env_name): Ditto.
* environ.cc (spenvs): Add two environment variables.
* spawn.cc (spawn_guts): Call build_env after RevertToSelf. Always set
ciresrv.mount_h.
(cygheap_user::ontherange): Recalculate homedrive/homepath if they are
empty. Use env_logsrv to get logon server.
(cygheap_user::env_logsrv): Calculate server name here rather than
relying on it having been previously calculated.
(cygheap_user::env_domain): Ditto for domain name.
(cygheap-user::env_name): New method.
2002-06-12 Pierre Humblet <pierre.humblet@ieee.org>
* syscalls.cc (seteuid32): Do not get or set the environment. Do not
call LookupAccountSid nor internal_getlogin. Set cygheap->user name
and sid from the passwd entry.
* uinfo.cc (uinfo_init): Only call internal_getlogin when starting from
a non Cygwin process and use the values returned in user.
(internal_getlogin): Simplify to case where starting from a non Cygwin
process. Store return values in user and return void. Do not set the
Windows default environment.
* dcrt0.cc (dll_crt0_1): Call uinfo_init only when needed. Do not set
myself->uid nor reset user.sid.
* spawn.cc (spawn_guts): Get the sid from cygheap->user. Always
RevertToSelf(). Don't set uid in impersonated case.
* cygheap.cc (cygheap_user::set_sid): Do not set orig_sig.
(cygheap_user::set_orig_sid): New.
* cygheap.h: Declare cygheap_user::set_sid.
* winsup.h: Add argument to uinfo_init().
2002-06-14 Corinna Vinschen <corinna@vinschen.de> 2002-06-14 Corinna Vinschen <corinna@vinschen.de>
* environ.cc (build_env): If realloc moves envblock, move s with it. * environ.cc (build_env): If realloc moves envblock, move s with it.

View File

@ -445,54 +445,34 @@ cygheap_user::set_name (const char *new_name)
pname = cstrdup (new_name ? new_name : ""); pname = cstrdup (new_name ? new_name : "");
homedrive = NULL; homedrive = NULL;
homepath = NULL; homepath = NULL;
}
void
cygheap_user::set_logsrv (const char *new_logsrv)
{
if (plogsrv) if (plogsrv)
cfree (plogsrv - 2); cfree (plogsrv);
if (!new_logsrv || !*new_logsrv)
plogsrv = NULL;
else
{
plogsrv = (char *) cmalloc (HEAP_STR, strlen (new_logsrv) + 3) + 2;
strcpy (plogsrv, new_logsrv);
}
}
void
cygheap_user::set_domain (const char *new_domain)
{
if (pdomain) if (pdomain)
cfree (pdomain); cfree (pdomain);
pdomain = (new_domain && *new_domain) ? cstrdup (new_domain) : NULL; plogsrv = pdomain = NULL;
} }
BOOL BOOL
cygheap_user::set_sid (PSID new_sid) cygheap_user::set_sid (PSID new_sid)
{ {
if (!new_sid) if (new_sid)
{
if (psid)
cfree (psid);
if (orig_psid)
cfree (orig_psid);
psid = NULL;
orig_psid = NULL;
return TRUE;
}
else
{ {
if (!psid) if (!psid)
{ psid = cmalloc (HEAP_STR, MAX_SID_LEN);
if (!orig_psid) if (psid)
{ return CopySid (MAX_SID_LEN, psid, new_sid);
orig_psid = cmalloc (HEAP_STR, MAX_SID_LEN);
CopySid (MAX_SID_LEN, orig_psid, new_sid);
}
psid = cmalloc (HEAP_STR, MAX_SID_LEN);
}
return CopySid (MAX_SID_LEN, psid, new_sid);
} }
return FALSE;
}
BOOL
cygheap_user::set_orig_sid ()
{
if (psid)
{
if (!orig_psid) orig_psid = cmalloc (HEAP_STR, MAX_SID_LEN);
if (orig_psid)
return CopySid (MAX_SID_LEN, orig_psid, psid);
}
return FALSE;
} }

View File

@ -124,28 +124,17 @@ 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; }
void set_logsrv (const char *new_logsrv);
const char *logsrv () const { return plogsrv; }
const char *env_logsrv (); const char *env_logsrv ();
const char *env_homepath (); const char *env_homepath ();
const char *env_homedrive (); const char *env_homedrive ();
const char *env_userprofile (); const char *env_userprofile ();
const char *env_domain ();
void set_domain (const char *new_domain); const char *env_name ();
const char *domain () const { return pdomain; }
BOOL set_sid (PSID new_sid); BOOL set_sid (PSID new_sid);
BOOL set_orig_sid ();
PSID sid () const { return psid; } PSID sid () const { return psid; }
PSID orig_sid () const { return orig_psid; } PSID orig_sid () const { return orig_psid; }
void operator =(cygheap_user &user)
{
set_name (user.name ());
set_logsrv (user.logsrv ());
set_domain (user.domain ());
set_sid (user.sid ());
}
const char *ontherange (homebodies what, struct passwd * = NULL); const char *ontherange (homebodies what, struct passwd * = NULL);
}; };

View File

@ -608,7 +608,6 @@ dll_crt0_1 ()
DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE)) DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE))
h = NULL; h = NULL;
set_myself (mypid, h); set_myself (mypid, h);
myself->uid = spawn_info->moreinfo->uid;
__argc = spawn_info->moreinfo->argc; __argc = spawn_info->moreinfo->argc;
__argv = spawn_info->moreinfo->argv; __argv = spawn_info->moreinfo->argv;
envp = spawn_info->moreinfo->envp; envp = spawn_info->moreinfo->envp;
@ -623,8 +622,6 @@ dll_crt0_1 ()
} }
if (child_proc_info->subproc_ready) if (child_proc_info->subproc_ready)
ProtectHandle (child_proc_info->subproc_ready); ProtectHandle (child_proc_info->subproc_ready);
if (myself->uid == ILLEGAL_UID)
cygheap->user.set_sid (NULL);
break; break;
} }
} }
@ -679,8 +676,9 @@ dll_crt0_1 ()
/* Allocate cygheap->fdtab */ /* Allocate cygheap->fdtab */
dtable_init (); dtable_init ();
/* Initialize uid, gid. */ /* Initialize uid, gid if necessary. */
uinfo_init (); if (child_proc_info == NULL || spawn_info->moreinfo->uid == ILLEGAL_UID)
uinfo_init ();
/* Initialize signal/subprocess handling. */ /* Initialize signal/subprocess handling. */
sigproc_init (); sigproc_init ();

View File

@ -765,6 +765,8 @@ static NO_COPY spenv spenvs[] =
{"LOGONSERVER=", &cygheap_user::env_logsrv}, {"LOGONSERVER=", &cygheap_user::env_logsrv},
{"SYSTEMDRIVE=", NULL}, {"SYSTEMDRIVE=", NULL},
{"SYSTEMROOT=", NULL}, {"SYSTEMROOT=", NULL},
{"USERDOMAIN=", &cygheap_user::env_name},
{"USERNAME=", &cygheap_user::env_domain},
{"USERPROFILE=", &cygheap_user::env_userprofile}, {"USERPROFILE=", &cygheap_user::env_userprofile},
}; };

View File

@ -567,8 +567,6 @@ spawn_guts (const char * prog_arg, const char *const *argv,
ciresrv.moreinfo->argc = newargv.argc; ciresrv.moreinfo->argc = newargv.argc;
ciresrv.moreinfo->argv = newargv; ciresrv.moreinfo->argv = newargv;
ciresrv.hexec_proc = hexec_proc; ciresrv.hexec_proc = hexec_proc;
ciresrv.moreinfo->envp = build_env (envp, envblock, ciresrv.moreinfo->envc,
real_path.iscygexec ());
if (mode != _P_OVERLAY || if (mode != _P_OVERLAY ||
!DuplicateHandle (hMainProc, myself.shared_handle (), hMainProc, !DuplicateHandle (hMainProc, myself.shared_handle (), hMainProc,
@ -610,14 +608,14 @@ spawn_guts (const char * prog_arg, const char *const *argv,
char sa_buf[1024]; char sa_buf[1024];
cygbench ("spawn-guts"); cygbench ("spawn-guts");
ciresrv.mount_h = cygwin_mount_h;
if (!cygheap->user.impersonated || cygheap->user.token == INVALID_HANDLE_VALUE) if (!cygheap->user.impersonated || cygheap->user.token == INVALID_HANDLE_VALUE)
{ {
PSECURITY_ATTRIBUTES sec_attribs = sec_user_nih (sa_buf); PSECURITY_ATTRIBUTES sec_attribs = sec_user_nih (sa_buf);
ciresrv.moreinfo->uid = getuid32 ();
/* FIXME: This leaks a handle in the CreateProcessAsUser case since the
child process doesn't know about cygwin_mount_h. */
ciresrv.mount_h = cygwin_mount_h;
newheap = cygheap_setup_for_child (&ciresrv, cygheap->fdtab.need_fixup_before ()); newheap = cygheap_setup_for_child (&ciresrv, cygheap->fdtab.need_fixup_before ());
ciresrv.moreinfo->envp = build_env (envp, envblock, ciresrv.moreinfo->envc,
real_path.iscygexec ());
rc = CreateProcess (runpath, /* image name - with full path */ rc = CreateProcess (runpath, /* image name - with full path */
one_line.buf, /* what was passed to exec */ one_line.buf, /* what was passed to exec */
sec_attribs, /* process security attrs */ sec_attribs, /* process security attrs */
@ -631,16 +629,9 @@ spawn_guts (const char * prog_arg, const char *const *argv,
} }
else else
{ {
cygsid sid; PSID sid = cygheap->user.sid ();
DWORD ret_len;
if (!GetTokenInformation (cygheap->user.token, TokenUser, &sid, /* Set security attributes with sid */
sizeof sid, &ret_len))
{
sid = NO_SID;
system_printf ("GetTokenInformation: %E");
}
/* Retrieve security attributes before setting psid to NULL
since it's value is needed by `sec_user'. */
PSECURITY_ATTRIBUTES sec_attribs = sec_user_nih (sa_buf, sid); PSECURITY_ATTRIBUTES sec_attribs = sec_user_nih (sa_buf, sid);
RevertToSelf (); RevertToSelf ();
@ -655,7 +646,6 @@ spawn_guts (const char * prog_arg, const char *const *argv,
char wstname[1024]; char wstname[1024];
char dskname[1024]; char dskname[1024];
ciresrv.moreinfo->uid = ILLEGAL_UID;
hwst = GetProcessWindowStation (); hwst = GetProcessWindowStation ();
SetUserObjectSecurity (hwst, &dsi, get_null_sd ()); SetUserObjectSecurity (hwst, &dsi, get_null_sd ());
GetUserObjectInformation (hwst, UOI_NAME, wstname, 1024, &n); GetUserObjectInformation (hwst, UOI_NAME, wstname, 1024, &n);
@ -667,6 +657,8 @@ spawn_guts (const char * prog_arg, const char *const *argv,
si.lpDesktop = wstname; si.lpDesktop = wstname;
newheap = cygheap_setup_for_child (&ciresrv, cygheap->fdtab.need_fixup_before ()); newheap = cygheap_setup_for_child (&ciresrv, cygheap->fdtab.need_fixup_before ());
ciresrv.moreinfo->envp = build_env (envp, envblock, ciresrv.moreinfo->envc,
real_path.iscygexec ());
rc = CreateProcessAsUser (cygheap->user.token, rc = CreateProcessAsUser (cygheap->user.token,
runpath, /* image name - with full path */ runpath, /* image name - with full path */
one_line.buf, /* what was passed to exec */ one_line.buf, /* what was passed to exec */

View File

@ -1943,8 +1943,6 @@ mkfifo (const char *_path, mode_t mode)
return -1; return -1;
} }
extern struct passwd *internal_getlogin (cygheap_user &user);
/* seteuid: standards? */ /* seteuid: standards? */
extern "C" int extern "C" int
seteuid32 (__uid32_t uid) seteuid32 (__uid32_t uid)
@ -1958,17 +1956,11 @@ seteuid32 (__uid32_t uid)
} }
sigframe thisframe (mainthread); sigframe thisframe (mainthread);
DWORD ulen = UNLEN + 1;
DWORD dlen = INTERNET_MAX_HOST_NAME_LENGTH + 1;
char orig_username[UNLEN + 1];
char orig_domain[INTERNET_MAX_HOST_NAME_LENGTH + 1];
char username[UNLEN + 1];
char domain[INTERNET_MAX_HOST_NAME_LENGTH + 1];
cygsid usersid, pgrpsid; cygsid usersid, pgrpsid;
HANDLE ptok, sav_token; HANDLE ptok, sav_token;
BOOL sav_impersonated, sav_token_is_internal_token; BOOL sav_impersonated, sav_token_is_internal_token;
BOOL process_ok, explicitly_created_token = FALSE; BOOL process_ok, explicitly_created_token = FALSE;
struct passwd * pw_new, * pw_cur; struct passwd * pw_new;
cygheap_user user; cygheap_user user;
PSID origpsid, psid2 = NO_SID; PSID origpsid, psid2 = NO_SID;
@ -1984,12 +1976,6 @@ seteuid32 (__uid32_t uid)
/* Save current information */ /* Save current information */
sav_token = cygheap->user.token; sav_token = cygheap->user.token;
sav_impersonated = cygheap->user.impersonated; sav_impersonated = cygheap->user.impersonated;
char *env;
orig_username[0] = orig_domain[0] = '\0';
if ((env = getenv ("USERNAME")))
strlcpy (orig_username, env, sizeof(orig_username));
if ((env = getenv ("USERDOMAIN")))
strlcpy (orig_domain, env, sizeof(orig_domain));
RevertToSelf(); RevertToSelf();
if (!OpenProcessToken (GetCurrentProcess (), if (!OpenProcessToken (GetCurrentProcess (),
@ -2065,16 +2051,6 @@ seteuid32 (__uid32_t uid)
} }
} }
/* Lookup username and domain before impersonating,
LookupAccountSid() returns a different answer afterwards. */
SID_NAME_USE use;
if (!LookupAccountSid (NULL, usersid, username, &ulen,
domain, &dlen, &use))
{
debug_printf ("LookupAccountSid (): %E");
__seterrno ();
goto failed;
}
/* If using the token, set info and impersonate */ /* If using the token, set info and impersonate */
if (!process_ok) if (!process_ok)
{ {
@ -2104,38 +2080,17 @@ seteuid32 (__uid32_t uid)
cygheap->user.impersonated = TRUE; cygheap->user.impersonated = TRUE;
} }
/* user.token is used in internal_getlogin () to determine if /* If sav_token was internally created and is replaced, destroy it. */
impersonation is active. If so, the token is used for if (sav_token != INVALID_HANDLE_VALUE &&
retrieving user's SID. */ sav_token != cygheap->user.token &&
user.token = cygheap->user.impersonated ? cygheap->user.token sav_token_is_internal_token)
: INVALID_HANDLE_VALUE; CloseHandle (sav_token);
/* Unsetting these two env vars is necessary to get NetUserGetInfo() cygheap->user.set_name (pw_new->pw_name);
called in internal_getlogin (). Otherwise the wrong path is used cygheap->user.set_sid (usersid);
after a user switch, probably. */ myself->uid = uid;
unsetenv ("HOMEDRIVE"); return 0;
unsetenv ("HOMEPATH");
setenv ("USERDOMAIN", domain, 1);
setenv ("USERNAME", username, 1);
pw_cur = internal_getlogin (user);
if (pw_cur == pw_new)
{
/* If sav_token was internally created and is replaced, destroy it. */
if (sav_token != INVALID_HANDLE_VALUE &&
sav_token != cygheap->user.token &&
sav_token_is_internal_token)
CloseHandle (sav_token);
myself->uid = uid;
cygheap->user = user;
return 0;
}
debug_printf ("Diffs!!! token: %d, cur: %d, new: %d, orig: %d",
cygheap->user.token, pw_cur->pw_uid,
pw_new->pw_uid, cygheap->user.orig_uid);
set_errno (EPERM);
failed: failed:
setenv ("USERNAME", orig_username, 1);
setenv ("USERDOMAIN", orig_domain, 1);
cygheap->user.token = sav_token; cygheap->user.token = sav_token;
cygheap->user.impersonated = sav_impersonated; cygheap->user.impersonated = sav_impersonated;
if ( cygheap->user.token != INVALID_HANDLE_VALUE && if ( cygheap->user.token != INVALID_HANDLE_VALUE &&

View File

@ -27,100 +27,37 @@ details. */
#include "cygerrno.h" #include "cygerrno.h"
#include "cygheap.h" #include "cygheap.h"
#include "registry.h" #include "registry.h"
#include "child_info.h"
struct passwd * void
internal_getlogin (cygheap_user &user) internal_getlogin (cygheap_user &user)
{ {
char buf[512];
char username[UNLEN + 1];
DWORD username_len = UNLEN + 1;
struct passwd *pw = NULL; struct passwd *pw = NULL;
if (!GetUserName (username, &username_len))
user.set_name (NULL);
else
user.set_name (username);
debug_printf ("GetUserName() = %s", user.name ());
if (wincap.has_security ()) if (wincap.has_security ())
{ {
LPWKSTA_USER_INFO_1 wui; HANDLE ptok = INVALID_HANDLE_VALUE;
NET_API_STATUS ret;
char *env;
user.set_logsrv (NULL);
/* First trying to get logon info from environment */
if (!*user.name () && (env = getenv ("USERNAME")) != NULL)
user.set_name (env);
if ((env = getenv ("USERDOMAIN")) != NULL)
user.set_domain (env);
if ((env = getenv ("LOGONSERVER")) != NULL)
user.set_logsrv (env + 2); /* filter leading double backslashes */
if (user.name () && user.domain ())
debug_printf ("User: %s, Domain: %s, Logon Server: %s",
user.name (), user.domain (), user.logsrv ());
else if (!(ret = NetWkstaUserGetInfo (NULL, 1, (LPBYTE *) &wui)))
{
sys_wcstombs (buf, wui->wkui1_username, UNLEN + 1);
user.set_name (buf);
sys_wcstombs (buf, wui->wkui1_logon_server,
INTERNET_MAX_HOST_NAME_LENGTH + 1);
user.set_logsrv (buf);
sys_wcstombs (buf, wui->wkui1_logon_domain,
INTERNET_MAX_HOST_NAME_LENGTH + 1);
user.set_domain (buf);
NetApiBufferFree (wui);
}
if (!user.logsrv () && user.domain () &&
get_logon_server (user.domain (), buf, NULL))
user.set_logsrv (buf + 2);
debug_printf ("Domain: %s, Logon Server: %s, Windows Username: %s",
user.domain (), user.logsrv (), user.name ());
HANDLE ptok = user.token; /* Which is INVALID_HANDLE_VALUE if no
impersonation took place. */
DWORD siz; DWORD siz;
cygsid tu; cygsid tu;
ret = 0; DWORD ret = 0;
/* Try to get the SID either from already impersonated token /* Try to get the SID either from current process and
or from current process first. To differ that two cases is store it in user.psid */
important, because you can't rely on the user information if (!OpenProcessToken (GetCurrentProcess (),
in a process token of a currently impersonated process. */ TOKEN_ADJUST_DEFAULT | TOKEN_QUERY,
if (ptok == INVALID_HANDLE_VALUE &ptok))
&& !OpenProcessToken (GetCurrentProcess (), system_printf ("OpenProcessToken(): %E\n");
TOKEN_ADJUST_DEFAULT | TOKEN_QUERY,
&ptok))
debug_printf ("OpenProcessToken(): %E\n");
else if (!GetTokenInformation (ptok, TokenUser, &tu, sizeof tu, &siz)) else if (!GetTokenInformation (ptok, TokenUser, &tu, sizeof tu, &siz))
debug_printf ("GetTokenInformation(): %E"); system_printf ("GetTokenInformation(): %E");
else if (!(ret = user.set_sid (tu))) else if (!(ret = user.set_sid (tu)))
debug_printf ("Couldn't retrieve SID from access token!"); system_printf ("Couldn't retrieve SID from access token!");
/* If that failes, try to get the SID from localhost. This can only /* We must set the user name, uid and gid.
be done if a domain is given because there's a chance that a local If we have a SID, try to get the corresponding Cygwin
and a domain user may have the same name. */ password entry. Set user name which can be different
if (!ret && user.domain ()) from the Windows user name */
{ if (ret)
char domain[DNLEN + 1]; {
DWORD dlen = sizeof (domain); cygsid gsid (NO_SID);
siz = sizeof (tu);
SID_NAME_USE use = SidTypeInvalid;
/* Concat DOMAIN\USERNAME for the next lookup */
strcat (strcat (strcpy (buf, user.domain ()), "\\"), user.name ());
if (!LookupAccountName (NULL, buf, tu, &siz,
domain, &dlen, &use) ||
!legal_sid_type (use))
debug_printf ("Couldn't retrieve SID locally!");
else user.set_sid (tu);
}
/* If we have a SID, try to get the corresponding Cygwin user name
which can be different from the Windows user name. */
cygsid gsid (NO_SID);
if (ret)
{
cygsid psid; cygsid psid;
for (int pidx = 0; (pw = internal_getpwent (pidx)); ++pidx) for (int pidx = 0; (pw = internal_getpwent (pidx)); ++pidx)
@ -133,72 +70,51 @@ internal_getlogin (cygheap_user &user)
gsid = NO_SID; gsid = NO_SID;
break; break;
} }
}
/* If this process is started from a non Cygwin process, /* Set token owner to the same value as token user and
set token owner to the same value as token user and primary group to the group in /etc/passwd. */
primary group to the group which is set as primary group
in /etc/passwd. */
if (ptok != INVALID_HANDLE_VALUE && !myself->ppid_handle)
{
if (!SetTokenInformation (ptok, TokenOwner, &tu, sizeof tu)) if (!SetTokenInformation (ptok, TokenOwner, &tu, sizeof tu))
debug_printf ("SetTokenInformation(TokenOwner): %E"); debug_printf ("SetTokenInformation(TokenOwner): %E");
if (gsid && !SetTokenInformation (ptok, TokenPrimaryGroup, if (gsid && !SetTokenInformation (ptok, TokenPrimaryGroup,
&gsid, sizeof gsid)) &gsid, sizeof gsid))
debug_printf ("SetTokenInformation(TokenPrimaryGroup): %E"); debug_printf ("SetTokenInformation(TokenPrimaryGroup): %E");
} }
/* Close token only if it's a result from OpenProcessToken(). */ if (ptok != INVALID_HANDLE_VALUE)
if (ptok != INVALID_HANDLE_VALUE
&& user.token == INVALID_HANDLE_VALUE)
CloseHandle (ptok); CloseHandle (ptok);
} }
debug_printf ("Cygwins Username: %s", user.name ());
if (!pw) if (!pw)
pw = getpwnam (user.name ()); pw = getpwnam (user.name ());
if (!myself->ppid_handle) if (pw)
(void) cygheap->user.ontherange (CH_HOME, pw); {
user.real_uid = pw->pw_uid;
user.real_gid = pw->pw_gid;
}
else
{
user.real_uid = DEFAULT_UID;
user.real_gid = DEFAULT_GID;
}
return pw; (void) cygheap->user.ontherange (CH_HOME, pw);
return;
} }
void void
uinfo_init () uinfo_init ()
{ {
struct passwd *p; if (!child_proc_info)
internal_getlogin (cygheap->user); /* Set the cygheap->user. */
/* Initialize to non impersonated values. /* Real and effective uid/gid are identical on process start up. */
Setting `impersonated' to TRUE seems to be wrong but it myself->uid = cygheap->user.orig_uid = cygheap->user.real_uid;
isn't. Impersonated is thought as "Current User and `token' myself->gid = cygheap->user.orig_gid = cygheap->user.real_gid;
are coincident". See seteuid() for the mechanism behind that. */ cygheap->user.set_orig_sid(); /* Update the original sid */
if (cygheap->user.token != INVALID_HANDLE_VALUE && cygheap->user.token != NULL)
CloseHandle (cygheap->user.token);
cygheap->user.token = INVALID_HANDLE_VALUE;
cygheap->user.impersonated = TRUE;
/* If uid is ILLEGAL_UID, the process is started from a non cygwin cygheap->user.token = INVALID_HANDLE_VALUE; /* No token present */
process or the user context was changed in spawn.cc */
if (myself->uid == ILLEGAL_UID)
if ((p = internal_getlogin (cygheap->user)) != NULL)
{
myself->uid = p->pw_uid;
/* Set primary group only if process has been started from a
non cygwin process. */
if (!myself->ppid_handle)
myself->gid = p->pw_gid;
}
else
{
myself->uid = DEFAULT_UID;
myself->gid = DEFAULT_GID;
}
/* Real and effective uid/gid are always identical on process start up.
This is at least true for NT/W2K. */
cygheap->user.orig_uid = cygheap->user.real_uid = myself->uid;
cygheap->user.orig_gid = cygheap->user.real_gid = myself->gid;
} }
extern "C" char * extern "C" char *
@ -317,7 +233,7 @@ cygheap_user::ontherange (homebodies what, struct passwd *pw)
} }
} }
if (homedrive == NULL) if (homedrive == NULL || !homedrive[0])
{ {
if (!pw) if (!pw)
pw = getpwnam (name ()); pw = getpwnam (name ());
@ -328,10 +244,10 @@ cygheap_user::ontherange (homebodies what, struct passwd *pw)
sys_mbstowcs (wuser, name (), sizeof (wuser) / sizeof (*wuser)); sys_mbstowcs (wuser, name (), sizeof (wuser) / sizeof (*wuser));
if ((ret = NetUserGetInfo (NULL, wuser, 3, (LPBYTE *)&ui))) if ((ret = NetUserGetInfo (NULL, wuser, 3, (LPBYTE *)&ui)))
{ {
if (logsrv ()) if (env_logsrv ())
{ {
WCHAR wlogsrv[INTERNET_MAX_HOST_NAME_LENGTH + 3]; WCHAR wlogsrv[INTERNET_MAX_HOST_NAME_LENGTH + 3];
strcat (strcpy (buf, "\\\\"), logsrv ()); strcpy (buf, env_logsrv ());
sys_mbstowcs (wlogsrv, buf, sizeof (wlogsrv) / sizeof(*wlogsrv)); sys_mbstowcs (wlogsrv, buf, sizeof (wlogsrv) / sizeof(*wlogsrv));
ret = NetUserGetInfo (wlogsrv, wuser, 3,(LPBYTE *)&ui); ret = NetUserGetInfo (wlogsrv, wuser, 3,(LPBYTE *)&ui);
} }
@ -383,17 +299,41 @@ cygheap_user::ontherange (homebodies what, struct passwd *pw)
const char * const char *
cygheap_user::env_logsrv () cygheap_user::env_logsrv ()
{ {
char *p = plogsrv - 2; if (plogsrv)
return plogsrv;
*p = p[1] = '\\'; char logsrv[INTERNET_MAX_HOST_NAME_LENGTH + 3];
return p; if (!get_logon_server (env_domain (), logsrv, NULL))
return NULL;
return plogsrv = cstrdup (logsrv);
}
const char *
cygheap_user::env_domain ()
{
if (pdomain)
return pdomain;
char username[UNLEN + 1];
DWORD ulen = sizeof (username);
char userdomain[DNLEN + 1];
DWORD dlen = sizeof (userdomain);
SID_NAME_USE use;
if (!LookupAccountSid (NULL, sid (), username, &ulen,
userdomain, &dlen, &use))
{
__seterrno ();
return NULL;
}
return pdomain = cstrdup (userdomain);
} }
const char * const char *
cygheap_user::env_userprofile () cygheap_user::env_userprofile ()
{ {
static char buf[512]; /* FIXME: This shouldn't be static. */ static char buf[512]; /* FIXME: This shouldn't be static. */
if (strcasematch (name (), "SYSTEM") || !domain () || !logsrv ()) if (strcasematch (name (), "SYSTEM") || !env_domain () || !env_logsrv ())
return NULL; return NULL;
if (get_registry_hive_path (sid (), buf)) if (get_registry_hive_path (sid (), buf))
@ -413,3 +353,9 @@ cygheap_user::env_homedrive ()
{ {
return ontherange (CH_HOMEDRIVE); return ontherange (CH_HOMEDRIVE);
} }
const char *
cygheap_user::env_name ()
{
return name ();
}