zoukankan      html  css  js  c++  java
  • 6.2 口令文件

    6.2 口令文件

    口令文件包括了以下字段,这些字段包含在<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  加密口令字段包含了一个占位符,在早期的UNIX系统版本中,该字段存放加密口令,将加密口令放在一个人人刻度的文件中构成了一个安全漏洞,所以现在已经将加密口令存放在另一个位置。(密码口令字字段包含了经单向密码单法处理过的用户口令字副本。因为此算法是单问的,所以我们不能从密码口令字猜测到原来的口令字);

    l  口令文件项中某些字段可以为空,如果密码口令字段为空,这通常就意味着该用户没有口令字。(不希望这样做。)

    l  shell字段包含一个可招待程序名,它被用于用户登录shell,若该字段为空,则取系统默认值,通常是/bash/sh。注意到squidshell字段被设置为/dev/null这是一个设备,不能执行,这样做的目的是阻止任何人以用户squid的名义登录到该系统为了阻止一个特定用户登录系统,除了使用/dev/null之外,还有若干种替代方法:

    n  /bin/false作为登录的shell,它简单地以不成功非0状态终止,该shell将此种终止状态判断为假;

    n  /bin/true禁止一个账户,它所作的一切就是以成功0状态终止;

    n  某些系统还提供了nologin命令,它打印可自定义的出错信息,然后以非0状态终止。

    l  因为对用户名nobody的记录的密码口令字段只包含一个字符(*),所以密码口令字决不会与此值相匹配。此用户名可用于网络服务器,这些服务器允许我们登录到一个系统,但其用户ID和组ID(65534),并不提供优先权。以此用户ID和组ID我们可存取的文件只是大家都可读、写的文件。(这假定用户ID65534和组ID65534并不拥有任何文件)

    l  某些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

     

          某些系统提供了vipw命令,允许管理员使用该命令编辑口令文件。vipw命令串行化对口令文件所作的修改,并且确保所作的更改与其他相关文件保持一致。系统也常常经由图形用户界面GUI提供类似的功能。

    1.1查询口令文件

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

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

    #include <pwd.h>

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

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

    getpwuidls(1)程序使用,以便将包含在一个i-node中的数值用户ID映照为用户登录名。getpwnaw在我们键入登录名时由login(1)程序使用。

    这两个函数都返回一个指向passwd结构的指针,该结构已由这两个函数在执行时填入了所需的信息。此结构通常是在相关函数内的静态变量,只要调用相关函数,其内容就会被重写。

    如果我们要查看的只是一个登录名或一个用户ID,那么这两个POSIX.1函数是能满足要求的,但是也有些程序要查看整个口令字文件。下列三个函数则可用于此种目的。

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

    #include <pwd.h>

    struct passwd *getpwent(void);

    void setpwent(void);

    void endpwent(void);

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

    调用getpwent时,它返回口令文件中的下一个记录。如同上面所述的两个POSIX.1函数一样,它返回一个由它填写好的passwd结构的指针。每次调用此函数时都重写该结构。在第一次调用该函数时,它打开它所使用的各个文件。在使用本函数时,对口令文件中各个记录安排的顺序并无要求。某些系统采用散列算法对/etc/passwd文件中的各项排序。

    函数setpwent反绕它所使用的文件,endpwent则关闭这些文件。在使用getpwent查看完了口令字文件后,一定要调用endpwent关闭这些文件。getpwent知道什么时间它应当打开它所使用的文件(第一次被调用时),但是它并不能知道何时关闭这些文件。

    程序6.1示出了函数getpwnam的一个实现。

    #include <pwd.h>
    #include <stdio.h>
    #include <stdlib.h>
    struct passwd *getpwnam(const char *name)
    {
    struct passwd *ptr;
    setpwent();
    while ((ptr = getpwent()) != NULL)
    if (strcmp(name, ptr->pw_name) == 0)
    break; //found a match
    endpwent();
    return ptr; //ptr is NULL if no match fount

    int main(int argc, char *argv[])

    struct passwd *my;
    if (argc != 2)
    perror("usage : a.out loginname");



    printf("login name is %s\n", argv[1]);




    my = getpwnam(argv[1]);



    printf("pw_name = %s\n", my->pw_name);



    printf("pw_passwd = %s\n", my->pw_passwd);



    printf("pw_uid = %d\n", my->pw_uid);



    printf("pw_gid = %d\n", my->pw_gid);



    printf("pw_gecos = %s\n", my->pw_gecos);



    printf("pw_dir = %s\n", my->pw_dir);



    printf("pw_shell = %s\n", my->pw_shell);


    //some OS do not support the following
    //printf("pw_class = %s\n", my->pw_class);



    //printf("pw_change = %d\n", my->pw_change);



    //printf("pw_expire = %d\n", my->pw_expire);




    exit(0);
    }

    在程序开始处调用setpwent是保护性的措施,以便在调用者在此之前已经调用过getpwent的情况下,反绕有关文件使它们定位到文件开始处。getpwnawgetpwuid完成后不应使有关文件仍处于打开状态,所以应调用endpwent关闭它们。

  • 相关阅读:
    74.QT窗口实现类的封装
    73,QT指针数组实战(指针数组与数组指针)
    72.函数模板指针与类函数模板的绑定
    71.lambda表达式的递归
    C++ new delete(一)
    ios之@class
    xcode菜单栏
    ios 自定义delegate(一)
    strong&weak
    TCP/UDP
  • 原文地址:https://www.cnblogs.com/shaoguangleo/p/2805991.html
Copyright © 2011-2022 走看看