OSDN Git Service

* dtable.cc (dtable::build_fhandler_from_name): Set some fhandler
authorcorinna <corinna>
Fri, 21 Feb 2003 14:29:17 +0000 (14:29 +0000)
committercorinna <corinna>
Fri, 21 Feb 2003 14:29:17 +0000 (14:29 +0000)
data on sockets to evaluate AF_LOCAL sockets correctly.
(dtable::build_fhandler): Set unit number on sockets.
* fhandler.h (fhandler_socket): Add unit number.
(fhandler_socket::get_unit): New method.
* fhandler_socket.cc (fhandler_socket::fhandler_socket): Set unit
number.
(fhandler_socket::fstat): Reorganize to return more Linux-like
values.
* net.cc: include ctype.h.
(fdsock): Set unit number when building fhandler.
* path.cc (path_conv::check): Set device type to FH_SOCKET if file
is a AF_UNIX socket.
(get_devn): Evaluate unit for virtual socket devices.
(win32_device_name): Set windows path for sockets to unix_path with
just backslashes to keep the different names.
* syscalls.cc (fstat64): Don't override st_ino, st_dev and st_rdev
for sockets.
(stat_worker): Ditto.

From Pierre Humblet:

* autoload.cc (AccessCheck): Add.
(DuplicateToken): Add.
* security.h (check_file_access): Declare.
* syscalls.cc (access): Convert path to Windows, check existence
and readonly attribute. Call check_file_access instead of acl_access.
* security.cc (check_file_access): Create.
* sec_acl (acl_access): Delete.

winsup/cygwin/ChangeLog
winsup/cygwin/autoload.cc
winsup/cygwin/dtable.cc
winsup/cygwin/fhandler.h
winsup/cygwin/fhandler_socket.cc
winsup/cygwin/net.cc
winsup/cygwin/path.cc
winsup/cygwin/sec_acl.cc
winsup/cygwin/security.cc
winsup/cygwin/security.h
winsup/cygwin/syscalls.cc

index b05cdc4..ab1c240 100644 (file)
@@ -1,3 +1,35 @@
+2003-02-21  Corinna Vinschen  <corinna@vinschen.de>
+
+       * dtable.cc (dtable::build_fhandler_from_name): Set some fhandler
+       data on sockets to evaluate AF_LOCAL sockets correctly.
+       (dtable::build_fhandler): Set unit number on sockets.
+       * fhandler.h (fhandler_socket): Add unit number.
+       (fhandler_socket::get_unit): New method.
+       * fhandler_socket.cc (fhandler_socket::fhandler_socket): Set unit
+       number.
+       (fhandler_socket::fstat): Reorganize to return more Linux-like
+       values.
+       * net.cc: include ctype.h.
+       (fdsock): Set unit number when building fhandler.
+       * path.cc (path_conv::check): Set device type to FH_SOCKET if file
+       is a AF_UNIX socket.
+       (get_devn): Evaluate unit for virtual socket devices.
+       (win32_device_name): Set windows path for sockets to unix_path with
+       just backslashes to keep the different names.
+       * syscalls.cc (fstat64): Don't override st_ino, st_dev and st_rdev
+       for sockets.
+       (stat_worker): Ditto.
+
+2003-02-21  Pierre Humblet  <pierre.humblet@ieee.org>
+
+       * autoload.cc (AccessCheck): Add.
+       (DuplicateToken): Add.
+       * security.h (check_file_access): Declare.
+       * syscalls.cc (access): Convert path to Windows, check existence
+       and readonly attribute. Call check_file_access instead of acl_access.
+       * security.cc (check_file_access): Create.
+       * sec_acl (acl_access): Delete.
+
 2003-02-19  Christopher Faylor  <cgf@redhat.com>
 
        * fhandler.cc (fhandler_base::open): Move some filesystem specific
index d071ab1..b29c9d2 100644 (file)
@@ -307,6 +307,7 @@ wsock_init ()
 LoadDLLprime (wsock32, wsock_init)
 LoadDLLprime (ws2_32, wsock_init)
 
+LoadDLLfunc (AccessCheck, 32, advapi32)
 LoadDLLfunc (AddAccessAllowedAce, 16, advapi32)
 LoadDLLfunc (AddAccessDeniedAce, 16, advapi32)
 LoadDLLfunc (AddAce, 20, advapi32)
@@ -318,6 +319,7 @@ LoadDLLfuncEx (CryptAcquireContextA, 20, advapi32, 1)
 LoadDLLfuncEx (CryptGenRandom, 12, advapi32, 1)
 LoadDLLfuncEx (CryptReleaseContext, 8, advapi32, 1)
 LoadDLLfunc (DeregisterEventSource, 4, advapi32)
+LoadDLLfunc (DuplicateToken, 12, advapi32)
 LoadDLLfuncEx (DuplicateTokenEx, 24, advapi32, 1)
 LoadDLLfunc (EqualSid, 8, advapi32)
 LoadDLLfunc (GetAce, 12, advapi32)
index 03490b6..73af42e 100644 (file)
@@ -299,9 +299,15 @@ dtable::build_fhandler_from_name (int fd, const char *name, HANDLE handle,
   if (!pc.exists () && handle)
     pc.fillin (handle);
 
-  fhandler_base *fh = build_fhandler (fd, pc.get_devn (),
-                                     pc.return_and_clear_normalized_path (),
+  char *posix_path = pc.return_and_clear_normalized_path ();
+  fhandler_base *fh = build_fhandler (fd, pc.get_devn (), posix_path,
                                      pc, pc.get_unitn ());
+  if (pc.issocket ()) /* Only true for files pretending an AF_LOCAL socket. */
+    {
+      fhandler_socket * fhs = (fhandler_socket *) fh;
+      fhs->set_addr_family (AF_LOCAL);
+      fhs->set_sun_path (posix_path);
+    }
   return fh;
 }
 
@@ -352,7 +358,7 @@ dtable::build_fhandler (int fd, DWORD dev, char *unix_name,
        fh = cnew (fhandler_pipe) (dev);
        break;
       case FH_SOCKET:
-       if ((fh = cnew (fhandler_socket) ()))
+       if ((fh = cnew (fhandler_socket) (unit)))
          inc_need_fixup_before ();
        break;
       case FH_DISK:
index 8840cb8..cc6ae7c 100644 (file)
@@ -385,12 +385,14 @@ class fhandler_socket: public fhandler_base
   struct _WSAPROTOCOL_INFOA *prot_info_ptr;
   char *sun_path;
   int had_connect_or_listen;
+  int unit;
 
  public:
-  fhandler_socket ();
+  fhandler_socket (int unit);
   ~fhandler_socket ();
   int get_socket () { return (int) get_handle(); }
   fhandler_socket * is_socket () { return this; }
+  int get_unit () { return unit; }
 
   bool saw_shutdown_read () const {return FHISSETF (SHUTRD);}
   bool saw_shutdown_write () const {return FHISSETF (SHUTWR);}
index 6c867f9..b10e28a 100644 (file)
@@ -94,8 +94,8 @@ get_inet_addr (const struct sockaddr *in, int inlen,
 /**********************************************************************/
 /* fhandler_socket */
 
-fhandler_socket::fhandler_socket ()
-  : fhandler_base (FH_SOCKET), sun_path (NULL)
+fhandler_socket::fhandler_socket (int nunit)
+  : fhandler_base (FH_SOCKET), unit (nunit), sun_path (NULL)
 {
   set_need_fork_fixup ();
   prot_info_ptr = (LPWSAPROTOCOL_INFOA) cmalloc (HEAP_BUF,
@@ -309,12 +309,47 @@ fhandler_socket::dup (fhandler_base *child)
 int __stdcall
 fhandler_socket::fstat (struct __stat64 *buf, path_conv *pc)
 {
-  int res = fhandler_base::fstat (buf, pc);
+  int res;
+  if (get_addr_family () == AF_LOCAL && get_sun_path ())
+    {
+      path_conv spc (get_sun_path (),
+                     PC_SYM_NOFOLLOW | PC_NULLEMPTY | PC_FULL | PC_POSIX,
+                    NULL);
+      fhandler_base *fh = cygheap->fdtab.build_fhandler (-1, FH_DISK,
+                                                        get_sun_path (),
+                                                        spc, 0);
+      if (fh)
+        {
+         res = fh->fstat (buf, &spc);
+         /* Faking Linux like values on top of the file specific values. */
+         if (get_socket_type ()) /* fstat() */
+           {
+             buf->st_dev = 0;
+             buf->st_mode |= S_IRWXU | S_IRWXG | S_IRWXO;
+             buf->st_ino = (ino_t) get_handle ();
+           }
+         buf->st_rdev = buf->st_size = buf->st_blocks = 0;
+         return res;
+       }
+    }
+
+  res = fhandler_base::fstat (buf, pc);
   if (!res)
     {
-      buf->st_mode &= ~_IFMT;
-      buf->st_mode |= _IFSOCK;
-      buf->st_ino = (ino_t) get_handle ();
+      if (get_socket_type ()) /* fstat */
+        {
+         buf->st_ino = (ino_t) get_handle ();
+         buf->st_mode &= ~S_IFMT;
+         buf->st_mode |= S_IFSOCK;
+       }
+      else
+        {
+         path_conv spc ("/dev", PC_SYM_NOFOLLOW | PC_NULLEMPTY, NULL);
+         buf->st_dev = spc.volser ();
+         buf->st_ino = (ino_t) get_namehash ();
+         buf->st_mode &= ~S_IRWXO;
+         buf->st_rdev = (get_device () << 16) | get_unit ();
+       }
     }
   return res;
 }
index 6bfec1f..cfc716c 100644 (file)
@@ -14,6 +14,7 @@ details. */
 
 #include "winsup.h"
 #include <errno.h>
+#include <ctype.h>
 #include <sys/socket.h>
 #include <sys/un.h>
 #include <iphlpapi.h>
@@ -521,8 +522,9 @@ fdsock (int &fd, const char *name, SOCKET soc)
   else
     debug_printf ("not setting socket inheritance since winsock2_active %d",
                  winsock2_active);
-  fhandler_socket *fh =
-    (fhandler_socket *) cygheap->fdtab.build_fhandler (fd, FH_SOCKET, name);
+  fhandler_socket *fh = (fhandler_socket *)
+       cygheap->fdtab.build_fhandler (fd, FH_SOCKET, name, NULL,
+                                      tolower (name[5]) - 'a');
   if (!fh)
     return NULL;
   fh->set_io_handle ((HANDLE) soc);
index d75f8a0..dea1d37 100644 (file)
@@ -799,10 +799,8 @@ out:
          set_has_buggy_open (strcmp (fs.name, "SUNWNFS") == 0);
        }
     }
-#if 0
   if (issocket ())
     devn = FH_SOCKET;
-#endif
 
   if (!(opt & PC_FULL))
     {
@@ -954,7 +952,10 @@ get_devn (const char *name, int &unit)
     devn = FH_PIPEW;
   else if (deveq ("tcp") || deveq ("udp") || deveq ("streamsocket")
           || deveq ("dgsocket"))
-    devn = FH_SOCKET;
+    {
+      devn = FH_SOCKET;
+      unit = tolower (*name) - 'a';
+    }
 
   return devn;
 }
@@ -1118,6 +1119,12 @@ win32_device_name (const char *src_path, char *win32_path,
     return false;
   switch (devn)
     {
+      case FH_SOCKET:
+       char *c;
+       strcpy (win32_path, src_path);
+       while (c = strchr (win32_path, '/'))
+         *c = '\\';
+        break;
       case FH_RANDOM:
        __small_sprintf (win32_path, devfmt, unit == 8 ? "" : "u");
        break;
index febda4f..3a9f08b 100644 (file)
@@ -413,69 +413,6 @@ getacl (const char *file, DWORD attr, int nentries, __aclent32_t *aclbufp)
   return pos;
 }
 
-int
-acl_access (const char *path, int flags)
-{
-  __aclent32_t acls[MAX_ACL_ENTRIES];
-  int cnt;
-
-  if ((cnt = acl32 (path, GETACL, MAX_ACL_ENTRIES, acls)) < 1)
-    return -1;
-
-  /* Only check existence. */
-  if (!(flags & (R_OK | W_OK | X_OK)))
-    return 0;
-
-  for (int i = 0; i < cnt; ++i)
-    {
-      switch (acls[i].a_type)
-       {
-       case USER_OBJ:
-       case USER:
-         if (acls[i].a_id != myself->uid)
-           {
-             /*
-              * Check if user is a NT group:
-              * Take SID from passwd, search SID in token groups
-              */
-             cygsid owner;
-             struct passwd *pw;
-
-             if ((pw = internal_getpwuid (acls[i].a_id)) != NULL
-                 && owner.getfrompw (pw)
-                 && internal_getgroups (0, NULL, &owner) > 0)
-               break;
-             continue;
-           }
-         break;
-       case GROUP_OBJ:
-       case GROUP:
-         if (acls[i].a_id != myself->gid)
-            {
-             cygsid group;
-             struct __group32 *gr = NULL;
-
-             if ((gr = internal_getgrgid (acls[i].a_id)) != NULL
-                 && group.getfromgr (gr)
-                 && internal_getgroups (0, NULL, &group) > 0)
-               break;
-             continue;
-           }
-         break;
-       case OTHER_OBJ:
-         break;
-       default:
-         continue;
-       }
-      if ((!(flags & R_OK) || (acls[i].a_perm & S_IROTH))
-         && (!(flags & W_OK) || (acls[i].a_perm & S_IWOTH))
-         && (!(flags & X_OK) || (acls[i].a_perm & S_IXOTH)))
-       return 0;
-    }
-  set_errno (EACCES);
-  return -1;
-}
-
 static
 int
 acl_worker (const char *path, int cmd, int nentries, __aclent32_t *aclbufp,
index 35ac5cf..847aa4a 100644 (file)
@@ -1918,3 +1918,54 @@ set_file_attribute (int use_ntsec, const char *file, int attribute)
   return set_file_attribute (use_ntsec, file,
                             myself->uid, myself->gid, attribute);
 }
+
+int
+check_file_access (const char *fn, int flags)
+{
+  int ret = -1;
+  char sd_buf[4096];
+  DWORD sd_size = sizeof sd_buf;
+  PSECURITY_DESCRIPTOR psd = (PSECURITY_DESCRIPTOR) sd_buf;
+  HANDLE hToken, hIToken;
+  BOOL status;
+  char pbuf[sizeof (PRIVILEGE_SET) + 3 * sizeof (LUID_AND_ATTRIBUTES)];
+  DWORD desired = 0, granted, plength = sizeof pbuf;
+  static GENERIC_MAPPING NO_COPY mapping = { FILE_GENERIC_READ,
+                                            FILE_GENERIC_WRITE,
+                                            FILE_GENERIC_EXECUTE,
+                                            FILE_ALL_ACCESS };
+  if (read_sd (fn, psd, &sd_size) <= 0)
+    goto done;
+
+  if (cygheap->user.issetuid ())
+    hToken = cygheap->user.token;
+  else if (!OpenProcessToken (hMainProc, TOKEN_DUPLICATE, &hToken))
+    {
+      __seterrno ();
+      goto done;
+    }
+  if (!(status = DuplicateToken (hToken, SecurityIdentification, &hIToken)))
+    __seterrno ();
+  if (hToken != cygheap->user.token)
+    CloseHandle (hToken);
+  if (!status)
+    goto done;
+
+  if (flags & R_OK)
+    desired |= FILE_READ_DATA;
+  if (flags & W_OK)
+    desired |= FILE_WRITE_DATA;
+  if (flags & X_OK)
+    desired |= FILE_EXECUTE;
+  if (!AccessCheck (psd, hIToken, desired, &mapping,
+                   (PPRIVILEGE_SET) pbuf, &plength, &granted, &status))
+    __seterrno ();
+  else if (!status)
+    set_errno (EACCES);
+  else
+    ret = 0;
+  CloseHandle (hIToken);
+ done:
+  debug_printf ("flags %x, ret %d", flags, ret);
+  return ret;
+}
index 9cbea2f..a859526 100644 (file)
@@ -225,6 +225,7 @@ LONG __stdcall read_sd(const char *file, PSECURITY_DESCRIPTOR sd_buf, LPDWORD sd
 LONG __stdcall write_sd(const char *file, PSECURITY_DESCRIPTOR sd_buf, DWORD sd_size);
 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 (const char *, int);
 
 void set_security_attribute (int attribute, PSECURITY_ATTRIBUTES psa,
                             void *sd_buf, DWORD sd_buf_size);
index 59bb531..cd3f2e6 100644 (file)
@@ -1016,7 +1016,7 @@ fstat64 (int fd, struct __stat64 *buf)
       path_conv pc (cfd->get_win32_name (), PC_SYM_NOFOLLOW);
       memset (buf, 0, sizeof (struct __stat64));
       res = cfd->fstat (buf, &pc);
-      if (!res)
+      if (!res && cfd->get_device () != FH_SOCKET)
        {
          if (!buf->st_ino)
            buf->st_ino = hash_path_name (0, cfd->get_win32_name ());
@@ -1106,7 +1106,7 @@ stat_worker (const char *name, struct __stat64 *buf, int nofollow,
                    pc, (DWORD) real_path);
       memset (buf, 0, sizeof (*buf));
       res = fh->fstat (buf, pc);
-      if (!res)
+      if (!res && fh->get_device () != FH_SOCKET)
        {
          if (!buf->st_ino)
            buf->st_ino = hash_path_name (0, fh->get_win32_name ());
@@ -1163,8 +1163,6 @@ cygwin_lstat (const char *name, struct __stat32 *buf)
   return ret;
 }
 
-extern int acl_access (const char *, int);
-
 extern "C" int
 access (const char *fn, int flags)
 {
@@ -1176,11 +1174,33 @@ access (const char *fn, int flags)
       return -1;
     }
 
-  if (allow_ntsec)
-    return acl_access (fn, flags);
+  path_conv real_path (fn, PC_SYM_FOLLOW | PC_FULL, stat_suffixes);
+  if (real_path.error)
+    {
+      set_errno (real_path.error);
+      return -1;
+    }
+
+  if (!real_path.exists ())
+    {
+      set_errno (ENOENT);
+      return -1;
+    }
+
+  if (!(flags & (R_OK | W_OK | X_OK)))
+    return 0;
+
+  if (real_path.has_attribute (FILE_ATTRIBUTE_READONLY) && (flags & W_OK))
+    {
+      set_errno (EACCES);
+      return -1;
+    }
+
+  if (real_path.has_acls () && allow_ntsec)
+    return check_file_access (real_path, flags);
 
   struct __stat64 st;
-  int r = stat_worker (fn, &st, 0);
+  int r = stat_worker (real_path, &st, 0);
   if (r)
     return -1;
   r = -1;