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关闭它们。

转载于:https://www.cnblogs.com/shaoguangleo/archive/2011/10/10/2805991.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值