* 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:
parent
3a6e96682d
commit
d551169a9f
|
@ -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.
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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];
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 *,
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
{
|
||||
|
|
|
@ -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 */
|
||||
|
|
Loading…
Reference in New Issue