setuid/setgid wrapper for python script

北城余情 提交于 2019-12-10 13:54:01

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!