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