Question

I am using a custom CUPS backend for printing on Mac OS X. The backend works by forwarding the print data to another machine (using ssh) and feeding the data to the printer from there. For this to work, the backend (implemented as a shell script), needs access to an ssh private key. Problem: since I upgraded to Yosemite, the script can no longer access the file containing the key. Instead I see the following error message on the console:

sandboxd: [...] deny file-read-data /

and

/usr/libexec/cups/backend/.mybackend-ssh/id_dsa: Permission denied

in the CUPS error log file.

How can I inject a file into the sandbox used to isolate CUPS backends?

Was it helpful?

Solution 2

After a long debugging session, I have finally solved this problem. In case other people run into the same difficulties, here is what I learned about CUPS backends under Mac OS X Yosemite:

  • Backends are executable files (in my case, a shell script) in the /usr/libexec/cups/backend/ directory. Information about the print job is passed into these programs via command line arguments ($1=job-id, $2=user, $3=title, $4=copies, $5=options, $6=file) and environment variables (e.g. $DEVICE_URI).

  • Backends are executed as user _lp, group _lp, with permissions further restricted by sandboxd. The current directory when the backend is started is the root directory /, but the backend does not have permission to read this directory. Directories which can be read include /usr/libexec/cups/backend/, /etc/ and subdirectories thereof. Only very restricted (or none at all?) access to the home directory of user _lp (in /var/spool/cups) is permitted.

  • My backend requires use of ssh. For this to work, ssh needs to be able to access the private key required to log into the remote server, and a known_hosts file which identifies the remote server. The required key can be placed in /usr/libexec/cups/backend/ or a subdirectory, it must be only readable by the user _lp. It seems that ssh, when started from the CUPS backend, has no permission to access /var/spool/cups/.ssh/, even if this directory exists; thus the known_hosts file must be stored in /etc/, as /etc/ssh_known_hosts. (Note that the ssh manual page incorrectly claims that this should be /etc/ssh/ssh_known_hosts.)

    Edit: On MacOS X 10.11 (El Capitan), ssh now seems to use the documented location /etc/ssh/ssh_known_hosts for the known hosts file. I had to move my file into /etc/ssh/ to make the printer filter work after the OS upgrade.

  • To debug issues like this, using cupsctl --debug-logging is invaluable: After this command is issued, everything written to stderr in the CUPS backend appears in /var/log/cups/error_log. Logging can be switched off again using cupsctl --no-debug-logging. In addition, whenever sandboxd denies an attempted file access, a message like sandboxd[426] ([15998]): sh(15998) deny file-read-data / can be found in /var/log/system.log.

OTHER TIPS

While this doesn't answer the question, I stumbled across this - http://www.papercut.com/kb/Main/MacOS1010YosemiteKnownIssues - when trying to get Tea4CUPS working in OS X 10.10 (I was not able to achieve this):

To get PaperCut working with Mac OS 10.10 in the interim, you’ll need to disable sandboxing. Edit the file /etc/cups/cups-files.conf to include the new line ‘Sandboxing Relaxed’. Then restart CUPS for this to take effect.

sudo sh -c 'echo "Sandboxing Relaxed" >> /etc/cups/cups-files.conf'
sudo launchctl stop org.cups.cupsd
Licensed under: CC-BY-SA with attribution
Not affiliated with apple.stackexchange
scroll top