* autoload.cc (GetSecurityInfo): Define new autoload function.
(RegQueryInfoKeyA): Ditto. * fhandler.h (fhandler_virtual::fill_filebuf): Change return type to bool. (fhandler_proc::fill_filebuf): Ditto. (fhandler_registry::fill_filebuf): Ditto. (fhandler_process::fill_filebuf): Ditto. (fhandler_registry::value_name): Add new member. (fhandler_registry::close): Add new method. (fhandler_process::p): Remove member. * fhandler_proc.cc (fhandler_proc::open): Add set_nohandle after calling superclass method. Check return value of fill_filebuf. (fhandler_proc::fill_filebuf): Change return type to bool. Add return statement. * fhandler_process.cc (fhandler_process::open): Add set_nohandle after calling superclass method. Remove references to p. Check return value of fill_filebuf. (fhandler_process::fill_filebuf): Change return type to bool. Don't use dereference operator on p. Add return statement. (fhandler_process::format_process_stat): Fix typo. * fhandler_registry.cc: Add static open_key declaration. (fhandler_registry::exists): Assume path is already normalised. Try opening the path as a key in its own right first, before reverting to enumerating subkeys and values of the parent key. (fhandler_registry::fstat): Add additional code to return more relevant information about the registry key/value. (fhandler_registry::readdir): Explicitly set desired access when opening registry key. Remove output of buf from debug_printf format string. (fhandler_registry::open): Use set_io_handle to store registry key handle. Set value_name member. Move code to read a value from the registry to fill_filebuf. Add call to fill_filebuf. (fhandler_registry::close): New method. (fhandler_registry::fill_filebuf): Change return type to bool. Add code to read a value from registry. (fhandler_registry::open_key): Make function static. Use KEY_READ as desired access unless this is the last path component. Check the return value of RegOpenKeyEx for an error instead of hKey. * fhandler_virtual.cc (fhandler_virtual::lseek): Check the return value of fill_filebuf. (fhandler_virtual::open): Remove call to set_nohandle. (fhandler_virtual::fill_filebuf): Change return type to bool. Add return statement. * security.cc (get_nt_object_attribute): New function. (get_object_attribute): New function. * security.h (get_object_attribute): New function declaration.
This commit is contained in:
@ -28,6 +28,7 @@ details. */
|
||||
#include <wininet.h>
|
||||
#include <ntsecapi.h>
|
||||
#include <subauth.h>
|
||||
#include <aclapi.h>
|
||||
#include "cygerrno.h"
|
||||
#include "security.h"
|
||||
#include "fhandler.h"
|
||||
@ -1301,6 +1302,174 @@ get_file_attribute (int use_ntsec, const char *file,
|
||||
return res > 0 ? 0 : -1;
|
||||
}
|
||||
|
||||
static int
|
||||
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;
|
||||
|
||||
PSECURITY_DESCRIPTOR psd = NULL;
|
||||
PSID owner_sid;
|
||||
PSID group_sid;
|
||||
PACL acl;
|
||||
|
||||
if (ERROR_SUCCESS != GetSecurityInfo (handle, object_type,
|
||||
DACL_SECURITY_INFORMATION |
|
||||
GROUP_SECURITY_INFORMATION |
|
||||
OWNER_SECURITY_INFORMATION,
|
||||
&owner_sid,
|
||||
&group_sid,
|
||||
&acl,
|
||||
NULL,
|
||||
&psd))
|
||||
{
|
||||
__seterrno ();
|
||||
debug_printf ("GetSecurityInfo %E");
|
||||
return -1;
|
||||
}
|
||||
|
||||
__uid32_t uid = cygsid (owner_sid).get_uid ();
|
||||
__gid32_t gid = cygsid (group_sid).get_gid ();
|
||||
if (uidret)
|
||||
*uidret = uid;
|
||||
if (gidret)
|
||||
*gidret = gid;
|
||||
|
||||
if (!attribute)
|
||||
{
|
||||
syscall_printf ("uid %d, gid %d", uid, gid);
|
||||
LocalFree (psd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
BOOL grp_member = is_grp_member (uid, gid);
|
||||
|
||||
if (!acl)
|
||||
{
|
||||
*attribute |= S_IRWXU | S_IRWXG | S_IRWXO;
|
||||
syscall_printf ("No ACL = %x, uid %d, gid %d",
|
||||
*attribute, uid, gid);
|
||||
LocalFree (psd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
ACCESS_ALLOWED_ACE *ace;
|
||||
int allow = 0;
|
||||
int deny = 0;
|
||||
int *flags, *anti;
|
||||
|
||||
for (DWORD i = 0; i < acl->AceCount; ++i)
|
||||
{
|
||||
if (!GetAce (acl, i, (PVOID *) &ace))
|
||||
continue;
|
||||
if (ace->Header.AceFlags & INHERIT_ONLY_ACE)
|
||||
continue;
|
||||
switch (ace->Header.AceType)
|
||||
{
|
||||
case ACCESS_ALLOWED_ACE_TYPE:
|
||||
flags = &allow;
|
||||
anti = &deny;
|
||||
break;
|
||||
case ACCESS_DENIED_ACE_TYPE:
|
||||
flags = &deny;
|
||||
anti = &allow;
|
||||
break;
|
||||
default:
|
||||
continue;
|
||||
}
|
||||
|
||||
cygsid ace_sid ((PSID) &ace->SidStart);
|
||||
if (owner_sid && ace_sid == owner_sid)
|
||||
{
|
||||
if (ace->Mask & FILE_READ_DATA)
|
||||
*flags |= S_IRUSR;
|
||||
if (ace->Mask & FILE_WRITE_DATA)
|
||||
*flags |= S_IWUSR;
|
||||
if (ace->Mask & FILE_EXECUTE)
|
||||
*flags |= S_IXUSR;
|
||||
}
|
||||
else if (group_sid && ace_sid == group_sid)
|
||||
{
|
||||
if (ace->Mask & FILE_READ_DATA)
|
||||
*flags |= S_IRGRP
|
||||
| ((grp_member && !(*anti & S_IRUSR)) ? S_IRUSR : 0);
|
||||
if (ace->Mask & FILE_WRITE_DATA)
|
||||
*flags |= S_IWGRP
|
||||
| ((grp_member && !(*anti & S_IWUSR)) ? S_IWUSR : 0);
|
||||
if (ace->Mask & FILE_EXECUTE)
|
||||
*flags |= S_IXGRP
|
||||
| ((grp_member && !(*anti & S_IXUSR)) ? S_IXUSR : 0);
|
||||
}
|
||||
else if (ace_sid == well_known_world_sid)
|
||||
{
|
||||
if (ace->Mask & FILE_READ_DATA)
|
||||
*flags |= S_IROTH
|
||||
| ((!(*anti & S_IRGRP)) ? S_IRGRP : 0)
|
||||
| ((!(*anti & S_IRUSR)) ? S_IRUSR : 0);
|
||||
if (ace->Mask & FILE_WRITE_DATA)
|
||||
*flags |= S_IWOTH
|
||||
| ((!(*anti & S_IWGRP)) ? S_IWGRP : 0)
|
||||
| ((!(*anti & S_IWUSR)) ? S_IWUSR : 0);
|
||||
if (ace->Mask & FILE_EXECUTE)
|
||||
{
|
||||
*flags |= S_IXOTH
|
||||
| ((!(*anti & S_IXGRP)) ? S_IXGRP : 0)
|
||||
| ((!(*anti & S_IXUSR)) ? S_IXUSR : 0);
|
||||
}
|
||||
if ((*attribute & S_IFDIR) &&
|
||||
(ace->Mask & (FILE_WRITE_DATA | FILE_EXECUTE | FILE_DELETE_CHILD))
|
||||
== (FILE_WRITE_DATA | FILE_EXECUTE))
|
||||
*flags |= S_ISVTX;
|
||||
}
|
||||
else if (ace_sid == well_known_null_sid)
|
||||
{
|
||||
/* Read SUID, SGID and VTX bits from NULL ACE. */
|
||||
if (ace->Mask & FILE_READ_DATA)
|
||||
*flags |= S_ISVTX;
|
||||
if (ace->Mask & FILE_WRITE_DATA)
|
||||
*flags |= S_ISGID;
|
||||
if (ace->Mask & FILE_APPEND_DATA)
|
||||
*flags |= S_ISUID;
|
||||
}
|
||||
}
|
||||
*attribute &= ~(S_IRWXU | S_IRWXG | S_IRWXO | S_ISVTX | S_ISGID | S_ISUID);
|
||||
*attribute |= allow;
|
||||
*attribute &= ~deny;
|
||||
|
||||
LocalFree (psd);
|
||||
|
||||
syscall_printf ("%x, uid %d, gid %d", *attribute, uid, gid);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
get_object_attribute (HANDLE handle, SE_OBJECT_TYPE object_type,
|
||||
int *attribute, __uid32_t *uidret, __gid32_t *gidret)
|
||||
{
|
||||
if (allow_ntsec)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
if (uidret)
|
||||
*uidret = getuid32 ();
|
||||
if (gidret)
|
||||
*gidret = getgid32 ();
|
||||
|
||||
if (!attribute)
|
||||
return 0;
|
||||
|
||||
/* symlinks are everything for everyone!*/
|
||||
if ((*attribute & S_IFLNK) == S_IFLNK)
|
||||
*attribute |= S_IRWXU | S_IRWXG | S_IRWXO;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
BOOL
|
||||
add_access_allowed_ace (PACL acl, int offset, DWORD attributes,
|
||||
PSID sid, size_t &len_add, DWORD inherit)
|
||||
|
Reference in New Issue
Block a user