0

I have a service that exists in the root directory and I want to give user group admin permissions to run the service.

The service exists in /root/home/custom_service/service.service

I tried chgrp admin ./home/custom_service/ then chmod g+rx ./home/custom_service/

When I check the permissions with ls -l ./home/custom_service/ I get -rw-r-xr-- 1 root admin 449 May 30 11:23 service.service

When I try and run the service from my testUsr account (which is in the group admin) this is the result:

I ran:

systemctl start service.service

Result:

==== AUTHENTICATING FOR org.freedesktop.systemd1.manage-units ===
Authentication is required to manage system services or units.
Authenticating as: scarycall
Password:
polkit-agent-helper-1: pam_authenticate failed: Permission denied
==== AUTHENTICATION FAILED ===
Failed to start service.service: Access denied
See system logs and 'systemctl status service.service' for details.

Note: I am able to run the service from root.


UPDATE:

Here is my polkit rule file:

Array.prototype.includes = function(variable) {
    for (var i = 0; i < this.length; i++) { if (this[i] === variable) { return true; } }
    return false;
}

polkit.addRule(function(action, subject) {
    var allowed = {
        units: [
            // Here you can add units that you want to allow admin users to manage.
            "service.service"
        ],
        actions: [
            "org.freedesktop.systemd1.manage-units"
        ],
        verbs: [
            "start", "stop", "restart"
        ]
    }
    var unit_name = action.lookup("unit");
    
    polkit.log("Action" + action);
    polkit.log("Unit=" + unit_name);
    polkit.log("Action ID=" + action.id);
    polkit.log("Verb=" + action.lookup("verb"));
    polkit.log("Subject=" + subject);
    
    if (allowed.actions.includes(action.id) &&
        allowed.units.includes(unit_name) &&
        allowed.verbs.includes(action.lookup("verb")) &&
        subject.isInGroup("admin")
    ) {
        return polkit.Result.YES;
    }
});

The system I am running on has systemd version 219 which does not pass unit or verb through the action. Here is what the logs from this rule look like:

/etc/polkit-1/rules.d/10-insight-service.rules:23: Action[Action id='org.freedesktop.systemd1.manage-units
/etc/polkit-1/rules.d/10-insight-service.rules:24: Unit=undefined
/etc/polkit-1/rules.d/10-insight-service.rules:25: Action ID=org.freedesktop.systemd1.manage-units
/etc/polkit-1/rules.d/10-insight-service.rules:26: Verb=undefined
/etc/polkit-1/rules.d/10-insight-service.rules:27: Subject=[Subject pid=13762 user='testUsr' groups=admin seat='' session='2072' local=false active=true]

The unit and verb details were not added until v226 seen here: https://github.com/systemd/systemd/commit/88ced61bf9673407f4b15bf51b1b408fd78c149d

RESOLUTION: Because the system I am running on runs an older version of systemd it does not support the unit or verb details of action. So I resolved to use sudo permissions and that worked.

In the sudoer file I added:

%admin ALL= NOPASSWD: /bin/systemctl start service.service
%admin ALL= NOPASSWD: /bin/systemctl stop service.service
%admin ALL= NOPASSWD: /bin/systemctl restart service.service
%admin ALL= NOPASSWD: /bin/systemctl status service.service
jo.oj
  • 3
  • 1

1 Answers1

0

You can create a Polkit policy that allows users in the admin group to start, stop or restart specific system units. For example.

// Allow user in admin group to manage specific systemd units
Array.prototype.includes = function(variable) {
    for (var i = 0; i < this.length; i++) { if (this[i] === variable) { return true; } }
    return false;
}

polkit.addRule(function(action, subject) {
    var allowed = {
        units: [
            // Here you can add units that you want to allow admin users to manage.
            "backup.service",
            "nginx.service",
            "backup-rotate.service"
        ],
        actions: [
            "org.freedesktop.systemd1.manage-unit-files"
        ],
        verbs: [
            "start", "stop", "restart"
        ]
    }
    var unit_name = action.lookup("unit");
    if (allowed.actions.includes(action.id) &&
        allowed.units.includes(unit_name) &&
        allowed.verbs.includes(action.lookup("verb")) &&
        subject.isInGroup("admin")
    ) {
        return polkit.Result.YES;
    }
});

Save the policy file as /etc/polkit-1/rules.d/60-units.rules, the new rule should take effect immediately.

memchr
  • 551
  • 1
  • 9
  • So the rule file name would be 60-units.rules – jo.oj Jul 03 '23 at 17:32
  • Yes, I made a typo, the name of the rule files is irrelevant, but it's common practice to prefix them with a number. – memchr Jul 03 '23 at 17:57
  • is the vi: ft=javascript comment required? Is it marking the file type like #!/bin/bash? – jo.oj Jul 03 '23 at 18:10
  • I've added the file and saved it but the error remains the same - the authentication message still appears the same and is authenticating as 'scarycall' still – jo.oj Jul 03 '23 at 18:48
  • The rule file is an example, did you change the `allowed.unites` array? If not, you should append the name of the desired service to this array. – memchr Jul 03 '23 at 19:57
  • I updated allowed units? Also when I polkit.log() the unit_name it is undefined, as is action.lookup("verb") – jo.oj Jul 03 '23 at 20:12
  • My systemctl version does not have access to unit or verb so those undefined values seem to be the break case here – jo.oj Jul 03 '23 at 20:23
  • If your unit is called `service.service`, add it to the `units` array of the `allowed` object. `action.lookup` is a polkit built-in method. And `unit_name` is defined in this rule. What is your OS and polkit version? Also what is the rule file you using now? Please post it. – memchr Jul 03 '23 at 20:26
  • >>> My systemctl version does not have access to unit or verb <<< What does that mean? Please clarify, – memchr Jul 03 '23 at 20:28
  • And if you have read the rules file, your account will need to be added to the admin group if it is not already. – memchr Jul 03 '23 at 20:33
  • I updated the original post with the polkit file and what the logs return – jo.oj Jul 03 '23 at 20:42
  • It is `org.freedesktop.systemd1.manage-unit-files` **not** `org.freedesktop.systemd1.manage-units`. – memchr Jul 03 '23 at 20:48
  • Based on the action id output by the log it is `org.freedesktop.systemd1.manage-units` – jo.oj Jul 03 '23 at 20:50
  • There are two actions here, `manage-unit-files` `manage-units` does not allow you to enable/disable the service. https://www.freedesktop.org/software/systemd/man/org.freedesktop.systemd1.html – memchr Jul 03 '23 at 21:00
  • >>> Based on the action id output by the log <<< Please note that there are two separate logs because the rule file is called twice. – memchr Jul 03 '23 at 21:01