我创建了一个类似于守护程序的程序,在他对自己进行身份验证之后,它将在其自己的环境下为特定用户启动X11会话。
第一种方法是使用命令using system()
,其中我将模拟用户并按如下所示启动x11会话:
std::string cmd = "echo daemonuserpwd | sudo -S su " + unixUser + " -c 'xinit -- :4' &";
system(cmd.c_str());
这可以正常工作,并调用.xinitrc
位于用户主目录中的文件,这是必不可少的步骤,因为我使用它来启动所需的程序,而这些程序正是我在其中运行应用程序所需的。
但是,我读到有关的问题system()
,因此我尝试进一步介绍并使用fork创建用户环境,并使用来启动会话execl()
,如下所示:
int child = fork();
if(child == 0)
{
struct passwd * userInfo = getpwnam(unixUser.c_str());
setgid(userInfo->pw_gid);
setuid(userInfo->pw_uid);
system("whoami");
execl("/usr/bin/xinit", "xinit", "--", ":4", (char*)0);
//system("xinit -- :4");
}
这也可以,debugging命令system("whoami");
说的是正确的用户。X11会话已启动,但是.xinitrc
从fork进程启动会话时不会调用该文件。设置用户环境后,我还尝试通过系统执行命令,结果相同(两个选项均调用中的默认值xinitrc
)/etc/X11/xinit/xinitrc
。
.xinitrc
使用该fork()
方法时,是否也为了使文件被调用而丢失了某些内容?
免责声明:使用libpam执行用户身份验证,并且正确清理了用户输入以防止注入。
编辑:使用execle
@LieRyan建议的最终解决方法:
struct passwd * userInfo = getpwnam(unixUser.c_str());
char buf[0xff];
sprintf(buf, "HOME=%s", userInfo->pw_dir);
char *env[] = {buf, NULL};
execle("/usr/bin/sudo", "sudo", "-u", unixUser.c_str(), "xinit", "--", ":4", (char*)0, env);
调用setuid
该进程所属的更改,但不会更改该用户登录$HOME
后将设置的环境变量,因此不会指向正确的位置来获取“ .xinitrc”文件。
以下代码行应为您解决此问题。
setenv("HOME",userInfo->pw_dir,1);
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句