* cygheap.cc (cygheap_root::cygheap_root): New function.

(cygheap_root::~cygheap_root): Ditto.
        (cygheap_root::operator=): Ditto.
        (cygheap_user::~cygheap_user): Ditto.
        (cygheap_user::set_name): Ditto.
        (cygheap_user::set_logsrv): Ditto.
        (cygheap_user::set_domain): Ditto.
        (cygheap_user::set_sid): Ditto.
        * cygheap.h (cygheap_root): New class.
        (cygheap_user): Ditto.
        (init_cygheap): Change type of `root' member to cygheap_root.
        Add `user' member.
        * dir.cc (opendir): Use new `cygheap_root' class.
        * dcrt0.cc (dll_crt0_1): Use new `cygheap_user' class.
        * fork.cc (fork_parent): Ditto.
        * grp.cc (getgroups): Ditto.
        * passwd.cc (search_for): Ditto.
        * path.cc: Use new `cygheap_root' class throughout.
        * pinfo.h (_pinfo): Remove `use_psid'. Move `username', `psid',
        `logsrv', `domain', `orig_{uid,gid}' and `real_{uid,gid}' to
        cygheap_user class.
        * security.cc: Use new `cygheap_user' class throughout.
        * shared.cc (sec_user): Ditto.
        * sigproc.cc (proc_subproc): Remove copy statements for user
        related information moved to `cygheap_user' class.
        * spawn.cc (spawn_guts): Invalidate current chroot settings
        when creating Windows environment. Use new `cygheap_user' class.
        * syscalls.cc: Use new `cygheap_user' class throughout.
        * uinfo.cc: Ditto.
        * uinfo.cc (internal_getlogin): Change parameters to reflect the
        move of user information to cygheap.
This commit is contained in:
Corinna Vinschen 2000-11-15 00:13:09 +00:00
parent fe8c097112
commit 1f0f8e127c
16 changed files with 287 additions and 138 deletions

View File

@ -1,3 +1,37 @@
Wed Nov 15 0:51:00 2000 Corinna Vinschen <corinna@vinschen.de>
* cygheap.cc (cygheap_root::cygheap_root): New function.
(cygheap_root::~cygheap_root): Ditto.
(cygheap_root::operator=): Ditto.
(cygheap_user::~cygheap_user): Ditto.
(cygheap_user::set_name): Ditto.
(cygheap_user::set_logsrv): Ditto.
(cygheap_user::set_domain): Ditto.
(cygheap_user::set_sid): Ditto.
* cygheap.h (cygheap_root): New class.
(cygheap_user): Ditto.
(init_cygheap): Change type of `root' member to cygheap_root.
Add `user' member.
* dir.cc (opendir): Use new `cygheap_root' class.
* dcrt0.cc (dll_crt0_1): Use new `cygheap_user' class.
* fork.cc (fork_parent): Ditto.
* grp.cc (getgroups): Ditto.
* passwd.cc (search_for): Ditto.
* path.cc: Use new `cygheap_root' class throughout.
* pinfo.h (_pinfo): Remove `use_psid'. Move `username', `psid',
`logsrv', `domain', `orig_{uid,gid}' and `real_{uid,gid}' to
cygheap_user class.
* security.cc: Use new `cygheap_user' class throughout.
* shared.cc (sec_user): Ditto.
* sigproc.cc (proc_subproc): Remove copy statements for user
related information moved to `cygheap_user' class.
* spawn.cc (spawn_guts): Invalidate current chroot settings
when creating Windows environment. Use new `cygheap_user' class.
* syscalls.cc: Use new `cygheap_user' class throughout.
* uinfo.cc: Ditto.
* uinfo.cc (internal_getlogin): Change parameters to reflect the
move of user information to cygheap.
Tue Nov 14 17:05:00 2000 Eric Fifer <efifer@dircon.co.uk>
* dir.cc (rewinddir): Always set __d_position = 0, so next

View File

@ -279,3 +279,93 @@ cstrdup1 (const char *s)
MALLOC_CHECK;
return p;
}
cygheap_root::cygheap_root (cygheap_root &nroot)
{
rootlen = nroot.rootlen;
root = nroot.root ? cstrdup (nroot.root) : NULL;
}
cygheap_root::~cygheap_root ()
{
if (root)
cfree (root);
}
char *
cygheap_root::operator =(const char *new_root)
{
if (root)
{
cfree (root);
root = NULL;
}
rootlen = 0;
if (new_root && *new_root)
{
root = cstrdup (new_root);
rootlen = strlen (root);
if (rootlen > 1 && root[rootlen - 1] == '/')
root[--rootlen] = '\0';
if (!rootlen)
{
cfree (root);
root = NULL;
}
}
return root;
}
cygheap_user::~cygheap_user ()
{
if (pname)
cfree (pname);
if (plogsrv)
cfree (plogsrv);
if (pdomain)
cfree (pdomain);
if (psid)
cfree (psid);
}
void
cygheap_user::set_name (const char *new_name)
{
if (pname)
cfree (pname);
pname = cstrdup (new_name ? new_name : "");
}
void
cygheap_user::set_logsrv (const char *new_logsrv)
{
if (plogsrv)
cfree (plogsrv);
plogsrv = (new_logsrv && *new_logsrv) ? cstrdup (new_logsrv) : NULL;
}
void
cygheap_user::set_domain (const char *new_domain)
{
if (pdomain)
cfree (pdomain);
pdomain = (new_domain && *new_domain) ? cstrdup (new_domain) : NULL;
}
BOOL
cygheap_user::set_sid (PSID new_sid)
{
if (!new_sid)
{
if (psid)
cfree (psid);
psid = NULL;
return TRUE;
}
else
{
if (!psid)
psid = cmalloc (HEAP_STR, MAX_SID_LEN);
return CopySid (MAX_SID_LEN, psid, new_sid);
}
}

View File

@ -39,15 +39,64 @@ struct _cmalloc_entry
char data[0];
};
class cygheap_root
{
/* Root directory information.
This is used after a chroot is called. */
size_t rootlen;
char *root;
public:
cygheap_root (cygheap_root &nroot);
~cygheap_root ();
char *operator =(const char *new_root);
size_t length () const { return rootlen; }
const char *path () const { return root; }
};
class cygheap_user {
/* Extendend user information.
The information is derived from the internal_getlogin call
when on a NT system. */
char *pname; /* user's name */
char *plogsrv; /* Logon server, may be FQDN */
char *pdomain; /* Logon domain of the user */
PSID psid; /* buffer for user's SID */
public:
uid_t orig_uid; /* Remains intact even after impersonation */
uid_t orig_gid; /* Ditto */
uid_t real_uid; /* Remains intact on seteuid, replaced by setuid */
gid_t real_gid; /* Ditto */
cygheap_user () : pname (NULL), plogsrv (NULL), pdomain (NULL), psid (NULL) {}
~cygheap_user ();
void set_name (const char *new_name);
const char *name () const { return pname; }
void set_logsrv (const char *new_logsrv);
const char *logsrv () const { return plogsrv; }
void set_domain (const char *new_domain);
const char *domain () const { return pdomain; }
BOOL set_sid (PSID new_sid);
PSID sid () const { return psid; }
void operator =(cygheap_user &user)
{
set_name (user.name ());
set_logsrv (user.logsrv ());
set_domain (user.domain ());
set_sid (user.sid ());
}
};
struct init_cygheap
{
_cmalloc_entry *chain;
struct
{
size_t rootlen;
char *root;
};
cygheap_root root;
cygheap_user user;
mode_t umask;
};

View File

@ -711,7 +711,7 @@ dll_crt0_1 ()
ProtectHandle (child_proc_info->subproc_ready);
myself->uid = spawn_info->moreinfo->uid;
if (myself->uid == USHRT_MAX)
myself->use_psid = 0;
cygheap->user.set_sid (NULL);
break;
}
}

View File

@ -76,7 +76,7 @@ opendir (const char *dirname)
goto failed;
}
if (stat (cygheap->rootlen ? dirname : real_dirname.get_win32 (),
if (stat (cygheap->root.length () ? dirname : real_dirname.get_win32 (),
&statbuf) == -1)
goto failed;

View File

@ -402,7 +402,7 @@ fork_parent (void *stack_here, HANDLE& hParent, dll *&first_dll, bool& load_dlls
uid_t uid;
uid = geteuid();
if (myself->impersonated && myself->token != INVALID_HANDLE_VALUE)
seteuid (myself->orig_uid);
seteuid (cygheap->user.orig_uid);
ch.parent = hParent;
ch.cygheap = cygheap;
@ -474,7 +474,6 @@ fork_parent (void *stack_here, HANDLE& hParent, dll *&first_dll, bool& load_dlls
forked->hProcess = pi.hProcess;
forked->dwProcessId = pi.dwProcessId;
forked->copysigs(myself);
memcpy (forked->username, myself->username, MAX_USER_NAME);
set_child_mmap_ptr (forked);
forked.remember ();

View File

@ -19,6 +19,7 @@ details. */
#include "sync.h"
#include "sigproc.h"
#include "pinfo.h"
#include "cygheap.h"
#include "cygerrno.h"
/* Read /etc/group only once for better performance. This is done
@ -273,14 +274,7 @@ extern "C"
int
getgroups (int gidsetsize, gid_t *grouplist)
{
#if 0
if (gidsetsize <= 0)
return 0;
grouplist[0] = myself->gid;
return 1;
#else
return getgroups (gidsetsize, grouplist, myself->gid, myself->username);
#endif
return getgroups (gidsetsize, grouplist, myself->gid, cygheap->user.name ());
}
extern "C"

View File

@ -19,6 +19,7 @@ details. */
#include "sync.h"
#include "sigproc.h"
#include "pinfo.h"
#include "cygheap.h"
#include <sys/termios.h>
/* Read /etc/passwd only once for better performance. This is done
@ -179,7 +180,7 @@ search_for (uid_t uid, const char *name)
request for the current user. */
if (passwd_state != loaded
|| (!name && uid == myself->uid)
|| (name && strcasematch(name, myself->username)))
|| (name && strcasematch(name, cygheap->user.name ())))
return default_pw;
return NULL;

View File

@ -109,10 +109,11 @@ cwdstuff cygcwd; /* The current working directory. */
(isdirsep(path[cygwin_shared->mount.cygdrive_len + 1]) || \
!path[cygwin_shared->mount.cygdrive_len + 1]))
#define ischrootpath(path) \
(cygheap->rootlen && \
strncasematch (cygheap->root, path, cygheap->rootlen) && \
(path[cygheap->rootlen] == '/' || path[cygheap->rootlen] == '\0'))
#define ischrootpath(p) \
(cygheap->root.length () && \
strncasematch (cygheap->root.path (), p, cygheap->root.length ()) && \
(p[cygheap->root.length ()] == '/' \
|| p[cygheap->root.length ()] == '\0'))
/* Return non-zero if PATH1 is a prefix of PATH2.
Both are assumed to be of the same path style and / vs \ usage.
@ -615,7 +616,7 @@ normalize_posix_path (const char *src, char *dst)
/* Two leading /'s? If so, preserve them. */
else if (isslash (src[1]))
{
if (cygheap->rootlen)
if (cygheap->root.length ())
{
debug_printf ("ENOENT = normalize_posix_path (%s)", src);
return ENOENT;
@ -631,10 +632,10 @@ normalize_posix_path (const char *src, char *dst)
}
}
/* Exactly one leading slash. Absolute path. Check for chroot. */
else if (cygheap->rootlen)
else if (cygheap->root.length ())
{
strcpy (dst, cygheap->root);
dst += cygheap->rootlen;
strcpy (dst, cygheap->root.path ());
dst += cygheap->root.length ();
}
while (*src)
@ -669,7 +670,7 @@ normalize_posix_path (const char *src, char *dst)
else
{
if (!ischrootpath (dst_start) ||
dst - dst_start != (int) cygheap->rootlen)
dst - dst_start != (int) cygheap->root.length ())
while (dst > dst_start && !isslash (*--dst))
continue;
src++;
@ -718,7 +719,7 @@ normalize_win32_path (const char *src, char *dst)
/* Two leading \'s? If so, preserve them. */
else if (SLASH_P (src[0]) && SLASH_P (src[1]))
{
if (cygheap->rootlen)
if (cygheap->root.length ())
{
debug_printf ("ENOENT = normalize_win32_path (%s)", src);
return ENOENT;
@ -727,13 +728,13 @@ normalize_win32_path (const char *src, char *dst)
++src;
}
/* If absolute path, care for chroot. */
else if (SLASH_P (src[0]) && !SLASH_P (src[1]) && cygheap->rootlen)
else if (SLASH_P (src[0]) && !SLASH_P (src[1]) && cygheap->root.length ())
{
strcpy (dst, cygheap->root);
strcpy (dst, cygheap->root.path ());
char *c;
while ((c = strchr (dst, '/')) != NULL)
*c = '\\';
dst += cygheap->rootlen;
dst += cygheap->root.length ();
dst_root_start = dst;
*dst++ = '\\';
}
@ -997,7 +998,7 @@ mount_info::conv_to_win32_path (const char *src_path, char *win32_path,
}
isrelpath = !isabspath (src_path);
*flags = set_flags_from_win32_path (dst);
if (cygheap->rootlen && dst[0] && dst[1] == ':')
if (cygheap->root.length () && dst[0] && dst[1] == ':')
{
char posix_path[MAX_PATH + 1];
@ -2939,9 +2940,10 @@ cwdstuff::get (char *buf, int need_posix, int with_chroot, unsigned ulen)
tocopy = win32;
else
tocopy = with_chroot && ischrootpath(posix) ?
posix + cygheap->rootlen : posix;
posix + cygheap->root.length () : posix;
debug_printf("cygheap->root: %s, posix: %s", cygheap->root, posix);
debug_printf("cygheap->root: %s, posix: %s",
(const char *) cygheap->root.path (), posix);
if (strlen (tocopy) >= ulen)
{
set_errno (ERANGE);

View File

@ -73,24 +73,11 @@ public:
pid_t sid; /* Session ID */
int ctty; /* Control tty */
bool has_pgid_children;/* True if we've forked or spawned children with our GID. */
char username[MAX_USER_NAME]; /* user's name */
/* Extendend user information.
The information is derived from the internal_getlogin call
when on a NT system. */
int use_psid; /* TRUE if psid contains valid data */
char psid[MAX_SID_LEN]; /* buffer for user's SID */
char logsrv[MAX_HOST_NAME]; /* Logon server, may be FQDN */
char domain[MAX_COMPUTERNAME_LENGTH+1]; /* Logon domain of the user */
/* token is needed if sexec should be called. It can be set by a call
to `set_impersonation_token()'. */
HANDLE token;
BOOL impersonated;
uid_t orig_uid; /* Remains intact also after impersonation */
uid_t orig_gid; /* Ditto */
uid_t real_uid; /* Remains intact on seteuid, replaced by setuid */
gid_t real_gid; /* Ditto */
/* Resources used by process. */
long start_time;

View File

@ -29,6 +29,7 @@ details. */
#include "sync.h"
#include "sigproc.h"
#include "pinfo.h"
#include "cygheap.h"
#include "security.h"
extern BOOL allow_ntea;
@ -326,7 +327,7 @@ is_grp_member (uid_t uid, gid_t gid)
gid_t grps[NGROUPS_MAX];
int cnt = getgroups (NGROUPS_MAX, grps,
pw ? pw->pw_gid : myself->gid,
pw ? pw->pw_name : myself->username);
pw ? pw->pw_name : cygheap->user.name ());
int i;
for (i = 0; i < cnt; ++i)
if (grps[i] == gid)
@ -352,9 +353,9 @@ lookup_name (const char *name, const char *logsrv, PSID ret_sid)
if (! name)
return FALSE;
if (*myself->domain)
if (cygheap->user.domain ())
{
strcat (strcat (strcpy (domuser, myself->domain), "\\"), name);
strcat (strcat (strcpy (domuser, cygheap->user.domain ()), "\\"), name);
if (LookupAccountName (NULL, domuser,
sid, (sidlen = MAX_SID_LEN, &sidlen),
dom, (domlen = MAX_COMPUTERNAME_LENGTH, &domlen),
@ -1138,7 +1139,7 @@ set_file_attribute (int use_ntsec, const char *file, int attribute)
{
return set_file_attribute (use_ntsec, file,
myself->uid, myself->gid,
attribute, myself->logsrv);
attribute, cygheap->user.logsrv ());
}
static int

View File

@ -17,6 +17,7 @@ details. */
#include "sync.h"
#include "sigproc.h"
#include "pinfo.h"
#include "cygheap.h"
#include "shared_info.h"
#include "registry.h"
#include "cygwin_version.h"
@ -219,9 +220,9 @@ sec_user (PVOID sa_buf, PSID sid2, BOOL inherit)
char sid_buf[MAX_SID_LEN];
PSID sid = (PSID) sid_buf;
if (myself->use_psid)
CopySid (MAX_SID_LEN, sid, myself->psid);
else if (! lookup_name (getlogin (), myself->logsrv, sid))
if (cygheap->user.sid ())
CopySid (MAX_SID_LEN, sid, (void *) cygheap->user.sid ());
else if (! lookup_name (getlogin (), cygheap->user.logsrv (), sid))
return inherit ? &sec_none_nih : &sec_none;
size_t acl_len = sizeof (ACL)

View File

@ -263,18 +263,7 @@ proc_subproc (DWORD what, DWORD val)
vchild->pgid = myself->pgid;
vchild->sid = myself->sid;
vchild->ctty = myself->ctty;
vchild->orig_uid = myself->orig_uid;
vchild->orig_gid = myself->orig_gid;
vchild->real_uid = myself->real_uid;
vchild->real_gid = myself->real_gid;
vchild->impersonated = myself->impersonated;
if (myself->use_psid)
{
vchild->use_psid = 1;
memcpy (vchild->psid, myself->psid, MAX_SID_LEN);
}
memcpy (vchild->logsrv, myself->logsrv, MAX_HOST_NAME);
memcpy (vchild->domain, myself->domain, MAX_COMPUTERNAME_LENGTH+1);
vchild->token = myself->token;
vchild->process_state |= PID_INITIALIZING | (myself->process_state & PID_USETTY);

View File

@ -554,7 +554,12 @@ skip_arg_parsing:
if (real_path.iscygexec ())
envblock = NULL;
else
envblock = winenv (envp, 0);
{
cygheap_root sav_root (cygheap->root);
cygheap->root = NULL;
envblock = winenv (envp, 0);
cygheap->root = sav_root;
}
ciresrv.cygheap = cygheap;
ciresrv.cygheap_max = cygheap_max;
@ -625,7 +630,7 @@ skip_arg_parsing:
/* Remove impersonation */
uid_t uid = geteuid();
if (myself->impersonated && myself->token != INVALID_HANDLE_VALUE)
seteuid (myself->orig_uid);
seteuid (cygheap->user.orig_uid);
/* Load users registry hive. */
load_registry_hive (sid);
@ -705,7 +710,6 @@ skip_arg_parsing:
syscall_printf ("-1 = spawnve (), process table full");
return -1;
}
child->username[0] = '\0';
child->progname[0] = '\0';
child->dwProcessId = pi.dwProcessId;
child->hProcess = pi.hProcess;

View File

@ -704,7 +704,7 @@ chown_worker (const char *name, unsigned fmode, uid_t uid, gid_t gid)
res = set_file_attribute (win32_path.has_acls (),
win32_path.get_win32 (),
uid, gid, attrib,
myself->logsrv);
cygheap->user.logsrv ());
}
if (res != 0 && get_errno () == ENOSYS)
{
@ -815,7 +815,7 @@ chmod (const char *path, mode_t mode)
if (! set_file_attribute (win32_path.has_acls (),
win32_path.get_win32 (),
uid, gid,
mode, myself->logsrv)
mode, cygheap->user.logsrv ())
&& allow_ntsec)
res = 0;
@ -1796,7 +1796,7 @@ setgid (gid_t gid)
{
int ret = setegid (gid);
if (!ret)
myself->real_gid = myself->gid;
cygheap->user.real_gid = myself->gid;
return ret;
}
@ -1806,12 +1806,12 @@ setuid (uid_t uid)
{
int ret = seteuid (uid);
if (!ret)
myself->real_uid = myself->uid;
debug_printf ("real: %d, effective: %d", myself->real_uid, myself->uid);
cygheap->user.real_uid = myself->uid;
debug_printf ("real: %d, effective: %d", cygheap->user.real_uid, myself->uid);
return ret;
}
extern char *internal_getlogin (_pinfo *pi);
extern const char *internal_getlogin (cygheap_user &user, HANDLE token);
/* seteuid: standards? */
extern "C" int
@ -1830,7 +1830,7 @@ seteuid (uid_t uid)
}
if (uid != myself->uid)
if (uid == myself->orig_uid)
if (uid == cygheap->user.orig_uid)
{
debug_printf ("RevertToSelf() (uid == orig_uid, token=%d)",
myself->token);
@ -1850,32 +1850,28 @@ seteuid (uid_t uid)
myself->impersonated = TRUE;
}
struct _pinfo pi;
/* pi.token is used in internal_getlogin() to determine if
cygheap_user user;
/* token is used in internal_getlogin() to determine if
impersonation is active. If so, the token is used for
retrieving user's SID. */
pi.token = myself->impersonated ? myself->token
: INVALID_HANDLE_VALUE;
struct passwd *pw_cur = getpwnam (internal_getlogin (&pi));
HANDLE token = myself->impersonated ? myself->token
: INVALID_HANDLE_VALUE;
struct passwd *pw_cur = getpwnam (internal_getlogin (user, token));
if (pw_cur != pw_new)
{
debug_printf ("Diffs!!! token: %d, cur: %d, new: %d, orig: %d",
myself->token, pw_cur->pw_uid,
pw_new->pw_uid, myself->orig_uid);
pw_new->pw_uid, cygheap->user.orig_uid);
set_errno (EPERM);
return -1;
}
myself->uid = uid;
strcpy (myself->username, pi.username);
strcpy (myself->logsrv, pi.logsrv);
strcpy (myself->domain, pi.domain);
memcpy (myself->psid, pi.psid, MAX_SID_LEN);
myself->use_psid = 1;
cygheap->user = user;
}
}
else
set_errno (ENOSYS);
debug_printf ("real: %d, effective: %d", myself->real_uid, myself->uid);
debug_printf ("real: %d, effective: %d", cygheap->user.real_uid, myself->uid);
return 0;
}
@ -1930,11 +1926,7 @@ chroot (const char *newroot)
set_errno (ret);
goto done;
}
cygheap->rootlen = strlen (cygheap->root);
if (cygheap->rootlen > 1 && buf[cygheap->rootlen - 1] == '/')
buf[--cygheap->rootlen] = '\0';
cygheap->root = (char *) crealloc (cygheap->root, cygheap->rootlen + 1);
strcpy (cygheap->root, buf);
cygheap->root = buf;
ret = 0;
done:

View File

@ -20,18 +20,20 @@ details. */
#include "sync.h"
#include "sigproc.h"
#include "pinfo.h"
#include "cygheap.h"
#include "registry.h"
#include "security.h"
char *
internal_getlogin (_pinfo *pi)
const char *
internal_getlogin (cygheap_user &user, HANDLE token)
{
if (! pi)
api_fatal ("pinfo pointer is NULL!\n");
char username[MAX_USER_NAME];
DWORD username_len = MAX_USER_NAME;
if (! GetUserName (pi->username, &username_len))
strcpy (pi->username, "unknown");
if (! GetUserName (username, &username_len))
user.set_name ("unknown");
else
user.set_name (username);
if (os_being_run == winNT)
{
LPWKSTA_USER_INFO_1 wui;
@ -42,31 +44,37 @@ internal_getlogin (_pinfo *pi)
if ((env = getenv ("USERNAME")) != NULL)
un = env;
if ((env = getenv ("LOGONSERVER")) != NULL)
strcpy (pi->logsrv, env + 2); /* filter leading double backslashes */
user.set_logsrv (env + 2); /* filter leading double backslashes */
if ((env = getenv ("USERDOMAIN")) != NULL)
strcpy (pi->domain, env);
user.set_domain (env);
/* Trust only if usernames are identical */
if (un && strcasematch (pi->username, un)
&& pi->domain[0] && pi->logsrv[0])
debug_printf ("Domain: %s, Logon Server: %s", pi->domain, pi->logsrv);
if (un && strcasematch (user.name (), un)
&& user.domain () && user.logsrv ())
debug_printf ("Domain: %s, Logon Server: %s",
user.domain (), user.logsrv ());
/* If that failed, try to get that info from NetBIOS */
else if (!NetWkstaUserGetInfo (NULL, 1, (LPBYTE *)&wui))
{
sys_wcstombs (pi->username, wui->wkui1_username, MAX_USER_NAME);
sys_wcstombs (pi->logsrv, wui->wkui1_logon_server, MAX_HOST_NAME);
sys_wcstombs (pi->domain, wui->wkui1_logon_domain,
char buf[512];
sys_wcstombs (buf, wui->wkui1_username, MAX_USER_NAME);
user.set_name (buf);
sys_wcstombs (buf, wui->wkui1_logon_server, MAX_HOST_NAME);
user.set_logsrv (buf);
sys_wcstombs (buf, wui->wkui1_logon_domain,
MAX_COMPUTERNAME_LENGTH + 1);
user.set_domain (buf);
/* Save values in environment */
if (!strcasematch (pi->username, "SYSTEM")
&& pi->domain[0] && pi->logsrv[0])
if (!strcasematch (user.name (), "SYSTEM")
&& user.domain () && user.logsrv ())
{
LPUSER_INFO_3 ui = NULL;
WCHAR wbuf[MAX_HOST_NAME + 2];
strcat (strcpy (buf, "\\\\"), pi->logsrv);
setenv ("USERNAME", pi->username, 1);
strcat (strcpy (buf, "\\\\"), user.logsrv ());
setenv ("USERNAME", user.name (), 1);
setenv ("LOGONSERVER", buf, 1);
setenv ("USERDOMAIN", pi->domain, 1);
setenv ("USERDOMAIN", user.domain (), 1);
/* HOMEDRIVE and HOMEPATH are wrong most of the time, too,
after changing user context! */
sys_mbstowcs (wbuf, buf, MAX_HOST_NAME + 2);
@ -95,12 +103,12 @@ internal_getlogin (_pinfo *pi)
}
}
debug_printf ("Domain: %s, Logon Server: %s, Windows Username: %s",
pi->domain, pi->logsrv, pi->username);
user.domain (), user.logsrv (), user.name ());
NetApiBufferFree (wui);
}
if (allow_ntsec)
{
HANDLE ptok = pi->token; /* Which is INVALID_HANDLE_VALUE if no
HANDLE ptok = token; /* Which is INVALID_HANDLE_VALUE if no
impersonation took place. */
DWORD siz;
char tu[1024];
@ -116,29 +124,28 @@ internal_getlogin (_pinfo *pi)
else if (!GetTokenInformation (ptok, TokenUser, (LPVOID) &tu,
sizeof tu, &siz))
debug_printf ("GetTokenInformation(): %E");
else if (!(ret = CopySid (MAX_SID_LEN, (PSID) pi->psid,
((TOKEN_USER *) &tu)->User.Sid)))
else if (!(ret = user.set_sid (((TOKEN_USER *) &tu)->User.Sid)))
debug_printf ("Couldn't retrieve SID from access token!");
/* Close token only if it's a result from OpenProcessToken(). */
if (ptok != INVALID_HANDLE_VALUE && pi->token == INVALID_HANDLE_VALUE)
if (ptok != INVALID_HANDLE_VALUE && token == INVALID_HANDLE_VALUE)
CloseHandle (ptok);
/* If that failes, try to get the SID from localhost. This can only
be done if a domain is given because there's a chance that a local
and a domain user may have the same name. */
if (!ret && pi->domain[0])
if (!ret && user.domain ())
{
/* Concat DOMAIN\USERNAME for the next lookup */
strcat (strcat (strcpy (buf, pi->domain), "\\"), pi->username);
if (!(ret = lookup_name (buf, NULL, (PSID) pi->psid)))
strcat (strcat (strcpy (buf, user.domain ()), "\\"), user.name ());
if (!(ret = lookup_name (buf, NULL, user.sid ())))
debug_printf ("Couldn't retrieve SID locally!");
}
/* If that failes, too, as a last resort try to get the SID from
the logon server. */
if (!ret && !(ret = lookup_name(pi->username, pi->logsrv,
(PSID)pi->psid)))
debug_printf ("Couldn't retrieve SID from '%s'!", pi->logsrv);
if (!ret && !(ret = lookup_name(user.name (), user.logsrv (),
user.sid ())))
debug_printf ("Couldn't retrieve SID from '%s'!", user.logsrv ());
/* If we have a SID, try to get the corresponding Cygwin user name
which can be different from the Windows user name. */
@ -148,31 +155,29 @@ internal_getlogin (_pinfo *pi)
char psidbuf[MAX_SID_LEN];
PSID psid = (PSID) psidbuf;
pi->use_psid = 1;
if (!strcasematch (pi->username, "SYSTEM")
&& pi->domain[0] && pi->logsrv[0])
if (!strcasematch (user.name (), "SYSTEM")
&& user.domain () && user.logsrv ())
{
if (get_registry_hive_path (pi->psid, buf))
if (get_registry_hive_path (user.sid (), buf))
setenv ("USERPROFILE", buf, 1);
}
while ((pw = getpwent ()) != NULL)
if (get_pw_sid (psid, pw) && EqualSid (pi->psid, psid))
if (get_pw_sid (psid, pw) && EqualSid (user.sid (), psid))
{
strcpy (pi->username, pw->pw_name);
user.set_name (pw->pw_name);
break;
}
endpwent ();
}
}
}
debug_printf ("Cygwins Username: %s", pi->username);
return pi->username;
debug_printf ("Cygwins Username: %s", user.name ());
return user.name ();
}
void
uinfo_init ()
{
char *username;
struct passwd *p;
/* Initialize to non impersonated values.
@ -185,7 +190,8 @@ uinfo_init ()
/* If uid is USHRT_MAX, the process is started from a non cygwin
process or the user context was changed in spawn.cc */
if (myself->uid == USHRT_MAX)
if ((p = getpwnam (username = internal_getlogin (myself))) != NULL)
if ((p = getpwnam (internal_getlogin (cygheap->user,
INVALID_HANDLE_VALUE))) != NULL)
{
myself->uid = p->pw_uid;
myself->gid = p->pw_gid;
@ -197,8 +203,8 @@ uinfo_init ()
}
/* Real and effective uid/gid are always identical on process start up.
This is at least true for NT/W2K. */
myself->orig_uid = myself->real_uid = myself->uid;
myself->orig_gid = myself->real_gid = myself->gid;
cygheap->user.orig_uid = cygheap->user.real_uid = myself->uid;
cygheap->user.orig_gid = cygheap->user.real_gid = myself->gid;
}
extern "C" char *
@ -210,19 +216,19 @@ getlogin (void)
static NO_COPY char this_username[MAX_USER_NAME];
#endif
return strcpy (this_username, myself->username);
return strcpy (this_username, cygheap->user.name ());
}
extern "C" uid_t
getuid (void)
{
return myself->real_uid;
return cygheap->user.real_uid;
}
extern "C" gid_t
getgid (void)
{
return myself->real_gid;
return cygheap->user.real_gid;
}
extern "C" uid_t