简体   繁体   English

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

[英]setuid() return -1 when specified user ID is the same as the effective user ID

I've compiled a binary Authorization and here's its permission我已经编译了一个二进制Authorization ,这是它的许可

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

I ran it with the root permission我用 root 权限运行它

sudo ./Authorization须藤 ./授权

so in the beginning, the uid(real uid) and euid(effective uid) of my process is所以一开始,我的进程的uid(真实uid)euid(有效uid)

uid :0 euid :0用户名:0用户名:0

then my program would invoke seteuid(501) to change the euid , now it's然后我的程序将调用seteuid(501)来更改euid ,现在是

uid :0 euid :501用户名:0用户名:501

At last, my program would invoke setuid(501) , I expected the result is最后,我的程序会调用setuid(501) ,我预计结果是

uid:501 euid: 501用户名:501用户名:501

According to manual of of setuid ()根据手册的setuid ()

The setuid() function is permitted if the effective user ID is that of the super user, or if the specified user ID is the same as the effective user ID.如果有效用户 ID 是超级用户的 ID或者指定的用户 ID 与有效用户 ID 相同,则允许使用 setuid() 函数

However, setuid(501) return -1 which is not expected, and not the behavior described in the manual, WHY ??但是, setuid(501)返回 -1 这不是预期的,而不是手册中描述的行为,为什么??

Here's my code这是我的代码

#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;
}

You can try to figure it out using the classic error explanation.您可以尝试使用经典的错误解释来弄清楚。 To do that you can add some code to the section:为此,您可以向该部分添加一些代码:

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

Dont forget to add these headers:不要忘记添加这些标题:

#include <string.h>
#include <errno.h>

Good luck!祝你好运!

I tried your code on my macOS (10.12.6) and the error is EPERM (Operation not permitted).我在我的 macOS (10.12.6) 上尝试了你的代码,错误是EPERM (不允许操作)。

Not sure if the macOS's man page is out of date.不确定 macOS 的手册页是否已过时。 On my macOS, the setuid 's man page is still of June 4, 1993 .在我的 macOS 上, setuid的手册页仍然是June 4, 1993


On Linux (Debian 8.9), setuid 's man page says:在 Linux (Debian 8.9) 上, setuid的手册页说:

setuid() sets the effective user ID of the calling process. setuid()设置调用进程的有效用户 ID If the effective UID of the caller is root , the real UID and saved set-user-ID are also set.如果调用者的有效 UID 为 root ,则同时设置真实 UID 和保存的 set-user-ID。

The APUE (2nd edition) book ( 8.11 Changing User IDs and Group IDs ) says: APUE (第 2 版)书( 8.11 Changing User IDs and Group IDs )说:

Only a superuser process can change the real user ID.只有超级用户进程可以更改真实用户 ID。 Normally, the real user ID is set by the login(1) program when we log in and never changes.通常,真实的用户 ID 是在我们登录时由login(1)程序设置的,并且永远不会改变。 Because login is a superuser process, it sets all three user IDs when it calls setuid.因为 login 是一个超级用户进程,所以它在调用 setuid 时会设置所有三个用户 ID。

The POSIX.1-2008 (SUSv4) says: POSIX.1-2008 (SUSv4) 说:

The various behaviors of the setuid() and setgid() functions when called by non-privileged processes reflect the behavior of different historical implementations. setuid()setgid()函数在被非特权进程调用时的各种行为反映了不同历史实现的行为。 For portability, it is recommended that new non-privileged applications use the seteuid() and setegid() functions instead.为了可移植性,建议新的非特权应用程序改用seteuid()setegid()函数。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM