今天看了有关进程凭证的一些知识,写个文章记录一下今天所学的内容。
每个进程都有一套用数字表示的uid和gid
1.实际用户id(ruid),实际组id(rgid).这两个id值标示了文件的性质,指出了我们实际上是谁。
2.有效用户id(euid),有效组id(egid),辅助组id,这三个id值标示了进程的性质,用于文件权限访问检查。
3.文件系统用户id,文件系统组id(linux特有) 在进行诸如文件打开,改变文件属主,修改文件权限之类的文件系统操作时决定其权限的是文件系统用户id。
4.保存set-user-ID和保存set-group-ID(组权限同用户)
(1).若可执行文件的set-user-ID权限位开启,则进程的euid置为可执行文件的属主。若未设置,则进程的euid不变。
(2).保存set-user-ID的值由对应的有效ID复制而来,无论正在执行的文件是否设置了set-user-ID权限,这一复制都将进行。
Set-User-ID程序会将进程的有效用户id设置为可执行文件的用户id,例如linux中的 passwd 、wall、mount、umount这些命令在使用ll查看时可以看到代表执行的X变为了s。
以下简单记录一下修改各个id的函数,只记录了修改用户的,用户组的大致相同,除setfsuid外每个set*都有一个对应的get*函数
int setuid(uid_t uid)
0 on success -1 on error
setuid用于修改用户的有效id,规则取决于进程是否是特权进程(既有效用户id为0)
1.当非特权进程调用setuid()时,仅能修改进程的euid为相应的ruid或者保存set-user-ID,这意味着对非特权用户而言,仅当执行set-user-ID时,setuid()才起作用,在执行普通程序时进程的ruid和euid、保存set-user-ID相同。
2.特权进程以非0参数调用setuid()时,其ruid、euid、和保存set-user-ID均被置为uid参数所指的值,这个操作是单向的,
一旦特权进程使用此方式修改了其ID,所有特权将消失,且之后也不能再调用setuid()重新将euid置为0.
int seteuid(uid_t euid)
0 on success -1 on error
使用seteuid()修改权限时遵循以下规则:
1.非特权进程仅能将其euid修改为相应的ruid或者保存设置ID
2.特权进程能够修改其euid为任意值若将euid修改为非0值,则不再具有特权,但可以使用规则(1)进行恢复
可以使用以下代码来在特权与非特权之间切换
euid=geteuid();//save initial euid
if(seteuid(getuid())==-1)//drop privilege
err("seteuid");
if(seteuid(euid)==-1)//regain privilege
err("seteuid");
int setreuid(uid_t uid,uid_t euid)
0 on success -1 on error
修改ruid和euid,若只想修改其中一个,可以将另外一个设置为-1
1.非特权进程只能将euid置为ruid、euid或保存set-user-ID,ruid只能设置为当前ruid或euid
2.特权进程可以任意设置
3.不管进程是否具有特权,只要以下成立,就能将set-user-ID设置为新的euid
(1).ruid不为-1
(2).对有效用户id所设置的值不同于系统调用之前的ruid
既如果进程使用setreuid()仅将euid修改为ruid的当前值那么set-user-ID的值不变,且后续可调用setreuid()将euid恢复为保存set-user-ID的值。
#define _GNU_SOURCE
int setresuid(uid_t ruid,uid_t euid,uid_t suid)
0 on success -1 on error
1.非特权进程可以将ruid euid 保存set-user-ID设置为三者的其中之一
2.特权进程能够任意设置
3.不管系统调用是否对其他ID做了任何改动,总是将文件系统id设置为euid相同。
int setfsuid(uid_t fsuid)
return the previous file-system user ID
设置规则同上。