Request: CUPS Snap (“cups”) auto connection to of cups:cups-control to cups:admin and also of the network-manager-observe interface

  1. Yes, I can do that. I simply did not know that it is possible and the default. If I do so, do we need to re-vote or is it simply understood?
  2. OK, as the permissions of a plug a given by-Snap and not by-app (one app plugs cups-control so all the other apps plugging only cups are also allowed to admin) I can let them all plug cups-control and so the CUPS Snap does not plug cups any more.
  3. This is a good idea. Please implement it. But as it takes time for you to implement and for the mainyainers to approve the @reviewers should for now apply the auto connections as they are and I modify the CUPS Snap as soon as this new exit code is available.

@reviewers, is it OK if I rename the slots of the CUPS Snap to standard?

From

slots:
  # Provide the cups-control and cups slots for other snaps to connect to
  admin:
    interface: cups-control
  printing:
    interface: cups

to

slots:
  # Provide the cups-control and cups slots for other snaps to connect to
  cups-control:
    interface: cups-control
  cups:
    interface: cups

so that we now need the following auto-connections:

sudo snap connect cups:cups-control cups:cups-control
sudo snap connect cups:cups cups:cups
sudo snap connect cups:network-manager-observe

Does it work this way? Does it need a new voting? Or can I simply do this change right now and you apply the auto-connects this way in the Snap Store?

Could you apply the auto-connects this way then, set slots-per-plug: * for connecting and auto-connecting both cups and cups-control for user applications uploaded into the Snap Store, and let the Snap Store allow auto-connection of cups for uploaded user applications without explicit approval?

@jamesh, If I do the renaming of the slots (printing -> cups, admin -> cups-control) as described in my previous post and build the Snap I get the following error:

Snapping |                                                           
Failed to create snap, snap command failed:
stdout:

stderr:
error: cannot pack "/root/prime": cannot validate snap "cups": cannot have plug and slot with the same name: "cups-control"

We would appreciate it if you anonymously reported this issue.
No other data than the traceback and the version of snapcraft in use will be sent.

How do I do this correctly?

Plugs and slots share the same namespace, as that error message indicates. I was suggesting that you rename the plugs (which are only of interest to the cups snap) to something else, so the slots could use the default names.

So you mean the plug(s) for the command line tools which come with the Snap? So for example I use only one universal plug for the command line tools, like cups-internal and let this get auto-connected to the slot cups:cups-control via auto-connect? User applications then plug their cups to cups:cups and their cups-control to cups:cups-control?

This would mean that I also have to modify CUPS so that it accepts admin requests also on cups:cups-internal? Or can I modify CUPS to accept admin requests simply if the SNAP NAME (not the interface plugged) is “cups” and then the tools do not need to plug anything at all?

And if I have to use cups-internal for the CUPS tools does this not need to extend the design of snapd to support this plug?

@jamesh, @reviewers:

I got it working now:

First I re-defined plugs and slots in snapcraft.yaml:

plugs:
  cups-internal:
    interface: cups-control

slots:
  # Provide the cups-control and cups slots for other snaps to connect to
  cups-control:
    interface: cups-control
  cups:
    interface: cups

I set the slots of cupsd as follows:

apps:
  cupsd:
    [...]
    slots: [cups-control, cups]

On all other apps I replaced the plugs cups and cups-control by cups-internal:

  cups-browsed:
    [...]
    plugs: [network, network-bind, network-manager-observe, avahi-control, cups-internal]
  lpinfo:
    command: sbin/lpinfo
    plugs: [network, cups-internal]
  lpadmin:
    command: sbin/lpadmin
    plugs: [network, avahi-control, home, cups-internal]
  lpstat:
    command: bin/lpstat
    plugs: [network, avahi-control, cups-internal]
  [...]

I build CUPS with a configure option to call the cupsctl API call with cups-control as slot name:

parts:
  [...]
  cups:
    [...]
    configflags:
      [...]
      - --with-cups-control-slot=cups-control
      [...]

Now I change the connection I requested in this thread to

sudo snap connect cups:cups-internal cups:cups-control
sudo snap connect cups:network-manager-observe

and for external utilities (example) I do the following connections:

sudo snap connect cups-admin-test:cups-control cups:cups-control
sudo snap connect cups-user-app-test:cups cups:cups

Now it all works as expected.

@reviewers:

This means:

This request should be now considered as that following auto-connections are requested:

sudo snap connect cups:cups-internal cups:cups-control
sudo snap connect cups:network-manager-observe

The auto-connections are internally doing the same as the original ones, the interfaces are only renamed.

It must be assured that a Snap of a user application which prints and is put into the Snap Store should auto-connect its cups plug to BOTH :cups AND cups:cups on installation. slots-per-plug: * should be used at the right place for that.

Same for Snaps of printer managers using cups-control with the difference that here explicit permission should be needed for auto-connection. Also here slots-per-plug: * at the right place should be used.

@reviewers: I will commit my above-mentioned changes now, could you apply the changes as I described here? Thanks in advance.

@reviewers, @jamesh, Changes for new slot names cups:cups and cups:cups-control are committed to the CUPS Snap now. The Snap Store is rebuilding it currently.

Here is a PR adding the extra snapctl is-connected exit code:

And here’s one that adds an implicit system:cups slot:

@jamesh, thank you very much for your pull requests.

@jamesh, one question, can the client-is-from-the-same-Snap case not be checked much more easily? Keeping in mind that the Snap Store can only hold one Snap named “cups” and on a system there also can be only one Snap called “cups” be installed, CUPS could identify inquiries from the same snap by the AppArmor context? For CUPS it starts always with snap.cups. and for other Snaps it never starts with snap.cups..

Yes, you could interpret the snap name in the AppArmor label yourself as a temporary measure. If that lets you get rid of the cups-control plug on the snap, I’d do that: if you can get by without the self connections, it should make your snap a bit more robust.

@reviewers, as it will take time until @jamesh’s pull requests will get implemented in snapd and the CUPS Snap is working as it is now, I ask you to apply the auto-connections of interfaces and the slots-per-plug: * as I described in post #31 to make the CUPS Snap working in a user-friendly way right now. Thanks in advance.

@jamesh, with the check of the AppArmor label I can free myself from the requirement that the Snap Store team has to approve the self connection as auto connection. Independent of this, the utilities have to plug one of cups or cups-control as otherwise AppArmor blocks their access to the CUPS Socket, even if the utilities belong to the same Snap, and I get a lpstat: Bad file descriptor. I have quickly tested it right now, simply removing the cups-internal plug from lpstat and lpinfo in snapcraft.yaml.

So the only way to get access to the socket at all for the utilities is to create the cups-internal alias to the cups-control plug as I am using right now (see my longer post above). This is independent of the method how to allow administrative inquiries, checking the AppArmor label (or adding another exit code to snapctl) only reduces the number of auto-connections to be approved by the Snap Store team.

@jamesh, in the second pull request, in interfaces/builtin/cups.go you have deny-auto-connection: true. Should that not be false as for simple printing (no admin) we want to auto-connect by default. Am I right?

Re. the “bad file descriptor” error, Try removing the “slots:” stanza from the cupsd app definition in your snapcraft.yaml. This will cause those slots to be associated with every app of the snap, which should give the utilities access to the slot.

Re. auto-connection of the cups interface, this matches the current policy of cups-control. It seemed easier to propose just one change at a time.

@jamesh, because of the auto-connection of the cups interface, we have inrtroduced it to have separate cups and cups-comtrol so that cups auto-connects and cups-control not. So therefore we should let cups do auto-connect right from the beginning.

Sorry to be a pain, this thread seems to have at least two parts - ongoing troubleshooting/development of cups capabilities and the actual auto-connect request.

To make it simple and clean to follow (including anyone outside the development group above), can we finalize the set of auto-connections, the reasoning for each one (why it’s needed), and a separate thread for the different backend implementations?

1 Like

@jamesh, I tested now the following:

I removed

plugs:
  [...]
  cups-internal:
    interface: cups-control

and

apps:
  cupsd:
    [...]
    slots: [cups-control, cups]

and I also removed the cups-internal plug from all the utilities, making the utilities plugging nothing CUPS-related ( like cups, cups-control).

This works perfectly for me now, without any cups:cups-internal -> cups:cups-control connection and without modifying CUPS to pass same-Snap inquiries without calling snapctl.

Strange is the following:
If I run cups.lpinfo -v, the CUPS daemon of the Snap grants access because it connects via cups-control, but neither the lpinfo apps entry nor the whole CUPS Snaps plugs cups-control. why does this work?
Then I stopped the snapped daemons via sudo snap stop cups and started an unsnapped CUPS daemon from the source directory of CUPS, current GIT state with all Snap support, built for running unsnapped but supporting admin check of snapped clients (./configure --enable-snapped-clients). This CUPS also permitted access, also telling that the client is the CUPS Snap’s lpinfo plugging cups-control. Why is this working? Why does snapctl tell that the client is connecting cups-control but my current CUPS Snap has no cups-control plug at all?

@igor, sorry, I started the thread for asking for interface auto-connections and my requested auto-connections got voted on and approved, but ptobably not applied, as the third and last voter, @popey, did not tell that he has applied the changes, perhaps he has only voting but not admin rights. Then @diddledani came up with a question, me and @jamesh answered and then @jamesh gave me some hints for improvement and we started a discussion, working out the correct solution for the CUPS interfaces, covering both situations of the system’s CUPS being the CUPS Snap or classically (DEB) installed.

Up to now we concluded that the CUPS Snap needs the following auto-connections:

sudo snap connect cups:cups-internal cups:cups-control
sudo snap connect cups:network-manager-observe

and application of slots-per-plug: * so that cups and cups-control plugs of user application Snaps can connect and auto-connect to both the CUPS Snap’s and the system’s slots.

@till.kamppeter I haven’t voted because I was waiting for this (now 43 post) thread to calm down. I’m not an admin, I’m a reviewer like others. I just didn’t want to wade into an already lengthy and confusing thread.

1 Like

@jamesh, now I have copied my last CUPS Snap over to a more “neutral” machine, and here the cups.lpinfo -v gets always Forbidden due to the fact that it does not plug cups-control. For these tools to work with the cupsd in the CUPS Snap I need to change the check in CUPS or put back in the cups-internal. Only if the classic CUPS (with Snap admin check) is used I MUST put back in the cups-internal as a classic CUPS is never “in the same Snap” as a tool from the CUPS Snap.