2000-02-18 03:38:33 +08:00
|
|
|
/* uinfo.cc: user info (uid, gid, etc...)
|
|
|
|
|
2001-09-12 04:01:02 +08:00
|
|
|
Copyright 1996, 1997, 1998, 1999, 2000, 2001 Red Hat, Inc.
|
2000-02-18 03:38:33 +08:00
|
|
|
|
|
|
|
This file is part of Cygwin.
|
|
|
|
|
|
|
|
This software is a copyrighted work licensed under the terms of the
|
|
|
|
Cygwin license. Please consult the file "CYGWIN_LICENSE" for
|
|
|
|
details. */
|
|
|
|
|
|
|
|
#include "winsup.h"
|
2000-08-03 00:28:18 +08:00
|
|
|
#include <pwd.h>
|
2000-07-30 00:24:59 +08:00
|
|
|
#include <unistd.h>
|
2000-07-28 01:30:51 +08:00
|
|
|
#include <winnls.h>
|
2001-05-01 02:21:48 +08:00
|
|
|
#include <wininet.h>
|
2000-02-18 03:38:33 +08:00
|
|
|
#include <utmp.h>
|
|
|
|
#include <limits.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <lm.h>
|
2001-10-16 07:39:33 +08:00
|
|
|
#include <errno.h>
|
2000-11-16 17:53:26 +08:00
|
|
|
#include <sys/cygwin.h>
|
2000-08-22 13:10:20 +08:00
|
|
|
#include "sync.h"
|
|
|
|
#include "sigproc.h"
|
2000-08-12 13:35:42 +08:00
|
|
|
#include "pinfo.h"
|
2001-07-27 03:22:24 +08:00
|
|
|
#include "security.h"
|
2001-04-19 05:10:15 +08:00
|
|
|
#include "fhandler.h"
|
2001-10-01 12:10:07 +08:00
|
|
|
#include "path.h"
|
2001-04-19 05:10:15 +08:00
|
|
|
#include "dtable.h"
|
2001-10-16 07:39:33 +08:00
|
|
|
#include "cygerrno.h"
|
2000-11-15 08:13:09 +08:00
|
|
|
#include "cygheap.h"
|
2000-09-08 10:56:55 +08:00
|
|
|
#include "registry.h"
|
2000-02-18 03:38:33 +08:00
|
|
|
|
2001-04-25 20:54:21 +08:00
|
|
|
struct passwd *
|
2000-11-16 05:14:27 +08:00
|
|
|
internal_getlogin (cygheap_user &user)
|
2000-02-18 03:38:33 +08:00
|
|
|
{
|
2001-10-29 19:53:52 +08:00
|
|
|
char buf[512];
|
2001-05-01 02:21:48 +08:00
|
|
|
char username[UNLEN + 1];
|
2001-06-10 05:25:55 +08:00
|
|
|
DWORD username_len = UNLEN + 1;
|
2001-04-25 20:54:21 +08:00
|
|
|
struct passwd *pw = NULL;
|
2000-11-15 08:13:09 +08:00
|
|
|
|
2001-06-10 05:25:55 +08:00
|
|
|
if (!GetUserName (username, &username_len))
|
* fork.cc (fork): Eliminate superfluous call to getuid().
* security.h: New define `NO_SID'. Remove declarations of functions
moved to methods into class cygsid.
(class cygsid): Declare new methods `getfromstr', `get_sid',
`getfrompw', `getfromgr', `get_rid', `get_uid', `get_gid', `string'
and new constructors and operators =, == and !=.
Declare new global cygsids `well_known_XXX_sid' substituting the
corresponding `get_XXX_sid' functions. Remove declarations of
these functions.
* sec_helper.cc (well_known_admin_sid): New global variable.
(well_known_system_sid): Ditto
(well_known_creator_owner_sid): Ditto
(well_known_world_sid): Ditto
(cygsid::string): New method, substituting `convert_sid_to_string_sid'.
(cygsid::get_sid): New method, substituting `get_sid'.
(cygsid::getfromstr): New method, substituting
`convert_string_sid_to_sid'.
(cygsid::getfrompw): New method, substituting `get_pw_sid'.
(cygsid::getfromgr): New method, substituting `get_gr_sid'.
(cygsid::get_id): New method, substituting `get_id_from_sid'.
(get_admin_sid): Eliminated.
(get_system_sid): Ditto.
(get_creator_owner_sid): Ditto.
(get_world_sid): Ditto.
* grp.cc: Use new cygsid methods and well known sids throughout.
* registry.cc: Ditto.
* sec_acl.cc: Ditto.
* security.cc: Ditto.
* shared.cc: Ditto.
* syscalls.cc (seteuid): Ditto. Eliminate redundant conditional.
* uinfo.cc (internal_getlogin): Ditto.
* spawn.cc (spawn_guts) Revert previous patch.
2001-05-16 03:23:31 +08:00
|
|
|
user.set_name ("unknown");
|
|
|
|
else
|
|
|
|
user.set_name (username);
|
2001-06-10 05:25:55 +08:00
|
|
|
debug_printf ("GetUserName() = %s", user.name ());
|
2001-01-28 13:51:15 +08:00
|
|
|
|
* Makefile.in: Build wincap.o.
* wincap.cc: New file.
* wincap.h: Ditto.
* autoload.cc: Add dynamic load statement for `CreateHardLinkA'.
* dcrt0.cc (os_being_run): Eliminated.
(osname): Ditto.
(iswinnt): Ditto.
(set_os_type): Ditto.
(dll_crt0_1): Call wincap.init() instead of set_os_type().
(_dll_crt0): Ditto.
* environ.cc (set_chunksize): New function.
(parse_thing): `forkchunk' setting now invokes function `set_chunksize'.
* fork.cc (chunksize): Eliminated. Moved to be member of wincap.
* host_dependent.h: Removed.
* syscalls.cc (_link): Try using `CreateHardLinkA' first, if available.
* cygheap.cc, dcrt0.cc, delqueue.cc, dir.cc,
environ.cc, fhandler.cc, fhandler.h, fhandler_console.cc,
fhandler_mem.cc, fork.cc, mmap.cc, net.cc, pinfo.cc, pinfo.h,
security.cc, syscalls.cc, sysconf.cc, syslog.cc, thread.cc,
times.cc, tty.cc, uinfo.cc, uname.cc, winsup.h: Use new wincap
capability check throughout.
* winsup.h: Include wincap.h. Eliminate extern declarations of
`os_being_run' and `iswinnt'. Eliminate `os_type" definition.
* include/cygwin/version.h: Bump version to 1.3.4.
2001-09-13 01:46:37 +08:00
|
|
|
if (wincap.has_security ())
|
2000-02-18 03:38:33 +08:00
|
|
|
{
|
2001-06-10 05:25:55 +08:00
|
|
|
LPWKSTA_USER_INFO_1 wui;
|
|
|
|
NET_API_STATUS ret;
|
|
|
|
char *env;
|
|
|
|
|
|
|
|
user.set_logsrv (NULL);
|
|
|
|
/* First trying to get logon info from environment */
|
|
|
|
if ((env = getenv ("USERNAME")) != NULL)
|
|
|
|
user.set_name (env);
|
|
|
|
if ((env = getenv ("USERDOMAIN")) != NULL)
|
|
|
|
user.set_domain (env);
|
|
|
|
if ((env = getenv ("LOGONSERVER")) != NULL)
|
|
|
|
user.set_logsrv (env + 2); /* filter leading double backslashes */
|
|
|
|
if (user.name () && user.domain ())
|
|
|
|
debug_printf ("User: %s, Domain: %s, Logon Server: %s",
|
|
|
|
user.name (), user.domain (), user.logsrv ());
|
2001-10-13 09:35:15 +08:00
|
|
|
else if (!(ret = NetWkstaUserGetInfo (NULL, 1, (LPBYTE *) &wui)))
|
2001-05-30 04:43:40 +08:00
|
|
|
{
|
2001-06-10 05:25:55 +08:00
|
|
|
sys_wcstombs (buf, wui->wkui1_username, UNLEN + 1);
|
|
|
|
user.set_name (buf);
|
|
|
|
sys_wcstombs (buf, wui->wkui1_logon_server,
|
2001-09-08 05:32:07 +08:00
|
|
|
INTERNET_MAX_HOST_NAME_LENGTH + 1);
|
2001-06-10 05:25:55 +08:00
|
|
|
user.set_logsrv (buf);
|
|
|
|
sys_wcstombs (buf, wui->wkui1_logon_domain,
|
|
|
|
INTERNET_MAX_HOST_NAME_LENGTH + 1);
|
|
|
|
user.set_domain (buf);
|
|
|
|
NetApiBufferFree (wui);
|
2001-09-08 05:32:07 +08:00
|
|
|
}
|
2001-06-10 05:25:55 +08:00
|
|
|
if (!user.logsrv () && get_logon_server_and_user_domain (buf, NULL))
|
|
|
|
{
|
|
|
|
user.set_logsrv (buf + 2);
|
|
|
|
setenv ("LOGONSERVER", buf, 1);
|
* autoload.cc: Add load statements for `LookupAccountNameW',
`LsaClose', `LsaEnumerateAccountRights', `LsaFreeMemory',
`LsaOpenPolicy', `LsaQueryInformationPolicy', `NetLocalGroupEnum',
`NetLocalGroupGetMembers', `NetServerEnum', `NetUserGetGroups' and
`NtCreateToken'.
* ntdll.h: Add declaration for `NtCreateToken'.
* sec_helper.cc: Add `well_known_local_sid', `well_known_dialup_sid',
`well_known_network_sid', `well_known_batch_sid',
`well_known_interactive_sid', `well_known_service_sid' and
`well_known_authenticated_users_sid'.
(cygsid::string): Define as const method.
(cygsid::get_sid): Set psid to NO_SID on error.
(cygsid::getfromstr): Ditto.
(cygsid::getfrompw): Simplify.
(cygsid::getfromgr): Check for gr == NULL.
(legal_sid_type): Move to security.h.
(set_process_privilege): Return -1 on error, otherwise 0 or 1 related
to previous privilege setting.
* security.cc (extract_nt_dom_user): Remove `static'.
(lsa2wchar): New function.
(open_local_policy): Ditto.
(close_local_policy): Ditto.
(get_lsa_srv_inf): Ditto.
(get_logon_server): Ditto.
(get_logon_server_and_user_domain): Ditto.
(get_user_groups): Ditto.
(is_group_member): Ditto.
(get_user_local_groups): Ditto.
(sid_in_token_groups): Ditto.
(get_user_primary_group): Ditto.
(get_group_sidlist): Ditto.
(get_system_priv_list): Ditto.
(get_priv_list): Ditto.
(get_dacl): Ditto.
(create_token): Ditto.
(subauth): Return immediately if SE_TCB_NAME can't be assigned.
Change all return statements in case of error to jumps to `out'
label. Add `out' label to support cleanup.
* security.h: Add extern declarations for `well_known_local_sid',
`well_known_dialup_sid', `well_known_network_sid',
`well_known_batch_sid', `well_known_interactive_sid',
`well_known_service_sid' and `well_known_authenticated_users_sid'.
Add extern declarations for functions `create_token',
`extract_nt_dom_user' and `get_logon_server_and_user_domain'.
(class cygsid): Add method `assign'. Change operator= to call new
`assign' method. Add `debug_print' method.
(class cygsidlist): New class.
(legal_sid_type): Moved from sec_helper.cc to here.
* spawn.cc (spawn_guts) Revert reversion of previous patch.
Call `RevertToSelf' and `ImpersonateLoggedOnUser' instead of `seteuid'
again.
* syscalls.cc (seteuid): Rearranged. Call `create_token' now when
needed. Call `subauth' if `create_token' fails. Try setting token
owner and primary group only if token was not explicitely created
by `create_token'.
* uinfo.cc (internal_getlogin): Try harder to generate correct user
information. Especially don't trust return value of `GetUserName'.
2001-05-20 16:10:47 +08:00
|
|
|
}
|
2001-10-23 02:31:00 +08:00
|
|
|
debug_printf ("Domain: %s, Logon Server: %s, Windows Username: %s",
|
|
|
|
user.domain (), user.logsrv (), user.name ());
|
2001-06-10 05:25:55 +08:00
|
|
|
|
2001-10-23 02:31:00 +08:00
|
|
|
/* NetUserGetInfo() can be slow in NT domain environment, thus we
|
|
|
|
* only obtain HOMEDRIVE and HOMEPATH if they are not already set
|
|
|
|
* in the environment. */
|
|
|
|
if (!getenv ("HOMEPATH") || !getenv ("HOMEDRIVE"))
|
2001-11-05 14:09:15 +08:00
|
|
|
{
|
2001-10-23 02:31:00 +08:00
|
|
|
LPUSER_INFO_3 ui = NULL;
|
|
|
|
WCHAR wuser[UNLEN + 1];
|
|
|
|
|
|
|
|
sys_mbstowcs (wuser, user.name (), sizeof (wuser) / sizeof (*wuser));
|
|
|
|
if ((ret = NetUserGetInfo (NULL, wuser, 3, (LPBYTE *)&ui)))
|
2000-09-03 12:16:35 +08:00
|
|
|
{
|
2001-10-23 02:31:00 +08:00
|
|
|
if (user.logsrv ())
|
* autoload.cc: Add load statements for `LookupAccountNameW',
`LsaClose', `LsaEnumerateAccountRights', `LsaFreeMemory',
`LsaOpenPolicy', `LsaQueryInformationPolicy', `NetLocalGroupEnum',
`NetLocalGroupGetMembers', `NetServerEnum', `NetUserGetGroups' and
`NtCreateToken'.
* ntdll.h: Add declaration for `NtCreateToken'.
* sec_helper.cc: Add `well_known_local_sid', `well_known_dialup_sid',
`well_known_network_sid', `well_known_batch_sid',
`well_known_interactive_sid', `well_known_service_sid' and
`well_known_authenticated_users_sid'.
(cygsid::string): Define as const method.
(cygsid::get_sid): Set psid to NO_SID on error.
(cygsid::getfromstr): Ditto.
(cygsid::getfrompw): Simplify.
(cygsid::getfromgr): Check for gr == NULL.
(legal_sid_type): Move to security.h.
(set_process_privilege): Return -1 on error, otherwise 0 or 1 related
to previous privilege setting.
* security.cc (extract_nt_dom_user): Remove `static'.
(lsa2wchar): New function.
(open_local_policy): Ditto.
(close_local_policy): Ditto.
(get_lsa_srv_inf): Ditto.
(get_logon_server): Ditto.
(get_logon_server_and_user_domain): Ditto.
(get_user_groups): Ditto.
(is_group_member): Ditto.
(get_user_local_groups): Ditto.
(sid_in_token_groups): Ditto.
(get_user_primary_group): Ditto.
(get_group_sidlist): Ditto.
(get_system_priv_list): Ditto.
(get_priv_list): Ditto.
(get_dacl): Ditto.
(create_token): Ditto.
(subauth): Return immediately if SE_TCB_NAME can't be assigned.
Change all return statements in case of error to jumps to `out'
label. Add `out' label to support cleanup.
* security.h: Add extern declarations for `well_known_local_sid',
`well_known_dialup_sid', `well_known_network_sid',
`well_known_batch_sid', `well_known_interactive_sid',
`well_known_service_sid' and `well_known_authenticated_users_sid'.
Add extern declarations for functions `create_token',
`extract_nt_dom_user' and `get_logon_server_and_user_domain'.
(class cygsid): Add method `assign'. Change operator= to call new
`assign' method. Add `debug_print' method.
(class cygsidlist): New class.
(legal_sid_type): Moved from sec_helper.cc to here.
* spawn.cc (spawn_guts) Revert reversion of previous patch.
Call `RevertToSelf' and `ImpersonateLoggedOnUser' instead of `seteuid'
again.
* syscalls.cc (seteuid): Rearranged. Call `create_token' now when
needed. Call `subauth' if `create_token' fails. Try setting token
owner and primary group only if token was not explicitely created
by `create_token'.
* uinfo.cc (internal_getlogin): Try harder to generate correct user
information. Especially don't trust return value of `GetUserName'.
2001-05-20 16:10:47 +08:00
|
|
|
{
|
2001-10-23 02:31:00 +08:00
|
|
|
WCHAR wlogsrv[INTERNET_MAX_HOST_NAME_LENGTH + 3];
|
|
|
|
strcat (strcpy (buf, "\\\\"), user.logsrv ());
|
|
|
|
|
|
|
|
sys_mbstowcs (wlogsrv, buf,
|
2001-11-05 14:09:15 +08:00
|
|
|
sizeof (wlogsrv) / sizeof(*wlogsrv));
|
2001-10-23 02:31:00 +08:00
|
|
|
ret = NetUserGetInfo (wlogsrv, wuser, 3,(LPBYTE *)&ui);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (!ret)
|
|
|
|
{
|
|
|
|
sys_wcstombs (buf, ui->usri3_home_dir, MAX_PATH);
|
|
|
|
if (!buf[0])
|
|
|
|
{
|
|
|
|
sys_wcstombs (buf, ui->usri3_home_dir_drive, MAX_PATH);
|
|
|
|
if (buf[0])
|
|
|
|
strcat (buf, "\\");
|
* autoload.cc: Add load statements for `LookupAccountNameW',
`LsaClose', `LsaEnumerateAccountRights', `LsaFreeMemory',
`LsaOpenPolicy', `LsaQueryInformationPolicy', `NetLocalGroupEnum',
`NetLocalGroupGetMembers', `NetServerEnum', `NetUserGetGroups' and
`NtCreateToken'.
* ntdll.h: Add declaration for `NtCreateToken'.
* sec_helper.cc: Add `well_known_local_sid', `well_known_dialup_sid',
`well_known_network_sid', `well_known_batch_sid',
`well_known_interactive_sid', `well_known_service_sid' and
`well_known_authenticated_users_sid'.
(cygsid::string): Define as const method.
(cygsid::get_sid): Set psid to NO_SID on error.
(cygsid::getfromstr): Ditto.
(cygsid::getfrompw): Simplify.
(cygsid::getfromgr): Check for gr == NULL.
(legal_sid_type): Move to security.h.
(set_process_privilege): Return -1 on error, otherwise 0 or 1 related
to previous privilege setting.
* security.cc (extract_nt_dom_user): Remove `static'.
(lsa2wchar): New function.
(open_local_policy): Ditto.
(close_local_policy): Ditto.
(get_lsa_srv_inf): Ditto.
(get_logon_server): Ditto.
(get_logon_server_and_user_domain): Ditto.
(get_user_groups): Ditto.
(is_group_member): Ditto.
(get_user_local_groups): Ditto.
(sid_in_token_groups): Ditto.
(get_user_primary_group): Ditto.
(get_group_sidlist): Ditto.
(get_system_priv_list): Ditto.
(get_priv_list): Ditto.
(get_dacl): Ditto.
(create_token): Ditto.
(subauth): Return immediately if SE_TCB_NAME can't be assigned.
Change all return statements in case of error to jumps to `out'
label. Add `out' label to support cleanup.
* security.h: Add extern declarations for `well_known_local_sid',
`well_known_dialup_sid', `well_known_network_sid',
`well_known_batch_sid', `well_known_interactive_sid',
`well_known_service_sid' and `well_known_authenticated_users_sid'.
Add extern declarations for functions `create_token',
`extract_nt_dom_user' and `get_logon_server_and_user_domain'.
(class cygsid): Add method `assign'. Change operator= to call new
`assign' method. Add `debug_print' method.
(class cygsidlist): New class.
(legal_sid_type): Moved from sec_helper.cc to here.
* spawn.cc (spawn_guts) Revert reversion of previous patch.
Call `RevertToSelf' and `ImpersonateLoggedOnUser' instead of `seteuid'
again.
* syscalls.cc (seteuid): Rearranged. Call `create_token' now when
needed. Call `subauth' if `create_token' fails. Try setting token
owner and primary group only if token was not explicitely created
by `create_token'.
* uinfo.cc (internal_getlogin): Try harder to generate correct user
information. Especially don't trust return value of `GetUserName'.
2001-05-20 16:10:47 +08:00
|
|
|
else
|
2001-10-23 02:31:00 +08:00
|
|
|
{
|
|
|
|
env = getenv ("SYSTEMDRIVE");
|
|
|
|
if (env && *env)
|
|
|
|
strcat (strcpy (buf, env), "\\");
|
|
|
|
else
|
|
|
|
GetSystemDirectoryA (buf, MAX_PATH);
|
|
|
|
}
|
* autoload.cc: Add load statements for `LookupAccountNameW',
`LsaClose', `LsaEnumerateAccountRights', `LsaFreeMemory',
`LsaOpenPolicy', `LsaQueryInformationPolicy', `NetLocalGroupEnum',
`NetLocalGroupGetMembers', `NetServerEnum', `NetUserGetGroups' and
`NtCreateToken'.
* ntdll.h: Add declaration for `NtCreateToken'.
* sec_helper.cc: Add `well_known_local_sid', `well_known_dialup_sid',
`well_known_network_sid', `well_known_batch_sid',
`well_known_interactive_sid', `well_known_service_sid' and
`well_known_authenticated_users_sid'.
(cygsid::string): Define as const method.
(cygsid::get_sid): Set psid to NO_SID on error.
(cygsid::getfromstr): Ditto.
(cygsid::getfrompw): Simplify.
(cygsid::getfromgr): Check for gr == NULL.
(legal_sid_type): Move to security.h.
(set_process_privilege): Return -1 on error, otherwise 0 or 1 related
to previous privilege setting.
* security.cc (extract_nt_dom_user): Remove `static'.
(lsa2wchar): New function.
(open_local_policy): Ditto.
(close_local_policy): Ditto.
(get_lsa_srv_inf): Ditto.
(get_logon_server): Ditto.
(get_logon_server_and_user_domain): Ditto.
(get_user_groups): Ditto.
(is_group_member): Ditto.
(get_user_local_groups): Ditto.
(sid_in_token_groups): Ditto.
(get_user_primary_group): Ditto.
(get_group_sidlist): Ditto.
(get_system_priv_list): Ditto.
(get_priv_list): Ditto.
(get_dacl): Ditto.
(create_token): Ditto.
(subauth): Return immediately if SE_TCB_NAME can't be assigned.
Change all return statements in case of error to jumps to `out'
label. Add `out' label to support cleanup.
* security.h: Add extern declarations for `well_known_local_sid',
`well_known_dialup_sid', `well_known_network_sid',
`well_known_batch_sid', `well_known_interactive_sid',
`well_known_service_sid' and `well_known_authenticated_users_sid'.
Add extern declarations for functions `create_token',
`extract_nt_dom_user' and `get_logon_server_and_user_domain'.
(class cygsid): Add method `assign'. Change operator= to call new
`assign' method. Add `debug_print' method.
(class cygsidlist): New class.
(legal_sid_type): Moved from sec_helper.cc to here.
* spawn.cc (spawn_guts) Revert reversion of previous patch.
Call `RevertToSelf' and `ImpersonateLoggedOnUser' instead of `seteuid'
again.
* syscalls.cc (seteuid): Rearranged. Call `create_token' now when
needed. Call `subauth' if `create_token' fails. Try setting token
owner and primary group only if token was not explicitely created
by `create_token'.
* uinfo.cc (internal_getlogin): Try harder to generate correct user
information. Especially don't trust return value of `GetUserName'.
2001-05-20 16:10:47 +08:00
|
|
|
}
|
2001-10-23 02:31:00 +08:00
|
|
|
setenv ("HOMEPATH", buf + 2, 1);
|
|
|
|
buf[2] = '\0';
|
|
|
|
setenv ("HOMEDRIVE", buf, 1);
|
2000-09-03 12:16:35 +08:00
|
|
|
}
|
2001-10-23 02:31:00 +08:00
|
|
|
if (ui)
|
|
|
|
NetApiBufferFree (ui);
|
2001-05-30 04:43:40 +08:00
|
|
|
}
|
2001-04-25 17:43:25 +08:00
|
|
|
|
2001-06-10 05:25:55 +08:00
|
|
|
if (allow_ntsec)
|
2001-05-30 04:43:40 +08:00
|
|
|
{
|
2001-06-10 05:25:55 +08:00
|
|
|
HANDLE ptok = user.token; /* Which is INVALID_HANDLE_VALUE if no
|
|
|
|
impersonation took place. */
|
|
|
|
DWORD siz;
|
|
|
|
cygsid tu;
|
|
|
|
int ret = 0;
|
|
|
|
|
|
|
|
/* Try to get the SID either from already impersonated token
|
|
|
|
or from current process first. To differ that two cases is
|
|
|
|
important, because you can't rely on the user information
|
|
|
|
in a process token of a currently impersonated process. */
|
|
|
|
if (ptok == INVALID_HANDLE_VALUE
|
|
|
|
&& !OpenProcessToken (GetCurrentProcess (),
|
2001-09-08 05:32:07 +08:00
|
|
|
TOKEN_ADJUST_DEFAULT | TOKEN_QUERY,
|
2001-06-10 05:25:55 +08:00
|
|
|
&ptok))
|
|
|
|
debug_printf ("OpenProcessToken(): %E\n");
|
|
|
|
else if (!GetTokenInformation (ptok, TokenUser, &tu, sizeof tu, &siz))
|
|
|
|
debug_printf ("GetTokenInformation(): %E");
|
|
|
|
else if (!(ret = user.set_sid (tu)))
|
|
|
|
debug_printf ("Couldn't retrieve SID from access token!");
|
|
|
|
/* 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 && user.domain ())
|
|
|
|
{
|
|
|
|
/* Concat DOMAIN\USERNAME for the next lookup */
|
|
|
|
strcat (strcat (strcpy (buf, user.domain ()), "\\"), user.name ());
|
|
|
|
if (!(ret = lookup_name (buf, NULL, user.sid ())))
|
|
|
|
debug_printf ("Couldn't retrieve SID locally!");
|
|
|
|
}
|
2001-04-25 17:43:25 +08:00
|
|
|
|
2001-06-10 05:25:55 +08:00
|
|
|
/* If that fails, too, as a last resort try to get the SID from
|
|
|
|
the logon server. */
|
|
|
|
if (!ret && !(ret = lookup_name (user.name (), user.logsrv (),
|
|
|
|
user.sid ())))
|
|
|
|
debug_printf ("Couldn't retrieve SID from '%s'!", user.logsrv ());
|
2001-05-30 04:43:40 +08:00
|
|
|
|
2001-06-10 05:25:55 +08:00
|
|
|
/* If we have a SID, try to get the corresponding Cygwin user name
|
|
|
|
which can be different from the Windows user name. */
|
|
|
|
cygsid gsid (NO_SID);
|
|
|
|
if (ret)
|
|
|
|
{
|
|
|
|
cygsid psid;
|
|
|
|
|
|
|
|
for (int pidx = 0; (pw = internal_getpwent (pidx)); ++pidx)
|
|
|
|
if (psid.getfrompw (pw) && EqualSid (user.sid (), psid))
|
|
|
|
{
|
|
|
|
user.set_name (pw->pw_name);
|
|
|
|
struct group *gr = getgrgid (pw->pw_gid);
|
|
|
|
if (gr)
|
|
|
|
if (!gsid.getfromgr (gr))
|
|
|
|
gsid = NO_SID;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (!strcasematch (user.name (), "SYSTEM")
|
|
|
|
&& user.domain () && user.logsrv ())
|
|
|
|
{
|
|
|
|
if (get_registry_hive_path (user.sid (), buf))
|
|
|
|
setenv ("USERPROFILE", buf, 1);
|
|
|
|
else
|
|
|
|
unsetenv ("USERPROFILE");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* If this process is started from a non Cygwin process,
|
|
|
|
set token owner to the same value as token user and
|
|
|
|
primary group to the group which is set as primary group
|
|
|
|
in /etc/passwd. */
|
|
|
|
if (ptok != INVALID_HANDLE_VALUE && myself->ppid == 1)
|
|
|
|
{
|
|
|
|
if (!SetTokenInformation (ptok, TokenOwner, &tu, sizeof tu))
|
|
|
|
debug_printf ("SetTokenInformation(TokenOwner): %E");
|
|
|
|
if (gsid && !SetTokenInformation (ptok, TokenPrimaryGroup,
|
2001-09-08 05:32:07 +08:00
|
|
|
&gsid, sizeof gsid))
|
2001-06-10 05:25:55 +08:00
|
|
|
debug_printf ("SetTokenInformation(TokenPrimaryGroup): %E");
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Close token only if it's a result from OpenProcessToken(). */
|
|
|
|
if (ptok != INVALID_HANDLE_VALUE
|
|
|
|
&& user.token == INVALID_HANDLE_VALUE)
|
|
|
|
CloseHandle (ptok);
|
|
|
|
}
|
2000-02-18 03:38:33 +08:00
|
|
|
}
|
2000-11-15 08:13:09 +08:00
|
|
|
debug_printf ("Cygwins Username: %s", user.name ());
|
2001-10-29 19:53:52 +08:00
|
|
|
if (!pw)
|
|
|
|
pw = getpwnam(user.name ());
|
|
|
|
if (!getenv ("HOME"))
|
|
|
|
{
|
|
|
|
const char *homedrive, *homepath;
|
|
|
|
if (pw && pw->pw_dir && *pw->pw_dir)
|
2001-11-05 14:09:15 +08:00
|
|
|
{
|
2001-10-29 19:53:52 +08:00
|
|
|
setenv ("HOME", pw->pw_dir, 1);
|
|
|
|
debug_printf ("Set HOME (from /etc/passwd) to %s", pw->pw_dir);
|
|
|
|
}
|
|
|
|
else if ((homedrive = getenv ("HOMEDRIVE"))
|
|
|
|
&& (homepath = getenv ("HOMEPATH")))
|
|
|
|
{
|
|
|
|
char home[MAX_PATH];
|
|
|
|
strcpy (buf, homedrive);
|
|
|
|
strcat (buf, homepath);
|
|
|
|
cygwin_conv_to_full_posix_path (buf, home);
|
|
|
|
setenv ("HOME", home, 1);
|
|
|
|
debug_printf ("Set HOME (from HOMEDRIVE/HOMEPATH) to %s", home);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return pw;
|
2000-02-18 03:38:33 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
uinfo_init ()
|
|
|
|
{
|
|
|
|
struct passwd *p;
|
|
|
|
|
2000-06-29 01:42:28 +08:00
|
|
|
/* Initialize to non impersonated values.
|
|
|
|
Setting `impersonated' to TRUE seems to be wrong but it
|
|
|
|
isn't. Impersonated is thought as "Current User and `token'
|
|
|
|
are coincident". See seteuid() for the mechanism behind that. */
|
2001-06-04 22:29:54 +08:00
|
|
|
if (cygheap->user.token != INVALID_HANDLE_VALUE)
|
|
|
|
CloseHandle (cygheap->user.token);
|
2001-05-17 05:53:18 +08:00
|
|
|
cygheap->user.token = INVALID_HANDLE_VALUE;
|
2000-11-16 05:04:02 +08:00
|
|
|
cygheap->user.impersonated = TRUE;
|
2000-06-29 01:42:28 +08:00
|
|
|
|
2000-07-02 18:17:44 +08:00
|
|
|
/* 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)
|
2001-04-25 20:54:21 +08:00
|
|
|
if ((p = internal_getlogin (cygheap->user)) != NULL)
|
2000-07-02 08:00:17 +08:00
|
|
|
{
|
2000-09-03 12:16:35 +08:00
|
|
|
myself->uid = p->pw_uid;
|
2001-04-25 17:43:25 +08:00
|
|
|
/* Set primary group only if ntsec is off or the process has been
|
|
|
|
started from a non cygwin process. */
|
|
|
|
if (!allow_ntsec || myself->ppid == 1)
|
|
|
|
myself->gid = p->pw_gid;
|
2000-07-02 08:00:17 +08:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2000-09-03 12:16:35 +08:00
|
|
|
myself->uid = DEFAULT_UID;
|
|
|
|
myself->gid = DEFAULT_GID;
|
2000-07-02 08:00:17 +08:00
|
|
|
}
|
2000-06-29 01:42:28 +08:00
|
|
|
/* Real and effective uid/gid are always identical on process start up.
|
|
|
|
This is at least true for NT/W2K. */
|
2000-11-15 08:13:09 +08:00
|
|
|
cygheap->user.orig_uid = cygheap->user.real_uid = myself->uid;
|
|
|
|
cygheap->user.orig_gid = cygheap->user.real_gid = myself->gid;
|
2000-02-18 03:38:33 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
extern "C" char *
|
|
|
|
getlogin (void)
|
|
|
|
{
|
|
|
|
#ifdef _MT_SAFE
|
2001-03-19 05:11:25 +08:00
|
|
|
char *this_username=_reent_winsup ()->_username;
|
2000-02-18 03:38:33 +08:00
|
|
|
#else
|
2001-05-01 02:21:48 +08:00
|
|
|
static NO_COPY char this_username[UNLEN + 1];
|
2000-02-18 03:38:33 +08:00
|
|
|
#endif
|
|
|
|
|
2000-11-15 08:13:09 +08:00
|
|
|
return strcpy (this_username, cygheap->user.name ());
|
2000-02-18 03:38:33 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
extern "C" uid_t
|
|
|
|
getuid (void)
|
|
|
|
{
|
2000-11-15 08:13:09 +08:00
|
|
|
return cygheap->user.real_uid;
|
2000-02-18 03:38:33 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
extern "C" gid_t
|
|
|
|
getgid (void)
|
|
|
|
{
|
2000-11-15 08:13:09 +08:00
|
|
|
return cygheap->user.real_gid;
|
2000-02-18 03:38:33 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
extern "C" uid_t
|
|
|
|
geteuid (void)
|
|
|
|
{
|
2000-06-17 03:36:07 +08:00
|
|
|
return myself->uid;
|
2000-02-18 03:38:33 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
extern "C" gid_t
|
|
|
|
getegid (void)
|
|
|
|
{
|
2000-06-17 03:36:07 +08:00
|
|
|
return myself->gid;
|
2000-02-18 03:38:33 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Not quite right - cuserid can change, getlogin can't */
|
|
|
|
extern "C" char *
|
|
|
|
cuserid (char *src)
|
|
|
|
{
|
|
|
|
if (src)
|
|
|
|
{
|
|
|
|
strcpy (src, getlogin ());
|
|
|
|
return src;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
return getlogin ();
|
|
|
|
}
|
|
|
|
}
|