说明

setuid()设置调用过程的有效用户ID。如果调用进程具有特权(更确切地说:如果该进程在其用户名称空间中具有CAP_SETUID功能),则还将设置实际UID和保存的set-user-ID。

在Linux下,setuid()的实现类似于具有_POSIX_SAVED_IDS功能的POSIX版本。这允许set-user-ID(而不是root)程序删除其所有用户特权,执行一些未特权的工作,然后以安全的方式重新使用原始的有效用户ID。

如果用户是root或程序是set-user-ID-root,则必须格外小心:setuid()检查调用方的有效用户ID,如果是超级用户,则将所有与进程相关的用户ID设置为uid。发生这种情况后,该程序将无法重新获得root特权。

因此,希望暂时放弃root特权,假定未特权用户的身份,然后再获取root特权的set-user-ID-root程序不能使用setuid()。您可以使用seteuid(2)完成此操作。

SETUID - Linux手册页

Linux程序员手册 第2部分
更新日期: 2019-03-06

遵循规范

POSIX.1-2001,POSIX.1-2008,SVr4。与4.4BSD调用不太兼容,后者会设置所有真实,已保存和有效的用户ID。

名称

setuid-设置用户身份

出版信息

这个页面是Linux手册页项目5.08版的一部分。有关项目的说明、有关报告错误的信息以及此页面的最新版本,请访问https://www.kernel.org/doc/man-pages/

语法

#包括
#包括

int setuid(uid_t uid);

另外参见

getuid(2),seteuid(2),setfsuid(2),setreuid(2),功能(7),凭据(7),user_namespaces(7)

错误说明

EAGAIN
该调用将更改调用者的真实uid(即uid与调用者的真实UID不匹配),但是分配必要的内核数据结构时出现暂时故障。
EAGAIN
uid与调用方的真实用户ID不匹配,并且此调用会使属于真实用户ID uid的进程数超过调用方的RLIMIT_NPROC资源限制。从Linux 3.1开始,不再发生这种错误情况(但是功能强大的应用程序应检查该错误);请参阅execve(2)中对EAGAIN的描述。
EINVAL
uid中指定的用户标识在此用户名称空间中无效。
EPERM
用户没有特权(Linux:用户名称空间中不具有CAP_SETUID功能),并且uid与调用过程的实际UID或保存的set-user-ID不匹配。

返回值

成功时,返回零。如果出错,则返回-1,并正确设置errno。

注意:在某些情况下,即使调用者的UID为0,setuid()也会失败;忽略检查setuid()的失败返回是一个严重的安全错误。

备注

Linux具有文件系统用户ID的概念,通常等于有效用户ID。 setuid()调用还设置了调用进程的文件系统用户ID。参见setfsuid(2)。

如果uid与旧的有效UID不同,则将禁止该进程离开核心转储。

原始的Linux setuid()系统调用仅支持16位用户ID。随后,Linux 2.4添加了支持32位ID的setuid32()。 glibc setuid()包装函数透明地处理了内核版本之间的差异。

C library/kernel differences

在内核级别,用户ID和组ID是每个线程的属性。但是,POSIX要求进程中的所有线程共享相同的凭据。 NPTL线程实现通过为更改过程UID和GID的各种系统调用提供包装函数来处理POSIX要求。这些包装函数(包括setuid()的包装函数)采用基于信号的技术,以确保当一个线程更改凭据时,该进程中的所有其他线程也更改其凭据。有关详细信息,请参见nptl(7)。

日期:2019-08-20 17:59:23 来源:oir作者:oir