[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

RFC: [PATCH] SCM_CREDS support 2(2)



Hi,

Patch 2(2) on SCM_CREDS support for GNU/Hurd.

This patch is optional. kFreeBSD dos not support this case (but Linux
is).

This patch implements the last cases in the test code sent to the list
in September 2013, options <-n> and <-z> see
http://lists.debian.org/debian-hurd/2013/09/msg00034.html 

Options:
no flag:
-z: send a zero credentials byte as data (used by dbus)
-n: don't create explicit credentials structure

1) Sent credentials and PID are correct:
./scm_cred_recv &
./scm_cred_send -n
Linux: OK, only sent ids
kFreeBSD: nOK; ERROR: bad cmsg header cmhp == NULL, data: OK
Hurd: same as kFreeBSD

./scm_cred_recv -z&
./scm_cred_send -nz
Linux: OK, same as above
kFreeBSD: nOK; ERROR: bad cmsg header cmhp == NULL, data: OK
Hurd: OK, sent IDs + groups

2) When no credentials structure is sent the behaviour is different:
Linux:
-n: received credentials are created
-zn: received credentials ones are created

kFreeBSD: 
-n: ERROR: bad cmsg header cmhp == NULL
-zn: ERROR: bad cmsg header cmhp == NULL

Hurd:
-n: ERROR: bad cmsg header cmhp == NULL
-zn: received credentials are created

--- a/sysdeps/mach/hurd/sendmsg.c
+++ b/sysdeps/mach/hurd/sendmsg.c
@@ -193,6 +193,49 @@
       goto label;
     }
 
+  /* Special case: message->msg_controllen <  sizeof (struct cmsghdr) */
+  /* Special case: cmsg == NULL and zero credentials byte sent */
+  else if (cmsg == NULL && (strncmp(data.ptr, "\0", 1) == 0))
+    {
+      union {
+	struct cmsghdr cmh;
+	char control[CMSG_SPACE(sizeof(struct cmsgcred))];
+	/* Space large enough to hold a cmsgcred structure */
+      } control_un;
+
+      struct msghdr msgh;
+      msgh.msg_name = NULL;
+      msgh.msg_namelen = 0;
+      msgh.msg_control = control_un.control;
+      msgh.msg_controllen = sizeof(control_un.control);
+      msgh.msg_flags = 0;
+
+      struct cmsghdr *cmhp = CMSG_FIRSTHDR(&msgh);
+      cmhp->cmsg_level = SOL_SOCKET;
+      cmhp->cmsg_type = SCM_CREDS;
+      cmhp->cmsg_len = CMSG_LEN(sizeof(struct cmsgcred));
+
+      ucredp = (struct cmsgcred *) CMSG_DATA(cmhp);
+      /* FIXME: to remove pid: not checked in check_auth? */
+      pid = __getpid();
+      euids = __geteuid();
+      auids = __getuid();
+      egids = __getegid();
+      agids = __getgid();
+      euidslen = auidslen = egidslen = agidslen = 1;
+
+      nports = 0;
+      control = control_un.control;
+      control_len = sizeof(control_un.control);
+
+      err = check_auth(euids, euidslen, auids, auidslen,
+			egids, egidslen, agids, agidslen,
+			ucredp);
+      if (err)
+	return __hurd_fail (err);
+      goto label;
+    }
+
   /* SCM_RIGHTS support: get the number of fds to send.  */
   cmsg = CMSG_FIRSTHDR (message);
   for (; cmsg; cmsg = CMSG_NXTHDR (message, cmsg))

Reply to: