Welcome to mirror list, hosted at ThFree Co, Russian Federation.

cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristopher Faylor <me@cgf.cx>2002-07-02 05:36:15 +0400
committerChristopher Faylor <me@cgf.cx>2002-07-02 05:36:15 +0400
commit74fcdaec2071bb23c090bc13b9cfd0c4765ed3bd (patch)
treed3b434a7db3a5299525ed8741601bd646e1ffb3a /winsup/cygwin/security.cc
parentcc81f456ac9c552bf50e15df7181271c226d908b (diff)
* 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.
Diffstat (limited to 'winsup/cygwin/security.cc')
-rw-r--r--winsup/cygwin/security.cc169
1 files changed, 169 insertions, 0 deletions
diff --git a/winsup/cygwin/security.cc b/winsup/cygwin/security.cc
index f5516aa60..c7dfbbefa 100644
--- a/winsup/cygwin/security.cc
+++ b/winsup/cygwin/security.cc
@@ -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)