OSDN Git Service

* fhandler.cc (fhandler_base::open): Simplify access evaluation
authorcorinna <corinna>
Wed, 14 Apr 2004 16:36:25 +0000 (16:36 +0000)
committercorinna <corinna>
Wed, 14 Apr 2004 16:36:25 +0000 (16:36 +0000)
expression.
(fhandler_base::facl): New method.
* fhandler.h: Declare facl method in fhandler_base,
fhandler_disk_file and fhandler_virtual.
* fhandler_disk_file.cc (fhandler_disk_file::facl): New method.
* fhandler_virtual.cc (fhandler_virtual::facl): New method.
* sec_acl.cc: Remove forward declaration for aclsort32 and acl32.
(setacl): Remove static.  Add and use handle parameter.
(getacl): Ditto.
(acl_worker): Reorganize to call fhandler's facl method eventually.
(facl32): Ditto.
* security.cc (get_nt_object_security): Remove static.
* security.h: Add extern declarations for get_nt_object_security,
aclsort32, acl32, getacl and setacl.

Apply missing syscalls.cc patch and ChangeLog of previous check in.
* syscalls.cc (chown_worker): Reorganize to call fhandler's fchown
method eventually.
(fchown): Ditto.

winsup/cygwin/ChangeLog
winsup/cygwin/fhandler.cc
winsup/cygwin/fhandler.h
winsup/cygwin/fhandler_disk_file.cc
winsup/cygwin/fhandler_virtual.cc
winsup/cygwin/sec_acl.cc
winsup/cygwin/security.cc
winsup/cygwin/security.h
winsup/cygwin/syscalls.cc

index 7ee5de3..a93aa27 100644 (file)
@@ -1,5 +1,23 @@
 2004-04-14  Corinna Vinschen  <corinna@vinschen.de>
 
+       * fhandler.cc (fhandler_base::open): Simplify access evaluation
+       expression.
+       (fhandler_base::facl): New method.
+       * fhandler.h: Declare facl method in fhandler_base,
+       fhandler_disk_file and fhandler_virtual.
+       * fhandler_disk_file.cc (fhandler_disk_file::facl): New method.
+       * fhandler_virtual.cc (fhandler_virtual::facl): New method.
+       * sec_acl.cc: Remove forward declaration for aclsort32 and acl32.
+       (setacl): Remove static.  Add and use handle parameter.
+       (getacl): Ditto.
+       (acl_worker): Reorganize to call fhandler's facl method eventually.
+       (facl32): Ditto.
+       * security.cc (get_nt_object_security): Remove static.
+       * security.h: Add extern declarations for get_nt_object_security,
+       aclsort32, acl32, getacl and setacl.
+
+2004-04-14  Corinna Vinschen  <corinna@vinschen.de>
+
        * fhandler.cc (fhandler_base::open): Accomodate query_write_control
        query_state.
        (fhandler_base::fchown): New method.
@@ -17,6 +35,9 @@
        NtSetSecurityObject failed or handle is NULL.
        (set_nt_attribute): Call write_sd with additional handle attribute.
        * security.h (write_sd): Declare with additional handle argument.
+       * syscalls.cc (chown_worker): Reorganize to call fhandler's fchown
+       method eventually.
+       (fchown): Ditto.
 
 2004-04-14  Corinna Vinschen  <corinna@vinschen.de>
 
index b93102d..af9d633 100644 (file)
@@ -13,6 +13,7 @@ details. */
 #include <stdlib.h>
 #include <sys/cygwin.h>
 #include <sys/uio.h>
+#include <sys/acl.h>
 #include <signal.h>
 #include "cygerrno.h"
 #include "perprocess.h"
@@ -442,27 +443,28 @@ fhandler_base::open (int flags, mode_t mode)
       goto done;
     }
 
-  if (query_open ())
-    switch (query_open ())
-      {
-       case query_null_access:
-         access = 0;
-         break;
-       case query_read_control:
-         access = READ_CONTROL;
-         break;
-       case query_write_control:
-         access = READ_CONTROL | WRITE_OWNER | WRITE_DAC;
-         break;
-      }
-  else if (get_major () == DEV_TAPE_MAJOR)
-    access = GENERIC_READ | GENERIC_WRITE;
-  else if ((flags & (O_RDONLY | O_WRONLY | O_RDWR)) == O_RDONLY)
-    access = GENERIC_READ;
-  else if ((flags & (O_RDONLY | O_WRONLY | O_RDWR)) == O_WRONLY)
-    access = GENERIC_WRITE;
-  else
-    access = GENERIC_READ | GENERIC_WRITE;
+  switch (query_open ())
+    {
+      case query_null_access:
+       access = 0;
+       break;
+      case query_read_control:
+       access = READ_CONTROL;
+       break;
+      case query_write_control:
+       access = READ_CONTROL | WRITE_OWNER | WRITE_DAC;
+       break;
+      default:
+       if (get_major () == DEV_TAPE_MAJOR)
+         access = GENERIC_READ | GENERIC_WRITE;
+       else if ((flags & (O_RDONLY | O_WRONLY | O_RDWR)) == O_RDONLY)
+         access = GENERIC_READ;
+       else if ((flags & (O_RDONLY | O_WRONLY | O_RDWR)) == O_WRONLY)
+         access = GENERIC_WRITE;
+       else
+         access = GENERIC_READ | GENERIC_WRITE;
+        break;
+    }
 
   /* Allow reliable lseek on disk devices. */
   if (get_major () == DEV_FLOPPY_MAJOR)
@@ -1429,3 +1431,10 @@ fhandler_base::fchown (__uid32_t uid, __gid32_t gid)
   /* By default, just succeeds. */
   return 0;
 }
+
+int
+fhandler_base::facl (int cmd, int nentries, __aclent32_t *aclbufp)
+{
+  /* By default, just succeeds. */
+  return 0;
+}
index 0ee198c..3e27b7b 100644 (file)
@@ -35,6 +35,7 @@ class fhandler_disk_file;
 typedef struct __DIR DIR;
 struct dirent;
 struct iovec;
+struct __acl32;
 
 enum conn_state
 {
@@ -245,6 +246,7 @@ class fhandler_base
   int __stdcall fstat_by_name (struct __stat64 *buf) __attribute__ ((regparm (2)));
   virtual int __stdcall fchmod (mode_t mode) __attribute__ ((regparm (1)));
   virtual int __stdcall fchown (__uid32_t uid, __gid32_t gid) __attribute__ ((regparm (2)));
+  virtual int __stdcall facl (int, int, __acl32 *) __attribute__ ((regparm (3)));
   virtual int ioctl (unsigned int cmd, void *);
   virtual int fcntl (int cmd, void *);
   virtual char const *ttyname () { return get_name (); }
@@ -571,6 +573,7 @@ class fhandler_disk_file: public fhandler_base
   int __stdcall fstat (struct __stat64 *buf) __attribute__ ((regparm (2)));
   int __stdcall fchmod (mode_t mode) __attribute__ ((regparm (1)));
   int __stdcall fchown (__uid32_t uid, __gid32_t gid) __attribute__ ((regparm (2)));
+  int __stdcall facl (int, int, __acl32 *) __attribute__ ((regparm (3)));
 
   HANDLE mmap (caddr_t *addr, size_t len, DWORD access, int flags, _off64_t off);
   int munmap (HANDLE h, caddr_t addr, size_t len);
@@ -1105,6 +1108,7 @@ class fhandler_virtual : public fhandler_base
   int __stdcall fstat (struct stat *buf) __attribute__ ((regparm (2)));
   int __stdcall fchmod (mode_t mode) __attribute__ ((regparm (1)));
   int __stdcall fchown (__uid32_t uid, __gid32_t gid) __attribute__ ((regparm (2)));
+  int __stdcall facl (int, int, __acl32 *) __attribute__ ((regparm (3)));
   virtual bool fill_filebuf ();
   void fixup_after_exec ();
 };
index f649d4d..b330a96 100644 (file)
@@ -12,6 +12,7 @@ details. */
 #include <unistd.h>
 #include <stdlib.h>
 #include <sys/cygwin.h>
+#include <sys/acl.h>
 #include <signal.h>
 #include "cygerrno.h"
 #include "perprocess.h"
@@ -445,6 +446,83 @@ fhandler_disk_file::fchown (__uid32_t uid, __gid32_t gid)
   return res;
 }
 
+int _stdcall
+fhandler_disk_file::facl (int cmd, int nentries, __aclent32_t *aclbufp)
+{
+  int res = -1;
+  int oret = 0;
+
+  if (!get_io_handle ())
+    {
+      query_open (query_write_control);
+      if (!(oret = open_fs (O_BINARY, 0)))
+        return -1;
+    }
+
+  if (!pc.has_acls () || !allow_ntsec)
+    {
+      switch (cmd)
+        {
+         struct __stat64 st;
+
+         case SETACL:
+           set_errno (ENOSYS);
+           break;
+         case GETACL:
+           if (!aclbufp)
+             set_errno(EFAULT);
+           else if (nentries < MIN_ACL_ENTRIES)
+             set_errno (ENOSPC);
+           else if (!fstat_by_handle (&st))
+             {
+               aclbufp[0].a_type = USER_OBJ;
+               aclbufp[0].a_id = st.st_uid;
+               aclbufp[0].a_perm = (st.st_mode & S_IRWXU) >> 6;
+               aclbufp[1].a_type = GROUP_OBJ;
+               aclbufp[1].a_id = st.st_gid;
+               aclbufp[1].a_perm = (st.st_mode & S_IRWXG) >> 3;
+               aclbufp[2].a_type = OTHER_OBJ;
+               aclbufp[2].a_id = ILLEGAL_GID;
+               aclbufp[2].a_perm = st.st_mode & S_IRWXO;
+               aclbufp[3].a_type = CLASS_OBJ; 
+               aclbufp[3].a_id = ILLEGAL_GID;
+               aclbufp[3].a_perm = S_IRWXU | S_IRWXG | S_IRWXO;
+               res = MIN_ACL_ENTRIES;
+             }
+           break;
+         case GETACLCNT:
+           res = MIN_ACL_ENTRIES;
+           break;
+       }
+    }
+  else
+    {
+      switch (cmd)
+       {
+         case SETACL:
+           if (!aclsort32 (nentries, 0, aclbufp))
+             res = setacl (get_io_handle (), pc, nentries, aclbufp);
+           break;
+         case GETACL:
+           if (!aclbufp)
+             set_errno(EFAULT);
+           else
+             res = getacl (get_io_handle (), pc, pc, nentries, aclbufp);
+           break;
+         case GETACLCNT:
+           res = getacl (get_io_handle (), pc, pc, 0, NULL);
+         default:
+           set_errno (EINVAL);
+           break;
+       }
+    }
+
+  if (oret)
+    close_fs ();
+
+  return res;
+}
+
 fhandler_disk_file::fhandler_disk_file () :
   fhandler_base ()
 {
index 16b8392..fa3d2ed 100644 (file)
@@ -12,6 +12,7 @@ details. */
 #include <unistd.h>
 #include <stdlib.h>
 #include <sys/cygwin.h>
+#include <sys/acl.h>
 #include "cygerrno.h"
 #include "security.h"
 #include "path.h"
@@ -242,3 +243,11 @@ fhandler_virtual::fchown (__uid32_t uid, __gid32_t gid)
   set_errno (EPERM);
   return -1;
 }
+
+int
+fhandler_virtual::facl (int cmd, int nentries, __aclent32_t *aclbufp)
+{
+  /* Same as on Linux. */
+  set_errno (EPERM);
+  return -1;
+}
index a8dbe2f..e5e0589 100644 (file)
@@ -31,9 +31,6 @@ details. */
 #include "cygheap.h"
 #include "pwdgrp.h"
 
-extern "C" int aclsort32 (int nentries, int, __aclent32_t *aclbufp);
-extern "C" int acl32 (const char *path, int cmd, int nentries, __aclent32_t *aclbufp);
-
 static int
 searchace (__aclent32_t *aclp, int nentries, int type, __uid32_t id = ILLEGAL_UID)
 {
@@ -46,12 +43,13 @@ searchace (__aclent32_t *aclp, int nentries, int type, __uid32_t id = ILLEGAL_UI
   return -1;
 }
 
-static int
-setacl (const char *file, int nentries, __aclent32_t *aclbufp)
+int
+setacl (HANDLE handle, const char *file, int nentries, __aclent32_t *aclbufp)
 {
   security_descriptor sd_ret;
 
-  if (read_sd (file, sd_ret) <= 0)
+  if ((!handle || get_nt_object_security (handle, SE_FILE_OBJECT, sd_ret))
+      && read_sd (file, sd_ret) <= 0)
     {
       debug_printf ("read_sd %E");
       return -1;
@@ -223,7 +221,7 @@ setacl (const char *file, int nentries, __aclent32_t *aclbufp)
       return -1;
     }
   debug_printf ("Created SD-Size: %d", sd_ret.size ());
-  return write_sd (NULL, file, sd_ret);
+  return write_sd (handle, file, sd_ret);
 }
 
 /* Temporary access denied bits */
@@ -257,13 +255,15 @@ getace (__aclent32_t &acl, int type, int id, DWORD win_ace_mask,
       acl.a_perm |= DENY_X;
 }
 
-static int
-getacl (const char *file, DWORD attr, int nentries, __aclent32_t *aclbufp)
+int
+getacl (HANDLE handle, const char *file, DWORD attr, int nentries,
+       __aclent32_t *aclbufp)
 {
   security_descriptor sd;
 
   int ret;
-  if ((ret = read_sd (file, sd)) <= 0)
+  if (!handle || get_nt_object_security (handle, SE_FILE_OBJECT, sd)
+      && (ret = read_sd (file, sd)) <= 0)
     {
       debug_printf ("read_sd %E");
       return ret;
@@ -409,93 +409,33 @@ getacl (const char *file, DWORD attr, int nentries, __aclent32_t *aclbufp)
 
 static int
 acl_worker (const char *path, int cmd, int nentries, __aclent32_t *aclbufp,
-           int nofollow)
+           unsigned fmode)
 {
   extern suffix_info stat_suffixes[];
-  path_conv real_path (path, (nofollow ? PC_SYM_NOFOLLOW : PC_SYM_FOLLOW) | PC_FULL, stat_suffixes);
-  if (real_path.error)
-    {
-      set_errno (real_path.error);
-      syscall_printf ("-1 = acl (%s)", path);
-      return -1;
-    }
-  if (!real_path.has_acls () || !allow_ntsec)
-    {
-      struct __stat64 st;
-      int ret = -1;
-
-      switch (cmd)
-       {
-       case SETACL:
-         set_errno (ENOSYS);
-         break;
-       case GETACL:
-         if (!aclbufp)
-           set_errno(EFAULT);
-         else if (nentries < MIN_ACL_ENTRIES)
-           set_errno (ENOSPC);
-         else if ((nofollow && !lstat64 (path, &st))
-                  || (!nofollow && !stat64 (path, &st)))
-           {
-             aclbufp[0].a_type = USER_OBJ;
-             aclbufp[0].a_id = st.st_uid;
-             aclbufp[0].a_perm = (st.st_mode & S_IRWXU) >> 6;
-             aclbufp[1].a_type = GROUP_OBJ;
-             aclbufp[1].a_id = st.st_gid;
-             aclbufp[1].a_perm = (st.st_mode & S_IRWXG) >> 3;
-             aclbufp[2].a_type = OTHER_OBJ;
-             aclbufp[2].a_id = ILLEGAL_GID;
-             aclbufp[2].a_perm = st.st_mode & S_IRWXO;
-             aclbufp[3].a_type = CLASS_OBJ;
-             aclbufp[3].a_id = ILLEGAL_GID;
-             aclbufp[3].a_perm = S_IRWXU | S_IRWXG | S_IRWXO;
-             ret = MIN_ACL_ENTRIES;
-           }
-         break;
-       case GETACLCNT:
-         ret = MIN_ACL_ENTRIES;
-         break;
-       }
-      syscall_printf ("%d = acl (%s)", ret, path);
-      return ret;
-    }
-  switch (cmd)
+  int res = -1;
+  fhandler_base *fh = build_fh_name (path, NULL, fmode | PC_FULL,
+                                    stat_suffixes);
+  if (fh->error ())
     {
-      case SETACL:
-       if (!aclsort32 (nentries, 0, aclbufp))
-         return setacl (real_path.get_win32 (),
-                        nentries, aclbufp);
-       break;
-      case GETACL:
-       if (!aclbufp)
-         set_errno(EFAULT);
-       else
-         return getacl (real_path.get_win32 (),
-                        real_path.file_attributes (),
-                        nentries, aclbufp);
-       break;
-      case GETACLCNT:
-       return getacl (real_path.get_win32 (),
-                      real_path.file_attributes (),
-                      0, NULL);
-      default:
-       set_errno (EINVAL);
-       break;
+      debug_printf ("got %d error from build_fh_name", fh->error ());
+      set_errno (fh->error ());
     }
-  syscall_printf ("-1 = acl (%s)", path);
-  return -1;
+  else
+    res = fh->facl (cmd, nentries, aclbufp);
+  syscall_printf ("%d = acl (%s)", res, path);
+  return res;
 }
 
 extern "C" int
 acl32 (const char *path, int cmd, int nentries, __aclent32_t *aclbufp)
 {
-  return acl_worker (path, cmd, nentries, aclbufp, 0);
+  return acl_worker (path, cmd, nentries, aclbufp, PC_SYM_FOLLOW);
 }
 
 extern "C" int
 lacl32 (const char *path, int cmd, int nentries, __aclent32_t *aclbufp)
 {
-  return acl_worker (path, cmd, nentries, aclbufp, 1);
+  return acl_worker (path, cmd, nentries, aclbufp, PC_SYM_NOFOLLOW);
 }
 
 extern "C" int
@@ -507,15 +447,9 @@ facl32 (int fd, int cmd, int nentries, __aclent32_t *aclbufp)
       syscall_printf ("-1 = facl (%d)", fd);
       return -1;
     }
-  const char *path = cfd->get_name ();
-  if (path == NULL)
-    {
-      syscall_printf ("-1 = facl (%d) (no name)", fd);
-      set_errno (ENOSYS);
-      return -1;
-    }
-  syscall_printf ("facl (%d): calling acl (%s)", fd, path);
-  return acl_worker (path, cmd, nentries, aclbufp, 0);
+  int res = cfd->facl (cmd, nentries, aclbufp);
+  syscall_printf ("%d = facl (%s) )", res, cfd->get_name ());
+  return res;
 }
 
 extern "C" int
index 0915a77..c0ad954 100644 (file)
@@ -1341,7 +1341,7 @@ get_nt_attribute (const char *file, mode_t *attribute,
   get_info_from_sd (sd, attribute, uidret, gidret);
 }
 
-static int
+int
 get_nt_object_security (HANDLE handle, SE_OBJECT_TYPE object_type,
                        security_descriptor &sd_ret)
 {
index e81a8d8..df78775 100644 (file)
@@ -253,6 +253,8 @@ int __stdcall get_file_attribute (int, HANDLE, const char *, mode_t *,
                                  __uid32_t * = NULL, __gid32_t * = NULL);
 int __stdcall set_file_attribute (bool, HANDLE, const char *, int);
 int __stdcall set_file_attribute (bool, HANDLE, const char *, __uid32_t, __gid32_t, int);
+int __stdcall get_nt_object_security (HANDLE, SE_OBJECT_TYPE,
+                                     security_descriptor &);
 int __stdcall get_object_attribute (HANDLE handle, SE_OBJECT_TYPE object_type, mode_t *,
                                  __uid32_t * = NULL, __gid32_t * = NULL);
 LONG __stdcall read_sd (const char *file, security_descriptor &sd);
@@ -266,6 +268,13 @@ void set_security_attribute (int attribute, PSECURITY_ATTRIBUTES psa,
 
 bool get_sids_info (cygpsid, cygpsid, __uid32_t * , __gid32_t *);
 
+/* sec_acl.cc */
+struct __acl32;
+extern "C" int aclsort32 (int, int, __acl32 *);
+extern "C" int acl32 (const char *, int, int, __acl32 *);
+int getacl (HANDLE, const char *, DWORD, int, __acl32 *);
+int setacl (HANDLE, const char *, int, __acl32 *);
+
 /* Try a subauthentication. */
 HANDLE subauth (struct passwd *pw);
 /* Try creating a token directly. */
index 237e537..5f1b58e 100644 (file)
@@ -823,50 +823,20 @@ done:
 static int
 chown_worker (const char *name, unsigned fmode, __uid32_t uid, __gid32_t gid)
 {
-  int res;
-
-  if (check_null_empty_str_errno (name))
-    return -1;
-
   if (!wincap.has_security ())  // real chown only works on NT
-    res = 0;                   // return zero (and do nothing) under Windows 9x
-  else
-    {
-      /* we need Win32 path names because of usage of Win32 API functions */
-      path_conv win32_path (PC_NONULLEMPTY, name, fmode);
-
-      if (win32_path.error)
-       {
-         set_errno (win32_path.error);
-         res = -1;
-         goto done;
-       }
-
-      /* FIXME: This makes chown on a device succeed always.  Someday we'll want
-        to actually allow chown to work properly on devices. */
-      if (win32_path.is_auto_device () && !win32_path.issocket ())
-       {
-         res = 0;
-         goto done;
-       }
+    return 0;                  // return zero (and do nothing) under Windows 9x
 
-      mode_t attrib = 0;
-      if (win32_path.isdir ())
-       attrib |= S_IFDIR;
-      res = get_file_attribute (win32_path.has_acls (), NULL,
-                               win32_path.get_win32 (), &attrib);
-      if (!res)
-        res = set_file_attribute (win32_path.has_acls (), NULL, win32_path,
-                                  uid, gid, attrib);
-      if (res != 0 && (!win32_path.has_acls () || !allow_ntsec))
-       {
-         /* fake - if not supported, pretend we're like win95
-            where it just works */
-         res = 0;
-       }
+  int res = -1;
+  fhandler_base *fh = build_fh_name (name, NULL, fmode | PC_FULL,
+                                    stat_suffixes);
+  if (fh->error ())
+    {
+      debug_printf ("got %d error from build_fh_name", fh->error ());
+      set_errno (fh->error ());
     }
+  else
+    res = fh->fchown (uid, gid);
 
-done:
   syscall_printf ("%d = %schown (%s,...)",
                  res, (fmode & PC_SYM_NOFOLLOW) ? "l" : "", name);
   return res;
@@ -908,18 +878,10 @@ fchown32 (int fd, __uid32_t uid, __gid32_t gid)
       return -1;
     }
 
-  const char *path = cfd->get_name ();
+  int res = cfd->fchown (uid, gid);
 
-  if (path == NULL)
-    {
-      syscall_printf ("-1 = fchown (%d,...) (no name)", fd);
-      set_errno (ENOSYS);
-      return -1;
-    }
-
-  syscall_printf ("fchown (%d,...): calling chown_worker (%s,FOLLOW,...)",
-                 fd, path);
-  return chown_worker (path, PC_SYM_FOLLOW, uid, gid);
+  syscall_printf ("%d = fchown (%s,...)", res, cfd->get_name ());
+  return res;
 }
 
 extern "C" int