systemctl - 从 setuid root 程序运行“systemctl restart ___”而不询问 root 密码?
问题描述
我正在为运行 Linux (CentOS 8) 的网络设备进行开发,对于 VGA 控制台上的一些非常基本的配置,我们设置了一个锁定的用户帐户。我们提供了几个 suid root 程序,它们可以设置 IP 地址和配置 NTP。(所有其他设置都是通过 Apache 和一些网页完成的。)
我们需要从这些程序中做的一些事情是重新启动 NetworkManager.service、重新启动 chronyd.service、断电和重新启动。poweroff 和 reboot 都很好用,但重新启动服务却不行。相反,我们得到这个:
Restarting ntp service
==== AUTHENTICATING FOR org.freedesktop.systemd1.manage-units ====
Authentication is required to restart 'chronyd.service'.
Authenticating as: root
Password:
我猜 systemctl 正在尝试对身份验证进行智能处理,并且能够检测到运行它的用户不是 root,即使它具有 root 权限。有什么方法可以更改用户 ID,以便 systemctl 事情是它的根调用它?
作为参考,我已将完整源代码附加到下面的 suid 根程序之一。
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
void print_usage()
{
printf("Usage: safeguard <option>\n");
printf("Options:\n");
printf(" poweroff\n");
printf(" reboot\n");
printf(" ntp [restarts NTP service]\n");
printf(" net [restarts NetworkManager service]\n");
}
int main(int argc, char *argv[])
{
if (argc < 2) {
print_usage();
return 0;
}
if (0==strcmp(argv[1], "poweroff")) {
printf("Executing poweroff\n");
system("poweroff");
return 0;
} else if (0==strcmp(argv[1], "reboot")) {
printf("Executing reboot\n");
system("reboot");
return 0;
} else if (0==strcmp(argv[1], "ntp")) {
printf("Restarting ntp service\n");
system("systemctl restart chronyd.service");
return 0;
} else if (0==strcmp(argv[1], "net")) {
printf("Restarting NetworkManager service\n");
system("systemctl restart NetworkManager.service");
return 0;
}
print_usage();
return 0;
}
解决方案
我想到了。我必须添加以下代码才能将“真实用户 ID”更改为与“有效用户 ID”相同。
uid_t uid, euid, suid;
getresuid(&uid, &euid, &suid);
setresuid(euid, euid, suid);
推荐阅读
- node.js - 如何添加到集合顶部/从集合底部删除(猫鼬)?
- c# - 使用选择元素 ASP.NET Core MVC 中的属性保存父项和子项
- python - 在 Flask-sqlalchemy 中按订单号在 db 中对数据进行排序
- jitsi - 如果主持人设置了会议密码,Jibri 将无法录制
- python-3.x - 算法 python3 时间效率
- python - 根据条件在列中查找值
- c# - 我如何进行异步数字排序应用程序 WPF
- javascript - 为什么我不能让我的页面附加文本并出现在我的 HTML 页面上?
- c - Visual Studio 中的 ASCII 字符看起来很奇怪
- python - 使用python将嵌套的json文件更改为数据框