* sec_helper.cc (cygsid::getfrompw): Change parameter to `const'.
(cygsid::getfromgr): Ditto. * security.cc: Use `sys_mbstowcs' and `sys_wcstombs' throughout. (extract_nt_dom_user): Try to get user and domain from SID in pw->pw_gecos first. * security.h (class cygsid): Change parameter of getfrompw() and getfromgr() to `const'. * uinfo.cc (internal_getlogin): Change order for evaluating user information in winNT case. Drop usage of NetWkstaUserGetInfo().
This commit is contained in:
parent
98ae4ae7d5
commit
b2939a814c
|
@ -1,4 +1,16 @@
|
|||
Tue May 28 21:34:00 2001 Corinna Vinschen <corinna@vinschen.de>
|
||||
Tue May 29 19:02:00 2001 Corinna Vinschen <corinna@vinschen.de>
|
||||
|
||||
* sec_helper.cc (cygsid::getfrompw): Change parameter to `const'.
|
||||
(cygsid::getfromgr): Ditto.
|
||||
* security.cc: Use `sys_mbstowcs' and `sys_wcstombs' throughout.
|
||||
(extract_nt_dom_user): Try to get user and domain from SID in
|
||||
pw->pw_gecos first.
|
||||
* security.h (class cygsid): Change parameter of getfrompw() and
|
||||
getfromgr() to `const'.
|
||||
* uinfo.cc (internal_getlogin): Change order for evaluating user
|
||||
information in winNT case. Drop usage of NetWkstaUserGetInfo().
|
||||
|
||||
Mon May 28 21:34:00 2001 Corinna Vinschen <corinna@vinschen.de>
|
||||
|
||||
* shortcut.c (check_shortcut): Treat only Cygwin shortcuts as symlinks.
|
||||
|
||||
|
|
|
@ -121,14 +121,14 @@ cygsid::getfromstr (const char *nsidstr)
|
|||
}
|
||||
|
||||
BOOL
|
||||
cygsid::getfrompw (struct passwd *pw)
|
||||
cygsid::getfrompw (const struct passwd *pw)
|
||||
{
|
||||
char *sp = (pw && pw->pw_gecos) ? strrchr (pw->pw_gecos, ',') : NULL;
|
||||
return (*this = sp ? sp + 1 : "") != NULL;
|
||||
}
|
||||
|
||||
BOOL
|
||||
cygsid::getfromgr (struct group *gr)
|
||||
cygsid::getfromgr (const struct group *gr)
|
||||
{
|
||||
char *sp = (gr && gr->gr_passwd) ? gr->gr_passwd : NULL;
|
||||
return (*this = sp ?: "") != NULL;
|
||||
|
|
|
@ -22,6 +22,7 @@ details. */
|
|||
#include <sys/stat.h>
|
||||
#include <sys/acl.h>
|
||||
#include <ctype.h>
|
||||
#include <winnls.h>
|
||||
#include <wingdi.h>
|
||||
#include <winuser.h>
|
||||
#include <wininet.h>
|
||||
|
@ -64,12 +65,21 @@ cygwin_set_impersonation_token (const HANDLE hToken)
|
|||
void
|
||||
extract_nt_dom_user (const struct passwd *pw, char *domain, char *user)
|
||||
{
|
||||
cygsid psid;
|
||||
DWORD ulen = UNLEN + 1;
|
||||
DWORD dlen = INTERNET_MAX_HOST_NAME_LENGTH + 1;
|
||||
SID_NAME_USE use;
|
||||
char buf[INTERNET_MAX_HOST_NAME_LENGTH + UNLEN + 2];
|
||||
char *c;
|
||||
|
||||
strcpy (domain, "");
|
||||
strcpy (buf, pw->pw_name);
|
||||
debug_printf ("pw_gecos = %x (%s)", pw->pw_gecos, pw->pw_gecos);
|
||||
|
||||
if (psid.getfrompw (pw) &&
|
||||
LookupAccountSid (NULL, psid, user, &ulen, domain, &dlen, &use))
|
||||
return;
|
||||
|
||||
if (pw->pw_gecos)
|
||||
{
|
||||
if ((c = strstr (pw->pw_gecos, "U-")) != NULL &&
|
||||
|
@ -153,7 +163,7 @@ str2buf2uni (UNICODE_STRING &tgt, WCHAR *buf, const char *srcstr)
|
|||
tgt.Length = strlen (srcstr) * sizeof (WCHAR);
|
||||
tgt.MaximumLength = tgt.Length + sizeof(WCHAR);
|
||||
tgt.Buffer = (PWCHAR) buf;
|
||||
mbstowcs (buf, srcstr, tgt.MaximumLength);
|
||||
sys_mbstowcs (buf, srcstr, tgt.MaximumLength);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -219,15 +229,15 @@ get_lsa_srv_inf (LSA_HANDLE lsa, char *logonserver, char *domain)
|
|||
&cnt, &tot, SV_TYPE_DOMAIN_CTRL, primary, NULL))
|
||||
== STATUS_SUCCESS && cnt > 0)
|
||||
{
|
||||
wcstombs (name, buf[0].sv101_name, INTERNET_MAX_HOST_NAME_LENGTH + 1);
|
||||
sys_wcstombs (name, buf[0].sv101_name, INTERNET_MAX_HOST_NAME_LENGTH + 1);
|
||||
if (domain)
|
||||
wcstombs (domain, primary, INTERNET_MAX_HOST_NAME_LENGTH + 1);
|
||||
sys_wcstombs (domain, primary, INTERNET_MAX_HOST_NAME_LENGTH + 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
wcstombs (name, account, INTERNET_MAX_HOST_NAME_LENGTH + 1);
|
||||
sys_wcstombs (name, account, INTERNET_MAX_HOST_NAME_LENGTH + 1);
|
||||
if (domain)
|
||||
wcstombs (domain, account, INTERNET_MAX_HOST_NAME_LENGTH + 1);
|
||||
sys_wcstombs (domain, account, INTERNET_MAX_HOST_NAME_LENGTH + 1);
|
||||
}
|
||||
if (ret == STATUS_SUCCESS)
|
||||
NetApiBufferFree (buf);
|
||||
|
@ -259,7 +269,7 @@ static BOOL
|
|||
get_user_groups (WCHAR *wlogonserver, cygsidlist &grp_list, char *user)
|
||||
{
|
||||
WCHAR wuser[UNLEN + 1];
|
||||
mbstowcs (wuser, user, UNLEN + 1);
|
||||
sys_mbstowcs (wuser, user, UNLEN + 1);
|
||||
LPGROUP_USERS_INFO_0 buf;
|
||||
DWORD cnt, tot;
|
||||
NET_API_STATUS ret;
|
||||
|
@ -282,13 +292,13 @@ get_user_groups (WCHAR *wlogonserver, cygsidlist &grp_list, char *user)
|
|||
DWORD dlen = INTERNET_MAX_HOST_NAME_LENGTH + 1;
|
||||
SID_NAME_USE use = SidTypeInvalid;
|
||||
|
||||
wcstombs (group, buf[i].grui0_name, UNLEN + 1);
|
||||
sys_wcstombs (group, buf[i].grui0_name, UNLEN + 1);
|
||||
if (!LookupAccountName (NULL, group, gsid, &glen, domain, &dlen, &use))
|
||||
debug_printf ("LookupAccountName(%s): %lu\n", group, GetLastError ());
|
||||
if (!legal_sid_type (use))
|
||||
{
|
||||
strcat (strcpy (group, domain), "\\");
|
||||
wcstombs (group + strlen (group), buf[i].grui0_name,
|
||||
sys_wcstombs (group + strlen (group), buf[i].grui0_name,
|
||||
UNLEN + 1 - strlen (group));
|
||||
glen = UNLEN + 1;
|
||||
dlen = INTERNET_MAX_HOST_NAME_LENGTH + 1;
|
||||
|
@ -353,7 +363,7 @@ get_user_local_groups (WCHAR *wlogonserver, const char *logonserver,
|
|||
DWORD dlen = INTERNET_MAX_HOST_NAME_LENGTH + 1;
|
||||
SID_NAME_USE use = SidTypeInvalid;
|
||||
|
||||
wcstombs (group, buf[i].lgrpi0_name, UNLEN + 1);
|
||||
sys_wcstombs (group, buf[i].lgrpi0_name, UNLEN + 1);
|
||||
if (!LookupAccountName (NULL, group, gsid, &glen, domain, &dlen, &use))
|
||||
{
|
||||
glen = UNLEN + 1;
|
||||
|
@ -366,7 +376,7 @@ get_user_local_groups (WCHAR *wlogonserver, const char *logonserver,
|
|||
else if (!legal_sid_type (use))
|
||||
{
|
||||
strcat (strcpy (group, domain), "\\");
|
||||
wcstombs (group + strlen (group), buf[i].lgrpi0_name,
|
||||
sys_wcstombs (group + strlen (group), buf[i].lgrpi0_name,
|
||||
UNLEN + 1 - strlen (group));
|
||||
glen = UNLEN + 1;
|
||||
dlen = INTERNET_MAX_HOST_NAME_LENGTH + 1;
|
||||
|
@ -409,7 +419,7 @@ get_user_primary_group (WCHAR *wlogonserver, const char *user,
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
mbstowcs (wuser, user, UNLEN + 1);
|
||||
sys_mbstowcs (wuser, user, UNLEN + 1);
|
||||
if (NetUserGetInfo (wlogonserver, wuser, 3, (LPBYTE *) &buf))
|
||||
return FALSE;
|
||||
pgrpsid = usersid;
|
||||
|
@ -435,7 +445,7 @@ get_group_sidlist (const char *logonserver, cygsidlist &grp_list,
|
|||
SID_NAME_USE use;
|
||||
|
||||
auth_pos = -1;
|
||||
mbstowcs (wserver, logonserver, INTERNET_MAX_HOST_NAME_LENGTH + 1);
|
||||
sys_mbstowcs (wserver, logonserver, INTERNET_MAX_HOST_NAME_LENGTH + 1);
|
||||
if (!LookupAccountSid (NULL, usersid, user, &ulen, domain, &dlen, &use))
|
||||
{
|
||||
debug_printf ("LookupAccountSid () %E");
|
||||
|
@ -569,7 +579,8 @@ get_priv_list (LSA_HANDLE lsa, cygsid &usersid, cygsidlist &grp_list)
|
|||
PTOKEN_PRIVILEGES tmp;
|
||||
DWORD tmp_count;
|
||||
|
||||
wcstombs (buf, privstrs[i].Buffer, INTERNET_MAX_HOST_NAME_LENGTH + 1);
|
||||
sys_wcstombs (buf, privstrs[i].Buffer,
|
||||
INTERNET_MAX_HOST_NAME_LENGTH + 1);
|
||||
if (!LookupPrivilegeValue (NULL, buf, &priv))
|
||||
continue;
|
||||
|
||||
|
|
|
@ -45,8 +45,8 @@ public:
|
|||
|
||||
inline PSID set () { return psid = (PSID) sbuf; }
|
||||
|
||||
BOOL getfrompw (struct passwd *pw);
|
||||
BOOL getfromgr (struct group *gr);
|
||||
BOOL getfrompw (const struct passwd *pw);
|
||||
BOOL getfromgr (const struct group *gr);
|
||||
|
||||
int get_id (BOOL search_grp, int *type = NULL);
|
||||
inline int get_uid () { return get_id (FALSE); }
|
||||
|
|
|
@ -31,62 +31,61 @@ struct passwd *
|
|||
internal_getlogin (cygheap_user &user)
|
||||
{
|
||||
char username[UNLEN + 1];
|
||||
DWORD username_len = UNLEN + 1;
|
||||
DWORD ulen = UNLEN + 1;
|
||||
struct passwd *pw = NULL;
|
||||
|
||||
if (!GetUserName (username, &username_len))
|
||||
if (!GetUserName (username, &ulen))
|
||||
user.set_name ("unknown");
|
||||
else
|
||||
user.set_name (username);
|
||||
debug_printf ("GetUserName() = %s", user.name ());
|
||||
|
||||
if (os_being_run == winNT)
|
||||
{
|
||||
LPWKSTA_USER_INFO_1 wui;
|
||||
NET_API_STATUS ret;
|
||||
char buf[512];
|
||||
char dom[INTERNET_MAX_HOST_NAME_LENGTH + 1];
|
||||
char *env, *un = NULL;
|
||||
HANDLE ptok = user.token; /* Which is INVALID_HANDLE_VALUE if no
|
||||
impersonation took place. */
|
||||
DWORD siz;
|
||||
cygsid tu;
|
||||
NET_API_STATUS ret = 0;
|
||||
char domain[INTERNET_MAX_HOST_NAME_LENGTH + 1];
|
||||
DWORD dlen = INTERNET_MAX_HOST_NAME_LENGTH + 1;
|
||||
SID_NAME_USE use;
|
||||
char buf[MAX_PATH];
|
||||
|
||||
/* First trying to get logon info from environment */
|
||||
if ((env = getenv ("USERNAME")) != NULL)
|
||||
un = env;
|
||||
if ((env = getenv ("LOGONSERVER")) != NULL)
|
||||
user.set_logsrv (env + 2); /* filter leading double backslashes */
|
||||
if ((env = getenv ("USERDOMAIN")) != NULL)
|
||||
user.set_domain (env);
|
||||
/* Trust only if usernames are identical */
|
||||
if (un && strcasematch (user.name (), un)
|
||||
&& user.domain () && user.logsrv ())
|
||||
debug_printf ("Domain: %s, Logon Server: %s",
|
||||
user.domain (), user.logsrv ());
|
||||
/* If that failed, try to get that info from NetBIOS */
|
||||
else if (!(ret = NetWkstaUserGetInfo (NULL, 1, (LPBYTE *)&wui)))
|
||||
/* 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. */
|
||||
user.set_sid (NO_SID);
|
||||
if (ptok == INVALID_HANDLE_VALUE
|
||||
&& !OpenProcessToken (GetCurrentProcess (),
|
||||
TOKEN_ADJUST_DEFAULT | TOKEN_QUERY,
|
||||
&ptok))
|
||||
debug_printf ("OpenProcessToken(): %E");
|
||||
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!");
|
||||
else if (!LookupAccountSid (NULL, user.sid (), username, &ulen,
|
||||
domain, &dlen, &use))
|
||||
debug_printf ("LookupAccountSid (): %E");
|
||||
else
|
||||
{
|
||||
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);
|
||||
/* Save values in environment */
|
||||
if (!strcasematch (user.name (), "SYSTEM")
|
||||
&& user.domain () && user.logsrv ())
|
||||
{
|
||||
LPUSER_INFO_3 ui = NULL;
|
||||
WCHAR wbuf[INTERNET_MAX_HOST_NAME_LENGTH + 2];
|
||||
|
||||
strcat (strcpy (buf, "\\\\"), user.logsrv ());
|
||||
user.set_name (username);
|
||||
user.set_domain (domain);
|
||||
}
|
||||
if (get_logon_server_and_user_domain (domain, NULL))
|
||||
user.set_logsrv (domain + 2);
|
||||
setenv ("USERNAME", user.name (), 1);
|
||||
setenv ("LOGONSERVER", buf, 1);
|
||||
setenv ("LOGONSERVER", user.logsrv (), 1);
|
||||
setenv ("USERDOMAIN", user.domain (), 1);
|
||||
/* HOMEDRIVE and HOMEPATH are wrong most of the time, too,
|
||||
after changing user context! */
|
||||
sys_mbstowcs (wbuf, buf, INTERNET_MAX_HOST_NAME_LENGTH + 2);
|
||||
if (!NetUserGetInfo (NULL, wui->wkui1_username, 3, (LPBYTE *)&ui)
|
||||
|| !NetUserGetInfo (wbuf,wui->wkui1_username,3,(LPBYTE *)&ui))
|
||||
|
||||
LPUSER_INFO_3 ui;
|
||||
WCHAR wlogsrv[INTERNET_MAX_HOST_NAME_LENGTH + 1];
|
||||
WCHAR wuser[UNLEN + 1];
|
||||
sys_mbstowcs (wlogsrv, user.logsrv (), INTERNET_MAX_HOST_NAME_LENGTH + 1);
|
||||
sys_mbstowcs (wuser, user.name (), UNLEN + 1);
|
||||
if (!NetUserGetInfo (wlogsrv, wuser, 3, (LPBYTE *)&ui) ||
|
||||
!NetUserGetInfo (NULL, wuser, 3, (LPBYTE *)&ui))
|
||||
{
|
||||
sys_wcstombs (buf, ui->usri3_home_dir, MAX_PATH);
|
||||
if (!buf[0])
|
||||
|
@ -96,7 +95,7 @@ internal_getlogin (cygheap_user &user)
|
|||
strcat (buf, "\\");
|
||||
else
|
||||
{
|
||||
env = getenv ("SYSTEMDRIVE");
|
||||
char *env = getenv ("SYSTEMDRIVE");
|
||||
if (env && *env)
|
||||
strcat (strcpy (buf, env), "\\");
|
||||
else
|
||||
|
@ -108,69 +107,11 @@ internal_getlogin (cygheap_user &user)
|
|||
setenv ("HOMEDRIVE", buf, 1);
|
||||
NetApiBufferFree (ui);
|
||||
}
|
||||
}
|
||||
debug_printf ("Domain: %s, Logon Server: %s, Windows Username: %s",
|
||||
user.domain (), user.logsrv (), user.name ());
|
||||
NetApiBufferFree (wui);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* If `NetWkstaUserGetInfo' failed, try to get default values known
|
||||
by local policy object.*/
|
||||
debug_printf ("NetWkstaUserGetInfo() Err %d", ret);
|
||||
|
||||
if (get_logon_server_and_user_domain (buf, dom))
|
||||
{
|
||||
user.set_logsrv (buf + 2);
|
||||
user.set_domain (dom);
|
||||
setenv ("LOGONSERVER", buf, 1);
|
||||
setenv ("USERDOMAIN", dom, 1);
|
||||
}
|
||||
else
|
||||
debug_printf ("get_logon_server_and_user_domain() failed");
|
||||
}
|
||||
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. */
|
||||
cygsid gsid (NO_SID);
|
||||
if (ret)
|
||||
if (user.sid ())
|
||||
{
|
||||
cygsid psid;
|
||||
|
||||
|
@ -179,28 +120,15 @@ internal_getlogin (cygheap_user &user)
|
|||
{
|
||||
user.set_name (pw->pw_name);
|
||||
struct group *gr = getgrgid (pw->pw_gid);
|
||||
if (gr)
|
||||
if (!gsid.getfromgr (gr))
|
||||
if (gr && !gsid.getfromgr (gr))
|
||||
gsid = NO_SID;
|
||||
extract_nt_dom_user (pw, dom, buf);
|
||||
setenv ("USERNAME", buf, 1);
|
||||
if (*dom)
|
||||
user.set_domain (dom);
|
||||
else if (user.logsrv ())
|
||||
user.set_domain (user.logsrv ());
|
||||
if (user.domain ())
|
||||
setenv ("USERDOMAIN", user.domain (), 1);
|
||||
break;
|
||||
}
|
||||
if (!strcasematch (user.name (), "SYSTEM")
|
||||
&& user.domain () && user.logsrv ())
|
||||
{
|
||||
if (!strcasematch (user.name (), "SYSTEM"))
|
||||
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
|
||||
|
@ -220,7 +148,6 @@ internal_getlogin (cygheap_user &user)
|
|||
&& user.token == INVALID_HANDLE_VALUE)
|
||||
CloseHandle (ptok);
|
||||
}
|
||||
}
|
||||
debug_printf ("Cygwins Username: %s", user.name ());
|
||||
return pw ?: getpwnam(user.name ());
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue