* fhandler.h (fhandler_base::fhaccess): Add parameter.
* security.h (check_file_access, check_registry_access): Likewise.
* security.cc (check_file_access, check_registry_access)
(check_access): Implement new parameter.
* fhandler.cc (fhandler_base::fhaccess): Likewise.
(device_access_denied): Update caller.
* syscalls.cc (access, faccessat): Update callers.
* spawn.cc (find_exec, fixup): Likewise.
+2009-09-25 Eric Blake <ebb9@byu.net>
+
+ * fhandler.h (fhandler_base::fhaccess): Add parameter.
+ * security.h (check_file_access, check_registry_access): Likewise.
+ * security.cc (check_file_access, check_registry_access)
+ (check_access): Implement new parameter.
+ * fhandler.cc (fhandler_base::fhaccess): Likewise.
+ (device_access_denied): Update caller.
+ * syscalls.cc (access, faccessat): Update callers.
+ * spawn.cc (find_exec, fixup): Likewise.
+
2009-09-24 Corinna Vinschen <corinna@vinschen.de>
* posix_ipc.cc (mq_open): Avoid closing the same descriptor twice in
if (!mode)
mode |= R_OK;
- return fhaccess (mode);
+ return fhaccess (mode, true);
}
int
-fhandler_base::fhaccess (int flags)
+fhandler_base::fhaccess (int flags, bool effective)
{
int res = -1;
if (error ())
goto eaccess_done;
else if (has_acls ())
{
- res = check_file_access (pc, flags);
+ res = check_file_access (pc, flags, effective);
goto done;
}
else if (get_device () == FH_REGISTRY && open (O_RDONLY, 0) && get_handle ())
{
- res = check_registry_access (get_handle (), flags);
+ res = check_registry_access (get_handle (), flags, effective);
close ();
return res;
}
if (flags & R_OK)
{
- if (st.st_uid == myself->uid)
+ if (st.st_uid == (effective ? myself->uid : cygheap->user.real_uid))
{
if (!(st.st_mode & S_IRUSR))
goto eaccess_done;
}
- else if (st.st_gid == myself->gid)
+ else if (st.st_gid == (effective ? myself->gid : cygheap->user.real_gid))
{
if (!(st.st_mode & S_IRGRP))
goto eaccess_done;
if (flags & W_OK)
{
- if (st.st_uid == myself->uid)
+ if (st.st_uid == (effective ? myself->uid : cygheap->user.real_uid))
{
if (!(st.st_mode & S_IWUSR))
goto eaccess_done;
}
- else if (st.st_gid == myself->gid)
+ else if (st.st_gid == (effective ? myself->gid : cygheap->user.real_gid))
{
if (!(st.st_mode & S_IWGRP))
goto eaccess_done;
if (flags & X_OK)
{
- if (st.st_uid == myself->uid)
+ if (st.st_uid == (effective ? myself->uid : cygheap->user.real_uid))
{
if (!(st.st_mode & S_IXUSR))
goto eaccess_done;
}
- else if (st.st_gid == myself->gid)
+ else if (st.st_gid == (effective ? myself->gid : cygheap->user.real_gid))
{
if (!(st.st_mode & S_IXGRP))
goto eaccess_done;
bool is_fs_special () {return pc.is_fs_special ();}
bool issymlink () {return pc.issymlink ();}
bool device_access_denied (int) __attribute__ ((regparm (2)));
- int fhaccess (int flags) __attribute__ ((regparm (2)));
+ int fhaccess (int flags, bool) __attribute__ ((regparm (3)));
};
class fhandler_mailslot : public fhandler_base
/* security.cc: NT file access control functions
Copyright 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
- 2006, 2007 Red Hat, Inc.
+ 2006, 2007, 2008, 2009 Red Hat, Inc.
Originaly written by Gunther Ebert, gunther.ebert@ixos-leipzig.de
Completely rewritten by Corinna Vinschen <corinna@vinschen.de>
static int
check_access (security_descriptor &sd, GENERIC_MAPPING &mapping,
- DWORD desired, int flags)
+ DWORD desired, int flags, bool effective)
{
int ret = -1;
BOOL status;
DWORD granted;
DWORD plen = sizeof (PRIVILEGE_SET) + 3 * sizeof (LUID_AND_ATTRIBUTES);
PPRIVILEGE_SET pset = (PPRIVILEGE_SET) alloca (plen);
- HANDLE tok = cygheap->user.issetuid () ? cygheap->user.imp_token ()
- : hProcImpToken;
+ HANDLE tok = ((effective && cygheap->user.issetuid ())
+ ? cygheap->user.imp_token ()
+ : hProcImpToken);
if (!tok && !DuplicateTokenEx (hProcToken, MAXIMUM_ALLOWED, NULL,
SecurityImpersonation, TokenImpersonation,
}
int
-check_file_access (path_conv &pc, int flags)
+check_file_access (path_conv &pc, int flags, bool effective)
{
security_descriptor sd;
int ret = -1;
if (flags & X_OK)
desired |= FILE_EXECUTE;
if (!get_file_sd (NULL, pc, sd))
- ret = check_access (sd, mapping, desired, flags);
+ ret = check_access (sd, mapping, desired, flags, effective);
debug_printf ("flags %x, ret %d", flags, ret);
return ret;
}
int
-check_registry_access (HANDLE hdl, int flags)
+check_registry_access (HANDLE hdl, int flags, bool effective)
{
security_descriptor sd;
int ret = -1;
if (flags & X_OK)
desired |= KEY_QUERY_VALUE;
if (!get_reg_sd (hdl, sd))
- ret = check_access (sd, mapping, desired, flags);
+ ret = check_access (sd, mapping, desired, flags, effective);
/* As long as we can't write the registry... */
if (flags & W_OK)
{
bool is_chown);
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);
-int __stdcall check_file_access (path_conv &, int);
-int __stdcall check_registry_access (HANDLE, int);
+int __stdcall check_file_access (path_conv &, int, bool);
+int __stdcall check_registry_access (HANDLE, int, bool);
void set_security_attribute (path_conv &pc, int attribute,
PSECURITY_ATTRIBUTES psa,
if ((suffix = perhaps_suffix (tmp, buf, err, opt)) != NULL)
{
- if (buf.has_acls () && check_file_access (buf, X_OK))
+ if (buf.has_acls () && check_file_access (buf, X_OK, true))
continue;
if (posix == tmp)
/* Check if script is executable. Otherwise we start non-executable
scripts successfully, which is incorrect behaviour. */
- if (real_path.has_acls () && check_file_access (real_path, X_OK) < 0)
+ if (real_path.has_acls ()
+ && check_file_access (real_path, X_OK, true) < 0)
return -1; /* errno is already set. */
/* Replace argv[0] with the full path to the script if this is the
fhandler_base *fh = build_fh_name (fn, NULL, PC_SYM_FOLLOW, stat_suffixes);
if (fh)
{
- res = fh->fhaccess (flags);
+ res = fh->fhaccess (flags, false);
delete fh;
}
}
stat_suffixes);
if (fh)
{
- res = fh->fhaccess (mode);
+ res = fh->fhaccess (mode, flags & AT_EACCESS);
delete fh;
}
}