* dcrt0.cc: Add load statements for `GetSidIdentifierAuthority'
and `RegLoadKeyA'. * registry.cc (get_registry_hive_path): New function. (load_registry_hive): Ditto. * security.cc (convert_sid_to_string_sid): New function. (get_ssid): Renamed to `convert_string_sid_to_sid'. (get_pw_sid): Call `convert_string_sid_to_sid' instead of `get_ssid'. (get_gr_sid): Ditto. (get_admin_sid): Ditto. (get_system_sid): Ditto. (get_creator_owner_sid): Ditto. (get_world_sid): Ditto. * shared.h: New prototypes for `get_registry_hive_path' and `load_registry_hive'. * spawn.cc (spawn_guts): Set child->psid to NULL to force calling `internal_getlogin' from child process in case of changing user context. Call `load_registry_hive' in case of changing user context. (_spawnve): Copy user infos only if user context remains the same. * uinfo.cc: Add load statement for `NetUserGetInfo'. Remove load statement for `NetGetDCName'. (internal_getlogin): Rewrite to speed up process startup and to correct user environment in case user context changes. (uinfo_init): Call internal_getlogin only if myself->psid is NULL, that is user context changes. * winsup.h: Add prototypes for `convert_sid_to_string_sid', `convert_string_sid_to_sid' and `get_pw_sid'.
This commit is contained in:
@@ -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;
|
||||
LPUSER_INFO_3 ui = NULL;
|
||||
WCHAR wbuf[256];
|
||||
|
||||
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);
|
||||
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;
|
||||
/* 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;
|
||||
|
||||
while ((pw = getpwent ()) != NULL)
|
||||
if (get_pw_sid (psid, pw) && EqualSid (pi->psid, psid))
|
||||
{
|
||||
strcpy (pi->username, pw->pw_name);
|
||||
break;
|
||||
}
|
||||
endpwent ();
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user