当指定的用户ID与有效用户ID相同时,setuid()返回-1

时间:2017-10-26 14:40:12

标签: c macos unix

我已经编译了二进制文件Authorization并获得了其权限

  

-rwsr-sr-x 1根轮18464 10 26 22:07 ./授权

我使用root权限

运行它
  

sudo ./Authorization

所以在开始时,我的流程的 uid(真实uid) euid(有效uid)

  

uid :0 euid :0

然后我的程序会调用 seteuid(501)来更改 euid ,现在它

  

uid :0 euid :501

最后,我的程序会调用 setuid(501),我预计结果是

  

uid:501 euid:501

根据 setuid ()

的手册
  

如果有效用户ID是超级用户ID,则允许使用setuid()函数        user,或者指定的用户ID与有效用户ID相同。

但是, setuid(501)会返回-1,这是预期的,而不是手册中描述的行为,为什么 ??

这是我的代码

#include <stdio.h>
#include <unistd.h>
int main(int argc, const char * argv[]) {
    printf("uid: %d euid: %d\n", getuid(), geteuid());

    if (seteuid(501) == -1) {
        printf("seteuid error\n");
    }
    printf("seteuid(501)> uid: %d euid: %d\n", getuid(), geteuid());

    if (setuid(501) == -1) {
        printf("setuid error\n");
    }
    printf("setuid(501)> uid: %d euid: %d\n", getuid(), geteuid());

    return 0;
}

2 个答案:

答案 0 :(得分:1)

您可以尝试使用经典错误说明来解决这个问题。 为此,您可以在该部分添加一些代码:

 if (setuid(501) == -1) {
    printf("setuid error\n");
    printf ("Error while setting uid: %s\n", strerror(errno));
}

别忘了添加这些标题:

#include <string.h>
#include <errno.h>
祝你好运!

答案 1 :(得分:0)

我在macOS上尝试了你的代码(10.12.6),错误是EPERM(不允许操作)。

不确定macOS的手册页是否已过期。在我的macOS上,setuid的手册页仍为June 4, 1993

在Linux(Debian 8.9)上,setuid的手册页说:

  

setuid()设置了调用进程的有效用户ID 如果呼叫者的有效UID是root ,则还会设置真实的UID和已保存的set-user-ID。

APUE(2)书(8.11 Changing User IDs and Group IDs)说:

  

只有超级用户进程才能更改真实用户ID。通常,当我们登录时,真实用户ID由login(1)程序设置,并且永远不会更改。由于login是超级用户进程,因此在调用setuid时会设置所有三个用户ID。

POSIX.1-2008(SUSv4)says

  

非特权调用时setuid()setgid()函数的各种行为   流程反映了不同历史实现的行为。 为了便携性,它是   建议新的非特权应用程序使用seteuid()setegid()函数。