5

I have some bash scripts that I use with the user 'root' to manage iptable rules.

The problem is that I want these things at the same time:

  • The script must be owned by root
  • Permissions must be 700
  • I want to have an executable binary that certain user can execute. This executable will run the mentioned script as root.

This used to work, and is still what I use in older distributions:

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>

int main()
{
   setuid(0);
   system("/root/iptables/my-iptables-script.sh");

   return 0;
}

So I compile this and then use sudo chown root and sudo chmod 4777. This way the user can now execute the binary and run the script owned by root.

But now I installed Ubuntu 13.10 and when I run that binary I get "permission denied" for the script.

Is it possible that something changed in this respect since 12.04?

What can I do?

X Tian
  • 10,463
  • can you run the script without the C program? – Braiam Feb 26 '14 at 21:42
  • @Braiam Yes, as root. – ChocoDeveloper Feb 26 '14 at 21:52
  • What happens if you try to run the binary as root? If the error remains then run it as: strace -f -e trace=process /path/to/binary What is the shebang line of the script? – Hauke Laging Feb 26 '14 at 22:11
  • @HaukeLaging The binary works fine as root. The shebang of the scripts is #!/bin/sh – ChocoDeveloper Feb 26 '14 at 22:19
  • See the duplicate I referenced, it offers several ways to get around this, bottom line, shell scripts cannot be setuid! – slm Feb 26 '14 at 22:22
  • @slm I'm not using setuid on a shell script, I'm using it on a binary. And it works fine on Ubuntu 12.04 and Fedora 17. The solution in your link says to write native code. – ChocoDeveloper Feb 26 '14 at 22:33
  • @slm I didn't read the whole thing, tell me if I'm wrong. – ChocoDeveloper Feb 26 '14 at 22:34
  • 1
    @ChocoDeveloper Then change the binary to: system("strace -f -o /root/iptables/script.strace /root/iptables/my-iptables-script.sh"); and give us the content of script.strace. – Hauke Laging Feb 26 '14 at 22:35
  • @HaukeLaging I get this in the cli: strace: Can't stat '/root/iptables/my-iptables-script.sh': Permission denied – ChocoDeveloper Feb 26 '14 at 22:50
  • @HaukeLaging script.strace is empty, understandably (I also tried placing it in my own folder just in case, instead of a root folder) – ChocoDeveloper Feb 26 '14 at 22:52
  • @HaukeLaging Does it make sense to the see the strace generated when running the binary as root? I never used strace before to be honest. – ChocoDeveloper Feb 26 '14 at 22:57
  • 1
    Is your underlying filesystem mounted nosuid? mount | grep nosuid? – slm Feb 26 '14 at 23:10
  • @ChocoDeveloper If strace cannot stat the script file then the binary does obviously not run as root. Either your sudo chmod 4777 did not work or the SUID bit was reset by a non-root user writing to the file or (as slm indicates) the binary resides on a nosuid filesystem. You may add a message to the binary which tells the user the RUID and EUID (after setuid(0)). – Hauke Laging Feb 26 '14 at 23:15
  • @slm Not sure, I think it's not: http://pastebin.com/3aQ48Kr0 . I'm on /home/myuser/somefolder – ChocoDeveloper Feb 26 '14 at 23:15
  • Confirm where the script and executable are with this type of command: df -h /path/to/file. – slm Feb 26 '14 at 23:17
  • @ChocoDeveloper You think /home/myuser/Encryptor [...] (rw,nosuid,nodev is not mounted nosuid, really? – Hauke Laging Feb 26 '14 at 23:17
  • @HaukeLaging That's not the folder I'm on. – ChocoDeveloper Feb 26 '14 at 23:18
  • @slm df says the binary is in filesystem /home/myuser/.Private mounted on /home/myuser, and the script is in filesystem /dev/mapper/ubuntu--vg-root mounted on / – ChocoDeveloper Feb 26 '14 at 23:22
  • For security reasons, no script should run SUID (it isjust too easy to break in). – vonbrand Feb 26 '14 at 23:40
  • @vonbrand But I'm using SUID in a binary. Are you saying that's bad too? – ChocoDeveloper Feb 26 '14 at 23:43

1 Answers1

6

The easiest and cleanest solution is probably to use sudo.

You can configure it to allow a given unix group to run exactly this script as root.

%iptablegroup ALL = (root) NOPASSWD: /path/to/script 

Then all you have to do is add the needed users to that group and everything should be fine.

michas
  • 21,510
  • But I need to run this programatically. I can't use sudo because I won't be there to type in my password. And I don't want to disable the password for sudo. Can I disable it for just this script? – ChocoDeveloper Feb 26 '14 at 23:10
  • Sure you can. I just changed the answer to do so. See man sudoers for lots of examples. – michas Feb 26 '14 at 23:21