组成员身份和setuid / setgid流程


10

其流程去缓和权限通过setuid()setgid()似乎没有继承的UID / GID他们设置了组成员。

我有一个服务器进程,必须以root用户身份执行才能打开特权端口。后,它的去升级到一个特定的非privilleged UID / GID,1 -例如,其的用户foo(UID 73)。用户foo是组的成员bar

> cat /etc/group | grep bar
bar:x:54:foo

因此,如果我以登录foo,则可以读取/test.txt具有以下特征的文件:

> ls -l /test.txt
-rw-r----- 1 root bar 10 Mar  8 16:22 /test.txt

但是,std=gnu99当以root 身份运行时,以下C程序(compile ):

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

int main (void) {
    setgid(73);
    setuid(73);
    int fd = open("/test.txt", O_RDONLY);
    fprintf(stderr,"%d\n", fd);
    return 0;
}   

始终报告“ 权限被拒绝”。我想这与它是一个非登录过程有关,但是在某种程度上限制了权限的工作方式。


1.这通常是服务器的SOP,我认为应该有一种解决方法,因为我发现有人用apache 进行报告 – apache已添加到音频组中,并且显然可以使用声音系统。当然,这很可能发生在fork中,而不是原始过程中,但实际上在我的上下文中情况是一样的(这是setuid调用后分叉的子过程)。


切换setuid()/ setgid()呼叫。
vonbrand 2014年

@vonbrand ROTFL我以为我在那里洗了脸 -但结果相同,所以我将编辑问题以消除红鲱鱼。
goldilocks 2014年

1
如果您使用setgid(54)而不是setgid(73)(如/etc/groups,组bar中的ID为54),是否有效?
lgeorget 2014年

@lgeorget当然可以,但这没有达到目的。该进程出于其他原因需要其自己的GID,同样,这些文件必须具有其所拥有的权限。这就是为什么必须要有多个组的成员资格-例如,如果您有两个用户需要这样做。请注意,setuid()这样做之后您将无法再做...但是,嗯...我想您可以seteuid()……
goldilocks 2014年

1
我的问题是确保某处没有其他隐藏的细微问题。:-)
lgeorget 2014年

Answers:


14

问题是,setuidsetgid 不足以让您的过程中的所有需要的凭据。流程的授权取决于

  • 它的UID
  • 它的GID
  • 其补充团体
  • 它的能力。

请参阅man 7 credentials以获得更详细的概述。因此,在您的情况下,问题在于您正确设置了UID和GID,但没有设置流程的补充组。并且组的barGID为54,没有73,因此该进程不被识别为组。

你应该做

#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <grp.h>

int main (void) {
    gid_t supplementary_groups[] = {54};

    setgroups(1, supplementary_groups);
    setgid(73);
    setuid(73);
    int fd = open("/test.txt", O_RDONLY);
    fprintf(stderr,"%d\n", fd);
    return 0;
}  

1
这是一个有趣的问题,值得更多的批评,因为它实际上可能对许多人有用。:-)
lgeorget 2014年

所以我在串行端口上也遇到类似的问题。我为dialout小组实施了此方法,并且第一次起作用。
tl8

0

好的,在网上有点拖网。起初我以为APUE会保留所有答案,但是却弄错了。我的副本(旧版)正在使用中,因此... Unix和Linux管理手册的第5章看起来很有希望,但我还没有得到(仅仅是前两个版本的副本,也在使用中)。

我发现的一些小资源(google是“ daemon编写unix”的谷歌)都在谈论重要的步骤,例如如何与tty分离等。但是关于UID / GID却一无所获。奇怪的是,甚至http://tldp.org上的 HOWTO广泛收藏似乎都没有细节。唯一令人兴奋的是Jason Short的《让我们写一个Linux守护进程》(第一部分)。有关SUID / SGID以及所有混乱情况的全部详细信息,请参见Chen,Wagner和Dean的SUID揭秘(USENIX 2002中的一篇论文)。但是要小心,Linux还有一个额外的UID,即FSUID(有关讨论,请参见Wolter的Unix不兼容说明:UID设置函数)。

守护进程绝对不是胆小鬼。D. Wheeler 针对Linux和Unix安全编程中提供了一般的安全注意事项HOWTO-创建安全软件Systemd承诺将简化大多数操作(从而减少导致安全问题的错误的余地),请参见守护程序手册


1
问题不在于守护进程。您已经将SUID位(赋予进程可执行文件所有者的权限)与混淆setuid(),它允许进程任意更改其UID。SUID通常旨在允许升级权限(非特权->特权),而setuid()只能做相反的事情。
goldilocks 2014年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.