Bug 1269212

Summary: cannot disallow action
Product: [Fedora] Fedora Reporter: Oliver Henshaw <oliver.henshaw>
Component: polkitAssignee: Miloslav Trmač <mitr>
Status: CLOSED NOTABUG QA Contact: Fedora Extras Quality Assurance <extras-qa>
Severity: unspecified Docs Contact:
Priority: unspecified    
Version: 21CC: mitr
Target Milestone: ---   
Target Release: ---   
Hardware: Unspecified   
OS: Unspecified   
Whiteboard:
Fixed In Version: Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2015-10-06 22:21:13 UTC Type: Bug
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:

Description Oliver Henshaw 2015-10-06 16:32:02 UTC
Description of problem:

I want to disallow hibernate for most users, since it's unreliable. But I can't seem to manage it, nor can I disallow suspend (it's easier to test). Even unconditionally disabling suspend doesn't work.

# cat /etc/polkit-1/rules.d/10-disable-suspend.rules 
polkit.addRule(function(action, subject) {
  if (action.id == "org.freedesktop.login1.suspend") {
    polkit.log("Disabled");
    return polkit.Result.NO;
  }
});
$ pkcheck --action-id org.freedesktop.login1.suspend --process $$
$ echo $?
0

but I do see "/etc/polkit-1/rules.d/10-disable-suspend.rules:3: Disabled" in the logs, so the rule is running.

If I add a second no-op rule:
polkit.addRule(function(action, subject) {
  if (action.id == "org.freedesktop.login1.suspend") {
    polkit.log("Fall back to default");
  }
});

then I don't see the second message in the logs, so my rule should be the final answer. If I change the return value to polkit.Result.NOT_HANDLED then I see the fall back log message - as expected.

So everything seems to be working except the directive to not authorize the action. I have the same results on the F21 Workstation live image, so it's probably not just a local problem.


Version-Release number of selected component (if applicable):
polkit-0.113-4.fc21.x86_64

Comment 1 Miloslav Trmač 2015-10-06 22:21:13 UTC
Thanks for your report.

Try:
> polkit.addRule(function(action, subject) {
>   if (action.id == "org.freedesktop.login1.suspend"
>       || action.id == "org.freedesktop.login1.suspend-multiple-sessions") {
>     polkit.log("Disabled: " + action.id);
>     return polkit.Result.NO;
>   }
> });

The suspend-multiple-sessions action has an “org.freedesktop.policykit.imply” annotation to the effect that suspend-multiple-sessions automatically authorizes the single-session action as well.

polkit does not distinguish between “NO” configured in the .action file and a “NO” returned by .results; either one can be overridden with the .imply annotation.

It is designed this way primarily to handle the AUTH_* values, for benefit of control center panels which may aggregate multiple actions in a single dialog, and want to provide a single “Unlock” button which allows the user to only authenticate once.

This is not obviously the only possible design for the imply mechanism—but because you do want to prohibit suspend even if other users are logged in, regardless of how the “imply” mechanism works, denying both actions in a .rule file seems the right thing to do.

(Feel free to reopen this report if this does not work for you or address your concern.)

Comment 2 Oliver Henshaw 2015-10-07 11:53:55 UTC
Thanks, that works with the minor wrinkle that I also handle org.freedesktop.login1.hibernate-ignore-inhibit (which implies .hibernate too)

I've filed bug #1269450 to request that the pkaction --verbose output makes the imply relationship clear for actions on both sides. But I can kinda see why you might not want to do that.