* 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> Tue Nov 14 17:05:00 2000 Eric Fifer <efifer@dircon.co.uk>
* dir.cc (rewinddir): Always set __d_position = 0, so next * dir.cc (rewinddir): Always set __d_position = 0, so next

View File

@ -279,3 +279,93 @@ cstrdup1 (const char *s)
MALLOC_CHECK; MALLOC_CHECK;
return p; 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]; 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 struct init_cygheap
{ {
_cmalloc_entry *chain; _cmalloc_entry *chain;
struct cygheap_root root;
{ cygheap_user user;
size_t rootlen;
char *root;
};
mode_t umask; mode_t umask;
}; };

View File

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

View File

@ -76,7 +76,7 @@ opendir (const char *dirname)
goto failed; goto failed;
} }
if (stat (cygheap->rootlen ? dirname : real_dirname.get_win32 (), if (stat (cygheap->root.length () ? dirname : real_dirname.get_win32 (),
&statbuf) == -1) &statbuf) == -1)
goto failed; 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_t uid;
uid = geteuid(); uid = geteuid();
if (myself->impersonated && myself->token != INVALID_HANDLE_VALUE) if (myself->impersonated && myself->token != INVALID_HANDLE_VALUE)
seteuid (myself->orig_uid); seteuid (cygheap->user.orig_uid);
ch.parent = hParent; ch.parent = hParent;
ch.cygheap = cygheap; 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->hProcess = pi.hProcess;
forked->dwProcessId = pi.dwProcessId; forked->dwProcessId = pi.dwProcessId;
forked->copysigs(myself); forked->copysigs(myself);
memcpy (forked->username, myself->username, MAX_USER_NAME);
set_child_mmap_ptr (forked); set_child_mmap_ptr (forked);
forked.remember (); forked.remember ();

View File

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

View File

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

View File

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

View File

@ -73,24 +73,11 @@ public:
pid_t sid; /* Session ID */ pid_t sid; /* Session ID */
int ctty; /* Control tty */ int ctty; /* Control tty */
bool has_pgid_children;/* True if we've forked or spawned children with our GID. */ 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 /* token is needed if sexec should be called. It can be set by a call
to `set_impersonation_token()'. */ to `set_impersonation_token()'. */
HANDLE token; HANDLE token;
BOOL impersonated; 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. */ /* Resources used by process. */
long start_time; long start_time;

View File

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

View File

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

View File

@ -263,18 +263,7 @@ proc_subproc (DWORD what, DWORD val)
vchild->pgid = myself->pgid; vchild->pgid = myself->pgid;
vchild->sid = myself->sid; vchild->sid = myself->sid;
vchild->ctty = myself->ctty; 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; 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->token = myself->token;
vchild->process_state |= PID_INITIALIZING | (myself->process_state & PID_USETTY); vchild->process_state |= PID_INITIALIZING | (myself->process_state & PID_USETTY);

View File

@ -554,7 +554,12 @@ skip_arg_parsing:
if (real_path.iscygexec ()) if (real_path.iscygexec ())
envblock = NULL; envblock = NULL;
else 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 = cygheap;
ciresrv.cygheap_max = cygheap_max; ciresrv.cygheap_max = cygheap_max;
@ -625,7 +630,7 @@ skip_arg_parsing:
/* Remove impersonation */ /* Remove impersonation */
uid_t uid = geteuid(); uid_t uid = geteuid();
if (myself->impersonated && myself->token != INVALID_HANDLE_VALUE) if (myself->impersonated && myself->token != INVALID_HANDLE_VALUE)
seteuid (myself->orig_uid); seteuid (cygheap->user.orig_uid);
/* Load users registry hive. */ /* Load users registry hive. */
load_registry_hive (sid); load_registry_hive (sid);
@ -705,7 +710,6 @@ skip_arg_parsing:
syscall_printf ("-1 = spawnve (), process table full"); syscall_printf ("-1 = spawnve (), process table full");
return -1; return -1;
} }
child->username[0] = '\0';
child->progname[0] = '\0'; child->progname[0] = '\0';
child->dwProcessId = pi.dwProcessId; child->dwProcessId = pi.dwProcessId;
child->hProcess = pi.hProcess; 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 (), res = set_file_attribute (win32_path.has_acls (),
win32_path.get_win32 (), win32_path.get_win32 (),
uid, gid, attrib, uid, gid, attrib,
myself->logsrv); cygheap->user.logsrv ());
} }
if (res != 0 && get_errno () == ENOSYS) 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 (), if (! set_file_attribute (win32_path.has_acls (),
win32_path.get_win32 (), win32_path.get_win32 (),
uid, gid, uid, gid,
mode, myself->logsrv) mode, cygheap->user.logsrv ())
&& allow_ntsec) && allow_ntsec)
res = 0; res = 0;
@ -1796,7 +1796,7 @@ setgid (gid_t gid)
{ {
int ret = setegid (gid); int ret = setegid (gid);
if (!ret) if (!ret)
myself->real_gid = myself->gid; cygheap->user.real_gid = myself->gid;
return ret; return ret;
} }
@ -1806,12 +1806,12 @@ setuid (uid_t uid)
{ {
int ret = seteuid (uid); int ret = seteuid (uid);
if (!ret) if (!ret)
myself->real_uid = myself->uid; cygheap->user.real_uid = myself->uid;
debug_printf ("real: %d, effective: %d", myself->real_uid, myself->uid); debug_printf ("real: %d, effective: %d", cygheap->user.real_uid, myself->uid);
return ret; return ret;
} }
extern char *internal_getlogin (_pinfo *pi); extern const char *internal_getlogin (cygheap_user &user, HANDLE token);
/* seteuid: standards? */ /* seteuid: standards? */
extern "C" int extern "C" int
@ -1830,7 +1830,7 @@ seteuid (uid_t uid)
} }
if (uid != myself->uid) if (uid != myself->uid)
if (uid == myself->orig_uid) if (uid == cygheap->user.orig_uid)
{ {
debug_printf ("RevertToSelf() (uid == orig_uid, token=%d)", debug_printf ("RevertToSelf() (uid == orig_uid, token=%d)",
myself->token); myself->token);
@ -1850,32 +1850,28 @@ seteuid (uid_t uid)
myself->impersonated = TRUE; myself->impersonated = TRUE;
} }
struct _pinfo pi; cygheap_user user;
/* pi.token is used in internal_getlogin() to determine if /* token is used in internal_getlogin() to determine if
impersonation is active. If so, the token is used for impersonation is active. If so, the token is used for
retrieving user's SID. */ retrieving user's SID. */
pi.token = myself->impersonated ? myself->token HANDLE token = myself->impersonated ? myself->token
: INVALID_HANDLE_VALUE; : INVALID_HANDLE_VALUE;
struct passwd *pw_cur = getpwnam (internal_getlogin (&pi)); struct passwd *pw_cur = getpwnam (internal_getlogin (user, token));
if (pw_cur != pw_new) if (pw_cur != pw_new)
{ {
debug_printf ("Diffs!!! token: %d, cur: %d, new: %d, orig: %d", debug_printf ("Diffs!!! token: %d, cur: %d, new: %d, orig: %d",
myself->token, pw_cur->pw_uid, myself->token, pw_cur->pw_uid,
pw_new->pw_uid, myself->orig_uid); pw_new->pw_uid, cygheap->user.orig_uid);
set_errno (EPERM); set_errno (EPERM);
return -1; return -1;
} }
myself->uid = uid; myself->uid = uid;
strcpy (myself->username, pi.username); cygheap->user = user;
strcpy (myself->logsrv, pi.logsrv);
strcpy (myself->domain, pi.domain);
memcpy (myself->psid, pi.psid, MAX_SID_LEN);
myself->use_psid = 1;
} }
} }
else else
set_errno (ENOSYS); 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; return 0;
} }
@ -1930,11 +1926,7 @@ chroot (const char *newroot)
set_errno (ret); set_errno (ret);
goto done; goto done;
} }
cygheap->rootlen = strlen (cygheap->root); cygheap->root = buf;
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);
ret = 0; ret = 0;
done: done:

View File

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