* security.cc: Change some formatting.
* include/cygwin/version.h: Bump API minor version. * cygheap.h (class cygheap_user): Add member groups. * security.h (class cygsidlist): Add members type and maxcount, methods position, addfromgr, alloc_sids and free_sids and operator+= (const PSID psid). Modify contains () to call position () and optimize add () to use maxcount. (class user_groups): Create. Update declarations of verify_token and create_token. * security.cc (cygsidlist::alloc_sids): New. (cygsidlist::free_sids): New. (get_token_group_sidlist): Create from get_group_sidlist. (get_initgroups_sidlist): Create from get_group_sidlist. (get_group_sidlist): Suppress. (get_setgroups_sidlist): Create. (verify_token): Modify arguments. Add setgroups case. (create_token): Modify arguments. Call get_initgroups_sidlist and get_setgroups_sidlist as needed. Set SE_GROUP_LOGON_ID from auth_pos outside of the loop. Rename the various group sid lists consistently. * syscalls.cc (seteuid32): Modify to use cygheap->user.groups. (setegid32): Call cygheap->user.groups.update_pgrp. * grp.cc (setgroups): Create. (setgroups32): Create. * uinfo.cc (internal_getlogin): Initialize and update user.groups.pgsid. * cygwin.din: Add setgroups and setgroups32.
This commit is contained in:
parent
eb5720f255
commit
5519d54352
@ -1,3 +1,34 @@
|
||||
2002-07-29 Corinna Vinschen <corinna@vinschen.de>
|
||||
|
||||
* security.cc: Change some formatting.
|
||||
* include/cygwin/version.h: Bump API minor version.
|
||||
|
||||
2002-07-28 Pierre Humblet <Pierre.Humblet@ieee.org>
|
||||
|
||||
* cygheap.h (class cygheap_user): Add member groups.
|
||||
* security.h (class cygsidlist): Add members type and maxcount,
|
||||
methods position, addfromgr, alloc_sids and free_sids and
|
||||
operator+= (const PSID psid). Modify contains () to call
|
||||
position () and optimize add () to use maxcount.
|
||||
(class user_groups): Create.
|
||||
Update declarations of verify_token and create_token.
|
||||
* security.cc (cygsidlist::alloc_sids): New.
|
||||
(cygsidlist::free_sids): New.
|
||||
(get_token_group_sidlist): Create from get_group_sidlist.
|
||||
(get_initgroups_sidlist): Create from get_group_sidlist.
|
||||
(get_group_sidlist): Suppress.
|
||||
(get_setgroups_sidlist): Create.
|
||||
(verify_token): Modify arguments. Add setgroups case.
|
||||
(create_token): Modify arguments. Call get_initgroups_sidlist and
|
||||
get_setgroups_sidlist as needed. Set SE_GROUP_LOGON_ID from auth_pos
|
||||
outside of the loop. Rename the various group sid lists consistently.
|
||||
* syscalls.cc (seteuid32): Modify to use cygheap->user.groups.
|
||||
(setegid32): Call cygheap->user.groups.update_pgrp.
|
||||
* grp.cc (setgroups): Create.
|
||||
(setgroups32): Create.
|
||||
* uinfo.cc (internal_getlogin): Initialize and update user.groups.pgsid.
|
||||
* cygwin.din: Add setgroups and setgroups32.
|
||||
|
||||
2002-07-28 Christopher Faylor <cgf@redhat.com>
|
||||
|
||||
* fhandler_console.cc (fhandler_console::read): Use appropriate
|
||||
|
@ -113,6 +113,7 @@ public:
|
||||
__gid32_t orig_gid; /* Ditto */
|
||||
__uid32_t real_uid; /* Remains intact on seteuid, replaced by setuid */
|
||||
__gid32_t real_gid; /* Ditto */
|
||||
user_groups groups; /* Primary and supp SIDs */
|
||||
|
||||
/* token is needed if set(e)uid should be called. It can be set by a call
|
||||
to `set_impersonation_token()'. */
|
||||
|
@ -678,6 +678,9 @@ _setdtablesize = setdtablesize
|
||||
setgid
|
||||
_setgid = setgid
|
||||
setgid32
|
||||
setgroups
|
||||
_setgroups = setgroups
|
||||
setgroups32
|
||||
setjmp
|
||||
_setjmp = setjmp
|
||||
setlocale
|
||||
|
@ -457,3 +457,64 @@ initgroups (const char *, __gid16_t)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* setgroups32: standards? */
|
||||
extern "C"
|
||||
int
|
||||
setgroups32 (int ngroups, const __gid32_t *grouplist)
|
||||
{
|
||||
if (ngroups < 0 || (ngroups > 0 && !grouplist))
|
||||
{
|
||||
set_errno (EINVAL);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!wincap.has_security ())
|
||||
return 0;
|
||||
|
||||
cygsidlist gsids (cygsidlist_alloc, ngroups);
|
||||
struct __group32 *gr;
|
||||
|
||||
if (ngroups && !gsids.sids)
|
||||
return -1;
|
||||
|
||||
for (int gidx = 0; gidx < ngroups; ++gidx)
|
||||
{
|
||||
for (int gidy = 0; gidy < gidx; gidy++)
|
||||
if (grouplist[gidy] == grouplist[gidx])
|
||||
goto found; /* Duplicate */
|
||||
for (int gidy = 0; (gr = internal_getgrent (gidy)); ++gidy)
|
||||
if (gr->gr_gid == (__gid32_t) grouplist[gidx])
|
||||
{
|
||||
if (gsids.addfromgr (gr))
|
||||
goto found;
|
||||
break;
|
||||
}
|
||||
debug_printf ("No sid found for gid %d", grouplist[gidx]);
|
||||
gsids.free_sids ();
|
||||
set_errno (EINVAL);
|
||||
return -1;
|
||||
found:
|
||||
continue;
|
||||
}
|
||||
cygheap->user.groups.update_supp (gsids);
|
||||
return 0;
|
||||
}
|
||||
|
||||
extern "C"
|
||||
int
|
||||
setgroups (int ngroups, const __gid16_t *grouplist)
|
||||
{
|
||||
__gid32_t *grouplist32 = NULL;
|
||||
|
||||
if (ngroups > 0 && grouplist)
|
||||
{
|
||||
grouplist32 = (__gid32_t *) alloca (ngroups * sizeof (__gid32_t));
|
||||
if (grouplist32 == NULL)
|
||||
return -1;
|
||||
for (int i = 0; i < ngroups; i++)
|
||||
grouplist32[i] = grouplist[i];
|
||||
}
|
||||
return setgroups32 (ngroups, grouplist32);
|
||||
|
||||
}
|
||||
|
@ -154,12 +154,13 @@ details. */
|
||||
54: Export __fpclassifyd, __fpclassifyf, __signbitd, __signbitf.
|
||||
55: Export fcloseall, fcloseall_r.
|
||||
56: Make ntsec on by default.
|
||||
57: Export setgroups.
|
||||
*/
|
||||
|
||||
/* Note that we forgot to bump the api for ualarm, strtoll, strtoull */
|
||||
|
||||
#define CYGWIN_VERSION_API_MAJOR 0
|
||||
#define CYGWIN_VERSION_API_MINOR 56
|
||||
#define CYGWIN_VERSION_API_MINOR 57
|
||||
|
||||
/* There is also a compatibity version number associated with the
|
||||
shared memory regions. It is incremented when incompatible
|
||||
|
@ -47,6 +47,22 @@ BOOL allow_ntsec = true;
|
||||
The default is TRUE to reflect the old behaviour. */
|
||||
BOOL allow_smbntsec;
|
||||
|
||||
cygsid *
|
||||
cygsidlist::alloc_sids (int n)
|
||||
{
|
||||
if (n > 0)
|
||||
return (cygsid *) cmalloc (HEAP_STR, n * sizeof (cygsid));
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
cygsidlist::free_sids ()
|
||||
{
|
||||
if (sids)
|
||||
cfree (sids);
|
||||
}
|
||||
|
||||
extern "C" void
|
||||
cygwin_set_impersonation_token (const HANDLE hToken)
|
||||
{
|
||||
@ -152,7 +168,7 @@ str2buf2uni (UNICODE_STRING &tgt, WCHAR *buf, const char *srcstr)
|
||||
sys_mbstowcs (buf, srcstr, tgt.MaximumLength);
|
||||
}
|
||||
|
||||
#if 0 //unused
|
||||
#if 0 /* unused */
|
||||
static void
|
||||
lsa2wchar (WCHAR *tgt, LSA_UNICODE_STRING &src, int size)
|
||||
{
|
||||
@ -194,7 +210,7 @@ close_local_policy (LSA_HANDLE &lsa)
|
||||
lsa = INVALID_HANDLE_VALUE;
|
||||
}
|
||||
|
||||
#if 0 // unused
|
||||
#if 0 /* unused */
|
||||
static BOOL
|
||||
get_lsa_srv_inf (LSA_HANDLE lsa, char *logonserver, char *domain)
|
||||
{
|
||||
@ -226,7 +242,8 @@ get_lsa_srv_inf (LSA_HANDLE lsa, char *logonserver, char *domain)
|
||||
not member of a domain. The name in the primary domain info is the
|
||||
name of the workgroup then. */
|
||||
if (pdi->Sid &&
|
||||
(ret = NetGetDCName (NULL, primary, (LPBYTE *) &buf)) == STATUS_SUCCESS)
|
||||
(ret =
|
||||
NetGetDCName (NULL, primary, (LPBYTE *) &buf)) == STATUS_SUCCESS)
|
||||
{
|
||||
sys_wcstombs (name, buf, INTERNET_MAX_HOST_NAME_LENGTH + 1);
|
||||
strcpy (logonserver, name);
|
||||
@ -271,7 +288,8 @@ get_logon_server (const char *domain, char *server, WCHAR *wserver)
|
||||
{
|
||||
sys_wcstombs (server, buf, INTERNET_MAX_HOST_NAME_LENGTH + 1);
|
||||
if (wserver)
|
||||
for (WCHAR *ptr1 = buf; (*wserver++ = *ptr1++); ) {}
|
||||
for (WCHAR *ptr1 = buf; (*wserver++ = *ptr1++);)
|
||||
;
|
||||
NetApiBufferFree (buf);
|
||||
return TRUE;
|
||||
}
|
||||
@ -280,7 +298,8 @@ get_logon_server (const char *domain, char *server, WCHAR *wserver)
|
||||
}
|
||||
|
||||
static BOOL
|
||||
get_user_groups (WCHAR *wlogonserver, cygsidlist &grp_list, char *user, char *domain)
|
||||
get_user_groups (WCHAR *wlogonserver, cygsidlist &grp_list, char *user,
|
||||
char *domain)
|
||||
{
|
||||
char dgroup[INTERNET_MAX_HOST_NAME_LENGTH + GNLEN + 2];
|
||||
WCHAR wuser[UNLEN + 1];
|
||||
@ -316,7 +335,8 @@ get_user_groups (WCHAR *wlogonserver, cygsidlist &grp_list, char *user, char *do
|
||||
debug_printf ("LookupAccountName(%s): %E", dgroup);
|
||||
else if (legal_sid_type (use))
|
||||
grp_list += gsid;
|
||||
else debug_printf ("Global group %s invalid. Domain: %s Use: %d",
|
||||
else
|
||||
debug_printf ("Global group %s invalid. Domain: %s Use: %d",
|
||||
dgroup, domain, use);
|
||||
}
|
||||
|
||||
@ -441,7 +461,8 @@ get_user_primary_group (WCHAR *wlogonserver, const char *user,
|
||||
}
|
||||
|
||||
pgrpsid = pusersid;
|
||||
if (IsValidSid (pgrpsid) && (count = *GetSidSubAuthorityCount (pgrpsid)) > 1)
|
||||
if (IsValidSid (pgrpsid)
|
||||
&& (count = *GetSidSubAuthorityCount (pgrpsid)) > 1)
|
||||
{
|
||||
*GetSidSubAuthority (pgrpsid, count - 1) = buf->usri3_primary_group_id;
|
||||
retval = TRUE;
|
||||
@ -473,29 +494,11 @@ get_unix_group_sidlist (struct passwd *pw, cygsidlist &grp_list)
|
||||
}
|
||||
}
|
||||
|
||||
static BOOL
|
||||
get_group_sidlist (cygsidlist &grp_list,
|
||||
cygsid &usersid, cygsid &pgrpsid, struct passwd *pw,
|
||||
PTOKEN_GROUPS my_grps, LUID auth_luid, int &auth_pos,
|
||||
BOOL *special_pgrp)
|
||||
static void
|
||||
get_token_group_sidlist (cygsidlist &grp_list, PTOKEN_GROUPS my_grps,
|
||||
LUID auth_luid, int &auth_pos)
|
||||
{
|
||||
char user[UNLEN + 1];
|
||||
char domain[INTERNET_MAX_HOST_NAME_LENGTH + 1];
|
||||
WCHAR wserver[INTERNET_MAX_HOST_NAME_LENGTH + 3];
|
||||
char server[INTERNET_MAX_HOST_NAME_LENGTH + 3];
|
||||
cygsidlist sup_list;
|
||||
|
||||
auth_pos = -1;
|
||||
|
||||
grp_list += well_known_world_sid;
|
||||
grp_list += well_known_authenticated_users_sid;
|
||||
if (usersid == well_known_system_sid)
|
||||
{
|
||||
grp_list += well_known_admins_sid;
|
||||
get_unix_group_sidlist (pw, grp_list);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (my_grps)
|
||||
{
|
||||
if (sid_in_token_groups (my_grps, well_known_local_sid))
|
||||
@ -524,6 +527,30 @@ get_group_sidlist (cygsidlist &grp_list,
|
||||
grp_list += buf;
|
||||
auth_pos = grp_list.count - 1;
|
||||
}
|
||||
}
|
||||
|
||||
static BOOL
|
||||
get_initgroups_sidlist (cygsidlist &grp_list,
|
||||
PSID usersid, PSID pgrpsid, struct passwd *pw,
|
||||
PTOKEN_GROUPS my_grps, LUID auth_luid, int &auth_pos,
|
||||
BOOL &special_pgrp)
|
||||
{
|
||||
grp_list += well_known_world_sid;
|
||||
grp_list += well_known_authenticated_users_sid;
|
||||
if (usersid == well_known_system_sid)
|
||||
{
|
||||
auth_pos = -1;
|
||||
grp_list += well_known_admins_sid;
|
||||
get_unix_group_sidlist (pw, grp_list);
|
||||
}
|
||||
else
|
||||
{
|
||||
char user[UNLEN + 1];
|
||||
char domain[INTERNET_MAX_HOST_NAME_LENGTH + 1];
|
||||
WCHAR wserver[INTERNET_MAX_HOST_NAME_LENGTH + 3];
|
||||
char server[INTERNET_MAX_HOST_NAME_LENGTH + 3];
|
||||
|
||||
get_token_group_sidlist (grp_list, my_grps, auth_luid, auth_pos);
|
||||
extract_nt_dom_user (pw, domain, user);
|
||||
if (get_logon_server (domain, server, wserver))
|
||||
get_user_groups (wserver, grp_list, user, domain);
|
||||
@ -531,16 +558,26 @@ get_group_sidlist (cygsidlist &grp_list,
|
||||
if (!get_user_local_groups (grp_list, usersid))
|
||||
return FALSE;
|
||||
}
|
||||
/* special_pgrp true if pgrpsid is not null and not in normal groups */
|
||||
*special_pgrp = FALSE;
|
||||
if (pgrpsid && !grp_list.contains (pgrpsid))
|
||||
{
|
||||
*special_pgrp = TRUE;
|
||||
/* special_pgrp true if pgrpsid is not in normal groups */
|
||||
if ((special_pgrp = !grp_list.contains (pgrpsid)))
|
||||
grp_list += pgrpsid;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
get_setgroups_sidlist (cygsidlist &tmp_list, PTOKEN_GROUPS my_grps,
|
||||
user_groups &groups, LUID auth_luid, int &auth_pos)
|
||||
{
|
||||
PSID pgpsid = groups.pgsid;
|
||||
tmp_list += well_known_world_sid;
|
||||
tmp_list += well_known_authenticated_users_sid;
|
||||
get_token_group_sidlist (tmp_list, my_grps, auth_luid, auth_pos);
|
||||
for (int gidx = 0; gidx < groups.sgsids.count; gidx++)
|
||||
tmp_list += groups.sgsids.sids[gidx];
|
||||
if (!groups.sgsids.contains (pgpsid))
|
||||
tmp_list += pgpsid;
|
||||
}
|
||||
|
||||
static const char *sys_privs[] = {
|
||||
SE_TCB_NAME,
|
||||
SE_ASSIGNPRIMARYTOKEN_NAME,
|
||||
@ -569,8 +606,8 @@ PTOKEN_PRIVILEGES
|
||||
get_system_priv_list (cygsidlist &grp_list)
|
||||
{
|
||||
LUID priv;
|
||||
PTOKEN_PRIVILEGES privs = (PTOKEN_PRIVILEGES) malloc (sizeof (ULONG) +
|
||||
20 * sizeof (LUID_AND_ATTRIBUTES));
|
||||
PTOKEN_PRIVILEGES privs = (PTOKEN_PRIVILEGES)
|
||||
malloc (sizeof (ULONG) + 20 * sizeof (LUID_AND_ATTRIBUTES));
|
||||
if (!privs)
|
||||
{
|
||||
debug_printf ("malloc (system_privs) failed.");
|
||||
@ -605,8 +642,8 @@ get_priv_list (LSA_HANDLE lsa, cygsid &usersid, cygsidlist &grp_list)
|
||||
{
|
||||
if (grp == -1)
|
||||
{
|
||||
if ((ret = LsaEnumerateAccountRights (lsa, usersid, &privstrs, &cnt))
|
||||
!= STATUS_SUCCESS)
|
||||
if ((ret = LsaEnumerateAccountRights (lsa, usersid, &privstrs,
|
||||
&cnt)) != STATUS_SUCCESS)
|
||||
continue;
|
||||
}
|
||||
else if ((ret = LsaEnumerateAccountRights (lsa, grp_list.sids[grp],
|
||||
@ -654,8 +691,21 @@ get_priv_list (LSA_HANDLE lsa, cygsid &usersid, cygsidlist &grp_list)
|
||||
return privs;
|
||||
}
|
||||
|
||||
/* Accept a token if
|
||||
- the requested usersid matches the TokenUser and
|
||||
- if setgroups has been called:
|
||||
the token groups that are listed in /etc/group match the union of
|
||||
the requested primary and supplementary groups in gsids.
|
||||
- else the (unknown) implicitly requested supplementary groups and those
|
||||
in the token are the groups associated with the usersid. We assume
|
||||
they match and verify only the primary groups.
|
||||
The requested primary group must appear in the token.
|
||||
The primary group in the token is a group associated with the usersid,
|
||||
except if the token is internal and the group is in the token SD
|
||||
(see create_token). In that latter case that group must match the
|
||||
requested primary group. */
|
||||
BOOL
|
||||
verify_token (HANDLE token, cygsid &usersid, cygsid &pgrpsid, BOOL *pintern)
|
||||
verify_token (HANDLE token, cygsid &usersid, user_groups &groups, BOOL *pintern)
|
||||
{
|
||||
DWORD size;
|
||||
BOOL intern = FALSE;
|
||||
@ -666,18 +716,20 @@ verify_token (HANDLE token, cygsid &usersid, cygsid &pgrpsid, BOOL *pintern)
|
||||
if (!GetTokenInformation (cygheap->user.token, TokenSource,
|
||||
&ts, sizeof ts, &size))
|
||||
debug_printf ("GetTokenInformation(): %E");
|
||||
else *pintern = intern = !memcmp (ts.SourceName, "Cygwin.1", 8);
|
||||
else
|
||||
*pintern = intern = !memcmp (ts.SourceName, "Cygwin.1", 8);
|
||||
}
|
||||
/* Verify usersid */
|
||||
cygsid tok_usersid = NO_SID;
|
||||
if (!GetTokenInformation (token, TokenUser,
|
||||
&tok_usersid, sizeof tok_usersid, &size))
|
||||
debug_printf ("GetTokenInformation(): %E");
|
||||
if (usersid != tok_usersid) return FALSE;
|
||||
if (usersid != tok_usersid)
|
||||
return FALSE;
|
||||
|
||||
/* In an internal token, if the sd group is not well_known_null_sid,
|
||||
it must match pgrpsid */
|
||||
if (intern)
|
||||
/* For an internal token, if setgroups was not called and if the sd group
|
||||
is not well_known_null_sid, it must match pgrpsid */
|
||||
if (intern && !groups.issetgroups ())
|
||||
{
|
||||
char sd_buf[MAX_SID_LEN + sizeof (SECURITY_DESCRIPTOR)];
|
||||
PSID gsid = NO_SID;
|
||||
@ -688,14 +740,15 @@ verify_token (HANDLE token, cygsid &usersid, cygsid &pgrpsid, BOOL *pintern)
|
||||
else if (!GetSecurityDescriptorGroup ((PSECURITY_DESCRIPTOR) sd_buf,
|
||||
&gsid, (BOOL *) &size))
|
||||
debug_printf ("GetSecurityDescriptorGroup(): %E");
|
||||
if (well_known_null_sid != gsid) return pgrpsid == gsid;
|
||||
if (well_known_null_sid != gsid)
|
||||
return gsid == groups.pgsid;
|
||||
}
|
||||
/* See if the pgrpsid is the tok_usersid in the token groups */
|
||||
|
||||
PTOKEN_GROUPS my_grps = NULL;
|
||||
BOOL ret = FALSE;
|
||||
char saw_buf[NGROUPS_MAX] = {};
|
||||
char *saw = saw_buf, sawpg = FALSE;
|
||||
|
||||
if ( pgrpsid == tok_usersid)
|
||||
return TRUE;
|
||||
if (!GetTokenInformation (token, TokenGroups, NULL, 0, &size) &&
|
||||
GetLastError () != ERROR_INSUFFICIENT_BUFFER)
|
||||
debug_printf ("GetTokenInformation(token, TokenGroups): %E\n");
|
||||
@ -703,34 +756,66 @@ verify_token (HANDLE token, cygsid &usersid, cygsid &pgrpsid, BOOL *pintern)
|
||||
debug_printf ("malloc (my_grps) failed.");
|
||||
else if (!GetTokenInformation (token, TokenGroups, my_grps, size, &size))
|
||||
debug_printf ("GetTokenInformation(my_token, TokenGroups): %E\n");
|
||||
else if (!groups.issetgroups ()) /* setgroups was never called */
|
||||
{
|
||||
ret = sid_in_token_groups (my_grps, groups.pgsid);
|
||||
if (ret == FALSE)
|
||||
ret = (groups.pgsid == tok_usersid);
|
||||
}
|
||||
else /* setgroups was called */
|
||||
{
|
||||
struct __group32 *gr;
|
||||
cygsid gsid;
|
||||
if (groups.sgsids.count > (int) sizeof (saw_buf) &&
|
||||
!(saw = (char *) calloc (groups.sgsids.count, sizeof (char))))
|
||||
goto done;
|
||||
|
||||
/* token groups found in /etc/group match the user.gsids ? */
|
||||
for (int gidx = 0; (gr = internal_getgrent (gidx)); ++gidx)
|
||||
if (gsid.getfromgr (gr) && sid_in_token_groups (my_grps, gsid))
|
||||
{
|
||||
int pos = groups.sgsids.position (gsid);
|
||||
if (pos >= 0)
|
||||
saw[pos] = TRUE;
|
||||
else if (groups.pgsid == gsid)
|
||||
sawpg = TRUE;
|
||||
else
|
||||
ret = sid_in_token_groups (my_grps, pgrpsid);
|
||||
goto done;
|
||||
}
|
||||
for (int gidx = 0; gidx < groups.sgsids.count; gidx++)
|
||||
if (!saw[gidx])
|
||||
goto done;
|
||||
if (sawpg || groups.sgsids.contains (groups.pgsid))
|
||||
ret = TRUE;
|
||||
}
|
||||
done:
|
||||
if (my_grps)
|
||||
free (my_grps);
|
||||
if (saw != saw_buf)
|
||||
free (saw);
|
||||
return ret;
|
||||
}
|
||||
|
||||
HANDLE
|
||||
create_token (cygsid &usersid, cygsid &pgrpsid, struct passwd *pw)
|
||||
create_token (cygsid &usersid, user_groups &new_groups, struct passwd *pw)
|
||||
{
|
||||
NTSTATUS ret;
|
||||
LSA_HANDLE lsa = INVALID_HANDLE_VALUE;
|
||||
int old_priv_state;
|
||||
|
||||
cygsidlist grpsids;
|
||||
cygsidlist tmp_gsids (cygsidlist_auto, 12);
|
||||
|
||||
SECURITY_QUALITY_OF_SERVICE sqos =
|
||||
{ sizeof sqos, SecurityImpersonation, SECURITY_STATIC_TRACKING, FALSE };
|
||||
OBJECT_ATTRIBUTES oa =
|
||||
{ sizeof oa, 0, 0, 0, 0, &sqos };
|
||||
OBJECT_ATTRIBUTES oa = { sizeof oa, 0, 0, 0, 0, &sqos };
|
||||
PSECURITY_ATTRIBUTES psa;
|
||||
BOOL special_pgrp;
|
||||
BOOL special_pgrp = FALSE;
|
||||
char sa_buf[1024];
|
||||
LUID auth_luid = SYSTEM_LUID;
|
||||
LARGE_INTEGER exp = { QuadPart:0x7fffffffffffffffLL };
|
||||
|
||||
TOKEN_USER user;
|
||||
PTOKEN_GROUPS grps = NULL;
|
||||
PTOKEN_GROUPS new_tok_gsids = NULL;
|
||||
PTOKEN_PRIVILEGES privs = NULL;
|
||||
TOKEN_OWNER owner;
|
||||
TOKEN_PRIMARY_GROUP pgrp;
|
||||
@ -746,7 +831,7 @@ create_token (cygsid &usersid, cygsid &pgrpsid, struct passwd *pw)
|
||||
HANDLE primary_token = INVALID_HANDLE_VALUE;
|
||||
|
||||
HANDLE my_token = INVALID_HANDLE_VALUE;
|
||||
PTOKEN_GROUPS my_grps = NULL;
|
||||
PTOKEN_GROUPS my_tok_gsids = NULL;
|
||||
DWORD size;
|
||||
|
||||
/* SE_CREATE_TOKEN_NAME privilege needed to call NtCreateToken. */
|
||||
@ -772,7 +857,8 @@ create_token (cygsid &usersid, cygsid &pgrpsid, struct passwd *pw)
|
||||
if (usersid != well_known_system_sid)
|
||||
if (!GetTokenInformation (my_token, TokenStatistics,
|
||||
&stats, sizeof stats, &size))
|
||||
debug_printf ("GetTokenInformation(my_token, TokenStatistics): %E\n");
|
||||
debug_printf
|
||||
("GetTokenInformation(my_token, TokenStatistics): %E\n");
|
||||
else
|
||||
auth_luid = stats.AuthenticationId;
|
||||
|
||||
@ -781,55 +867,59 @@ create_token (cygsid &usersid, cygsid &pgrpsid, struct passwd *pw)
|
||||
if (!GetTokenInformation (my_token, TokenGroups, NULL, 0, &size) &&
|
||||
GetLastError () != ERROR_INSUFFICIENT_BUFFER)
|
||||
debug_printf ("GetTokenInformation(my_token, TokenGroups): %E\n");
|
||||
else if (!(my_grps = (PTOKEN_GROUPS) malloc (size)))
|
||||
debug_printf ("malloc (my_grps) failed.");
|
||||
else if (!GetTokenInformation (my_token, TokenGroups, my_grps,
|
||||
else if (!(my_tok_gsids = (PTOKEN_GROUPS) malloc (size)))
|
||||
debug_printf ("malloc (my_tok_gsids) failed.");
|
||||
else if (!GetTokenInformation (my_token, TokenGroups, my_tok_gsids,
|
||||
size, &size))
|
||||
{
|
||||
debug_printf ("GetTokenInformation(my_token, TokenGroups): %E\n");
|
||||
free (my_grps);
|
||||
my_grps = NULL;
|
||||
free (my_tok_gsids);
|
||||
my_tok_gsids = NULL;
|
||||
}
|
||||
CloseHandle (my_token);
|
||||
}
|
||||
|
||||
/* Create list of groups, the user is member in. */
|
||||
int auth_pos;
|
||||
if (!get_group_sidlist (grpsids, usersid, pgrpsid, pw,
|
||||
my_grps, auth_luid, auth_pos, &special_pgrp))
|
||||
if (new_groups.issetgroups ())
|
||||
get_setgroups_sidlist (tmp_gsids, my_tok_gsids, new_groups, auth_luid,
|
||||
auth_pos);
|
||||
else if (!get_initgroups_sidlist (tmp_gsids, usersid, new_groups.pgsid, pw,
|
||||
my_tok_gsids, auth_luid, auth_pos,
|
||||
special_pgrp))
|
||||
goto out;
|
||||
|
||||
/* Primary group. */
|
||||
pgrp.PrimaryGroup = pgrpsid;
|
||||
pgrp.PrimaryGroup = new_groups.pgsid;
|
||||
|
||||
/* Create a TOKEN_GROUPS list from the above retrieved list of sids. */
|
||||
char grps_buf[sizeof (ULONG) + grpsids.count * sizeof (SID_AND_ATTRIBUTES)];
|
||||
grps = (PTOKEN_GROUPS) grps_buf;
|
||||
grps->GroupCount = grpsids.count;
|
||||
for (DWORD i = 0; i < grps->GroupCount; ++i)
|
||||
char grps_buf[sizeof (ULONG) + tmp_gsids.count * sizeof (SID_AND_ATTRIBUTES)];
|
||||
new_tok_gsids = (PTOKEN_GROUPS) grps_buf;
|
||||
new_tok_gsids->GroupCount = tmp_gsids.count;
|
||||
for (DWORD i = 0; i < new_tok_gsids->GroupCount; ++i)
|
||||
{
|
||||
grps->Groups[i].Sid = grpsids.sids[i];
|
||||
grps->Groups[i].Attributes = SE_GROUP_MANDATORY |
|
||||
SE_GROUP_ENABLED_BY_DEFAULT |
|
||||
SE_GROUP_ENABLED;
|
||||
if (auth_pos >= 0 && i == (DWORD) auth_pos)
|
||||
grps->Groups[i].Attributes |= SE_GROUP_LOGON_ID;
|
||||
new_tok_gsids->Groups[i].Sid = tmp_gsids.sids[i];
|
||||
new_tok_gsids->Groups[i].Attributes = SE_GROUP_MANDATORY |
|
||||
SE_GROUP_ENABLED_BY_DEFAULT | SE_GROUP_ENABLED;
|
||||
}
|
||||
if (auth_pos >= 0)
|
||||
new_tok_gsids->Groups[auth_pos].Attributes |= SE_GROUP_LOGON_ID;
|
||||
|
||||
/* Retrieve list of privileges of that user. */
|
||||
if (!(privs = get_priv_list (lsa, usersid, grpsids)))
|
||||
if (!(privs = get_priv_list (lsa, usersid, tmp_gsids)))
|
||||
goto out;
|
||||
|
||||
/* Create default dacl. */
|
||||
if (!sec_acl ((PACL) acl_buf, FALSE,
|
||||
grpsids.contains (well_known_admins_sid)?well_known_admins_sid:usersid))
|
||||
tmp_gsids.contains (well_known_admins_sid) ?
|
||||
well_known_admins_sid : usersid))
|
||||
goto out;
|
||||
dacl.DefaultDacl = (PACL) acl_buf;
|
||||
|
||||
/* Let's be heroic... */
|
||||
ret = NtCreateToken (&token, TOKEN_ALL_ACCESS, &oa, TokenImpersonation,
|
||||
&auth_luid, &exp, &user, grps, privs, &owner, &pgrp,
|
||||
&dacl, &source);
|
||||
&auth_luid, &exp, &user, new_tok_gsids, privs, &owner,
|
||||
&pgrp, &dacl, &source);
|
||||
if (ret)
|
||||
__seterrno_from_win_error (RtlNtStatusToDosError (ret));
|
||||
else if (GetLastError () == ERROR_PROC_NOT_FOUND)
|
||||
@ -842,13 +932,15 @@ create_token (cygsid &usersid, cygsid &pgrpsid, struct passwd *pw)
|
||||
/* Set security descriptor and primary group */
|
||||
psa = __sec_user (sa_buf, usersid, TRUE);
|
||||
if (psa->lpSecurityDescriptor &&
|
||||
!SetSecurityDescriptorGroup (
|
||||
(PSECURITY_DESCRIPTOR) psa->lpSecurityDescriptor,
|
||||
special_pgrp ? pgrpsid : well_known_null_sid, FALSE))
|
||||
!SetSecurityDescriptorGroup ((PSECURITY_DESCRIPTOR)
|
||||
psa->lpSecurityDescriptor,
|
||||
special_pgrp ? new_groups.pgsid
|
||||
: well_known_null_sid,
|
||||
FALSE))
|
||||
debug_printf ("SetSecurityDescriptorGroup %E");
|
||||
/* Convert to primary token. */
|
||||
if (!DuplicateTokenEx (token, MAXIMUM_ALLOWED, psa,
|
||||
SecurityImpersonation, TokenPrimary, &primary_token))
|
||||
if (!DuplicateTokenEx (token, MAXIMUM_ALLOWED, psa, SecurityImpersonation,
|
||||
TokenPrimary, &primary_token))
|
||||
{
|
||||
__seterrno ();
|
||||
debug_printf ("DuplicateTokenEx %E");
|
||||
@ -862,8 +954,8 @@ out:
|
||||
CloseHandle (token);
|
||||
if (privs)
|
||||
free (privs);
|
||||
if (my_grps)
|
||||
free (my_grps);
|
||||
if (my_tok_gsids)
|
||||
free (my_tok_gsids);
|
||||
close_local_policy (lsa);
|
||||
|
||||
debug_printf ("%d = create_token ()", primary_token);
|
||||
@ -963,8 +1055,7 @@ subauth (struct passwd *pw)
|
||||
LsaFreeReturnBuffer (profile);
|
||||
/* Convert to primary token. */
|
||||
if (!DuplicateTokenEx (user_token, TOKEN_ALL_ACCESS, &sa,
|
||||
SecurityImpersonation, TokenPrimary,
|
||||
&primary_token))
|
||||
SecurityImpersonation, TokenPrimary, &primary_token))
|
||||
__seterrno ();
|
||||
|
||||
out:
|
||||
@ -1296,8 +1387,8 @@ get_file_attribute (int use_ntsec, const char *file,
|
||||
}
|
||||
|
||||
static int
|
||||
get_nt_object_attribute (HANDLE handle, SE_OBJECT_TYPE object_type, int *attribute,
|
||||
__uid32_t *uidret, __gid32_t *gidret)
|
||||
get_nt_object_attribute (HANDLE handle, SE_OBJECT_TYPE object_type,
|
||||
int *attribute, __uid32_t *uidret, __gid32_t *gidret)
|
||||
{
|
||||
if (!wincap.has_security ())
|
||||
return 0;
|
||||
@ -1311,11 +1402,8 @@ get_nt_object_attribute (HANDLE handle, SE_OBJECT_TYPE object_type, int *attribu
|
||||
DACL_SECURITY_INFORMATION |
|
||||
GROUP_SECURITY_INFORMATION |
|
||||
OWNER_SECURITY_INFORMATION,
|
||||
&owner_sid,
|
||||
&group_sid,
|
||||
&acl,
|
||||
NULL,
|
||||
&psd))
|
||||
&owner_sid, &group_sid,
|
||||
&acl, NULL, &psd))
|
||||
{
|
||||
__seterrno ();
|
||||
debug_printf ("GetSecurityInfo %E");
|
||||
@ -1341,8 +1429,7 @@ get_nt_object_attribute (HANDLE handle, SE_OBJECT_TYPE object_type, int *attribu
|
||||
if (!acl)
|
||||
{
|
||||
*attribute |= S_IRWXU | S_IRWXG | S_IRWXO;
|
||||
syscall_printf ("No ACL = %x, uid %d, gid %d",
|
||||
*attribute, uid, gid);
|
||||
syscall_printf ("No ACL = %x, uid %d, gid %d", *attribute, uid, gid);
|
||||
LocalFree (psd);
|
||||
return 0;
|
||||
}
|
||||
@ -1442,7 +1529,8 @@ get_object_attribute (HANDLE handle, SE_OBJECT_TYPE object_type,
|
||||
{
|
||||
if (allow_ntsec)
|
||||
{
|
||||
int res = get_nt_object_attribute (handle, object_type, attribute, uidret, gidret);
|
||||
int res = get_nt_object_attribute (handle, object_type, attribute,
|
||||
uidret, gidret);
|
||||
if (attribute && (*attribute & S_IFLNK) == S_IFLNK)
|
||||
*attribute |= S_IRWXU | S_IRWXG | S_IRWXO;
|
||||
return res;
|
||||
@ -1475,8 +1563,7 @@ add_access_allowed_ace (PACL acl, int offset, DWORD attributes,
|
||||
ACCESS_ALLOWED_ACE *ace;
|
||||
if (GetAce (acl, offset, (PVOID *) &ace))
|
||||
ace->Header.AceFlags |= inherit;
|
||||
len_add += sizeof (ACCESS_DENIED_ACE) - sizeof (DWORD)
|
||||
+ GetLengthSid (sid);
|
||||
len_add += sizeof (ACCESS_DENIED_ACE) - sizeof (DWORD) + GetLengthSid (sid);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@ -1492,8 +1579,7 @@ add_access_denied_ace (PACL acl, int offset, DWORD attributes,
|
||||
ACCESS_DENIED_ACE *ace;
|
||||
if (GetAce (acl, offset, (PVOID *) &ace))
|
||||
ace->Header.AceFlags |= inherit;
|
||||
len_add += sizeof (ACCESS_DENIED_ACE) - sizeof (DWORD)
|
||||
+ GetLengthSid (sid);
|
||||
len_add += sizeof (ACCESS_DENIED_ACE) - sizeof (DWORD) + GetLengthSid (sid);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@ -1614,8 +1700,7 @@ alloc_sd (__uid32_t uid, __gid32_t gid, int attribute,
|
||||
if (attribute & S_IXGRP)
|
||||
group_allow |= FILE_GENERIC_EXECUTE;
|
||||
if ((attribute & (S_IFDIR | S_IWGRP | S_IXGRP))
|
||||
== (S_IFDIR | S_IWGRP | S_IXGRP)
|
||||
&& !(attribute & S_ISVTX))
|
||||
== (S_IFDIR | S_IWGRP | S_IXGRP) && !(attribute & S_ISVTX))
|
||||
group_allow |= FILE_DELETE_CHILD;
|
||||
|
||||
/* Construct allow attribute for everyone. */
|
||||
@ -1771,8 +1856,8 @@ set_security_attribute (int attribute, PSECURITY_ATTRIBUTES psa,
|
||||
psa->lpSecurityDescriptor = sd_buf;
|
||||
InitializeSecurityDescriptor ((PSECURITY_DESCRIPTOR) sd_buf,
|
||||
SECURITY_DESCRIPTOR_REVISION);
|
||||
psa->lpSecurityDescriptor = alloc_sd (geteuid32 (), getegid32 (),
|
||||
attribute, (PSECURITY_DESCRIPTOR)sd_buf,
|
||||
psa->lpSecurityDescriptor = alloc_sd (geteuid32 (), getegid32 (), attribute,
|
||||
(PSECURITY_DESCRIPTOR) sd_buf,
|
||||
&sd_buf_size);
|
||||
}
|
||||
|
||||
@ -1803,8 +1888,7 @@ set_nt_attribute (const char *file, __uid32_t uid, __gid32_t gid,
|
||||
|
||||
int
|
||||
set_file_attribute (int use_ntsec, const char *file,
|
||||
__uid32_t uid, __gid32_t gid,
|
||||
int attribute)
|
||||
__uid32_t uid, __gid32_t gid, int attribute)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
@ -1825,6 +1909,5 @@ int
|
||||
set_file_attribute (int use_ntsec, const char *file, int attribute)
|
||||
{
|
||||
return set_file_attribute (use_ntsec, file,
|
||||
myself->uid, myself->gid,
|
||||
attribute);
|
||||
myself->uid, myself->gid, attribute);
|
||||
}
|
||||
|
@ -86,40 +86,63 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
typedef enum { cygsidlist_unknown, cygsidlist_alloc, cygsidlist_auto } cygsidlist_type;
|
||||
class cygsidlist {
|
||||
int maxcount;
|
||||
public:
|
||||
int count;
|
||||
cygsid *sids;
|
||||
cygsidlist_type type;
|
||||
|
||||
cygsidlist () : count (0), sids (NULL) {}
|
||||
~cygsidlist () { delete [] sids; }
|
||||
|
||||
BOOL add (cygsid &nsi)
|
||||
cygsidlist (cygsidlist_type t, int m)
|
||||
{
|
||||
cygsid *tmp = new cygsid [count + 1];
|
||||
type = t;
|
||||
count = 0;
|
||||
maxcount = m;
|
||||
if (t == cygsidlist_alloc)
|
||||
sids = alloc_sids (m);
|
||||
else
|
||||
sids = new cygsid [m];
|
||||
}
|
||||
~cygsidlist () { if (type == cygsidlist_auto) delete [] sids; }
|
||||
|
||||
BOOL add (const PSID nsi) /* Only with auto for now */
|
||||
{
|
||||
if (count >= maxcount)
|
||||
{
|
||||
cygsid *tmp = new cygsid [ 2 * maxcount];
|
||||
if (!tmp)
|
||||
return FALSE;
|
||||
maxcount *= 2;
|
||||
for (int i = 0; i < count; ++i)
|
||||
tmp[i] = sids[i];
|
||||
delete [] sids;
|
||||
sids = tmp;
|
||||
}
|
||||
sids[count++] = nsi;
|
||||
return TRUE;
|
||||
}
|
||||
BOOL add (const PSID nsid) { return add (nsid); }
|
||||
BOOL add (cygsid &nsi) { return add ((PSID) nsi); }
|
||||
BOOL add (const char *sidstr)
|
||||
{ cygsid nsi (sidstr); return add (nsi); }
|
||||
BOOL addfromgr (struct __group32 *gr) /* Only with alloc */
|
||||
{ return sids[count++].getfromgr (gr); }
|
||||
|
||||
BOOL operator+= (cygsid &si) { return add (si); }
|
||||
BOOL operator+= (const char *sidstr) { return add (sidstr); }
|
||||
BOOL operator+= (const PSID psid) { return add (psid); }
|
||||
|
||||
BOOL contains (cygsid &sid) const
|
||||
int position (const PSID sid) const
|
||||
{
|
||||
for (int i = 0; i < count; ++i)
|
||||
if (sids[i] == sid)
|
||||
return TRUE;
|
||||
return FALSE;
|
||||
return i;
|
||||
return -1;
|
||||
}
|
||||
|
||||
BOOL contains (const PSID sid) const { return position (sid) >= 0; }
|
||||
cygsid *alloc_sids (int n);
|
||||
void free_sids ();
|
||||
void debug_print (const char *prefix = NULL) const
|
||||
{
|
||||
debug_printf ("-- begin sidlist ---");
|
||||
@ -131,6 +154,26 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
class user_groups {
|
||||
public:
|
||||
cygsid pgsid;
|
||||
cygsidlist sgsids;
|
||||
BOOL ischanged;
|
||||
|
||||
BOOL issetgroups () const { return (sgsids.type == cygsidlist_alloc); }
|
||||
void update_supp (const cygsidlist &newsids)
|
||||
{
|
||||
sgsids.free_sids ();
|
||||
sgsids = newsids;
|
||||
ischanged = TRUE;
|
||||
}
|
||||
void update_pgrp (const PSID sid)
|
||||
{
|
||||
pgsid = sid;
|
||||
ischanged = TRUE;
|
||||
}
|
||||
};
|
||||
|
||||
extern cygsid well_known_null_sid;
|
||||
extern cygsid well_known_world_sid;
|
||||
extern cygsid well_known_local_sid;
|
||||
@ -180,9 +223,9 @@ void set_security_attribute (int attribute, PSECURITY_ATTRIBUTES psa,
|
||||
/* Try a subauthentication. */
|
||||
HANDLE subauth (struct passwd *pw);
|
||||
/* Try creating a token directly. */
|
||||
HANDLE create_token (cygsid &usersid, cygsid &pgrpsid, struct passwd * pw);
|
||||
HANDLE create_token (cygsid &usersid, user_groups &groups, struct passwd * pw);
|
||||
/* Verify an existing token */
|
||||
BOOL verify_token (HANDLE token, cygsid &usersid, cygsid &pgrpsid, BOOL * pintern = NULL);
|
||||
BOOL verify_token (HANDLE token, cygsid &usersid, user_groups &groups, BOOL * pintern = NULL);
|
||||
|
||||
/* Extract U-domain\user field from passwd entry. */
|
||||
void extract_nt_dom_user (const struct passwd *pw, char *domain, char *user);
|
||||
|
@ -1958,9 +1958,8 @@ seteuid32 (__uid32_t uid)
|
||||
debug_printf ("uid: %d myself->gid: %d", uid, myself->gid);
|
||||
|
||||
if (!wincap.has_security ()
|
||||
|| (!cygheap->user.issetuid ()
|
||||
&& uid == myself->uid
|
||||
&& myself->gid == cygheap->user.orig_gid)
|
||||
|| (uid == myself->uid
|
||||
&& !cygheap->user.groups.ischanged)
|
||||
|| uid == ILLEGAL_UID)
|
||||
{
|
||||
debug_printf ("Nothing happens");
|
||||
@ -1968,7 +1967,8 @@ seteuid32 (__uid32_t uid)
|
||||
}
|
||||
|
||||
sigframe thisframe (mainthread);
|
||||
cygsid usersid, pgrpsid;
|
||||
cygsid usersid;
|
||||
user_groups &groups = cygheap->user.groups;
|
||||
HANDLE ptok, sav_token;
|
||||
BOOL sav_impersonated, sav_token_is_internal_token;
|
||||
BOOL process_ok, explicitly_created_token = FALSE;
|
||||
@ -1976,8 +1976,7 @@ seteuid32 (__uid32_t uid)
|
||||
PSID origpsid, psid2 = NO_SID;
|
||||
|
||||
pw_new = getpwuid32 (uid);
|
||||
if (!usersid.getfrompw (pw_new) ||
|
||||
(!pgrpsid.getfromgr (getgrgid32 (myself->gid))))
|
||||
if (!usersid.getfrompw (pw_new))
|
||||
{
|
||||
set_errno (EINVAL);
|
||||
return -1;
|
||||
@ -1995,7 +1994,7 @@ seteuid32 (__uid32_t uid)
|
||||
/* Verify if the process token is suitable.
|
||||
Currently we do not try to differentiate between
|
||||
internal tokens and others */
|
||||
process_ok = verify_token (ptok, usersid, pgrpsid);
|
||||
process_ok = verify_token (ptok, usersid, groups);
|
||||
debug_printf("Process token %sverified", process_ok ? "" : "not ");
|
||||
if (process_ok)
|
||||
{
|
||||
@ -2011,7 +2010,7 @@ seteuid32 (__uid32_t uid)
|
||||
if (!process_ok && cygheap->user.token != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
/* Verify if the current tokem is suitable */
|
||||
BOOL token_ok = verify_token (cygheap->user.token, usersid, pgrpsid,
|
||||
BOOL token_ok = verify_token (cygheap->user.token, usersid, groups,
|
||||
&sav_token_is_internal_token);
|
||||
debug_printf("Thread token %d %sverified",
|
||||
cygheap->user.token, token_ok?"":"not ");
|
||||
@ -2048,7 +2047,7 @@ seteuid32 (__uid32_t uid)
|
||||
{
|
||||
/* If no impersonation token is available, try to
|
||||
authenticate using NtCreateToken() or subauthentication. */
|
||||
cygheap->user.token = create_token (usersid, pgrpsid, pw_new);
|
||||
cygheap->user.token = create_token (usersid, groups, pw_new);
|
||||
if (cygheap->user.token != INVALID_HANDLE_VALUE)
|
||||
explicitly_created_token = TRUE;
|
||||
else
|
||||
@ -2076,7 +2075,7 @@ seteuid32 (__uid32_t uid)
|
||||
/* Try setting primary group in token to current group */
|
||||
if (!SetTokenInformation (cygheap->user.token,
|
||||
TokenPrimaryGroup,
|
||||
&pgrpsid, sizeof pgrpsid))
|
||||
&groups.pgsid, sizeof(cygsid)))
|
||||
debug_printf ("SetTokenInformation(user.token, "
|
||||
"TokenPrimaryGroup): %E");
|
||||
}
|
||||
@ -2098,6 +2097,7 @@ seteuid32 (__uid32_t uid)
|
||||
cygheap->user.set_name (pw_new->pw_name);
|
||||
cygheap->user.set_sid (usersid);
|
||||
myself->uid = uid;
|
||||
groups.ischanged = FALSE;
|
||||
return 0;
|
||||
|
||||
failed:
|
||||
@ -2142,6 +2142,7 @@ setegid32 (__gid32_t gid)
|
||||
return 0;
|
||||
|
||||
sigframe thisframe (mainthread);
|
||||
user_groups * groups = &cygheap->user.groups;
|
||||
cygsid gsid;
|
||||
HANDLE ptok;
|
||||
|
||||
@ -2153,6 +2154,7 @@ setegid32 (__gid32_t gid)
|
||||
}
|
||||
myself->gid = gid;
|
||||
|
||||
groups->update_pgrp (gsid);
|
||||
/* If impersonated, update primary group and revert */
|
||||
if (cygheap->user.issetuid ())
|
||||
{
|
||||
|
@ -48,9 +48,12 @@ internal_getlogin (cygheap_user &user)
|
||||
&ptok))
|
||||
system_printf ("OpenProcessToken(): %E\n");
|
||||
else if (!GetTokenInformation (ptok, TokenUser, &tu, sizeof tu, &siz))
|
||||
system_printf ("GetTokenInformation(): %E");
|
||||
system_printf ("GetTokenInformation (TokenUser): %E");
|
||||
else if (!(ret = user.set_sid (tu)))
|
||||
system_printf ("Couldn't retrieve SID from access token!");
|
||||
else if (!GetTokenInformation (ptok, TokenPrimaryGroup,
|
||||
&user.groups.pgsid, sizeof tu, &siz))
|
||||
system_printf ("GetTokenInformation (TokenPrimaryGroup): %E");
|
||||
/* We must set the user name, uid and gid.
|
||||
If we have a SID, try to get the corresponding Cygwin
|
||||
password entry. Set user name which can be different
|
||||
@ -75,11 +78,14 @@ internal_getlogin (cygheap_user &user)
|
||||
primary group to the group in /etc/passwd. */
|
||||
if (!SetTokenInformation (ptok, TokenOwner, &tu, sizeof tu))
|
||||
debug_printf ("SetTokenInformation(TokenOwner): %E");
|
||||
if (gsid && !SetTokenInformation (ptok, TokenPrimaryGroup,
|
||||
if (gsid)
|
||||
{
|
||||
user.groups.pgsid = gsid;
|
||||
if (!SetTokenInformation (ptok, TokenPrimaryGroup,
|
||||
&gsid, sizeof gsid))
|
||||
debug_printf ("SetTokenInformation(TokenPrimaryGroup): %E");
|
||||
}
|
||||
|
||||
}
|
||||
if (ptok != INVALID_HANDLE_VALUE)
|
||||
CloseHandle (ptok);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user