【问题标题】:Linux C programming execute as userLinux C 编程以用户身份执行
【发布时间】:2013-10-03 14:08:04
【问题描述】:

我有一个以 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的动作

【问题讨论】:

    标签: c linux su setuid


    【解决方案1】:

    如果您使用fork+exec,您可以更改子进程的euid,同时以root 身份留在父进程中。 代码可能如下所示:

     #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(100);
         setuid(1000);
         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;
     }
    

    【讨论】:

      【解决方案2】:

      如果您想以普通用户身份做一件事,而以 root 用户身份做另一件事,那么您始终可以在您不想拥有 root 权限的子进程中 fork 和 setuid,同时为程序的其他部分保留这些权限。

      【讨论】:

        【解决方案3】:

        来自 setuid 手册:[if caller was root] it is impossible for the program to regain root privileges

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-10-13
          • 2013-01-29
          • 2018-03-14
          • 2022-01-14
          • 1970-01-01
          • 2017-07-28
          相关资源
          最近更新 更多