0

我对 setreuid 有点困惑。

场景:一个进程以普通用户身份运行(id:cateof),但在很短的时间内需要以 root 身份运行。我必须从 cateof 提升对 root 的权限,然后再恢复为普通用户。我的第一个想法是在 setreuid(0, 0); 之间嵌套我的“根调用”。和一个 setreuid(ruid, euid); 就够了,但我错了。回到普通用户的唯一方法是在“root call”之后直接调用 setreuid(ruid, euid) 两次。

这是代码:

int main(...) {
    //check the permission, that the program is setuid
    //become normal user 
    ruid = getuid ();
    euid = geteuid ();
    setreuid(ruid, euid); 
    ...
    setreuid(0, 0);
    root_action();
    setreuid(ruid, euid); //undo root #1
    setreuid(geteuid(), getuid()); //undo root#2

如果我不在最后一行调用setreuid(geteuid(), getuid()),则该进程将继续以 root 身份运行。为什么我需要调用它两次???

4

1 回答 1

1

你第一次调用 setreuid 实际上是一个无操作 - 它不会放弃特权,你本质上是说将我的真实 uid 设置为 mygetuid并将我的有效 uid 设置为 my geteuid,在 setuid 应用程序的情况下与你相同获得。

在以用户身份运行的 setuidroot程序开始时bob,然后getuid() == bobgeteuid() == root

如果您想放弃特权,那么您可能应该调用:

setreuid(euid, ruid);

Thad 会将有效 uid 设置为bob,将实际 uid 设置为rood。在那之后所做的一切都将好像由非特权用户 bob完成,了解此时您还没有完全放弃切换回root特权的能力,因为您还没有清除保存的用户 ID 信息。

获得 root 权限将通过以下方式完成:

setreuid(ruid, euid);

同样,最后,当您重新删除权限时,您需要执行相同的操作:

setreuid(euid, ruid);

即设置有效的 uid 为 id bob。[answer here][1] 是类似的情况,它更简洁地解释了细节。

通常,在检查这些信息时,一个小打印机助手,如:

void printids(char *header) {
    uid_t ruid, euid, saveduid;
    getresuid(&ruid, &euid, &saveduid);
    printf("%s ruid=%d euid=%d saveduid=%d\n", header, ruid, euid, saveduid);
}

帮助确定所有步骤中的权限/uid 信息。

seteuid()用于临时更改权限会更简单一些,而不是更重一些setreuid()。您还可以使用setresuid()调用来更明确地设置真实、有效和保存的用户 ID 值。

保存和删除权限:

setresuid(ruid, ruid, euid);

重新获得root权限:

setresuid(euid, euid, -1);

退回到非 root 权限:

setresuid(ruid, ruid, -1);

即我们让保存的用户ID保留根信息,并在根/非根之间操作realuid和值切换euid

于 2012-05-08T15:58:56.877 回答