Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cupsGetPPD3() function of CUPS library tries to load PPD from IPP printer and not from the CUPS queue #4725

Closed
michaelrsweet opened this issue Oct 3, 2015 · 7 comments

Comments

@michaelrsweet
Copy link
Collaborator

Version: 2.1.0
CUPS.org User: till.kamppeter

Since CUPS 2.1.0 the PPD files of the local print queues in /etc/cups/ppd/ are not world-readable any more as CUPS' default permissions for config files get correctly applied.

This makes desktop applications run by a normal user and calling the cupsGetPPD3() function of CUPS library (or any cupsGetPPD*() function as they all call cupsGetPPD3()) not being able to directly load the PPD file from /etc/cups/ppd/ and so we get a fallback to load the PPD through cupsd by loading the URL

http://localhost:631/printers/.ppd

This works correctly as long as the device URI of the printer is not an ipp://... one (IPP network printer or IPP-over-USB printer with ippusbxd). In case of an ipp://... URI the function seems to try to download the PPD from the printer and not from the CUPS server on which the print queue resides. This looks like that the function here uses the device URI of the printer and not the printer URI of the CUPS queue.

I found out this by trying to open the printer properties dialog in system-config-printer (right-click on printer icon then choose "Properties" in menu). For printers with usb://... or hp://... (HPLIP) URIs this works, but for my printers with ipp://... URIs it takes some time (printer-internal timeout) and then I got an error message telling that the printer properties could not be loaded:

Unable to get queue details. Treating queue as raw.

The printer was an IPP-over-USB printer using ippusbxd with the URI

ipp://localhost:60000/ipp/print?isippoverusb=true&serial=BR54BFB02C05XK&vid=03f0&pid=c211&procid=1184

and running ippusbxd in debug mode I could see that cupsGetPPD3() was trying to load the following URI:

http://localhost:60000/ipp/print?isippoverusb=true&serial=BR54BFB02C05XK&vid=03f0&pid=c211&procid=1184.ppd

which naturally did not lead to the PPD file of the CUPS queue to be loaded.

If you have a native IPP printer you could observer the network communication with appropriate software (Wireshark?).

Another consequence is that the print dialog of the Chromium browser does not show PPD options for print queues with ipp://... URIs.

I did not test ipps://... print queues.

@michaelrsweet
Copy link
Collaborator Author

CUPS.org User: till.kamppeter

I have found out what the problem here is and I have a (simple) fix for it (patch attached).

The problem was that cupsGetPPD3() uses cups_get_printer_uri() (also in cups/util.c) to determine the printer URI but cups_get_printer_uri() has a bug that it considers all ipp://... and ipps://... queues as pointing to a remote CUPS queue and therefore returns the device URI for the PPD being loaded from the remote CUPS server. If the ipp(s)://... printer is a native IPP printer (or IPP-over-USB) this naturally not works.

The patch corrects the determination whether a queue is a remote CUPS queue. With the patch applied the problem goes away. system-config-printer opens the properties dialogs for all types of queues immediately with all PPD options and the print dialog of Chromium Browser also opens immediately and shows the PPD options of all queues.

@michaelrsweet
Copy link
Collaborator Author

CUPS.org User: till.kamppeter

By the way, this bug was discovered after the fix of STR #4703, due to which the PPDs are not world-readable any more.

@michaelrsweet
Copy link
Collaborator Author

CUPS.org User: mike

Fixed in Subversion repository.

@michaelrsweet
Copy link
Collaborator Author

CUPS.org User: mike

Till, the attached patch is different from yours, mainly because your patch incorrectly assumes that the local and remote queue names are the same (and that strlen(device_uri) > strlen(name)); I just look for /printers/ and /classes/ (which are mostly unique to CUPS).

Let me know if you still have problems...

@michaelrsweet
Copy link
Collaborator Author

CUPS.org User: till.kamppeter

Can you actually attach your patch? Thanks.

@michaelrsweet
Copy link
Collaborator Author

"fix-ppd-file-load-for-ipp-printers.patch":

--- a/cups/util.c
+++ b/cups/util.c
@@ -1528,8 +1528,10 @@
}

 if (device_uri &&
  •    (!strncmp(device_uri, "ipp://", 6) ||
    
  •     !strncmp(device_uri, "ipps://", 7) ||
    
  •    (((!strncmp(device_uri, "ipp://", 6) ||
    
  •  !strncmp(device_uri, "ipps://", 7)) &&
    
  • !strcmp(device_uri + strlen(device_uri) - strlen(resource),
    
  •     resource)) ||
      ((strstr(device_uri, "._ipp.") != NULL ||
        strstr(device_uri, "._ipps.") != NULL) &&
       !strcmp(device_uri + strlen(device_uri) - 5, "/cups"))))
    

@michaelrsweet
Copy link
Collaborator Author

"str4725.patch":

Index: cups/util.c

--- cups/util.c (revision 12882)
+++ cups/util.c (working copy)
@@ -1528,10 +1528,9 @@
}

 if (device_uri &&
  •    (!strncmp(device_uri, "ipp://", 6) ||
    
  •     !strncmp(device_uri, "ipps://", 7) ||
    
  •     ((strstr(device_uri, "._ipp.") != NULL ||
    
  •       strstr(device_uri, "._ipps.") != NULL) &&
    
  •    (((!strncmp(device_uri, "ipp://", 6) || !strncmp(device_uri, "ipps://", 7)) &&
    
  • (strstr(device_uri, "/printers/") != NULL || strstr(device_uri, "/classes/") != NULL)) ||
    
  •     ((strstr(device_uri, "._ipp.") != NULL || strstr(device_uri, "._ipps.") != NULL) &&
       !strcmp(device_uri + strlen(device_uri) - 5, "/cups"))))
    
    {
    /*

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant