From bb34ad9674effea3d4401186cd729e4feb9ad881 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Sat, 24 Jun 2000 17:37:52 +0000 Subject: [PATCH] * fork.cc (fork): Fix error in copying SID pointer. * spawn.cc (_spawnve): Ditto. * passwd.cc: Remove static from `passwd_in_memory_p'. (read_etc_passwd): Remove static. * uinfo.cc: Move global declaration of `read_etc_group' and `group_in_memory_p' into `uinfo_init'. (internal_getlogin): Try to get SID from current process first. (uinfo_init): Don't set uid and gid if `myself' has a valid SID. Only load /etc/passwd and /etc/group in that case. --- winsup/cygwin/ChangeLog | 12 ++++++++++ winsup/cygwin/fork.cc | 3 ++- winsup/cygwin/passwd.cc | 4 ++-- winsup/cygwin/spawn.cc | 3 ++- winsup/cygwin/uinfo.cc | 49 ++++++++++++++++++++++++++++++++--------- 5 files changed, 56 insertions(+), 15 deletions(-) diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index 41818fcad..a5aa61761 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,15 @@ +Sat Jun 24 19:30:00 2000 Corinna Vinschen + + * fork.cc (fork): Fix error in copying SID pointer. + * spawn.cc (_spawnve): Ditto. + * passwd.cc: Remove static from `passwd_in_memory_p'. + (read_etc_passwd): Remove static. + * uinfo.cc: Move global declaration of `read_etc_group' and + `group_in_memory_p' into `uinfo_init'. + (internal_getlogin): Try to get SID from current process first. + (uinfo_init): Don't set uid and gid if `myself' has a valid SID. + Only load /etc/passwd and /etc/group in that case. + Sat Jun 24 12:29:59 2000 Christopher Faylor * shared.cc (shared_info::initialize): Improve error message clarity. diff --git a/winsup/cygwin/fork.cc b/winsup/cygwin/fork.cc index b0248026b..f3b32b7f9 100644 --- a/winsup/cygwin/fork.cc +++ b/winsup/cygwin/fork.cc @@ -419,8 +419,9 @@ fork () child->process_state |= PID_INITIALIZING | (myself->process_state & PID_USETTY); memcpy (child->username, myself->username, MAX_USER_NAME); - child->psid = myself->psid; memcpy (child->sidbuf, myself->sidbuf, 40); + if (myself->psid) + child->psid = child->sidbuf; memcpy (child->logsrv, myself->logsrv, 256); memcpy (child->domain, myself->domain, MAX_COMPUTERNAME_LENGTH+1); child->token = myself->token; diff --git a/winsup/cygwin/passwd.cc b/winsup/cygwin/passwd.cc index f385b7d54..33c1d6fe8 100644 --- a/winsup/cygwin/passwd.cc +++ b/winsup/cygwin/passwd.cc @@ -24,7 +24,7 @@ static int max_lines = 0; /* Set to 1 when /etc/passwd has been read in by read_etc_passwd (). */ /* Functions in this file need to check the value of passwd_in_memory_p and read in the password file if it isn't set. */ -static int passwd_in_memory_p = 0; +int passwd_in_memory_p = 0; /* Position in the passwd cache */ #ifdef _MT_SAFE @@ -103,7 +103,7 @@ add_pwd_line (char *line) /* Read in /etc/passwd and save contents in the password cache. This sets passwd_in_memory_p to 1 so functions in this file can tell that /etc/passwd has been read in */ -static void +void read_etc_passwd () { extern int passwd_sem; diff --git a/winsup/cygwin/spawn.cc b/winsup/cygwin/spawn.cc index 7225c5377..6ec011914 100644 --- a/winsup/cygwin/spawn.cc +++ b/winsup/cygwin/spawn.cc @@ -847,8 +847,9 @@ _spawnve (HANDLE hToken, int mode, const char *path, const char *const *argv, if (!hToken && !myself->token) { memcpy (child->username, myself->username, MAX_USER_NAME); - child->psid = myself->psid; memcpy (child->sidbuf, myself->sidbuf, 40); + if (myself->psid) + child->psid = child->sidbuf; memcpy (child->logsrv, myself->logsrv, 256); memcpy (child->domain, myself->domain, MAX_COMPUTERNAME_LENGTH+1); } diff --git a/winsup/cygwin/uinfo.cc b/winsup/cygwin/uinfo.cc index c2ca4e3f7..66bd1aee6 100644 --- a/winsup/cygwin/uinfo.cc +++ b/winsup/cygwin/uinfo.cc @@ -18,11 +18,6 @@ details. */ #include #include -/* FIXME: shouldn't violate internal object space -- these two - should be static inside grp.cc */ -void read_etc_group (); -extern int group_in_memory_p; - char * internal_getlogin (struct pinfo *pi) { @@ -95,21 +90,42 @@ internal_getlogin (struct pinfo *pi) } if (allow_ntsec) { - /* Try to get the SID from localhost first. 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. */ + HANDLE ptok = INVALID_HANDLE_VALUE; + DWORD siz; + char tu[1024]; int ret = 0; + + /* Try to get the SID from current process first */ + if (!OpenProcessToken (GetCurrentProcess (), TOKEN_QUERY, &ptok)) + debug_printf ("OpenProcessToken(): %E\n"); + else if (!GetTokenInformation (ptok, TokenUser, (LPVOID) &tu, + sizeof tu, &siz)) + debug_printf ("GetTokenInformation(): %E"); + else if (!(ret = CopySid (40, (PSID) pi->sidbuf, + ((TOKEN_USER *) &tu)->User.Sid))) + debug_printf ("Couldn't retrieve SID from access token!"); + if (ptok != INVALID_HANDLE_VALUE) + CloseHandle (ptok); - if (pi->domain[0]) + /* 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]) { /* Concat DOMAIN\USERNAME for the next lookup */ strcat (strcat (strcpy (buf, pi->domain), "\\"), pi->username); if (!(ret = lookup_name (buf, NULL, (PSID) pi->sidbuf))) 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->sidbuf))) debug_printf ("Couldn't retrieve SID from '%s'!", pi->logsrv); + + /* If we have a SID, try to get the corresponding Cygwin user name + which can be different from the Windows user name. */ if (ret) { struct passwd *pw; @@ -140,6 +156,11 @@ internal_getlogin (struct pinfo *pi) void uinfo_init () { + void read_etc_passwd (); + extern int passwd_in_memory_p; + void read_etc_group (); + extern int group_in_memory_p; + char *username; struct passwd *p; @@ -147,8 +168,14 @@ uinfo_init () another cygwin process without changing the user context. So all user infos in myself as well as the environment are (perhaps) valid. */ - username = myself->psid ? myself->username : internal_getlogin (myself); - if ((p = getpwnam (username)) != NULL) + if (myself->psid) + { + if (!passwd_in_memory_p) + read_etc_passwd(); + if (!group_in_memory_p) + read_etc_group (); + } + else if ((p = getpwnam (username = internal_getlogin (myself))) != NULL) { /* calling getpwnam assures us that /etc/password has been read in, but we can't be sure about /etc/group */