Status changed to 'Confirmed' because the bug affects multiple users. ** Changed in: policykit-1 (Ubuntu) Status: New => Confirmed
-- You received this bug notification because you are a member of Ubuntu Touch seeded packages, which is subscribed to policykit-1 in Ubuntu. https://bugs.launchpad.net/bugs/2084150 Title: Path move from /lib to /usr/lib causes systemd-reply-password pkexec mismatch Status in PolicyKit: Unknown Status in policykit-1 package in Ubuntu: Confirmed Bug description: In Ubuntu/Noble, the location of /lib/systemd/systemd-reply-password is now /usr/lib/systemd/systemd-reply-password. This is also reflected in the policykit-1 action: [jammy]$ grep path /usr/share/polkit-1/actions/org.freedesktop.systemd1.policy <annotate key="org.freedesktop.policykit.exec.path">/lib/systemd/systemd-reply-password</annotate> [noble]$ grep path /usr/share/polkit-1/actions/org.freedesktop.systemd1.policy <annotate key="org.freedesktop.policykit.exec.path">/usr/lib/systemd/systemd-reply-password</annotate> So far, so good. However, if you have software that is written according to the specs documented in systemd, you get the following problem: https://github.com/systemd/systemd/blob/70516b026b7a83dbe7b8141c67f2dbe412ce24d9/docs/PASSWORD_AGENTS.md > Access to the socket is restricted to privileged users. > To acquire the necessary privileges to send the answer > back, consider using PolicyKit. In fact, the GNOME agent > we ship does that, and you may simply piggyback on that, > by executing > "/usr/bin/pkexec /lib/systemd/systemd-reply-password 1 /path/to/socket" > or "/usr/bin/pkexec /lib/systemd/systemd-reply-password 0 /path/to/socket" > and writing the password to its standard input. Use '1' > as argument if a password was entered by the user, or '0' > if the user canceled the request. If you follow these specs, the exec path is /lib/systemd/systemd- reply-password and not /usr/lib/systemd/systemd-reply-password. This means that the action in /usr/share/polkit-1/actions/org.freedesktop.systemd1.policy is not matched, and no action-id org.freedesktop.systemd1.reply-password is found. That means that a rules.d script like this does not work: polkit.addRule(function(action, subject) { if (action.id == "org.freedesktop.systemd1.reply-password" && subject.local && subject.active && (subject.isInGroup("sudo") || subject.isInGroup("netdev"))) { return polkit.Result.YES; } return polkit.Result.NOT_HANDLED; }); For a call to /lib/systemd/systemd-reply-password the action.id will not be "org.freedesktop.systemd1.reply-password" but it will be "org.freedesktop.policykit.exec". Adding a second <annotation> in /usr/share/polkit-1/actions/org.freedesktop.systemd1.policy does NOT help: <annotate key="org.freedesktop.policykit.exec.path">/lib/systemd/systemd-reply-password</annotate> <annotate key="org.freedesktop.policykit.exec.path">/usr/lib/systemd/systemd-reply-password</annotate> <!-- yes, multiple are allowed, but with different keys/attributes --> <!-- so, only the last one will be used --> Adding a second <action> with the same "org.freedesktop.systemd1.reply-password" id does NOT work either. It will only use the second one. It looks like the sane thing to do would be to patch polkitd to do a `realpath /lib/systemd/systemd-reply-password` to find `/usr/lib/systemd/systemd-reply-password` before comparing it to the org.freedesktop.policykit.exec.path value. Alternatively EVERY caller to /lib/systemd/systemd-reply-password should check which the realest path is, before calling it. In which case you end up with something like this: > diff --git a/openvpn-u2f-ask-password b/openvpn-u2f-ask-password > index b0637ae..4ffa1a7 100755 > --- a/openvpn-u2f-ask-password > +++ b/openvpn-u2f-ask-password > @@ -351,7 +351,11 @@ class AskPassword: > > def respond(self, response): > subprocess.run( > - ['/usr/bin/pkexec', '/lib/systemd/systemd-reply-password', > + ['/usr/bin/pkexec', > + # Work around incompatibility with policykit actions and > + # Ubuntu move of /lib to /usr/lib, which causes polkit-1 > + # actions not to be matched if the non-real path is used. > + os.path.realpath('/lib/systemd/systemd-reply-password'), > '1', self._values['Socket']], > input=response.encode('ascii')) > print('DEBUG: response to {!r}: {}'.format( This was quite elusive to track down. If nothing else, I hope this ticket helps someone else. Cheers, Walter Doekes OSSO B.V. ==== A possible fix could be to call realpath(3) just before the call to find_action_for_path: https://github.com/polkit- org/polkit/blob/94e2b5471f8e559897a80f6dbd84f454debc0d38/src/programs/pkexec.c#L796-L799 So it is called just before the comparison here: https://github.com/polkit- org/polkit/blob/94e2b5471f8e559897a80f6dbd84f454debc0d38/src/programs/pkexec.c#L309 That would make calls to both /lib/systemd/systemd-reply-password and /usr/lib/systemd/systemd-reply-password behave the same. To manage notifications about this bug go to: https://bugs.launchpad.net/policykit-1/+bug/2084150/+subscriptions -- Mailing list: https://launchpad.net/~touch-packages Post to : touch-packages@lists.launchpad.net Unsubscribe : https://launchpad.net/~touch-packages More help : https://help.launchpad.net/ListHelp