Linux环境编程---系统数据文件

linux系统的正常运行需要使用大量与系统有关的数据文件,例如口令文件/etc/passwd和件/etc/group等,由于历史原因,这些数据文件都是ASCII文本文件,并且使用标准IO库读这些文件,对于较大的系统,顺序扫描这些文件很花费时间,我们需要能够以非ASCII文本格式存放这些文件。

口令文件

在posix中称为用户数据库,在linux中系统口令文件包含了用户名,加密口令,数值用户ID,数值组ID,注释字段,初始工作目录以及初始shell的字段,这些字段包含在<pwd.h>中定义的passwd结构中。下面用一个linux的口令文件做演示
在这里插入图片描述
关于这些登录项,需要注意下列各点

  • 首先超级用户root的用户ID是0
  • 加密口令字段包含了一个占位符,该字段存的是加密口令,可是因为把加密口令放在一个人人可读的文件中很不安全,所以现在是用另一个文件存加密口令,用占位符X标识占位符的存在
  • 口令文件中的某些字段可能为空,如果口令为空,那就意味着该用户没有口令(不推荐这么做)squid中有一个空白注释字段,不产生任何影响
  • shell字段包含了一个可执行程序名,它被用作用户的初始登陆shell若该字段为空则系统取默认值/bin/sh
  • 我们可以看到squid的初始shell是/dev/null,这个代表阻止任何人以squid的名义登陆,同时我们阻止一个用户登陆还可以将shell设置为/bin/false,他简单的以不成功状态终止
  • 使用nobody登陆的目的是让任何人都可登陆系统,但是用户ID与组ID不提供任何特权,只能访问人人可读写的文件

POSIX提供了两个获取口令文件的函数,再给出用户登录名或数值用户ID后,这两个函数就能查看相关项
struct passwd *getpwuid(uid_t uid);
struct passwd *getpwnam(const char *name);
这两个函数都返回指向passwd结构的指针,该结构已由这两个函数在执行的时候填入信息,passwd结构通常是函数内部的静态变量,只要调用任意一个相关函数,其内容就会被重写
如果想要看全部口令文件,可用下面三个函数
struct passwd *getpwent(void);
void setpwent(void);
void endpwent(void);
调用getpwent的时候,他返回口令文件的下一个记录向,如同上面的两个POSIX函数一样,他返回一个passed结构体指针每次调用此函数都哦重写该结构,第一次调用该函数的时候,他打开所使用的各个文件,在使用本函数的时候,对口令文件中各个记录向安排顺序并无要求。
函数setpwent反绕它所使用的文件,endpwent关闭这些文件

阴影口令

在我们刚看得到口令文件中加密口令由于安全性原因存在另一个文件里,我们一般用单向加密算法处理用户口令,单向可以保证我们不能通过加密后的口令推导出原口令,我们只能次次在键入指令后将键入指令加密然后与加密口令进行对比,可是由于用户的口令一般可以被猜测(就是你的密码大概率是你生日呀女票生日呀之类的)所以为了防止别人获取原始资料,我们将加密口令与相关数据存放在一个叫阴影口令的文件中,该文件至少包含用户名与加密口令等。
一般阴影口令中的数据如下图
在这里插入图片描述
那么我们用阴影口令文件来保护我们的加密口令,当然这个文件的权限也很难获取,只有少数几个程序可以获取,这些程序还必须经过root用户授权

组文件

口令文件是登陆用户的初始文件,在系统文件中还有组文件,linux中组文件包含的字段有组名,加密口令,数值组ID,指向各用户名指针的数组这几个字段,最后一个是一个指针数组,其中每一个指针指向一个属于该组的用户名,该数组以null指针结尾,可以用下列两个POSIX函数来查看组名或者数值组ID
struct group *getgrgid(gid_t gid);
struct group *getgrnam(const char *name);
如同对口令文件进行操作的函数一样,这两个函数的返回值也是一个静态变量的指针,在每次调用的时候都重写该静态变量

附属组ID

在最原始版本的时候,那个时候还没有附属组ID这个东西,用户每一次只能属于一个组,当用户登陆的时候,系统按照口令文件记录项中的数值组ID赋给他实际组ID当我们要进入其他组完成作业的时候就要用newgrp指令更改组,这样次次显性的更改的组ID很麻烦于是在1983年4.2BSD系统引入了附属组ID的概念,一个组除了他所在的组之外可以加入附属组,同时我们在验证一个文件的操作权限的时候先验证他的用户ID再验证组ID最后验证附属组ID就要就可以让用户不用改组参与多个项目提高效率。
为了获取与设置附属组ID于是提供了下面三个API
int getgroups(int size, gid_t list[]);
int setgroups(size_t size, const gid_t *list);
setgroups(): _BSD_SOURCE
getgroups将进程所属用户的各附属组ID填写到list中,最大数量是size个实际填写数量由函数返回,有一种特殊情况,如果size为0的话,函数只返回附属组ID数,而对list不做修改。setgroups可由超级用户调用以便为调用进程设置附属组ID表。list是组ID数组,而size是数组中元素数量

其他数据文件

到这里我们已经看了口令文件和组文件,在日常操作中linux还有很多文件,比如提供网络服务的网络文件,记录协议信息的数据文件等,幸运的是,对于这些数据文件的接口都与上述对口令文件和组文件的相似
一般情况下对于每一个数据文件至少有下面三个函数

  1. get函数:读下一个记录,如果需要,还要打开文件,此函数一般返回一个指向一个结构的指针,当已达到文件末尾的时候返回空指针,大多数get函数返回一个指向静态存储类结构的指针,如果保存其内容就要复制它。
  2. set函数:打开相应数据文件,然后反绕该文件,如果希望在相应文件起使开始处理,则调用此函数
  3. end函数:关闭相应数据文件,在结束了对相应数据文件的读写操作后,调用此函数关闭所有相关文件。

下面是一些常用的系统文件
在这里插入图片描述

登陆账户与系统标识

登陆账户记录

大多数linux系统提供下面两个数据文件:utmp文件记录当前登陆到系统的用户,wtmp记录每一个用户的登陆与注销。登陆的时候,login程序填写此类型结构,然后将他写入到utmp与wtmp中,注销的时候,init进程将utmp文件中相应的记录擦除,并将一个新记录写入到wtmp中。

系统标识

POSIX定义了返回主机与操作系统有关的API
int uname(struct utsname *buf);通过该函数传入一个utsname结构的地址,然后该函数填写此结构,每个数组的长度由实现确定,某些实现在该结构中提供了另一些字段
在这里插入图片描述
每一个字符串都用null结尾
如果宿主机连接到TCP/IP网络中,则该主机名通常是该主机的完整域名

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值