]> git.ipfire.org Git - thirdparty/cups.git/blobdiff - scheduler/auth.c
Import CUPS 1.4svn r7023 into easysw/current.
[thirdparty/cups.git] / scheduler / auth.c
index 06aec349c1b21570eb9e11670f29807ecd0ce80f..d77d075d61566d87cc6b38fb6fc677be262bc8d9 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * "$Id: auth.c 6649 2007-07-11 21:46:42Z mike $"
+ * "$Id: auth.c 6947 2007-09-12 21:09:49Z mike $"
  *
  *   Authorization routines for the Common UNIX Printing System (CUPS).
  *
@@ -83,6 +83,9 @@
 extern const char *cssmErrorString(int error);
 #  endif /* HAVE_SECBASEPRIV_H */
 #endif /* HAVE_AUTHORIZATION_H */
+#ifdef HAVE_SYS_PARAM_H
+#  include <sys/param.h>
+#endif /* HAVE_SYS_PARAM_H */
 #ifdef HAVE_SYS_UCRED_H
 #  include <sys/ucred.h>
 typedef struct xucred cupsd_ucred_t;
@@ -329,7 +332,7 @@ 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[65],           /* Username string */
+               username[256],          /* Username string */
                password[33];           /* Password string */
   const char   *localuser;             /* Certificate username */
   char         nonce[HTTP_MAX_VALUE],  /* Nonce value from client */
@@ -366,7 +369,12 @@ cupsdAuthorize(cupsd_client_t *con)        /* I - Client connection */
                   con->uri, con->best, con->best ? con->best->location : "");
 
   if (con->best && con->best->type != AUTH_NONE)
-    type = con->best->type;
+  {
+    if (con->best->type == AUTH_DEFAULT)
+      type = DefaultAuthType;
+    else
+      type = con->best->type;
+  }
   else
     type = DefaultAuthType;
 
@@ -458,6 +466,10 @@ cupsdAuthorize(cupsd_client_t *con)        /* I - Client connection */
     if (authinfo->count == 1)
       strlcpy(username, authinfo->items[0].value, sizeof(username));
 
+    cupsdLogMessage(CUPSD_LOG_DEBUG,
+                    "cupsdAuthorize: Authorized as %s using AuthRef",
+                   username);
+
     AuthorizationFreeItemSet(authinfo);
   }
 #endif /* HAVE_AUTHORIZATION_H */
@@ -510,6 +522,10 @@ cupsdAuthorize(cupsd_client_t *con)        /* I - Client connection */
     }
 
     strlcpy(username, authorization + 9, sizeof(username));
+
+    cupsdLogMessage(CUPSD_LOG_DEBUG,
+                    "cupsdAuthorize: Authorized as %s using PeerCred",
+                   username);
   }
 #endif /* SO_PEERCRED && AF_LOCAL */
   else if (!strncmp(authorization, "Local", 5) &&
@@ -524,7 +540,13 @@ cupsdAuthorize(cupsd_client_t *con)        /* I - Client connection */
       authorization ++;
 
     if ((localuser = cupsdFindCert(authorization)) != NULL)
+    {
       strlcpy(username, localuser, sizeof(username));
+
+      cupsdLogMessage(CUPSD_LOG_DEBUG,
+                     "cupsdAuthorize: Authorized as %s using Local",
+                     username);
+    }
     else
     {
       cupsdLogMessage(CUPSD_LOG_ERROR,
@@ -786,6 +808,10 @@ cupsdAuthorize(cupsd_client_t *con)        /* I - Client connection */
            }
 #endif /* HAVE_LIBPAM */
           }
+
+         cupsdLogMessage(CUPSD_LOG_DEBUG,
+                         "cupsdAuthorize: Authorized as %s using Basic",
+                         username);
           break;
 
       case AUTH_BASICDIGEST :
@@ -810,6 +836,10 @@ cupsdAuthorize(cupsd_client_t *con)        /* I - Client connection */
                            username);
             return;
          }
+
+         cupsdLogMessage(CUPSD_LOG_DEBUG,
+                         "cupsdAuthorize: Authorized as %s using BasicDigest",
+                         username);
          break;
     }
   }
@@ -881,9 +911,13 @@ cupsdAuthorize(cupsd_client_t *con)        /* I - Client connection */
                      username);
       return;
     }
+
+    cupsdLogMessage(CUPSD_LOG_DEBUG,
+                    "cupsdAuthorize: Authorized as %s using Digest",
+                   username);
   }
 #ifdef HAVE_GSSAPI
-  else if (!strncmp(authorization, "Negotiate", 9) && type == AUTH_NEGOTIATE
+  else if (!strncmp(authorization, "Negotiate", 9)) 
   {
     int                        len;            /* Length of authorization string */
     gss_cred_id_t      server_creds;   /* Server credentials */
@@ -895,6 +929,7 @@ cupsdAuthorize(cupsd_client_t *con) /* I - Client connection */
                        output_token = GSS_C_EMPTY_BUFFER;
                                        /* Output token for username */
     gss_name_t         client_name;    /* Client name */
+    unsigned int       ret_flags;      /* Credential flags */
 
 
 #  ifdef __APPLE__
@@ -934,10 +969,7 @@ cupsdAuthorize(cupsd_client_t *con)        /* I - Client connection */
     */
 
     if ((server_creds = get_gss_creds(GSSServiceName)) == NULL)
-    {
-      con->no_negotiate = 1;
       return;  
-    }
 
    /*
     * Decode the authorization string to get the input token...
@@ -963,7 +995,7 @@ cupsdAuthorize(cupsd_client_t *con) /* I - Client connection */
                                          &client_name,
                                          NULL,
                                          &con->gss_output_token,
-                                         NULL,
+                                         &ret_flags,
                                          NULL,
                                          &con->gss_delegated_cred);
 
@@ -976,15 +1008,28 @@ cupsdAuthorize(cupsd_client_t *con)      /* I - Client connection */
       if (context != GSS_C_NO_CONTEXT)
        gss_delete_sec_context(&minor_status, &context, GSS_C_NO_BUFFER);
 
-      con->no_negotiate = 1;
+      gss_release_cred(&minor_status, &server_creds);
       return;
     }
 
    /*
-    * Get the username associated with the credentials...
+    * Release our credentials...
+    */
+
+    gss_release_cred(&minor_status, &server_creds);
+
+   /*
+    * Get the username associated with the client's credentials...
     */
 
-    if (major_status == GSS_S_COMPLETE)
+    if (!con->gss_delegated_cred)
+      cupsdLogMessage(CUPSD_LOG_DEBUG,
+                      "cupsdAuthorize: No delegated credentials!");
+
+    if (major_status == GSS_S_CONTINUE_NEEDED)
+      cupsdLogGSSMessage(CUPSD_LOG_DEBUG, major_status, minor_status,
+                         "cupsdAuthorize: Credentials not complete");
+    else if (major_status == GSS_S_COMPLETE)
     {
       major_status = gss_display_name(&minor_status, client_name, 
                                      &output_token, NULL);
@@ -995,13 +1040,16 @@ cupsdAuthorize(cupsd_client_t *con)      /* I - Client connection */
                            "cupsdAuthorize: Error getting username");
        gss_release_name(&minor_status, &client_name);
        gss_delete_sec_context(&minor_status, &context, GSS_C_NO_BUFFER);
-       con->no_negotiate = 1;
        return;
       }
 
       gss_release_name(&minor_status, &client_name);
       strlcpy(username, output_token.value, sizeof(username));
 
+      cupsdLogMessage(CUPSD_LOG_DEBUG,
+                     "cupsdAuthorize: Authorized as %s using Negotiate",
+                     username);
+
       gss_release_buffer(&minor_status, &output_token);
       gss_delete_sec_context(&minor_status, &context, GSS_C_NO_BUFFER);
 
@@ -1011,9 +1059,25 @@ cupsdAuthorize(cupsd_client_t *con)      /* I - Client connection */
       gss_release_name(&minor_status, &client_name);
   }
 #endif /* HAVE_GSSAPI */
-  else
+  else if (type != AUTH_NONE)
   {
-    cupsdLogMessage(CUPSD_LOG_ERROR, "Bad authentication data.");
+    char       scheme[256];            /* Auth scheme... */
+    static const char * const types[] =        /* Auth types */
+    {
+      "None",
+      "Basic",
+      "Digest",
+      "BasicDigest",
+      "Negotiate"
+    };
+
+
+    if (sscanf(authorization, "%255s", scheme) != 1)
+      strcpy(scheme, "UNKNOWN");
+
+    cupsdLogMessage(CUPSD_LOG_ERROR,
+                    "Bad authentication data \"%s ...\", expected \"%s ...\"",
+                    scheme, types[type]);
     return;
   }
 
@@ -1025,9 +1089,6 @@ cupsdAuthorize(cupsd_client_t *con)       /* I - Client connection */
 
   strlcpy(con->username, username, sizeof(con->username));
   strlcpy(con->password, password, sizeof(con->password));
-
-  cupsdLogMessage(CUPSD_LOG_DEBUG, "cupsdAuthorize: username=\"%s\"",
-                  con->username);
 }
 
 
@@ -1736,7 +1797,9 @@ cupsdIsAuthorized(cupsd_client_t *con,    /* I - Connection */
   unsigned             address[4];     /* Authorization address */
   cupsd_location_t     *best;          /* Best match for location so far */
   int                  hostlen;        /* Length of hostname */
-  const char           *username;      /* Username to authorize */
+  char                 username[256],  /* Username to authorize */
+                       ownername[256], /* Owner name to authorize */
+                       *ptr;           /* Pointer into username */
   struct passwd                *pw;            /* User password data */
   static const char * const levels[] = /* Auth levels */
                {
@@ -1886,7 +1949,7 @@ cupsdIsAuthorized(cupsd_client_t *con,    /* I - Connection */
       !(best->type == AUTH_NEGOTIATE || 
         (best->type == AUTH_NONE && DefaultAuthType == AUTH_NEGOTIATE)))
   {
-    cupsdLogMessage(CUPSD_LOG_DEBUG2,
+    cupsdLogMessage(CUPSD_LOG_DEBUG,
                     "cupsdIsAuthorized: Need upgrade to TLS...");
     return (HTTP_UPGRADE_REQUIRED);
   }
@@ -1913,10 +1976,10 @@ cupsdIsAuthorized(cupsd_client_t *con,  /* I - Connection */
     attr = ippFindAttribute(con->request, "requesting-user-name", IPP_TAG_NAME);
     if (attr)
     {
-      cupsdLogMessage(CUPSD_LOG_DEBUG2,
+      cupsdLogMessage(CUPSD_LOG_DEBUG,
                       "cupsdIsAuthorized: requesting-user-name=\"%s\"",
                       attr->values[0].string.text);
-      username = attr->values[0].string.text;
+      strlcpy(username, attr->values[0].string.text, sizeof(username));
     }
     else if (best->satisfy == AUTH_SATISFY_ALL || auth == AUTH_DENY)
       return (HTTP_UNAUTHORIZED);      /* Non-anonymous needs user/pass */
@@ -1925,7 +1988,7 @@ cupsdIsAuthorized(cupsd_client_t *con,    /* I - Connection */
   }
   else
   {
-    cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdIsAuthorized: username=\"%s\"",
+    cupsdLogMessage(CUPSD_LOG_DEBUG, "cupsdIsAuthorized: username=\"%s\"",
                    con->username);
 
 #ifdef HAVE_AUTHORIZATION_H
@@ -1940,7 +2003,7 @@ cupsdIsAuthorized(cupsd_client_t *con,    /* I - Connection */
        return (HTTP_OK);               /* unless overridden with Satisfy */
     }
 
-    username = con->username;
+    strlcpy(username, con->username, sizeof(username));
   }
 
  /*
@@ -1951,6 +2014,23 @@ cupsdIsAuthorized(cupsd_client_t *con,   /* I - Connection */
   if (!strcmp(username, "root"))
     return (HTTP_OK);
 
+ /*
+  * Strip any @domain or @KDC from the username and owner...
+  */
+
+  if ((ptr = strchr(username, '@')) != NULL)
+    *ptr = '\0';
+
+  if (owner)
+  {
+    strlcpy(ownername, owner, sizeof(ownername));
+
+    if ((ptr = strchr(ownername, '@')) != NULL)
+      *ptr = '\0';
+  }
+  else
+    ownername[0] = '\0';
+
  /*
   * Get the user info...
   */
@@ -2006,7 +2086,7 @@ cupsdIsAuthorized(cupsd_client_t *con,    /* I - Connection */
     for (i = 0; i < best->num_names; i ++)
     {
       if (!strcasecmp(best->names[i], "@OWNER") && owner &&
-          !strcasecmp(username, owner))
+          !strcasecmp(username, ownername))
        return (HTTP_OK);
       else if (!strcasecmp(best->names[i], "@SYSTEM"))
       {
@@ -2057,7 +2137,7 @@ cupsdIsAuthorized(cupsd_client_t *con,    /* I - Connection */
   * The user isn't part of the specified group, so deny access...
   */
 
-  cupsdLogMessage(CUPSD_LOG_DEBUG2,
+  cupsdLogMessage(CUPSD_LOG_DEBUG,
                   "cupsdIsAuthorized: User not in group(s)!");
 
   return (HTTP_UNAUTHORIZED);
@@ -2382,7 +2462,8 @@ get_gss_creds(const char *service_name)   /* I - Service name */
     return (NULL);
   }
 
-  cupsdLogMessage(CUPSD_LOG_INFO, "Attempting to acquire credentials for %s...", 
+  cupsdLogMessage(CUPSD_LOG_DEBUG,
+                  "get_gss_creds: Attempting to acquire credentials for %s...", 
                   (char *)token.value);
 
   server_creds = GSS_C_NO_CREDENTIAL;
@@ -2398,7 +2479,8 @@ get_gss_creds(const char *service_name)   /* I - Service name */
     return (NULL);
   }
 
-  cupsdLogMessage(CUPSD_LOG_INFO, "Credentials acquired successfully for %s.", 
+  cupsdLogMessage(CUPSD_LOG_DEBUG,
+                  "get_gss_creds: Credentials acquired successfully for %s.", 
                   (char *)token.value);
 
   gss_release_name(&minor_status, &server_name);
@@ -2586,5 +2668,5 @@ to64(char          *s,                    /* O - Output string */
 
 
 /*
- * End of "$Id: auth.c 6649 2007-07-11 21:46:42Z mike $".
+ * End of "$Id: auth.c 6947 2007-09-12 21:09:49Z mike $".
  */