I have a Python script that I wish to be able to be run as the system user guybrush
with UID 200 and group guybrush
with GID 200.
At the moment my Python script (located in /path/to/script.py
) looks like this:
#!/usr/bin/env python2
import os
print "uid: %s" % os.getuid()
print "euid: %s" % os.getgid()
print "gid: %s" % os.geteuid()
print "egid: %s" % os.getegid()
My attempted C wrapper (scriptwrap.c
) looks like this:
#include <unistd.h>
#include <sys/types.h>
int main(int argc, char *argv[]) {
setuid(geteuid());
setgid(getegid());
return execv("/path/to/script.py", argv);
}
I then compile, chown, and chmod the wrapper as follows:
$ gcc scriptwrap.c -o scriptwrap
$ chown guybrush:guybrush scriptwrap
$ chmod 6755 scriptwrap
Yet when I run scriptwrap, I get the following output:
uid: 1000
euid: 1000
gid: 200
egid: 200
So for some reason only the GID is being set (my normal UID is 1000). What can I do to fix this?
Edit: If I chown the script to root:root
and run it, the UID, eUID, GID, and eGID are all set to 0.
Also, this is on Ubuntu 12.04.4 LTS.
The setuid bit simply indicates that when running the executable, it will set its permissions to that of the user who created it (owner), instead of setting it to the user who launched it.
Setuid is a Linux file permission setting that allows a user to execute that file or program with the permission of the owner of that file. This is primarily used to elevate the privileges of the current user.
setuid: a bit that makes an executable run with the privileges of the owner of the file. setgid: a bit that makes an executable run with the privileges of the group of the file. sticky bit: a bit set on directories that allows only the owner or root can delete files and subdirectories.
setuid and setgid files are dangerous because they might give an unauthorized user root access, or at least access to run a program in another user's name. To make a program setuid root, the user must be root.
Well I figured this out (and learnt a bit in the process). Embarrassingly my initial problem was caused by a typo in my Python script: I was printing out the GID under the label euid
, and the eUID under the label gid
. Oops.
So the eUID and eGID are actually set correctly - great. But the UID and GID still aren't set despite my use of setuid
and setgid
in the C wrapper.
It turns out that this is due to the behaviour of setuid
and setgid
differing based on whether you are root
or not: If you are root and you call setuid
, it sets your real UID and your effective UID to whatever you pass it in, if you are not root
it just sets the effective UID (source). So my use of setuid
(and setgid
) are essentially no-ops.
However it is possible to set the real UID and GID by using the setreuid
and setregid
calls:
#include <unistd.h>
#include <sys/types.h>
int main(int argc, char *argv[]) {
setreuid(geteuid(), geteuid());
setregid(getegid(), getegid());
return execv("/path/to/script.py", argv);
}
Which results in the following output from the (corrected) Python script when run:
uid: 200
euid: 200
gid: 200
egid: 200
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With