Linux C编程以用户身份执行

15

我有一个以root身份运行的程序,我希望该程序能够执行另一个普通用户的应用程序。我尝试使用setgid(),它可以工作,但是我无法切换回root或其他用户。目前这个程序非常简单。

 #include <stdio.h>
 #include <unistd.h>
 #include <stdlib.h>

 int main(int argc, char *argv[] )
 {
     if ( argc != 2) {
         printf("usage: %s command\n",argv[0]);
         exit(1);
     }
     setgid(100);
     setuid(1000);
     putenv("HOME=/home/caroline");
     putenv("DISPLAY=:0");
     system(argv[1]);
     seteuid(1001);
     putenv("HOME=/home/john");
     putenv("DISPLAY=:1");
     system(argv[1]);
     return 0;
 }

我该怎么做?就像命令行中的操作su $user -c $command一样。

3个回答

14
如果你使用fork+exec,你可以在父进程中保持为root的同时改变子进程的euid。 代码可能如下所示:
 #include <stdio.h>
 #include <unistd.h>
 #include <stdlib.h>

 int runAs(int gid, int uid, char **env, char *command) {
   int status;
   int child = fork();
   if (child == 0) {
    setgid(gid);
     setuid(uid);
     do {
       putenv(*env);
       env++;
     } while (env != null);
     exec(command);
   } else if (child > 0) {
    waitpid(child,&status,WUNTRACED | WCONTINUED);
   } else {
     // Error: fork() failed!
   }
 }
       

 int main(int argc, char *argv[] )
 {
     char *env[3];
     if ( argc != 2) {
         printf("usage: %s command\n",argv[0]);
         exit(1);
     }
     env[0] = "HOME=/home/caroline";
     env[1] = "DISPLAY=:0";
     env[2] = NULL;
     runAs(100, 1000, env, argv[1]);

     env[0] = "HOME=/home/john";
     env[1] = "DISPLAY=:1";
     runAs(100, 1001, env, argv[1]);
     return 0;
 }

4

如果您想以普通用户身份执行一件事情,而以 root 身份执行其他事情,则可以始终在子进程中进行分叉和设置 setuid,使您希望不具有 root 特权的部分程序保持其特权,同时为程序的其他部分保留它们。


2

来自setuid手册:[如果调用者是root]程序无法重新获得root特权

你想做什么?你可以将SUID位设置到你的程序中,并以用户身份运行它,然后你可以使用seteuid暂时放弃root权限并成为调用用户,然后再次重置权限。如果你真的必须以root身份运行它 - 我猜你应该fork(),将一个进程留作root,另一个进程作为setuid()。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接