[1792230 views]

[]

Odi's astoundingly incomplete notes

New entries | Code

Allowing normal users to restart Apache using polkit

Allow an ordinary unprivileged user to restart a system service like Apache is a frequent requirement in operations. I enounter this on a daily basis when the customer (owner of the machine) asks me (manufacturer of the application) to configure Apache for our application or to troubleshoot an issue. Of course they don't just want to give me complete root access. So what do they do? Usually it's just sudo /etc/init.d/httpd restart.

I am very uneasy with passing user controlled arguments to shell scripts. The whole command should be wrapped into a script that does its job without any arguments.

And in a second step you could do it also via polkit. As that's a bit verbose, here is how.

1. Create the program to run. Here we simply execute the command to restart Apache.
/usr/local/sbin/httpd-restart:
#!/bin/sh
exec /etc/init.d/httpd restart

2. Create the policy for pkexec. Customize the action ID (freely chose the part after pkexec).
/usr/share/polkit-1/actions/httpd-restart.policy:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE policyconfig PUBLIC
 "-//freedesktop//DTD PolicyKit Policy Configuration 1.0//EN"
 "http://www.freedesktop.org/standards/PolicyKit/1.0/policyconfig.dtd">
<policyconfig>
  <vendor>Odi</vendor>
  <vendor_url>http://www.odi.ch/</vendor_url>
  <icon_name>computer</icon_name>

  <action id="org.freedesktop.policykit.pkexec.httpd-restart">
    <description>Restart Apache</description>
    <message>Authentication is required to restart Apache</message>
    <defaults>
      <allow_inactive>no</allow_inactive>
      <allow_active>no</allow_active>
    </defaults>
    <annotate key="org.freedesktop.policykit.exec.path">/usr/local/sbin/httpd-restart</annotate>
  </action>
</policyconfig>

3. Define a rule to which user this applies.
/etc/polkit-1/rules.d/httpd-restart.rules:
polkit.addRule(function(action, subject) {
               if (action.id == "org.freedesktop.policykit.pkexec.httpd-restart" &&
                   subject.user == "john.doe") {
                   return polkit.Result.YES;
               }
           });

4. Now user john.doe can safely execute this without entering a password:
pkexec /usr/local/sbin/httpd-restart
Security notes:
pkexec is an suid binary. It performs checks via polkit and then executes the passed command. It essentially works the same as sudo (which is also an suid binary). The same precautions to running a binary as root apply: don't let users execute random binaries as root if those binaries can also do their job as a normal user.

That means: don't run an editor (vim) as root just to edit a file that happens to be owned by root. Editing doesn't require root privileges. Neither does file access. Let them run their favourite editor themselves and give them access to the file with permissions/ACLs. See man setfacl.

posted on 2016-01-24 14:49 UTC in Code | 0 comments | permalink