Linux中让特殊权限(SUID)对Python脚本生效

本文介绍了如何在Linux系统中使Python脚本具备特殊权限(SUID),通常此权限仅对C/C++编译程序有效。通过一个名为`suid-python`的C源代码实现,经过修改、编译和授权步骤,使得Python脚本可以在非所有者权限下执行特定操作,如创建文件夹。同时,文章提供了测试脚本`test.py`的编写和授权过程,强调了正确配置文件和目录权限的重要性。
摘要由CSDN通过智能技术生成

Linux中让特殊权限(SUID)对Python脚本生效

通常情况下,我们需要用Python写一些脚本对项目文件做管理,而这样的文件管理是必然附带特殊权限的。通常的处理方法是RPC。但是首先RPC写起来还是挺麻烦的,其次对于存储池来说,RPC服务器在处理完指定数据后客户端往往需要一段不短的时间来等待数据在存储节点间的同步。由此,我希望能使用SUID来直接在客户端执行脚本。但很显然,SUID通常只能对C/C++等编译出来的程序生效,对Python脚本是无效的,除非你打算给/usr/bin/python设置SUID——那就相当于完全开放权限了。为此,我在网上找了很久,终于找到了一个可行的方案。

suid-python

我在StackOverflow上找到了这个问题:Semantics of SUID (Set-User-ID),该问题下方有人贴上了一个C的源代码:suid-python.c,我惊喜的发现它可以完全满足我的需求。我先把源代码贴上来。

/* suid-python version 0.95
 *   by Steven Elliott <selliott4@austin.rr.com>
 *
 * A program to securely run Python scripts with the setuid bits set on the
 * script applied to the resulting Python process as if the Python script was
 * an executable.  This utility could probably be easily adapted to other
 * scripting languages.
 *
 * Install this program by building it with
 *   gcc -o suid-python suid-python.c
 * then copy it to a secure directory
 *   cp suid-python /usr/local/bin
 * and then set the ownership to root setuid bit
 *   chown root.root suid-python
 *   chmod 755 suid-python
 *   chmod u+s suid-python
 *
 * Try it by creating a secure Python script that starts with
 *   #!/usr/bin/env suid-python
 * that is to run as a user other than the invoking user.  Set that user and
 * corresponding setuid bits, and then run it.
 *
 * This program is subject to the same open source license as Python:
 *   http://www.python.org/2.4.2/license.html
 */

#include <errno.h>
#include <libgen.h>
#include <pwd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>

/* Defines */

/* Flags.  There are to be used with "#if", not "#ifdef".  These are all off
 * since there are security problems with each one.
 */
#define ISEC_ALLOWED     0      /* Isecure directories. */
#define STICKY_ALLOWED   0      /* Consider sticky bits, such as /tmp */
#define SWITCHES_ALLOWED 0      /* Python switches, such as -i */

#define NOBODY "nobody"
#define PYTHON "python"
#define SAFE_PATH "PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:" \
                  "/usr/sbin:/usr/bin:/usr/X11R6/bin"

/* Globals */

/* Harmful environment variables on Linux.  Other OSs may have other 
 * variables.
 */
static char *bad_prefixes[] = {
    "IFS", "LD_", "PATH", "PYTHON", NULL };

/* Directories that are likely to be trusted (directories that are likely to
 * be local and that don't have the "nosuid" mount option set).
 */
#if ! ISEC_ALLOWED
static char *trusted_dirs[] = {
    "/bin/", "/boot/", "/etc/", "/lib/", "/opt/",
    "/root/", "/sbin/", "/usr/", NULL
};
#endif

static gid_t script_gid;
static int script_sgid_set;
static int script_suid_set;
static uid_t script_uid;
struct stat script_stat;

void
usage(char *name)
{
   
    fprintf(stderr, "Usage: %s suid-script [arg1 [arg2 ..]]\n",
            basename(name));
}

/* Wrapper functions that abort when they fail. */

char *
getcwd_abort(char *buf, size_t size)
{
   
    char *cwd;

    cwd = getcwd(buf, size);
    if (!cwd)
    {
   
        fprintf(stderr, "Could not get the CWD of %s.  errno=%d\n",
                buf, errno);
        exit(1);
    }

    return cwd;
}

int
lstat_abort(const char *file_name, struct stat *buf)
{
   
    if (lstat(file_name, buf) == -1)
    {
   
        fprintf(stderr, "Could not lstat %s.  errno=%d\n", file_name, errno);
        exit(1);
    }

    return 0;
}

void *
malloc_abort(size_t size)
{
   
    void *buf;

    buf = malloc(size);
    if (!buf)
    {
   
 
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值