diff --git a/patches/cupsd-fix-load-cupsd.conf.patch b/patches/cupsd-fix-load-cupsd.conf.patch new file mode 100644 index 0000000..d436010 --- /dev/null +++ b/patches/cupsd-fix-load-cupsd.conf.patch @@ -0,0 +1,86 @@ +From: Till Kamppeter +Date: Sat, 22 Feb 2020 14:28:58 +0100 +Subject: Fix scheduler cupsd.conf load + +When running it without arguments it is supposed to read the local CUPS's +cupsd.conf and show a summary of the setting. in CUPS 2.3.1 it shows a mess +with a lot of HTML inside and this is due to the fact that when loading the +file via HTTP using the /admin/cups/cupsd.conf path the scheduler calls the +admin.cgi program which returns the admin front page of the web admin +interface. cupsctl then tries to interpret that as the config file and displays +garbage. Even worse is if you run cupsctl with command line argument (one of +the five switches or a key=value pair) to change a setting. It seems to load +cupsd.conf again and gets again the HTML code of the web interface page. +cupsctl tries to interpret this again, producing garbage, adds the +user-supplied setting and writes all this back into cupsd.conf. Then it tries +to restart the scheduler which fails due to the broken config file. +The problem is that in the file scheduler/client.conf, in the function +get_file() the URI from the client is at first checked whether it begins with +"/admin/" and in this case the CGI program admin.cgi is responsible. Only after +that the check for "/admin/conf/cupsd.conf" comes and is never reached. +I have changed the order now appropriately and this way cupsctl works again. +Note that the problem only occurs if the web interface is active and the +cupsctl command is issued by a non-root user. +This is a regression caused by issue #5652. + +Bug: https://github.com/apple/cups/issues/5744 +--- + scheduler/client.c | 38 +++++++++++++++++++------------------- + 1 file changed, 19 insertions(+), 19 deletions(-) + +diff --git a/scheduler/client.c b/scheduler/client.c +index c2ee8f1..54b841b 100644 +--- a/scheduler/client.c ++++ b/scheduler/client.c +@@ -2789,6 +2789,25 @@ get_file(cupsd_client_t *con, /* I - Client connection */ + + perm_check = 0; + } ++ else if (!strcmp(con->uri, "/admin/conf/cupsd.conf")) ++ { ++ strlcpy(filename, ConfigurationFile, len); ++ ++ perm_check = 0; ++ } ++ else if (!strncmp(con->uri, "/admin/log/", 11)) ++ { ++ if (!strncmp(con->uri + 11, "access_log", 10) && AccessLog[0] == '/') ++ strlcpy(filename, AccessLog, len); ++ else if (!strncmp(con->uri + 11, "error_log", 9) && ErrorLog[0] == '/') ++ strlcpy(filename, ErrorLog, len); ++ else if (!strncmp(con->uri + 11, "page_log", 8) && PageLog[0] == '/') ++ strlcpy(filename, PageLog, len); ++ else ++ return (NULL); ++ ++ perm_check = 0; ++ } + else if (!strncmp(con->uri, "/admin", 6) || !strncmp(con->uri, "/classes", 8) || !strncmp(con->uri, "/jobs", 5) || !strncmp(con->uri, "/printers", 9)) + { + /* +@@ -2822,25 +2841,6 @@ get_file(cupsd_client_t *con, /* I - Client connection */ + + perm_check = 0; + } +- else if (!strcmp(con->uri, "/admin/conf/cupsd.conf")) +- { +- strlcpy(filename, ConfigurationFile, len); +- +- perm_check = 0; +- } +- else if (!strncmp(con->uri, "/admin/log/", 11)) +- { +- if (!strncmp(con->uri + 11, "access_log", 10) && AccessLog[0] == '/') +- strlcpy(filename, AccessLog, len); +- else if (!strncmp(con->uri + 11, "error_log", 9) && ErrorLog[0] == '/') +- strlcpy(filename, ErrorLog, len); +- else if (!strncmp(con->uri + 11, "page_log", 8) && PageLog[0] == '/') +- strlcpy(filename, PageLog, len); +- else +- return (NULL); +- +- perm_check = 0; +- } + else if (con->language) + { + snprintf(language, sizeof(language), "/%s", con->language->language); diff --git a/patches/libcups-fix-convert-option-choice-names-in-ppd.patch b/patches/libcups-fix-convert-option-choice-names-in-ppd.patch new file mode 100644 index 0000000..bc4db9f --- /dev/null +++ b/patches/libcups-fix-convert-option-choice-names-in-ppd.patch @@ -0,0 +1,99 @@ +From: Till Kamppeter +Date: Mon, 17 Feb 2020 09:05:58 +0100 +Subject: Fix conversion of PPD InputSlot choice names + +When I create a CUPS queue with a PPD file with choice names "Tray-1", "Tray-2", +... in the InputSlot option CUPS translates these names to double-dashed IPP +attribute names: "tray--1", "tray--2", ... in the "media-source" attribute, both +when passing a job to the printer with the IPP backend, making the printer +ignore the tray choice, and also when answering a get-printer-attributes IPP +request from a client. This happens when in the PPD a dash is followed by a +digit, as the pwg_unppdize_name() function in cups/ppd-cache.c inserts a dash +whenever a non-digit is followed by a digit in the PPD name. As IPP attribute +names generally never have double-dashes and also no dashes in the beginning or +the end of the name, I have modified the pwg_unppdize_name() function +appropriately. + +Bug: https://github.com/apple/cups/issues/5740 +Bug-Debian: https://bugs.debian.org/949315 +--- + cups/ppd-cache.c | 47 ++++++++++++++++++++++++++++++++++++++--------- + 1 file changed, 38 insertions(+), 9 deletions(-) + +diff --git a/cups/ppd-cache.c b/cups/ppd-cache.c +index 5965e38..6609f53 100644 +--- a/cups/ppd-cache.c ++++ b/cups/ppd-cache.c +@@ -5140,6 +5140,8 @@ pwg_unppdize_name(const char *ppd, /* I - PPD keyword */ + { + char *ptr, /* Pointer into name buffer */ + *end; /* End of name buffer */ ++ int nodash = 1; /* Next char in IPP name cannot be a ++ dash (first char or after a dash) */ + + + if (_cups_islower(*ppd)) +@@ -5151,7 +5153,9 @@ pwg_unppdize_name(const char *ppd, /* I - PPD keyword */ + const char *ppdptr; /* Pointer into PPD keyword */ + + for (ppdptr = ppd + 1; *ppdptr; ppdptr ++) +- if (_cups_isupper(*ppdptr) || strchr(dashchars, *ppdptr)) ++ if (_cups_isupper(*ppdptr) || strchr(dashchars, *ppdptr) || ++ (*ppdptr == '-' && *(ppdptr - 1) == '-') || ++ (*ppdptr == '-' && *(ppdptr + 1) == '\0')) + break; + + if (!*ppdptr) +@@ -5163,19 +5167,44 @@ pwg_unppdize_name(const char *ppd, /* I - PPD keyword */ + + for (ptr = name, end = name + namesize - 1; *ppd && ptr < end; ppd ++) + { +- if (_cups_isalnum(*ppd) || *ppd == '-') ++ if (_cups_isalnum(*ppd)) ++ { + *ptr++ = (char)tolower(*ppd & 255); +- else if (strchr(dashchars, *ppd)) +- *ptr++ = '-'; ++ nodash = 0; ++ } ++ else if (*ppd == '-' || strchr(dashchars, *ppd)) ++ { ++ if (nodash == 0) ++ { ++ *ptr++ = '-'; ++ nodash = 1; ++ } ++ } + else ++ { + *ptr++ = *ppd; ++ nodash = 0; ++ } + +- if (!_cups_isupper(*ppd) && _cups_isalnum(*ppd) && +- _cups_isupper(ppd[1]) && ptr < end) +- *ptr++ = '-'; +- else if (!isdigit(*ppd & 255) && isdigit(ppd[1] & 255)) +- *ptr++ = '-'; ++ if (nodash == 0) ++ { ++ if (!_cups_isupper(*ppd) && _cups_isalnum(*ppd) && ++ _cups_isupper(ppd[1]) && ptr < end) ++ { ++ *ptr++ = '-'; ++ nodash = 1; ++ } ++ else if (!isdigit(*ppd & 255) && isdigit(ppd[1] & 255)) ++ { ++ *ptr++ = '-'; ++ nodash = 1; ++ } ++ } + } + ++ /* Remove trailing dashes */ ++ while (ptr > name && *(ptr - 1) == '-') ++ ptr --; ++ + *ptr = '\0'; + } diff --git a/snapcraft.yaml b/snapcraft.yaml index 81f57a9..904e60f 100644 --- a/snapcraft.yaml +++ b/snapcraft.yaml @@ -116,6 +116,8 @@ parts: patch -p0 < $SNAPCRAFT_STAGE/patches/cups-deviced-allow-run-by-root.patch patch -p1 < $SNAPCRAFT_STAGE/patches/cups-airprint-support.patch patch -p1 < $SNAPCRAFT_STAGE/patches/cupsd-extra-check-for-admin-tasks-snap-cups-control.patch + patch -p1 < $SNAPCRAFT_STAGE/patches/libcups-fix-convert-option-choice-names-in-ppd.patch + patch -p1 < $SNAPCRAFT_STAGE/patches/cupsd-fix-load-cupsd.conf.patch sed -i 's|fchown(cupsFileNumber(fp), getuid(), Group)|0|g' scheduler/file.c sed -i 's|(fchmod(cupsFileNumber(fp), mode))|(0)|g' scheduler/file.c sed -i 's|chown(filename, user, group)|0|g' scheduler/conf.c