* 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:
parent
470e8c460d
commit
9a771b2961
|
@ -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.
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -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 ();
|
||||||
|
|
|
@ -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},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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 &&
|
||||||
|
|
|
@ -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 ();
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue