c++ - 从系统 c++ 函数调用 shell 脚本,使 shell 脚本以不同的用户身份运行
问题描述
我正在使用系统 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; }
解决方案
一些文档开始:
从man 3 system的警告部分:
不要使用
system()
特权程序(set-user-ID 或 set-group-ID 程序,或具有功能的程序),因为某些环境变量的奇怪值可能会破坏系统完整性。例如,PATH
可以操纵任意程序以特权执行。改用exec(3)
函数族,但不使用execlp(3)
orexecvp(3)
(也使用PATH
环境变量来搜索可执行文件)。
system()
事实上,在/bin/sh
bash 版本 2 的系统上,具有 set-user-ID 或 set-group-ID 权限的程序无法正常工作:作为一项安全措施,bash 2 在启动时会放弃权限。Debian 使用不同的 shell,dash(1)
当作为 sh 调用时它不会这样做。)
并且来自bash 手册-p
对命令行参数的描述(添加了重点):
开启特权模式。在此模式下,不处理
$BASH_ENV
and$ENV
文件,不从环境继承 shell 函数,并且如果出现在环境中的 , 和 变量将被SHELLOPTS
忽略。如果 shell 以不等于真实用户(组)标识的有效用户(组)标识启动,并且未提供 -p 选项,则执行这些操作并将有效用户标识设置为真实用户标识。如果在启动时提供了 -p 选项,则不会重置有效用户 ID。关闭此选项会导致有效用户和组 ID 设置为真实用户和组 ID。BASHOPTS
CDPATH
GLOBIGNORE
因此,即使您/bin/sh
在运行时没有放弃特权,bash
也会在没有明确告诉它不要的情况下依次运行。
因此,一种选择是废弃使用system()
,并执行较低级别的fork()
/ exec()
。bash -p your-script-name
Allow suid on shell scripts中提到了允许脚本以提升的权限运行的其他一些方法。特别是setuid()
用于更改真实 UID 的答案看起来值得研究。
或者配置sudo
为不需要给定用户的特定脚本的密码。
推荐阅读
- firebase - admin.messaging().sendToDevice() 不工作 - Firebase 云消息传递
- python - Ubuntu bash 和 Anaconda 的兼容性
- python - 我如何将一些数据从 php 发送到 python
- php - 当 WHERE 参数为空或不存在时,如何取消 select 语句?
- javascript - firebase Query.orderBy* 返回无序列表
- dart - 调用 setState 后如何防止 Flutter 应用滚动到顶部?
- unity3d - 如何通过 Unity 3D 跨多个平台使用 Google 登录?
- java - 安装单个 Eclipse,同时使用不同的 JDK 安装或不同的 ini 配置启动会话
- tensorflow - Tensorflow - 在执行 mean_squared_error 损失函数时没有为任何变量提供梯度
- bash - 如何在bash中求和倒数?