]> git.ipfire.org Git - thirdparty/cups.git/blobdiff - scheduler/auth.c
Remove svn:keywords since they cause svn_load_dirs.pl to complain about every file.
[thirdparty/cups.git] / scheduler / auth.c
index 89011f7db89ab0e2ef1cc58fd89f6190a6da9959..da3c8347bf3c96fe363fc09c2325318f406a0d79 100644 (file)
@@ -1,5 +1,5 @@
-;/*
- * "$Id: auth.c 5083 2006-02-06 02:57:43Z mike $"
+/*
+ * "$Id: auth.c 181 2006-06-22 20:01:18Z jlovell $"
  *
  *   Authorization routines for the Common UNIX Printing System (CUPS).
  *
  *   cupsdAddName()            - Add a name to a location...
  *   cupsdAllowHost()          - Add a host name that is allowed to access the
  *                               location.
- *   cupsdAllowIP()            - Add an IP address or network that is allowed to
- *                               access the location.
+ *   cupsdAllowIP()            - Add an IP address or network that is allowed
+ *                               to access the location.
+ *   cupsdAuthorize()          - Validate any authorization credentials.
  *   cupsdCheckAuth()          - Check authorization masks.
  *   cupsdCheckGroup()         - Check for a user's group membership.
  *   cupsdCopyLocation()       - Make a copy of a location...
- *   cupsdDeleteAllLocations() - Free all memory used for location authorization.
+ *   cupsdDeleteAllLocations() - Free all memory used for location
+ *                               authorization.
  *   cupsdDeleteLocation()     - Free all memory used by a location.
- *   cupsdDenyHost()           - Add a host name that is not allowed to access the
- *                               location.
- *   cupsdDenyIP()             - Add an IP address or network that is not allowed
- *                               to access the location.
+ *   cupsdDenyHost()           - Add a host name that is not allowed to access
+ *                               the location.
+ *   cupsdDenyIP()             - Add an IP address or network that is not
+ *                               allowed to access the location.
  *   cupsdFindBest()           - Find the location entry that best matches the
  *                               resource.
  *   cupsdFindLocation()       - Find the named location.
- *   cupsdGetMD5Passwd()       - Get an MD5 password.
  *   cupsdIsAuthorized()       - Check to see if the user is authorized...
  *   add_allow()               - Add an allow mask to the location.
  *   add_deny()                - Add a deny mask to the location.
  *   compare_locations()       - Compare two locations.
  *   cups_crypt()              - Encrypt the password using the DES or MD5
  *                               algorithms, as needed.
+ *   get_md5_password()        - Get an MD5 password.
  *   pam_func()                - PAM conversation function.
  *   to64()                    - Base64-encode an integer value...
  */
@@ -90,6 +92,8 @@ static int            compare_locations(cupsd_location_t *a,
 #if !HAVE_LIBPAM
 static char            *cups_crypt(const char *pw, const char *salt);
 #endif /* !HAVE_LIBPAM */
+static char            *get_md5_password(const char *username,
+                                         const char *group, char passwd[33]);
 #if HAVE_LIBPAM
 static int             pam_func(int, const struct pam_message **,
                                 struct pam_response **, void *);
@@ -115,8 +119,8 @@ typedef struct cupsd_authdata_s             /**** Authentication data ****/
  * Local globals...
  */
 
-#if defined(__hpux) && defined(HAVE_LIBPAM)
-static cupsd_authdata_t        *auth_datat;    /* Current client being authenticated */
+#if defined(__hpux) && HAVE_LIBPAM
+static cupsd_authdata_t        *auth_data    /* Current client being authenticated */
 #endif /* __hpux && HAVE_LIBPAM */
 
 
@@ -189,7 +193,7 @@ cupsdAddName(cupsd_location_t *loc, /* I - Location to add to */
   if (temp == NULL)
   {
     cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to add name to location %s: %s",
-                    loc->location, strerror(errno));
+                    loc->location ? loc->location : "nil", strerror(errno));
     return;
   }
 
@@ -199,7 +203,7 @@ cupsdAddName(cupsd_location_t *loc, /* I - Location to add to */
   {
     cupsdLogMessage(CUPSD_LOG_ERROR,
                     "Unable to duplicate name for location %s: %s",
-                    loc->location, strerror(errno));
+                    loc->location ? loc->location : "nil", strerror(errno));
     return;
   }
 
@@ -221,7 +225,7 @@ cupsdAllowHost(cupsd_location_t *loc,       /* I - Location to add to */
 
 
   cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdAllowHost(loc=%p(%s), name=\"%s\")",
-                  loc, loc->location, name);
+                  loc, loc->location ? loc->location : "nil", name);
 
   if ((temp = add_allow(loc)) == NULL)
     return;
@@ -284,9 +288,9 @@ cupsdAllowIP(cupsd_location_t *loc, /* I - Location to add to */
 
   cupsdLogMessage(CUPSD_LOG_DEBUG2,
                   "cupsdAllowIP(loc=%p(%s), address=%x:%x:%x:%x, netmask=%x:%x:%x:%x)",
-                 loc, loc->location, address[0], address[1], address[2],
-                 address[3], netmask[0], netmask[1], netmask[2],
-                 netmask[3]);
+                 loc, loc->location ? loc->location : "nil",
+                 address[0], address[1], address[2], address[3],
+                 netmask[0], netmask[1], netmask[2], netmask[3]);
 
   if ((temp = add_allow(loc)) == NULL)
     return;
@@ -388,7 +392,7 @@ cupsdAuthorize(cupsd_client_t *con) /* I - Client connection */
     */
 
     authorization += 5;
-    while (isspace(*authorization))
+    while (isspace(*authorization & 255))
       authorization ++;
 
     if ((localuser = cupsdFindCert(authorization)) != NULL)
@@ -412,7 +416,7 @@ cupsdAuthorize(cupsd_client_t *con) /* I - Client connection */
 
 
     authorization += 5;
-    while (isspace(*authorization))
+    while (isspace(*authorization & 255))
       authorization ++;
 
     userlen = sizeof(username);
@@ -478,7 +482,13 @@ cupsdAuthorize(cupsd_client_t *con)        /* I - Client connection */
             strlcpy(data.username, username, sizeof(data.username));
            strlcpy(data.password, password, sizeof(data.password));
 
+#  ifdef __sun
+           pamdata.conv        = (int (*)(int, struct pam_message **,
+                                          struct pam_response **,
+                                          void *))pam_func;
+#  else
            pamdata.conv        = pam_func;
+#  endif /* __sun */
            pamdata.appdata_ptr = &data;
 
 #  ifdef __hpux
@@ -572,7 +582,7 @@ cupsdAuthorize(cupsd_client_t *con) /* I - Client connection */
              cupsdLogMessage(CUPSD_LOG_ERROR,
                              "cupsdAuthorize: Unknown username \"%s\"!",
                              username);
-             return (HTTP_UNAUTHORIZED);
+             return;
            }
 
 #  ifdef HAVE_SHADOW_H
@@ -656,7 +666,7 @@ cupsdAuthorize(cupsd_client_t *con) /* I - Client connection */
          * Do Basic authentication with the Digest password file...
          */
 
-         if (!cupsdGetMD5Passwd(username, NULL, md5))
+         if (!get_md5_password(username, NULL, md5))
          {
             cupsdLogMessage(CUPSD_LOG_ERROR,
                            "cupsdAuthorize: Unknown MD5 username \"%s\"!",
@@ -727,7 +737,7 @@ cupsdAuthorize(cupsd_client_t *con) /* I - Client connection */
     * Validate the username and password...
     */
 
-    if (!cupsdGetMD5Passwd(username, NULL, md5))
+    if (!get_md5_password(username, NULL, md5))
     {
       cupsdLogMessage(CUPSD_LOG_ERROR,
                      "cupsdAuthorize: Unknown MD5 username \"%s\"!",
@@ -859,9 +869,12 @@ cupsdCheckAuth(
            */
 
            for (iface = (cupsd_netif_t *)cupsArrayFirst(NetIFList);
-                iface && !strcmp(masks->mask.name.name, iface->name);
+                iface;
                 iface = (cupsd_netif_t *)cupsArrayNext(NetIFList))
            {
+              if (strcmp(masks->mask.name.name, iface->name))
+                continue;
+
               if (iface->address.addr.sa_family == AF_INET)
              {
               /*
@@ -1012,7 +1025,7 @@ cupsdCheckGroup(
   * file...
   */
 
-  if (cupsdGetMD5Passwd(username, groupname, junk) != NULL)
+  if (get_md5_password(username, groupname, junk) != NULL)
     return (1);
 
  /*
@@ -1248,7 +1261,7 @@ cupsdDenyHost(cupsd_location_t *loc,      /* I - Location to add to */
 
 
   cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdDenyHost(loc=%p(%s), name=\"%s\")",
-                  loc, loc->location, name);
+                  loc, loc->location ? loc->location : "nil", name);
 
   if ((temp = add_deny(loc)) == NULL)
     return;
@@ -1311,9 +1324,9 @@ cupsdDenyIP(cupsd_location_t *loc,        /* I - Location to add to */
 
   cupsdLogMessage(CUPSD_LOG_DEBUG,
                   "cupsdDenyIP(loc=%p(%s), address=%x:%x:%x:%x, netmask=%x:%x:%x:%x)",
-                 loc, loc->location, address[0], address[1], address[2],
-                 address[3], netmask[0], netmask[1], netmask[2],
-                 netmask[3]);
+                 loc, loc->location ? loc->location : "nil",
+                 address[0], address[1], address[2], address[3],
+                 netmask[0], netmask[1], netmask[2], netmask[3]);
 
   if ((temp = add_deny(loc)) == NULL)
     return;
@@ -1394,7 +1407,7 @@ cupsdFindBest(const char   *path, /* I - Resource path */
        loc = (cupsd_location_t *)cupsArrayNext(Locations))
   {
     cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdFindBest: Location %s Limit %x",
-                    loc->location, loc->limit);
+                    loc->location ? loc->location : "nil", loc->limit);
 
     if (!strncmp(uri, "/printers/", 10) || !strncmp(uri, "/classes/", 9))
     {
@@ -1402,7 +1415,7 @@ cupsdFindBest(const char   *path, /* I - Resource path */
       * Use case-insensitive comparison for queue names...
       */
 
-      if (loc->length > bestlen &&
+      if (loc->length > bestlen && loc->location &&
           !strncasecmp(uri, loc->location, loc->length) &&
          loc->location[0] == '/' &&
          (limit & loc->limit) != 0)
@@ -1417,7 +1430,7 @@ cupsdFindBest(const char   *path, /* I - Resource path */
       * Use case-sensitive comparison for other URIs...
       */
 
-      if (loc->length > bestlen &&
+      if (loc->length > bestlen && loc->location &&
           !strncmp(uri, loc->location, loc->length) &&
          loc->location[0] == '/' &&
          (limit & loc->limit) != 0)
@@ -1455,68 +1468,6 @@ cupsdFindLocation(const char *location)  /* I - Connection */
 }
 
 
-/*
- * 'cupsdGetMD5Passwd()' - Get an MD5 password.
- */
-
-char *                                 /* O - MD5 password string */
-cupsdGetMD5Passwd(const char *username,        /* I - Username */
-                  const char *group,   /* I - Group */
-                  char       passwd[33])/* O - MD5 password string */
-{
-  cups_file_t  *fp;                    /* passwd.md5 file */
-  char         filename[1024],         /* passwd.md5 filename */
-               line[256],              /* Line from file */
-               tempuser[33],           /* User from file */
-               tempgroup[33];          /* Group from file */
-
-
-  cupsdLogMessage(CUPSD_LOG_DEBUG2,
-                  "cupsdGetMD5Passwd(username=\"%s\", group=\"%s\", passwd=%p)",
-                  username, group ? group : "(null)", passwd);
-
-  snprintf(filename, sizeof(filename), "%s/passwd.md5", ServerRoot);
-  if ((fp = cupsFileOpen(filename, "r")) == NULL)
-  {
-    if (errno != ENOENT)
-      cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to open %s - %s", filename,
-                      strerror(errno));
-
-    return (NULL);
-  }
-
-  while (cupsFileGets(fp, line, sizeof(line)) != NULL)
-  {
-    if (sscanf(line, "%32[^:]:%32[^:]:%32s", tempuser, tempgroup, passwd) != 3)
-    {
-      cupsdLogMessage(CUPSD_LOG_ERROR, "Bad MD5 password line: %s", line);
-      continue;
-    }
-
-    if (!strcmp(username, tempuser) &&
-        (group == NULL || !strcmp(group, tempgroup)))
-    {
-     /*
-      * Found the password entry!
-      */
-
-      cupsdLogMessage(CUPSD_LOG_DEBUG2, "Found MD5 user %s, group %s...",
-                      username, tempgroup);
-
-      cupsFileClose(fp);
-      return (passwd);
-    }
-  }
-
- /*
-  * Didn't find a password entry - return NULL!
-  */
-
-  cupsFileClose(fp);
-  return (NULL);
-}
-
-
 /*
  * 'cupsdIsAuthorized()' - Check to see if the user is authorized...
  */
@@ -1549,7 +1500,8 @@ cupsdIsAuthorized(cupsd_client_t *con,    /* I - Connection */
 
   cupsdLogMessage(CUPSD_LOG_DEBUG2,
                   "cupsdIsAuthorized: con->uri=\"%s\", con->best=%p(%s)",
-                  con->uri, con->best, con->best ? con->best->location : "");
+                  con->uri, con->best, con->best ? con->best->location ?
+                                          con->best->location : "(null)" : "");
   if (owner)
     cupsdLogMessage(CUPSD_LOG_DEBUG2,
                     "cupsdIsAuthorized: owner=\"%s\"", owner);
@@ -1618,7 +1570,7 @@ cupsdIsAuthorized(cupsd_client_t *con,    /* I - Connection */
   if (!strcasecmp(con->http.hostname, "localhost"))
   {
    /*
-    * Access from localhost (127.0.0.1 or :::1) is always allowed...
+    * Access from localhost (127.0.0.1 or ::1) is always allowed...
     */
 
     auth = AUTH_ALLOW;
@@ -1673,6 +1625,7 @@ cupsdIsAuthorized(cupsd_client_t *con,    /* I - Connection */
   */
 
   if (best->encryption >= HTTP_ENCRYPT_REQUIRED && !con->http.tls &&
+      strcasecmp(con->http.hostname, "localhost") &&
       best->satisfy == AUTH_SATISFY_ALL)
   {
     cupsdLogMessage(CUPSD_LOG_DEBUG2,
@@ -1962,45 +1915,45 @@ cups_crypt(const char *pw,              /* I - Password string */
 
     pwlen = strlen(pw);
 
-    _cups_md5_init(&state);
-    _cups_md5_append(&state, (unsigned char *)pw, pwlen);
-    _cups_md5_append(&state, (unsigned char *)salt, salt_end - salt);
+    _cupsMD5Init(&state);
+    _cupsMD5Append(&state, (unsigned char *)pw, pwlen);
+    _cupsMD5Append(&state, (unsigned char *)salt, salt_end - salt);
 
-    _cups_md5_init(&state2);
-    _cups_md5_append(&state2, (unsigned char *)pw, pwlen);
-    _cups_md5_append(&state2, (unsigned char *)salt + 3, salt_end - salt - 3);
-    _cups_md5_append(&state2, (unsigned char *)pw, pwlen);
-    _cups_md5_finish(&state2, digest);
+    _cupsMD5Init(&state2);
+    _cupsMD5Append(&state2, (unsigned char *)pw, pwlen);
+    _cupsMD5Append(&state2, (unsigned char *)salt + 3, salt_end - salt - 3);
+    _cupsMD5Append(&state2, (unsigned char *)pw, pwlen);
+    _cupsMD5Finish(&state2, digest);
 
     for (i = pwlen; i > 0; i -= 16)
-      _cups_md5_append(&state, digest, i > 16 ? 16 : i);
+      _cupsMD5Append(&state, digest, i > 16 ? 16 : i);
 
     for (i = pwlen; i > 0; i >>= 1)
-      _cups_md5_append(&state, (unsigned char *)((i & 1) ? "" : pw), 1);
+      _cupsMD5Append(&state, (unsigned char *)((i & 1) ? "" : pw), 1);
 
-    _cups_md5_finish(&state, digest);
+    _cupsMD5Finish(&state, digest);
 
     for (i = 0; i < 1000; i ++)
     {
-      _cups_md5_init(&state);
+      _cupsMD5Init(&state);
 
       if (i & 1)
-        _cups_md5_append(&state, (unsigned char *)pw, pwlen);
+        _cupsMD5Append(&state, (unsigned char *)pw, pwlen);
       else
-        _cups_md5_append(&state, digest, 16);
+        _cupsMD5Append(&state, digest, 16);
 
       if (i % 3)
-        _cups_md5_append(&state, (unsigned char *)salt + 3, salt_end - salt - 3);
+        _cupsMD5Append(&state, (unsigned char *)salt + 3, salt_end - salt - 3);
 
       if (i % 7)
-        _cups_md5_append(&state, (unsigned char *)pw, pwlen);
+        _cupsMD5Append(&state, (unsigned char *)pw, pwlen);
 
       if (i & 1)
-        _cups_md5_append(&state, digest, 16);
+        _cupsMD5Append(&state, digest, 16);
       else
-        _cups_md5_append(&state, (unsigned char *)pw, pwlen);
+        _cupsMD5Append(&state, (unsigned char *)pw, pwlen);
 
-      _cups_md5_finish(&state, digest);
+      _cupsMD5Finish(&state, digest);
     }
 
    /*
@@ -2041,6 +1994,68 @@ cups_crypt(const char *pw,               /* I - Password string */
 #endif /* !HAVE_LIBPAM */
 
 
+/*
+ * 'get_md5_password()' - Get an MD5 password.
+ */
+
+static char *                          /* O - MD5 password string */
+get_md5_password(const char *username, /* I - Username */
+                 const char *group,    /* I - Group */
+                 char       passwd[33])        /* O - MD5 password string */
+{
+  cups_file_t  *fp;                    /* passwd.md5 file */
+  char         filename[1024],         /* passwd.md5 filename */
+               line[256],              /* Line from file */
+               tempuser[33],           /* User from file */
+               tempgroup[33];          /* Group from file */
+
+
+  cupsdLogMessage(CUPSD_LOG_DEBUG2,
+                  "get_md5_password(username=\"%s\", group=\"%s\", passwd=%p)",
+                  username, group ? group : "(null)", passwd);
+
+  snprintf(filename, sizeof(filename), "%s/passwd.md5", ServerRoot);
+  if ((fp = cupsFileOpen(filename, "r")) == NULL)
+  {
+    if (errno != ENOENT)
+      cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to open %s - %s", filename,
+                      strerror(errno));
+
+    return (NULL);
+  }
+
+  while (cupsFileGets(fp, line, sizeof(line)) != NULL)
+  {
+    if (sscanf(line, "%32[^:]:%32[^:]:%32s", tempuser, tempgroup, passwd) != 3)
+    {
+      cupsdLogMessage(CUPSD_LOG_ERROR, "Bad MD5 password line: %s", line);
+      continue;
+    }
+
+    if (!strcmp(username, tempuser) &&
+        (group == NULL || !strcmp(group, tempgroup)))
+    {
+     /*
+      * Found the password entry!
+      */
+
+      cupsdLogMessage(CUPSD_LOG_DEBUG2, "Found MD5 user %s, group %s...",
+                      username, tempgroup);
+
+      cupsFileClose(fp);
+      return (passwd);
+    }
+  }
+
+ /*
+  * Didn't find a password entry - return NULL!
+  */
+
+  cupsFileClose(fp);
+  return (NULL);
+}
+
+
 #if HAVE_LIBPAM
 /*
  * 'pam_func()' - PAM conversation function.
@@ -2156,5 +2171,5 @@ to64(char          *s,                    /* O - Output string */
 
 
 /*
- * End of "$Id: auth.c 5083 2006-02-06 02:57:43Z mike $".
+ * End of "$Id: auth.c 181 2006-06-22 20:01:18Z jlovell $".
  */