用于python脚本的setuid/setgid包装器

Dan*_*bbs 5 python permissions setuid wrapper elevated-privileges

我有一个Python脚本,我希望能够作为guybrush具有UID 200 的系统用户和guybrush具有GID 200的组运行.

目前我的Python脚本(位于/path/to/script.py)看起来像这样:

#!/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()
Run Code Online (Sandbox Code Playgroud)

我尝试过的C wrapper(scriptwrap.c)看起来像这样:

#include <unistd.h>
#include <sys/types.h>

int main(int argc, char *argv[]) {
    setuid(geteuid());
    setgid(getegid());
    return execv("/path/to/script.py", argv);
}
Run Code Online (Sandbox Code Playgroud)

然后我按如下方式编译,chown和chmod包装器:

$ gcc scriptwrap.c -o scriptwrap
$ chown guybrush:guybrush scriptwrap
$ chmod 6755 scriptwrap
Run Code Online (Sandbox Code Playgroud)

然而,当我运行scriptwrap时,我得到以下输出:

uid: 1000
euid: 1000
gid: 200
egid: 200
Run Code Online (Sandbox Code Playgroud)

所以出于某种原因只设置了GID(我的普通UID是1000).我该怎么做才能解决这个问题?

编辑:如果我将脚本chown root:root并运行它,UID,eUID,GID和eGID都设置为0.

此外,这是在Ubuntu 12.04.4 LTS上.

Dan*_*bbs 5

好吧,我想出来了(并在此过程中学到了一点).令人尴尬的是,我的初始问题是由我的Python脚本中的拼写引起的:我在标签下打印出GID,标签下面euid是eUID gid.哎呀.

所以eUID和eGID实际设置正确 - 很棒.但是,尽管我在C包装器中使用了setuid和UID,但仍然没有设置UID和GID setgid.

事实证明,这是由于你的行为setuidsetgid不同而不同root:如果你是root并且你打电话setuid,它会将你的真实UID和你的有效UID设置为你传递给它的任何东西,如果你不是root它只需设置有效的UID().所以我对setuid(和setgid)的使用基本上都是无操作.

但是,可以使用setreuidsetregid调用来设置真实的UID和GID :

#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);
}
Run Code Online (Sandbox Code Playgroud)

这导致运行时(更正的)Python脚本的以下输出:

uid: 200
euid: 200
gid: 200
egid: 200
Run Code Online (Sandbox Code Playgroud)