本节书摘来自异步社区《UNIX网络编程 卷2:进程间通信(第2版)》一书中的第2章,第2.4节,作者:【美】W. Richard Stevens著,更多章节内容可以访问云栖社区“异步社区”公众号查看
2.4 IPC权限
新的消息队列、有名信号量或共享内存区对象是由其oflag参数中含有O_CREAT标志的mq_open、sem_open或shm_open函数创建的。如图2-4所注,权限位与这些IPC类型的每个对象相关联,就像它们与每个Unix文件相关联一样。
当同样由这三个函数打开一个已存在的消息队列、信号量或共享内存区对象时(或者未指定O_CREAT,或者指定了O_CREAT但没有指定O_EXCL,同时对象已经存在),将基于如下信息执行权限测试:
(1)创建时赋予该IPC对象的权限位;
(2)所请求的访问类型(O_RDONLY、O_WRONLY或O_RDWR);
(3)调用进程的有效用户ID、有效组ID以及各个辅助组ID(若支持的话)。
大多数Unix内核按如下步骤执行权限测试。
(1)如果当前进程的有效用户ID为0(超级用户),那就允许访问。
(2)在当前进程的有效用户ID等于该IPC对象的属主ID的前提下,如果相应的用户访问权限位已设置,那就允许访问,否则拒绝访问。
这里相应的访问权限位的意思是:如果当前进程为读访问而打开该IPC对象,那么用户读权限位必须设置;如果当前进程为写访问而打开该IPC对象,那么用户写权限位必须设置。
(3)在当前进程的有效组ID或它的某个辅助组ID等于该IPC对象的组ID的前提下,如果相应的组访问权限位已设置,那就允许访问,否则拒绝访问。
(4)如果相应的其他用户访问权限位已设置,那就允许访问,否则拒绝访问。
这4个步骤是按所列的顺序尝试的。因此,如果当前进程拥有该IPC对象(第2步),那么访问权的授予与拒绝只依赖于用户访问权限——组访问权限绝不会考虑。类似地,如果当前进程不拥有该IPC对象,但它属于某个合适的组,那么访问权的授予与拒绝只依赖于组访问权限——其他用户访问权限绝不会考虑。
我们从图2-3中指出,sem_open不使用O_RDONLY、O_WRONLY或O_RDWR标志。然而在10.2节我们将指出,某些Unix实现采用O_RDWR,因为只要使用一个信号量,都涉及读写该信号量的值。