diff options
Diffstat (limited to 'winsup/cygwin/uinfo.cc')
-rw-r--r-- | winsup/cygwin/uinfo.cc | 169 |
1 files changed, 106 insertions, 63 deletions
diff --git a/winsup/cygwin/uinfo.cc b/winsup/cygwin/uinfo.cc index 4e4a0c459..c2ca4e3f7 100644 --- a/winsup/cygwin/uinfo.cc +++ b/winsup/cygwin/uinfo.cc @@ -26,92 +26,135 @@ extern int group_in_memory_p; char * internal_getlogin (struct pinfo *pi) { - DWORD username_len = MAX_USER_NAME; - if (! pi) api_fatal ("pinfo pointer is NULL!\n"); + DWORD username_len = MAX_USER_NAME; + if (! GetUserName (pi->username, &username_len)) + strcpy (pi->username, "unknown"); if (os_being_run == winNT) { - LPWKSTA_USER_INFO_1 ui; - if (allow_ntsec && !NetWkstaUserGetInfo (NULL, 1, (LPBYTE *)&ui)) + LPWKSTA_USER_INFO_1 wui; + char buf[256], *env; + + /* First trying to get logon info from environment */ + buf[0] = '\0'; + if ((env = getenv ("USERNAME")) != NULL) + strcpy (buf, env); + if ((env = getenv ("LOGONSERVER")) != NULL) + strcpy (pi->logsrv, env + 2); /* filter leading double backslashes */ + if ((env = getenv ("USERDOMAIN")) != NULL) + strcpy (pi->domain, env); + /* Trust only if usernames are identical */ + if (!strcasecmp (pi->username, buf) && pi->domain[0] && pi->logsrv[0]) + debug_printf ("Domain: %s, Logon Server: %s", pi->domain, pi->logsrv); + /* If that failed, try to get that info from NetBIOS */ + else if (!NetWkstaUserGetInfo (NULL, 1, (LPBYTE *)&wui)) { - wcstombs (pi->domain, - ui->wkui1_logon_domain, - (wcslen (ui->wkui1_logon_domain) + 1) * sizeof (WCHAR)); - debug_printf ("Domain: %s", pi->domain); - wcstombs (pi->logsrv, - ui->wkui1_logon_server, - (wcslen (ui->wkui1_logon_server) + 1) * sizeof (WCHAR)); - if (! *pi->logsrv) + wcstombs (pi->username, wui->wkui1_username, + (wcslen (wui->wkui1_username) + 1) * sizeof (WCHAR)); + wcstombs (pi->logsrv, wui->wkui1_logon_server, + (wcslen (wui->wkui1_logon_server) + 1) * sizeof (WCHAR)); + wcstombs (pi->domain, wui->wkui1_logon_domain, + (wcslen (wui->wkui1_logon_domain) + 1) * sizeof (WCHAR)); + /* Save values in environment */ + if (strcasecmp (pi->username, "SYSTEM") + && pi->domain[0] && pi->logsrv[0]) { - LPWSTR logon_srv = NULL; - - if (!NetGetDCName (NULL, - ui->wkui1_logon_domain, - (LPBYTE *)&logon_srv)) - wcstombs (pi->logsrv, - logon_srv, // filter leading double backslashes - (wcslen (logon_srv) + 1) * sizeof (WCHAR)); - if (logon_srv) - NetApiBufferFree (logon_srv); - debug_printf ("DC Server: %s", pi->logsrv); + LPUSER_INFO_3 ui = NULL; + WCHAR wbuf[256]; + + strcat (strcpy (buf, "\\\\"), pi->logsrv); + setenv ("USERNAME", pi->username, 1); + setenv ("LOGONSERVER", buf, 1); + setenv ("USERDOMAIN", pi->domain, 1); + /* HOMEDRIVE and HOMEPATH are wrong most of the time, too, + after changing user context! */ + mbstowcs (wbuf, buf, 256); + if (!NetUserGetInfo (NULL, wui->wkui1_username, 3, (LPBYTE *)&ui) + || !NetUserGetInfo (wbuf,wui->wkui1_username,3,(LPBYTE *)&ui)) + { + wcstombs (buf, ui->usri3_home_dir, 256); + if (!buf[0]) + { + wcstombs (buf, ui->usri3_home_dir_drive, 256); + if (buf[0]) + strcat (buf, "\\"); + } + if (!buf[0]) + strcat (strcpy (buf, getenv ("SYSTEMDRIVE")), "\\"); + setenv ("HOMEPATH", buf + 2, 1); + buf[2] = '\0'; + setenv ("HOMEDRIVE", buf, 1); + NetApiBufferFree (ui); + } } - else - debug_printf ("Logon Server: %s", pi->logsrv); - wcstombs (pi->username, - ui->wkui1_username, - (wcslen (ui->wkui1_username) + 1) * sizeof (WCHAR)); - debug_printf ("Windows Username: %s", pi->username); - NetApiBufferFree (ui); + debug_printf ("Domain: %s, Logon Server: %s, Windows Username: %s", + pi->domain, pi->logsrv, pi->username); + NetApiBufferFree (wui); } - else if (! GetUserName (pi->username, &username_len)) - strcpy (pi->username, "unknown"); - if (!lookup_name (pi->username, pi->logsrv, pi->psid)) + if (allow_ntsec) { - debug_printf ("myself->psid = NULL"); - pi->psid = NULL; - } - else if (allow_ntsec) - { - extern BOOL get_pw_sid (PSID, struct passwd*); - struct passwd *pw; - char psidbuf[40]; - PSID psid = (PSID) psidbuf; - - while ((pw = getpwent ()) != NULL) - if (get_pw_sid (psid, pw) && EqualSid (pi->psid, psid)) - { - strcpy (pi->username, pw->pw_name); - break; - } - endpwent (); + /* 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. */ + int ret = 0; + + if (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 (!ret && !(ret = lookup_name(pi->username, pi->logsrv, + (PSID)pi->sidbuf))) + debug_printf ("Couldn't retrieve SID from '%s'!", pi->logsrv); + if (ret) + { + struct passwd *pw; + char psidbuf[40]; + PSID psid = (PSID) psidbuf; + + pi->psid = (PSID) pi->sidbuf; + if (strcasecmp (pi->username, "SYSTEM") + && pi->domain[0] && pi->logsrv[0]) + { + if (get_registry_hive_path (pi->psid, buf)) + setenv ("USERPROFILE", buf, 1); + } + while ((pw = getpwent ()) != NULL) + if (get_pw_sid (psid, pw) && EqualSid (pi->psid, psid)) + { + strcpy (pi->username, pw->pw_name); + break; + } + endpwent (); + } } } - else - { - debug_printf ("myself->psid = NULL"); - pi->psid = NULL; - if (! GetUserName (pi->username, &username_len)) - strcpy (pi->username, "unknown"); - } - debug_printf ("Cygwins Username: %s\n", pi->username); + debug_printf ("Cygwins Username: %s", pi->username); return pi->username; } void uinfo_init () { + char *username; struct passwd *p; - myself->psid = (PSID) myself->sidbuf; - if ((p = getpwnam (internal_getlogin (myself))) != NULL) + /* If psid is non null, the process is forked or spawned from + 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) { /* calling getpwnam assures us that /etc/password has been - read in, but we can't be sure about /etc/group */ + read in, but we can't be sure about /etc/group */ if (!group_in_memory_p) - read_etc_group (); + read_etc_group (); myself->uid = p->pw_uid; myself->gid = p->pw_gid; @@ -197,7 +240,7 @@ dummy_autoload (void) { LoadDLLinit (netapi32) LoadDLLfunc (NetWkstaUserGetInfo, 12, netapi32) -LoadDLLfunc (NetGetDCName, 12, netapi32) +LoadDLLfunc (NetUserGetInfo, 16, netapi32) LoadDLLfunc (NetApiBufferFree, 4, netapi32) } } |