关于进程的用户ID,有效ID,保存设置的用户ID以及文件的所有者,同组以及其他用户的属性之间的关系

基础知识

  • 实际用户ID(RUID)/实际组ID:
    标识我们究竟是谁.这两个字段在登录时取自口令文件中的登录项.通常,在一个登录会话期间这些值并不改变.但是超级用户进程有方法改变它们.
  • 有效用户ID(EUID)/有效组ID/附属组ID:
    决定了我们文件访问权限,定义了操作者的权限,是进程的属性,决定了该进程的访问权限.
  • 保存的设置用户ID(SUID):
    有效用户ID副本,既然是有效用户ID的副本,作用是为了以后恢复有效用户ID
  • 设置用户ID位:
    用于对外的权限的开发,它的作用是我们如何去修改有效用户ID.

为了理解上面这几个概念.我们从linux中文件的文件属性字段来首先感性的认识一下(可以在linux下,使用ls -l来查看某个文件的属性.

jp@ubuntu:~$ ls -l test
-rw-rw-r-- 1 jp jp 662 613 17:21 test

通过观察上面的第一列,我们发现有:

-rw-rw-r--

其实这个属性从右往左分别编号为0—9,也就是

9 8 7 6 5 4 3 2 1 0
- r w - r w - r - -

其中0–2表示的是其他用户对此文件所具有的文件访问权限,3–5表示的是和该文件所拥有者同一组的对此文件所具有的文件访问权限,6—8表示的是该文件所拥有者对此文件所具有的文件访问权限.第9位表示的是此文件是属于什么类型的,所有的类型包含如下:

字母  "-"   表示该文件是一个普通文件(regular file)
字母  "d"   表示该文件是一个目录文件(directory file)
字母  "b"   表示该文件一个块特殊文件(block special file),这种类型
的文件提供对设备(如磁盘)带缓冲的访问,每次访问以固定长度为单位进行.
字母  "c"   表示该文件是一个字符特殊文件(character special file),这
种类型的文件提供对设备不带缓冲的访问,每次访问长度可变.系统中的所有设备
要么是字符特殊文件,要么是块特殊文件.
字母  "p"   表示该文件是用于进程间通信的,有时也称为命名管道(named pip)
字母  "s"   表示该文件是套接字,这种文件用于进程间的网络通信.
字母  "l"   表示该文件是符号链接(symbolic link),这种类型的文件指向另一个文件.

其中2,1,0这三个表示的是其他用户对文件的:读(read),写(write),可执行(excute)权限,如果没有相应的权限的话,用-表示.同理5–3,8–6都是相对应的同一组的,文件拥有者对此文件所用于的文件访问权限.
如果我们想更改这三组权限,我们可以使用chmod命令,相应的命令我这里就不赘述了(网上百度一大堆).
然后看第三列我们发现是jp

jp@ubuntu:~$ ls -l test
-rw-rw-r-- 1 jp jp 662 613 17:21 test

其实第三列表示的是文件目录的拥有者.然后第4列也是jp,表示的是该文件拥有者所在的组.在这里说明一下,第一个关键字,实际用户ID.其实就是下面jp@ubuntu中的jp.它表示我们当前的登录用户是什么!!!

jp@ubuntu:~$ ls -l test

接下来说明一下,实际用户ID跟有效用户ID之间的关系.当执行一个程序文件时,进程的有效用户ID通常就是实际用户ID,有效组ID通常是实际组ID.但是可以在文件模式(st_mode)中设置一个特殊标志,其含义是"当执行此文件时,将进程的有效用户ID设置为文件所有者的用户ID(st_uid)".与此相似,在文件模式中可以设置另一位,它将执行文件的进程的有效组ID设置为文件的组的所有者ID(st_gid).在文件模式中这两位被称为设置用户ID(set-user-ID)位和设置组ID(set-group-ID)位.
例如,若文件所有者是超级用户,而且设置为该文件的设置用户ID位,那么当该程序文件由一个进程执行时,该进程具有超级用户权限,不管执行此文件的进程的时间用户是什么,都会是这样.

上面所描述的:设置用户ID位,设置组ID位.其实是可以在ls -l中看到的,

jp@ubuntu:~$ chmod u+s test
jp@ubuntu:~$ ls -l test 
-rwSrw-r-- 1 jp jp 662 613 17:21 test

你会注意到用户这块属性的原先对应的可执行属性-变成了S
这个S其实就是设置用户ID位.其实上面所说的十位字段,还不完整,还少了两位:11位设置组ID位(SGID),12位设置用户ID位(SUID).这里你会发现,我们其实用的用户的可执行属性这个位置来显示的设置用户ID位(SUID).那么我们如何查看此时我们的用户是否具有对此文件的可执行属性呢?其实很简单.这里用了sS两种表示情况

-rwsrw-r--     此时在用户可执行位置上是s,那么表示SUID被设置,并且所有者具有此文件的可执行权利
-rwSrw-r--     此时在用户可执行位置上是S,那么表示SUID被设置,但是所有者不具有此文件的可执行权利
-rw-rwsr--     此时在同组可执行位置上是s,那么表示SGID被设置,并且同组用户具有此文件的可执行权利
-rw-rwSr--	   此时在同组可执行位置上是S,那么表示SGID被设置,但是同组用户不具有此文件的可执行权利

真正的所有的属性应该是下面这种:

-rwSrw-r--    1 0 0 1 1 0 1 1 0 1 0 0
-rwsrw-r--    1 0 0 1 1 1 1 1 0 1 0 0
注意:s跟S的不同之处
chmod u+s filename 设置SUID位

chmod u-s filename 去掉SUID设置

chmod g+s filename 设置SGID位

chmod g-s filename 去掉SGID设置

另外一种方法是chmod命令用八进制表示方法的设置。如果明白了前面的12位权限表示法也很简单。

进阶知识

  • 关于最开始的四个关键字的解释
    首先实际用户ID(RUID)或者实际用户组ID(RGID).其实就是表征我们此刻的用户是谁的.只有超级特权者才可以改变它.其实可以这样来理解RUID/RGID:
我们的Linux系统是多用户登录的,所以我们必须要知道当前登录的用户是谁,所以**RUID/RGID**就表征这个

那么EUID/EGID的作用是什么呢?这里摘抄自AUPE第80页的一段:

进程每次打开,创建或者删除一个文件时,内核就进行文件访问权限测试,而这种测试可能涉及文件的所有者(st_uid和st_gid),进程的有效ID(有效用户ID和有效用户组ID)以及进程的附属组ID(若文件支持的话).两个所有者ID是文件的性质两个有效ID和附属组ID则是进程的性质,内核进行的测试具体如下:

  1. 若进程的有效用户ID是0(超级用户),则允许访问.这给予了超级用户对整个文件系统进行处理的最充分的自由
  2. 若进程的有效用户ID等于文件的所有者ID(也就是进程拥有此文件),那么如果所有者适当的访问权限位被设置,则允许访问;否则拒绝访问.适当的访问权限指的的是,若进程为读而打开文件该文件,则用户读位应该设置为1;若进程为写而打开该文件,则用户写位为1;若进程将执行该文件,则用户执行位应该为1
  3. 若进程的有效组ID或进程的附属组ID之一等于该文件的组ID,那么如果适当的访问权限位被设置,则允许访问;否则拒绝访问.
  4. 若其他用户适当的访问权限位被设置,则允许访问;否则拒绝访问

按顺序执行这四步,注意,如果进程拥有此文件(第二步),则按用户访问权限批准或拒绝该进程对文件的访问-----不查看组访问权限(所以注意,是根据短路效应来的).类似的,若进程并不拥有该文件.但进程属于某个适当的组,则按组访问权限批准或拒绝该进程对文件的访问-----不查看其他用户的访问权限.那么如果进程也不属于某个适当的组,那么就查看其他用户的了.

所以,通过上面的解释,我们可以得出来:

  1. ls -l 文件属性
    文件属性,仅仅是文件的属性!!!也就是说,ls -l得出来的结果,表示:所有者,同组者,其他用户对该文件的访问权限而已
  2. 进程的EUID,EGID
    进程的EUID,EGID进程的属性.这些属性可以用来跟它想要访问的文件的所有者,同组者,其他用户进行比较,

更改用户ID和更改组ID

为什么要更改用户ID跟组ID呢?因为我们可能要切换实际用户,比如我们的linux系统可以用户多个用户,我们可以使用sudo su切换到root(超级用户)用户,也可以用su 用户名切换到其他的用户下.这其实就是更改用户ID用户组ID主要有以下两个函数来完成:

#include <unistd.h>
int setuid(uid_t uid);
int setgid(gid_t gid);

关于谁能更改ID有若干规则.现在先考虑更改用户ID的规则(关于用户ID我们所说明的一切都适用于组ID)

  1. 若进程具有超级用户特权,则setuid函数将实际用户ID,有效用户ID以及保存的设置用户ID(saved set-user-ID)设置为uid,注意是一下子设置了三个ID
  2. 若进程没有超级用户特权,但是uid等于实际用户ID保存的设置用户ID,则setuid只将有效用户ID设置为uid.不更改实际用户保存的设置用户ID
  3. 如果上面两个条件都不满足,则errno设置为EPERM,并返回-1

关于内核所维护的三个用户ID,还要注意以下几点:

  1. 只有超级用户进程可以更改实际用户ID,通常用户ID是在用户登录时,由login(1)程序设置的,而且决不会改变它.因为login是一个超级用户进程,当它调用setuid时,设置所有3个用户ID
  2. 仅当对程序文件(注意这个是一个文件!!!!)设置了设置用户ID位时(SUID),exec函数才设置有效用户ID.如果设置用户ID位没有设置,exec函数不会改变有效用户ID,而将维持其现有值.任何时候都可以调用setuid,将有效用户ID设置为实际用户ID或保存的设置用户ID(这一点在上面设置用户ID的时第二点说明了).自然地,不能将有效用户设置为任一随意值.
  3. 保存的设置用户ID是由exec复制有效用户ID而得到的.如果设置了文件的设置用户ID位,则在exec根据文件的用户ID设置了进程的有效用户ID以后,这个副本就被保存起来了.
    所以如下图所示:
    摘自AUPE同理
#include <unistd.h>
int seteuid(uid_t uid);
int setegid(gid_t gid);
  1. 对于非特权用户,可将其有效用户ID设置为其实际用户ID或其保存的设置用户ID
  2. 对于特权用户,可将其有效用户ID设置为uid(注意,setuid特权用户设置三个用户(实际用户,有效用户,保存的设置用户),而setegid,这里只改变一个)
#include <unistd.h>
int setreuid(uid_t ruid,uid_t euid);
int setregid(gid_t rgid,gid_t egid);
  • 一个非特权用户总能交换实际用户ID和有效用户ID.这就允许一个设置用户ID程序(设置为SUID位的文件程序)交换成用户的普通权限,以后又可以交换设置成用户ID权限.

最后一张图结束设置用户ID的内容
设置不同用户ID的各函数写的很乱,希望大家看完以后不要骂娘

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值