Linux – Managing per-user rc.d init scripts

delegationinitlinuxusers

I want to delegate SysV init scripts to each user.

Like the SysV init, each item in ${HOME}/rc.d starting with S will be launched on server start-up with the start argument. The same for the server shut-down with the one starting with K and with the stop argument.

I thought about scripting it myself, but maybe there is already some kind of implementation out there1. In summary it would be a script in /etc/init.d/ that iterates through all the users and launches runparts as the user on the relevant scripts.

The platform here is a Linux (Debian flavour), but I think the solution would be quite portable among various Unix-like platforms.

Update:

The point here is for users to be able to create their own init scripts that should be launch on their behalf when the system boots up. As Dan Carley pointed out, the services won't be able to access any system asset (priviledged ports, system logs, …).

1. This way I don't have to think that much about all the subtle security implications such as script timeouts for example…

Best Answer

Your question basically includes the answer.... A script that'll iterate through a subdir of each users home, looking for executable scripts. Then it sudo -u user /export/home/user/scripts/scriptname.sh start. You'll have no control over what the scripts do, so you`ll need to trust your users.

Insist that they write their scripts to accept stop start restart as $1 param and that they shouldn't use any environment variables that have been set up in their .profile, .cshrc or .bashrc files. The script effectively needs to be standalone.

#!/usr/bin/bash

run_cmd {
cd /export/home
for HOMEDIR in *; do
  for SCRIPT in /export/home/$HOMEDIR/scripts/*;  do
     if [ -x $SCRIPT ]; then
       echo "$ACTION user $HOMEDIR's script $SCRIPT"
       sudo -u $HOMEDIR $SCRIPT $ACTION &
     fi
  done
done

}

case $1 in
    start) ACTION=start;
           run_cmd;;
    stop) ACTION=stop;
           run_cmd;;
    restart) ACTION=stop;
             run_cmd;
             sleep 60;
             ACTION=start;
             run_cmd;;
    *) echo "$1 not recognized as valid cmd";;
esac

exit 0

You'll need to tweak this for your environment, location of bash/homedirs etc.