* 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:
Corinna Vinschen
2000-06-19 17:36:30 +00:00
parent 8929e0a70c
commit e219a2bdf0
8 changed files with 238 additions and 74 deletions

View File

@@ -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)
}
}