一、u+s的作用
u+s用于可执行的二进制文件,表示进程在执行该文件时,进程的有效用户id(euid)为文件的所有者id。
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
static void print_uid(){
long ruid, euid;
ruid = getuid();//get real uid
euid = geteuid();//get effective uid
printf("ruid = %ld, euid = %ld\n", ruid, euid);
}
int main(int argc, char const *argv[])
{
long ruid, euid;
print_uid();
// setuid(1001);
print_uid();
return 0;
}
1.普通可执行文件
在shbj用户下,编译上面的代码得到permission执行文件,其权限如下。
shbj@ubuntu:~/develop/workspace/c/procenv$ make permission
cc permission.c -o permission
shbj@ubuntu:~/develop/workspace/c/procenv$ ll permission
-rwxrwxr-x 1 shbj shbj 8665 Nov 20 17:42 permission*
分别在shbj(1000)、zhangsan(1001)、root(0)用户下执行
shbj@ubuntu:~/develop/workspace/c/procenv$ ./permission
ruid = 1000, euid = 1000
ruid = 1000, euid = 1000
zhangsan@ubuntu:/home/shbj/develop/workspace/c/procenv$ ./permission
ruid = 1001, euid = 1001
ruid = 1001, euid = 1001
root@ubuntu:/home/shbj/develop/workspace/c/procenv# ./permission
ruid = 0, euid = 0
ruid = 0, euid = 0
可以看到进程在运行,普通的可执行文件时,进程的有效用户id(euid)和实际用户id(ruid),都为当前用户的id(从父进程(shell)继承而来)。
2.设置了设置-用户-ID位(u+s)的可执行文件
shbj@ubuntu:~/develop/workspace/c/procenv$ chmod u+s permission
shbj@ubuntu:~/develop/workspace/c/procenv$ ll permission
-rwsrwxr-x 1 shbj shbj 8665 Nov 20 17:42 permission*
分别在shbj、zhangsan、root用户下执行
shbj@ubuntu:~/develop/workspace/c/procenv$ ./permission
ruid = 1000, euid = 1000
ruid = 1000, euid = 1000
zhangsan@ubuntu:/home/shbj/develop/workspace/c/procenv$ ./permission
ruid = 1001, euid = 1000
ruid = 1001, euid = 1000
root@ubuntu:/home/shbj/develop/workspace/c/procenv# ./permission
ruid = 0, euid = 1000
ruid = 0, euid = 1000
可以看到进程在执行带有设置-用户-ID位(也就是u+s)的可执行文件时,进程的有效用户id(euid)为执行文件的所用者id。
3.u+s与文件所用者和谁执行了chmod u+s间的关系?
(1).当前的permission文件,chmod u+s 是shbj用户执行的,所用者为shbj。
将其所用者改为root。
root@ubuntu:/home/shbj/develop/workspace/c/procenv# ll permission
-rwsrwxr-x 1 shbj shbj 8665 Nov 20 17:42 permission*
root@ubuntu:/home/shbj/develop/workspace/c/procenv# chown root permission
root@ubuntu:/home/shbj/develop/workspace/c/procenv# ll permission
-rwxrwxr-x 1 root shbj 8665 Nov 20 17:42 permission*
可以看到文件所有者改变时,文件的设置-用户-ID位也会被清除
root@ubuntu:/home/shbj/develop/workspace/c/procenv# chmod u+s permission
root@ubuntu:/home/shbj/develop/workspace/c/procenv# ./permission
ruid = 0, euid = 0
ruid = 0, euid = 0
root@ubuntu:/home/shbj/develop/workspace/c/procenv# su shbj
shbj@ubuntu:~/develop/workspace/c/procenv$ ./permission
ruid = 1000, euid = 0
ruid = 1000, euid = 0
shbj@ubuntu:~/develop/workspace/c/procenv$
(2).将可执行文件的所有者设为普通用户,chmod u+s由root执行。
root@ubuntu:/home/shbj/develop/workspace/c/procenv# chown shbj permission
root@ubuntu:/home/shbj/develop/workspace/c/procenv# ll permission
-rwxrwxr-x 1 shbj shbj 8665 Nov 20 17:42 permission*
root@ubuntu:/home/shbj/develop/workspace/c/procenv# chmod u+s permission
root@ubuntu:/home/shbj/develop/workspace/c/procenv# ll permission
-rwsrwxr-x 1 shbj shbj 8665 Nov 20 17:42 permission*
root@ubuntu:/home/shbj/develop/workspace/c/procenv#
root@ubuntu:/home/shbj/develop/workspace/c/procenv# ./permission
ruid = 0, euid = 1000
ruid = 0, euid = 1000
root@ubuntu:/home/shbj/develop/workspace/c/procenv# su shbj
shbj@ubuntu:~/develop/workspace/c/procenv$ ./permission
ruid = 1000, euid = 1000
ruid = 1000, euid = 1000
shbj@ubuntu:~/develop/workspace/c/procenv$ su zhangsan
Password:
zhangsan@ubuntu:/home/shbj/develop/workspace/c/procenv$ ./permission
ruid = 1001, euid = 1000
ruid = 1001, euid = 1000
可以看到,进程在执行设置了设置-用户-ID位的可执行文件时,其有效用户id只与文件所有者有关,与谁设置了设置-用户-ID位无关。
二、int setuid(uid_t uid)
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
static void print_uid(){
long ruid, euid;
ruid = getuid();//get real uid
euid = geteuid();//get effective uid
printf("ruid = %ld, euid = %ld\n", ruid, euid);
}
int main(int argc, char const *argv[])
{
long ruid, euid;
print_uid();
setuid(1001);
print_uid();
return 0;
}
1.若进程具有超级用户权限,则setuid将实际用户id和有效用户id设为uid。
root@ubuntu:/home/shbj/develop/workspace/c/procenv# ll permission
-rwxrwxr-x 1 shbj shbj 8717 Nov 20 22:03 permission*
root@ubuntu:/home/shbj/develop/workspace/c/procenv# ./permission
ruid = 0, euid = 0
ruid = 1001, euid = 1001
2.若进程没有超级用户权限,但是uid等于实际用户id,则setuid将有效用户id设置为uid。
shbj@ubuntu:~/develop/workspace/c/procenv$ chmod u+s permission
shbj@ubuntu:~/develop/workspace/c/procenv$ ll permission
-rwsrwxr-x 1 shbj shbj 8717 Nov 20 22:03 permission*
shbj@ubuntu:~/develop/workspace/c/procenv$ su zhangsan
Password:
zhangsan@ubuntu:/home/shbj/develop/workspace/c/procenv$ ./permission
ruid = 1001, euid = 1000
ruid = 1001, euid = 1001