After speaking to Uli about how to improve the patch, here is a better,
simpler version.

Tim.
*/

--- 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-09 17:02:06.000000000 +0000
@@ -26,6 +26,8 @@
  * Contents:
  *
  *   cupsDoAuthentication() - Authenticate a request.
+ *   cups_peercred_auth()   - Find out if SO_PEERCRED authentication
+ *                            is possible
  *   cups_local_auth()      - Get the local authorization certificate if
  *                            available/applicable...
  */
@@ -40,7 +42,9 @@
 #include <ctype.h>
 #include <errno.h>
 #include <fcntl.h>
+#include <pwd.h>
 #include <sys/stat.h>
+#include <sys/types.h>
 #if defined(WIN32) || defined(__EMX__)
 #  include <io.h>
 #else
@@ -177,6 +181,59 @@
   return (0);
 }
 
+/*
+ * 'cups_peercred_auth()'
+ *                     - UNIX Domain Sockets authentication
+ */
+
+static int				/* O - 0 if available, -1 if not */
+cups_peercred_auth(http_t *http)	/* I - HTTP connection to server */
+{
+#ifdef SO_PEERCRED
+  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, SO_PEERCRED
+  * 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), "SO_PEERCRED");
+
+  DEBUG_printf(("cups_peercred_auth: Returning authstring = \"%s\"\n",
+		http->authstring));
+
+  return (0);
+#else
+  return (-1);
+#endif /* SO_PEERCRED */
+}
 
 /*
  * 'cups_local_auth()' - Get the local authorization certificate if
@@ -234,7 +291,7 @@
   {
     DEBUG_printf(("cups_local_auth: Unable to open file %s: %s\n",
                   filename, strerror(errno)));
-    return (-1);
+    return cups_peercred_auth(http);
   }
 
  /*
--- 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-09 17:11:21.000000000 +0000
@@ -60,6 +60,9 @@
 
 #include "cupsd.h"
 #include <grp.h>
+#include <pwd.h>
+#include <sys/socket.h>
+#include <sys/types.h>
 #ifdef HAVE_SHADOW_H
 #  include <shadow.h>
 #endif /* HAVE_SHADOW_H */
@@ -79,6 +82,9 @@
 #ifdef HAVE_MEMBERSHIP_H
 #  include <membership.h>
 #endif /* HAVE_MEMBERSHIP_H */
+#if !defined(WIN32) && !defined(__EMX__)
+#  include <unistd.h>
+#endif
 
 
 /*
@@ -384,6 +390,42 @@
                     "cupsdAuthorize: No authentication data provided.");
     return;
   }
+#ifdef SO_PEERCRED
+  else if (!strncmp(authorization, "SO_PEERCRED", 3) &&
+	   con->http.hostaddr->addr.sa_family == AF_LOCAL)
+  {
+    long buflen;
+    char *buf;
+    struct passwd pwbuf, *pwbufptr;
+    struct ucred u;
+    socklen_t ulen = sizeof(u);
+    if (getsockopt(con->http.fd, SOL_SOCKET, SO_PEERCRED, &u, &ulen) == -1)
+    {
+      cupsdLogMessage(CUPSD_LOG_ERROR,
+		      "cupsdAuthorize: getsockopt failed for SO_PEERCRED");
+      return;
+    }
+
+    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 (u.uid, &pwbuf, buf, buflen, &pwbufptr) != 0)
+    {
+      cupsdLogMessage(CUPSD_LOG_ERROR,
+		      "cupsdAuthorize: getpwuid_r failed after SO_PEERCRED");
+      free (buf);
+      return;
+    }
+
+    strlcpy(username, pwbuf.pw_name, sizeof(username));
+    free (buf);
+    cupsdLogMessage(CUPSD_LOG_DEBUG2,
+		    "cupsdAuthorize: using SO_PEERCRED (uid=%d)", u.uid);
+  }
+#endif /* SO_PEERCRED */
   else if (!strncmp(authorization, "Local", 5) &&
            !strcasecmp(con->http.hostname, "localhost"))
   {

Attachment: signature.asc
Description: This is a digitally signed message part

--
redhat-lspp mailing list
[email protected]
https://www.redhat.com/mailman/listinfo/redhat-lspp

Reply via email to