Index: trunk/src/sh_socket.c
===================================================================
--- trunk/src/sh_socket.c	(revision 117)
+++ trunk/src/sh_socket.c	(revision 118)
@@ -678,4 +678,48 @@
 		      _("Message from recvmsg() was not SCM_CREDS"), 
 		      _("sh_socket_read"));
+
+      /* Check for file descriptors sent using SCM_RIGHTS, and
+       * close them. If MSG_CTRUNC is set, the buffer was too small,
+       * and no fds are duped.
+       */
+      if (msg.msg_controllen >= sizeof(struct cmsghdr) &&
+	  (msg.msg_flags & MSG_CTRUNC) == 0)
+	{
+	  unsigned int     data_size;
+	  unsigned int     data_i;
+	  int              fdcount, fdmax;
+	  struct cmsghdr * cmptr;
+	  int              fdsbuf[1 + (sizeof(cmsgmem)/sizeof(int))];
+
+	  for (cmptr = CMSG_FIRSTHDR(&msg); cmptr != NULL;
+	       cmptr = CMSG_NXTHDR(&msg, cmptr)) 
+	    {
+	      if (cmptr->cmsg_len > sizeof (cmsgmem) || 
+		  cmptr->cmsg_level != SOL_SOCKET ||
+		  cmptr->cmsg_type  != SCM_RIGHTS)
+		continue;
+
+	      /* Crappy way of finding the data length.
+	       * cmptr->cmsg_len includes both header and padding,
+	       * how are you supposed to find the data length?
+	       * cmptr->cmsg_len - ALIGN(sizeof(struct cmsghdr)) ?
+	       */
+	      data_size = 0;
+
+	      for (data_i = 0; data_i < cmptr->cmsg_len; ++data_i)
+		{
+		  if (CMSG_LEN(data_i) == cmptr->cmsg_len)
+		    {
+		      data_size = data_i;
+		      break;
+		    }
+		}
+	      memcpy(fdsbuf, CMSG_DATA(cmptr), data_size);
+	      fdmax = data_size / sizeof(int);
+	      for (fdcount = 0; fdcount < fdmax; ++fdcount)
+		(void) close(fdsbuf[fdcount]);
+	    }
+	}
+      
       close(talkfd);
       return -1;
