您的位置:首页 > 其它

Unix 系统数据文件和信息

2015-05-11 11:05 260 查看
转自:http://blog.csdn.net/litingli/article/details/5035047

第六章 系统数据文件和信息

系统正常运行需要使用大量系统数据文件,其中,所有UNIX系统都有的是:口令文件、组文件,大多数系统都提供的是:登录账户记录、系统标识、时间和日期例程,同时还有其他一些常用系统数据文件如:BSD网络软件有一个记录各网络服务器所提供服务的数据文件(/etc/services)、记录协议住处的数据文件(etc/protocols)等。

现在来按这个顺序讨论这些文件。

1、口令文件

口令文件包括了以下字段,这些字段包含在<pwd.h>中定义的passwd结构中:

说明

struct passwd成员

用户名

char *pw_name

加密口令

char *pw_passwd

数值用户ID

uid_t pw_uid

数值组ID

gid_t pw_gid

注释字段

char *pw_gecos

初始工作目录

char *pw_dir

初始shell(用户程序)

char *pw_shell

用户访问类

char *pw_class

下次更改口令时间

time_t pw_change

账户到期时间

time_t pw_expire

由于历史原因,口令文件存储在/etc/passwd中,并且是一个ASCII文件。每一行表示上表的各个字段,字段之间用冒号分隔。例如按照上面的字段顺序,passwd文件中可能会有如下内容:

squid:x:23:23::/var/spool/squid:/dev/null

sar:x:205:105:Litingli:/home/sar:/bin/bash

注:

l 如果是root用户,则其用户数值ID为0

l 口令文件项中某些字段可以为空

l shell字段包含一个可招待程序名,它被用于用户登录shell,若该字段为空,则取系统默认值。注意到squid中shell字段被设置为/dev/null这是一个设备,不能执行,这样做的目的是阻止任何人以用户squid的名义登录到该系统

某些UNIX系统提供finger(1)命令可用于查看注释字段中的信息,如对于以下记录:

sar:x:205:105:Litingli,scu,88-8888,66-6666:/home/sar:/bin/bash

注释字段的各个信息以逗号隔开:用户姓名,办公地点,办公电话,家庭电话等,使用finger(1)命令就可以打印注释字段中的信息:

#finger –p sar

Login:sar Name:Litingli

Directory:/home/sar Shell:/bin/sh

Office:88-8888 Home Phone:66-6666

On since Mon Jan 19 03:57 (EST) on ttyv0 (message off)

No mail

1.1查询口令文件

查询口令文件有两种方式:一种仅查询特定用户的记录,一种是查询文件中所有记录。

对于特定用户的查询,可以使用以下函数完成:

#include <pwd.h>

struct passwd *getpwuid(uid_t uid); //通过用户ID查询

struct passwd *getpwnam(const char* name); //通过用户名查询

对于所有记录的查询,可能使用以下函数完成:

#include <pwd.h>

struct passwd *getpwent(void);

void setpwent(void);

void endpwent(void);

调用getpwent时,返回口令文件中的下一个记录;setpwent反绕它所使用的文件,所谓反绕,是指使getpwent指向口令文件的开头,使其回到起点读取;最后,一定要使用endpwent关闭这些文件。

1.2编辑口令文件

某些系统提供vipw命令,允许管理员使用该命令编辑口令文件,此命令串行化对口令文件所做的修改(有点类似于锁的概念,串行化后,不会存在同时多个对口令文件的写操作),并确保所做的更改与其他相关文件保持一致。

2、阴影口令

之所以加入阴影口令,是出于安全的考虑,因为加密口令是经单向加密算法处理用户口令副本,由于其不可逆性,因此不能够将加密口令经过逆向算法还原成明文口令,但是这样也不能防止一些不法份子来猜口令,只要通过单向加密算法将猜测的明文口令变换成加密形式,然后将其与合法用户的加密口令对比,即可猜出(譬如不法份子可以申请一个账户,然后不断地修改其口令,每次修改后都查看一下口令文件中被加密的口令,看是否和合法用户的加密口令一样,那么他就找到了合法用户的明文口令了)。

可以发现,上面之所以不法份子能猜到合法用户的口令,是因为他可以查看口令文件中的加密口令,然后和他自己口令的加密形式来对比,就能猜出合法用户的口令。所以,只要将加密口令隐藏起来,使其无法获得原始资料,不法份子也就没法比较了。

这是就引入阴影口令的原因,现在我们将加密口令存放于阴影口令文件,而非前面提到的口令文件。阴影口令文件不是一般用户可以读取的,例如login(1)和passwd(1),这些函数必须要用户ID为root才能存取加密口令,所以就样就能很好的保护好“原始资料”。

明白了其工作原理,来看看其细节。阴影口令文件至少要包括用户名和加密口令。与该口令相关的其他信息也可存放在该文件中。在Linux2.4.22和Solaris 9中,有一组函数可以访问口令文件(其实这和前面查看口令文件的函数类似):

#include <shadow.h>]

struct spwd *getspnam(const char *name);

struct spwd *getspent(void);

void setspent(void);

void endspent(void);

FreeBSD5.2.1和MAC OS X10.3中,没有阴影口令结构。

3、组文件

UNIX组文件包含了以下字段:

说明

struct group成员

组名

char *gr_name

加密口令

char *gr_passwd

数值组ID

int gr_gid

指向各用户名的指针数组

char **gr_mem

同口令文件一样,组文件也分为两种查询方式:

对于特定组的查询可用以下函数:

#include <grp.h>

struct group *getgrgid(gid_t gid);

struct group *getgrnam(const char *name);

对于整个组文件的查询,可用以下三个函数,功能与口令文件的类似:

#include <grp.h>

struct group *getgrent(void);

void setgrent(void);

void endgrent(void);

4、附加组ID

为什么会出现一个附加组ID?这次和阴影口令不一样,并非出于安全的考虑。在传统UNIX中,每个用户任何时候只能属于一个组,当用户登录时,系统就会去查看口令文件中“数值组ID”这项,然后将此组ID赋于用户实际组ID(有点类似于一个人只能有一种国籍,要么是中国国籍,要么就是别国国籍)。这种组成员形式一直维持到1983年左右,后来在BSD4.2中引入了附加组ID,用户不仅可以属于口令文件中记录的组ID,而且还可以属于其他的组(这就类似于一个人在取得中国国籍之后,还可以取得其他国家的国籍)。

附加组ID的优点在于:不必显式地经常更改组。可以通过以下三个函数来获取和设置组ID:

#include <unistd.h>

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

#include <grp.h>

#include <unistd.h>

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

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

对于这些函数不再做过多说明。

另外,需要说明的是,在很多系统中,用户和组数据库是用网络信息服务(Network Information Service ,NIS)实现的,这使管理员可编辑数据库的主副本,然后将它分发到组织中的所有服务器上,客户端系统可以联系服务器以查看用户和组的有关信息。

5、登录账户记录

大多数UNIX系统者提供下列两个数据文件:utmp和wtmp文件,分别用于记录当前登录进系统的各个用户,跟踪各个登录、注销事件。在V7中,这两个文件都包含如下结构:

struct utmp{

char ut_line[8]; /*tty line: “ttyh0”,”ttyd0”,”ttyp0”,…*/

char ut_name[8]; /*login name*/

long ut_time; /*seconds since Epoch*/

};

登录时,login程序填写此类型结构,然后将其写入到utmp文件中,同时也添写其 wtmp文件中;注销时,init进程将utmp文件中相应的记录擦除(每个字节都填为0),并将一个新记录添写到wtmp文件中,在wtmp文件的注销记录中,将ut_name字段清0;在系统重启、更改系统时间和日期前后,都在wtmp文件中添写特殊的记录项。

who(1)程序读utmp文件,并以可读格式打印其内容;后来的UNIX版本提供了last(1)命令,它读wtmp文件并打印所选择的记录。

6、系统标识

可以通过uname函数得到当前主机和操作系统的有关信息:

#include <sys/utsname.h>

int uname(struct utsname *name);

该函数所用的数据结构如下(下面列出的只是POSIX.1定义的至少需要的字段,某些实现在该结构中提供了另外一些字段):

struct utsname{

char sysname[]; /*name of OS*/

char nodename[]; /*name of this node*/

char release[]; /*current release of operating system*/

char version[]; /*current version of this release*/

char machine[]; /*name of the hardware type*/

};

另外,BSD系统提供了gethostname函数(目前它已是POSIX.1的一部份),它只返回主机名,该名字通常是TCP/IP网络上主机的名字。

当然除了可以获取主机名之外,我们还需要设置主机名,hostname(1)命令可以二者都实现,超级用户则可以使用一个类似的函数sethostname用于设置主机名。

7、时间和日期例程

UNIX内核提供的基本时间服务是计算处国际标准时间公元1970年1月1日00:00:00以来经过的秒数,它是用数据类型time_t表示的,我们称其为日历时间:包括日期和时间。

time函数可以返回当前时间和日期:

#include <time.h>

time_t time(time_t *calptr);

与time函数相比,gettimeofday提供了更高的分辨率(最高为微秒级):

#include <sys/time.h>

int gettimeofday(struct timeval *restrict tp, void *restrict tzp);

其中,结构timeval定义如下:

struct timeval{

time_t tv_sec;

long tv_usec; /*microseconds*/

};

一旦获得这种以秒计的整型时间值后,通常要调用另一个时间函数将其转换为人们可读的时间和日期,下图说明了各个函数之间的关系:



结构tm定义如下(注意每个成员的范围):

struct tm{ /*a broken-down time*/

int tm_sec; /*seconds after the minute:[0-60]

int tm_min; /*minutes after the hour:[0-59]

int tm_hour; /*hours after midnight:[0-23]*/

int tm_mday; /*day of the month[1-31]*/

int tm_mon; /*months since January[0-11]*/

int tm_year; /*years since 1900*/

int tm_wday; /*days since Sunday:[0-6]*/

int tm_yday; /*days since January 1:[0-365]*/

int tm_isdst; /*datlight saving time flag:<0,0,>0*/

};

8、其他数据结构

在开头,已经提到了还有一些其他常用的数据文件,如:BSD网络软件有一个记录各网络服务器所提供服务的数据文件(/etc/services)、记录协议住处的数据文件(etc/protocols)等。幸运的是,针对这些数据的端口都与口令文件和组文件接口相似

1、 set函数,打开相应数据文件,然后反绕该文件。

2、 end函数,关闭相应数据文件。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐