• UNIX环境高级编程-第六章-系统数据文件和信息


    1.引言

    UNIX系统的正常运作需要适用大量与系统有关的数据文件,例如,口令文件/etc/passwd和组文件/etc/group就是经常被多个程序频繁适用的两个文件。用户每次登录UNIX系统,以及每次执行ls -l命令时都要使用口令文件。
    由于历史原因,这些数据文件都是ASCLL文本文件,并且使用标准IO库读这些文件。但是,对于较大的系统,顺序扫描口令文件很花费时间,我们需要能够以非ASCII文本格式存放这些文件,但仍向使用其他文件格式的应用程序提供接口,对于这些数据文件的可移植接口是本章的主题。本章也包括了系统标识函数,时间和日期函数。

    2.口令文件

    UNIX系统口令文件(POSIX.1则将其称为用户数据库)包含了图6-1中所示的各字段,这些字段包含了在中定义的passwd结构中。
    在这里插入图片描述

    由于历史原因,口令文件是/etc/passwd,而且是一个ASCII文件。每一行包含图6-1中所示的各字段,字段之间用冒号分隔。例如,在Linux中,该文件中可能有下列4行:

    root:x:0:0:root:/root:/bin/bash
    squid:x:23:23::/var:spool/squid:/dev/null
    nobody:x:65534:65534:Nobody:/home:/bin/sh
    sar:x:205:105:Stephen Rago:/home/sar:/bin/bash
    

    这些登录项,请注意下列各点:

    (1)通常有一个用户名为root的登录项,其用户ID是0(超级用户)
    (2)加密口令字段包含了一个占位符。较早期的UNIX系统版本中,该字段存放加密口令字。将加密口令字存放在一个人人刻度的文件中是一个安全性漏洞,所以现在将加密口令字存放在另一个文件中。在下一节讨论口令字时,我们再详细解释
    (3)口令文件项中的某些字段可能是空。如果加密口令字段为空,这通常就意味着该用户没有口令。squid登录项有一空白字段:注释字段,空白注释字段不产生任何影响。
    (4)shell字段包含了一个可执行程序名,它被用作该用户的登录shell。若该字段为空,则取系统默认值,通常是/bin/sh。注意,squid登录项的该字段为/dev/null。显然,这是一个设备,不是可执行文件,将启用于此处的目的是,阻止任何人以用户squid的名义登录到该系统。
    (5)为了阻止一个特定用户登陆系统,除使用/dev/null外,还有若干种替代方法。常见的一种方法是,将/bin/false用作登录shell。它简单地以不成功状态终止,该shell将此种终止状态判断为假。另一种常见方法是,用/bin/true禁止一个账户。它所做的一切是以成功状态终止。某些系统提供nologin命令,它打印可定制的出错信息,然后以非0状态终止。
    (6)使用nobody用户名的一个目的是,是任何人都可以登录至系统,但其用户ID(65534)和组ID(65534)不提供任何特权。该用户ID和组ID只能访问人人皆可读,写的文件。(假定用户ID65534和组ID65534并不拥有任何文件)
    (7)提供finger命令的某些UNIX系统支持注释字段种的附加信息。其中各部分之间用逗号分隔:用户姓名,办公室地点,办公室电话号码以及家庭电话号码等。另外,如果注释字段中的用户姓名是一个&,则它被替换为登录名。例如,可以有下列记录:
    sar:x :205:105:Steve Rago, SF 5-121,
    555-1111,555-2222:/home/sar:/bin/sh 使用finger命令就可以打印Steve Rago的有关信息

    某些系统提供了vipw命令,允许管理员使用该命令编辑口令文件。vipw命令串行化地更改口令文件,并且确保它所作的更改与其他相关文件保持一致。系统也常常经由图形用户界面提供类似的功能。
    POSIX.1定义了两个获取口令文件项的函数。在给出用户登录名或数值用户ID后,这两个函数就能查看相关项。

    #include
    struct passwd *getpwuid(uid_t uid);
    struct passwd *getpwnam(const char *name);
    

    getpwuid函数由ls程序使用,它将i节点种的数字用户ID映射为用户登录名。在键入登录名时,getpwnam函数由login程序使用。
    这两个函数都返回一个指向passwd结构的指针,该结构已由这两个函数在执行时填入信息。passwd结构通常是函数内部的静态变量,只要调用任一相关函数,其内容就会被重写。
    如果要查看的只是登录名或用户ID,那么这两个函数能满足要求,但是也有些程序要查看整个口令文件。下列3个函数可用于此种目的。

    #include 
    struct passwd *getpwent(void);
    void setpwent(void);
    void endpwent(void);
    

    调用getpwent时,它返回口令文件中的下一个记录项。如同上面所述的两个POSIX.1函数一样,它返回一个由它填写好的passwd结构的指针。每次调用此函数时都重写该结构。
    函数setpwent反绕它所使用的文件,endpwent则关闭这些文件。在使用getpwent查看完口令文件后,一定要调用endpwent关闭这些文件。getpwent知道什么时间应当打开它所使用的文件(第一次被调用时),但是它并不知道何时关闭这些文件。
    实例6-2:给出了getpwnam函数的一个实现。

    #include 
    #include 
    #include 
    
    struct passwd *
  • 相关阅读:
    若依多租户集成浅析(基于数据源隔离)
    玩转SQLite7:基本语法与数据类型
    API与C++中的API
    Flask--路由配置
    使用Hypothesis生成测试数据
    .NET6项目连接数据库方式方法
    【Linux】root和子用户都能执行的命令,sudo无法执行(已解决)
    flex布局 H5携程移动端头部个人中心和图标 (三)
    AD域控服务器部署
    mysql编译安装教程
  • 原文地址:https://blog.csdn.net/weixin_43979090/article/details/127107890