UNIX系统的口令文件(POSIX.1则将其称为用户数据库)包含了表6-1中所示的各字段,这些字段包含在<pwd.h>中定义的passwd结构中。
注意,POSIX.1只指定了passwd结构包含的10个字段中的5个。大多数平台至少支持其中7个字段。
表6-1 /etc/passwd文件中的字段
由于历史原因,口令文件存储在/etc/passwd中,而且是一个ASCII文件。每一行包含6-1中所示的各字段,字段之间用冒号分隔。例如,在linux上,该文件中可能有下列四行:
root:x:0:0:root:/root:/bin/bashbin:x:1:1:bin:/bin:/sbin/nologindaemon:x:2:2:daemon:/sbin:/sbin/nologinadm:x:3:4:adm:/var/adm:/sbin/nologin
nfsnobody:x:65534:65534:Anonymous NFS User:/var/lib/nfs:/sbin/nologin
关于这些登录项请注意下列各点:
即使你所使用的系统并不支持finger命令,这些信息仍可存放在注释字段中,该字段只是一个注释,并不由系统使用程序解释。
某些系统提供了vipw命令,允许管理员使用该命令编辑口令文件。vipw命令串行化对口令文件所作的更改,并且确保所作的更改与其他相关文件保持一致。系统也常常经由图形用户界面(GUI)提供类似的功能。
POSIX.1只定义了两个获取口令文件项的函数。在给出用户登录名或数值用户ID后,这两个函数就能查询相关项。
#include <pwd.h>struct passwd *getpwuid( uid_t uid );struct passwd *getpwnam( const char *name );两个函数返回值:若成功则返回指针,若出错则返回NULL
getpwuid函数由ls(1)程序使用,它将i节点中的数值用户ID映射为用户登录名。在键入登录名时,getpwnam函数由login(1)程序使用。
这两个函数都返回一个指向passwd结构的指针,该结构已由这两个函数在执行时填入信息。passwd结构通常是相关函数内的静态变量,只要调用相关函数,其内容就会被重写。
如果要查看的只是指定的某个登录名或用户ID所对应的passwd记录项,那么这两个函数能满足要求,但是也有些程序要查看整个口令文件。下列三个函数则可用于此种目的。
#include <pwd.h>struct passwd *getpwent( void );返回值:若成功则返回指针,若出错或到达文件结尾则返回NULLvoid setpwent( void );void endpwent( void );
调用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-1.c#include <pwd.h>#include <stddef.h>#include <string.h>struct passwd *getpwnam( const char *name ){ struct passwd *ptr; setpwent(); while((ptr = getpwent()) != NULL) if(strcmp(name, ptr->pw_name) == 0) break; /* found a match */ endpwent(); return(ptr); /* ptr is NULL if no match found */}
在程序开始处调用setpwent是自我保护性的措施,以便在调用者在此之前已经调用getpwent打开了有关文件情况下,反绕有关文件使它们定位到文件开始处。getpwent和getpwuid调用完成后不应使有关文件仍处于打开状态,所以应调用endpwent关闭它们。
本篇博文内容摘自《UNIX环境高级编程》(第二版)。关于本书的更多内容可参考:http://www.apuebook.com/。
新闻热点
疑难解答