OSDN Git Service

* fhandler.h (class fhandler_socket): Declare new method
authorcorinna <corinna>
Mon, 28 Feb 2005 13:11:47 +0000 (13:11 +0000)
committercorinna <corinna>
Mon, 28 Feb 2005 13:11:47 +0000 (13:11 +0000)
set_socketpair_eids.
* fhandler_socket.cc (fhandler_socket::set_socketpair_eids): New method.
(fhandler_socket::dup): Duplicate sec_pipe if necessary.
(fhandler_socket::listen): Only create sec_pipe if named pipes are
available. Initialized sec_peer_pid to 0 as on Linux.
(fhandler_socket::connect): Only run eid credential transaction if
named pipes are available.  Fake otherwise. Initialized sec_peer_pid
to 0 as on Linux.
(fhandler_socket::accept): Ditto.
(fhandler_socket::close): Move closing sec_pipe handle from here...
(fhandler_socket::~fhandler_socket): ... to here.
* net.cc (socketpair): Set eid credentials by calling
fhandler_socket::set_socketpair_eids() on both socket ends.
* wincap.h (wincaps::has_named_pipes): New element.
* wincap.cc: Implement above element throughout.

winsup/cygwin/ChangeLog
winsup/cygwin/fhandler.h
winsup/cygwin/fhandler_socket.cc
winsup/cygwin/net.cc
winsup/cygwin/wincap.cc
winsup/cygwin/wincap.h

index 4425697..49093a5 100644 (file)
@@ -1,3 +1,22 @@
+2005-02-28  Corinna Vinschen  <corinna@vinschen.de>
+
+       * fhandler.h (class fhandler_socket): Declare new method
+       set_socketpair_eids.
+       * fhandler_socket.cc (fhandler_socket::set_socketpair_eids): New method.
+       (fhandler_socket::dup): Duplicate sec_pipe if necessary.
+       (fhandler_socket::listen): Only create sec_pipe if named pipes are
+       available. Initialized sec_peer_pid to 0 as on Linux.
+       (fhandler_socket::connect): Only run eid credential transaction if
+       named pipes are available.  Fake otherwise. Initialized sec_peer_pid
+       to 0 as on Linux.
+       (fhandler_socket::accept): Ditto.
+       (fhandler_socket::close): Move closing sec_pipe handle from here...
+       (fhandler_socket::~fhandler_socket): ... to here.
+       * net.cc (socketpair): Set eid credentials by calling
+       fhandler_socket::set_socketpair_eids() on both socket ends.
+       * wincap.h (wincaps::has_named_pipes): New element.
+       * wincap.cc: Implement above element throughout.
+
 2005-02-26  Christopher Faylor  <cgf@timesys.com>
 
        * sigproc.cc (_pinfo::set_ctty): Move function
index 2d9aa5f..bdc8d3b 100644 (file)
@@ -365,7 +365,10 @@ class fhandler_socket: public fhandler_base
   __uid32_t sec_peer_uid;
   __gid32_t sec_peer_gid;
   char *eid_pipe_name (char *buf);
+ public:
+  void set_socketpair_eids (void);
 
+ private:
   struct _WSAPROTOCOL_INFOA *prot_info_ptr;
   char *sun_path;
   struct status_flags
index b5b4847..ee93ff5 100644 (file)
@@ -60,6 +60,14 @@ fhandler_socket::eid_pipe_name (char *buf)
   return buf;
 }
 
+void
+fhandler_socket::set_socketpair_eids (void)
+{
+  sec_pid = sec_peer_pid = getpid ();
+  sec_uid = sec_peer_uid = geteuid32 ();
+  sec_gid = sec_peer_gid = getegid32 ();
+}
+
 /* cygwin internal: map sockaddr into internet domain address */
 static int
 get_inet_addr (const struct sockaddr *in, int inlen,
@@ -154,6 +162,9 @@ fhandler_socket::~fhandler_socket ()
     cfree (prot_info_ptr);
   if (sun_path)
     cfree (sun_path);
+  /* Close eid credentials pipe handle. */
+  if (sec_pipe != INVALID_HANDLE_VALUE)
+    CloseHandle (sec_pipe);
 }
 
 char *fhandler_socket::get_proc_fd_name (char *buf)
@@ -341,12 +352,37 @@ fhandler_socket::fixup_after_exec ()
 int
 fhandler_socket::dup (fhandler_base *child)
 {
+  HANDLE nh;
+
   debug_printf ("here");
   fhandler_socket *fhs = (fhandler_socket *) child;
   fhs->addr_family = addr_family;
-  if (get_addr_family () == AF_LOCAL)
-    fhs->set_sun_path (get_sun_path ());
   fhs->set_socket_type (get_socket_type ());
+  if (get_addr_family () == AF_LOCAL)
+    {
+      fhs->set_sun_path (get_sun_path ());
+      if (get_socket_type () == SOCK_STREAM)
+        {
+         fhs->sec_pid = sec_pid;
+         fhs->sec_uid = sec_uid;
+         fhs->sec_gid = sec_gid;
+         fhs->sec_peer_pid = sec_peer_pid;
+         fhs->sec_peer_uid = sec_peer_uid;
+         fhs->sec_peer_gid = sec_peer_gid;
+         if (sec_pipe != INVALID_HANDLE_VALUE)
+           {
+             if (!DuplicateHandle (hMainProc, sec_pipe, hMainProc, &nh, 0,
+                                   TRUE, DUPLICATE_SAME_ACCESS))
+               {
+                 system_printf ("!DuplicateHandle(%x) failed, %E", sec_pipe);
+                 __seterrno ();
+                 return -1;
+               }
+             else
+               fhs->sec_pipe = nh;
+           }
+       }
+    }
   fhs->connect_state (connect_state ());
 
   if (winsock2_active)
@@ -378,12 +414,13 @@ fhandler_socket::dup (fhandler_base *child)
      having winsock called from fhandler_base and it creates only
      inheritable sockets which is wrong for winsock2. */
 
-  HANDLE nh;
   if (!DuplicateHandle (hMainProc, get_io_handle (), hMainProc, &nh, 0,
                        !winsock2_active, DUPLICATE_SAME_ACCESS))
     {
       system_printf ("!DuplicateHandle(%x) failed, %E", get_io_handle ());
       __seterrno ();
+      if (fhs->sec_pipe != INVALID_HANDLE_VALUE)
+        CloseHandle (fhs->sec_pipe);
       return -1;
     }
   VerifyHandle (nh);
@@ -630,20 +667,30 @@ fhandler_socket::connect (const struct sockaddr *name, int namelen)
        }
 
       /* eid credential transaction. */
-      struct ucred in = { getpid (), geteuid32 (), getegid32 () };
-      struct ucred out = { (pid_t) -1, (__uid32_t) -1, (__gid32_t) -1 };
-      DWORD bytes = 0;
-      if (CallNamedPipe(eid_pipe_name ((char *) alloca (CYG_MAX_PATH + 1)),
-                       &in, sizeof in, &out, sizeof out, &bytes, 1000))
-       {
-         debug_printf ("Received eid credentials: pid: %d, uid: %d, gid: %d",
-                       out.pid, out.uid, out.gid);
-         sec_peer_pid = out.pid;
-         sec_peer_uid = out.uid;
-         sec_peer_gid = out.gid;
-        }
-      else
-        debug_printf ("Receiving eid credentials failed: %E");
+      if (wincap.has_named_pipes ())
+        {
+         struct ucred in = { getpid (), geteuid32 (), getegid32 () };
+         struct ucred out = { (pid_t) 0, (__uid32_t) -1, (__gid32_t) -1 };
+         DWORD bytes = 0;
+         if (CallNamedPipe(eid_pipe_name ((char *) alloca (CYG_MAX_PATH + 1)),
+                           &in, sizeof in, &out, sizeof out, &bytes, 1000))
+           {
+             debug_printf ("Received eid credentials: pid: %d, uid: %d, gid: %d",
+                           out.pid, out.uid, out.gid);
+             sec_peer_pid = out.pid;
+             sec_peer_uid = out.uid;
+             sec_peer_gid = out.gid;
+           }
+         else
+           debug_printf ("Receiving eid credentials failed: %E");
+       }
+      else /* 9x */
+        {
+         /* Incorrect but wrong pid at least doesn't break getpeereid. */
+         sec_peer_pid = getpid ();
+         sec_peer_uid = geteuid32 ();
+         sec_peer_gid = getegid32 ();
+       }
     }
 
   err = WSAGetLastError ();
@@ -669,10 +716,13 @@ fhandler_socket::listen (int backlog)
          sec_pid = getpid ();
          sec_uid = geteuid32 ();
          sec_gid = getegid32 ();
-         sec_peer_pid = (pid_t) -1;
+         sec_peer_pid = (pid_t) 0;
          sec_peer_uid = (__uid32_t) -1;
          sec_peer_gid = (__gid32_t) -1;
-         sec_pipe =
+         /* A listening socket can call listen again, but that shouldn't
+            result in trying to create another pipe. */
+         if (wincap.has_named_pipes () && sec_pipe == INVALID_HANDLE_VALUE)
+           sec_pipe =
            CreateNamedPipe (eid_pipe_name ((char *) alloca (CYG_MAX_PATH + 1)),
                             PIPE_ACCESS_DUPLEX,
                             PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE,
@@ -692,7 +742,7 @@ fhandler_socket::accept (struct sockaddr *peer, int *len)
   bool secret_check_failed = false;
   bool in_progress = false;
   struct ucred in = { sec_pid, sec_uid, sec_gid };
-  struct ucred out = { (pid_t) -1, (__uid32_t) -1, (__gid32_t) -1 };
+  struct ucred out = { (pid_t) 0, (__uid32_t) -1, (__gid32_t) -1 };
 
   /* Allows NULL peer and len parameters. */
   struct sockaddr_in peer_dummy;
@@ -747,21 +797,31 @@ fhandler_socket::accept (struct sockaddr *peer, int *len)
        }
 
       /* eid credential transaction. */
-      DWORD bytes = 0;
-      bool ret = ConnectNamedPipe (sec_pipe, NULL);
-      if (ret || GetLastError () == ERROR_PIPE_CONNECTED)
+      if (wincap.has_named_pipes ())
         {
-         if (!ReadFile (sec_pipe, &out, sizeof out, &bytes, NULL))
-           debug_printf ("Receiving eid credentials failed: %E");
+         DWORD bytes = 0;
+         bool ret = ConnectNamedPipe (sec_pipe, NULL);
+         if (ret || GetLastError () == ERROR_PIPE_CONNECTED)
+           {
+             if (!ReadFile (sec_pipe, &out, sizeof out, &bytes, NULL))
+               debug_printf ("Receiving eid credentials failed: %E");
+             else
+                debug_printf ("Received eid credentials: pid: %d, uid: %d, gid: %d",
+                              out.pid, out.uid, out.gid);
+             if (!WriteFile (sec_pipe, &in, sizeof in, &bytes, NULL))
+               debug_printf ("Sending eid credentials failed: %E");
+             DisconnectNamedPipe (sec_pipe);
+           }
          else
-            debug_printf ("Received eid credentials: pid: %d, uid: %d, gid: %d",
-                          out.pid, out.uid, out.gid);
-         if (!WriteFile (sec_pipe, &in, sizeof in, &bytes, NULL))
-           debug_printf ("Sending eid credentials failed: %E");
-         DisconnectNamedPipe (sec_pipe);
+           debug_printf ("Connecting the eid credential pipe failed: %E");
+       }
+      else /* 9x */
+       {
+         /* Incorrect but wrong pid at least doesn't break getpeereid. */
+         out.pid = sec_pid;
+         out.uid = sec_uid;
+         out.gid = sec_gid;
        }
-      else
-        debug_printf ("Connecting the eid credential pipe failed: %E");
     }
 
   if ((SOCKET) res == INVALID_SOCKET)
@@ -1392,10 +1452,6 @@ fhandler_socket::close ()
   setsockopt (get_socket (), SOL_SOCKET, SO_LINGER,
              (const char *)&linger, sizeof linger);
 
-  /* Close eid credentials pipe handle. */
-  if (sec_pipe != INVALID_HANDLE_VALUE)
-    CloseHandle (sec_pipe);
-
   while ((res = closesocket (get_socket ())) != 0)
     {
       if (WSAGetLastError () != WSAEWOULDBLOCK)
index 98e121c..472e97c 100644 (file)
@@ -2198,6 +2198,8 @@ socketpair (int family, int type, int protocol, int *sb)
        ((fhandler_socket *) sb0)->set_addr_family (family);
        ((fhandler_socket *) sb0)->set_socket_type (type);
        ((fhandler_socket *) sb0)->connect_state (connected);
+       if (family == AF_LOCAL && type == SOCK_STREAM)
+         ((fhandler_socket *) sb0)->set_socketpair_eids ();
 
        cygheap_fdnew sb1 (sb0, false);
 
@@ -2207,6 +2209,8 @@ socketpair (int family, int type, int protocol, int *sb)
            ((fhandler_socket *) sb1)->set_addr_family (family);
            ((fhandler_socket *) sb1)->set_socket_type (type);
            ((fhandler_socket *) sb1)->connect_state (connected);
+           if (family == AF_LOCAL && type == SOCK_STREAM)
+             ((fhandler_socket *) sb1)->set_socketpair_eids ();
 
            sb[0] = sb0;
            sb[1] = sb1;
index 4011b5d..9a790b0 100644 (file)
@@ -42,6 +42,7 @@ static NO_COPY wincaps wincap_unknown = {
   has_move_file_ex:false,
   has_negative_pids:false,
   has_unreliable_pipes:false,
+  has_named_pipes:false,
   has_try_enter_critical_section:false,
   has_raw_devices:false,
   has_valid_processorlevel:false,
@@ -90,6 +91,7 @@ static NO_COPY wincaps wincap_95 = {
   has_move_file_ex:false,
   has_negative_pids:true,
   has_unreliable_pipes:true,
+  has_named_pipes:false,
   has_try_enter_critical_section:false,
   has_raw_devices:false,
   has_valid_processorlevel:false,
@@ -138,6 +140,7 @@ static NO_COPY wincaps wincap_95osr2 = {
   has_move_file_ex:false,
   has_negative_pids:true,
   has_unreliable_pipes:true,
+  has_named_pipes:false,
   has_try_enter_critical_section:false,
   has_raw_devices:false,
   has_valid_processorlevel:false,
@@ -186,6 +189,7 @@ static NO_COPY wincaps wincap_98 = {
   has_move_file_ex:false,
   has_negative_pids:true,
   has_unreliable_pipes:true,
+  has_named_pipes:false,
   has_try_enter_critical_section:false,
   has_raw_devices:false,
   has_valid_processorlevel:true,
@@ -234,6 +238,7 @@ static NO_COPY wincaps wincap_98se = {
   has_move_file_ex:false,
   has_negative_pids:true,
   has_unreliable_pipes:true,
+  has_named_pipes:false,
   has_try_enter_critical_section:false,
   has_raw_devices:false,
   has_valid_processorlevel:true,
@@ -282,6 +287,7 @@ static NO_COPY wincaps wincap_me = {
   has_move_file_ex:false,
   has_negative_pids:true,
   has_unreliable_pipes:true,
+  has_named_pipes:false,
   has_try_enter_critical_section:false,
   has_raw_devices:false,
   has_valid_processorlevel:true,
@@ -330,6 +336,7 @@ static NO_COPY wincaps wincap_nt3 = {
   has_move_file_ex:true,
   has_negative_pids:false,
   has_unreliable_pipes:false,
+  has_named_pipes:true,
   has_try_enter_critical_section:false,
   has_raw_devices:true,
   has_valid_processorlevel:true,
@@ -378,6 +385,7 @@ static NO_COPY wincaps wincap_nt4 = {
   has_move_file_ex:true,
   has_negative_pids:false,
   has_unreliable_pipes:false,
+  has_named_pipes:true,
   has_try_enter_critical_section:true,
   has_raw_devices:true,
   has_valid_processorlevel:true,
@@ -426,6 +434,7 @@ static NO_COPY wincaps wincap_nt4sp4 = {
   has_move_file_ex:true,
   has_negative_pids:false,
   has_unreliable_pipes:false,
+  has_named_pipes:true,
   has_try_enter_critical_section:true,
   has_raw_devices:true,
   has_valid_processorlevel:true,
@@ -474,6 +483,7 @@ static NO_COPY wincaps wincap_2000 = {
   has_move_file_ex:true,
   has_negative_pids:false,
   has_unreliable_pipes:false,
+  has_named_pipes:true,
   has_try_enter_critical_section:true,
   has_raw_devices:true,
   has_valid_processorlevel:true,
@@ -522,6 +532,7 @@ static NO_COPY wincaps wincap_xp = {
   has_move_file_ex:true,
   has_negative_pids:false,
   has_unreliable_pipes:false,
+  has_named_pipes:true,
   has_try_enter_critical_section:true,
   has_raw_devices:true,
   has_valid_processorlevel:true,
@@ -570,6 +581,7 @@ static NO_COPY wincaps wincap_2003 = {
   has_move_file_ex:true,
   has_negative_pids:false,
   has_unreliable_pipes:false,
+  has_named_pipes:true,
   has_try_enter_critical_section:true,
   has_raw_devices:true,
   has_valid_processorlevel:true,
index c6c54b0..6d7d63e 100644 (file)
@@ -43,6 +43,7 @@ struct wincaps
   unsigned has_move_file_ex                             : 1;
   unsigned has_negative_pids                            : 1;
   unsigned has_unreliable_pipes                         : 1;
+  unsigned has_named_pipes                              : 1;
   unsigned has_try_enter_critical_section              : 1;
   unsigned has_raw_devices                             : 1;
   unsigned has_valid_processorlevel                    : 1;
@@ -105,6 +106,7 @@ public:
   bool  IMPLEMENT (has_move_file_ex)
   bool  IMPLEMENT (has_negative_pids)
   bool  IMPLEMENT (has_unreliable_pipes)
+  bool  IMPLEMENT (has_named_pipes)
   bool  IMPLEMENT (has_try_enter_critical_section)
   bool  IMPLEMENT (has_raw_devices)
   bool  IMPLEMENT (has_valid_processorlevel)