Welcome to mirror list, hosted at ThFree Co, Russian Federation.

cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--winsup/cygwin/ChangeLog34
-rw-r--r--winsup/cygwin/cygheap.cc90
-rw-r--r--winsup/cygwin/cygheap.h59
-rw-r--r--winsup/cygwin/dcrt0.cc2
-rw-r--r--winsup/cygwin/dir.cc2
-rw-r--r--winsup/cygwin/fork.cc3
-rw-r--r--winsup/cygwin/grp.cc10
-rw-r--r--winsup/cygwin/passwd.cc3
-rw-r--r--winsup/cygwin/path.cc34
-rw-r--r--winsup/cygwin/pinfo.h13
-rw-r--r--winsup/cygwin/security.cc9
-rw-r--r--winsup/cygwin/shared.cc7
-rw-r--r--winsup/cygwin/sigproc.cc11
-rw-r--r--winsup/cygwin/spawn.cc10
-rw-r--r--winsup/cygwin/syscalls.cc40
-rw-r--r--winsup/cygwin/uinfo.cc98
16 files changed, 287 insertions, 138 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog
index 58e6e67c4..623570261 100644
--- a/winsup/cygwin/ChangeLog
+++ b/winsup/cygwin/ChangeLog
@@ -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
diff --git a/winsup/cygwin/cygheap.cc b/winsup/cygwin/cygheap.cc
index 15c2667c0..0d720e9d5 100644
--- a/winsup/cygwin/cygheap.cc
+++ b/winsup/cygwin/cygheap.cc
@@ -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);
+ }
+}
diff --git a/winsup/cygwin/cygheap.h b/winsup/cygwin/cygheap.h
index faa50bf12..779df67d3 100644
--- a/winsup/cygwin/cygheap.h
+++ b/winsup/cygwin/cygheap.h
@@ -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;
};
diff --git a/winsup/cygwin/dcrt0.cc b/winsup/cygwin/dcrt0.cc
index 7f75eca8f..c0a9f50d3 100644
--- a/winsup/cygwin/dcrt0.cc
+++ b/winsup/cygwin/dcrt0.cc
@@ -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;
}
}
diff --git a/winsup/cygwin/dir.cc b/winsup/cygwin/dir.cc
index ee7d2a967..a14b44f8f 100644
--- a/winsup/cygwin/dir.cc
+++ b/winsup/cygwin/dir.cc
@@ -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;
diff --git a/winsup/cygwin/fork.cc b/winsup/cygwin/fork.cc
index c5536e2b7..10c20040e 100644
--- a/winsup/cygwin/fork.cc
+++ b/winsup/cygwin/fork.cc
@@ -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 ();
diff --git a/winsup/cygwin/grp.cc b/winsup/cygwin/grp.cc
index 0469c0217..737c50595 100644
--- a/winsup/cygwin/grp.cc
+++ b/winsup/cygwin/grp.cc
@@ -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"
diff --git a/winsup/cygwin/passwd.cc b/winsup/cygwin/passwd.cc
index 62b2955a0..797fb5375 100644
--- a/winsup/cygwin/passwd.cc
+++ b/winsup/cygwin/passwd.cc
@@ -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;
diff --git a/winsup/cygwin/path.cc b/winsup/cygwin/path.cc
index b415afa5a..b878920f7 100644
--- a/winsup/cygwin/path.cc
+++ b/winsup/cygwin/path.cc
@@ -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);
diff --git a/winsup/cygwin/pinfo.h b/winsup/cygwin/pinfo.h
index 74ceb95c5..0171a71b0 100644
--- a/winsup/cygwin/pinfo.h
+++ b/winsup/cygwin/pinfo.h
@@ -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;
diff --git a/winsup/cygwin/security.cc b/winsup/cygwin/security.cc
index 6d0f5a6bc..35caf1d79 100644
--- a/winsup/cygwin/security.cc
+++ b/winsup/cygwin/security.cc
@@ -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
diff --git a/winsup/cygwin/shared.cc b/winsup/cygwin/shared.cc
index ee68c9b4a..fb023e725 100644
--- a/winsup/cygwin/shared.cc
+++ b/winsup/cygwin/shared.cc
@@ -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)
diff --git a/winsup/cygwin/sigproc.cc b/winsup/cygwin/sigproc.cc
index 999dc7319..472b101e8 100644
--- a/winsup/cygwin/sigproc.cc
+++ b/winsup/cygwin/sigproc.cc
@@ -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);
diff --git a/winsup/cygwin/spawn.cc b/winsup/cygwin/spawn.cc
index e17541446..7dc193c48 100644
--- a/winsup/cygwin/spawn.cc
+++ b/winsup/cygwin/spawn.cc
@@ -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;
diff --git a/winsup/cygwin/syscalls.cc b/winsup/cygwin/syscalls.cc
index 348a49b8b..90cc1b785 100644
--- a/winsup/cygwin/syscalls.cc
+++ b/winsup/cygwin/syscalls.cc
@@ -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:
diff --git a/winsup/cygwin/uinfo.cc b/winsup/cygwin/uinfo.cc
index 45f3747c0..8a95fa349 100644
--- a/winsup/cygwin/uinfo.cc
+++ b/winsup/cygwin/uinfo.cc
@@ -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