Zdenek Dohnal e0f466
diff -up cups-2.2.4/scheduler/ipp.c.substitute-bad-attrs cups-2.2.4/scheduler/ipp.c
Zdenek Dohnal e0f466
--- cups-2.2.4/scheduler/ipp.c.substitute-bad-attrs	2018-04-12 08:44:42.202592413 +0200
Zdenek Dohnal e0f466
+++ cups-2.2.4/scheduler/ipp.c	2018-04-12 08:46:21.347689359 +0200
Zdenek Dohnal e0f466
@@ -164,6 +164,7 @@ cupsdProcessIPPRequest(
Zdenek Dohnal e0f466
   ipp_attribute_t	*uri = NULL;	/* Printer or job URI attribute */
Zdenek Dohnal e0f466
   ipp_attribute_t	*username;	/* requesting-user-name attr */
Zdenek Dohnal e0f466
   int			sub_id;		/* Subscription ID */
Zdenek Dohnal e0f466
+  int			valid = 1;	/* Valid request? */
Zdenek Dohnal e0f466
 
Zdenek Dohnal e0f466
 
Zdenek Dohnal e0f466
   cupsdLogMessage(CUPSD_LOG_DEBUG2,
Zdenek Dohnal e0f466
@@ -402,20 +403,55 @@ cupsdProcessIPPRequest(
Zdenek Dohnal e0f466
       else
Zdenek Dohnal e0f466
       {
Zdenek Dohnal e0f466
        /*
Zdenek Dohnal e0f466
-	* OK, all the checks pass so far; make sure requesting-user-name is
Zdenek Dohnal e0f466
-	* not "root" from a remote host...
Zdenek Dohnal e0f466
+	* OK, all the checks pass so far; validate "requesting-user-name"
Zdenek Dohnal e0f466
+	* attribute value...
Zdenek Dohnal e0f466
 	*/
Zdenek Dohnal e0f466
 
Zdenek Dohnal e0f466
-        if ((username = ippFindAttribute(con->request, "requesting-user-name",
Zdenek Dohnal e0f466
-	                                 IPP_TAG_NAME)) != NULL)
Zdenek Dohnal e0f466
-	{
Zdenek Dohnal e0f466
-	 /*
Zdenek Dohnal e0f466
-	  * Check for root user...
Zdenek Dohnal e0f466
-	  */
Zdenek Dohnal e0f466
-
Zdenek Dohnal e0f466
-	  if (!strcmp(username->values[0].string.text, "root") &&
Zdenek Dohnal e0f466
-	      _cups_strcasecmp(con->http->hostname, "localhost") &&
Zdenek Dohnal e0f466
-	      strcmp(con->username, "root"))
Zdenek Dohnal e0f466
+        if ((username = ippFindAttribute(con->request, "requesting-user-name", IPP_TAG_ZERO)) != NULL)
Zdenek Dohnal e0f466
+        {
Zdenek Dohnal e0f466
+         /*
Zdenek Dohnal e0f466
+          * Validate "requesting-user-name"...
Zdenek Dohnal e0f466
+          */
Zdenek Dohnal e0f466
+
Zdenek Dohnal e0f466
+          if (username->group_tag != IPP_TAG_OPERATION && StrictConformance)
Zdenek Dohnal e0f466
+          {
Zdenek Dohnal e0f466
+	    cupsdAddEvent(CUPSD_EVENT_SERVER_AUDIT, NULL, NULL, "%04X %s \"requesting-user-name\" attribute in wrong group.", IPP_STATUS_ERROR_BAD_REQUEST, con->http->hostname);
Zdenek Dohnal e0f466
+	    send_ipp_status(con, IPP_STATUS_ERROR_BAD_REQUEST, _("\"requesting-user-name\" attribute in wrong group."));
Zdenek Dohnal e0f466
+	    valid = 0;
Zdenek Dohnal e0f466
+          }
Zdenek Dohnal e0f466
+          else if (username->value_tag != IPP_TAG_NAME && username->value_tag != IPP_TAG_NAMELANG)
Zdenek Dohnal e0f466
+          {
Zdenek Dohnal e0f466
+	    cupsdAddEvent(CUPSD_EVENT_SERVER_AUDIT, NULL, NULL, "%04X %s \"requesting-user-name\" attribute with wrong syntax.", IPP_STATUS_ERROR_ATTRIBUTES_OR_VALUES, con->http->hostname);
Zdenek Dohnal e0f466
+	    send_ipp_status(con, IPP_STATUS_ERROR_ATTRIBUTES_OR_VALUES, _("\"requesting-user-name\" attribute with wrong syntax."));
Zdenek Dohnal e0f466
+	    if ((attr = ippCopyAttribute(con->response, username, 0)) != NULL)
Zdenek Dohnal e0f466
+	      attr->group_tag = IPP_TAG_UNSUPPORTED_GROUP;
Zdenek Dohnal e0f466
+	    valid = 0;
Zdenek Dohnal e0f466
+          }
Zdenek Dohnal e0f466
+          else if (!ippValidateAttribute(username))
Zdenek Dohnal e0f466
+          {
Zdenek Dohnal e0f466
+	    cupsdAddEvent(CUPSD_EVENT_SERVER_AUDIT, NULL, NULL, "%04X %s \"requesting-user-name\" attribute with bad value.", IPP_STATUS_ERROR_ATTRIBUTES_OR_VALUES, con->http->hostname);
Zdenek Dohnal e0f466
+
Zdenek Dohnal e0f466
+            if (StrictConformance)
Zdenek Dohnal e0f466
+            {
Zdenek Dohnal e0f466
+             /*
Zdenek Dohnal e0f466
+              * Throw an error...
Zdenek Dohnal e0f466
+              */
Zdenek Dohnal e0f466
+
Zdenek Dohnal e0f466
+	      send_ipp_status(con, IPP_STATUS_ERROR_ATTRIBUTES_OR_VALUES, _("\"requesting-user-name\" attribute with wrong syntax."));
Zdenek Dohnal e0f466
+              if ((attr = ippCopyAttribute(con->response, username, 0)) != NULL)
Zdenek Dohnal e0f466
+                attr->group_tag = IPP_TAG_UNSUPPORTED_GROUP;
Zdenek Dohnal e0f466
+	      valid = 0;
Zdenek Dohnal e0f466
+	    }
Zdenek Dohnal e0f466
+	    else
Zdenek Dohnal e0f466
+	    {
Zdenek Dohnal e0f466
+	     /*
Zdenek Dohnal e0f466
+	      * Map bad "requesting-user-name" to 'anonymous'...
Zdenek Dohnal e0f466
+	      */
Zdenek Dohnal e0f466
+
Zdenek Dohnal e0f466
+              ippSetString(con->request, &username, 0, "anonymous");
Zdenek Dohnal e0f466
+	    }
Zdenek Dohnal e0f466
+          }
Zdenek Dohnal e0f466
+          else if (!strcmp(username->values[0].string.text, "root") && _cups_strcasecmp(con->http->hostname, "localhost") && strcmp(con->username, "root"))
Zdenek Dohnal e0f466
 	  {
Zdenek Dohnal e0f466
 	   /*
Zdenek Dohnal e0f466
 	    * Remote unauthenticated user masquerading as local root...
Zdenek Dohnal e0f466
@@ -431,6 +467,8 @@ cupsdProcessIPPRequest(
Zdenek Dohnal e0f466
 	else
Zdenek Dohnal e0f466
 	  sub_id = 0;
Zdenek Dohnal e0f466
 
Zdenek Dohnal e0f466
+        if (valid)
Zdenek Dohnal e0f466
+        {
Zdenek Dohnal e0f466
        /*
Zdenek Dohnal e0f466
         * Then try processing the operation...
Zdenek Dohnal e0f466
 	*/
Zdenek Dohnal e0f466
@@ -634,6 +672,7 @@ cupsdProcessIPPRequest(
Zdenek Dohnal e0f466
 			      ippOpString(
Zdenek Dohnal e0f466
 			          con->request->request.op.operation_id));
Zdenek Dohnal e0f466
 	      break;
Zdenek Dohnal e0f466
+        }
Zdenek Dohnal e0f466
 	}
Zdenek Dohnal e0f466
       }
Zdenek Dohnal e0f466
     }
Zdenek Dohnal e0f466
@@ -1594,27 +1633,34 @@ add_job(cupsd_client_t  *con,		/* I - Cl
Zdenek Dohnal e0f466
                     _("Bad job-name value: Wrong type or count."));
Zdenek Dohnal e0f466
     if ((attr = ippCopyAttribute(con->response, attr, 0)) != NULL)
Zdenek Dohnal e0f466
       attr->group_tag = IPP_TAG_UNSUPPORTED_GROUP;
Zdenek Dohnal e0f466
-    return (NULL);
Zdenek Dohnal e0f466
+
Zdenek Dohnal e0f466
+    if (StrictConformance)
Zdenek Dohnal e0f466
+      return (NULL);
Zdenek Dohnal e0f466
+
Zdenek Dohnal e0f466
+    /* Don't use invalid attribute */
Zdenek Dohnal e0f466
+    ippDeleteAttribute(con->request, attr);
Zdenek Dohnal e0f466
+
Zdenek Dohnal e0f466
+    ippAddString(con->request, IPP_TAG_JOB, IPP_TAG_NAME, "job-name", NULL, "Untitled");
Zdenek Dohnal e0f466
   }
Zdenek Dohnal e0f466
   else if (!ippValidateAttribute(attr))
Zdenek Dohnal e0f466
   {
Zdenek Dohnal e0f466
     send_ipp_status(con, IPP_ATTRIBUTES, _("Bad job-name value: %s"),
Zdenek Dohnal e0f466
                     cupsLastErrorString());
Zdenek Dohnal e0f466
+
Zdenek Dohnal e0f466
     if ((attr = ippCopyAttribute(con->response, attr, 0)) != NULL)
Zdenek Dohnal e0f466
       attr->group_tag = IPP_TAG_UNSUPPORTED_GROUP;
Zdenek Dohnal e0f466
-    return (NULL);
Zdenek Dohnal e0f466
-  }
Zdenek Dohnal e0f466
 
Zdenek Dohnal e0f466
-  attr = ippFindAttribute(con->request, "requesting-user-name", IPP_TAG_NAME);
Zdenek Dohnal e0f466
+    if (StrictConformance)
Zdenek Dohnal e0f466
+      return (NULL);
Zdenek Dohnal e0f466
 
Zdenek Dohnal e0f466
-  if (attr && !ippValidateAttribute(attr))
Zdenek Dohnal e0f466
-  {
Zdenek Dohnal e0f466
-    send_ipp_status(con, IPP_ATTRIBUTES, _("Bad requesting-user-name value: %s"), cupsLastErrorString());
Zdenek Dohnal e0f466
-    if ((attr = ippCopyAttribute(con->response, attr, 0)) != NULL)
Zdenek Dohnal e0f466
-      attr->group_tag = IPP_TAG_UNSUPPORTED_GROUP;
Zdenek Dohnal e0f466
-    return (NULL);
Zdenek Dohnal e0f466
+    /* Don't use invalid attribute */
Zdenek Dohnal e0f466
+    ippDeleteAttribute(con->request, attr);
Zdenek Dohnal e0f466
+
Zdenek Dohnal e0f466
+    ippAddString(con->request, IPP_TAG_JOB, IPP_TAG_NAME, "job-name", NULL, "Untitled");
Zdenek Dohnal e0f466
   }
Zdenek Dohnal e0f466
 
Zdenek Dohnal e0f466
+  attr = ippFindAttribute(con->request, "requesting-user-name", IPP_TAG_NAME);
Zdenek Dohnal e0f466
+
Zdenek Dohnal e0f466
 #ifdef WITH_LSPP
Zdenek Dohnal e0f466
   if (is_lspp_config())
Zdenek Dohnal e0f466
   {