rpms/cups/devel cups-scm_credentials.patch,NONE,1.1

fedora-cvs-commits at redhat.com fedora-cvs-commits at redhat.com
Wed Mar 7 18:13:55 UTC 2007


Author: twaugh

Update of /cvs/dist/rpms/cups/devel
In directory cvs.devel.redhat.com:/tmp/cvs-serv609

Added Files:
	cups-scm_credentials.patch 
Log Message:
First attempt at SCM_CREDENTIALS support.

cups-scm_credentials.patch:
 cups/auth.c      |   56 ++++++++++++++++++++++++++++++++++++
 cups/http.c      |   40 +++++++++++++++++++++++++
 scheduler/auth.c |   85 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 181 insertions(+)

--- NEW FILE cups-scm_credentials.patch ---
--- cups-1.2.8/cups/http.c.scm_credentials	2007-03-07 18:01:09.000000000 +0000
+++ cups-1.2.8/cups/http.c	2007-03-07 18:03:00.000000000 +0000
@@ -2515,6 +2515,46 @@
   httpGetLength2(http);
   httpClearFields(http);
 
+#ifdef AF_LOCAL
+  if (!strncmp(http->authstring, "SCM_CREDENTIALS", 15))
+  {
+    struct msghdr msg;
+    struct cmsghdr *cmsg;
+    struct iovec vec;
+    char dummy;
+    char buf[CMSG_SPACE(sizeof(struct ucred))];
+    struct ucred *uptr;
+
+    if (recv(http->fd, &dummy, 1, 0) != 1)
+    {
+      DEBUG_printf(("http_send: failed to synchronize for SCM_CREDENTIALS"));
+      return (-1);
+    }
+
+    memset (&msg, 0, sizeof(msg));
+    vec.iov_base = &dummy;
+    vec.iov_len = 1;
+    msg.msg_iov = &vec;
+    msg.msg_iovlen = 1;
+    msg.msg_control = buf;
+    msg.msg_controllen = sizeof(buf);
+    cmsg = CMSG_FIRSTHDR(&msg);
+    cmsg->cmsg_level = SOL_SOCKET;
+    cmsg->cmsg_type = SCM_CREDENTIALS;
+    cmsg->cmsg_len = CMSG_LEN(sizeof(struct ucred));
+    uptr = (struct ucred *)CMSG_DATA(cmsg);
+    uptr->uid = getuid();
+    uptr->gid = getgid();
+    uptr->pid = getpid();
+    msg.msg_controllen = cmsg->cmsg_len;
+    if (sendmsg(http->fd, &msg, 0) == -1)
+    {
+      DEBUG_printf(("http_send: failed to send SCM_CREDENTIALS"));
+      return (-1);
+    }
+  }
+#endif /* AF_LOCAL */
+
   return (0);
 }
 
--- cups-1.2.8/cups/auth.c.scm_credentials	2007-01-10 16:48:37.000000000 +0000
+++ cups-1.2.8/cups/auth.c	2007-03-07 18:01:09.000000000 +0000
@@ -47,6 +47,8 @@
 #  include <unistd.h>
 #endif /* WIN32 || __EMX__ */
 
+#include <sys/types.h>
+#include <pwd.h>
 
 /*
  * Local functions...
@@ -177,6 +179,54 @@
   return (0);
 }
 
+#ifdef AF_LOCAL
+/*
+ * 'cups_scm_credentials_auth()'
+ *                     - UNIX Domain Sockets authentication
+ */
+
+static int				/* O - 0 if available, -1 if not */
+cups_scm_credentials_auth(http_t *http)	/* I - HTTP connection to server */
+{
+  long buflen;
+  char *buf;
+  struct passwd pwbuf, *pwbufptr;
+
+  if (http->hostaddr->addr.sa_family != AF_LOCAL)
+    return (-1);
+
+ /*
+  * Are we trying to authenticate as ourselves?  If not, SCM_CREDENTIALS
+  * is no use.
+  */
+  buflen = sysconf (_SC_GETPW_R_SIZE_MAX);
+  buf = malloc (buflen);
+  if (buf == NULL)
+    return (-1);
+  if (getpwnam_r (cupsUser(), &pwbuf, buf, buflen, &pwbufptr) != 0)
+  {
+    free (buf);
+    return (-1);
+  }
+  if (pwbuf.pw_uid != getuid())
+  {
+    free (buf);
+    return (-1);
+  }
+  free (buf);
+
+ /*
+  * Set the authorization string and return...
+  */
+
+  snprintf(http->authstring, sizeof(http->authstring), "SCM_CREDENTIALS");
+
+  DEBUG_printf(("cups_scm_credentials_auth: Returning authstring = \"%s\"\n",
+		http->authstring));
+
+  return (0);
+}
+#endif /* AF_LOCAL */
 
 /*
  * 'cups_local_auth()' - Get the local authorization certificate if
@@ -234,7 +284,13 @@
   {
     DEBUG_printf(("cups_local_auth: Unable to open file %s: %s\n",
                   filename, strerror(errno)));
+
+#ifdef AF_LOCAL
+    return cups_scm_credentials_auth(http);
+#else
     return (-1);
+#endif /* AF_LOCAL */
+    
   }
 
  /*
--- cups-1.2.8/scheduler/auth.c.scm_credentials	2006-09-12 14:58:39.000000000 +0100
+++ cups-1.2.8/scheduler/auth.c	2007-03-07 18:03:15.000000000 +0000
@@ -80,6 +80,10 @@
 #  include <membership.h>
 #endif /* HAVE_MEMBERSHIP_H */
 
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <pwd.h>
+
 
 /*
  * Local functions...
@@ -384,6 +388,87 @@
                     "cupsdAuthorize: No authentication data provided.");
     return;
   }
+#ifdef AF_LOCAL
+  else if (!strncmp(authorization, "SCM_CREDENTIALS", 3) &&
+	   con->http.hostaddr->addr.sa_family == AF_LOCAL)
+  {
+    const int val = 1;
+    struct msghdr msg;
+    struct cmsghdr *cmsg;
+    struct iovec vec;
+    char dummy;
+    char buf[CMSG_SPACE(sizeof(struct ucred))];
+
+    cupsdLogMessage(CUPSD_LOG_DEBUG, "SCM_CREDENTIALS authentication");
+
+    /* Turn on reception of credentials. */
+    if (setsockopt(con->http.fd, SOL_SOCKET, SO_PASSCRED, &val, sizeof(val)))
+    {
+      cupsdLogMessage(CUPSD_LOG_ERROR, "SCM_CREDENTIALS setsockopt failed!");
+      return;
+    }
+
+    /* If the client sends their SCM_CREDENTIALS message too soon we will
+     * read it as part of the HTTP request.  To prevent that, they wait
+     * until we send them this zero byte to synchronize.
+     */
+    dummy = '\0';
+    if (send(con->http.fd, &dummy, 1, 0) != 1)
+    {
+      cupsdLogMessage(CUPSD_LOG_ERROR, "SCM_CREDENTIALS sync failed");
+      return;
+    }
+
+    memset (&msg, 0, sizeof(msg));
+    vec.iov_base = &dummy;
+    vec.iov_len = 1;
+    msg.msg_iov = &vec;
+    msg.msg_iovlen = 1;
+    msg.msg_control = buf;
+    msg.msg_controllen = sizeof(buf);
+    if (recvmsg(con->http.fd, &msg, 0) == -1)
+    {
+      cupsdLogMessage(CUPSD_LOG_ERROR, "SCM_CREDENTIALS recvmsg failed!");
+      return;
+    }
+
+    for (cmsg = CMSG_FIRSTHDR(&msg); cmsg; cmsg = CMSG_NXTHDR(&msg,cmsg))
+    {
+      if (cmsg->cmsg_level == SOL_SOCKET &&
+	  cmsg->cmsg_type == SCM_CREDENTIALS)
+      {
+	long buflen;
+	char *buf;
+	struct passwd pwbuf, *pwbufptr;
+	struct ucred *uptr;
+
+	if (cmsg->cmsg_len != CMSG_LEN(sizeof(struct ucred)))
+	{
+	  cupsdLogMessage(CUPSD_LOG_ERROR,
+			  "SCM_CREDENTIALS cmsg_len mismatch!");
+	  return;
+	}
+
+	uptr = (struct ucred *)CMSG_DATA(cmsg);
+
+	buflen = sysconf (_SC_GETPW_R_SIZE_MAX);
+	buf = malloc (buflen);
+	if (buf == NULL)
+	  return;
+
+	/* Look up which username the UID is for. */
+	if (getpwuid_r (uptr->uid, &pwbuf, buf, buflen, &pwbufptr) != 0)
+	{
+	  free (buf);
+	  return;
+	}
+
+	strlcpy(username, pwbuf.pw_name, sizeof(username));
+	free (buf);
+      }
+    }
+  }
+#endif /* AF_LOCAL */
   else if (!strncmp(authorization, "Local", 5) &&
            !strcasecmp(con->http.hostname, "localhost"))
   {




More information about the fedora-cvs-commits mailing list