* autoload.cc: Add LoadDLLfunc statements for SetTokenInformation@16.

* cygheap.cc: Include security.h.
        * grp.cc (internal_getgrent): New function.
        (getgroups): Rearranged using `internal_getgrent' and the new
        `cygsid' class.
        * passwd.cc (internal_getpwent): New function.
        * sec_acl.cc: Use new `cygsid' class throughout.
        (acl_access): Use `internal_getgrent' instead of `getgrent'.
        * sec_helper.cc: Use new `cygsid' class throughout.
        (get_id_from_sid): Use `internal_getgrent' instead of `getgrent'.
        Use `internal_getpwent' instead of `getpwent'.
        * security.cc: Use new `cygsid' class throughout.
        * security.h: Move `MAX_SID_LEN' from winsup.h to here.
        Add extern declarations for `internal_getgrent' and `internal_getpwent'.
        (class cygsid): New class.
        * shared.cc (sec_user): Use new `cygsid' class.
        * syscalls.cc (seteuid): Try to set owner to user and primary group to
        current group in impersonation token before performing impersonation.
        (setegid): Try to set primary group in process token to the new group
        if ntsec is on.
        * uinfo.cc (internal_getlogin): Use new `cygsid' class.
        Try to set owner to user and primary group to current group in process
        token if the process has been started from a non cygwin process.
        (uinfo_init): Set primary group only if the process has been started
        from a non cygwin process.
        * winsup.h: Move define for `MAX_SID_LEN' to security.h.
This commit is contained in:
Corinna Vinschen 2001-04-25 09:43:25 +00:00
parent 3a6e96682d
commit d551169a9f
13 changed files with 276 additions and 153 deletions

View File

@ -1,3 +1,32 @@
Tue Apr 25 11:08:00 2001 Corinna Vinschen <corinna@vinschen.de>
* autoload.cc: Add LoadDLLfunc statements for SetTokenInformation@16.
* cygheap.cc: Include security.h.
* grp.cc (internal_getgrent): New function.
(getgroups): Rearranged using `internal_getgrent' and the new
`cygsid' class.
* passwd.cc (internal_getpwent): New function.
* sec_acl.cc: Use new `cygsid' class throughout.
(acl_access): Use `internal_getgrent' instead of `getgrent'.
* sec_helper.cc: Use new `cygsid' class throughout.
(get_id_from_sid): Use `internal_getgrent' instead of `getgrent'.
Use `internal_getpwent' instead of `getpwent'.
* security.cc: Use new `cygsid' class throughout.
* security.h: Move `MAX_SID_LEN' from winsup.h to here.
Add extern declarations for `internal_getgrent' and `internal_getpwent'.
(class cygsid): New class.
* shared.cc (sec_user): Use new `cygsid' class.
* syscalls.cc (seteuid): Try to set owner to user and primary group to
current group in impersonation token before performing impersonation.
(setegid): Try to set primary group in process token to the new group
if ntsec is on.
* uinfo.cc (internal_getlogin): Use new `cygsid' class.
Try to set owner to user and primary group to current group in process
token if the process has been started from a non cygwin process.
(uinfo_init): Set primary group only if the process has been started
from a non cygwin process.
* winsup.h: Move define for `MAX_SID_LEN' to security.h.
Mon Apr 16 23:20:00 2001 Andy Younger <andylyounger@hotmail.com>
* fhandler_dsp.cc: Improved handling of 8 bit playback modes.

View File

@ -318,6 +318,7 @@ LoadDLLfunc (SetSecurityDescriptorControl, 12, advapi32)
LoadDLLfunc (SetSecurityDescriptorDacl, 16, advapi32)
LoadDLLfunc (SetSecurityDescriptorGroup, 12, advapi32)
LoadDLLfunc (SetSecurityDescriptorOwner, 12, advapi32)
LoadDLLfunc (SetTokenInformation, 16, advapi32)
LoadDLLinit (netapi32)
LoadDLLfunc (NetWkstaUserGetInfo, 12, netapi32)

View File

@ -20,6 +20,7 @@
#include "cygerrno.h"
#include "sync.h"
#include "shared_info.h"
#include "security.h"
init_cygheap NO_COPY *cygheap;
void NO_COPY *cygheap_max = NULL;

View File

@ -258,69 +258,86 @@ setgrent ()
grp_pos = 0;
}
/* Internal function. ONLY USE THIS INTERNALLY, NEVER `getgrent'!!! */
struct group *
internal_getgrent (int pos)
{
if (group_state <= initializing)
read_etc_group();
if (pos < curr_lines)
return group_buf + pos;
return NULL;
}
int
getgroups (int gidsetsize, gid_t *grouplist, gid_t gid, const char *username)
{
HANDLE hToken = NULL;
char buf[4096];
DWORD size;
int cnt = 0;
struct group *gr;
if (group_state <= initializing)
read_etc_group();
if (allow_ntsec &&
OpenProcessToken (hMainProc, TOKEN_QUERY, &hToken) &&
GetTokenInformation (hToken, TokenGroups, buf, 4096, &size))
OpenProcessToken (hMainProc, TOKEN_QUERY, &hToken))
{
TOKEN_GROUPS *groups = (TOKEN_GROUPS *) buf;
char ssid[MAX_SID_LEN];
PSID sid = (PSID) ssid;
for (DWORD pg = 0; pg < groups->GroupCount; ++pg)
if (GetTokenInformation (hToken, TokenGroups, NULL, 0, &size)
|| GetLastError () == ERROR_INSUFFICIENT_BUFFER)
{
struct group *gr;
while ((gr = getgrent ()) != NULL)
char buf[size];
TOKEN_GROUPS *groups = (TOKEN_GROUPS *) buf;
if (GetTokenInformation (hToken, TokenGroups, buf, size, &size))
{
if (get_gr_sid (sid, gr) &&
EqualSid (sid, groups->Groups[pg].Sid))
{
if (cnt < gidsetsize)
grouplist[cnt] = gr->gr_gid;
++cnt;
if (gidsetsize && cnt > gidsetsize)
goto error;
break;
}
cygsid sid;
for (int gidx = 0; (gr = internal_getgrent (gidx)); ++gidx)
if (get_gr_sid (sid, gr))
for (DWORD pg = 0; pg < groups->GroupCount; ++pg)
if (sid == groups->Groups[pg].Sid)
{
if (cnt < gidsetsize)
grouplist[cnt] = gr->gr_gid;
++cnt;
if (gidsetsize && cnt > gidsetsize)
{
CloseHandle (hToken);
goto error;
}
break;
}
}
endgrent ();
}
else
debug_printf ("%d = GetTokenInformation(NULL) %E", size);
CloseHandle (hToken);
return cnt;
if (cnt)
return cnt;
}
else
{
for (int i = 0; i < curr_lines; ++i)
if (gid == group_buf[i].gr_gid)
for (int gidx = 0; (gr = internal_getgrent (gidx)); ++gidx)
if (gid == gr->gr_gid)
{
if (cnt < gidsetsize)
grouplist[cnt] = gr->gr_gid;
++cnt;
if (gidsetsize && cnt > gidsetsize)
goto error;
}
else if (gr->gr_mem)
for (int gi = 0; gr->gr_mem[gi]; ++gi)
if (strcasematch (username, gr->gr_mem[gi]))
{
if (cnt < gidsetsize)
grouplist[cnt] = group_buf[i].gr_gid;
grouplist[cnt] = gr->gr_gid;
++cnt;
if (gidsetsize && cnt > gidsetsize)
goto error;
}
else if (group_buf[i].gr_mem)
for (int gi = 0; group_buf[i].gr_mem[gi]; ++gi)
if (strcasematch (username, group_buf[i].gr_mem[gi]))
{
if (cnt < gidsetsize)
grouplist[cnt] = group_buf[i].gr_gid;
++cnt;
if (gidsetsize && cnt > gidsetsize)
goto error;
}
return cnt;
}
return cnt;
error:
set_errno (EINVAL);

View File

@ -359,6 +359,18 @@ setpassent ()
return 0;
}
/* Internal function. ONLY USE THIS INTERNALLY, NEVER `getpwent'!!! */
struct passwd *
internal_getpwent (int pos)
{
if (passwd_state <= initializing)
read_etc_passwd ();
if (pos < curr_lines)
return passwd_buf + pos;
return NULL;
}
extern "C" char *
getpass (const char * prompt)
{

View File

@ -68,13 +68,7 @@ setacl (const char *file, int nentries, aclent_t *aclbufp)
__seterrno ();
return -1;
}
char owner_buf[MAX_SID_LEN];
if (!CopySid (MAX_SID_LEN, (PSID) owner_buf, owner_sid))
{
__seterrno ();
return -1;
}
owner_sid = (PSID) owner_buf;
cygsid owner (owner_sid);
/* Get group SID. */
PSID group_sid = NULL;
@ -83,13 +77,7 @@ setacl (const char *file, int nentries, aclent_t *aclbufp)
__seterrno ();
return -1;
}
char group_buf[MAX_SID_LEN];
if (!CopySid (MAX_SID_LEN, (PSID) group_buf, group_sid))
{
__seterrno ();
return -1;
}
group_sid = (PSID) group_buf;
cygsid group (group_sid);
/* Initialize local security descriptor. */
SECURITY_DESCRIPTOR sd;
@ -98,13 +86,13 @@ setacl (const char *file, int nentries, aclent_t *aclbufp)
__seterrno ();
return -1;
}
if (!SetSecurityDescriptorOwner(&sd, owner_sid, FALSE))
if (!SetSecurityDescriptorOwner(&sd, owner, FALSE))
{
__seterrno ();
return -1;
}
if (group_sid
&& !SetSecurityDescriptorGroup(&sd, group_sid, FALSE))
if (group
&& !SetSecurityDescriptorGroup(&sd, group, FALSE))
{
__seterrno ();
return -1;
@ -116,8 +104,7 @@ setacl (const char *file, int nentries, aclent_t *aclbufp)
size_t acl_len = sizeof (ACL);
int ace_off = 0;
char sidbuf[MAX_SID_LEN];
PSID sid = (PSID) sidbuf;
cygsid sid;
struct passwd *pw;
struct group *gr;
int pos;
@ -164,7 +151,7 @@ setacl (const char *file, int nentries, aclent_t *aclbufp)
case DEF_USER_OBJ:
allow |= STANDARD_RIGHTS_ALL & ~DELETE;
if (!add_access_allowed_ace (acl, ace_off++, allow,
owner_sid, acl_len, inheritance))
owner, acl_len, inheritance))
return -1;
break;
case USER:
@ -178,7 +165,7 @@ setacl (const char *file, int nentries, aclent_t *aclbufp)
case GROUP_OBJ:
case DEF_GROUP_OBJ:
if (!add_access_allowed_ace (acl, ace_off++, allow,
group_sid, acl_len, inheritance))
group, acl_len, inheritance))
return -1;
break;
case GROUP:
@ -320,21 +307,21 @@ getacl (const char *file, DWORD attr, int nentries, aclent_t *aclbufp)
if (!GetAce (acl, i, (PVOID *) &ace))
continue;
PSID ace_sid = (PSID) &ace->SidStart;
cygsid ace_sid ((PSID) &ace->SidStart);
int id;
int type = 0;
if (EqualSid (ace_sid, owner_sid))
if (ace_sid == owner_sid)
{
type = USER_OBJ;
id = uid;
}
else if (EqualSid (ace_sid, group_sid))
else if (ace_sid == group_sid)
{
type = GROUP_OBJ;
id = gid;
}
else if (EqualSid (ace_sid, get_world_sid ()))
else if (ace_sid == get_world_sid ())
{
type = OTHER_OBJ;
id = 0;
@ -431,23 +418,20 @@ acl_access (const char *path, int flags)
* Check if user is a NT group:
* Take SID from passwd, search SID in group, check is_grp_member.
*/
char owner_sidbuf[MAX_SID_LEN];
PSID owner_sid = (PSID) owner_sidbuf;
char group_sidbuf[MAX_SID_LEN];
PSID group_sid = (PSID) group_sidbuf;
cygsid owner;
cygsid group;
struct passwd *pw;
struct group *gr = NULL;
if ((pw = getpwuid (acls[i].a_id)) != NULL
&& get_pw_sid (owner_sid, pw))
&& get_pw_sid (owner, pw))
{
while ((gr = getgrent ()))
if (get_gr_sid (group_sid, gr)
&& EqualSid (owner_sid, group_sid)
for (int gidx = 0; (gr = internal_getgrent (gidx)); ++gidx)
if (get_gr_sid (group, gr)
&& owner == group
&& is_grp_member (myself->uid, gr->gr_gid))
break;
endgrent ();
}
}
if (!gr)
continue;
}

View File

@ -120,56 +120,40 @@ get_gr_sid (PSID sid, struct group *gr)
PSID
get_admin_sid ()
{
static NO_COPY char admin_sid_buf[MAX_SID_LEN];
static NO_COPY PSID admin_sid = NULL;
static NO_COPY cygsid admin_sid (NULL);
if (!admin_sid)
{
admin_sid = (PSID) admin_sid_buf;
convert_string_sid_to_sid (admin_sid, "S-1-5-32-544");
}
convert_string_sid_to_sid (admin_sid.set (), "S-1-5-32-544");
return admin_sid;
}
PSID
get_system_sid ()
{
static NO_COPY char system_sid_buf[MAX_SID_LEN];
static NO_COPY PSID system_sid = NULL;
static NO_COPY cygsid system_sid (NULL);
if (!system_sid)
{
system_sid = (PSID) system_sid_buf;
convert_string_sid_to_sid (system_sid, "S-1-5-18");
}
convert_string_sid_to_sid (system_sid.set (), "S-1-5-18");
return system_sid;
}
PSID
get_creator_owner_sid ()
{
static NO_COPY char owner_sid_buf[MAX_SID_LEN];
static NO_COPY PSID owner_sid = NULL;
static NO_COPY cygsid owner_sid (NULL);
if (!owner_sid)
{
owner_sid = (PSID) owner_sid_buf;
convert_string_sid_to_sid (owner_sid, "S-1-3-0");
}
convert_string_sid_to_sid (owner_sid.set (), "S-1-3-0");
return owner_sid;
}
PSID
get_world_sid ()
{
static NO_COPY char world_sid_buf[MAX_SID_LEN];
static NO_COPY PSID world_sid = NULL;
static NO_COPY cygsid world_sid (NULL);
if (!world_sid)
{
world_sid = (PSID) world_sid_buf;
convert_string_sid_to_sid (world_sid, "S-1-1-0");
}
convert_string_sid_to_sid (world_sid.set (), "S-1-1-0");
return world_sid;
}
@ -186,22 +170,20 @@ get_id_from_sid (PSID psid, BOOL search_grp, int *type)
/* First try to get SID from passwd or group entry */
if (allow_ntsec)
{
char sidbuf[MAX_SID_LEN];
PSID sid = (PSID) sidbuf;
cygsid sid;
int id = -1;
if (!search_grp)
{
struct passwd *pw;
while ((pw = getpwent ()) != NULL)
for (int pidx = 0; (pw = internal_getpwent (pidx)); ++pidx)
{
if (get_pw_sid (sid, pw) && EqualSid (psid, sid))
if (get_pw_sid (sid, pw) && sid == psid)
{
id = pw->pw_uid;
break;
}
}
endpwent ();
if (id >= 0)
{
if (type)
@ -212,15 +194,14 @@ get_id_from_sid (PSID psid, BOOL search_grp, int *type)
if (search_grp || type)
{
struct group *gr;
while ((gr = getgrent ()) != NULL)
for (int gidx = 0; (gr = internal_getgrent (gidx)); ++gidx)
{
if (get_gr_sid (sid, gr) && EqualSid (psid, sid))
if (get_gr_sid (sid, gr) && sid == psid)
{
id = gr->gr_gid;
break;
}
}
endgrent ();
if (id >= 0)
{
if (type)
@ -321,8 +302,7 @@ is_grp_member (uid_t uid, gid_t gid)
BOOL
lookup_name (const char *name, const char *logsrv, PSID ret_sid)
{
char sidbuf[MAX_SID_LEN];
PSID sid = (PSID) sidbuf;
cygsid sid;
DWORD sidlen;
char domuser[MAX_COMPUTERNAME_LENGTH+MAX_USER_NAME+1];
char dom[MAX_COMPUTERNAME_LENGTH+1];

View File

@ -333,8 +333,8 @@ get_nt_attribute (const char *file, int *attribute,
continue;
}
PSID ace_sid = (PSID) &ace->SidStart;
if (owner_sid && EqualSid (ace_sid, owner_sid))
cygsid ace_sid ((PSID) &ace->SidStart);
if (owner_sid && ace_sid == owner_sid)
{
if (ace->Mask & FILE_READ_DATA)
*flags |= S_IRUSR;
@ -343,7 +343,7 @@ get_nt_attribute (const char *file, int *attribute,
if (ace->Mask & FILE_EXECUTE)
*flags |= S_IXUSR;
}
else if (group_sid && EqualSid (ace_sid, group_sid))
else if (group_sid && ace_sid == group_sid)
{
if (ace->Mask & FILE_READ_DATA)
*flags |= S_IRGRP
@ -355,7 +355,7 @@ get_nt_attribute (const char *file, int *attribute,
*flags |= S_IXGRP
| ((grp_member && !(*anti & S_IXUSR)) ? S_IXUSR : 0);
}
else if (EqualSid (ace_sid, get_world_sid ()))
else if (ace_sid == get_world_sid ())
{
if (ace->Mask & FILE_READ_DATA)
*flags |= S_IROTH
@ -469,26 +469,22 @@ alloc_sd (uid_t uid, gid_t gid, const char *logsrv, int attribute,
/* Get SID and name of new owner. */
char owner[MAX_USER_NAME];
char *owner_sid_buf[MAX_SID_LEN];
PSID owner_sid = NULL;
cygsid owner_sid;
struct passwd *pw = getpwuid (uid);
strcpy (owner, pw ? pw->pw_name : getlogin ());
owner_sid = (PSID) owner_sid_buf;
if ((!pw || !get_pw_sid (owner_sid, pw))
&& !lookup_name (owner, logsrv, owner_sid))
return NULL;
debug_printf ("owner: %s [%d]", owner,
*GetSidSubAuthority((PSID) owner_sid,
*GetSidSubAuthorityCount((PSID) owner_sid) - 1));
*GetSidSubAuthority(owner_sid,
*GetSidSubAuthorityCount(owner_sid) - 1));
/* Get SID and name of new group. */
char *group_sid_buf[MAX_SID_LEN];
PSID group_sid = NULL;
cygsid group_sid (NULL);
struct group *grp = getgrgid (gid);
if (grp)
{
group_sid = (PSID) group_sid_buf;
if ((!grp || !get_gr_sid (group_sid, grp))
if ((!grp || !get_gr_sid (group_sid.set (), grp))
&& !lookup_name (grp->gr_name, logsrv, group_sid))
return NULL;
}
@ -643,13 +639,13 @@ alloc_sd (uid_t uid, gid_t gid, const char *logsrv, int attribute,
for (DWORD i = 0; i < oacl->AceCount; ++i)
if (GetAce (oacl, i, (PVOID *) &ace))
{
PSID ace_sid = (PSID) &ace->SidStart;
cygsid ace_sid ((PSID) &ace->SidStart);
/* Check for related ACEs. */
if ((cur_owner_sid && EqualSid (ace_sid, cur_owner_sid))
|| (owner_sid && EqualSid (ace_sid, owner_sid))
|| (cur_group_sid && EqualSid (ace_sid, cur_group_sid))
|| (group_sid && EqualSid (ace_sid, group_sid))
|| (EqualSid (ace_sid, get_world_sid ())))
if ((cur_owner_sid && ace_sid == cur_owner_sid)
|| (owner_sid && ace_sid == owner_sid)
|| (cur_group_sid && ace_sid == cur_group_sid)
|| (group_sid && ace_sid == group_sid)
|| (ace_sid == get_world_sid ()))
continue;
/*
* Add unrelated ACCESS_DENIED_ACE to the beginning but

View File

@ -12,9 +12,46 @@ details. */
#define INHERIT_ALL (CONTAINER_INHERIT_ACE|OBJECT_INHERIT_ACE)
#define INHERIT_ONLY (INHERIT_ONLY_ACE|CONTAINER_INHERIT_ACE|OBJECT_INHERIT_ACE)
#define MAX_SID_LEN 40
class cygsid {
PSID psid;
char sbuf[MAX_SID_LEN];
public:
inline cygsid () : psid ((PSID) sbuf) {}
inline cygsid (PSID nsid) { *this = nsid; }
inline PSID set () { return psid = (PSID) sbuf; }
inline const PSID operator= (PSID nsid)
{
if (!nsid)
psid = NULL;
else
{
psid = (PSID) sbuf;
CopySid (MAX_SID_LEN, psid, nsid);
}
return psid;
}
inline BOOL operator== (PSID nsid)
{
if (!psid || !nsid)
return nsid == psid;
return EqualSid (psid, nsid);
}
inline operator const PSID () { return psid; }
};
extern BOOL allow_ntsec;
extern BOOL allow_smbntsec;
/* These both functions are needed to allow walking through the passwd
and group lists so they are somehow security related. Besides that
I didn't find a better place to declare them. */
extern struct passwd *internal_getpwent (int);
extern struct group *internal_getgrent (int);
/* File manipulation */
int __stdcall set_process_privileges ();
int __stdcall get_file_attribute (int, const char *, int *,

View File

@ -239,11 +239,10 @@ sec_user (PVOID sa_buf, PSID sid2, BOOL inherit)
((char *) sa_buf + sizeof (*psa));
PACL acl = (PACL) ((char *) sa_buf + sizeof (*psa) + sizeof (*psd));
char sid_buf[MAX_SID_LEN];
PSID sid = (PSID) sid_buf;
cygsid sid;
if (cygheap->user.sid ())
CopySid (MAX_SID_LEN, sid, (void *) cygheap->user.sid ());
sid = cygheap->user.sid ();
else if (! lookup_name (getlogin (), cygheap->user.logsrv (), sid))
return inherit ? &sec_none_nih : &sec_none;

View File

@ -1977,11 +1977,36 @@ seteuid (uid_t uid)
debug_printf ("Impersonate (uid == %d)", uid);
RevertToSelf ();
if (cygheap->user.token != INVALID_HANDLE_VALUE)
if (!ImpersonateLoggedOnUser (cygheap->user.token))
system_printf ("Impersonate (%d) in set (e)uid failed: %E",
cygheap->user.token);
else
cygheap->user.impersonated = TRUE;
{
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;
@ -2018,12 +2043,35 @@ setegid (gid_t gid)
{
if (gid != (gid_t) -1)
{
if (!getgrgid (gid))
struct group *gr;
if (!(gr = getgrgid (gid)))
{
set_errno (EINVAL);
return -1;
}
myself->gid = gid;
if (allow_ntsec)
{
cygsid gsid;
HANDLE ptok;
if (get_gr_sid (gsid, gr))
{
if (!OpenProcessToken (GetCurrentProcess (),
TOKEN_ADJUST_DEFAULT,
&ptok))
debug_printf ("OpenProcessToken(): %E\n");
else
{
if (!SetTokenInformation (ptok, TokenPrimaryGroup,
&gsid, sizeof gsid))
debug_printf ("SetTokenInformation(myself, "
"TokenPrimaryGroup): %E");
CloseHandle (ptok);
}
}
}
}
}
else

View File

@ -115,7 +115,7 @@ internal_getlogin (cygheap_user &user)
HANDLE ptok = user.token; /* Which is INVALID_HANDLE_VALUE if no
impersonation took place. */
DWORD siz;
char tu[1024];
cygsid tu;
int ret = 0;
/* Try to get the SID either from already impersonated token
@ -123,18 +123,14 @@ internal_getlogin (cygheap_user &user)
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_QUERY, &ptok))
&& !OpenProcessToken (GetCurrentProcess (),
TOKEN_ADJUST_DEFAULT | TOKEN_QUERY,
&ptok))
debug_printf ("OpenProcessToken(): %E\n");
else if (!GetTokenInformation (ptok, TokenUser, (LPVOID) &tu,
sizeof tu, &siz))
else if (!GetTokenInformation (ptok, TokenUser, &tu, sizeof tu, &siz))
debug_printf ("GetTokenInformation(): %E");
else if (!(ret = user.set_sid (((TOKEN_USER *) &tu)->User.Sid)))
else if (!(ret = user.set_sid (tu)))
debug_printf ("Couldn't retrieve SID from access token!");
/* Close token only if it's a result from OpenProcessToken(). */
if (ptok != INVALID_HANDLE_VALUE
&& user.token == INVALID_HANDLE_VALUE)
CloseHandle (ptok);
/* 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. */
@ -146,7 +142,7 @@ internal_getlogin (cygheap_user &user)
debug_printf ("Couldn't retrieve SID locally!");
}
/* If that failes, too, as a last resort try to get the SID from
/* 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 ())))
@ -154,11 +150,11 @@ internal_getlogin (cygheap_user &user)
/* If we have a SID, try to get the corresponding Cygwin user name
which can be different from the Windows user name. */
cygsid gsid (NULL);
if (ret)
{
struct passwd *pw;
char psidbuf[MAX_SID_LEN];
PSID psid = (PSID) psidbuf;
cygsid psid;
if (!strcasematch (user.name (), "SYSTEM")
&& user.domain () && user.logsrv ())
@ -166,14 +162,35 @@ internal_getlogin (cygheap_user &user)
if (get_registry_hive_path (user.sid (), buf))
setenv ("USERPROFILE", buf, 1);
}
while ((pw = getpwent ()) != NULL)
for (int pidx = 0; (pw = internal_getpwent (pidx)); ++pidx)
if (get_pw_sid (psid, pw) && EqualSid (user.sid (), psid))
{
user.set_name (pw->pw_name);
struct group *gr = getgrgid (pw->pw_gid);
if (gr)
if (!get_gr_sid (gsid.set (), gr))
gsid = NULL;
break;
}
endpwent ();
}
/* If this process is started from a non Cygwin process,
set token owner to the same value as token user and
primary group to the group which is set as primary group
in /etc/passwd. */
if (ptok != INVALID_HANDLE_VALUE && myself->ppid == 1)
{
if (!SetTokenInformation (ptok, TokenOwner, &tu, sizeof tu))
debug_printf ("SetTokenInformation(TokenOwner): %E");
if (gsid && !SetTokenInformation (ptok, TokenPrimaryGroup,
&gsid, sizeof gsid))
debug_printf ("SetTokenInformation(TokenPrimaryGroup): %E");
}
/* Close token only if it's a result from OpenProcessToken(). */
if (ptok != INVALID_HANDLE_VALUE
&& user.token == INVALID_HANDLE_VALUE)
CloseHandle (ptok);
}
}
debug_printf ("Cygwins Username: %s", user.name ());
@ -198,7 +215,10 @@ uinfo_init ()
if ((p = getpwnam (internal_getlogin (cygheap->user))) != NULL)
{
myself->uid = p->pw_uid;
myself->gid = p->pw_gid;
/* Set primary group only if ntsec is off or the process has been
started from a non cygwin process. */
if (!allow_ntsec || myself->ppid == 1)
myself->gid = p->pw_gid;
}
else
{

View File

@ -101,7 +101,6 @@ extern int dynamically_loaded;
#define DEFAULT_UID 500
#define DEFAULT_GID 544
#define MAX_SID_LEN 40
#define MAX_HOST_NAME 256
/* status bit manipulation */