* 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:
Christopher Faylor
2002-07-02 01:36:15 +00:00
parent cc81f456ac
commit 74fcdaec20
9 changed files with 508 additions and 153 deletions

View File

@ -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)