问题
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.
回答1:
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
来源:https://stackoverflow.com/questions/24541427/setuid-setgid-wrapper-for-python-script