diff options
author | cvs2svn <> | 2002-09-22 16:04:17 +0400 |
---|---|---|
committer | cvs2svn <> | 2002-09-22 16:04:17 +0400 |
commit | e8038acb1b5f441fe7b2570c9448cf73b2038477 (patch) | |
tree | 9bc675d4928360fc4998eb5a43727fd1a4ce427d /winsup/cygwin/uinfo.cc | |
parent | 9783ce28caf426c5ab39d1d6aefa31cfdb1b8234 (diff) |
This commit was manufactured by cvs2svn to create tagZ-cygwin_daemon_merge_HEAD
'Z-cygwin_daemon_merge_HEAD'.
Sprout from cygwin_daemon 2002-01-02 00:06:36 UTC cvs2svn 'This commit was manufactured by cvs2svn to create branch 'cygwin_daemon'.'
Cherrypick from cygwin_daemon 2002-02-25 17:47:52 UTC cvs2svn 'This commit was manufactured by cvs2svn to create branch 'cygwin_daemon'.':
winsup/cygwin/how-spawn-works.txt
winsup/cygwin/wsock_event.h
Cherrypick from cygwin_daemon 2002-06-06 15:35:10 UTC cvs2svn 'This commit was manufactured by cvs2svn to create branch 'cygwin_daemon'.':
winsup/cygwin/include/netinet/udp.h
winsup/cygwin/stackdump.sgml
Cherrypick from cygwin_daemon 2002-01-17 10:39:38 UTC cvs2svn 'This commit was manufactured by cvs2svn to create branch 'cygwin_daemon'.':
winsup/cygwin/libc/fnmatch.c
Cherrypick from cygwin_daemon 2002-07-03 20:31:40 UTC cvs2svn 'This commit was manufactured by cvs2svn to create branch 'cygwin_daemon'.':
winsup/cygwin/include/sys/statfs.h
Cherrypick from cygwin_daemon 2002-09-04 15:17:25 UTC cvs2svn 'This commit was manufactured by cvs2svn to create branch 'cygwin_daemon'.':
winsup/cygwin/how-autoload-works.txt
Cherrypick from master 2002-09-22 12:04:15 UTC Conrad Scott <conrad.scott@dsl.pipex.com> '2002-09-22 Conrad Scott <conrad.scott@dsl.pipex.com>':
winsup/cygserver/threaded_queue.cc
winsup/cygserver/woutsup.h
winsup/cygwin/CYGWIN_LICENSE
winsup/cygwin/ChangeLog
winsup/cygwin/ChangeLog-1998
winsup/cygwin/ChangeLog-1999
winsup/cygwin/ChangeLog-2000
winsup/cygwin/Makefile.in
winsup/cygwin/assert.cc
winsup/cygwin/autoload.cc
winsup/cygwin/child_info.h
winsup/cygwin/configure
winsup/cygwin/configure.in
winsup/cygwin/cygerrno.h
winsup/cygwin/cygheap.cc
winsup/cygwin/cygheap.h
winsup/cygwin/cygmagic
winsup/cygwin/cygmalloc.h
winsup/cygwin/cygrun.c
winsup/cygwin/cygserver.cc
winsup/cygwin/cygserver_client.cc
winsup/cygwin/cygserver_ipc.h
winsup/cygwin/cygserver_process.cc
winsup/cygwin/cygserver_shm.cc
winsup/cygwin/cygserver_shm.h
winsup/cygwin/cygserver_transport.cc
winsup/cygwin/cygserver_transport_pipes.cc
winsup/cygwin/cygserver_transport_sockets.cc
winsup/cygwin/cygthread.cc
winsup/cygwin/cygthread.h
winsup/cygwin/cygwin.din
winsup/cygwin/cygwin.sc
winsup/cygwin/dcrt0.cc
winsup/cygwin/debug.cc
winsup/cygwin/debug.h
winsup/cygwin/dir.cc
winsup/cygwin/dlfcn.cc
winsup/cygwin/dll_init.cc
winsup/cygwin/dll_init.h
winsup/cygwin/dlmalloc.c
winsup/cygwin/dtable.cc
winsup/cygwin/dtable.h
winsup/cygwin/environ.cc
winsup/cygwin/environ.h
winsup/cygwin/errno.cc
winsup/cygwin/exceptions.cc
winsup/cygwin/exec.cc
winsup/cygwin/external.cc
winsup/cygwin/fcntl.cc
winsup/cygwin/fhandler.cc
winsup/cygwin/fhandler.h
winsup/cygwin/fhandler_clipboard.cc
winsup/cygwin/fhandler_console.cc
winsup/cygwin/fhandler_disk_file.cc
winsup/cygwin/fhandler_dsp.cc
winsup/cygwin/fhandler_floppy.cc
winsup/cygwin/fhandler_mem.cc
winsup/cygwin/fhandler_proc.cc
winsup/cygwin/fhandler_process.cc
winsup/cygwin/fhandler_random.cc
winsup/cygwin/fhandler_raw.cc
winsup/cygwin/fhandler_registry.cc
winsup/cygwin/fhandler_serial.cc
winsup/cygwin/fhandler_socket.cc
winsup/cygwin/fhandler_tape.cc
winsup/cygwin/fhandler_termios.cc
winsup/cygwin/fhandler_tty.cc
winsup/cygwin/fhandler_virtual.cc
winsup/cygwin/fhandler_windows.cc
winsup/cygwin/fhandler_zero.cc
winsup/cygwin/fork.cc
winsup/cygwin/glob.c
winsup/cygwin/gmon.c
winsup/cygwin/grp.cc
winsup/cygwin/heap.cc
winsup/cygwin/heap.h
winsup/cygwin/hires.h
winsup/cygwin/how-cygheap-works.txt
winsup/cygwin/how-fhandlers-work.txt
winsup/cygwin/how-signals-work.txt
winsup/cygwin/how-to-debug-cygwin.txt
winsup/cygwin/include/cygwin/acl.h
winsup/cygwin/include/cygwin/cygserver.h
winsup/cygwin/include/cygwin/cygserver_process.h
winsup/cygwin/include/cygwin/cygserver_transport.h
winsup/cygwin/include/cygwin/cygserver_transport_pipes.h
winsup/cygwin/include/cygwin/cygserver_transport_sockets.h
winsup/cygwin/include/cygwin/grp.h
winsup/cygwin/include/cygwin/if.h
winsup/cygwin/include/cygwin/ipc.h
winsup/cygwin/include/cygwin/msg.h
winsup/cygwin/include/cygwin/mtio.h
winsup/cygwin/include/cygwin/sem.h
winsup/cygwin/include/cygwin/shm.h
winsup/cygwin/include/cygwin/socket.h
winsup/cygwin/include/cygwin/stat.h
winsup/cygwin/include/cygwin/types.h
winsup/cygwin/include/cygwin/version.h
winsup/cygwin/include/fnmatch.h
winsup/cygwin/include/getopt.h
winsup/cygwin/include/glob.h
winsup/cygwin/include/limits.h
winsup/cygwin/include/netdb.h
winsup/cygwin/include/netinet/ip.h
winsup/cygwin/include/netinet/tcp.h
winsup/cygwin/include/pthread.h
winsup/cygwin/include/sys/cygwin.h
winsup/cygwin/include/sys/ioctl.h
winsup/cygwin/include/sys/mount.h
winsup/cygwin/include/sys/resource.h
winsup/cygwin/include/sys/socket.h
winsup/cygwin/include/sys/soundcard.h
winsup/cygwin/include/sys/strace.h
winsup/cygwin/include/sys/sysmacros.h
winsup/cygwin/include/sys/termios.h
winsup/cygwin/include/sys/uio.h
winsup/cygwin/include/sys/un.h
winsup/cygwin/include/sys/vfs.h
winsup/cygwin/init.cc
winsup/cygwin/ioctl.cc
winsup/cygwin/ipc.cc
winsup/cygwin/lib/cygwin_crt0.c
winsup/cygwin/lib/dll_main.cc
winsup/cygwin/lib/getopt.c
winsup/cygwin/localtime.cc
winsup/cygwin/malloc.cc
winsup/cygwin/malloc_wrapper.cc
winsup/cygwin/miscfuncs.cc
winsup/cygwin/mkvers.sh
winsup/cygwin/mmap.cc
winsup/cygwin/msg.cc
winsup/cygwin/net.cc
winsup/cygwin/ntdll.h
winsup/cygwin/ntea.cc
winsup/cygwin/passwd.cc
winsup/cygwin/path.cc
winsup/cygwin/path.h
winsup/cygwin/perthread.h
winsup/cygwin/pinfo.cc
winsup/cygwin/pinfo.h
winsup/cygwin/pipe.cc
winsup/cygwin/poll.cc
winsup/cygwin/pthread.cc
winsup/cygwin/pwdgrp.h
winsup/cygwin/regex/regcomp.c
winsup/cygwin/registry.cc
winsup/cygwin/resource.cc
winsup/cygwin/safe_memory.h
winsup/cygwin/sched.cc
winsup/cygwin/sec_acl.cc
winsup/cygwin/sec_helper.cc
winsup/cygwin/security.cc
winsup/cygwin/security.h
winsup/cygwin/select.cc
winsup/cygwin/sem.cc
winsup/cygwin/shared.cc
winsup/cygwin/shared_info.h
winsup/cygwin/shm.cc
winsup/cygwin/signal.cc
winsup/cygwin/sigproc.cc
winsup/cygwin/sigproc.h
winsup/cygwin/smallprint.c
winsup/cygwin/spawn.cc
winsup/cygwin/speclib
winsup/cygwin/strace.cc
winsup/cygwin/sync.cc
winsup/cygwin/sync.h
winsup/cygwin/syscalls.cc
winsup/cygwin/sysconf.cc
winsup/cygwin/syslog.cc
winsup/cygwin/termios.cc
winsup/cygwin/thread.cc
winsup/cygwin/thread.h
winsup/cygwin/threaded_queue.cc
winsup/cygwin/threaded_queue.h
winsup/cygwin/times.cc
winsup/cygwin/tty.cc
winsup/cygwin/tty.h
winsup/cygwin/uinfo.cc
winsup/cygwin/uname.cc
winsup/cygwin/wait.cc
winsup/cygwin/winbase.h
winsup/cygwin/wincap.cc
winsup/cygwin/wincap.h
winsup/cygwin/window.cc
winsup/cygwin/winsup.h
winsup/cygwin/winver.rc
winsup/cygwin/woutsup.h
Delete:
winsup/cygwin/include/cygwin/ip.h
winsup/cygwin/include/sys/ipc.h
winsup/cygwin/include/sys/shm.h
winsup/cygwin/include/wchar.h
winsup/cygwin/lib/_cygwin_S_IEXEC.cc
winsup/cygwin/regexp/regerror.c
winsup/cygwin/regexp/regexp.3
winsup/cygwin/regexp/regexp.c
winsup/cygwin/regexp/regsub.c
winsup/cygwin/shortcut.c
winsup/cygwin/shortcut.h
winsup/cygwin/test.c
Diffstat (limited to 'winsup/cygwin/uinfo.cc')
-rw-r--r-- | winsup/cygwin/uinfo.cc | 510 |
1 files changed, 310 insertions, 200 deletions
diff --git a/winsup/cygwin/uinfo.cc b/winsup/cygwin/uinfo.cc index 9bbbe9e9c..fc8b73cc6 100644 --- a/winsup/cygwin/uinfo.cc +++ b/winsup/cygwin/uinfo.cc @@ -1,6 +1,6 @@ /* uinfo.cc: user info (uid, gid, etc...) - Copyright 1996, 1997, 1998, 1999, 2000, 2001 Red Hat, Inc. + Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002 Red Hat, Inc. This file is part of Cygwin. @@ -17,226 +17,110 @@ details. */ #include <limits.h> #include <stdlib.h> #include <lm.h> +#include <errno.h> #include <sys/cygwin.h> -#include "sync.h" -#include "sigproc.h" #include "pinfo.h" #include "security.h" #include "fhandler.h" #include "path.h" #include "dtable.h" +#include "cygerrno.h" #include "cygheap.h" #include "registry.h" +#include "child_info.h" +#include "environ.h" -struct passwd * +void internal_getlogin (cygheap_user &user) { - char username[UNLEN + 1]; - DWORD username_len = UNLEN + 1; struct passwd *pw = NULL; - if (!GetUserName (username, &username_len)) - user.set_name ("unknown"); - else - user.set_name (username); - debug_printf ("GetUserName() = %s", user.name ()); - if (wincap.has_security ()) { - LPWKSTA_USER_INFO_1 wui; - NET_API_STATUS ret; - char buf[512]; - 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 ()); - else if (!(ret = NetWkstaUserGetInfo (NULL, 1, (LPBYTE *)&wui))) - { - sys_wcstombs (buf, wui->wkui1_username, UNLEN + 1); - user.set_name (buf); - sys_wcstombs (buf, wui->wkui1_logon_server, - INTERNET_MAX_HOST_NAME_LENGTH + 1); - user.set_logsrv (buf); - sys_wcstombs (buf, wui->wkui1_logon_domain, - INTERNET_MAX_HOST_NAME_LENGTH + 1); - user.set_domain (buf); - NetApiBufferFree (wui); - } - if (!user.logsrv () && get_logon_server_and_user_domain (buf, NULL)) - { - user.set_logsrv (buf + 2); - setenv ("LOGONSERVER", buf, 1); - } - LPUSER_INFO_3 ui = NULL; - WCHAR wuser[UNLEN + 1]; - WCHAR wlogsrv[INTERNET_MAX_HOST_NAME_LENGTH + 3]; - - /* HOMEDRIVE and HOMEPATH are wrong most of the time, too, - after changing user context! */ - sys_mbstowcs (wuser, user.name (), UNLEN + 1); - wlogsrv[0] = '\0'; - if (user.logsrv ()) - { - strcat (strcpy (buf, "\\\\"), user.logsrv ()); - sys_mbstowcs (wlogsrv, buf, INTERNET_MAX_HOST_NAME_LENGTH + 3); - } - if (!NetUserGetInfo (NULL, wuser, 3, (LPBYTE *)&ui) - || (wlogsrv[0] && !NetUserGetInfo (wlogsrv, wuser, 3,(LPBYTE *)&ui))) - { - 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, "\\"); - else - { - env = getenv ("SYSTEMDRIVE"); - if (env && *env) - strcat (strcpy (buf, env), "\\"); - else - GetSystemDirectoryA (buf, MAX_PATH); - } - } - setenv ("HOMEPATH", buf + 2, 1); - buf[2] = '\0'; - setenv ("HOMEDRIVE", buf, 1); - NetApiBufferFree (ui); - } - debug_printf ("Domain: %s, Logon Server: %s, Windows Username: %s", - user.domain (), user.logsrv (), user.name ()); + HANDLE ptok = INVALID_HANDLE_VALUE; + DWORD siz; + cygsid tu; + DWORD ret = 0; - if (allow_ntsec) - { - 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 (), - TOKEN_ADJUST_DEFAULT | TOKEN_QUERY, - &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!"); - } - - /* 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 ()); - - /* If we have a SID, try to get the corresponding Cygwin user name - which can be different from the Windows user name. */ + /* Try to get the SID either from current process and + store it in user.psid */ + if (!OpenProcessToken (hMainProc, TOKEN_ADJUST_DEFAULT | TOKEN_QUERY, + &ptok)) + system_printf ("OpenProcessToken(): %E\n"); + else if (!GetTokenInformation (ptok, TokenUser, &tu, sizeof tu, &siz)) + system_printf ("GetTokenInformation (TokenUser): %E"); + else if (!(ret = user.set_sid (tu))) + system_printf ("Couldn't retrieve SID from access token!"); + else if (!GetTokenInformation (ptok, TokenPrimaryGroup, + &user.groups.pgsid, sizeof tu, &siz)) + system_printf ("GetTokenInformation (TokenPrimaryGroup): %E"); + /* We must set the user name, uid and gid. + If we have a SID, try to get the corresponding Cygwin + password entry. Set user name which can be different + from the Windows user name */ + if (ret) + { 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"); - } - } + 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 __group32 *gr = getgrgid32 (pw->pw_gid); + if (gr) + if (!gsid.getfromgr (gr)) + gsid = NO_SID; + break; + } - /* 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) + /* Set token owner to the same value as token user and + primary group to the group in /etc/passwd. */ + if (!SetTokenInformation (ptok, TokenOwner, &tu, sizeof tu)) + debug_printf ("SetTokenInformation(TokenOwner): %E"); + if (gsid) { - if (!SetTokenInformation (ptok, TokenOwner, &tu, sizeof tu)) - debug_printf ("SetTokenInformation(TokenOwner): %E"); - if (gsid && !SetTokenInformation (ptok, TokenPrimaryGroup, - &gsid, sizeof gsid)) + user.groups.pgsid = gsid; + if (!SetTokenInformation (ptok, TokenPrimaryGroup, + &gsid, sizeof gsid)) debug_printf ("SetTokenInformation(TokenPrimaryGroup): %E"); } + } + if (ptok != INVALID_HANDLE_VALUE) + CloseHandle (ptok); + } - /* Close token only if it's a result from OpenProcessToken(). */ - if (ptok != INVALID_HANDLE_VALUE - && user.token == INVALID_HANDLE_VALUE) - CloseHandle (ptok); - } + if (!pw) + pw = getpwnam (user.name ()); + + if (pw) + { + myself->uid = pw->pw_uid; + myself->gid = pw->pw_gid; + } + else + { + myself->uid = DEFAULT_UID; + myself->gid = DEFAULT_GID; } - debug_printf ("Cygwins Username: %s", user.name ()); - return pw ?: getpwnam(user.name ()); + + (void) cygheap->user.ontherange (CH_HOME, pw); + + return; } void uinfo_init () { - struct passwd *p; - - /* 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. */ - if (cygheap->user.token != INVALID_HANDLE_VALUE) - CloseHandle (cygheap->user.token); - cygheap->user.token = INVALID_HANDLE_VALUE; - cygheap->user.impersonated = TRUE; - - /* 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 = internal_getlogin (cygheap->user)) != NULL) - { - myself->uid = p->pw_uid; - /* 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; - } - else - { - myself->uid = DEFAULT_UID; - myself->gid = DEFAULT_GID; - } - /* Real and effective uid/gid are always identical on process start up. - This is at least true for NT/W2K. */ + if (!child_proc_info) + internal_getlogin (cygheap->user); /* Set the cygheap->user. */ + + /* 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 * @@ -245,31 +129,55 @@ getlogin (void) #ifdef _MT_SAFE char *this_username=_reent_winsup ()->_username; #else - static NO_COPY char this_username[UNLEN + 1]; + static char this_username[UNLEN + 1] NO_COPY; #endif return strcpy (this_username, cygheap->user.name ()); } -extern "C" uid_t +extern "C" __uid32_t +getuid32 (void) +{ + return cygheap->user.real_uid; +} + +extern "C" __uid16_t getuid (void) { return cygheap->user.real_uid; } -extern "C" gid_t +extern "C" __gid32_t +getgid32 (void) +{ + return cygheap->user.real_gid; +} + +extern "C" __gid16_t getgid (void) { return cygheap->user.real_gid; } -extern "C" uid_t +extern "C" __uid32_t +geteuid32 (void) +{ + return myself->uid; +} + +extern "C" __uid16_t geteuid (void) { return myself->uid; } -extern "C" gid_t +extern "C" __gid32_t +getegid32 (void) +{ + return myself->gid; +} + +extern "C" __gid16_t getegid (void) { return myself->gid; @@ -279,13 +187,215 @@ getegid (void) extern "C" char * cuserid (char *src) { - if (src) + if (!src) + return getlogin (); + + strcpy (src, getlogin ()); + return src; +} + +const char * +cygheap_user::ontherange (homebodies what, struct passwd *pw) +{ + LPUSER_INFO_3 ui = NULL; + WCHAR wuser[UNLEN + 1]; + NET_API_STATUS ret; + char homepath_env_buf[MAX_PATH + 1]; + char homedrive_env_buf[3]; + char *newhomedrive = NULL; + char *newhomepath = NULL; + + + debug_printf ("what %d, pw %p", what, pw); + if (what == CH_HOME) + { + char *p; + if (homedrive) + newhomedrive = homedrive; + else if ((p = getenv ("HOMEDRIVE"))) + newhomedrive = p; + + if (homepath) + newhomepath = homepath; + else if ((p = getenv ("HOMEPATH"))) + newhomepath = p; + + if ((p = getenv ("HOME"))) + debug_printf ("HOME is already in the environment %s", p); + else + { + if (!pw) + pw = getpwnam (name ()); + if (pw && pw->pw_dir && *pw->pw_dir) + { + debug_printf ("Set HOME (from /etc/passwd) to %s", pw->pw_dir); + setenv ("HOME", pw->pw_dir, 1); + } + else if (!newhomedrive || !newhomepath) + setenv ("HOME", "/", 1); + else + { + char home[MAX_PATH]; + char buf[MAX_PATH + 1]; + strcpy (buf, newhomedrive); + strcat (buf, newhomepath); + cygwin_conv_to_full_posix_path (buf, home); + debug_printf ("Set HOME (from HOMEDRIVE/HOMEPATH) to %s", home); + setenv ("HOME", home, 1); + } + } + } + + if (what != CH_HOME && homepath == NULL && newhomepath == NULL) + { + if (!pw) + pw = getpwnam (name ()); + if (pw && pw->pw_dir && *pw->pw_dir) + cygwin_conv_to_full_win32_path (pw->pw_dir, homepath_env_buf); + else + { + homepath_env_buf[0] = homepath_env_buf[1] = '\0'; + if (logsrv ()) + { + WCHAR wlogsrv[INTERNET_MAX_HOST_NAME_LENGTH + 3]; + sys_mbstowcs (wlogsrv, logsrv (), + sizeof (wlogsrv) / sizeof (*wlogsrv)); + sys_mbstowcs (wuser, winname (), sizeof (wuser) / sizeof (*wuser)); + if (!(ret = NetUserGetInfo (wlogsrv, wuser, 3,(LPBYTE *)&ui))) + { + sys_wcstombs (homepath_env_buf, ui->usri3_home_dir, MAX_PATH); + if (!homepath_env_buf[0]) + { + sys_wcstombs (homepath_env_buf, ui->usri3_home_dir_drive, + MAX_PATH); + if (homepath_env_buf[0]) + strcat (homepath_env_buf, "\\"); + else + cygwin_conv_to_full_win32_path ("/", homepath_env_buf); + } + } + } + if (ui) + NetApiBufferFree (ui); + } + + if (homepath_env_buf[1] != ':') + { + newhomedrive = almost_null; + newhomepath = homepath_env_buf; + } + else + { + homedrive_env_buf[0] = homepath_env_buf[0]; + homedrive_env_buf[1] = homepath_env_buf[1]; + homedrive_env_buf[2] = '\0'; + newhomedrive = homedrive_env_buf; + newhomepath = homepath_env_buf + 2; + } + } + + if (newhomedrive && newhomedrive != homedrive) + cfree_and_set (homedrive, (newhomedrive == almost_null) + ? almost_null : cstrdup (newhomedrive)); + + if (newhomepath && newhomepath != homepath) + cfree_and_set (homepath, cstrdup (newhomepath)); + + switch (what) { - strcpy (src, getlogin ()); - return src; + case CH_HOMEDRIVE: + return homedrive; + case CH_HOMEPATH: + return homepath; + default: + return homepath; } +} + +const char * +cygheap_user::test_uid (char *&what, const char *name, size_t namelen) +{ + if (!what && !issetuid ()) + what = getwinenveq (name, namelen, HEAP_STR); + return what; +} + +const char * +cygheap_user::env_logsrv (const char *name, size_t namelen) +{ + if (test_uid (plogsrv, name, namelen)) + return plogsrv; + + const char *mydomain = domain (); + const char *myname = winname (); + if (!mydomain || strcasematch (myname, "SYSTEM")) + return almost_null; + + char logsrv[INTERNET_MAX_HOST_NAME_LENGTH + 3]; + cfree_and_set (plogsrv, almost_null); + if (get_logon_server (mydomain, logsrv, NULL)) + plogsrv = cstrdup (logsrv); + return plogsrv; +} + +const char * +cygheap_user::env_domain (const char *name, size_t namelen) +{ + if (pwinname && test_uid (pdomain, name, namelen)) + return pdomain; + + char username[UNLEN + 1]; + DWORD ulen = sizeof (username); + char userdomain[DNLEN + 1]; + DWORD dlen = sizeof (userdomain); + SID_NAME_USE use; + + cfree_and_set (pwinname, almost_null); + cfree_and_set (pdomain, almost_null); + if (!LookupAccountSid (NULL, sid (), username, &ulen, + userdomain, &dlen, &use)) + __seterrno (); else { - return getlogin (); + pwinname = cstrdup (username); + pdomain = cstrdup (userdomain); } + return pdomain; +} + +const char * +cygheap_user::env_userprofile (const char *name, size_t namelen) +{ + if (test_uid (puserprof, name, namelen)) + return puserprof; + + char userprofile_env_buf[MAX_PATH + 1]; + cfree_and_set (puserprof, almost_null); + /* FIXME: Should this just be setting a puserprofile like everything else? */ + const char *myname = winname (); + if (myname && strcasematch (myname, "SYSTEM") + && get_registry_hive_path (sid (), userprofile_env_buf)) + puserprof = cstrdup (userprofile_env_buf); + + return puserprof; +} + +const char * +cygheap_user::env_homepath (const char *name, size_t namelen) +{ + return ontherange (CH_HOMEPATH); +} + +const char * +cygheap_user::env_homedrive (const char *name, size_t namelen) +{ + return ontherange (CH_HOMEDRIVE); +} + +const char * +cygheap_user::env_name (const char *name, size_t namelen) +{ + if (!test_uid (pwinname, name, namelen)) + (void) domain (); + return pwinname; } |