Permissions
組成員資格和 setuid/setgid 程序
通過並且似乎不繼承他們設置的 uid/gid 的組成員身份來降低權限的程序。
setuid()``setgid()
我有一個伺服器程序,必須以 root 身份執行才能打開特權埠;之後,它降級為特定的非特權 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
但是,以下 C 程序(編譯
std=gnu99
)在 root 執行時:#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; }
總是報告Permission denied。我想這與它是一個非登錄過程有關,但它有點妨礙權限的工作方式。
- 這通常是伺服器的 SOP,我認為必須有辦法解決這個問題,因為我發現有人用 apache 做這件事的報告——apache 已添加到音頻組,顯然可以使用音響系統。當然,這可能發生在 fork 而不是原始程序中,但實際上在我的上下文中情況是相同的(它是在 setuid 呼叫之後分叉的子程序)。
問題在於,
setuid
並setgid
不足以為您的程序提供所需的所有憑據。程序的授權取決於
- 它的 UID
- 它的 GID
- 其補充組
- 它的能力。
請參閱
man 7 credentials
以獲取更詳細的概述。因此,在您的情況下,問題在於您正確設置了 UID 和 GID,但您沒有設置流程的補充組。並且組bar
的 GID 為 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; }