APUE学习笔记(5)-设置用户ID

写在前面

1.          本文内容对应《 UNIX 环境高级编程》 ( 2 ) 》第 4 章。

2.          总结了用户 ID 和文件访问权限检查的概念,以及设置用户 ID 的用法。

3.          希望本文对您有所帮助,也欢迎您给我提意见和建议。

 


用户

ID

一个进程与两类 ID 相关:

l          实际用户 ID 和实际组 ID ,用于标识用户究竟是谁。这两个字段在登录时取自口令文件中的登录项。可以使用 getuid getgid 函数查询。

l          有效用户 ID 和有效组 ID ,与附加组 ID 一起,用于文件访问权限检查。可以使用 geteuid getegid 函数查询。通常,等于实际用户 ID 和实际组 ID

一个文件仅将其所有者 ID 和所有组 ID 记录在 stat 结构的 st_uid st_gid 字段。

 


文件访问权限检查

进程每次打开,创建或删除一个文件时,内核就进行文件访问权限检查。内核按顺序执行以下四步,一旦满足就停止检查:

l          若进程的有效用户 ID 0 (超级用户),则允许访问。

l          若进程的有效用户 ID 等于文件的所有者 ID ,并且所有者适当的访问权限位被设置,则允许访问,否则拒绝访问。

l          若进程的有效组 ID 或进程的附加组 ID 之一等于文件的组 ID ,并且适当的访问权限位被设置,则允许访问,否则拒绝访问。

l          若其他用户适当的访问权限位被设置,则允许访问,否则拒绝访问。

 


设置用户

ID

可以看到,权限检查依赖于有效 ID ,而与实际 ID 无关。使用 access 函数可以按照实际用户 ID 和实际组 ID 进行权限检查。通常,进程的有效 ID 等于实际 ID 。一个例外是使用设置用户 ID 位和设置组 ID 位。如果一个程序文件的设置用户 ID 位被置位,那么,当执行此文件时,将进程的有效用户 ID 设置为文件所有者 ID st_uid )。设置组 ID 的机制与此类似。文件的设置用户 ID 位和设置组 ID 位包含在 stat 结构的 st_mode 字段中,可用宏 S_ISUID S_ISGID 测试。

         实验程序如下:

#include <stdio.h>

#include <stdlib.h>

#include <unistd.h>

#include <fcntl.h>

#include <sys/stat.h>

 

int main(int argc, char *argv[])

{

     struct stat st;

 

     if(argc != 2)

     {

       printf("usage: a.out <filename>./n");

       exit(0);

     }

     stat(argv[1], &st);

     printf("uid=%d, gid=%d, euid=%d, egid=%d./n",

         getuid(), getgid(), geteuid(), getegid());

     printf("%s: st_uid=%d, st_gid=%d./n", argv[1], st.st_uid, st.st_gid);

     if(access(argv[1], R_OK) < 0)

       printf("access error for %s./n", argv[1]);

     else

       printf("access ok for %s./n", argv[1]);

     if(open(argv[1], O_RDONLY) < 0)

       printf("open error for %s./n", argv[1]);

     else

       printf("open ok for %s./n", argv[1]);

     exit(0);

}

         运行结果为:

pydeng@pydeng-laptop:~/apue.2e/mytest$ sudo su

root@pydeng-laptop:/home/pydeng/apue.2e/mytest# chown root a.out

root@pydeng-laptop:/home/pydeng/apue.2e/mytest# chmod u+s a.out

root@pydeng-laptop:/home/pydeng/apue.2e/mytest# ls -l a.out

-rwsr-xr-x 1 root pydeng 9566 2009-08-12 19:28 a.out

root@pydeng-laptop:/home/pydeng/apue.2e/mytest# exit

pydeng@pydeng-laptop:~/apue.2e/mytest$ ./a.out /etc/shadow

uid=1000, gid=1000, euid=0, egid=1000.

/etc/shadow: st_uid=0, st_gid=42.

access error for /etc/shadow.

open ok for /etc/shadow.

 


新文件和目录的所有权

新文件的用户 ID 设置为进程的有效用户 ID 。至于组 ID 有些复杂。在 linux 下,新文件的组 ID 取决于它所在目录的设置组 ID 位是否设置。如果该目录的这一位已经设置,则将新文件的组 ID 设置为目录的组 ID ,否则将新文件的组 ID 设置为进程的有效组 ID

实验程序如下:

#include <stdio.h>

#include <stdlib.h>

#include <fcntl.h>

#include <sys/stat.h>

 

int main(int argc, char *argv[])

{

     struct stat st;

 

     if(argc != 2)

     {

       printf("usage: a.out <filename>./n");

       exit(0);

     }

     if(open(argv[1], O_CREAT) < 0)

     {

       printf("create file error./n");

       exit(0);

     }

     stat(argv[1], &st);

     printf("%s: st_uid=%d, st_gid=%d./n", argv[1], st.st_uid, st.st_gid);

     exit(0);

}

         运行结果为:

pydeng@pydeng-laptop:~/apue.2e/mytest$ sudo su

root@pydeng-laptop:/home/pydeng/apue.2e/mytest# chmod 777 /usr/

root@pydeng-laptop:/home/pydeng/apue.2e/mytest# exit

pydeng@pydeng-laptop:~/apue.2e/mytest$ ./a.out /usr/mytemp

/usr/mytemp: st_uid=1000, st_gid=1000.

 

pydeng@pydeng-laptop:~/apue.2e/mytest$ sudo su

root@pydeng-laptop:/home/pydeng/apue.2e/mytest# chmod g+s /usr/

root@pydeng-laptop:/home/pydeng/apue.2e/mytest# ls -l /

drwxrwsrwx  12 root root  4096 2009-08-12 19:46 usr

...

root@pydeng-laptop:/home/pydeng/apue.2e/mytest# exit

pydeng@pydeng-laptop:~/apue.2e/mytest$ ./a.out /usr/mytemp2

/usr/mytemp2: st_uid=1000, st_gid=0.

 

pydeng@pydeng-laptop:~/apue.2e/mytest$ sudo su

root@pydeng-laptop:/home/pydeng/apue.2e/mytest# chmod g-s /usr

root@pydeng-laptop:/home/pydeng/apue.2e/mytest# chmod 755 /usr

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值