Index: syscalls.cc =================================================================== RCS file: /cvs/src/src/winsup/cygwin/syscalls.cc,v retrieving revision 1.239 diff -u -p -r1.239 syscalls.cc --- syscalls.cc 14 Jan 2003 20:19:27 -0000 1.239 +++ syscalls.cc 15 Jan 2003 04:23:59 -0000 @@ -1948,22 +1948,14 @@ mkfifo (const char *_path, mode_t mode) extern "C" int seteuid32 (__uid32_t uid) { + debug_printf ("uid: %u myself->gid: %u", uid, myself->gid); - debug_printf ("uid: %d myself->gid: %d", uid, myself->gid); - - if (!wincap.has_security () - || (uid == myself->uid && !cygheap->user.groups.ischanged)) + if (uid == myself->uid && !cygheap->user.groups.ischanged) { debug_printf ("Nothing happens"); return 0; } - if (uid == ILLEGAL_UID) - { - set_errno (EINVAL); - return -1; - } - sigframe thisframe (mainthread); cygsid usersid; user_groups &groups = cygheap->user.groups; @@ -1974,6 +1966,8 @@ seteuid32 (__uid32_t uid) PSID origpsid, psid2 = NO_SID; pw_new = internal_getpwuid (uid); + if (!wincap.has_security () && pw_new) + goto success; if (!usersid.getfrompw (pw_new)) { set_errno (EINVAL); @@ -2092,9 +2086,9 @@ seteuid32 (__uid32_t uid) sav_token != cygheap->user.token && sav_token_is_internal_token) CloseHandle (sav_token); - cygheap->user.set_name (pw_new->pw_name); cygheap->user.set_sid (usersid); success: + cygheap->user.set_name (pw_new->pw_name); myself->uid = uid; groups.ischanged = FALSE; return 0; @@ -2135,22 +2129,21 @@ setuid (__uid16_t uid) extern "C" int setegid32 (__gid32_t gid) { - if (!wincap.has_security () || gid == myself->gid) - return 0; + debug_printf ("new egid: %u current: %u", gid, myself->gid); - if (gid == ILLEGAL_GID) + if (gid == myself->gid || !wincap.has_security ()) { - set_errno (EINVAL); - return -1; + myself->gid = gid; + return 0; } sigframe thisframe (mainthread); user_groups * groups = &cygheap->user.groups; cygsid gsid; HANDLE ptok; - struct __group32 * gr = internal_getgrgid (gid); - if (!gr || gr->gr_gid != gid || !gsid.getfromgr (gr)) + + if (!gsid.getfromgr (gr)) { set_errno (EINVAL); return -1; Index: child_info.h =================================================================== RCS file: /cvs/src/src/winsup/cygwin/child_info.h,v retrieving revision 1.36 diff -u -p -r1.36 child_info.h --- child_info.h 15 Oct 2002 07:03:44 -0000 1.36 +++ child_info.h 15 Jan 2003 04:24:27 -0000 @@ -71,7 +71,6 @@ class fhandler_base; class cygheap_exec_info { public: - __uid32_t uid; char *old_title; int argc; char **argv; Index: spawn.cc =================================================================== RCS file: /cvs/src/src/winsup/cygwin/spawn.cc,v retrieving revision 1.118 diff -u -p -r1.118 spawn.cc --- spawn.cc 17 Oct 2002 17:45:09 -0000 1.118 +++ spawn.cc 15 Jan 2003 04:24:54 -0000 @@ -658,7 +658,6 @@ spawn_guts (const char * prog_arg, const char wstname[1024]; char dskname[1024]; - ciresrv.moreinfo->uid = ILLEGAL_UID; hwst = GetProcessWindowStation (); SetUserObjectSecurity (hwst, &dsi, get_null_sd ()); GetUserObjectInformation (hwst, UOI_NAME, wstname, 1024, &n); Index: dcrt0.cc =================================================================== RCS file: /cvs/src/src/winsup/cygwin/dcrt0.cc,v retrieving revision 1.168 diff -u -p -r1.168 dcrt0.cc --- dcrt0.cc 10 Jan 2003 12:32:46 -0000 1.168 +++ dcrt0.cc 15 Jan 2003 04:25:17 -0000 @@ -684,9 +684,8 @@ dll_crt0_1 () /* Init global well known SID objects */ cygsid::init (); - /* Initialize uid, gid if necessary. */ - if (child_proc_info == NULL || spawn_info->moreinfo->uid == ILLEGAL_UID) - uinfo_init (); + /* Initialize user info. */ + uinfo_init (); /* Initialize signal/subprocess handling. */ sigproc_init (); Index: uinfo.cc =================================================================== RCS file: /cvs/src/src/winsup/cygwin/uinfo.cc,v retrieving revision 1.97 diff -u -p -r1.97 uinfo.cc --- uinfo.cc 10 Dec 2002 12:43:49 -0000 1.97 +++ uinfo.cc 15 Jan 2003 04:25:38 -0000 @@ -102,15 +102,18 @@ internal_getlogin (cygheap_user &user) void uinfo_init () { - if (!child_proc_info) - internal_getlogin (cygheap->user); /* Set the cygheap->user. */ - + if (!child_proc_info || cygheap->user.token != INVALID_HANDLE_VALUE) + { + if (!child_proc_info) + internal_getlogin (cygheap->user); /* Set the cygheap->user. */ + else + CloseHandle (cygheap->user.token); + cygheap->user.set_orig_sid (); /* Update the original sid */ + cygheap->user.token = INVALID_HANDLE_VALUE; /* No token present */ + } /* Real and effective uid/gid are identical on process start up. */ cygheap->user.orig_uid = cygheap->user.real_uid = myself->uid; cygheap->user.orig_gid = cygheap->user.real_gid = myself->gid; - cygheap->user.set_orig_sid (); /* Update the original sid */ - - cygheap->user.token = INVALID_HANDLE_VALUE; /* No token present */ } extern "C" char * @@ -214,8 +217,6 @@ cygheap_user::ontherange (homebodies wha debug_printf ("HOME is already in the environment %s", p); else { - if (!pw) - pw = internal_getpwnam (name ()); if (pw && pw->pw_dir && *pw->pw_dir) { debug_printf ("Set HOME (from /etc/passwd) to %s", pw->pw_dir); Index: cygheap.h =================================================================== RCS file: /cvs/src/src/winsup/cygwin/cygheap.h,v retrieving revision 1.56 diff -u -p -r1.56 cygheap.h --- cygheap.h 22 Oct 2002 16:18:55 -0000 1.56 +++ cygheap.h 15 Jan 2003 04:26:26 -0000 @@ -206,6 +206,12 @@ struct user_heap_info unsigned chunk; }; +typedef enum +{ + ETC_PASSWD = 1, + ETC_GROUP= 2 +} etc_changed_bits; + struct init_cygheap { _cmalloc_entry *chain; @@ -223,8 +229,8 @@ struct init_cygheap #ifdef DEBUGGING cygheap_debug debug; #endif - - bool etc_changed (); + int etc_changed_flags; + bool etc_changed (etc_changed_bits); }; #define CYGHEAPSIZE (sizeof (init_cygheap) + (16000 * sizeof (fhandler_union)) + (4 * 65536)) Index: cygheap.cc =================================================================== RCS file: /cvs/src/src/winsup/cygwin/cygheap.cc,v retrieving revision 1.74 diff -u -p -r1.74 cygheap.cc --- cygheap.cc 22 Oct 2002 16:18:55 -0000 1.74 +++ cygheap.cc 15 Jan 2003 04:26:47 -0000 @@ -382,7 +382,7 @@ cstrdup1 (const char *s) } bool -init_cygheap::etc_changed () +init_cygheap::etc_changed (etc_changed_bits who) { bool res = 0; @@ -404,13 +404,20 @@ init_cygheap::etc_changed () } } - if (etc_changed_h != INVALID_HANDLE_VALUE - && WaitForSingleObject (etc_changed_h, 0) == WAIT_OBJECT_0) - { - (void) FindNextChangeNotification (etc_changed_h); - res = 1; - } - + if (etc_changed_h != INVALID_HANDLE_VALUE) + { + if (etc_changed_flags & who) + { + etc_changed_flags &= ~who; + res = 1; + } + else if (WaitForSingleObject (etc_changed_h, 0) == WAIT_OBJECT_0) + { + (void) FindNextChangeNotification (etc_changed_h); + etc_changed_flags |= ~who; + res = 1; + } + } return res; } Index: pwdgrp.h =================================================================== RCS file: /cvs/src/src/winsup/cygwin/pwdgrp.h,v retrieving revision 1.8 diff -u -p -r1.8 pwdgrp.h --- pwdgrp.h 10 Dec 2002 12:43:49 -0000 1.8 +++ pwdgrp.h 15 Jan 2003 04:27:38 -0000 @@ -19,7 +19,7 @@ extern struct __group32 *internal_getgrs extern struct __group32 *internal_getgrgid (__gid32_t gid, BOOL = FALSE); extern struct __group32 *internal_getgrnam (const char *, BOOL = FALSE); extern struct __group32 *internal_getgrent (int); -int internal_getgroups (int, __gid32_t *); +int internal_getgroups (int, __gid32_t *, cygsid * = NULL); enum pwdgrp_state { uninitialized = 0, @@ -31,14 +31,15 @@ class pwdgrp_check { pwdgrp_state state; FILETIME last_modified; char file_w32[MAX_PATH]; + etc_changed_bits me; public: - pwdgrp_check () : state (uninitialized) {} + pwdgrp_check (etc_changed_bits who) : state (uninitialized) { me = who; } BOOL isinitializing () { if (state <= initializing) - state = initializing; - else if (cygheap->etc_changed ()) + state = initializing; + else if (cygheap->etc_changed (me)) { if (!file_w32[0]) state = initializing; @@ -61,7 +62,12 @@ public: { state = nstate; } - BOOL isuninitialized () const { return state == uninitialized; } + BOOL isuninitialized () const + { + if (state == uninitialized) + (void) cygheap->etc_changed (me); + return (state == uninitialized); + } void set_last_modified (HANDLE fh, const char *name) { if (!file_w32[0]) Index: passwd.cc =================================================================== RCS file: /cvs/src/src/winsup/cygwin/passwd.cc,v retrieving revision 1.57 diff -u -p -r1.57 passwd.cc --- passwd.cc 10 Jan 2003 12:32:46 -0000 1.57 +++ passwd.cc 15 Jan 2003 04:28:01 -0000 @@ -30,7 +30,7 @@ static struct passwd *passwd_buf; /* pas static int curr_lines; static int max_lines; -static pwdgrp_check passwd_state; +static pwdgrp_check passwd_state (ETC_PASSWD); /* Position in the passwd cache */ @@ -40,7 +40,7 @@ static pwdgrp_check passwd_state; static int pw_pos = 0; #endif -/* Remove a : teminated string from the buffer, and increment the pointer */ +/* Remove a : terminated string from the buffer, and increment the pointer */ static char * grab_string (char **p) { @@ -65,7 +65,7 @@ grab_int (char **p) { char *src = *p; unsigned int val = strtoul (src, p, 10); - *p = (*p == src || **p != ':') ? almost_null : *p + 1; + *p = (*p == src || **p != ':') ? (char *) "" : *p + 1; return val; } @@ -154,16 +154,16 @@ read_etc_passwd () static char linebuf[1024]; char strbuf[128] = ""; BOOL searchentry = TRUE; - __uid32_t default_uid = DEFAULT_UID; struct passwd *pw; if (wincap.has_security ()) { + static char pretty_ls[] = "????????:*:-1:-1:"; + add_pwd_line (pretty_ls); cygsid tu = cygheap->user.sid (); tu.string (strbuf); - if (myself->uid == ILLEGAL_UID - && (searchentry = !internal_getpwsid (tu))) - default_uid = DEFAULT_UID_NT; + if (myself->uid == ILLEGAL_UID) + searchentry = !internal_getpwsid (tu); } else if (myself->uid == ILLEGAL_UID) searchentry = !internal_getpwuid (DEFAULT_UID); @@ -173,11 +173,12 @@ read_etc_passwd () myself->uid != (__uid32_t) pw->pw_uid && !internal_getpwuid (myself->uid)))) { + (void) cygheap->user.ontherange (CH_HOME, NULL); snprintf (linebuf, sizeof (linebuf), "%s:*:%lu:%lu:,%s:%s:/bin/sh", cygheap->user.name (), - myself->uid == ILLEGAL_UID ? default_uid : myself->uid, + myself->uid == ILLEGAL_UID ? DEFAULT_UID_NT : myself->uid, myself->gid, - strbuf, getenv ("HOME") ?: "/"); + strbuf, getenv ("HOME") ?: ""); debug_printf ("Completing /etc/passwd: %s", linebuf); add_pwd_line (linebuf); } Index: grp.cc =================================================================== RCS file: /cvs/src/src/winsup/cygwin/grp.cc,v retrieving revision 1.61 diff -u -p -r1.61 grp.cc --- grp.cc 10 Dec 2002 12:43:49 -0000 1.61 +++ grp.cc 15 Jan 2003 04:28:25 -0000 @@ -40,7 +40,7 @@ static int max_lines; static int grp_pos = 0; #endif -static pwdgrp_check group_state; +static pwdgrp_check group_state (ETC_GROUP); static char * NO_COPY null_ptr = NULL; static int @@ -157,7 +157,7 @@ read_etc_group () if (!internal_getgrgid (myself->gid)) { static char linebuf [200]; - char group_name [UNLEN + 1] = "unknown"; + char group_name [UNLEN + 1] = "mkgroup"; char strbuf[128] = ""; if (wincap.has_security ()) @@ -173,6 +173,9 @@ read_etc_group () debug_printf ("Completing /etc/group: %s", linebuf); add_grp_line (linebuf); } + static char pretty_ls[] = "????????::-1:"; + if (wincap.has_security ()) + add_grp_line (pretty_ls); } return; } @@ -195,20 +198,14 @@ internal_getgrsid (cygsid &sid) struct __group32 * internal_getgrgid (__gid32_t gid, BOOL check) { - struct __group32 * default_grp = NULL; - if (group_state.isuninitialized () || (check && group_state.isinitializing ())) read_etc_group (); for (int i = 0; i < curr_lines; i++) - { - if (group_buf[i].gr_gid == myself->gid) - default_grp = group_buf + i; - if (group_buf[i].gr_gid == gid) - return group_buf + i; - } - return allow_ntsec || gid != ILLEGAL_GID ? NULL : default_grp; + if (group_buf[i].gr_gid == gid) + return group_buf + i; + return NULL; } struct __group32 * @@ -316,7 +313,7 @@ internal_getgrent (int pos) } int -internal_getgroups (int gidsetsize, __gid32_t *grouplist) +internal_getgroups (int gidsetsize, __gid32_t *grouplist, cygsid * srchsid) { HANDLE hToken = NULL; DWORD size; @@ -345,6 +342,13 @@ internal_getgroups (int gidsetsize, __gi { cygsid sid; + if (srchsid) + { + for (DWORD pg = 0; pg < groups->GroupCount; ++pg) + if (*srchsid == groups->Groups[pg].Sid) + return 1; + return 0; + } for (int gidx = 0; (gr = internal_getgrent (gidx)); ++gidx) if (sid.getfromgr (gr)) for (DWORD pg = 0; pg < groups->GroupCount; ++pg)