* 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:
Corinna Vinschen 2001-04-30 21:19:42 +00:00
parent 965cecdfca
commit 57ff940dd4
8 changed files with 353 additions and 113 deletions

View File

@ -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.

View File

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

View File

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

View File

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

View File

@ -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, &quota, &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

View File

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

View File

@ -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;

View File

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