linux:有效用户id、实际用户id、设置用户id - Go语言中文社区

linux:有效用户id、实际用户id、设置用户id


概念

实际用户id(RUID,进程特有的概念): 在开机时,你输入的账号的对应id就是实际用户uid,说白了就是登录号,站在用户的角度上看。
有效用户id(EUID,进程特有的概念): 一般和RUID相同,站在操作系统的角度上看,用于给操作系统判断某个进程是否拥有操作某个文件的权限。
设置用户id(SUID,set user id,文件特有的概念): 站在文件的角度上看,文件权限有r-w-x-s-t类型,其中的s表示SUID是打开状态(即可用状态)。如果一个文件的权限位里面没有s,则表示SUID是关闭状态(即不可用状态)。注意:SUID只能用于可执行文件,其作用是修改EUID(有效用户id)
保存的设置用户id(SSUID,saved SUID,《Unix高级环境编程 第3版》的8.11节里面定义的,进程特有的概念),也有博客称为保留的设置用户id: EUID(有效用户id)的备份,既然是备份,则应该是恢复的作用。SSUID由linux的exec()函数保存,可以把SSUID理解为exec()函数里面的一个局部变量。exec()的执行逻辑大概如下(自己猜测的,为了好理解SSUID的作用):

// 这里假设 "可执行文件"为/etc/passwd, 该文件的权限位-rwsr-xr-x,文件的拥有者是root
void exec("可执行文件") {
	SSUID = EID;
	进程的EID = 可执行文件用户(即root用户);
	执行"可执行文件";
	//此时调用本函数的进程已经拥有root权限了
	
	EID = SSUID;
	
}

文件特有的概念:
**FUID(file uid):**文件的拥有者
**FGID(file gid):**文件的拥有者所在组的组id
设置用户id(SUID,set user id,文件特有的概念): 站在文件的角度上看,文件权限有r-w-x-s-t类型,其中的s表示SUID是打开状态(即可用状态)。如果一个文件的权限位里面没有s,则表示SUID是关闭状态(即不可用状态)。注意:SUID只能用于可执行文件,其作用是修改EUID(有效用户id)

总结:RUID、EUID、SSUID都是针对进程的,即站在进程的角度,即进程特有的概念。而SUID则是针对文件的,即站在文件的角度,或者说是SUID是可执行文件特有的概念!为什么要修改进程的EUID?目的是想让进程在某一时刻能够拥有特殊的权限。

更改用户ID

进程特有的概念
一个文件有9个文件权限位,比如/etc/passwd的9个权限位是 rwsr-xr-x, 其中的s就是SUID(设置用户ID位),说明/etc/passwd的设置用户ID位是打开状态。

在这里插入图片描述

以下内容均来自https://www.cnblogs.com/stemon/p/5287631.html的内容

对于一个普通文件,有三个ID,这三个ID对应三组权限,这三组权限控制着进程对该文件的访问权限。
在这里插入图片描述
对于linux系统,某个用户登录后,创建一个文件,那个这个文件的用户ID就是这个用户的ID。该用户创建的所有的进程都可以访问这个文件,因为该用户创建的进程的实际用户ID和有效用户ID都是这个用户的ID。但是当一个用户创建的进程要去访问其他用户创建的文件的时候,就需要用到有效用户ID的改变,来能够有权限访问这个文件。

实例分析一:

如何在权限不够的情况下执行特权权限,具体的方法就是更改进程的有效用户ID。
对于linux系统来说,用户的密码都存放在/etc/shadow文件下,查看一下这个文件的权限:

在这里插入图片描述

假如我是一个普通的用户,显然我是可以修改我自己的密码的,通过passwd命令,无可厚非,自己修改自己的密码当然是允许的。

但是仔细想想有没有什么不对的地方,作为一个普通的用户登录后,我的所有的进程的实际用户ID和有效用户ID都应该是我自己(这个用户)的UID。从上面对/etc/shadow文件用户ID和所属的组ID看,我不具备修改这个文件的权限,那么执行passwd命令是怎么修改我的密码的呢?

根据上面所讲的知识,决定进程对文件的访问权限的是执行操作时的有效用户ID,所以在执行passwd命令时,进行的有效用户ID肯定不是我这个普通用户的UID,一定被修改过了。

还有一点,在执行passwd这个命令的时候,在磁盘上肯定有一个可执行的文件,下面看看这个可执行文件的权限:
在这里插入图片描述

我们看到了一个s,这就是使用户设置ID位有效,上面说过这个位的作用就是修改执行这个可执行文件的进程的有效用户ID,那么我么来看看他是怎样修改执行passwd命令的进程的有效用户ID的。

首先看一下命令的执行的过程,当普通用户执行passwd命令时,shell会fork出一个子进程,此时该进程的有效用户ID还是这个普通用户的ID,然后exec程序执行/usr/bin/passwd这个例程(可执行文件)。通过上面的表我们就能知道,exec发现/usr/bin/passwd这个可执行文件有SUID为,于是会把进程的有效用户ID设置成可执行文件的用户ID,显示是root,此时这个进程就获得了root的权限,得到了读写/etc/shadow文件的权限,从而普通用户可以完成密码的修改。exec进程退出后,会恢复普通用户的有效用户ID为实际用户ID(也就是该普通用户的ID),这样就保证了不会是普通用户一直具有root权限。

在exec时,修改进程的有效用户ID为文件的用户ID,还是恢复进程的有效用户ID为进程的实际用户ID,这些都是linux内核完成的,用户是不能干预这些步骤的。

这样的过程既实现了普通用户权限的暂时的提升,不让普通用户长久的拥有root权限。同时即使在普通用户拥有root权限的这段短暂的时间里,普通用户也不能为所欲为,因为普通用户的这个进程必须按照/usr/bin/passwd这个可执行文件的指令内容执行,不能干之外的任何事情,而这个可执行文件又是root事先写好的,多么完美的设计啊~~

这就是设置用户ID为的作用,它的存在就是为了普通用户能够在某些时候获取一段时间的超级权限,但是你可能疑问,为什么不能用setuid直接修改呢?

如果这里可以用setuid直接修改进程的有效用户ID来获得特权权限,那么整个系统的超级权限就不可控制了,这违背了最小权限模型。所以linux的设计是:setuid在非特权用户下面,有效用户ID只能设置成为实际用户ID或者保存的设置用户ID。保存的设置用户ID又是有效用户ID的副本,有效用户ID只能是实际用户ID或者文件的所有者ID(在设置了保存用户ID位时)。

这样你就不能将有效用户ID设置成随意的值,所以对普通用户创建的任何文件,如果没有得到超级用户的授权,那么无论怎么编写代码来设置运行进程的有效用户ID或者设置用户ID位,由于这个可执行文件是普通用户自己编写的,所以权限根本没有任何改变。这里就是说只有root自己创建的可执行文件并且设置了用户ID位,才能够提升执行该可执行文件的进程的权限。

版权声明:本文来源CSDN,感谢博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/u010919133/article/details/89290087
站方申明:本站部分内容来自社区用户分享,若涉及侵权,请联系站方删除。

0 条评论

请先 登录 后评论

官方社群

GO教程

猜你喜欢