【问题标题】:Calling shell script from system c++ function making the shell script running as different user从系统 c++ 函数调用 shell 脚本使 shell 脚本以不同的用户身份运行
【发布时间】:2021-06-14 15:53:41
【问题描述】:

我正在使用系统 c++ 调用来执行调用程序以 root 身份运行的 shell 脚本,但是从 c++ 代码调用的 shell sctipt 以不同的用户身份运行。

如何确保 shell 脚本也应该像 c++ 二进制文件一样以 root 用户身份运行。 我不想依赖使用 sudo 命令,因为它可以要求输入密码。

> [user@user ~]$ ll a.out temp.sh
> -rwsrwsr-x 1 root     root     8952 Jun 14 13:16 a.out
> -rwxrwxr-x 1 user     user   34 Jun 14 15:43 temp.sh
[user@user ~]$ cat temp.sh

#!/bin/bash read -n 1 -p "Hello"

[user@user ~]$ ps aux | grep temp 
root     13247  0.0  0.0  13252 1540 pts/0    S+   15:44   0:00 ./a.out ./temp.sh 
user 13248  0.0  0.0 113152  2544 pts/0    S+   15:44   0:00 /bin/bash ./temp.sh 

c++代码

#include <bits/stdc++.h>
using namespace std;
int main(int argc, char *argv[])
{
system(argv[1]);
return 0;
}

【问题讨论】:

    标签: c++ linux bash shell


    【解决方案1】:

    一些文档开始:

    来自man 3 system 的警告部分:

    不要在特权程序(set-user-ID 或 set-group-ID 程序,或具有功能的程序)中使用system(),因为某些环境变量的奇怪值可能会被用来破坏系统完整性。例如,PATH 可以被操纵,以便以特权执行任意程序。请改用exec(3) 系列函数,但不要使用execlp(3)execvp(3)(它们也使用PATH 环境变量来搜索可执行文件)。

    system() 事实上,在/bin/sh 是 bash 版本 2 的系统上,具有 set-user-ID 或 set-group-ID 权限的程序无法正常工作:作为安全措施,bash 2 放弃了权限在启动时。 Debian 使用不同的 shell,dash(1),它在作为 sh 调用时不会这样做。)

    以及来自the bash manual's-p 命令行参数的描述(已添加重点):

    开启特权模式。在这种模式下,$BASH_ENV$ENV 文件不被处理,shell 函数不从环境继承,SHELLOPTSBASHOPTSCDPATHGLOBIGNORE 变量,如果它们出现在环境,无视。 如果 shell 以不等于真实用户(组)id 的有效用户(组)id 启动,并且未提供 -p 选项,则执行这些操作并将有效用户 id 设置为真实用户(组)id用户身份。如果在启动时提供了 -p 选项,则不会重置有效用户 ID。 关闭此选项会导致将有效用户和组 ID 设置为真实用户和组 ID。

    因此,即使您的/bin/sh 在运行时没有放弃特权,bash 在它运行时也会在没有明确告诉它不要的情况下依次运行。

    因此,一种选择是使用system() 废弃,并使用bash -p your-script-name 的较低级别的fork()/exec()

    Allow suid on shell scripts 中提到了允许脚本以提升的权限运行的其他一些方法。特别是使用 setuid() 更改真实 UID 的答案看起来值得研究。

    或将sudo 配置为不需要为给定用户的特定脚本提供密码。


    另见Why should I not #include &lt;bits/stdc++.h&gt;?

    【讨论】:

    • 使用 fork 并使用父级的有效 uid 设置真实的 uid(设置了 setuid 字段时,父级的 euid = 0),然后调用 execl 函数来调用 shell 脚本可以完成工作,不确定如果这是正确的方法,但它正在工作并且 shell scipt 以 root 身份运行(euid = realui = 0)。这是根据您提到的声明,我确实使子进程的 euid 等于 realuid。
    猜你喜欢
    • 2011-03-10
    • 1970-01-01
    • 2018-01-20
    • 2018-05-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多