]> git.ipfire.org Git - thirdparty/cups.git/blobdiff - scheduler/auth.c
Move debug printfs to internal usage only.
[thirdparty/cups.git] / scheduler / auth.c
index 01f16634eb57d0f20e3d8e95e46a947140312dc3..0774ae3cf6627af289781549ca9d9df79872d231 100644 (file)
@@ -1,51 +1,14 @@
 /*
- * "$Id: auth.c 7830 2008-08-04 20:38:50Z mike $"
+ * Authorization routines for the CUPS scheduler.
  *
- *   Authorization routines for the CUPS scheduler.
+ * Copyright © 2007-2018 by Apple Inc.
+ * Copyright © 1997-2007 by Easy Software Products, all rights reserved.
  *
- *   Copyright 2007-2011 by Apple Inc.
- *   Copyright 1997-2007 by Easy Software Products, all rights reserved.
+ * This file contains Kerberos support code, copyright 2006 by
+ * Jelmer Vernooij.
  *
- *   This file contains Kerberos support code, copyright 2006 by
- *   Jelmer Vernooij.
- *
- *   These coded instructions, statements, and computer programs are the
- *   property of Apple Inc. and are protected by Federal copyright
- *   law.  Distribution and use rights are outlined in the file "LICENSE.txt"
- *   which should have been included with this file.  If this file is
- *   file is missing or damaged, see the license at "http://www.cups.org/".
- *
- * Contents:
- *
- *   cupsdAddIPMask()          - Add an IP address authorization mask.
- *   cupsdAddLocation()        - Add a location for authorization.
- *   cupsdAddName()            - Add a name to a location...
- *   cupsdAddNameMask()        - Add a host or interface name authorization
- *                               mask.
- *   cupsdAuthorize()          - Validate any authorization credentials.
- *   cupsdCheckAccess()        - Check whether the given address is allowed to
- *                               access a location.
- *   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.
- *   cupsdFindBest()           - Find the location entry that best matches the
- *                               resource.
- *   cupsdFindLocation()       - Find the named location.
- *   cupsdFreeLocation()       - Free all memory used by a location.
- *   cupsdIsAuthorized()       - Check to see if the user is authorized...
- *   cupsdNewLocation()        - Create a new location for authorization.
- *   check_authref()           - Check if an authorization services reference
- *                               has the supplied right.
- *   compare_locations()       - Compare two locations.
- *   copy_authmask()           - Copy function for auth masks.
- *   cups_crypt()              - Encrypt the password using the DES or MD5
- *                               algorithms, as needed.
- *   free_authmask()           - Free function for auth masks.
- *   get_md5_password()        - Get an MD5 password.
- *   pam_func()                - PAM conversation function.
- *   to64()                    - Base64-encode an integer value...
+ * Licensed under Apache License v2.0.  See the file "LICENSE" for more
+ * information.
  */
 
 /*
@@ -67,9 +30,6 @@
 #    include <security/pam_appl.h>
 #  endif /* HAVE_PAM_PAM_APPL_H */
 #endif /* HAVE_LIBPAM */
-#ifdef HAVE_USERSEC_H
-#  include <usersec.h>
-#endif /* HAVE_USERSEC_H */
 #ifdef HAVE_MEMBERSHIP_H
 #  include <membership.h>
 #endif /* HAVE_MEMBERSHIP_H */
@@ -89,14 +49,13 @@ extern const char *cssmErrorString(int error);
 typedef struct xucred cupsd_ucred_t;
 #  define CUPSD_UCRED_UID(c) (c).cr_uid
 #else
+#  ifndef __OpenBSD__
 typedef struct ucred cupsd_ucred_t;
+#  else
+typedef struct sockpeercred cupsd_ucred_t;
+#  endif
 #  define CUPSD_UCRED_UID(c) (c).uid
 #endif /* HAVE_SYS_UCRED_H */
-#ifdef HAVE_KRB5_IPC_CLIENT_SET_TARGET_UID
-/* Not in public headers... */
-extern void    krb5_ipc_client_set_target_uid(uid_t);
-extern void    krb5_ipc_client_clear_target(void);
-#endif /* HAVE_KRB5_IPC_CLIENT_SET_TARGET_UID */
 
 
 /*
@@ -109,16 +68,11 @@ static int         check_authref(cupsd_client_t *con, const char *right);
 static int             compare_locations(cupsd_location_t *a,
                                          cupsd_location_t *b);
 static cupsd_authmask_t        *copy_authmask(cupsd_authmask_t *am, void *data);
-#if !HAVE_LIBPAM && !defined(HAVE_USERSEC_H)
-static char            *cups_crypt(const char *pw, const char *salt);
-#endif /* !HAVE_LIBPAM && !HAVE_USERSEC_H */
 static void            free_authmask(cupsd_authmask_t *am, void *data);
-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 *);
-#elif !defined(HAVE_USERSEC_H)
+#else
 static void            to64(char *s, unsigned long v, int n);
 #endif /* HAVE_LIBPAM */
 
@@ -130,21 +84,12 @@ static void                to64(char *s, unsigned long v, int n);
 #if HAVE_LIBPAM
 typedef struct cupsd_authdata_s                /**** Authentication data ****/
 {
-  char username[33],                   /* Username string */
-       password[33];                   /* Password string */
+  char username[HTTP_MAX_VALUE],       /* Username string */
+       password[HTTP_MAX_VALUE];       /* Password string */
 } cupsd_authdata_t;
 #endif /* HAVE_LIBPAM */
 
 
-/*
- * Local globals...
- */
-
-#if defined(__hpux) && HAVE_LIBPAM
-static cupsd_authdata_t        *auth_data;     /* Current client being authenticated */
-#endif /* __hpux && HAVE_LIBPAM */
-
-
 /*
  * 'cupsdAddIPMask()' - Add an IP address authorization mask.
  */
@@ -158,12 +103,7 @@ cupsdAddIPMask(
   cupsd_authmask_t     temp;           /* New host/domain mask */
 
 
-  cupsdLogMessage(CUPSD_LOG_DEBUG2,
-                  "cupsdAddIPMask(masks=%p(%p), address=%x:%x:%x:%x, "
-                 "netmask=%x:%x:%x:%x)",
-                 masks, *masks,
-                 address[0], address[1], address[2], address[3],
-                 netmask[0], netmask[1], netmask[2], netmask[3]);
+  cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdAddIPMask(masks=%p(%p), address=%x:%x:%x:%x, netmask=%x:%x:%x:%x)", masks, *masks, address[0], address[1], address[2], address[3], netmask[0], netmask[1], netmask[2], netmask[3]);
 
   temp.type = CUPSD_AUTH_IP;
   memcpy(temp.mask.ip.address, address, sizeof(temp.mask.ip.address));
@@ -203,8 +143,7 @@ cupsdAddLocation(cupsd_location_t *loc)     /* I - Location to add */
   {
     cupsArrayAdd(Locations, loc);
 
-    cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdAddLocation: Added location \"%s\"",
-                    loc->location ? loc->location : "(null)");
+    cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdAddLocation: Added location \"%s\"", loc->location ? loc->location : "(null)");
   }
 }
 
@@ -217,8 +156,7 @@ void
 cupsdAddName(cupsd_location_t *loc,    /* I - Location to add to */
              char             *name)   /* I - Name to add */
 {
-  cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdAddName(loc=%p, name=\"%s\")",
-                  loc, name);
+  cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdAddName(loc=%p, name=\"%s\")", loc, name);
 
   if (!loc->names)
     loc->names = cupsArrayNew3(NULL, NULL, NULL, 0,
@@ -248,9 +186,7 @@ cupsdAddNameMask(cups_array_t **masks,      /* IO - Masks array (created as needed) *
                        *ifptr;         /* Pointer to end of name */
 
 
-  cupsdLogMessage(CUPSD_LOG_DEBUG2,
-                  "cupsdAddNameMask(masks=%p(%p), name=\"%s\")",
-                  masks, *masks, name);
+  cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdAddNameMask(masks=%p(%p), name=\"%s\")", masks, *masks, name);
 
   if (!_cups_strcasecmp(name, "@LOCAL"))
   {
@@ -322,29 +258,11 @@ cupsdAuthorize(cupsd_client_t *con)       /* I - Client connection */
   int          type;                   /* Authentication type */
   const char   *authorization;         /* Pointer into Authorization string */
   char         *ptr,                   /* Pointer into string */
-               username[256],          /* Username string */
-               password[33];           /* Password string */
+               username[HTTP_MAX_VALUE],
+                                       /* Username string */
+               password[HTTP_MAX_VALUE];
+                                       /* Password string */
   cupsd_cert_t *localuser;             /* Certificate username */
-  char         nonce[HTTP_MAX_VALUE],  /* Nonce value from client */
-               md5[33],                /* MD5 password */
-               basicmd5[33];           /* MD5 of Basic password */
-  static const char * const states[] = /* HTTP client states... */
-               {
-                 "WAITING",
-                 "OPTIONS",
-                 "GET",
-                 "GET",
-                 "HEAD",
-                 "POST",
-                 "POST",
-                 "POST",
-                 "PUT",
-                 "PUT",
-                 "DELETE",
-                 "TRACE",
-                 "CLOSE",
-                 "STATUS"
-               };
 
 
  /*
@@ -352,31 +270,26 @@ cupsdAuthorize(cupsd_client_t *con)       /* I - Client connection */
   * authentication to expect...
   */
 
-  con->best = cupsdFindBest(con->uri, con->http.state);
+  con->best = cupsdFindBest(con->uri, httpGetState(con->http));
   con->type = CUPSD_AUTH_NONE;
 
-  cupsdLogMessage(CUPSD_LOG_DEBUG2,
-                  "cupsdAuthorize: con->uri=\"%s\", con->best=%p(%s)",
-                  con->uri, con->best, con->best ? con->best->location : "");
+  cupsdLogClient(con, CUPSD_LOG_DEBUG2, "con->uri=\"%s\", con->best=%p(%s)", con->uri, con->best, con->best ? con->best->location : "");
 
   if (con->best && con->best->type != CUPSD_AUTH_NONE)
   {
     if (con->best->type == CUPSD_AUTH_DEFAULT)
-      type = DefaultAuthType;
+      type = cupsdDefaultAuthType();
     else
       type = con->best->type;
   }
   else
-    type = DefaultAuthType;
+    type = cupsdDefaultAuthType();
 
  /*
   * Decode the Authorization string...
   */
 
-  authorization = httpGetField(&con->http, HTTP_FIELD_AUTHORIZATION);
-
-  cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdAuthorize: Authorization=\"%s\"",
-                  authorization);
+  authorization = httpGetField(con->http, HTTP_FIELD_AUTHORIZATION);
 
   username[0] = '\0';
   password[0] = '\0';
@@ -399,15 +312,16 @@ cupsdAuthorize(cupsd_client_t *con)       /* I - Client connection */
     * No authorization data provided, return early...
     */
 
-    cupsdLogMessage(CUPSD_LOG_DEBUG,
-                    "cupsdAuthorize: No authentication data provided.");
+    cupsdLogClient(con, CUPSD_LOG_DEBUG, "No authentication data provided.");
     return;
   }
 #ifdef HAVE_AUTHORIZATION_H
   else if (!strncmp(authorization, "AuthRef ", 8) &&
-           !_cups_strcasecmp(con->http.hostname, "localhost"))
+           httpAddrLocalhost(httpGetAddress(con->http)))
   {
     OSStatus           status;         /* Status */
+    char               authdata[HTTP_MAX_VALUE];
+                                       /* Nonce value from client */
     int                        authlen;        /* Auth string length */
     AuthorizationItemSet *authinfo;    /* Authorization item set */
 
@@ -419,22 +333,18 @@ cupsdAuthorize(cupsd_client_t *con)       /* I - Client connection */
     while (isspace(*authorization & 255))
       authorization ++;
 
-    authlen = sizeof(nonce);
-    httpDecode64_2(nonce, &authlen, authorization);
+    authlen = sizeof(authdata);
+    httpDecode64_2(authdata, &authlen, authorization);
 
     if (authlen != kAuthorizationExternalFormLength)
     {
-      cupsdLogMessage(CUPSD_LOG_ERROR,
-                     "External Authorization reference size is incorrect!");
+      cupsdLogClient(con, CUPSD_LOG_ERROR, "External Authorization reference size is incorrect.");
       return;
     }
 
-    if ((status = AuthorizationCreateFromExternalForm(
-                     (AuthorizationExternalForm *)nonce, &con->authref)) != 0)
+    if ((status = AuthorizationCreateFromExternalForm((AuthorizationExternalForm *)authdata, &con->authref)) != 0)
     {
-      cupsdLogMessage(CUPSD_LOG_ERROR,
-                     "AuthorizationCreateFromExternalForm returned %d (%s)",
-                     (int)status, cssmErrorString(status));
+      cupsdLogClient(con, CUPSD_LOG_ERROR, "AuthorizationCreateFromExternalForm returned %d (%s)", (int)status, cssmErrorString(status));
       return;
     }
 
@@ -448,9 +358,7 @@ cupsdAuthorize(cupsd_client_t *con) /* I - Client connection */
       {
         strlcpy(username, authinfo->items[0].value, sizeof(username));
 
-        cupsdLogMessage(CUPSD_LOG_DEBUG,
-                       "cupsdAuthorize: Authorized as \"%s\" using AuthRef",
-                       username);
+        cupsdLogClient(con, CUPSD_LOG_DEBUG, "Authorized as \"%s\" using AuthRef.", username);
       }
 
       AuthorizationFreeItemSet(authinfo);
@@ -468,26 +376,21 @@ cupsdAuthorize(cupsd_client_t *con)       /* I - Client connection */
 
       peersize = sizeof(peercred);
 
-      if (getsockopt(con->http.fd, 0, LOCAL_PEERCRED, &peercred, &peersize))
+      if (getsockopt(httpGetFd(con->http), 0, LOCAL_PEERCRED, &peercred, &peersize))
       {
-        cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to get peer credentials - %s",
-                        strerror(errno));
+        cupsdLogClient(con, CUPSD_LOG_ERROR, "Unable to get peer credentials - %s", strerror(errno));
         return;
       }
 
       if ((pwd = getpwuid(CUPSD_UCRED_UID(peercred))) == NULL)
       {
-        cupsdLogMessage(CUPSD_LOG_ERROR,
-                        "Unable to find UID %d for peer credentials.",
-                        (int)CUPSD_UCRED_UID(peercred));
+        cupsdLogClient(con, CUPSD_LOG_ERROR, "Unable to find UID %d for peer credentials.", (int)CUPSD_UCRED_UID(peercred));
         return;
       }
 
       strlcpy(username, pwd->pw_name, sizeof(username));
 
-      cupsdLogMessage(CUPSD_LOG_DEBUG,
-                     "cupsdAuthorize: Authorized as \"%s\" using "
-                     "AuthRef + PeerCred", username);
+      cupsdLogClient(con, CUPSD_LOG_DEBUG, "Authorized as \"%s\" using AuthRef + PeerCred.", username);
     }
 
     con->type = CUPSD_AUTH_BASIC;
@@ -495,7 +398,7 @@ cupsdAuthorize(cupsd_client_t *con) /* I - Client connection */
 #endif /* HAVE_AUTHORIZATION_H */
 #if defined(SO_PEERCRED) && defined(AF_LOCAL)
   else if (!strncmp(authorization, "PeerCred ", 9) &&
-           con->http.hostaddr->addr.sa_family == AF_LOCAL)
+           con->http->hostaddr->addr.sa_family == AF_LOCAL && con->best)
   {
    /*
     * Use peer credentials from domain socket connection...
@@ -506,53 +409,63 @@ cupsdAuthorize(cupsd_client_t *con)       /* I - Client connection */
     socklen_t          peersize;       /* Size of peer credentials */
 #ifdef HAVE_AUTHORIZATION_H
     const char         *name;          /* Authorizing name */
+    int                        no_peer = 0;    /* Don't allow peer credentials? */
+
+   /*
+    * See if we should allow peer credentials...
+    */
 
     for (name = (char *)cupsArrayFirst(con->best->names);
          name;
          name = (char *)cupsArrayNext(con->best->names))
-      if (!_cups_strncasecmp(name, "@AUTHKEY(", 9) || !_cups_strcasecmp(name, "@SYSTEM"))
+    {
+      if (!_cups_strncasecmp(name, "@AUTHKEY(", 9) ||
+          !_cups_strcasecmp(name, "@SYSTEM"))
       {
-       cupsdLogMessage(CUPSD_LOG_ERROR,
-                       "PeerCred authentication not allowed for resource.");
-       return;
+       /* Normally don't want peer credentials if we need an auth key... */
+       no_peer = 1;
+      }
+      else if (!_cups_strcasecmp(name, "@OWNER"))
+      {
+       /* but if @OWNER is present then we allow it... */
+        no_peer = 0;
+        break;
       }
+    }
+
+    if (no_peer)
+    {
+      cupsdLogClient(con, CUPSD_LOG_ERROR, "PeerCred authentication not allowed for resource per AUTHKEY policy.");
+      return;
+    }
 #endif /* HAVE_AUTHORIZATION_H */
 
     if ((pwd = getpwnam(authorization + 9)) == NULL)
     {
-      cupsdLogMessage(CUPSD_LOG_ERROR, "User \"%s\" does not exist.",
-                      authorization + 9);
+      cupsdLogClient(con, CUPSD_LOG_ERROR, "User \"%s\" does not exist.", authorization + 9);
       return;
     }
 
     peersize = sizeof(peercred);
 
 #  ifdef __APPLE__
-    if (getsockopt(con->http.fd, 0, LOCAL_PEERCRED, &peercred, &peersize))
+    if (getsockopt(httpGetFd(con->http), 0, LOCAL_PEERCRED, &peercred, &peersize))
 #  else
-    if (getsockopt(con->http.fd, SOL_SOCKET, SO_PEERCRED, &peercred, &peersize))
+    if (getsockopt(httpGetFd(con->http), SOL_SOCKET, SO_PEERCRED, &peercred, &peersize))
 #  endif /* __APPLE__ */
     {
-      cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to get peer credentials - %s",
-                      strerror(errno));
+      cupsdLogClient(con, CUPSD_LOG_ERROR, "Unable to get peer credentials - %s", strerror(errno));
       return;
     }
 
     if (pwd->pw_uid != CUPSD_UCRED_UID(peercred))
     {
-      cupsdLogMessage(CUPSD_LOG_ERROR,
-                      "Invalid peer credentials for \"%s\" - got %d, "
-                     "expected %d!", authorization + 9,
-                     CUPSD_UCRED_UID(peercred), pwd->pw_uid);
+      cupsdLogClient(con, CUPSD_LOG_ERROR, "Invalid peer credentials for \"%s\" - got %d, expected %d.", authorization + 9, CUPSD_UCRED_UID(peercred), pwd->pw_uid);
 #  ifdef HAVE_SYS_UCRED_H
-      cupsdLogMessage(CUPSD_LOG_DEBUG, "cupsdAuthorize: cr_version=%d",
-                      peercred.cr_version);
-      cupsdLogMessage(CUPSD_LOG_DEBUG, "cupsdAuthorize: cr_uid=%d",
-                      peercred.cr_uid);
-      cupsdLogMessage(CUPSD_LOG_DEBUG, "cupsdAuthorize: cr_ngroups=%d",
-                      peercred.cr_ngroups);
-      cupsdLogMessage(CUPSD_LOG_DEBUG, "cupsdAuthorize: cr_groups[0]=%d",
-                      peercred.cr_groups[0]);
+      cupsdLogClient(con, CUPSD_LOG_DEBUG2, "cr_version=%d", peercred.cr_version);
+      cupsdLogClient(con, CUPSD_LOG_DEBUG2, "cr_uid=%d", peercred.cr_uid);
+      cupsdLogClient(con, CUPSD_LOG_DEBUG2, "cr_ngroups=%d", peercred.cr_ngroups);
+      cupsdLogClient(con, CUPSD_LOG_DEBUG2, "cr_groups[0]=%d", peercred.cr_groups[0]);
 #  endif /* HAVE_SYS_UCRED_H */
       return;
     }
@@ -563,15 +476,13 @@ cupsdAuthorize(cupsd_client_t *con)       /* I - Client connection */
     con->gss_uid = CUPSD_UCRED_UID(peercred);
 #  endif /* HAVE_GSSAPI */
 
-    cupsdLogMessage(CUPSD_LOG_DEBUG,
-                    "cupsdAuthorize: Authorized as %s using PeerCred",
-                   username);
+    cupsdLogClient(con, CUPSD_LOG_DEBUG, "Authorized as %s using PeerCred.", username);
 
     con->type = CUPSD_AUTH_BASIC;
   }
 #endif /* SO_PEERCRED && AF_LOCAL */
   else if (!strncmp(authorization, "Local", 5) &&
-           !_cups_strcasecmp(con->http.hostname, "localhost"))
+          httpAddrLocalhost(httpGetAddress(con->http)))
   {
    /*
     * Get Local certificate authentication data...
@@ -581,28 +492,16 @@ cupsdAuthorize(cupsd_client_t *con)       /* I - Client connection */
     while (isspace(*authorization & 255))
       authorization ++;
 
-    if ((localuser = cupsdFindCert(authorization)) != NULL)
+    if ((localuser = cupsdFindCert(authorization)) == NULL)
     {
-      strlcpy(username, localuser->username, sizeof(username));
-
-      cupsdLogMessage(CUPSD_LOG_DEBUG,
-                     "cupsdAuthorize: Authorized as %s using Local",
-                     username);
-    }
-    else
-    {
-      cupsdLogMessage(CUPSD_LOG_ERROR,
-                      "cupsdAuthorize: Local authentication certificate not "
-                     "found!");
+      cupsdLogClient(con, CUPSD_LOG_ERROR, "Local authentication certificate not found.");
       return;
     }
 
-#ifdef HAVE_GSSAPI
-    if (localuser->ccache)
-      con->type = CUPSD_AUTH_NEGOTIATE;
-    else
-#endif /* HAVE_GSSAPI */
-      con->type = CUPSD_AUTH_BASIC;
+    strlcpy(username, localuser->username, sizeof(username));
+    con->type = localuser->type;
+
+    cupsdLogClient(con, CUPSD_LOG_DEBUG, "Authorized as %s using Local.", username);
   }
   else if (!strncmp(authorization, "Basic", 5))
   {
@@ -626,8 +525,7 @@ cupsdAuthorize(cupsd_client_t *con) /* I - Client connection */
 
     if ((ptr = strchr(username, ':')) == NULL)
     {
-      cupsdLogMessage(CUPSD_LOG_ERROR,
-                      "cupsdAuthorize: Missing Basic password!");
+      cupsdLogClient(con, CUPSD_LOG_ERROR, "Missing Basic password.");
       return;
     }
 
@@ -639,8 +537,7 @@ cupsdAuthorize(cupsd_client_t *con) /* I - Client connection */
       * Username must not be empty...
       */
 
-      cupsdLogMessage(CUPSD_LOG_ERROR,
-                      "cupsdAuthorize: Empty Basic username!");
+      cupsdLogClient(con, CUPSD_LOG_ERROR, "Empty Basic username.");
       return;
     }
 
@@ -650,8 +547,7 @@ cupsdAuthorize(cupsd_client_t *con) /* I - Client connection */
       * Password must not be empty...
       */
 
-      cupsdLogMessage(CUPSD_LOG_ERROR,
-                      "cupsdAuthorize: Empty Basic password!");
+      cupsdLogClient(con, CUPSD_LOG_ERROR, "Empty Basic password.");
       return;
     }
 
@@ -681,60 +577,40 @@ cupsdAuthorize(cupsd_client_t *con)       /* I - Client connection */
             strlcpy(data.username, username, sizeof(data.username));
            strlcpy(data.password, password, sizeof(data.password));
 
-#  if defined(__sun) || defined(__hpux)
+#  ifdef __sun
            pamdata.conv        = (int (*)(int, struct pam_message **,
                                           struct pam_response **,
                                           void *))pam_func;
 #  else
            pamdata.conv        = pam_func;
-#  endif /* __sun || __hpux */
+#  endif /* __sun */
            pamdata.appdata_ptr = &data;
 
-#  ifdef __hpux
-          /*
-           * Workaround for HP-UX bug in pam_unix; see pam_func() below for
-           * more info...
-           */
-
-           auth_data = &data;
-#  endif /* __hpux */
-
            pamerr = pam_start("cups", username, &pamdata, &pamh);
            if (pamerr != PAM_SUCCESS)
            {
-             cupsdLogMessage(CUPSD_LOG_ERROR,
-                             "cupsdAuthorize: pam_start() returned %d (%s)!",
-                             pamerr, pam_strerror(pamh, pamerr));
+             cupsdLogClient(con, CUPSD_LOG_ERROR, "pam_start() returned %d (%s)", pamerr, pam_strerror(pamh, pamerr));
              return;
            }
 
 #  ifdef HAVE_PAM_SET_ITEM
 #    ifdef PAM_RHOST
-           pamerr = pam_set_item(pamh, PAM_RHOST, con->http.hostname);
+           pamerr = pam_set_item(pamh, PAM_RHOST, con->http->hostname);
            if (pamerr != PAM_SUCCESS)
-             cupsdLogMessage(CUPSD_LOG_WARN,
-                             "cupsdAuthorize: pam_set_item(PAM_RHOST) "
-                             "returned %d (%s)!", pamerr,
-                             pam_strerror(pamh, pamerr));
+             cupsdLogClient(con, CUPSD_LOG_WARN, "pam_set_item(PAM_RHOST) returned %d (%s)", pamerr, pam_strerror(pamh, pamerr));
 #    endif /* PAM_RHOST */
 
 #    ifdef PAM_TTY
            pamerr = pam_set_item(pamh, PAM_TTY, "cups");
            if (pamerr != PAM_SUCCESS)
-             cupsdLogMessage(CUPSD_LOG_WARN,
-                             "cupsdAuthorize: pam_set_item(PAM_TTY) "
-                             "returned %d (%s)!", pamerr,
-                             pam_strerror(pamh, pamerr));
+             cupsdLogClient(con, CUPSD_LOG_WARN, "pam_set_item(PAM_TTY) returned %d (%s)", pamerr, pam_strerror(pamh, pamerr));
 #    endif /* PAM_TTY */
 #  endif /* HAVE_PAM_SET_ITEM */
 
            pamerr = pam_authenticate(pamh, PAM_SILENT);
            if (pamerr != PAM_SUCCESS)
            {
-             cupsdLogMessage(CUPSD_LOG_ERROR,
-                             "cupsdAuthorize: pam_authenticate() returned %d "
-                             "(%s)!",
-                             pamerr, pam_strerror(pamh, pamerr));
+             cupsdLogClient(con, CUPSD_LOG_ERROR, "pam_authenticate() returned %d (%s)", pamerr, pam_strerror(pamh, pamerr));
              pam_end(pamh, 0);
              return;
            }
@@ -742,48 +618,19 @@ cupsdAuthorize(cupsd_client_t *con)       /* I - Client connection */
 #  ifdef HAVE_PAM_SETCRED
             pamerr = pam_setcred(pamh, PAM_ESTABLISH_CRED | PAM_SILENT);
            if (pamerr != PAM_SUCCESS)
-             cupsdLogMessage(CUPSD_LOG_WARN,
-                             "cupsdAuthorize: pam_setcred() "
-                             "returned %d (%s)!", pamerr,
-                             pam_strerror(pamh, pamerr));
+             cupsdLogClient(con, CUPSD_LOG_WARN, "pam_setcred() returned %d (%s)", pamerr, pam_strerror(pamh, pamerr));
 #  endif /* HAVE_PAM_SETCRED */
 
            pamerr = pam_acct_mgmt(pamh, PAM_SILENT);
            if (pamerr != PAM_SUCCESS)
            {
-             cupsdLogMessage(CUPSD_LOG_ERROR,
-                             "cupsdAuthorize: pam_acct_mgmt() returned %d "
-                             "(%s)!",
-                             pamerr, pam_strerror(pamh, pamerr));
+             cupsdLogClient(con, CUPSD_LOG_ERROR, "pam_acct_mgmt() returned %d (%s)", pamerr, pam_strerror(pamh, pamerr));
              pam_end(pamh, 0);
              return;
            }
 
            pam_end(pamh, PAM_SUCCESS);
 
-#elif defined(HAVE_USERSEC_H)
-          /*
-           * Use AIX authentication interface...
-           */
-
-           char        *authmsg;       /* Authentication message */
-           int         reenter;        /* ??? */
-
-
-           cupsdLogMessage(CUPSD_LOG_DEBUG,
-                           "cupsdAuthorize: AIX authenticate of username "
-                           "\"%s\"", username);
-
-           reenter = 1;
-           if (authenticate(username, password, &reenter, &authmsg) != 0)
-           {
-             cupsdLogMessage(CUPSD_LOG_DEBUG,
-                             "cupsdAuthorize: Unable to authenticate username "
-                             "\"%s\": %s",
-                             username, strerror(errno));
-             return;
-           }
-
 #else
            /*
            * Use normal UNIX password file-based authentication...
@@ -805,9 +652,7 @@ cupsdAuthorize(cupsd_client_t *con) /* I - Client connection */
              * No such user...
              */
 
-             cupsdLogMessage(CUPSD_LOG_ERROR,
-                             "cupsdAuthorize: Unknown username \"%s\"!",
-                             username);
+             cupsdLogClient(con, CUPSD_LOG_ERROR, "Unknown username \"%s\".", username);
              return;
            }
 
@@ -821,9 +666,7 @@ cupsdAuthorize(cupsd_client_t *con) /* I - Client connection */
              * Don't allow blank passwords!
              */
 
-             cupsdLogMessage(CUPSD_LOG_ERROR,
-                             "cupsdAuthorize: Username \"%s\" has no shadow "
-                             "password!", username);
+             cupsdLogClient(con, CUPSD_LOG_ERROR, "Username \"%s\" has no shadow password.", username);
              return;
            }
 
@@ -836,9 +679,7 @@ cupsdAuthorize(cupsd_client_t *con) /* I - Client connection */
              * Don't allow blank passwords!
              */
 
-             cupsdLogMessage(CUPSD_LOG_ERROR,
-                             "cupsdAuthorize: Username \"%s\" has no password!",
-                             username);
+             cupsdLogClient(con, CUPSD_LOG_ERROR, "Username \"%s\" has no password.", username);
              return;
            }
 
@@ -847,156 +688,37 @@ cupsdAuthorize(cupsd_client_t *con)      /* I - Client connection */
            * client...
            */
 
-           pass = cups_crypt(password, pw->pw_passwd);
-
-           cupsdLogMessage(CUPSD_LOG_DEBUG2,
-                           "cupsdAuthorize: pw_passwd=\"%s\", crypt=\"%s\"",
-                           pw->pw_passwd, pass);
+           pass = crypt(password, pw->pw_passwd);
 
            if (!pass || strcmp(pw->pw_passwd, pass))
            {
 #  ifdef HAVE_SHADOW_H
              if (spw)
              {
-               pass = cups_crypt(password, spw->sp_pwdp);
-
-               cupsdLogMessage(CUPSD_LOG_DEBUG2,
-                               "cupsdAuthorize: sp_pwdp=\"%s\", crypt=\"%s\"",
-                               spw->sp_pwdp, pass);
+               pass = crypt(password, spw->sp_pwdp);
 
                if (pass == NULL || strcmp(spw->sp_pwdp, pass))
                {
-                 cupsdLogMessage(CUPSD_LOG_ERROR,
-                                 "cupsdAuthorize: Authentication failed for "
-                                 "user \"%s\"!",
-                                 username);
+                 cupsdLogClient(con, CUPSD_LOG_ERROR, "Authentication failed for user \"%s\".", username);
                  return;
                }
              }
              else
 #  endif /* HAVE_SHADOW_H */
              {
-               cupsdLogMessage(CUPSD_LOG_ERROR,
-                               "cupsdAuthorize: Authentication failed for "
-                               "user \"%s\"!",
-                               username);
+               cupsdLogClient(con, CUPSD_LOG_ERROR, "Authentication failed for user \"%s\".", username);
                return;
               }
            }
 #endif /* HAVE_LIBPAM */
           }
 
-         cupsdLogMessage(CUPSD_LOG_DEBUG,
-                         "cupsdAuthorize: Authorized as %s using Basic",
-                         username);
+         cupsdLogClient(con, CUPSD_LOG_DEBUG, "Authorized as \"%s\" using Basic.", username);
           break;
-
-      case CUPSD_AUTH_BASICDIGEST :
-         /*
-         * Do Basic authentication with the Digest password file...
-         */
-
-         if (!get_md5_password(username, NULL, md5))
-         {
-            cupsdLogMessage(CUPSD_LOG_ERROR,
-                           "cupsdAuthorize: Unknown MD5 username \"%s\"!",
-                           username);
-            return;
-         }
-
-         httpMD5(username, "CUPS", password, basicmd5);
-
-         if (strcmp(md5, basicmd5))
-         {
-            cupsdLogMessage(CUPSD_LOG_ERROR,
-                           "cupsdAuthorize: Authentication failed for \"%s\"!",
-                           username);
-            return;
-         }
-
-         cupsdLogMessage(CUPSD_LOG_DEBUG,
-                         "cupsdAuthorize: Authorized as %s using BasicDigest",
-                         username);
-         break;
     }
 
     con->type = type;
   }
-  else if (!strncmp(authorization, "Digest", 6))
-  {
-   /*
-    * Get the username, password, and nonce from the Digest attributes...
-    */
-
-    if (!httpGetSubField2(&(con->http), HTTP_FIELD_AUTHORIZATION, "username",
-                          username, sizeof(username)) || !username[0])
-    {
-     /*
-      * Username must not be empty...
-      */
-
-      cupsdLogMessage(CUPSD_LOG_ERROR,
-                      "cupsdAuthorize: Empty or missing Digest username!");
-      return;
-    }
-
-    if (!httpGetSubField2(&(con->http), HTTP_FIELD_AUTHORIZATION, "response",
-                          password, sizeof(password)) || !password[0])
-    {
-     /*
-      * Password must not be empty...
-      */
-
-      cupsdLogMessage(CUPSD_LOG_ERROR,
-                      "cupsdAuthorize: Empty or missing Digest password!");
-      return;
-    }
-
-    if (!httpGetSubField(&(con->http), HTTP_FIELD_AUTHORIZATION, "nonce",
-                         nonce))
-    {
-      cupsdLogMessage(CUPSD_LOG_ERROR,
-                     "cupsdAuthorize: No nonce value for Digest "
-                     "authentication!");
-      return;
-    }
-
-    if (strcmp(con->http.hostname, nonce))
-    {
-      cupsdLogMessage(CUPSD_LOG_ERROR,
-                     "cupsdAuthorize: Bad nonce value, expected \"%s\", "
-                     "got \"%s\"!", con->http.hostname, nonce);
-      return;
-    }
-
-   /*
-    * Validate the username and password...
-    */
-
-    if (!get_md5_password(username, NULL, md5))
-    {
-      cupsdLogMessage(CUPSD_LOG_ERROR,
-                     "cupsdAuthorize: Unknown MD5 username \"%s\"!",
-                     username);
-      return;
-    }
-
-    httpMD5Final(nonce, states[con->http.state], con->uri, md5);
-
-    if (strcmp(md5, password))
-    {
-      cupsdLogMessage(CUPSD_LOG_ERROR,
-                     "cupsdAuthorize: Authentication failed for \"%s\"!",
-                     username);
-      return;
-    }
-
-    cupsdLogMessage(CUPSD_LOG_DEBUG,
-                    "cupsdAuthorize: Authorized as %s using Digest",
-                   username);
-
-    con->type = CUPSD_AUTH_DIGEST;
-  }
 #ifdef HAVE_GSSAPI
   else if (!strncmp(authorization, "Negotiate", 9))
   {
@@ -1017,11 +739,9 @@ cupsdAuthorize(cupsd_client_t *con)       /* I - Client connection */
     * to use it...
     */
 
-    if (gss_init_sec_context == NULL)
+    if (&gss_init_sec_context == NULL)
     {
-      cupsdLogMessage(CUPSD_LOG_WARN,
-                      "GSSAPI/Kerberos authentication failed because the "
-                     "Kerberos framework is not present.");
+      cupsdLogClient(con, CUPSD_LOG_WARN, "GSSAPI/Kerberos authentication failed because the Kerberos framework is not present.");
       return;
     }
 #  endif /* __APPLE__ */
@@ -1036,8 +756,7 @@ cupsdAuthorize(cupsd_client_t *con)        /* I - Client connection */
 
     if (!*authorization)
     {
-      cupsdLogMessage(CUPSD_LOG_DEBUG2,
-                     "cupsdAuthorize: No authentication data specified.");
+      cupsdLogClient(con, CUPSD_LOG_DEBUG2, "No authentication data specified.");
       return;
     }
 
@@ -1045,11 +764,11 @@ cupsdAuthorize(cupsd_client_t *con)      /* I - Client connection */
     * Decode the authorization string to get the input token...
     */
 
-    len                = strlen(authorization);
-    input_token.value  = malloc(len);
+    len                = (int)strlen(authorization);
+    input_token.value  = malloc((size_t)len);
     input_token.value  = httpDecode64_2(input_token.value, &len,
                                        authorization);
-    input_token.length = len;
+    input_token.length = (size_t)len;
 
    /*
     * Accept the input token to get the authorization info...
@@ -1059,7 +778,7 @@ cupsdAuthorize(cupsd_client_t *con)        /* I - Client connection */
     client_name  = GSS_C_NO_NAME;
     major_status = gss_accept_sec_context(&minor_status,
                                          &context,
-                                         GSS_C_NO_CREDENTIAL,
+                                         ServerCreds,
                                          &input_token,
                                          GSS_C_NO_CHANNEL_BINDINGS,
                                          &client_name,
@@ -1074,9 +793,7 @@ cupsdAuthorize(cupsd_client_t *con)        /* I - Client connection */
 
     if (GSS_ERROR(major_status))
     {
-      cupsdLogGSSMessage(CUPSD_LOG_DEBUG, major_status, minor_status,
-                        "cupsdAuthorize: Error accepting GSSAPI security "
-                        "context");
+      cupsdLogGSSMessage(CUPSD_LOG_DEBUG, major_status, minor_status, "[Client %d] Error accepting GSSAPI security context.", con->number);
 
       if (context != GSS_C_NO_CONTEXT)
        gss_delete_sec_context(&minor_status, &context, GSS_C_NO_BUFFER);
@@ -1090,8 +807,7 @@ cupsdAuthorize(cupsd_client_t *con)        /* I - Client connection */
     */
 
     if (major_status == GSS_S_CONTINUE_NEEDED)
-      cupsdLogGSSMessage(CUPSD_LOG_DEBUG, major_status, minor_status,
-                        "cupsdAuthorize: Credentials not complete");
+      cupsdLogGSSMessage(CUPSD_LOG_DEBUG, major_status, minor_status, "[Client %d] Credentials not complete.", con->number);
     else if (major_status == GSS_S_COMPLETE)
     {
       major_status = gss_display_name(&minor_status, client_name,
@@ -1099,8 +815,7 @@ cupsdAuthorize(cupsd_client_t *con)        /* I - Client connection */
 
       if (GSS_ERROR(major_status))
       {
-       cupsdLogGSSMessage(CUPSD_LOG_DEBUG, major_status, minor_status,
-                          "cupsdAuthorize: Error getting username");
+       cupsdLogGSSMessage(CUPSD_LOG_DEBUG, major_status, minor_status, "[Client %d] Error getting username.", con->number);
        gss_release_name(&minor_status, &client_name);
        gss_delete_sec_context(&minor_status, &context, GSS_C_NO_BUFFER);
        return;
@@ -1108,9 +823,7 @@ cupsdAuthorize(cupsd_client_t *con)        /* I - Client connection */
 
       strlcpy(username, output_token.value, sizeof(username));
 
-      cupsdLogMessage(CUPSD_LOG_DEBUG,
-                     "cupsdAuthorize: Authorized as %s using Negotiate",
-                     username);
+      cupsdLogClient(con, CUPSD_LOG_DEBUG, "Authorized as \"%s\" using Negotiate.", username);
 
       gss_release_name(&minor_status, &client_name);
       gss_release_buffer(&minor_status, &output_token);
@@ -1126,7 +839,7 @@ cupsdAuthorize(cupsd_client_t *con)        /* I - Client connection */
     * to run as the correct user to get Kerberos credentials of its own.
     */
 
-    if (_httpAddrFamily(con->http.hostaddr) == AF_LOCAL)
+    if (httpAddrFamily(con->http->hostaddr) == AF_LOCAL)
     {
       cupsd_ucred_t    peercred;       /* Peer credentials */
       socklen_t                peersize;       /* Size of peer credentials */
@@ -1134,20 +847,17 @@ cupsdAuthorize(cupsd_client_t *con)      /* I - Client connection */
       peersize = sizeof(peercred);
 
 #    ifdef __APPLE__
-      if (getsockopt(con->http.fd, 0, LOCAL_PEERCRED, &peercred, &peersize))
+      if (getsockopt(httpGetFd(con->http), 0, LOCAL_PEERCRED, &peercred, &peersize))
 #    else
-      if (getsockopt(con->http.fd, SOL_SOCKET, SO_PEERCRED, &peercred,
+      if (getsockopt(httpGetFd(con->http), SOL_SOCKET, SO_PEERCRED, &peercred,
                      &peersize))
 #    endif /* __APPLE__ */
       {
-       cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to get peer credentials - %s",
-                       strerror(errno));
+       cupsdLogClient(con, CUPSD_LOG_ERROR, "Unable to get peer credentials - %s", strerror(errno));
       }
       else
       {
-       cupsdLogMessage(CUPSD_LOG_DEBUG,
-                       "cupsdAuthorize: Using credentials for UID %d...",
-                       CUPSD_UCRED_UID(peercred));
+       cupsdLogClient(con, CUPSD_LOG_DEBUG, "Using credentials for UID %d.", CUPSD_UCRED_UID(peercred));
         con->gss_uid = CUPSD_UCRED_UID(peercred);
       }
     }
@@ -1160,10 +870,9 @@ cupsdAuthorize(cupsd_client_t *con)       /* I - Client connection */
 
 
     if (sscanf(authorization, "%255s", scheme) != 1)
-      strcpy(scheme, "UNKNOWN");
+      strlcpy(scheme, "UNKNOWN", sizeof(scheme));
 
-    cupsdLogMessage(CUPSD_LOG_ERROR, "Bad authentication data \"%s ...\"",
-                    scheme);
+    cupsdLogClient(con, CUPSD_LOG_ERROR, "Bad authentication data \"%s ...\".", scheme);
     return;
   }
 
@@ -1186,8 +895,8 @@ cupsdAuthorize(cupsd_client_t *con)        /* I - Client connection */
 int                                    /* O - 1 if allowed, 0 otherwise */
 cupsdCheckAccess(
     unsigned         ip[4],            /* I - Client address */
-    char             *name,            /* I - Client hostname */
-    int              namelen,          /* I - Length of hostname */
+    const char       *name,            /* I - Client hostname */
+    size_t           namelen,          /* I - Length of hostname */
     cupsd_location_t *loc)             /* I - Location to check */
 {
   int  allow;                          /* 1 if allowed, 0 otherwise */
@@ -1245,8 +954,8 @@ cupsdCheckAccess(
 
 int                                    /* O - 1 if mask matches, 0 otherwise */
 cupsdCheckAuth(unsigned     ip[4],     /* I - Client address */
-              char         *name,      /* I - Client hostname */
-              int          name_len,   /* I - Length of hostname */
+              const char   *name,      /* I - Client hostname */
+              size_t       name_len,   /* I - Length of hostname */
               cups_array_t *masks)     /* I - Masks */
 {
   int                  i;              /* Looping var */
@@ -1278,6 +987,8 @@ cupsdCheckAuth(unsigned     ip[4], /* I - Client address */
           netip6[3] = htonl(ip[3]);
 #endif /* AF_INET6 */
 
+         cupsdNetIFUpdate();
+
           if (!strcmp(mask->mask.name.name, "*"))
          {
 #ifdef __APPLE__
@@ -1293,8 +1004,6 @@ cupsdCheckAuth(unsigned     ip[4],        /* I - Client address */
            * Check against all local interfaces...
            */
 
-            cupsdNetIFUpdate();
-
            for (iface = (cupsd_netif_t *)cupsArrayFirst(NetIFList);
                 iface;
                 iface = (cupsd_netif_t *)cupsArrayNext(NetIFList))
@@ -1431,8 +1140,8 @@ cupsdCheckGroup(
     const char    *groupname)          /* I - Group name */
 {
   int          i;                      /* Looping var */
-  struct group *group;                 /* System group info */
-  char         junk[33];               /* MD5 password (not used) */
+  struct group *group;                 /* Group info */
+  gid_t                groupid;                /* ID of named group */
 #ifdef HAVE_MBR_UID_TO_UUID
   uuid_t       useruuid,               /* UUID for username */
                groupuuid;              /* UUID for groupname */
@@ -1440,9 +1149,7 @@ cupsdCheckGroup(
 #endif /* HAVE_MBR_UID_TO_UUID */
 
 
-  cupsdLogMessage(CUPSD_LOG_DEBUG2,
-                  "cupsdCheckGroup(username=\"%s\", user=%p, groupname=\"%s\")",
-                  username, user, groupname);
+  cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdCheckGroup(username=\"%s\", user=%p, groupname=\"%s\")", username, user, groupname);
 
  /*
   * Validate input...
@@ -1464,33 +1171,63 @@ cupsdCheckGroup(
     * Group exists, check it...
     */
 
+    groupid = group->gr_gid;
+
+#ifdef HAVE_GETGROUPLIST
+    if (user)
+    {
+      int      ngroups;                /* Number of groups */
+#  ifdef __APPLE__
+      int      groups[2048];           /* Groups that user belongs to */
+#  else
+      gid_t    groups[2048];           /* Groups that user belongs to */
+#  endif /* __APPLE__ */
+
+      ngroups = (int)(sizeof(groups) / sizeof(groups[0]));
+#  ifdef __APPLE__
+      getgrouplist(username, (int)user->pw_gid, groups, &ngroups);
+#  else
+      getgrouplist(username, user->pw_gid, groups, &ngroups);
+#endif /* __APPLE__ */
+
+      for (i = 0; i < ngroups; i ++)
+        if ((int)groupid == (int)groups[i])
+         return (1);
+    }
+
+#else
     for (i = 0; group->gr_mem[i]; i ++)
+    {
       if (!_cups_strcasecmp(username, group->gr_mem[i]))
        return (1);
+    }
+#endif /* HAVE_GETGROUPLIST */
   }
+  else
+    groupid = (gid_t)-1;
 
  /*
   * Group doesn't exist or user not in group list, check the group ID
   * against the user's group ID...
   */
 
-  if (user && group && group->gr_gid == user->pw_gid)
+  if (user && groupid == user->pw_gid)
     return (1);
 
 #ifdef HAVE_MBR_UID_TO_UUID
  /*
-  * Check group membership through MacOS X membership API...
+  * Check group membership through macOS membership API...
   */
 
   if (user && !mbr_uid_to_uuid(user->pw_uid, useruuid))
   {
-    if (group)
+    if (groupid != (gid_t)-1)
     {
      /*
       * Map group name to UUID and check membership...
       */
 
-      if (!mbr_gid_to_uuid(group->gr_gid, groupuuid))
+      if (!mbr_gid_to_uuid(groupid, groupuuid))
         if (!mbr_check_membership(useruuid, groupuuid, &is_member))
          if (is_member)
            return (1);
@@ -1518,15 +1255,6 @@ cupsdCheckGroup(
     return (0);
 #endif /* HAVE_MBR_UID_TO_UUID */
 
- /*
-  * Username not found, group not found, or user is not part of the
-  * system group...  Check for a user and group in the MD5 password
-  * file...
-  */
-
-  if (get_md5_password(username, groupname, junk) != NULL)
-    return (1);
-
  /*
   * If we get this far, then the user isn't part of the named group...
   */
@@ -1563,6 +1291,7 @@ cupsdCopyLocation(
   if (loc->location)
     temp->location = _cupsStrAlloc(loc->location);
 
+  temp->length     = loc->length;
   temp->limit      = loc->limit;
   temp->order_type = loc->order_type;
   temp->type       = loc->type;
@@ -1648,7 +1377,7 @@ cupsdFindBest(const char   *path, /* I - Resource path */
                        *uriptr;        /* Pointer into URI */
   cupsd_location_t     *loc,           /* Current location */
                        *best;          /* Best match for location so far */
-  int                  bestlen;        /* Length of best match */
+  size_t               bestlen;        /* Length of best match */
   int                  limit;          /* Limit field */
   static const int     limits[] =      /* Map http_status_t to CUPSD_AUTH_LIMIT_xyz */
                {
@@ -1665,6 +1394,8 @@ cupsdFindBest(const char   *path, /* I - Resource path */
                  CUPSD_AUTH_LIMIT_DELETE,
                  CUPSD_AUTH_LIMIT_TRACE,
                  CUPSD_AUTH_LIMIT_ALL,
+                 CUPSD_AUTH_LIMIT_ALL,
+                 CUPSD_AUTH_LIMIT_ALL,
                  CUPSD_AUTH_LIMIT_ALL
                };
 
@@ -1677,6 +1408,12 @@ cupsdFindBest(const char   *path,        /* I - Resource path */
 
   strlcpy(uri, path, sizeof(uri));
 
+  if ((uriptr = strchr(uri, '?')) != NULL)
+    *uriptr = '\0';            /* Drop trailing query string */
+
+  if ((uriptr = uri + strlen(uri) - 1) > uri && *uriptr == '/')
+    *uriptr = '\0';            /* Remove trailing '/' */
+
   if (!strncmp(uri, "/printers/", 10) ||
       !strncmp(uri, "/classes/", 9))
   {
@@ -1690,8 +1427,6 @@ cupsdFindBest(const char   *path, /* I - Resource path */
       *uriptr = '\0';
   }
 
-  cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdFindBest: uri = \"%s\"...", uri);
-
  /*
   * Loop through the list of locations to find a match...
   */
@@ -1700,12 +1435,14 @@ cupsdFindBest(const char   *path,       /* I - Resource path */
   best    = NULL;
   bestlen = 0;
 
+  cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdFindBest: uri=\"%s\", limit=%x...", uri, limit);
+
+
   for (loc = (cupsd_location_t *)cupsArrayFirst(Locations);
        loc;
        loc = (cupsd_location_t *)cupsArrayNext(Locations))
   {
-    cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdFindBest: Location %s Limit %x",
-                    loc->location ? loc->location : "nil", loc->limit);
+    cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdFindBest: Location %s(%d) Limit %x", loc->location ? loc->location : "(null)", (int)loc->length, loc->limit);
 
     if (!strncmp(uri, "/printers/", 10) || !strncmp(uri, "/classes/", 9))
     {
@@ -1743,8 +1480,7 @@ cupsdFindBest(const char   *path, /* I - Resource path */
   * Return the match, if any...
   */
 
-  cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdFindBest: best = %s",
-                  best ? best->location : "NONE");
+  cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdFindBest: best=%s", best ? best->location : "NONE");
 
   return (best);
 }
@@ -1793,9 +1529,13 @@ cupsdIsAuthorized(cupsd_client_t *con,   /* I - Connection */
   int                  i,              /* Looping vars */
                        auth,           /* Authorization status */
                        type;           /* Type of authentication */
+  http_addr_t          *hostaddr = httpGetAddress(con->http);
+                                       /* Client address */
+  const char           *hostname = httpGetHostname(con->http, NULL, 0);
+                                       /* Client hostname */
   unsigned             address[4];     /* Authorization address */
   cupsd_location_t     *best;          /* Best match for location so far */
-  int                  hostlen;        /* Length of hostname */
+  size_t               hostlen;        /* Length of hostname */
   char                 *name,          /* Current username */
                        username[256],  /* Username to authorize */
                        ownername[256], /* Owner name to authorize */
@@ -1811,19 +1551,13 @@ cupsdIsAuthorized(cupsd_client_t *con,  /* I - Connection */
                {
                  "None",
                  "Basic",
-                 "Digest",
-                 "BasicDigest",
                  "Negotiate"
                };
 
 
-  cupsdLogMessage(CUPSD_LOG_DEBUG2,
-                  "cupsdIsAuthorized: con->uri=\"%s\", con->best=%p(%s)",
-                  con->uri, con->best, con->best ? con->best->location ?
-                                          con->best->location : "(null)" : "");
+  cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdIsAuthorized: con->uri=\"%s\", con->best=%p(%s)", con->uri, con->best, con->best ? con->best->location ? con->best->location : "(null)" : "");
   if (owner)
-    cupsdLogMessage(CUPSD_LOG_DEBUG2,
-                    "cupsdIsAuthorized: owner=\"%s\"", owner);
+    cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdIsAuthorized: owner=\"%s\"", owner);
 
  /*
   * If there is no "best" authentication rule for this request, then
@@ -1833,8 +1567,9 @@ cupsdIsAuthorized(cupsd_client_t *con,    /* I - Connection */
 
   if (!con->best)
   {
-    if (!strcmp(con->http.hostname, "localhost") ||
-        !strcmp(con->http.hostname, ServerName))
+    if (httpAddrLocalhost(httpGetAddress(con->http)) ||
+        !strcmp(hostname, ServerName) ||
+       cupsArrayFind(ServerAlias, (void *)hostname))
       return (HTTP_OK);
     else
       return (HTTP_FORBIDDEN);
@@ -1843,37 +1578,32 @@ cupsdIsAuthorized(cupsd_client_t *con,  /* I - Connection */
   best = con->best;
 
   if ((type = best->type) == CUPSD_AUTH_DEFAULT)
-    type = DefaultAuthType;
+    type = cupsdDefaultAuthType();
 
-  cupsdLogMessage(CUPSD_LOG_DEBUG2,
-                  "cupsdIsAuthorized: level=CUPSD_AUTH_%s, type=%s, "
-                 "satisfy=CUPSD_AUTH_SATISFY_%s, num_names=%d",
-                  levels[best->level], types[type],
-                 best->satisfy ? "ANY" : "ALL", cupsArrayCount(best->names));
+  cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdIsAuthorized: level=CUPSD_AUTH_%s, type=%s, satisfy=CUPSD_AUTH_SATISFY_%s, num_names=%d", levels[best->level], types[type], best->satisfy ? "ANY" : "ALL", cupsArrayCount(best->names));
 
   if (best->limit == CUPSD_AUTH_LIMIT_IPP)
-    cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdIsAuthorized: op=%x(%s)",
-                    best->op, ippOpString(best->op));
+    cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdIsAuthorized: op=%x(%s)", best->op, ippOpString(best->op));
 
  /*
   * Check host/ip-based accesses...
   */
 
 #ifdef AF_INET6
-  if (con->http.hostaddr->addr.sa_family == AF_INET6)
+  if (httpAddrFamily(hostaddr) == AF_INET6)
   {
    /*
     * Copy IPv6 address...
     */
 
-    address[0] = ntohl(con->http.hostaddr->ipv6.sin6_addr.s6_addr32[0]);
-    address[1] = ntohl(con->http.hostaddr->ipv6.sin6_addr.s6_addr32[1]);
-    address[2] = ntohl(con->http.hostaddr->ipv6.sin6_addr.s6_addr32[2]);
-    address[3] = ntohl(con->http.hostaddr->ipv6.sin6_addr.s6_addr32[3]);
+    address[0] = ntohl(hostaddr->ipv6.sin6_addr.s6_addr32[0]);
+    address[1] = ntohl(hostaddr->ipv6.sin6_addr.s6_addr32[1]);
+    address[2] = ntohl(hostaddr->ipv6.sin6_addr.s6_addr32[2]);
+    address[3] = ntohl(hostaddr->ipv6.sin6_addr.s6_addr32[3]);
   }
   else
 #endif /* AF_INET6 */
-  if (con->http.hostaddr->addr.sa_family == AF_INET)
+  if (con->http->hostaddr->addr.sa_family == AF_INET)
   {
    /*
     * Copy IPv4 address...
@@ -1882,18 +1612,17 @@ cupsdIsAuthorized(cupsd_client_t *con,  /* I - Connection */
     address[0] = 0;
     address[1] = 0;
     address[2] = 0;
-    address[3] = ntohl(con->http.hostaddr->ipv4.sin_addr.s_addr);
+    address[3] = ntohl(hostaddr->ipv4.sin_addr.s_addr);
   }
   else
     memset(address, 0, sizeof(address));
 
-  hostlen = strlen(con->http.hostname);
+  hostlen = strlen(hostname);
 
-  auth = cupsdCheckAccess(address, con->http.hostname, hostlen, best)
+  auth = cupsdCheckAccess(address, hostname, hostlen, best)
              ? CUPSD_AUTH_ALLOW : CUPSD_AUTH_DENY;
 
-  cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdIsAuthorized: auth=CUPSD_AUTH_%s...",
-                  auth ? "DENY" : "ALLOW");
+  cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdIsAuthorized: auth=CUPSD_AUTH_%s...", auth ? "DENY" : "ALLOW");
 
   if (auth == CUPSD_AUTH_DENY && best->satisfy == CUPSD_AUTH_SATISFY_ALL)
     return (HTTP_FORBIDDEN);
@@ -1903,11 +1632,13 @@ cupsdIsAuthorized(cupsd_client_t *con,  /* I - Connection */
   * See if encryption is required...
   */
 
-  if ((best->encryption >= HTTP_ENCRYPT_REQUIRED && !con->http.tls &&
-      _cups_strcasecmp(con->http.hostname, "localhost") &&
+  if ((best->encryption >= HTTP_ENCRYPT_REQUIRED && !con->http->tls &&
+      _cups_strcasecmp(hostname, "localhost") &&
+      !httpAddrLocalhost(hostaddr) &&
       best->satisfy == CUPSD_AUTH_SATISFY_ALL) &&
       !(type == CUPSD_AUTH_NEGOTIATE ||
-        (type == CUPSD_AUTH_NONE && DefaultAuthType == CUPSD_AUTH_NEGOTIATE)))
+        (type == CUPSD_AUTH_NONE &&
+         cupsdDefaultAuthType() == CUPSD_AUTH_NEGOTIATE)))
   {
     cupsdLogMessage(CUPSD_LOG_DEBUG,
                     "cupsdIsAuthorized: Need upgrade to TLS...");
@@ -1968,9 +1699,9 @@ cupsdIsAuthorized(cupsd_client_t *con,    /* I - Connection */
 #ifdef HAVE_GSSAPI
         (type != CUPSD_AUTH_NEGOTIATE || con->gss_uid <= 0) &&
 #endif /* HAVE_GSSAPI */
-        (con->type != CUPSD_AUTH_BASIC || type != CUPSD_AUTH_BASICDIGEST))
+        con->type != CUPSD_AUTH_BASIC)
     {
-      cupsdLogMessage(CUPSD_LOG_ERROR, "Authorized using %s, expected %s!",
+      cupsdLogMessage(CUPSD_LOG_ERROR, "Authorized using %s, expected %s.",
                       types[con->type], types[type]);
 
       return (HTTP_UNAUTHORIZED);
@@ -2031,8 +1762,7 @@ cupsdIsAuthorized(cupsd_client_t *con,    /* I - Connection */
     * allowed...
     */
 
-    cupsdLogMessage(CUPSD_LOG_DEBUG2,
-                    "cupsdIsAuthorized: Checking user membership...");
+    cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdIsAuthorized: Checking user membership...");
 
 #ifdef HAVE_AUTHORIZATION_H
    /*
@@ -2085,8 +1815,7 @@ cupsdIsAuthorized(cupsd_client_t *con,    /* I - Connection */
   * Check to see if this user is in any of the named groups...
   */
 
-  cupsdLogMessage(CUPSD_LOG_DEBUG2,
-                  "cupsdIsAuthorized: Checking group membership...");
+  cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdIsAuthorized: Checking group membership...");
 
  /*
   * Check to see if this user is in any of the named groups...
@@ -2096,9 +1825,7 @@ cupsdIsAuthorized(cupsd_client_t *con,    /* I - Connection */
        name;
        name = (char *)cupsArrayNext(best->names))
   {
-    cupsdLogMessage(CUPSD_LOG_DEBUG2,
-                    "cupsdIsAuthorized: Checking group \"%s\" membership...",
-                    name);
+    cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdIsAuthorized: Checking group \"%s\" membership...", name);
 
     if (!_cups_strcasecmp(name, "@SYSTEM"))
     {
@@ -2114,8 +1841,7 @@ cupsdIsAuthorized(cupsd_client_t *con,    /* I - Connection */
   * The user isn't part of the specified group, so deny access...
   */
 
-  cupsdLogMessage(CUPSD_LOG_DEBUG,
-                  "cupsdIsAuthorized: User not in group(s)!");
+  cupsdLogMessage(CUPSD_LOG_DEBUG, "cupsdIsAuthorized: User not in group(s).");
 
   return (con->username[0] ? HTTP_FORBIDDEN : HTTP_UNAUTHORIZED);
 }
@@ -2205,9 +1931,7 @@ check_authref(cupsd_client_t *con,        /* I - Connection */
     return (0);
   }
 
-  cupsdLogMessage(CUPSD_LOG_DEBUG2,
-                  "AuthorizationCopyRights(\"%s\") succeeded!",
-                 authright.name);
+  cupsdLogMessage(CUPSD_LOG_DEBUG2, "AuthorizationCopyRights(\"%s\") succeeded.", authright.name);
 
   return (1);
 }
@@ -2265,129 +1989,6 @@ copy_authmask(cupsd_authmask_t *mask,   /* I - Existing auth mask */
 }
 
 
-#if !HAVE_LIBPAM && !defined(HAVE_USERSEC_H)
-/*
- * 'cups_crypt()' - Encrypt the password using the DES or MD5 algorithms,
- *                  as needed.
- */
-
-static char *                          /* O - Encrypted password */
-cups_crypt(const char *pw,             /* I - Password string */
-           const char *salt)           /* I - Salt (key) string */
-{
-  if (!strncmp(salt, "$1$", 3))
-  {
-   /*
-    * Use MD5 passwords without the benefit of PAM; this is for
-    * Slackware Linux, and the algorithm was taken from the
-    * old shadow-19990827/lib/md5crypt.c source code... :(
-    */
-
-    int                        i;              /* Looping var */
-    unsigned long      n;              /* Output number */
-    int                        pwlen;          /* Length of password string */
-    const char         *salt_end;      /* End of "salt" data for MD5 */
-    char               *ptr;           /* Pointer into result string */
-    _cups_md5_state_t  state;          /* Primary MD5 state info */
-    _cups_md5_state_t  state2;         /* Secondary MD5 state info */
-    unsigned char      digest[16];     /* MD5 digest result */
-    static char                result[120];    /* Final password string */
-
-
-   /*
-    * Get the salt data between dollar signs, e.g. $1$saltdata$md5.
-    * Get a maximum of 8 characters of salt data after $1$...
-    */
-
-    for (salt_end = salt + 3; *salt_end && (salt_end - salt) < 11; salt_end ++)
-      if (*salt_end == '$')
-        break;
-
-   /*
-    * Compute the MD5 sum we need...
-    */
-
-    pwlen = strlen(pw);
-
-    _cupsMD5Init(&state);
-    _cupsMD5Append(&state, (unsigned char *)pw, pwlen);
-    _cupsMD5Append(&state, (unsigned char *)salt, salt_end - salt);
-
-    _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)
-      _cupsMD5Append(&state, digest, i > 16 ? 16 : i);
-
-    for (i = pwlen; i > 0; i >>= 1)
-      _cupsMD5Append(&state, (unsigned char *)((i & 1) ? "" : pw), 1);
-
-    _cupsMD5Finish(&state, digest);
-
-    for (i = 0; i < 1000; i ++)
-    {
-      _cupsMD5Init(&state);
-
-      if (i & 1)
-        _cupsMD5Append(&state, (unsigned char *)pw, pwlen);
-      else
-        _cupsMD5Append(&state, digest, 16);
-
-      if (i % 3)
-        _cupsMD5Append(&state, (unsigned char *)salt + 3, salt_end - salt - 3);
-
-      if (i % 7)
-        _cupsMD5Append(&state, (unsigned char *)pw, pwlen);
-
-      if (i & 1)
-        _cupsMD5Append(&state, digest, 16);
-      else
-        _cupsMD5Append(&state, (unsigned char *)pw, pwlen);
-
-      _cupsMD5Finish(&state, digest);
-    }
-
-   /*
-    * Copy the final sum to the result string and return...
-    */
-
-    memcpy(result, salt, salt_end - salt);
-    ptr = result + (salt_end - salt);
-    *ptr++ = '$';
-
-    for (i = 0; i < 5; i ++, ptr += 4)
-    {
-      n = (((digest[i] << 8) | digest[i + 6]) << 8);
-
-      if (i < 4)
-        n |= digest[i + 12];
-      else
-        n |= digest[5];
-
-      to64(ptr, n, 4);
-    }
-
-    to64(ptr, digest[11], 2);
-    ptr += 2;
-    *ptr = '\0';
-
-    return (result);
-  }
-  else
-  {
-   /*
-    * Use the standard crypt() function...
-    */
-
-    return (crypt(pw, salt));
-  }
-}
-#endif /* !HAVE_LIBPAM && !HAVE_USERSEC_H */
-
-
 /*
  * 'free_authmask()' - Free function for auth masks.
  */
@@ -2405,68 +2006,6 @@ free_authmask(cupsd_authmask_t *mask,    /* I - Auth mask to free */
 }
 
 
-/*
- * '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.
@@ -2489,62 +2028,40 @@ pam_func(
   * Allocate memory for the responses...
   */
 
-  if ((replies = malloc(sizeof(struct pam_response) * num_msg)) == NULL)
+  if ((replies = malloc(sizeof(struct pam_response) * (size_t)num_msg)) == NULL)
     return (PAM_CONV_ERR);
 
  /*
   * Answer all of the messages...
   */
 
-  DEBUG_printf(("pam_func: appdata_ptr = %p\n", appdata_ptr));
-
-#ifdef __hpux
- /*
-  * Apparently some versions of HP-UX 11 have a broken pam_unix security
-  * module.  This is a workaround...
-  */
-
-  data = auth_data;
-  (void)appdata_ptr;
-#else
   data = (cupsd_authdata_t *)appdata_ptr;
-#endif /* __hpux */
 
   for (i = 0; i < num_msg; i ++)
   {
-    DEBUG_printf(("pam_func: Message = \"%s\"\n", msg[i]->msg));
-
     switch (msg[i]->msg_style)
     {
       case PAM_PROMPT_ECHO_ON:
-          DEBUG_printf(("pam_func: PAM_PROMPT_ECHO_ON, returning \"%s\"...\n",
-                       data->username));
           replies[i].resp_retcode = PAM_SUCCESS;
           replies[i].resp         = strdup(data->username);
           break;
 
       case PAM_PROMPT_ECHO_OFF:
-          DEBUG_printf(("pam_func: PAM_PROMPT_ECHO_OFF, returning \"%s\"...\n",
-                       data->password));
           replies[i].resp_retcode = PAM_SUCCESS;
           replies[i].resp         = strdup(data->password);
           break;
 
       case PAM_TEXT_INFO:
-          DEBUG_puts("pam_func: PAM_TEXT_INFO...");
           replies[i].resp_retcode = PAM_SUCCESS;
           replies[i].resp         = NULL;
           break;
 
       case PAM_ERROR_MSG:
-          DEBUG_puts("pam_func: PAM_ERROR_MSG...");
           replies[i].resp_retcode = PAM_SUCCESS;
           replies[i].resp         = NULL;
           break;
 
       default:
-          DEBUG_printf(("pam_func: Unknown PAM message %d...\n",
-                       msg[i]->msg_style));
           free(replies);
           return (PAM_CONV_ERR);
     }
@@ -2558,7 +2075,7 @@ pam_func(
 
   return (PAM_SUCCESS);
 }
-#elif !defined(HAVE_USERSEC_H)
+#else
 
 
 /*
@@ -2579,8 +2096,3 @@ to64(char          *s,                    /* O - Output string */
     *s++ = itoa64[v & 0x3f];
 }
 #endif /* HAVE_LIBPAM */
-
-
-/*
- * End of "$Id: auth.c 7830 2008-08-04 20:38:50Z mike $".
- */