如何以root权限执行命令

6

我在Linux (Debian)上开发C代码。有时,我需要通过system()执行一些命令。

我想知道是否可以通过system()以root身份执行命令。如果不行,是否有任何函数可以在C代码中以root身份执行命令(或运行二进制文件)?


8
全球的Unix和Linux用户最好不要抱有希望。 - Crowman
如果任何用户都可以在没有额外授权的情况下以root身份执行代码,那么区分不同用户有什么意义呢? - phoeagon
3个回答

4
"We have encountered situations where we need to execute root commands as a normal user. Here is our solution, which involves using setuid/SUID.
Assuming the following: - Username: Tom - Group: gTom - C program file name: my_pro.c
Step 1: Write a C code tool named my_sudo.c."
...
int main(int args, char *argv[]) {
    if (args < 2) 
        printf("Usage: my_sudo [cmd] [arg1 arg2 ...]");

    // cmd here is the shell cmd that you want execute in "my_pro"
    // you can check the shell cmd privilege here
    // example:  if (argv[1] != "yum") return; we just allow yum execute here

    char cmd[MAX_CMD];
    int i;
    for ( i = 2; i < args; i ++) {
    // concatenate the cmd, example: "yum install xxxxx"
        strcat(cmd, " ");
        strcat(cmd, argv[i]);
    }

    system(cmd);
} 

步骤二:编译my_sudo.c获取my_sudo的可执行文件

   sudo chown root:gTom my_sudo   // user root && gTom group
   sudo chmod 4550 my_sudo        // use SUID to get root privilege

   #you will see my_sudo like this(ls -l)
   #-r-sr-x--- 1 root my_sudo 9028 Jul 19 10:09 my_sudo*

   #assume we put my_sudo to /usr/sbin/my_sudo

步骤三:在您的 C 代码中

...
int main() {
    ...
    system("/usr/bin/mysudo yum install xxxxx");
    ...
}

#gcc && ls -l
#-rwxr--r--  1 Tom gTom 1895797 Jul 23 13:55 my_pro

步骤四:执行./my_pro

您可以在不使用sudo的情况下执行yum install命令。


6
哎呀!你正在将参数连接成一个shell命令行!那么用户可以使用mysudo 'arg;sh'来获得root shell。而且你没有像sudo那样对环境进行净化。 - Stephane Chazelas

1
如果您是系统上具有sudo权限以作为root运行命令的用户,则只需在命令前加上sudo即可。
system("sudo yum install some-package");

如果您希望任何人都能够执行此操作,则必须在系统上担任管理员角色,将文件的所有者更改为root,并修改可执行文件的权限以作为root运行。这样做可以避免使用sudo修改system()命令字符串。
chmod +s my_program
chown root my_program

请注意,这样做可能会使您面临安全问题,除非您已经证明您的程序没有安全问题。
文件系统可能不允许您在程序上设置setuid位。如果您需要更多类似的信息,请参考SuperUser

我知道可以将可执行程序作为Root运行,这样程序就具有Root特权来调用函数。但是我想知道,在程序以非Root身份启动时,是否有可能通过使用C或Posix函数获取Root特权来执行命令。 - Angs
我已经更新了关于如何以root运行程序的答案。Johnathan是正确的,除非因为安全风险否则不应这样做。 - jxh
@jxh:这不是我要求的。如果程序已经具有root权限,那么使用system就不会有任何问题。我问的是是否有函数可以作为root执行命令或运行程序(假设程序以非root身份启动)。 - Angs
1
除非程序最初是以 root 启动并因此具有 root 的保存 UID,否则没有任何 函数 可以将 EUID 从非 root 更改为 root。请参阅 getuid()setuid() 以及相关内容获取更多信息。在要执行的命令前加上 sudo 程序是几乎唯一可行的方法。(还有各种不太正常的方法,但作为 root 运行的程序是风险,大风险)。 - Jonathan Leffler
@angs:如果你想要一个“安全”的解决方案,你必须审查所有将作为root调用system()的程序。然后,你可以在系统上创建一个新用户,专门用于运行这个程序。你可以将这个新用户添加到sudo列表中,无需输入密码,但需要指定允许运行的命令。此列表应与你的程序将调用的system()命令相匹配。然后,在你的system()命令之前加上sudo并设置可执行文件的setuid位,并将其chown给新用户。 - jxh
显示剩余7条评论

1
这是需要记住的一些技巧之一。存在安全风险,所以请注意谁会使用它。在“system”命令中,甚至可以执行外部脚本……尽管这会带来重大的安全风险,因为虽然每次编译此二进制文件时必须重新设置权限,但脚本可以无限更改并且此二进制文件将继续调用它。
#include <stdio.h>
#include <stdlib.h>

//Create as root
//gcc fixmusic.c -o fixmusic 
//chmod u+s fixmusic
//now run as non-root user and it should work despite limitations of user


int main(int argc, char *argv[] )
{

    setuid(0);

    char command[100];
    sprintf(command,"/usr/bin/chmod -R a+w /mnt/Local/Music");
    system(command);
    //This is just optional info if someone cat's the binary
    volatile const char comment [] = "INFO: Fixes music permissions";
    return 0;
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接