分类: 系统运维
2012-03-29 12:31:24
UNIX系统里组的使用随着时间发生了变化。在版本7,每个用户在任何时刻只属于某一个组。当我们登录的时候,我们被分配给真实组ID,对应于我们密码文
件项的数值组ID。我们可以在任何时候执行newgrp来修改它。如果newgrp命令成功(参考权限规则的手册页),我们的真实组ID被改为新组的
ID,而这会被后续的所有文件访问权限检查所使用。我们总是可以回到我们原始的组,通过执行无任何参数的newgrp。
这个组成员关系直到4.2BSD(1983年前后)才发生变化。在4.2BSD里,引入了补充组ID的概念。我们不仅属于对应于密码文件项里组ID表示的
组,同时还属于最多16个补充的组。文件访问权限检查被修改,以致不仅有效组ID会与文件组ID比较,同时所有的补充组ID也会和文件组ID比较。
补充组ID是POSIX.1所要求的一个特性。(在POSIX.1的早期版本,它们是可选的。)常量NGROUPS_MAX(第2章)指定了补充组ID的数量。一个普遍的值是16。
使用补充组ID的好处是我们不再需要显式地改变组。在同一时间同时属于多个组(也就是说,参与了多个项目)并不是不常见。
有三个函数用来得到和设置补充组ID。
在这三个函数中,只有getgroups是POSIX.1指定的。因为setgroups和initgroups是需要权限的操作,它们不是POSIX.1的一部分。然而,本文提到的四个平台都支持了这三个函数。
在Mac OS X 10.3,basegid被定义为int类型。
getgroups函数用补充组ID填充了数组grouplist。最多gidsetsize个元素被存储到这个数组里。函数返回被存储到数组的补充组ID的数量。
作为一个特殊情况,如果gidsetsize为0,函数只返回补充组ID的数量。数组grouplist不会被修改。(这允许调用都决定要分配的grouplist数组的大小。)
setgroups函数可以被超级用户调用来为调用进程设置补充组ID列表:grouplist包含了组ID的数组,而ngroups指定了数组元素的数量。ngroups的值不能比NGROUPS_MAX大。
setgroups唯一的使用经常是通过initgroups函数,它读取整个组文件--我们早先描述的通过函数getgrent、setgrent和
endgrent--并决定username的组成员关系。它接着调用setgroups来为这个用户初始化补充组ID。必须是超级用户才能调用
initgroups,因为它调用了setgroups。除了组文件里找到所有username所属的组,initgroups还把basegid包含在
补充组ID列表里,basegid是密码文件的username的组ID。
initgroups只被很少的程序调用:例如loing程序当我们登录时调用它。