5

I am trying to use polkit to allow specific user to start/stop/restart specific services. Those services are defined via systemd template, so for example user can run this command: systmctl stop my-daemon@<parameter>.service. Parameter is alphanumeric string, user defined. This polkit rule works perfectly:

polkit.addRule(function(action, subject) {
if (action.id == "org.freedesktop.systemd1.manage-units" &&
    action.lookup("unit") == "[email protected]" &&
    subject.user == "user1") {
    return polkit.Result.YES;
}

However, it's for static parameter, foo1 and it won't work with any other parameter.

I have tried regexp to make the rule generic, here are some examples of critical, third line of the rule:

action.lookup("unit") == "my-daemon@*" &&
action.lookup("unit") == "my-daemon@[:alnum:]+" &&
action.lookup("unit") == "my-daemon@foo[0-9]" &&

None of the above works. Seems to me polkit does not allow regexp in this place. I have read Polkit rule for systemd template unit files, but it isn't a solution for me - author is testing filename, not directly unit name. What am I doing wrong?

This is continuation of my previous question Controlling systemd system service as user, however before I had old systemd and it wasn't possible to write even the static rule. Now it should be possible and I am failing miserably.

OS Suse 12.5
Polkit version 0.113
Systemd version 228

1 Answer 1

3

Uff. Solved this one, thanks to the help of another programmer who sent links to good manual pages: https://www.freedesktop.org/software/polkit/docs/latest/polkit.8.html and mainly https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions which explains relevant things from JavaScript programming language.

As expected, I only changed one line that deals with name of the service.

polkit.addRule(function(action, subject) {
if (action.id == "org.freedesktop.systemd1.manage-units" &&
    RegExp('my-daemon@[A-Za-z0-9_-]+.service').test(action.lookup("unit")) === true &&
    subject.user == "foo1") {
    return polkit.Result.YES;
}
});

RegExp() is a function, and .test in the middle of the line tests the regular expression in ' ' to another string, which is function asking for name of the service. Hope it helps someone else stuck on similar issues.

3
  • The regex my-daemon@[A-Za-z0-9_-]+.service from the post might match other service names one might not intent to match, e.g. [email protected]. Two things are important: 1. A regex does not need to match the full string, if one wants to do that, add ^ & $ to the start / end of the regex. 2. . is a special character in Regex, matching any character, so one should use \. here. So the fixed regex is: ^my-daemon@[A-Za-z0-9_-]+\.service$. (I’m just assuming that RegExp behaves the same as Firefox does in case of RegExp.) Commented Oct 1, 2024 at 16:07
  • How did you figure out that the "unit" variable was available, I can't find any documention on what variables systemd provides to polkit. Commented Sep 8 at 22:07
  • Truth to tell, I can't remember after the years. Commented Sep 10 at 7:37

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.