我的自定义程序以非 root 权限执行,用户 ID 为:uid: 1000 euid: 0
其中在 fork() 之后,在子进程中调用 execv() 以运行 SSH 客户端服务。由于我在非特权用户下启动程序,当尝试将套接字绑定到设备时,Linux 内核会执行所有权限检查,导致子程序sock_setbindtodevice()
在检查CAP_NET_RAW
功能时失败,如下所示。
我当时考虑的解决方案是先在子进程中获取root权限,进行设置所需能力等特权操作,然后回退到非root。
这里的一个问题是,需要下拉到非 root 用户,因为当执行 ssh 命令时,我希望生成的DSA/RSA
密钥存储在$HOME/.ssh/known_hosts
而不是root/.ssh/known_hosts
.
请在下面找到代码片段:
void
global_exec_func (const char *proc_name, const char *proc_path, char **arg_list)
{
pid_t pid;
int status, euid;
struct __user_cap_header_struct cap_header_data;
cap_user_header_t cap_header = &cap_header_data;
struct __user_cap_data_struct cap_data_data;
cap_user_data_t cap_data = &cap_data_data;
pid = fork();
if (pid < 0) {
printf("%% can't fork process %s", proc_name);
return;
}
/*
* Child process.
*/
if (pid == 0) {
euid = geteuid(); /* Storing euid */
/*Gaining root privileges */
if (setuid(0) < 0) {
printf("setuid(0) failed");
}
printf("After setting: getuid: %d geteuid: %d\n", getuid(),
geteuid());
cap_header->pid = 0;
cap_header->version = _LINUX_CAPABILITY_VERSION;
/* Get the capabilities */
if(capget(cap_header, cap_data) < 0) {
printf("failed capget error:%s", strerror(errno));
}
cap_data->effective = (1 << CAP_NET_RAW); /* Set bit 13 */
cap_data->inheritable = 0;
/* Set the capabilities */
if (capset(cap_header, cap_data) < 0) {
printf("failed capset error:%s", strerror(errno));
}
/* Drop back privileges */
if (seteuid(euid) < 0) {
printf("seteuid(euid) failed");
}
printf("After drop: getuid: %d geteuid: %d\n", getuid(), geteuid());
prctl(PR_SET_KEEPCAPS, 1);
execv(proc_path, arg_list);
exit(1);
}
/*
* Parent Process code follows
*/
Result:
[local]linux#ssh 101.1.1.101
After setting: getuid: 0 geteuid: 0
After drop: getuid: 0 geteuid: 0
The authenticity of host '101.1.1.101 (101.1.1.101)' can't be established.
DSA key fingerprint is 0c:61:df:01:93:74:1f:5f:49:34:f4:4e:06:e8:d7:5f.
Are you sure you want to continue connecting (yes/no)? ^C
[local]linux#
结果显示 ssh 成功,但此时程序以 a 方式运行root
,这是不正确的。如何返回 UID,uid: 1000 euid: 0
以便将 ssh 密钥存储在正确的目录中。
请对我的解决方案发表评论和建议,它真的解决了问题吗?