C使用system()与execl()启动X11会话

纳迪尔

我创建了一个类似于守护程序的程序,在他对自己进行身份验证之后,它将在其自己的环境下为特定用户启动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] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章