Unix 系统数据文件和信息

转自: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用户,则其用户数值ID0

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

l  shell字段包含一个可招待程序名,它被用于用户登录shell,若该字段为空,则取系统默认值。注意到squidshell字段被设置为/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.1MAC 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函数,关闭相应数据文件。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值