11

I need to allow users in the dba group to control the database@ services. The answer to this related question is to just list all systemctl "verbs" that I want to allow in the sudoers file, however, that does not apply to my case because I don't know beforehand what databases might exist in the system. For example, if I list

%dba = /usr/bin/systemctl start database@awsesomeapp
%dba = /usr/bin/systemctl start database@anotherawsesomeapp
%dba = /usr/bin/systemctl start database@yetanotherawsesomeapp
%dba = /usr/bin/systemctl start database@wowyetanotherawsesomeapp
# ... other "verbs" omitted for brevity

that doesn't cover instances that might exist in the future, and a dba won't be able to

$ sudo systemctl start database@omgwowyetanotherawsesomeapp

Anyway, I'm thtinking more in terms of packaging than in fidling with a specific system.

Note that, as shown in this amazing answer to another related question, using sudo globs for this is ultimately insecure:

%dba ALL = /usr/bin/systemctl start database@[a-z]* # UNSAFE!

does allow

$ sudo systemctl start database@awsesomeapp unrelatedservice

I suspect using sudo is not going to solve my problem (although I sure hope I'm wrong). Is there any other way to allow non-root users to control systemd services?

For what it's worth, I need to do this in a CentOS 7 system, and RHEL7 systems in the future. I would also be interested in solutions that work on Arch Linux.

1

Sudoers file won't work like that, or so it seems to me. Sudoers file is intended to give a specific command access, not to the specify the arguments that can go with that command.

Create a script that runs as root and executes this:

/usr/bin/systemctl start database@

Make the script take an argument such as anotherawesomeapp so it executes this:

Script executes: /usr/bin/systemctl start database@anotherawsesomeapp

Give your users permission to run the script.sh file with /etc/sudoers.

scriptuser ALL=(ALL) NOPASSWD: /path/to/script.sh

User can run it like this:

sh script.sh anotherawsesomeapp

Example:

AppName=$1

/usr/bin/systemctl start database@$AppName;
if [ $? != "0" ] 
then; 
    echo "$AppName could not be started. Are you using the right application name?";
fi
  • 1
    As-is this has the same issues as the sudoers one. You need to quote the variable or it will be split on spaces. – kyrias Apr 17 '15 at 15:19
  • This is not going to work; setuid is not honoured for shell scripts (on Linux). – Martijn Jul 28 '15 at 9:32
  • All it is doing is using sudo to execute a script. It is not any different than the same with a 'hello world' script. If root can run the script, it will work. – Baazigar Aug 3 '15 at 14:43
0

A proposed solution based on SUID

You could create the said script that calls systemctl with sudo. Make the script owned by root. Provide SUID permission to root and read and execute permissions to the group of database administrators (dba).
Just be careful not to provide write permission to the group or to others because that way they may change the script and make it execute anything preceded with sudo! Also make sure the script is bullet-proof input-wise.

$ cat >> start_database.sh
sudo /usr/bin/systemctl start database@$1
(Ctrl+D)

This script could be improved by checking if the argument is indeed supplied and print a Usage: message if not..., also since it is a script with SUID it would be appropriate to check for ; to avoid the injection of other commands following the argument. Or even better make sure to allow as input only one of the app related strings you mentioned!
Then you must make sure the permissions for the script are strictly the following:

$ sudo chown root:dba start_database.sh
$ sudo chmod u-x,g-w,o-rwx start_database.sh
$ sudo chmod u+s,g+rx start_database.sh

Then to verify the correct permissions:

$ls -la
.
.
.
-rwSr-x--- 1 root dba       35 Aug  2 19:11 start_database.sh
.
.
.

So, to recap:

1. the owner of the script is root
2. the file can be read and executed by the dba group members
3. no-one else will be able to even read it.
4. SUID will enable the user that executes the script to become root as long as the script is executed.
5. So sudo will not stop for a password.

In any case, in a system with multiple users, be very careful with SUID because it may leave room for permission abuse.

  • You are missing a shebang in your script and even then, SUID will not work for scripts by default. – Jan Tojnar Nov 3 '17 at 12:34

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.