uid_t getuid(void);
uid_t geteuid(void);
int setuid(uid_t uid);
int seteuid(uid_t euid);
int setegid(gid_t egid);
setuid函数设置实际用户ID和有效用户ID
非root用户是不可能通过setuid或者seteuid取得其他权限
setuid执行步骤:
如果由普通用户调用,将当前进程的有效ID设置为uid
如果由有效用户ID符为0的进程调用,则将真实,有效和已保存用户ID都设置为uid
uid_t uid = getuid();
printf("uid: %d
", uid);
uid = geteuid();
printf("euid: %d
", uid);
# ./a.out
uid: 1004
euid: 1004
setuid和seteuid
当root 使用setuid()来变换成其他用户识别码时,root权限会被抛弃,完全转换成该用户身份,也就是说,该进程往后将不再具有可setuid()的权利,如果只是向暂时抛弃root 权限,稍后想重新取回权限,则必须使用seteuid()
设置setuid权限
# chmod 4xxx test.c //设置setuid权限
# chmod 2xxx dir //设置setgid权限
# chmod 6xxx test.c //设置setuid和setgid权限
# chmod 0xxx test.c //取消setuid和setgid权限
# chmod u+s test.c //设置setuid权限(setuid 只对文件有效)
# chmod g+s dir //(setgid 只对目录有效)
# chmod 1xxx test.c //为test.c文件加上sticky标志
# chmod o+t test.c //(sticky只对文件有效)
setuid占用属主x(执行)位,setgid占用组x位,sticky-bit占用其他x位
如果该位有x权限,就用小写s,没有就用大写S
setuid:使文件在执行阶段具有文件所有者的权限。典型的文件是 /usr/bin/passwd。如果一般用户执行该文件,则在执行过程中,该文件可以获得root权限,从而可以更改用户的密码
setgid:目录被设置该位后,任何用户在此目录下创建的文件都具有和该目录所属的组相同的组
sticky bit:该位可以理解为防删除位。一个文件是否可以被某用户删除,主要取决于该文件所属的组是否对该用户具有写权限。如果没有写权限,则这个目录下的所有文件都不能被删除,同时也不能添加新的文件。如果希望用户能够添加文件但同时不能删除文件,则可以对文件使用sticky bit位。设置该位后,就算用户对目录具有写权限,也不能删除该文件
setuid的安全性
# chmod 4755 vim
将vi的所有者改为root
这样,在普通用户下,vi就可以编辑任何文件
禁用setuid权限
# vi /rtc/fstab
添加nosuid
LANBEL=/home /home ext3 default,nosuid 1 2
这样就在很大程度上保护了系统的安全