IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 系统运维 -> UNIX环境高级编程 学习笔记 第六章 系统数据文件和信息 -> 正文阅读

[系统运维]UNIX环境高级编程 学习笔记 第六章 系统数据文件和信息

UNIX系统口令文件(POSIX.1称其为用户数据库)包含以下字段,这些字段也包含在头文件pwd.h中定义的passwd结构中:
在这里插入图片描述
由于历史原因,口令文件是一个ASCII文件,其中的每行都包含以上各字段,字段之间用冒号分隔。

有关口令文件的登录项的注意点:
1.通常有一个用户名为root的登录项,用户ID为0,是超级用户。
2.加密口令字段是一个占位符x,较早期的UNIX系统版本中,该字段存放加密后的密码,但将加密后的密码放在一个人人可读的文件中是一个安全漏洞,所以现在将加密口令放在另一个文件中。
3.某些字段可能为空(连续两个冒号表示两个冒号之间的字段为空)。如加密口令字段为空,则用户没有口令。空白注释字段没有任何影响。
4.shell字段包含一个可执行程序名,它被用作该用户的登录shell,此字段为空时,默认值为/bin/sh。用户squid的登录项的shell字段为/dev/null,这是一个设备而非可执行文件,目的是阻止任何人以用户squid登录到系统。
5.shell字段填为/bin/false时也可阻止特定用户登录系统,它简单地以不成功(非0)状态终止;shell字段也可填为/bin/true来阻止特定用户登录,它以成功(0)状态终止。某些系统提供nologin命令,它打印可定制的出错信息,然后以非0状态终止。
6.nobody用户名使任何人都能登录系统,它的用户ID(65534)和组ID(65534)不提供任何特权。该用户ID和组ID只能访问人人都可读写的文件(假设用户65534和组65534不拥有任何文件,实际就应该如此)。
7.提供finger命令的某些UNIX系统支持返回注释字段中的附加信息给调用者,finger命令要求注释字段按顺序包含各部分内容:用户姓名、办公室地点、办公室电话号、家庭电话号,各部分之间用逗号分隔,注释字段中的&会被替换为登录名:
在这里插入图片描述
注释字段只是一个注释,不由系统实用程序解释。

某些系统提供vipw命令,允许管理员通过此命令编辑口令文件,此命令串行化地更改口令文件,且确保它所做的更改与其他相关文件保持一致,系统也常常由图形用户界面(GUI)提供类似的功能。

POSIX.1定义了两个获取口令文件项的函数,给出用户登录名或UID后,就能查看相关项:
在这里插入图片描述
ls命令会使用getpwuid函数,将文件i节点中的数字用户ID映射为用户登录名。login命令会使用getpwnam函数。

以上函数返回的passwd结构通常是函数内部的静态变量,再次调用其内容会被重写。

SUS的XSI扩展中的有关口令文件的函数,可期望所有UNIX实现都提供了这些函数,但POSIX.1标准没有定义这三个函数:
在这里插入图片描述
每次调用getpwent时,它返回口令文件中的下一个记录项(首次调用时,在返回第一条口令文件项前,还会做打开口令文件操作),每次调用此函数时都重写返回的passwd结构。对此函数返回的口令文件项的顺序无要求,有些系统使用散列算法对口令文件中各项排序。

setpwent函数rewind到口令文件的开头,使得下次调用getepwent时返回第一条口令文件项。

endpwent函数会关闭getpwent函数打开的口令文件,用这个函数关闭打开的口令文件的原因是getpwent函数不知道何时应该关闭口令文件。

getpwnam函数的一个实现:

#include <pwd.h>
#include <string.h>

struct passwd *getpwnam(const char *name) {
    struct passwd *ptr;

    setpwent();    // 确保调用者在以前已经调用getpwent打开了口令文件的情况下,rewind到文件开始处
    while ((ptr = getpwent()) != NULL) {
        if (strcmp(name, ptr->pw_name) == 0) {
		    break;
		}
    }
    endpwent();
    return ptr;    // ptr is NULL if no match found
}

加密口令是经单向加密算法处理过的用户口令副本,不能从加密口令反变换到原来的口令,但可对口令进行猜测,将猜测的口令经单向算法变换成加密形式,然后将其与用户的加密口令相比较。

某些系统将加密口令存放在阴影口令文件中,该文件至少要包含用户名和加密口令,与该口令相关的其他信息也可放在该文件中:
在这里插入图片描述
阴影口令文件不应是一般用户可以读取的,仅有少数几个程序需要访问加密口令,如login、passwd,这些程序常常是设置用户ID为root的程序。

Linux 3.2.0和Solaris 10中访问阴影口令文件的函数:
在这里插入图片描述
FreeBSD 8.0和Mac OS X 10.6.8中没有阴影口令结构,这两个系统中附加的账户信息(如账户有效期)存放在口令文件中。

UNIX组文件(POSIX.1称其为组数据库)包含以下字段,这些字段包含在头文件grp.h定义的group结构中:
在这里插入图片描述
字段gr_mem是一个指针数组,其中每个指针指向一个属于该组的用户名,该数组以null指针结尾。

POSIX.1定义的返回指定组的group结构的函数:
在这里插入图片描述
这两个函数也常返回指向一个静态变量的指针,每次调用时都重写该静态变量。

搜索整个组文件(由SUS的XSI扩展定义,不是基本POSIX.1组成,所有UNIX都提供这3个函数):
在这里插入图片描述
setgrent函数打开组文件(如它尚未打开)并rewind它。

用户执行newgrp命令可更改实际组ID,执行不带参数的newgrp命令可回到与该用户名相同的预设组。

4.2 BSD引入了附属组ID,一个用户除了属于一个组外,还可属于至多16个另外的附属组。文件访问权限也修改为:不仅将进程的有效组ID与文件的组ID相比,也将所有附属组ID与文件的组ID比较。

POSIX.1早期版本中附属组ID特性是可选的。常量NGROUPS_MAX规定了附属组ID的数量,常用值为16。

获取和设置附属组ID的函数:
在这里插入图片描述
POSIX.1只说明了getgroups函数,因为setgroups和initgroups函数是特权操作,所以它们并非POSIX.1的组成部分。Mac OS X 10.6.8中,basegid类型为int。

getgroups函数将进程所属用户的各附属组ID填到grouplist中,填入数量最多是参数gidsetsize个,返回实际填写到数组中的附属组ID数。如果参数gidsetsize为0,则函数不修改grouplist参数,但仍返回附属组ID数,这样可确定grouplist参数数组的长度,以便进行分配空间。

setgroups函数可由root用户调用为调用进程设置附属组ID表,参数grouplist是组ID数组,参数ngroups说明了数组中的元素数(此值不能大于NGROUPS_MAX)。

通常只有initgroups函数调用setgroups函数(因此initgroups函数也需要超级用户权限),initgroups函数一般读整个组文件,然后用组文件中数据初始化username参数表示的用户的附属组,参数basegid也会加入用户的附属组中。login命令在用户登录时会调用此函数。

不同平台存储用户和组信息的方式:
在这里插入图片描述
Mac OS X只在单用户模式下使用/etc/passwd和/etc/master.passwd(单用户模式下没有任何系统提供的服务),在正常的多用户模式期间,目录服务守护进程提供对用户和组账户信息的访问。

对于阴影口令文件中的不活动字段,Solaris将其定义为自用户上次登录后到下次账户自动失效之间的天数,Linux将其定义为达到口令失效的尚余天数。

很多系统中,用户和组数据库是用网络信息服务(Network Information Service,NIS)实现的,管理员可编辑数据库的主副本,然后将它自动分发到组织中所有服务器上,客户联系服务器查看用户和组的有关信息,NIS+轻量级目录访问协议(Lightweight Directory Access Protocol,LDAP)提供了类似功能。很多客户通过配置文件/etc/nsswitch.conf控制管理每一类信息的方法。

对于除口令文件和组文件外的一些系统数据文件,一般为每个数据文件至少提供3个函数:
1.get函数:读下一条记录,如果要读的文件未打开,则先打开该文件,此函数通常返回指向一个结构的指针,该指针指向一个静态存储类结构,当到达文件尾端时返回空指针。
2.set函数:打开相应数据文件(如果该文件未打开),然后rewind该文件。
3.end函数:关闭相应数据文件。

除以上3个函数外,如果数据文件支持某种形式的键搜索,则也提供搜索指定键数据的例程,如口令文件有getpwnam函数搜索指定用户名的记录和getpwuid函数搜索指定用户ID的记录。

在这里插入图片描述
FreeBSD中,阴影口令文件是/etc/master.passwd,可使用特殊命令编辑该文件,该命令会产生阴影口令文件的一个副本,该副本名为/etc/passwd;另外,此命令也产生一个/etc/master.passwd文件的散列副本(/etc/spwd.db)和一个/etc/passwd的散列副本(/etc/pwd.db),这些散列副本为更大的系统提供更好的性能。

Solaris中,上图里的最后4个文件都是符号链接,链接到/etc/inet下的同名文件上。

大多UNIX系统都提供下列两个数据文件:utmp文件记录当前登录到系统的各个用户;wtmp文件跟踪各个登录和注销事件。在V7中,这两个文件中写入的是以下结构的一个二进制记录:
在这里插入图片描述
登录时,login程序填写此类型结构,然后将其写入utmp文件和wtmp文件,注销时,init进程将utmp文件中的相应记录擦除(每个字节都填为null字节),并将一个新纪录(此记录的ut_name字段为null)添加到wtmp文件中。在系统重启动后和更改系统时间前后,都会在wtmp文件追加特殊的记录项。who命令读取utmp,并以可读形式打印其中内容(当前登录用户信息);last命令读wtmp文件并打印其中记录。

utmp结构中的信息在V7中有20字节,在SVR2中被扩充为36字节,而在SVR4中被扩充为多于350字节。

Solaris中,utmp和wtmp文件在/var/adm目录下;FreeBSD 8.0和Linux 3.2.0中,这两个文件的路径为/var/run/utmp和/var/log/wtmp;Mac OS X 10.6.8中,utmp和wtmp文件不存在。

POSIX.1定义的返回与主机和操作系统相关信息的函数:
在这里插入图片描述
此函数会填写传入到name参数的utsname结构,POSIX.1只定义了该结构中最少需提供的字段,这些字段都是以null结尾的字符数组,每个数组的长度由实现确定:
在这里插入图片描述
utsname结构中的内容可由uname命令打印。

utsname结构没有给出POSIX.1版本信息,应使用宏_POSIX_VERSION获得此信息。

BSD派生的系统提供gethostname函数,它只返回主机名,该名字通常是TCP/IP网络上主机的名字(完整域名),但我运行时返回的是本地主机名:
在这里插入图片描述
namelen参数指定name参数的长度,如果空间足够,则返回的字符串以null结尾,否则不确定。

现在POSIX.1也定义了gethostname函数,该标准指定最大主机名长度为HOST_NAME_MAX。

在这里插入图片描述
hostname命令可获取和设置主机名,主机名通常在系统自举时设置,文件名由程序/etc/rc或init取自一个启动文件。

UNIX内核提供的基本时间服务是计算自协调世界时(Coordinated Universal Time,UTC)以来经过的秒数,这个秒数存放于数据类型time_t,称其为日历时间。

返回当前的UNIX时间戳:
在这里插入图片描述
时间戳作为函数值返回,如果参数calptr非空,时间戳同时也存放在该参数指向的空间。

POSIX.1的实时扩展增加了对多个系统时钟的支持,在SUS v4中,控制这些时钟的接口从可选组移到基本组。时钟通过clockid_t类型进行标识:
在这里插入图片描述
以下函数可获取特定时钟的时间:
在这里插入图片描述
当参数clock_id设为CLOCK_REALTIME时,由于timespec结构把时间表示为秒和纳秒,因此在系统支持高精度时间值得情况下,colck_gettime函数比time函数的精度更高。

获取特定时钟的精度:
在这里插入图片描述
如果参数clock_id表示的时钟的精度为1毫秒,则tsp参数指向的timespec结构的tv_sec字段为0,tv_nsec字段为1000000。

设置特定时钟的时间:
在这里插入图片描述
更改时钟值需要特权,有些时钟是不能修改的。

System V派生的系统使用stime函数设置系统时间;BSD派生的系统使用settimeofday函数设置系统时间。

SUS v4指定gettimeofday函数已经弃用,但还用很多程序使用它,因为它相比于time函数能提供更高的精度(微秒级):
在这里插入图片描述
tzp参数的唯一合法值是NULL,其他值会产生不确定的结果,某些平台用tzp参数说明时区,这完全依实现而定,SUS对此没有定义。

gettimeofday函数返回以timeval结构表示的UNIX时间戳,该结构将UNIX时间戳表示为秒和微秒。

取得UNIX时间戳后,通常调用函数将其转换为tm结构:
在这里插入图片描述
然后通常调用另一函数将tm结构转换为人可读的时间和日期,各个时间函数之间的关系:
在这里插入图片描述
上图中用虚线表示的函数受环境变量TZ的影响,它们会用TZ的值代替系统默认时区,如果TZ定义为空串,则使用UTC。

tm结构中秒的最大值超过59,原因是这样可以表示闰秒;除月、日外,tm结构中其他字段都以0开始;如果夏令时生效,则夏令时标志为正,如果为非夏令时时间,则该标志为0,如果此信息不可用,则其值为负。

SUS的以前版本允许双闰秒,tm_sec字段的最大值为61,UTC的正式定义不允许双闰秒,因此现在tm_sec值最大值定义为60。

将UNIX时间戳转换为tm结构:
在这里插入图片描述
local函数可将日历时间转换为本地时间(即考虑时区和夏令时标志);gmtime函数将日历时间转换成协调统一时间的tm结构。

将tm结构转换为日历时间:
在这里插入图片描述
将tm结构转换为格式化字符串:
在这里插入图片描述
函数asctime和ctime能用于产生一个26字节的可打印字符串,类似date命令的输出,但这些函数已被标记为弃用,因为它们容易出现缓冲区溢出的问题。

strftime_l函数允许调用者指定时区。strftime使用TZ环境变量指定时区。

参数tmptr指向一个tm结构,是要格式化的时间值,格式化的结果存放在参数buf表示的数组中,数组的大小由maxsize参数指明(单位为字节数),如果缓冲区能容纳格式化的结果和一个null终止符,则该函数返回在buf中存放的字节数(不含null),否则函数返回0。

format参数控制输出的格式,其中的转换说明会转换为特定的时间,其他字符原样输出,ISO C规定的转换说明如下:
在这里插入图片描述
strftime函数的每个转换说明产生一个定长的输出字符串,因此format参数字符串中没有字段宽度修饰符。

上图中%U表示该日期在该年中所属的周数,包含第一个星期日的周是第一周。%W与%U类似,但它将包含第一个星期一的周看做第一周。%V认为如果包含了1月1日的那周包含了新一年的4天及以上的天数,那么该周为一年中的第一周,否则该周被认为是上一年的最后一周。

strftime函数对某些转换说明支持修饰符,可使用E和O修饰符产生本地支持的另一种格式,某些系统支持另一些非标准的扩充支持。

使用strftime函数:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

int main() {
    time_t t;
    struct tm *tmp;
    char buf1[16];
    char buf2[64]; 

    time(&t);
    tmp = localtime(&t);
    if (strftime(buf1, 16, "time and date: %r, %a %b %d %Y", tmp) == 0) {
        printf("buffer length 16 is too small\n");
    } else {
        printf("%s\n", buf1);
    }

    if (strftime(buf2, 64, "time and date: %r, %a %b %d %Y", tmp) == 0) {
        printf("buffer length 64 is too small\n");
    } else {
        printf("%s\n", buf2);
    }

    exit(0);
}

运行它:
在这里插入图片描述
strptime函数将字符串时间分解为tm结构:
在这里插入图片描述
参数format给出了buf参数指向的缓冲区内的字符串的格式,format参数中的转换说明与strftime函数的转换说明稍有不同:
在这里插入图片描述
加密口令要从阴影文件中获取而不能从口令文件中获取(在FreeBSD 8.0中,仅当调用者的有效用户ID为0时,getpwnam或getpwuid函数返回的口令文件项的加密口令字段pw_passwd含加密口令;Mac OS X 10.6.8中,加密口令无法通过本章中的函数获取)。

在系统Linux 3.2.0和Solaris 10上,有超级用户权限时,可用以下程序从阴影口令文件中获取加密口令,如没有超级用户权限,调用getspnam会返回EACCESS错误:

#include <stdio.h>
#include <shadow.h>
#include <stdlib.h>

int main() {    // Linux/Solaris version
    struct spwd *ptr;

    if ((ptr = getspnam("sar")) == NULL) {
        printf("getspnam error\n");
		exit(1);
    }
    printf("sp_pwdp = %s\n", (ptr->sp_pwdp == NULL || ptr->sp_pwdp[0] == 0) ? "(null)" : ptr->sp_pwdp);
    exit(0);
}

在FreeBSD 8.0中,在具有超级用户权限时,可用以下程序从口令文件中输出加密口令,如果没有超级用户权限,则加密字段为星号:

#include <pwd.h>
#include <stdlib.h>
#include <stdio.h>

int main() {
    struct passwd *ptr;

    if ((ptr = getpwnam("sar")) == NULL) {
        printf("getpwnam error\n");
		exit(1);
    }
    printf("pw_passwd = %s\n", (ptr->pw_passwd == NULL || ptr->pw_passwd[0] == 0) ? "(null)" : ptr->pw_passwd);
    exit(0);
}

以上程序在Mac OS X 10.6.8上,不管运行时用户是什么权限都输出星号。

使用strftime函数输出类似date命令的格式化串:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#define MAXLINE 1024

int main() {
    time_t caltime;
    struct tm *tm;
    char line[MAXLINE];

    if ((caltime = time(NULL)) == -1) {
        printf("time error\n");
		exit(1);
    }
    if ((tm = localtime(&caltime)) == NULL) {
        printf("localtime error\n");
		exit(1);
    }
    if (strftime(line, MAXLINE, "%a %b %d %X %z %Y\n", tm) == 0) {
        printf("strftime error\n");
		exit(1);
    }
    fputs(line, stdout);
    exit(0);
}

运行它:
在这里插入图片描述
可见strftime函数输出TZ环境变量表示的时区的时间。

  系统运维 最新文章
配置小型公司网络WLAN基本业务(AC通过三层
如何在交付运维过程中建立风险底线意识,提
快速传输大文件,怎么通过网络传大文件给对
从游戏服务端角度分析移动同步(状态同步)
MySQL使用MyCat实现分库分表
如何用DWDM射频光纤技术实现200公里外的站点
国内顺畅下载k8s.gcr.io的镜像
自动化测试appium
ctfshow ssrf
Linux操作系统学习之实用指令(Centos7/8均
上一篇文章      下一篇文章      查看所有文章
加:2021-08-27 12:16:30  更:2021-08-27 12:16:44 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年12日历 -2024/12/29 9:04:08-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码
数据统计