mirror of
git://sourceware.org/git/newlib-cygwin.git
synced 2025-01-30 02:50:25 +08:00
* autoload.cc: Add LoadDLLinitfunc for secur32.dll.
Add LoadDLLfuncEx statements for AllocateLocallyUniqueId@4, DuplicateTokenEx@24, LsaNtStatusToWinError@4, LsaDeregisterLogonProcess@4, LsaFreeReturnBuffer@4, LsaLogonUser@56, LsaLookupAuthenticationPackage@12, LsaRegisterLogonProcess@12, * environ.cc: Add extern declaration for `subauth_id'. (subauth_id_init): New function for setting `subauth_id'. (struct parse_thing): Add entry for `subauth_id'. * fork.cc (fork_parent): Call `RevertToSelf' and `ImpersonateLoggedOnUser' instead of `seteuid'. * security.cc: Define global variable `subauth_id'. (extract_nt_dom_user): New function. (cygwin_logon_user): Call `extract_nt_dom_user' now. (str2lsa): New static function. (str2buf2lsa): Ditto. (str2buf2uni): Ditto. (subauth): Ditto. * security.h: Add prototype for `subauth'. * spawn.cc (spawn_guts): Use cygheap->user.token only if impersonated. Use `cygsid' type. Remove impersonation before allowing access to workstation/desktop to everyone. Call `RevertToSelf' and `ImpersonateLoggedOnUser' instead of `seteuid'. * syscalls.cc (seteuid): Rearranged to allow using subauthentication to retrieve user tokens when needed.
This commit is contained in:
parent
965cecdfca
commit
57ff940dd4
@ -1,3 +1,31 @@
|
||||
Mon Apr 30 22:09:00 2001 Corinna Vinschen <corinna@vinschen.de>
|
||||
|
||||
* autoload.cc: Add LoadDLLinitfunc for secur32.dll.
|
||||
Add LoadDLLfuncEx statements for AllocateLocallyUniqueId@4,
|
||||
DuplicateTokenEx@24, LsaNtStatusToWinError@4,
|
||||
LsaDeregisterLogonProcess@4, LsaFreeReturnBuffer@4,
|
||||
LsaLogonUser@56, LsaLookupAuthenticationPackage@12,
|
||||
LsaRegisterLogonProcess@12,
|
||||
* environ.cc: Add extern declaration for `subauth_id'.
|
||||
(subauth_id_init): New function for setting `subauth_id'.
|
||||
(struct parse_thing): Add entry for `subauth_id'.
|
||||
* fork.cc (fork_parent): Call `RevertToSelf' and
|
||||
`ImpersonateLoggedOnUser' instead of `seteuid'.
|
||||
* security.cc: Define global variable `subauth_id'.
|
||||
(extract_nt_dom_user): New function.
|
||||
(cygwin_logon_user): Call `extract_nt_dom_user' now.
|
||||
(str2lsa): New static function.
|
||||
(str2buf2lsa): Ditto.
|
||||
(str2buf2uni): Ditto.
|
||||
(subauth): Ditto.
|
||||
* security.h: Add prototype for `subauth'.
|
||||
* spawn.cc (spawn_guts): Use cygheap->user.token only if impersonated.
|
||||
Use `cygsid' type. Remove impersonation before allowing access to
|
||||
workstation/desktop to everyone. Call `RevertToSelf' and
|
||||
`ImpersonateLoggedOnUser' instead of `seteuid'.
|
||||
* syscalls.cc (seteuid): Rearranged to allow using subauthentication
|
||||
to retrieve user tokens when needed.
|
||||
|
||||
Mon Apr 30 20:26:00 2001 Corinna Vinschen <corinna@vinschen.de>
|
||||
|
||||
* uinfo.cc (internal_getlogin): Formatting change.
|
||||
|
@ -129,6 +129,28 @@ LoadDLLinitfunc (ntdll)
|
||||
return 0;
|
||||
}
|
||||
|
||||
LoadDLLinitfunc (secur32)
|
||||
{
|
||||
HANDLE h;
|
||||
static NO_COPY LONG here = -1L;
|
||||
|
||||
while (InterlockedIncrement (&here))
|
||||
{
|
||||
InterlockedDecrement (&here);
|
||||
Sleep (0);
|
||||
}
|
||||
|
||||
if (secur32_handle)
|
||||
/* nothing to do */;
|
||||
else if ((h = LoadLibrary ("secur32.dll")) != NULL)
|
||||
secur32_handle = h;
|
||||
else if (!secur32_handle)
|
||||
api_fatal ("could not load secur32.dll, %E");
|
||||
|
||||
InterlockedDecrement (&here);
|
||||
return 0; /* Already done by another thread? */
|
||||
}
|
||||
|
||||
LoadDLLinitfunc (user32)
|
||||
{
|
||||
HANDLE h;
|
||||
@ -271,12 +293,14 @@ LoadDLLfunc (AddAccessAllowedAce, 16, advapi32)
|
||||
LoadDLLfunc (AddAccessDeniedAce, 16, advapi32)
|
||||
LoadDLLfunc (AddAce, 20, advapi32)
|
||||
LoadDLLfunc (AdjustTokenPrivileges, 24, advapi32)
|
||||
LoadDLLfuncEx (AllocateLocallyUniqueId, 4, advapi32, 1)
|
||||
LoadDLLfunc (CopySid, 12, advapi32)
|
||||
LoadDLLfunc (CreateProcessAsUserA, 44, advapi32)
|
||||
LoadDLLfuncEx (CryptAcquireContextA, 20, advapi32, 1)
|
||||
LoadDLLfuncEx (CryptGenRandom, 12, advapi32, 1)
|
||||
LoadDLLfuncEx (CryptReleaseContext, 8, advapi32, 1)
|
||||
LoadDLLfunc (DeregisterEventSource, 4, advapi32)
|
||||
LoadDLLfuncEx (DuplicateTokenEx, 24, advapi32, 1)
|
||||
LoadDLLfunc (EqualSid, 8, advapi32)
|
||||
LoadDLLfunc (GetAce, 12, advapi32)
|
||||
LoadDLLfunc (GetFileSecurityA, 20, advapi32)
|
||||
@ -298,6 +322,7 @@ LoadDLLfunc (LogonUserA, 24, advapi32)
|
||||
LoadDLLfunc (LookupAccountNameA, 28, advapi32)
|
||||
LoadDLLfunc (LookupAccountSidA, 28, advapi32)
|
||||
LoadDLLfunc (LookupPrivilegeValueA, 12, advapi32)
|
||||
LoadDLLfuncEx (LsaNtStatusToWinError, 4, advapi32, 1)
|
||||
LoadDLLfunc (MakeSelfRelativeSD, 12, advapi32)
|
||||
LoadDLLfunc (OpenProcessToken, 12, advapi32)
|
||||
LoadDLLfunc (RegCloseKey, 4, advapi32)
|
||||
@ -334,6 +359,13 @@ LoadDLLfuncEx (RtlInitUnicodeString, 8, ntdll, 1)
|
||||
LoadDLLfuncEx (RtlNtStatusToDosError, 4, ntdll, 1)
|
||||
LoadDLLfuncEx (ZwQuerySystemInformation, 16, ntdll, 1)
|
||||
|
||||
LoadDLLinit (secur32)
|
||||
LoadDLLfuncEx (LsaDeregisterLogonProcess, 4, secur32, 1)
|
||||
LoadDLLfuncEx (LsaFreeReturnBuffer, 4, secur32, 1)
|
||||
LoadDLLfuncEx (LsaLogonUser, 56, secur32, 1)
|
||||
LoadDLLfuncEx (LsaLookupAuthenticationPackage, 12, secur32, 1)
|
||||
LoadDLLfuncEx (LsaRegisterLogonProcess, 12, secur32, 1)
|
||||
|
||||
LoadDLLinit (user32)
|
||||
LoadDLLfunc (CharToOemA, 8, user32)
|
||||
LoadDLLfunc (CharToOemBuffA, 12, user32)
|
||||
|
@ -35,6 +35,7 @@ extern BOOL allow_winsymlinks;
|
||||
extern BOOL strip_title_path;
|
||||
extern int pcheck_case;
|
||||
extern DWORD chunksize;
|
||||
extern int subauth_id;
|
||||
BOOL reset_com = TRUE;
|
||||
static BOOL envcache = TRUE;
|
||||
|
||||
@ -446,6 +447,19 @@ codepage_init (const char *buf)
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
subauth_id_init (const char *buf)
|
||||
{
|
||||
if (!buf || !*buf)
|
||||
return;
|
||||
|
||||
int i = strtol (buf, NULL, 0);
|
||||
|
||||
/* 0..127 are reserved by Microsoft, 132 is IIS subauthentication. */
|
||||
if (i > 127 && i != 132 && i <= 255)
|
||||
subauth_id = i;
|
||||
}
|
||||
|
||||
/* The structure below is used to set up an array which is used to
|
||||
parse the CYGWIN environment variable or, if enabled, options from
|
||||
the registry. */
|
||||
@ -482,6 +496,7 @@ struct parse_thing
|
||||
{"smbntsec", {&allow_smbntsec}, justset, NULL, {{FALSE}, {TRUE}}},
|
||||
{"reset_com", {&reset_com}, justset, NULL, {{FALSE}, {TRUE}}},
|
||||
{"strip_title", {&strip_title_path}, justset, NULL, {{FALSE}, {TRUE}}},
|
||||
{"subauth_id", {func: &subauth_id_init}, isfunc, NULL, {{0}, {0}}},
|
||||
{"title", {&display_title}, justset, NULL, {{FALSE}, {TRUE}}},
|
||||
{"tty", {NULL}, set_process_state, NULL, {{0}, {PID_USETTY}}},
|
||||
{"winsymlinks", {&allow_winsymlinks}, justset, NULL, {{FALSE}, {TRUE}}},
|
||||
|
@ -436,7 +436,7 @@ fork_parent (void *stack_here, HANDLE& hParent, dll *&first_dll,
|
||||
uid_t uid;
|
||||
uid = geteuid();
|
||||
if (cygheap->user.impersonated && cygheap->user.token != INVALID_HANDLE_VALUE)
|
||||
seteuid (cygheap->user.orig_uid);
|
||||
RevertToSelf ();
|
||||
|
||||
ch.parent = hParent;
|
||||
ch.cygheap = cygheap;
|
||||
@ -484,7 +484,7 @@ out:
|
||||
/* Restore impersonation */
|
||||
if (cygheap->user.impersonated
|
||||
&& cygheap->user.token != INVALID_HANDLE_VALUE)
|
||||
seteuid (uid);
|
||||
ImpersonateLoggedOnUser (cygheap->user.token);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -508,7 +508,7 @@ out:
|
||||
|
||||
/* Restore impersonation */
|
||||
if (cygheap->user.impersonated && cygheap->user.token != INVALID_HANDLE_VALUE)
|
||||
seteuid (uid);
|
||||
ImpersonateLoggedOnUser (cygheap->user.token);
|
||||
|
||||
ProtectHandle (pi.hThread);
|
||||
/* Protect the handle but name it similarly to the way it will
|
||||
|
@ -24,6 +24,9 @@ details. */
|
||||
#include <ctype.h>
|
||||
#include <wingdi.h>
|
||||
#include <winuser.h>
|
||||
#include <wininet.h>
|
||||
#include <ntsecapi.h>
|
||||
#include <subauth.h>
|
||||
#include "cygerrno.h"
|
||||
#include "perprocess.h"
|
||||
#include "fhandler.h"
|
||||
@ -56,6 +59,39 @@ cygwin_set_impersonation_token (const HANDLE hToken)
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
extract_nt_dom_user (const struct passwd *pw, char *domain, char *user)
|
||||
{
|
||||
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 (pw->pw_gecos)
|
||||
{
|
||||
if ((c = strstr (pw->pw_gecos, "U-")) != NULL &&
|
||||
(c == pw->pw_gecos || c[-1] == ','))
|
||||
{
|
||||
buf[0] = '\0';
|
||||
strncat (buf, c + 2, INTERNET_MAX_HOST_NAME_LENGTH + UNLEN + 1);
|
||||
if ((c = strchr (buf, ',')) != NULL)
|
||||
*c = '\0';
|
||||
}
|
||||
}
|
||||
if ((c = strchr (buf, '\\')) != NULL)
|
||||
{
|
||||
*c++ = '\0';
|
||||
strcpy (domain, buf);
|
||||
strcpy (user, c);
|
||||
}
|
||||
else
|
||||
{
|
||||
strcpy (domain, "");
|
||||
strcpy (user, buf);
|
||||
}
|
||||
}
|
||||
|
||||
extern "C"
|
||||
HANDLE
|
||||
cygwin_logon_user (const struct passwd *pw, const char *password)
|
||||
@ -71,32 +107,13 @@ cygwin_logon_user (const struct passwd *pw, const char *password)
|
||||
return INVALID_HANDLE_VALUE;
|
||||
}
|
||||
|
||||
char *c, *nt_user, *nt_domain = NULL;
|
||||
char usernamebuf[256];
|
||||
char nt_domain[INTERNET_MAX_HOST_NAME_LENGTH + 1];
|
||||
char nt_user[UNLEN + 1];
|
||||
HANDLE hToken;
|
||||
|
||||
strcpy (usernamebuf, pw->pw_name);
|
||||
debug_printf ("pw_gecos = %x (%s)", pw->pw_gecos, pw->pw_gecos);
|
||||
if (pw->pw_gecos)
|
||||
{
|
||||
if ((c = strstr (pw->pw_gecos, "U-")) != NULL &&
|
||||
(c == pw->pw_gecos || c[-1] == ','))
|
||||
{
|
||||
usernamebuf[0] = '\0';
|
||||
strncat (usernamebuf, c + 2, 255);
|
||||
if ((c = strchr (usernamebuf, ',')) != NULL)
|
||||
*c = '\0';
|
||||
}
|
||||
}
|
||||
nt_user = usernamebuf;
|
||||
if ((c = strchr (nt_user, '\\')) != NULL)
|
||||
{
|
||||
nt_domain = nt_user;
|
||||
*c = '\0';
|
||||
nt_user = c + 1;
|
||||
}
|
||||
extract_nt_dom_user (pw, nt_domain, nt_user);
|
||||
debug_printf ("LogonUserA (%s, %s, %s, ...)", nt_user, nt_domain, password);
|
||||
if (!LogonUserA (nt_user, nt_domain, (char *) password,
|
||||
if (!LogonUserA (nt_user, *nt_domain ? nt_domain : NULL, (char *) password,
|
||||
LOGON32_LOGON_INTERACTIVE,
|
||||
LOGON32_PROVIDER_DEFAULT,
|
||||
&hToken)
|
||||
@ -111,6 +128,126 @@ cygwin_logon_user (const struct passwd *pw, const char *password)
|
||||
return hToken;
|
||||
}
|
||||
|
||||
static void
|
||||
str2lsa (LSA_STRING &tgt, const char *srcstr)
|
||||
{
|
||||
tgt.Length = strlen(srcstr);
|
||||
tgt.MaximumLength = tgt.Length + 1;
|
||||
tgt.Buffer = (PCHAR) srcstr;
|
||||
}
|
||||
|
||||
static void
|
||||
str2buf2lsa (LSA_STRING &tgt, char *buf, const char *srcstr)
|
||||
{
|
||||
tgt.Length = strlen(srcstr);
|
||||
tgt.MaximumLength = tgt.Length + 1;
|
||||
tgt.Buffer = (PCHAR) buf;
|
||||
memcpy(buf, srcstr, tgt.MaximumLength);
|
||||
}
|
||||
|
||||
static void
|
||||
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);
|
||||
}
|
||||
|
||||
int subauth_id = 255;
|
||||
|
||||
HANDLE
|
||||
subauth (struct passwd *pw)
|
||||
{
|
||||
LSA_STRING name;
|
||||
HANDLE lsa_hdl;
|
||||
LSA_OPERATIONAL_MODE sec_mode;
|
||||
NTSTATUS ret, ret2;
|
||||
ULONG package_id, size;
|
||||
struct {
|
||||
LSA_STRING str;
|
||||
CHAR buf[16];
|
||||
} origin;
|
||||
struct {
|
||||
MSV1_0_LM20_LOGON auth;
|
||||
WCHAR dombuf[INTERNET_MAX_HOST_NAME_LENGTH + 1];
|
||||
WCHAR usrbuf[UNLEN + 1];
|
||||
WCHAR wkstbuf[1];
|
||||
CHAR authinf1[1];
|
||||
CHAR authinf2[1];
|
||||
} subbuf;
|
||||
TOKEN_SOURCE ts;
|
||||
PMSV1_0_LM20_LOGON_PROFILE profile;
|
||||
LUID luid;
|
||||
HANDLE user_token;
|
||||
QUOTA_LIMITS quota;
|
||||
char nt_domain[INTERNET_MAX_HOST_NAME_LENGTH + 1];
|
||||
char nt_user[UNLEN + 1];
|
||||
|
||||
set_process_privilege(SE_TCB_NAME);
|
||||
|
||||
/* Register as logon process. */
|
||||
str2lsa (name, "Cygwin");
|
||||
ret = LsaRegisterLogonProcess(&name, &lsa_hdl, &sec_mode);
|
||||
if (ret != STATUS_SUCCESS)
|
||||
{
|
||||
debug_printf ("LsaRegisterLogonProcess: %d", ret);
|
||||
set_errno (LsaNtStatusToWinError(ret));
|
||||
return INVALID_HANDLE_VALUE;
|
||||
}
|
||||
/* Get handle to MSV1_0 package. */
|
||||
str2lsa (name, MSV1_0_PACKAGE_NAME);
|
||||
ret = LsaLookupAuthenticationPackage(lsa_hdl, &name, &package_id);
|
||||
if (ret != STATUS_SUCCESS)
|
||||
{
|
||||
debug_printf ("LsaLookupAuthenticationPackage: %d", ret);
|
||||
set_errno (LsaNtStatusToWinError(ret));
|
||||
LsaDeregisterLogonProcess(lsa_hdl);
|
||||
return INVALID_HANDLE_VALUE;
|
||||
}
|
||||
/* Create origin. */
|
||||
str2buf2lsa (origin.str, origin.buf, "Cygwin");
|
||||
/* Create token source. */
|
||||
memcpy(ts.SourceName, "Cygwin.1", 8);
|
||||
AllocateLocallyUniqueId(&ts.SourceIdentifier);
|
||||
/* Get user information. */
|
||||
extract_nt_dom_user (pw, nt_domain, nt_user);
|
||||
/* Fill subauth with values. */
|
||||
subbuf.auth.MessageType = MsV1_0NetworkLogon;
|
||||
str2buf2uni(subbuf.auth.LogonDomainName, subbuf.dombuf, nt_domain);
|
||||
str2buf2uni(subbuf.auth.UserName, subbuf.usrbuf, nt_user);
|
||||
str2buf2uni(subbuf.auth.Workstation, subbuf.wkstbuf, "");
|
||||
memcpy(subbuf.auth.ChallengeToClient, "12345678", MSV1_0_CHALLENGE_LENGTH);
|
||||
str2buf2lsa(subbuf.auth.CaseSensitiveChallengeResponse, subbuf.authinf1, "");
|
||||
str2buf2lsa(subbuf.auth.CaseInsensitiveChallengeResponse, subbuf.authinf2,"");
|
||||
subbuf.auth.ParameterControl = 0 | (subauth_id << 24);
|
||||
/* Try to logon... */
|
||||
ret = LsaLogonUser(lsa_hdl, (PLSA_STRING) &origin, Network,
|
||||
package_id, &subbuf, sizeof subbuf,
|
||||
NULL, &ts, (PVOID *)&profile, &size,
|
||||
&luid, &user_token, "a, &ret2);
|
||||
if (ret != STATUS_SUCCESS)
|
||||
{
|
||||
debug_printf ("LsaLogonUser: %d", ret);
|
||||
set_errno (LsaNtStatusToWinError(ret));
|
||||
LsaDeregisterLogonProcess(lsa_hdl);
|
||||
return INVALID_HANDLE_VALUE;
|
||||
}
|
||||
LsaFreeReturnBuffer(profile);
|
||||
/* Convert to primary token. */
|
||||
SECURITY_ATTRIBUTES sa = { sizeof sa, NULL, TRUE };
|
||||
HANDLE primary_token;
|
||||
if (!DuplicateTokenEx (user_token, TOKEN_ALL_ACCESS, &sa,
|
||||
SecurityImpersonation, TokenPrimary,
|
||||
&primary_token))
|
||||
{
|
||||
CloseHandle (user_token);
|
||||
return INVALID_HANDLE_VALUE;
|
||||
}
|
||||
CloseHandle (user_token);
|
||||
return primary_token;
|
||||
}
|
||||
|
||||
/* read_sd reads a security descriptor from a file.
|
||||
In case of error, -1 is returned and errno is set.
|
||||
If sd_buf is too small, 0 is returned and sd_size
|
||||
|
@ -66,6 +66,8 @@ LONG __stdcall write_sd(const char *file, PSECURITY_DESCRIPTOR sd_buf, DWORD sd_
|
||||
BOOL __stdcall add_access_allowed_ace (PACL acl, int offset, DWORD attributes, PSID sid, size_t &len_add, DWORD inherit);
|
||||
BOOL __stdcall add_access_denied_ace (PACL acl, int offset, DWORD attributes, PSID sid, size_t &len_add, DWORD inherit);
|
||||
|
||||
/* Try a subauthentication. */
|
||||
HANDLE subauth (struct passwd *pw);
|
||||
|
||||
/* sec_helper.cc: Security helper functions. */
|
||||
char *__stdcall convert_sid_to_string_sid (PSID psid, char *sid_str);
|
||||
|
@ -578,7 +578,8 @@ skip_arg_parsing:
|
||||
/* Preallocated buffer for `sec_user' call */
|
||||
char sa_buf[1024];
|
||||
|
||||
if (!hToken && cygheap->user.token != INVALID_HANDLE_VALUE)
|
||||
if (!hToken && cygheap->user.impersonated
|
||||
&& cygheap->user.token != INVALID_HANDLE_VALUE)
|
||||
hToken = cygheap->user.token;
|
||||
|
||||
const char *runpath = null_app_name ? NULL : (const char *) real_path;
|
||||
@ -607,6 +608,28 @@ skip_arg_parsing:
|
||||
}
|
||||
else
|
||||
{
|
||||
cygsid sid;
|
||||
DWORD ret_len;
|
||||
if (!GetTokenInformation (hToken, TokenUser, &sid, sizeof sid, &ret_len))
|
||||
{
|
||||
sid = NULL;
|
||||
system_printf ("GetTokenInformation: %E");
|
||||
}
|
||||
|
||||
/* Retrieve security attributes before setting psid to NULL
|
||||
since it's value is needed by `sec_user'. */
|
||||
PSECURITY_ATTRIBUTES sec_attribs = allow_ntsec && sid
|
||||
? sec_user (sa_buf, sid)
|
||||
: &sec_all_nih;
|
||||
|
||||
/* Remove impersonation */
|
||||
if (cygheap->user.impersonated
|
||||
&& cygheap->user.token != INVALID_HANDLE_VALUE)
|
||||
RevertToSelf ();
|
||||
|
||||
/* Load users registry hive. */
|
||||
load_registry_hive (sid);
|
||||
|
||||
/* allow the child to interact with our window station/desktop */
|
||||
HANDLE hwst, hdsk;
|
||||
SECURITY_INFORMATION dsi = DACL_SECURITY_INFORMATION;
|
||||
@ -625,31 +648,6 @@ skip_arg_parsing:
|
||||
strcat (wstname, dskname);
|
||||
si.lpDesktop = wstname;
|
||||
|
||||
char tu[1024];
|
||||
PSID sid = NULL;
|
||||
DWORD ret_len;
|
||||
if (GetTokenInformation (hToken, TokenUser,
|
||||
(LPVOID) &tu, sizeof tu,
|
||||
&ret_len))
|
||||
sid = ((TOKEN_USER *) &tu)->User.Sid;
|
||||
else
|
||||
system_printf ("GetTokenInformation: %E");
|
||||
|
||||
/* Retrieve security attributes before setting psid to NULL
|
||||
since it's value is needed by `sec_user'. */
|
||||
PSECURITY_ATTRIBUTES sec_attribs = allow_ntsec && sid
|
||||
? sec_user (sa_buf, sid)
|
||||
: &sec_all_nih;
|
||||
|
||||
/* Remove impersonation */
|
||||
uid_t uid = geteuid ();
|
||||
if (cygheap->user.impersonated
|
||||
&& cygheap->user.token != INVALID_HANDLE_VALUE)
|
||||
seteuid (cygheap->user.orig_uid);
|
||||
|
||||
/* Load users registry hive. */
|
||||
load_registry_hive (sid);
|
||||
|
||||
rc = CreateProcessAsUser (hToken,
|
||||
runpath, /* image name - with full path */
|
||||
one_line.buf, /* what was passed to exec */
|
||||
@ -666,7 +664,7 @@ skip_arg_parsing:
|
||||
if (mode != _P_OVERLAY && mode != _P_VFORK
|
||||
&& cygheap->user.impersonated
|
||||
&& cygheap->user.token != INVALID_HANDLE_VALUE)
|
||||
seteuid (uid);
|
||||
ImpersonateLoggedOnUser (cygheap->user.token);
|
||||
}
|
||||
|
||||
MALLOC_CHECK;
|
||||
|
@ -1964,68 +1964,96 @@ seteuid (uid_t uid)
|
||||
}
|
||||
|
||||
if (uid != myself->uid)
|
||||
if (uid == cygheap->user.orig_uid)
|
||||
{
|
||||
debug_printf ("RevertToSelf () (uid == orig_uid, token=%d)",
|
||||
cygheap->user.token);
|
||||
RevertToSelf ();
|
||||
if (cygheap->user.token != INVALID_HANDLE_VALUE)
|
||||
cygheap->user.impersonated = FALSE;
|
||||
}
|
||||
else if (!cygheap->user.impersonated)
|
||||
{
|
||||
debug_printf ("Impersonate (uid == %d)", uid);
|
||||
RevertToSelf ();
|
||||
if (cygheap->user.token != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
struct group *gr;
|
||||
cygsid sid;
|
||||
DWORD siz;
|
||||
|
||||
/* Try setting owner to same value as user. */
|
||||
if (!GetTokenInformation (cygheap->user.token, TokenUser,
|
||||
&sid, sizeof sid, &siz))
|
||||
debug_printf ("GetTokenInformation(): %E");
|
||||
else if (!SetTokenInformation (cygheap->user.token,
|
||||
TokenOwner,
|
||||
&sid, sizeof sid))
|
||||
debug_printf ("SetTokenInformation(user.token, "
|
||||
"TokenOwner): %E");
|
||||
/* Try setting primary group in token to current group. */
|
||||
if ((gr = getgrgid (myself->gid)) &&
|
||||
get_gr_sid (sid, gr) &&
|
||||
!SetTokenInformation (cygheap->user.token,
|
||||
TokenPrimaryGroup,
|
||||
&sid, sizeof sid))
|
||||
debug_printf ("SetTokenInformation(user.token, "
|
||||
"TokenPrimaryGroup): %E");
|
||||
|
||||
/* Now try to impersonate. */
|
||||
if (!ImpersonateLoggedOnUser (cygheap->user.token))
|
||||
system_printf ("Impersonate (%d) in set(e)uid failed: %E",
|
||||
cygheap->user.token);
|
||||
else
|
||||
cygheap->user.impersonated = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
cygheap_user user;
|
||||
/* user.token is used in internal_getlogin () to determine if
|
||||
impersonation is active. If so, the token is used for
|
||||
retrieving user's SID. */
|
||||
user.token = cygheap->user.impersonated ? cygheap->user.token
|
||||
: INVALID_HANDLE_VALUE;
|
||||
struct passwd *pw_cur = internal_getlogin (user);
|
||||
if (pw_cur != pw_new)
|
||||
{
|
||||
debug_printf ("Diffs!!! token: %d, cur: %d, new: %d, orig: %d",
|
||||
cygheap->user.token, pw_cur->pw_uid,
|
||||
pw_new->pw_uid, cygheap->user.orig_uid);
|
||||
set_errno (EPERM);
|
||||
return -1;
|
||||
if (uid == cygheap->user.orig_uid)
|
||||
{
|
||||
debug_printf ("RevertToSelf () (uid == orig_uid, token=%d)",
|
||||
cygheap->user.token);
|
||||
RevertToSelf ();
|
||||
if (cygheap->user.token != INVALID_HANDLE_VALUE)
|
||||
cygheap->user.impersonated = FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
cygsid tsid, psid, gsid;
|
||||
DWORD siz;
|
||||
|
||||
/* Check if new user == user of impersonation token. */
|
||||
if (cygheap->user.token != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
if (!GetTokenInformation (cygheap->user.token, TokenUser,
|
||||
&tsid, sizeof tsid, &siz))
|
||||
debug_printf ("GetTokenInformation(): %E");
|
||||
else if (get_pw_sid (psid, pw_new) && tsid != psid)
|
||||
{
|
||||
/* If not, RevertToSelf and close old token. */
|
||||
RevertToSelf ();
|
||||
cygwin_set_impersonation_token (INVALID_HANDLE_VALUE);
|
||||
}
|
||||
}
|
||||
/* If no impersonation token is available, try to
|
||||
authenticate using subauthentication. */
|
||||
if (cygheap->user.token == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
HANDLE ptok = subauth (pw_new);
|
||||
if (ptok != INVALID_HANDLE_VALUE)
|
||||
cygwin_set_impersonation_token (ptok);
|
||||
else
|
||||
cygheap->user.impersonated = TRUE;
|
||||
}
|
||||
/* If no impersonation is active but an impersonation
|
||||
token is available, try to impersonate. */
|
||||
if (!cygheap->user.impersonated)
|
||||
{
|
||||
debug_printf ("Impersonate (uid == %d)", uid);
|
||||
RevertToSelf ();
|
||||
if (cygheap->user.token != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
struct group *gr;
|
||||
|
||||
/* Try setting owner to same value as user. */
|
||||
if (!SetTokenInformation (cygheap->user.token,
|
||||
TokenOwner,
|
||||
&tsid, sizeof tsid))
|
||||
debug_printf ("SetTokenInformation(user.token, "
|
||||
"TokenOwner): %E");
|
||||
/* Try setting primary group in token to current group. */
|
||||
if ((gr = getgrgid (myself->gid)) &&
|
||||
get_gr_sid (gsid, gr) &&
|
||||
!SetTokenInformation (cygheap->user.token,
|
||||
TokenPrimaryGroup,
|
||||
&gsid, sizeof gsid))
|
||||
debug_printf ("SetTokenInformation(user.token, "
|
||||
"TokenPrimaryGroup): %E");
|
||||
|
||||
/* Now try to impersonate. */
|
||||
if (!ImpersonateLoggedOnUser (cygheap->user.token))
|
||||
system_printf ("Impersonating (%d) in set(e)uid "
|
||||
"failed: %E", cygheap->user.token);
|
||||
else
|
||||
cygheap->user.impersonated = TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cygheap_user user;
|
||||
/* user.token is used in internal_getlogin () to determine if
|
||||
impersonation is active. If so, the token is used for
|
||||
retrieving user's SID. */
|
||||
user.token = cygheap->user.impersonated ? cygheap->user.token
|
||||
: INVALID_HANDLE_VALUE;
|
||||
struct passwd *pw_cur = internal_getlogin (user);
|
||||
if (pw_cur != pw_new)
|
||||
{
|
||||
debug_printf ("Diffs!!! token: %d, cur: %d, new: %d, orig: %d",
|
||||
cygheap->user.token, pw_cur->pw_uid,
|
||||
pw_new->pw_uid, cygheap->user.orig_uid);
|
||||
set_errno (EPERM);
|
||||
return -1;
|
||||
}
|
||||
myself->uid = uid;
|
||||
cygheap->user = user;
|
||||
}
|
||||
myself->uid = uid;
|
||||
cygheap->user = user;
|
||||
}
|
||||
}
|
||||
else
|
||||
|
Loading…
x
Reference in New Issue
Block a user