UNIX口令文件包含了以下图所示的个字段,这些字段包含在<pwd.h>中定义的passwd结构中。node
口令文件是/etc/passwd,并且是一个ASCII文件。每一行包含以下图所示的各字段,用冒号分隔,通常结构是算法
LOGNAME:PASSWORD:UID:GID:USERINFO:HOME:SHELL
关于这些登陆项,注意下面各点:shell
提供finger(l)命令的某些支持注释字段中的附加信息。如: 数组
#include <pwd.h> struct passwd *getpuid(uid_t uid);//给出用户id获取口令文件项 struct passwd *getpwnam(const char *name);//给出用户名获取口令文件项 //返回值:若成功,返回指针;若出错,返回NULL
这两个函数都返回一个指向passwd结构的指针。该结构已由这两个函数在执行时填入信息。passwd结构一般是函数内部的静态变量,只要调用任一相关函数,其内容就会被重写。安全
调用getpwent时,他返回口令文件的下一个记录项。每次调用此函数都重写passw结构。 函数setpwent反绕它所使用的文件,endpwent则关闭这些文件。在使用getpwent查看完口令文件后,必定要调用endpwent关闭这些文件。网络
#include <pwd.h> struct passwd *getpwent(void); //返回值:若成功,返回指针;若出错或者到达文件尾端,返回NULL void setpwent(void); void endpwent(void);
demo函数
#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) breakl; } endpwent(); return ptr; }
加密口令是通过单项加密算法处理过的用户口令副本。由于此算法是单向的,因此不能从加密口令猜想到原来的口令。为了避免让人得到原始资料(加密口令),如今,某些系统将加密口令存放在另外一个阴影口令(shadow password)文件中。该用户至少包含用户名和加密口令。与该口令相关的其余信息也能够存放在该文件中。ui
只有用户登陆名和加密口令这两个字段是必须的,阴影口令文件不该是通常用户能够读取的。 有一组函数能够访问阴影口令文件。加密
#include <shadow.h> struct spwd *getspnam(const char *name); struct spwd *getspent(void); //两个函数返回值:若成功,返回指针;若出错,返回NULL void setspent(void); void endspent(void);
字段gr_mem是一个指针数组,其中每一个指针指向一个属于该组的用户名。该数组以null指针结尾。 能够用下面函数查看组名或数值组ID。spa
#include <grp.h> struct group *getgrpid(gid_t gid); struct group *getgrnam(const char *name); //返回值:若成功,返回指针;出错,返回NULL
这两个函数也返回一个静态变量的指针,在每次调用时都重写该静态变量。 若要搜索整个组文件,则使用另外几个函数。
#include <grp.h> struct group *getgrent(void); //返回值:若成功,返回指针;;若出错或者到达文件尾端,返回NULL void setgrent(void); void endgrent(void);
在UNIX系统中,对组的使用已经作了更改。在V7中,每一个用户任什么时候候都只属于一个组。当用户登陆时,系统就按口令文件记录项中的数值组ID,付给他实际组ID。能够在任什么时候候执行newgrp(l)以更改组ID。若是newgrp执行成功,则实际组ID更改成新的组ID,将用于后续的文件访问权限检查。执行不带任何参数的newgrp,则可返回到原来的组。
在使用附属组时,咱们不只能够属于口令文件记录项中组ID所对应的的组,也可属于多至16个另外的组。文件访问权限检查相应的被修改成:不只将进程的有效组ID与文件的组ID进行比较,并且也将全部附属组ID与文件的组ID进行比较。
使用附属组ID的有点事没必要显式的常常更改组。一个组用户会参与多个项目,所以也就要同时属于多个组。
为了获取和设置组ID,提供以下函数
#include <unistd.h> int getgroups(int gidsize, gid_t grouplist[]); //返回值:若成功,返回附属组ID数量;若出错,返回-1 #include <grp.h> int setgroups(int ngroups, const gid_t grouplist[]); #include <grp.h> int initgroups(const char *username, gid_t basegid); //两个函数返回值:若成功,返回0;出错,返回-1
UNIX还有不少其余文件,如记录各网络所提供服务的数据文件(/etc/services),有一个记录协议信息的数据文件(/etc/networks)。
通常状况下,对于每一个数据文件至少有3个函数。
以下为访问系统数据文件的一些例程:
/* 大多数UNUX系统都提供下列两个数据文件:utmp文件记录当前登录到系统的各个用户:wtmp文件跟踪各个登录和注销事件。 每次写入这两个文件的是包含下列结构的一个二进制记录: */ struct utmp { char ut_line[8];/* tty line: "ttyh0","ttyd0", "ttyp0,..." */ char ut_name[8]; /*login name*/ long it_time; /*seconds since Epoch*/ };
登陆时,login程序填写此类型结构,而后将其写入到utmp文件中,同时也将其添写到wtmp文件中。注销时,init进程将utmp文件中相应记录擦除,并将一个新纪录添写到wtmp文件中。在wtmp文件的注销记录中,ut_name字段清除为0.在系统再启动时,以及更改系统时间和日期的先后,都在wtmp文件中追加特殊的记录项。who(l)程序读取utmp文件,并以可读格式打印其内容。后来的UNIX版本提供last(l)命令,它读wtmp文件并打印所选择的记录。
#include <sys/utsname.h> int uname(struct utsname *name);//返回与主机和操做系统有关的信息 //返回值:若成功,返回非负值;若出错,返回-1 struct ustname { char sysname[]; //操做系统名称 char nodename[]; //节点名 char release[]; //当前发行的操做系统 char version[]; //系统版本 char machine[]; //硬件类型名 }; //每一个字符串都以null字节结尾。utsname结构中的信息一般用uname(l)命令打印 /* namelen参数指定name缓冲区长度,如若提供足够的空间,则经过name返回的字符串以null字节结尾。如若没有提供足够的空间,则没有说明经过name返回的字符串是否以null结尾。 若是宿主主机链接到TCP/IP网络中,则此主机名一般是该主机的完整域名。 hostname(l)命令可用来获取和设置主机名。 */ #include <unistd.h> int gethostname(char *name, int namelen); //返回值:若成功,返回0;若出错,返回-1