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,413
  • 2
  • 33
  • 48
ChocoDeveloper
  • 345
  • 1
  • 5
  • 10
  • 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,190
  • 4
  • 63
  • 93
  • 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