第8章 用户和组

每个用户都有唯一的 登录名 和相关的数值型 用户标识符(UID) 。用户可以属于一个或多个 组(group)。每个组都有唯一 名称组标识符(GID)
UID和GID的主要目的是决定各种系统资源的所有权和控制进程访问这些资源的权限。例如,每个文件都属于一个特定的用户和组,每个进程都有一些UIDs和GIDs,决定了进程的所有者是谁,访问文件是有哪些权限(详情请看第9章)。
在本章中,我们介绍系统中用于定义用户和组的系统文件,然后阐述用于从这些文件获取信息的库函数。最后,讨论用于加密和认证登录密码的 crypt() 函数。

8.1 The Password File: /etc/passwd

系统密码文件(password file)/etc/passwd 中的每行都表示系统中的一个用户账号。每行都有七个字段组成,以冒号(:)分隔,如下:
在这里插入图片描述
这些字段按顺序分别是:

  1. 登录名(Login name) :这是一个具有唯一性的名称,用户登录时必须输入该名称。通常,也称之为 用户名(username)。我们也可以把登录名看成是一个可读的标识符,对应于数值型的用户标识符(userID,UID)。

  2. 加密密码(Encrypted password) :该字段是13个字符的加密密码,会在8.5节更详细地介绍。如果password字段包含其他的字符串(特别是,不是13个字符的字符串),那么就无法登录这个帐号,因为这个字符串不能表示一个有效的加密密码。值得注意的是,如果开启了shadow password,那么这个字段会被忽略。在这种情况下,/etc/passwd中的password字段按照惯例会是字母x (也可以出现任何非空字符),而加密过的密码会存储到shadow密码文件中(8.2节)。如果/etc/passwd中的password字段是空的,那么登录这个帐号就不需要密码(即使开启shadow password,也是这样)。

    在这里,我们假设使用了数据加密标准(Data Encryption Standard,DES)的加密方式。由于历史原因,UNIX password-encryption 模式仍旧被广泛使用。可以使用其他模式替换DES,例如MD5,根据输入它会产生128位的信息摘要(一种hash)。这个值会以34个字符的字符串存储 在密码文件(或者shadow密码文件)中。

  3. User ID(UID):这是用户的数值型的ID。如果这个字段的值是0,那么这个帐号具有超级用户权限。一般拥有这个帐号的登录名是root。在Linux2.2及更早的版本中,user ID是一个16位的值,允许使用0到65535范围的数字。在Linux2.4及之后的版本中,使用32位存储,可以使用更大的范围。

    在密码文件中,同个user ID具有多条记录是可以的(但是不常见),这样同个user ID就可以使用多个登录名,允许多个用户使用不同的密码访问相同的资源(例如文件)。不同的登录名可以关联不同的group IDs。

  4. Group ID (GID): 这是用户第一个组的group ID,它是一个数值型ID。该用户与更多组之间的关系在组文件(group file)中定义。

  5. 注释(comment):该字段持有关于这个用户的文本。该文本可以通过多种程序显示,例如finger(1)

  6. Home目录:这是用户登录时所处的初始目录。该字段会成为HOME环境变量的值。

  7. Login shell:用户登录时,传递哪些控制的程序(This is the program to which control is transferred once the user islogged in)。一般,这只是其中一个shell,例如bash,但是它可以是任何程序。如果字段为空,那么login shell默认是/bin/sh(the Bourne shell)。该字段会成为SHELL环境变量的值。
    在独立的系统中,所有的密码相关信息都存在文件/etc/passwd中。但是我们也可以通过使用网络信息系统(Network Information System, NIS)或轻量级目录访问协议(LDAP)将部分或全部密码信息发送并保存到远程系统。只要程序使用随后章节介绍的函数(getpwnam()、getpwuid()等)来访问密码信息,那么NIS或LDAP的使用对于应用来说是透明的。下面介绍的shadow密码文件和组文件,也可以采用类似的方法。

8.2 The Shadow Password File: /etc/shadow

有史以来,UNIX系统在 /etc/passwd 密码文件中维护所有的用户信息,包括加密的密码。这存在一个安全问题。因为很多非特权系统工具需要读取密码文件中的其他信息,所以所有用户对密码文件都具有可读权限。密码破解程序可以通过对大量可能的密码进行加密的方式查看这些加密后的密码能否匹配上用户加密过的密码。shadow密码文件 /etc/shadow 是防止此类攻击的方法。这样,所有非敏感的用户信息存储在公开可读的密码文件中,而加密过的密码存储在shadow密码文件中,shadow密码文件只有对特权程序才是可读的。
在这里插入图片描述
除了登录名(用于匹配密码文件中的相应记录)和加密密码,shadow密码文件中还包含了其他的一些与安全相关的字段。关于这些字段的更多详情可以参考 shadow(5) 手册页。我们主要关心加密的密码字段,在8.5节讲到crypt()函数时,会对该字段进行更深入地探讨。

8.3 The Group File: /etc/group

出于各种管理的目的,尤其是控制对文件和其他资源的访问,所以对用户分组是很有用的。
用户所属组的集合(用户属于哪些组)需要通过密码文件的group ID字段和组文件中列出的用户相结合之后才能得到。这种奇怪的跨两个文件的信息分隔是有历史原因的。在早期的UNIX实现中,用户只能是一个组的成员。用户初始组在登录时就已经由密码文件的group ID字段决定了,然后可以通过使用 newgrp(1) 命令,提供 组密码(group password) (如果组是受密码保护的) 来改变所属的组。4.2BSD引入了 多个同时组成员关系(multiple simultaneous group memberships) 的概念,这个概念随后成为POSIX.1-1990的标准。在这种模式下,组文件中列出了每个用户额外的所属组。(groups(1)命令显示该shell进程所属的组,如果将一个或多个用户名作为命令行参数,那么显示这些用户的所属组)
组文件 /etc/group 中的每一行表示一个组,每行包含由冒号(:)分割的四个字段,如下所示:
在这里插入图片描述

这些字段按顺序分别是:

  1. 组名(group name):这是组的名称。就像密码文件中的登录名,我们可以把它认为是可读的标识符,对应于数值型的组标识符。
  2. 加密密码(Encrypted password):该字段表示组密码(可不设置)。由于multiple group memberships的出现,组密码在UNIX系统中现在已经很少用了。然而还是可以为组设置组密码(特权用户可以使用 passwd命令 来设置)。如果开启了shadow密码,那么这个字段被忽略(这种情况下,这个字段一般是字符x,但是任何字符串或者空字符串都可以),而加密过的密码被存储在shadow组文件中 /etc/gshadow, 该文件只允许特权用户和程序访问。组密码的加密方式与用户密码的加密方式类似(8.5节)。
  3. 组标识符 (Group ID,GID) :这是组的数值型ID。通常有一个组的group ID是0,名称为root。在Linux2.2及更早的版本中,group IDs是16位的数值,范围是0到65535;在Linux2.4及以后版本中,使用32位存储。
  4. 用户列表(User list):这是以逗号分隔的用户名列表,是该组的成员。(该组包含的是用户名而不是user IDs,因为前面提过,在密码文件中,user IDs不一定是唯一的)。

如果用户 avrusersstaffteach 组的成员,我们可能在密码文件中看到以下记录:
在这里插入图片描述
在组文件中看到以下记录:
在这里插入图片描述
密码文件中的第四个字段是group ID 100,表示 avr 是组 users 的成员。在组文件中第四个字段包含用户名avr 的记录也表示是该用户的组。

8.4 Retrieving User and Group Information

本节中,我们看下可用于从密码文件、shadow密码文件和组文件中获取个人记录的库函数,以及浏览这些文件中的所有记录。

Retrieving records from the password file

getpwname()getpwuid() 函数用于从密码文件中获取记录。

# include <pwd.h>
//运行成功时返回指针,失败时返回NULL,"未找到"时,请查看下文的介绍
struct passwd *getpwnam(const char *name);
struct passwd *getpwuid(uid_t uid);

getpwnam() 函数的name参数中传入一个登录名,返回一个指向以下类型的结构体,对应于密码文件中的字段信息:

struct passwd 
{
   
    char *pw_name; /* Login name (username) */
    char *pw_passwd; /* Encrypted password */
    uid_t pw_uid; /* User ID */
    gid_t pw_gid; /* Group ID */
    char *pw_gecos; /* Comment (user information) */
    char *pw_dir; /* Initial working (home) directory */
    char *pw_shell; /* Login shell */
}

passwd 结构体中的 pw_gecos 和 pw_passwd 字段没有在SUSv3中定义,但是在所有UNIX实现中可用。只有当shadow password关闭时pw_passwd 字段才有效。(

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值