Snapping CPDB CUPS backend, a user daemon using D-Bus

In private chat with @zyga @zyga-snapd I said:

The print dialog is more complex: A CPDB-supporting print dialog (CPDB frontend) can support any number of CPDB backends (for CUPS, for printing to file, for cloud printing services, …) especially also more than one at a time, so that your dialog for example shows all locally available CUPS printers but also the printers of a cloud printing service you are using. Then there is the CUPS backend and another backend provided by the cloud printing service.

To be able to connect to several D-Bus services (CPDB backends) the frontend calls a D-Bus library function to list all services available on the session D-Bus and then finds all CPDB backends by their service name and connects to all of them.

This perhaps needs a new Snap interface. This needs to get checked

What is exactly happening is the following:

When the print dialog (frontend) is opened we list all available printers. For that we have to find all available backends, independent whether the backend executable is already running or not (and then gets started by D-Bus activation). For that, the appropriate frontend library function connects to the session D-Bus and on the D-Bus proxy it calls the methods ListNames and ListActivatableNames to get a list of all running D-Bus services and of all D-Bus-activatable D-Bus services, resp. In this list it filters the service names, only considering services whose name starts with org.openprinting.Backend.. By this a list of available backends is created. The function in the source code is cpdbActivateBackends() in the file cpdb/cpdb-frontend.c.

After that, the frontend talks to each backend in the list individually to list their printers, and also to list options for a given printer and to print jobs.

This means, that the frontend needs permissions to

  • access the session D-Bus proxy and execute methods on it.
  • Talk with session D-Bus services whose names are only determined during run-time of the program (so the names cannot get hardcoded into Snap packaging of the frontends.

Each application’s print dialog is a CPDB frontend, so a backend providing a session D-Bus service (D-Bus activatable user daemon) needs permission to talk with several clients with names only getting known at run time. Therefore cleint names cannot get hardcoded into the Snap packaging of the backends).

To print a job, the frontend calls a D-Bus method on the backend, which starts the job (set the user-selected options) and then returns a domain socket path to the frontend. Then the frontend has to send the job data (the data which gets printed) into this socket. The domain socket is one per job, so that jobs can be processed in parallel.

For Snap this means that each backend needs to provide a directory which the frontend mounts and into which the domain sockets for the jobs get created. This is a similar situation with the “cups” interface in the CUPS Snap, where the CUPS Snap provides a socket and the Snaps which plug “cups” access this socket to be able to print via the CUPS Snap’s cupsd.

@zyga @zyga-snapd @jamesh I hope this clarifies which kind of permissions the new interface needs to grant.

And sorry, yesterday I just dropped the info here that the changes on the upstream code were done.

1 Like