11

I'm trying to set up an Upstart job to run on system startup, and that can also be started/stopped by members of a group other than sudo. With a previous version, I usedupdate-rc.d and scripts stored in /etc/init.d/ to get this working by adding %Group ALL = NOPASSWD: /etc/init.d/scriptname to my sudoers file, but I can't seem to get an equivalent working for Upstart.

I tried adding %Group ALL = NOPASSWD: /sbin/initctl start jobname to the sudoers file, but trying to run the command start jobname produces this error:

start: Rejected send message, 1 matched rules; type="method_call", sender=":1.21" (uid=1000 pid=5148 comm="start jobname " interface="com.ubuntu.Upstart0_6.Job" member="Start" error name="(unset)" requested_reply="0" destination="com.ubuntu.Upstart" (uid=0 pid=1 comm="/sbin/init")

As near as I can tell, that's a complaint about how my user account isn't given the power to send 'Start' messages in the D-Bus config file for Upstart. I haven't been able to actually find any information on how to edit that file to give a group permission to access a specific service--does such an option exist? Is there a way to edit the Sudoers file so I can run the job without editing the config file? Am I better off just sticking with the previous version?

4 Answers4

7

You can start with finding out where the D-Bus configuration specific for Upstart is kept. See that destination="com.ubuntu.Upstart" snippet from the error message? Now try to grep it in the folder with D-Bus config files:

vhost07:~ $ grep -r "com.ubuntu.Upstart" /etc/dbus-1
/etc/dbus-1/system.d/Upstart.conf:    <allow own="com.ubuntu.Upstart" />
[...skipped...]

That Upstart.conf file has some examples of policies. I guess you could try to figure out the format of a policy from them. Then try to allow your specific user just the actions that it needs. For instance, as in:

<policy user="pope_benedict">
  <allow send_destination="com.ubuntu.Upstart"
         send_interface="com.ubuntu.Upstart0_6.Job"
         send_member="Start"/>
</policy>

This should permit the pope_benedict user to start that job.

Note that the values for the 'allow' policy attributes are listed in your original error message.

7

I'm personally using the following line in /etc/sudoers.d/jobname_myuser file:

myuser ALL = (root) NOPASSWD: /sbin/start jobname, /sbin/stop jobname, /sbin/restart jobname, /sbin/status jobname

as described here: https://serverfault.com/a/390723/68608

2

Such option does not exist in sudo.

The difference between Sysv scripts and Upstart configuration files is just that: Sysv scripts are scripts, executables in their own right and you can tell sudo to allow some group to execute them. In the other hand, Upstart configuration files are merely just configuration files, not executables, so the execution of start (symlink to initctl) is the thing sudo allows. Your issue here is that allowing people to run initctl you allow them to initctl everything.

Solution is though simple if your concern in merely a single job. Make a script, say /usr/bin/jobname.sh with

#!/bin/sh
initctl $1 jobname

then chmod 755 /usr/bin/jobname.sh and finally add that executable to your sudoers file:

%Group ALL = NOPASSWD: /usr/bin/jobname.sh

This way, everyone can call jobname.sh start or jobname.sh stop to control this specific job. You might want to add some checking to allow only start and stop parameters etc.

Tuminoid
  • 3,952
  • In other words, my issue isn't that the system denies group members the ability to run initctl, but that Upstart refuses any signals sent by users/groups not explicitly given an Allow policy entry in Upstart.conf? And there's no way to provide any more granularity than an all-jobs-or-none setting in the config file? – Angle O'Saxon Jan 09 '13 at 22:05
  • Initctl in your case is running fine even without sudoers change, Upstart is just refusing the messages from it if you don't specifically allow it for non-root users. See the other two answers. You can define dbus policy on per-job basis (see the com.ubuntu.Upstart0_6.<JOB> part) in the Upstart.conf. Depending on your needs, it might be simpler to make this kind of script for it instead of writing dbus policies and restarting dbus etc. Dbus policy is obviously the "right" thing to do, but depending on a case, simple script might go a long way with less trouble. – Tuminoid Jan 10 '13 at 06:34
  • Editing the DBus policy to use com.ubuntu.Upstart0_6.jobname as the send_interface produced the same error message as before. If I'm right in guessing that the error output contains the signal information, it looks interface or destination don't reflect the Upstart service that the signal refers to. I think that the service information is just arguments in the D-Bus method call message, and I'm not sure I can edit the D-Bus policy for Upstart to make decisions based on argument values. – Angle O'Saxon Jan 11 '13 at 01:17
  • A script of the sort you suggest is working pretty well for me, with one caveat: I've been needing to run it as sudo jobname.sh start, so that Upstart sees the request as coming from the root user.I'm making an effort to try to do this the "right" way (thus the move away from Sys-V scripts in the first place), so I'd like to get this working through a D-Bus policy or some other Upstart configuration option, but if I can't get that working I'll accept this answer. – Angle O'Saxon Jan 11 '13 at 01:23
  • Yes, you need to call it with sudo. The change in sudoers allows people to call the script as root to fix initctl requirements. If you implement this in production, please add checks for valid $1, or otherwise its huge security hole! At minimal [ "$1" = "start" -o "$1" = "stop" ] && initctl $1 jobname is required. – Tuminoid Jan 11 '13 at 06:30
  • 1
    I'd also quote "$1". With your [ "$1" = "start" -o "$1" = "stop" ] test I believe it's safe but unquoted $1 expansion in a script run as root is just unhealthy habit (unless word splitting is deliberately desired)... – Beni Cherniavsky-Paskin Jan 12 '16 at 09:13
0

As pointed above dbus daemon has a configuration file that specializes it for a particular application.

ls /etc/dbus-1/system.d/
avahi-dbus.conf
bluetooth.conf
...
Upstart.conf
wpa_supplicant.con

The configuration file also establishes resource limits, security parameters, and so forth.

For details see dbus-daemon-1(1) - Linux man page

To allow a group to start/stop Upstart jobs add following policy to /etc/dbus-1/system.d/Upstart.conf

  <policy group="YourGroupName">
    <allow send_destination="com.ubuntu.Upstart"
       send_interface="com.ubuntu.Upstart0_6.Job"
       send_type="method_call" send_member="Start" />
    <allow send_destination="com.ubuntu.Upstart"
       send_interface="com.ubuntu.Upstart0_6.Job"
       send_type="method_call" send_member="Stop" />
  </policy>

You should consider security implications of such policy before changing default policy. Members of the YourGroupName will be able to start/stop all Upstart jobs.

  • But is there a way to limit the jobs they can control? Or is that not possible because D-Bus doesn't pay attention to message content? – Angle O'Saxon Jan 09 '13 at 21:44
  • I tried adding that policy to Upstart.conf (replacing the groupname with my actual groupname), restarted D-Bus, and got start: You do not have permission to modify job: jobname when I tried to start the service. – Angle O'Saxon Jan 11 '13 at 00:53
  • OK. That means that policy is successfully applied. It appears that yourjob.conf is in /etc/init. User jobs should be in ~/.init. Is it plausible in your use case to place yourjob.conf in ~/.init? – Goran Miskovic Jan 11 '13 at 12:45
  • In regards of your first question: Policy defines which interfaces and members can be accessed. It does define which content/arguments can be sent/passed.

    Current restrictive policy has been eased down upstream. See cannot get upstart to run user job

    – Goran Miskovic Jan 11 '13 at 12:56