以root身份运行程序时的结果很奇怪

时间:2016-02-01 22:22:38

标签: c linux ubuntu

这是一个演示我的问题的程序的完整源代码 (操作系统是Ubuntu 14.04 32位,如果重要的话):

#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h>
#include <unistd.h>

int main(int argc, const char *argv[])
{
   int status, fd;

   printf("CURRENT UID: %d, CURRENT GID: %d\n", getuid(), getgid());

   fd = open("/dev/ttyS0", O_WRONLY);
   if(fd < 0)
   {
      printf("Error opening /dev/ttyS0: %s\n", strerror(errno));
      return 1;
   }
   printf("Successfully opened /dev/ttyS0\n");
   close(fd);

   /* DROP PRIVILEGES */

   setgid(1000);
   setuid(1000);

   printf("CURRENT UID: %d, CURRENT GID: %d\n", getuid(), getgid());

   fd = open("/dev/ttyS0", O_WRONLY);
   if(fd < 0)
   {
      printf("Error opening /dev/ttyS0: %s\n", strerror(errno));
      return 1;
   }
   printf("Successfully opened /dev/ttyS0\n");
   return 0;
}

系统中有两个用户:root和一个普通的非root用户(让我们称他为“ubuntu”),id = 1000。上面的程序试图打开一个串口(/ dev / ttyS0)两次:第一次作为root或ubuntu(取决于它是如何被调用的),第二次总是作为ubuntu。第一次尝试失败导致程序中止。用户ubuntu是拨出组的成员,因此理论上他有必要的权限来打开/ dev / ttyS0。我以四种不同的方式调用该程序:

1)直接以ubuntu

运行

调用:

&lt;我的程序路径&gt;

2)以ubuntu运行,但使用sudo

调用:

sudo -u ubuntu&lt;我的程序路径&gt;

3)以root身份运行,但权限已降至ubuntu的权限 (因此,有效地,以ubuntu运行):

调用:

sudo su
sudo -u ubuntu&lt;我的程序路径&gt;

在所有三种情况下,我得到以下预期结果:

CURRENT UID: 1000, CURRENT GID: 1000
Successfully opened /dev/ttyS0

CURRENT UID: 1000, CURRENT GID: 1000
Successfully opened /dev/ttyS0

然而,在最后一种情况下,会发生一些奇怪的事情:

4)直接以root身份运行

调用:

sudo su
&lt;我的程序路径&gt;

结果:

CURRENT UID: 0, CURRENT GID: 0
Successfully opened /dev/ttyS0

CURRENT UID: 1000, CURRENT GID: 1000
Error opening /dev/ttyS0: Permission denied

当然这是我不理解输出的最后两行:这次,当root删除了他的权限时,事实证明ubuntu没有足够的权限来打开/ dev / ttyS0,但为什么呢?这种情况与案例1-3有什么不同?

最后一件值得一提的事:如果我更改了我的代码行:

setgid(1000);

到此:

setgid(20); /* 20 is the id of dialout group */ 

然后最后一次尝试打开/ dev / ttyS0也是成功的。

当我以root身份运行程序然后通过将uid和gid更改为1000来删除ubuntu的权限时,是否意味着有关ubuntu成为拨出组成员的信息会丢失?你能否详细解释一下我的例子中的案例4以及为什么结果与我预期的不同?

1 个答案:

答案 0 :(得分:2)

设置userid和groupid 自动设置所有补充组(即所有组,不是用户的主要组,而是/etc/groups中分配给他的所有组)。尝试使用

initgroups("ubuntu", 1000);

setgid()之前调用。然后,该进程应具有拨出 -group的权限。

相关问题