用于python脚本的setuid/setgid包装器 [英] setuid/setgid wrapper for python script
问题描述
我有一个Python脚本,希望能够以具有UID 200的系统用户guybrush
和具有GID 200的组guybrush
的身份运行.
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.
目前,我的Python脚本(位于/path/to/script.py
中)如下所示:
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()
我尝试的C包装程序(scriptwrap.c
)看起来像这样:
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);
}
然后,我按如下所示编译,整理和chmod包装器:
I then compile, chown, and chmod the wrapper as follows:
$ gcc scriptwrap.c -o scriptwrap
$ chown guybrush:guybrush scriptwrap
$ chmod 6755 scriptwrap
但是,当我运行scriptwrap时,会得到以下输出:
Yet when I run scriptwrap, I get the following output:
uid: 1000
euid: 1000
gid: 200
egid: 200
因此由于某种原因,仅设置了GID(我的常规UID是1000).我该怎么做才能解决此问题?
So for some reason only the GID is being set (my normal UID is 1000). What can I do to fix this?
编辑:如果我将脚本整理为root:root
并运行,则UID,eUID,GID和eGID都将设置为0.
If I chown the script to root:root
and run it, the UID, eUID, GID, and eGID are all set to 0.
此外,它在Ubuntu 12.04.4 LTS上.
Also, this is on Ubuntu 12.04.4 LTS.
推荐答案
好,我弄清楚了这一点(并在此过程中学到了点知识).令人尴尬的是,最初的问题是由我的Python脚本中的错字引起的:我正在打印出标签euid
下的GID,并打印出标签gid
下的eUID.糟糕!
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.
因此,实际上已正确设置了eUID和eGID-太好了.但是,尽管我在C包装程序中使用了setuid
和setgid
,但仍未设置UID和GID.
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.
事实证明,这是由于setuid
和setgid
的行为根据您是否为root
而有所不同的:如果您是root用户并调用setuid
,它将设置您的实际UID和您的有效UID可以传递给您传入的所有内容,如果您不是root
,它只是设置有效的UID(源).因此,我对setuid
(和setgid
)的使用基本上是无操作的.
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.
但是,可以通过使用setreuid
和setregid
调用来设置实际的UID和GID:
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);
}
(更正后的)Python脚本在运行时会产生以下输出:
Which results in the following output from the (corrected) Python script when run:
uid: 200
euid: 200
gid: 200
egid: 200
这篇关于用于python脚本的setuid/setgid包装器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!