Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1738824
  • 博文数量: 438
  • 博客积分: 9799
  • 博客等级: 中将
  • 技术积分: 6092
  • 用 户 组: 普通用户
  • 注册时间: 2012-03-25 17:25
文章分类

全部博文(438)

文章存档

2019年(1)

2013年(8)

2012年(429)

分类: 系统运维

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。



  1. #include <unistd.h>

  2. int getgroups(int gidsetsize, gid_t grouplist[]);

  3. 成功返回补充组ID的数量,错误返回-1。

  4. #inlcude <grp.h> /* on Linux */

  5. #inlcude <unistd.h> /* on FreeBSD, Mac OS X, and Solaris */

  6. int setgroups(int ngroups, const gid_t grouplist[]);

  7. #inlcude <grp.h> /* on Linux and Solaris */

  8. #inlcude <unistd.h> /* on FreeBSD and Mac OS X */

  9. int initgroups(const char *username, gid_t basegid);

  10. 两者成功都返回0,否则返回-1。


在这三个函数中,只有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程序当我们登录时调用它。

阅读(2123) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~