Problem with polkit when allowing systemd managment by regular user

Hello,

Currently when I start my epson scanner with iscan (image scan for unix) I receive an authentication windows with ident “org.freedesktop.systemd1.manage-units” and polkit.subject-pid = iscan pid.
The reason is that the program tries to find a scanner and use avahi-daemon.service therefor. This service is not started at boot.
the avahi-daemon.socket is started


hpprol2:~ # systemctl status avahi-daemon.socket
● avahi-daemon.socket - Avahi mDNS/DNS-SD Stack Activation Socket
     Loaded: loaded (/usr/lib/systemd/system/avahi-daemon.socket; enabled; vendor preset: disabled)
     Active: active (running) since Sun 2022-04-03 09:02:14 CEST; 2h 3min ago
      Until: Sun 2022-04-03 09:02:14 CEST; 2h 3min ago
   Triggers: ● avahi-daemon.service
     Listen: /run/avahi-daemon/socket (Stream)
     CGroup: /system.slice/avahi-daemon.socket

Apr 03 09:02:14 hpprol2 systemd[1]: Listening on Avahi mDNS/DNS-SD Stack Activation Socket.

I want allowing a normal user to start avahi-deamon.service without root authentication.

It seems that a polkit rule can do the job.
It is the first time that I try to work with polkit.:expressionless:
I found in this document polkit - ArchWiki an example to allow management of individual systemd by regular user for wpa_supplicant

So I created /etc/polkit-1/rules.d/11-avahidaemon.rules


polkit.addRule(function(action, subject) {
    if (action.id == "org.freedesktop.systemd1.manage-units") {
    polkit.log("action=" + action)
        polkit.log("subject=" + subject)
    polkit.log("unit="+action.lookup("unit"))
        if (action.lookup("unit") == "avahi-daemon.service") {
        polkit.log("verb="+action.lookup("verb"))
            var verb = action.lookup("verb");
            if (verb == "start" || verb == "stop" || verb == "restart") {
                return polkit.Result.YES;
            }
        }
    }
});

But after a restart of polkit and even after a reboot the authentication is still asked.
Journalctl shows before authentication


Apr 03 10:58:22 hpprol2 systemd[23276]: Started Image Scan! for Linux.
Apr 03 10:58:22 hpprol2 iscan[15682]: io/hpmud/model.c 532: no hp_HP_LaserJet_200_color_M251n attributes found in /usr/share/hplip/data/models/models.dat
Apr 03 10:58:22 hpprol2 iscan[15682]: io/hpmud/model.c 543: no hp_HP_LaserJet_200_color_M251n attributes found in /usr/share/hplip/data/models/unreleased/unreleased.dat
Apr 03 10:58:22 hpprol2 dbus-daemon[728]: [system] Activating via systemd: service name='org.freedesktop.Avahi' unit='dbus-org.freedesktop.Avahi.service' requested by ':1.2569' (uid=1000 pid=15682 comm="/usr/bin/iscan")
Apr 03 10:58:22 hpprol2 dbus-daemon[728]: [system] Activation via systemd failed for unit 'dbus-org.freedesktop.Avahi.service': Unit dbus-org.freedesktop.Avahi.service not found.

after cancelling the authentication


Apr 03 10:58:51 hpprol2 polkitd[15400]: Operator of unix-session:16 FAILED to authenticate to gain authorization for action org.freedesktop.systemd1.manage-units for system-bus-name::1.2576 [/usr/bin/iscan] (owned by unix-user:philippe)
Apr 03 10:58:51 hpprol2 iscan[16079]: protocol/discovery/avahiDiscovery.c 472: Failed to create client object: Daemon not running

after succesfull authentication


Apr 03 11:00:42 hpprol2 polkitd[756]: Operator of unix-session:2 successfully authenticated as unix-user:root to gain TEMPORARY authorization for action org.freedesktop.systemd1.manage-units for system-bus-name::1.2584 [/usr/bin/iscan] (owned by unix-user:philippe)
Apr 03 11:00:43 hpprol2 dbus-daemon[748]: [system] Activating via systemd: service name='org.freedesktop.Avahi' unit='dbus-org.freedesktop.Avahi.service' requested by ':1.2588' (uid=1000 pid=7285 comm="/usr/bin/iscan")
A
Apr 03 11:00:43 hpprol2 avahi-daemon[7297]: Found user 'avahi' (UID 488) and group 'avahi' (GID 474).
Apr 03 11:00:43 hpprol2 avahi-daemon[7297]: Successfully dropped root privileges.
Apr 03 11:00:43 hpprol2 avahi-daemon[7297]: avahi-daemon 0.8 starting up.
Apr 03 11:00:43 hpprol2 systemd[1]: Started Avahi mDNS/DNS-SD Stack.
Apr 03 11:00:43 hpprol2 avahi-daemon[7297]: No service file found in /etc/avahi/services.
Apr 03 11:00:43 hpprol2 avahi-daemon[7297]: Joining mDNS multicast group on interface vlan3.IPv4 with address 192.168.3.1.
Apr 03 11:00:43 hpprol2 avahi-daemon[7297]: New relevant interface vlan3.IPv4 for mDNS.
Apr 03 11:00:43 hpprol2 avahi-daemon[7297]: Joining mDNS multicast group on interface vlan2.IPv4 with address 192.168.2.1.
Apr 03 11:00:43 hpprol2 avahi-daemon[7297]: New relevant interface vlan2.IPv4 for mDNS.
Apr 03 11:00:43 hpprol2 avahi-daemon[7297]: Joining mDNS multicast group on interface vlan1.IPv4 with address 192.168.1.1.
Apr 03 11:00:43 hpprol2 avahi-daemon[7297]: New relevant interface vlan1.IPv4 for mDNS.
Apr 03 11:00:43 hpprol2 avahi-daemon[7297]: Joining mDNS multicast group on interface vlan4.IPv4 with address 192.168.4.1.
Apr 03 11:00:43 hpprol2 avahi-daemon[7297]: New relevant interface vlan4.IPv4 for mDNS.
Apr 03 11:00:43 hpprol2 avahi-daemon[7297]: Joining mDNS multicast group on interface br0.IPv4 with address 192.168.1.120.
Apr 03 11:00:43 hpprol2 avahi-daemon[7297]: New relevant interface br0.IPv4 for mDNS.
Apr 03 11:00:43 hpprol2 avahi-daemon[7297]: Joining mDNS multicast group on interface lo.IPv4 with address 127.0.0.1.
Apr 03 11:00:43 hpprol2 avahi-daemon[7297]: New relevant interface lo.IPv4 for mDNS.
Apr 03 11:00:43 hpprol2 avahi-daemon[7297]: Network interface enumeration completed.
Apr 03 11:00:43 hpprol2 avahi-daemon[7297]: Registering new address record for 192.168.3.1 on vlan3.IPv4.
Apr 03 11:00:43 hpprol2 avahi-daemon[7297]: Registering new address record for 192.168.2.1 on vlan2.IPv4.
Apr 03 11:00:43 hpprol2 avahi-daemon[7297]: Registering new address record for 192.168.1.1 on vlan1.IPv4.
Apr 03 11:00:43 hpprol2 avahi-daemon[7297]: Registering new address record for 192.168.4.1 on vlan4.IPv4.
Apr 03 11:00:43 hpprol2 avahi-daemon[7297]: Registering new address record for 192.168.1.120 on br0.IPv4.
Apr 03 11:00:43 hpprol2 avahi-daemon[7297]: Registering new address record for 127.0.0.1 on lo.IPv4.
Apr 03 11:00:44 hpprol2 avahi-daemon[7297]: Server startup complete. Host name is hpprol2.local. Local service cookie is 1374376549.

First remark I don’t see the lines from polkit.log: Does this mean that this code is not executed or recognized?
I see in then man that for action.lookup(string key)

The lookup() method is used to lookup the polkit variables passed from the mechanism. For example, the pkexec(1) mechanism sets the variable program which can be obtained in JavaScript using the expression action.lookup(“program”). If there is no value for the given key, then undefined is returned.
Consult the documentation for each mechanism for what variables are available for each action.

where can I find this documentation?

in the avahi-daemon.service I see an alias


....
[Install]
WantedBy=multi-user.target
Also=avahi-daemon.socket
Alias=dbus-org.freedesktop.Avahi.service

Is there something special to do when an alias is present? This alias seems to be used by iscan.

Many thanks in adavance
Philippe

So you check for unit name avahi-daemon.service, but activation is requested for unit name dbus-org.freedesktop.Avahi.service. Of course they do not match.

First remark I don’t see the lines from polkit.log: Does this mean that this code is not executed or recognized?

It could be, it is impossible to tell without extra debugging. You may have rules that return earlier.

But polkit.log is broken in TW (as in - it does not behave as documented). If you remove --no-debug option from polkitd invocation you will see polkit.log output, but message format still does not match documentation. I do not know whether this is intended behavior or side effect of updating from mozjs-60 to mozjs-68 (which is responsible for printing these log messages). You may consider bug report.

where can I find this documentation [for action variables]?

Mostly in the source code of the corresponding programs. Even actions themselves are rarely documented in human readable form.

[Install]
WantedBy=multi-user.target
Also=avahi-daemon.socket
Alias=dbus-org.freedesktop.Avahi.service

Is there something special to do when an alias is present?

The Alias in [noparse][Install][/noparse] section is only used by “systemctl enable”.

This alias seems to be used by iscan.

The behavior of your program is more or less pointless - if unit was enabled it is already started; and if unit was not enabled the alias name is unknown.

Most likely it does not try to activate systemd unit at all. It simply contacts D-Bus service org.freedesktop.Avahi and D-Bus daemon tries to activate systemd service in response. The D-Bus configuration for Avahi service lists

SystemdService=dbus-org.freedesktop.Avahi.service

Thanks for your answer.
I tried to replace in the 11-avahi-daemon.rules the action.id by “dbus-org.freedesktop.Avahi.service” or “dbus-org.freedesktop.Avahi” but this seems not changing anything.
I see also that when the authentication pop-up is displayed then i have already these two lines

Apr 04 17:22:35 hpprol2 dbus-daemon[748]: [system] Activating via systemd: service name='org.freedesktop.Avahi' unit='dbus-org.freedesktop.Avahi.service' requested by ':1.1005' (uid=1000 pid=17351 comm="iscan")
Apr 04 17:22:35 hpprol2 dbus-daemon[748]: [system] Activation via systemd failed for unit 'dbus-org.freedesktop.Avahi.service': Unit dbus-org.freedesktop.Avahi.service not found.

So iscan asks for a service which doesn’t exist.
The popup displays this where the ident is “org.freedesktop.systemd1.manage.unit”
https://paste.opensuse.org/images/51192378.png

It could be, it is impossible to tell without extra debugging. You may have rules that return earlier.

I have no other rules in /etc/polkit-1/rules.d except the standard file “90-default-privs.rules”

The Alias in [noparse][Install][/noparse] section is only used by “systemctl enable”.

The behavior of your program is more or less pointless - if unit was enabled it is already started; and if unit was not enabled the alias name is unknown.

Ok this seems logic but then how can the authentication find the “org.freedesktop.systemd1.manage.unit”?
Is it then possible to use a polkit rules for this?

I’ll try to remove the --no-debug in the execstart of polkit to see if there are more logged data

Many thanks for your answer
Philippe

Yes, in the meanwhile I tested the behavior and when activation is performed by D-Bus daemon, no authentication is needed. Your rules work at least for manual “systemctl start avahi-daemon.service”.

I have no other rules in /etc/polkit-1/rules.d except the standard file “90-default-privs.rules”

Rules are also in /usr/share/polkit-1.

Ok this seems logic but then how can the authentication find the “org.freedesktop.systemd1.manage.unit”?

This is action for which authentication is requested.

Is it then possible to use a polkit rules for this?

I am not sure I understand the question. If you want to allow anyone to manage units without authentication, much easier is to set default allow_any=yes. Otherwise you are free to perform any checks in your rule script.

I’ll try to remove the --no-debug in the execstart of polkit to see if there are more logged data

Yes, this is needed to understand what happens.

BTW: My scanner is supported by imagescan, which installs the following rules:

**erlangen:~ #** tail /etc/udev/rules.d/utsushi-esci.rules 
ATTRS{idProduct}=="013c", ENV{utsushi_driver}="esci:gt-s650", ENV{firmware_file}="esfw010c.bin" 
ATTRS{idProduct}=="013d", ENV{utsushi_driver}="esci:gt-s650", ENV{firmware_file}="esfw010c.bin" 

**#  Give scanner users read/write permissions on the device. 
ENV{utsushi_driver}=="esci*", MODE="0666", OWNER="root", GROUP="root" **

#  Device detection by libutsushi depends on libsane_matched being set. 
ENV{utsushi_driver}=="esci*", ENV{libsane_matched}="yes" 

LABEL="utsushi_esci_rules_end" 
**erlangen:~ #**

There is no such rule associated with iscan?

Hello Karl,

No the epson perfection V30 doesn’t install any rules in /etc/udev.
This is a usb scanner and if I cancel the authentication the scanner is recognized and works with a regular user. As far as I understand iscan tries a lookup to find a possible multifunction printer+scannner and uses a call to the “dbus-org.freedesktop.Avahi.service” which trigger “avahi-daemon.service” and the authentication popup. If this fails I think that iscan continues with a lookup to usb and find the perfection V30 scanner.

Regards
Philippe

I see. From: https://wiki.archlinux.org/title/SANE/Scanner-specific_problems#Epson

For Epson scanners, you can choose between two different backends: “Image Scan v3” (imagescan/utsushi) or “Image Scan! for Linux” (iscan/epkowa). You can check here for all supported imagescan/utsushi devices and here for all supported iscan/epkowa devices. What used to be the iscan package in community is out of date, and buggy.

Did you ever try imagescan?

I tried utsushi but the scanner is not recognized and it also is not present in the list of supported scanner by imagescan.
I have also skanlite: this program has the same process as iscan. It asks first time for authentication and works on both options: cancel or enter the authentication password

Regards
Philippe

Hello,

I removed the option --no-debug in /usr/lib/systemd/system/polkit.service and restarted polkit but this doesn’t show more information in journalctl when i run iscan.

Regards
Philippe

That is not enough. To make systemd aware of your changes you need to reload systemd (systemctl daemon-reload) or reboot.

Hello,

Yes, I know this and I did the daemon-reload before restarting polkit.

Regards
Philippe

Well, in this case it means there is another rule that is evaluated earlier and returns.

**erlangen:~ #** systemd-analyze get-log-level  
info 
**erlangen:~ #** systemd-analyze set-log-level debug            
**erlangen:~ #** systemd-analyze get-log-level       
debug 
**erlangen:~ #**

Hello Karl,

Many thanks for your advice. I take good note of this instruction.:slight_smile:
I ran iscan after this setting and have more data but still difficult to understand exactly what occurs.
Here the journalctl output from the start of iscan up to the start of avahi-daemon after authentication

Apr 06 12:48:55 hpprol2 iscan[28119]: io/hpmud/model.c 532: no hp_HP_LaserJet_200_color_M251n attributes found in /usr/share/hplip/data/models/models.dat
Apr 06 12:48:55 hpprol2 iscan[28119]: io/hpmud/model.c 543: no hp_HP_LaserJet_200_color_M251n attributes found in /usr/share/hplip/data/models/unreleased/unreleased.dat
Apr 06 12:48:55 hpprol2 dbus-daemon[749]: [system] Activating via systemd: service name='org.freedesktop.Avahi' unit='dbus-org.freedesktop.Avahi.service' requested by ':1.1253' (uid=1000 pid=28119 comm="iscan")
Apr 06 12:48:55 hpprol2 dbus-daemon[749]: [system] Activation via systemd failed for unit 'dbus-org.freedesktop.Avahi.service': Unit dbus-org.freedesktop.Avahi.service not found.
Apr 06 12:48:55 hpprol2 systemd[1]: Got message type=signal sender=org.freedesktop.DBus destination=org.freedesktop.systemd1 path=/org/freedesktop/DBus interface=org.freedesktop.systemd1.Activator member=ActivationRequest cookie=553 reply_cookie=0 signature=s error-nam>
Apr 06 12:48:55 hpprol2 systemd[1]: dbus-org.freedesktop.Avahi.service: Failed to load configuration: No such file or directory
Apr 06 12:48:55 hpprol2 systemd[1]: dbus-org.freedesktop.Avahi.service: Trying to enqueue job dbus-org.freedesktop.Avahi.service/start/replace
Apr 06 12:48:55 hpprol2 systemd[1]: D-Bus activation failed for dbus-org.freedesktop.Avahi.service: Unit dbus-org.freedesktop.Avahi.service not found.
Apr 06 12:48:55 hpprol2 systemd[1]: Sent message type=signal sender=n/a destination=org.freedesktop.DBus path=/org/freedesktop/systemd1 interface=org.freedesktop.systemd1.Activator member=ActivationFailure cookie=38542 reply_cookie=0 signature=sss error-name=n/a error->
Apr 06 12:48:55 hpprol2 systemd[1]: dbus-org.freedesktop.Avahi.service: Collecting.
Apr 06 12:48:55 hpprol2 systemd[1]: Sent message type=signal sender=n/a destination=n/a path=/org/freedesktop/systemd1 interface=org.freedesktop.systemd1.Manager member=UnitNew cookie=38543 reply_cookie=0 signature=so error-name=n/a error-message=n/a
Apr 06 12:48:55 hpprol2 systemd[1]: Sent message type=signal sender=n/a destination=n/a path=/org/freedesktop/systemd1 interface=org.freedesktop.systemd1.Manager member=UnitRemoved cookie=38544 reply_cookie=0 signature=so error-name=n/a error-message=n/a
Apr 06 12:49:08 hpprol2 polkitd[14767]: **Operator of unix-session:11 successfully authenticated as unix-user:root to gain TEMPORARY authorization for action org.freedesktop.systemd1.manage-units for system-bus-name::1.1252 [iscan] (owned by unix-user:philippe)**
Apr 06 12:49:08 hpprol2 polkitd[14767]: 12:49:08.169: Operator of unix-session:11 successfully authenticated as unix-user:root to gain TEMPORARY authorization for action org.freedesktop.systemd1.manage-units for system-bus-name::1.1252 [iscan] (owned by unix-user:phili>
Apr 06 12:49:08 hpprol2 systemd[1]: Got message type=method_call sender=:1.1252 destination=org.freedesktop.systemd1 path=/org/freedesktop/systemd1 interface=org.freedesktop.systemd1.Manager member=StartUnit cookie=3 reply_cookie=0 signature=ss error-name=n/a error-mes>
Apr 06 12:49:08 hpprol2 systemd[1]: Sent message type=method_call sender=n/a destination=org.freedesktop.DBus path=/org/freedesktop/DBus interface=org.freedesktop.DBus member=GetConnectionUnixUser cookie=38547 reply_cookie=0 signature=s error-name=n/a error-message=n/a
Apr 06 12:49:08 hpprol2 systemd[1]: Got message type=method_return sender=org.freedesktop.DBus destination=:1.1 path=n/a interface=n/a member=n/a cookie=554 reply_cookie=38547 signature=u error-name=n/a error-message=n/a
Apr 06 12:49:08 hpprol2 systemd[1]: Sent message type=method_call sender=n/a destination=org.freedesktop.PolicyKit1 path=/org/freedesktop/PolicyKit1/Authority interface=org.freedesktop.PolicyKit1.Authority member=CheckAuthorization cookie=38548 reply_cookie=0 signature>
Apr 06 12:49:08 hpprol2 systemd[1]: Got message type=method_return sender=:1.284 destination=:1.1 path=n/a interface=n/a member=n/a cookie=3666 reply_cookie=38548 signature=(bba{ss}) error-name=n/a error-message=n/a
Apr 06 12:49:08 hpprol2 systemd[1]: Got message type=method_call sender=:1.1252 destination=org.freedesktop.systemd1 path=/org/freedesktop/systemd1 interface=org.freedesktop.systemd1.Manager member=StartUnit cookie=3 reply_cookie=0 signature=ss error-name=n/a error-mes>
Apr 06 12:49:08 hpprol2 systemd[1]: avahi-daemon.service: Trying to enqueue job avahi-daemon.service/start/replace
Apr 06 12:49:08 hpprol2 systemd[1]: systemd-journald-audit.socket: Cannot add dependency job, ignoring: Unit systemd-journald-audit.socket not found.
Apr 06 12:49:08 hpprol2 systemd[1]: avahi-daemon.service: Installed new job avahi-daemon.service/start as 6129
Apr 06 12:49:08 hpprol2 systemd[1]: avahi-daemon.service: Enqueued job avahi-daemon.service/start as 6129

if I understand it correctly, the call to dbus-org.freedesktop.Avahi.service fails and systemd seems calling org.freedesktop.systemd1.Manager and thereafter the authentication is started for **org.freedesktop.systemd1.manage-units.
**
Now as iscan works even when I cancel the authentication, I have a workaround

Regards
Philippe

Yep. When imagescan starts on host erlangen systemd never tries to authenticate as the udev rule already grants permission. You may try a similar approach with iscan.

By the way: An earlier version of backup-home mounted the disk with option noauto only. This resulted in an annoying dialog to authenticate, which wasn’t needed. Cancelling authentication wouldn’t stop invocation of the service either. Mounting the disk with noauto,user made the dialog disappear.

Granting permission suppresses the dialog: https://forums.opensuse.org/showthread.php/567650-Disk-spin-down-What-program-to-use-and-best-practice-today?p=3121654#post3121654