系统数据文件和信息之口令文件


UNIX系统的口令文件(POSIX.1则将其称为用户数据库)包含了表6-1中所示的各字段,这些字段包含在<pwd.h>中定义的passwd结构中。

注意,POSIX.1只指定了passwd结构包含的10个字段中的5个。大多数平台至少支持其中7个字段。

                                                        表6-1 /etc/passwd文件中的字段

::root:/root:/bin/::bin:/bin:/sbin/::daemon:/sbin:/sbin/::adm://adm:/sbin/nologin

nfsnobody:x:65534:65534:Anonymous NFS User:/var/lib/nfs:/sbin/nologin

关于这些登录项请注意下列各点:

  • 通常有一个用户名为root的登录项,其用户ID是0(超级用户)。
  • 加密口令字段包含了一个占位符。在早期的UNIX系统版本中,该字段存放加密口令。将加密口令存放在一个人人可读的文件中构成了一个安全性漏洞,所以现在将加密口令存放在另一个位置。
  • 口令文件项中某些字段可能是空。如果加密口令字段为空,这通常就意味着该用户没有口令(不推荐这样做)。注释字段为空,不产生任何影响。
  • shell字段包含了一个可执行程序名,它被用作该用户的登录shell。若该字段为空,则取系统默认值,通常是/bin/sh。注意,若某登录项的该字段为/dev/null,显然,这是一个设备,不能执行,因此将其用于此处的目的是,阻止任何人以该用户的名义登录到该系统。
  • 为了,除使用之外,还有若干种替代方法。一种常见的方法是,将用作登录shell。它简单地以不成功(非0)状态终止,该shell将此种终止状态判断为假。另一种常见的方法是,用禁止一个账户。它所作的一切是以成功(0)状态终止。某些系统提供命令,它打印可自定义的出错信息,然后以非0状态终止。
  • 使用nobody用户名的目的是,使任何人都可登录至系统,但其用户ID(65534)和组ID(65534)不提供任何特权。该用户ID和组ID只能访问人人皆可读、写的文件(假定用户ID65534和组ID65534并不拥有任何文件,而实际情况就应如此)。
  • 提供finger(1)命令的某些UNIX系统支持注释字段中的附加信息。其中,各部分之间都用逗号分隔:用户姓名、办公室地点、办公室电话号码以及家庭电话号码等。另外,如果注释字段中的用户姓名是一个&,则将其替换为登录名。

即使你所使用的系统并不支持finger命令,这些信息仍可存放在注释字段中,该字段只是一个注释,并不由系统使用程序解释。

某些系统提供了vipw命令,允许管理员使用该命令编辑口令文件。vipw命令串行化对口令文件所作的更改,并且确保所作的更改与其他相关文件保持一致。系统也常常经由图形用户界面(GUI)提供类似的功能。

POSIX.1只定义了两个获取口令文件项的函数。在

#include <pwd.h>
 passwd * passwd *getpwnam(   *

getpwuid函数由ls(1)程序使用,它将i节点中的数值用户ID映射为用户登录名。在键入登录名时,getpwnam函数由login(1)程序使用。

这两个函数都返回一个指向passwd结构的指针,该结构已由这两个函数在执行时填入信息。passwd结构通常是相关函数内的静态变量,只要调用相关函数,其内容就会被重写。

如果要查看的只是指定的某个登录名或用户ID所对应的passwd记录项,那么这两个函数能满足要求,但是也有些程序要。下列三个函数则可用于此种目的。

#include <pwd.h>

 passwd *getpwent(  setpwent(  endpwent(  );

调用getpwent时,它返回口令文件中的下一个记录项。如果上面所述的两个POSIX.1函数一样,它返回一个由它填写好的passwd结构的指针。每次调用此函数时都重写该结构。在第一次调用该函数时,它打开它所使用的各个文件。在使用本函数时,对口令文件中各个记录项的安排顺序并无要求。某些系统采用散列算法对/etc/passwd文件中的各项排序。

函数setpwent反绕它所使用的文件(rewinds  to  the  beginning  of the password database),endpwent则关闭这些文件(close the  password  database  after all processing has been performed)。在使用getpwent查看完口令文件后,一定要调用endpwent关闭这些文件。getpwent知道什么时间它应当打开它所使用的文件(第一次被调用时),但是它并不知道何时关闭这些文件。

程序清单6-1 getpwnam函数的一个实现

[root@localhost apue]# cat prog6-<pwd.h><stddef.h><.h>

 passwd *  * passwd *((ptr = getpwent()) !=(strcmp(name, ptr->pw_name) == ;          (ptr);    

在程序开始处调用setpwent是自我保护性的措施,以便在调用者在此之前已经调用getpwent打开了有关文件情况下,反绕有关文件使它们定位到文件开始处。getpwent和getpwuid调用完成后不应使有关文件仍处于打开状态,所以应调用endpwent关闭它们。

本篇博文内容摘自《UNIX环境高级编程》(第二版)。关于本书的更多内容可参考:http://www.apuebook.com/

相关内容