《Linux/Unix系统编程手册》读书笔记 目录

第8章

本章讲了用户和组,还有记录用户的密码文件/etc/passwd,shadow密码文件/etc/shadow还有组文件/etc/group。

每个用户都有唯一的用户名和相关的用户标识符(UID)。用户可以属于一个或多个组,每个组都有唯一的组名和相关的组标识符(GID)。

用户和组的用途为:1、可以确定各种系统资源的所有权;2、对赋予进程访问上述资源的权限加以控制。

首先来看一下密码文件/etc/passwd

lancelot@debian:~$ cat /etc/passwd
root:x:::root:/root:/bin/bash
daemon:x:::daemon:/usr/sbin:/bin/sh
bin:x:::bin:/bin:/bin/sh
sys:x:::sys:/dev:/bin/sh
sync:x:::sync:/bin:/bin/sync
games:x:::games:/usr/games:/bin/sh
man:x:::man:/var/cache/man:/bin/sh
lp:x:::lp:/var/spool/lpd:/bin/sh
mail:x:::mail:/var/mail:/bin/sh
news:x:::news:/var/spool/news:/bin/sh
uucp:x:::uucp:/var/spool/uucp:/bin/sh
proxy:x:::proxy:/bin:/bin/sh
www-data:x:::www-data:/var/www:/bin/sh
backup:x:::backup:/var/backups:/bin/sh
list:x:::Mailing List Manager:/var/list:/bin/sh
irc:x:::ircd:/var/run/ircd:/bin/sh
gnats:x:::Gnats Bug-Reporting System (admin):/var/lib/gnats:/bin/sh
nobody:x:::nobody:/nonexistent:/bin/sh
libuuid:x::::/var/lib/libuuid:/bin/sh
messagebus:x::::/var/run/dbus:/bin/false
colord:x:::colord colour management daemon,,,:/var/lib/colord:/bin/false
usbmux:x:::usbmux daemon,,,:/home/usbmux:/bin/false
Debian-exim:x::::/var/spool/exim4:/bin/false
avahi:x:::Avahi mDNS daemon,,,:/var/run/avahi-daemon:/bin/false
pulse:x:::PulseAudio daemon,,,:/var/run/pulse:/bin/false
speech-dispatcher:x:::Speech Dispatcher,,,:/var/run/speech-dispatcher:/bin/sh
hplip:x:::HPLIP system user,,,:/var/run/hplip:/bin/false
sshd:x::::/var/run/sshd:/usr/sbin/nologin
rtkit:x:::RealtimeKit,,,:/proc:/bin/false
statd:x::::/var/lib/nfs:/bin/false
saned:x::::/home/saned:/bin/false
Debian-gdm:x:::Gnome Display Manager:/var/lib/gdm3:/bin/false
lancelot:x:::lancelot,,,:/home/lancelot:/bin/bash
mysql:x:::MySQL Server,,,:/nonexistent:/bin/false
ftp:x:::ftp daemon,,,:/srv/ftp:/bin/false
telnetd:x::::/nonexistent:/bin/false

第一个字段是登录名;第二个字段是经过加密后的密码(x),实际上经过加密后的密码是存放在shadow密码文件;

第三个字段是用户的ID(UID);第四个字段是组ID(GID);第五个字段是注释;

第六个字段是主目录,是用户登录后的初始路径;第七个字段是登录shell。

接着来看实际存放密码的shadow 密码文件/etc/shadow

格式如下:

lancelot:$$tnTgvJYU$OhoUNZNIeNU7rlZf/f14oD2g.Uz8SbrnWeZbR4yL4XXRvzbCeijsAZE7Y9HlzU4thKVBVcqucwntJBi/4BoY60:::::::
mysql:!:::::::
ftp:*:::::::
telnetd:*:::::::

很明显可以看到第一个字段为用户登录名,第二个字段为见过加密后的密码,后面的字段为与安全性相关的字段。

看完用户,我们来看组文件/etc/group

lancelot@debian:~$ cat /etc/group
root:x::
daemon:x::
bin:x::
sys:x::
adm:x::
tty:x::
disk:x::
lp:x::
mail:x::
news:x::
uucp:x::
man:x::
proxy:x::
kmem:x::
dialout:x::
fax:x::
voice:x::
cdrom:x::lancelot
floppy:x::lancelot
tape:x::
sudo:x::
audio:x::pulse,lancelot
dip:x::lancelot
www-data:x::
backup:x::
operator:x::
list:x::
irc:x::
src:x::
gnats:x::
shadow:x::
utmp:x::telnetd
video:x::lancelot
sasl:x::
plugdev:x::lancelot
staff:x::
games:x::
users:x::
nogroup:x::
libuuid:x::
crontab:x::
fuse:x::
scanner:x::saned,lancelot
messagebus:x::
colord:x::
lpadmin:x::
ssl-cert:x::
bluetooth:x::lancelot
utempter:x::
netdev:x::lancelot
Debian-exim:x::
mlocate:x::
ssh:x::
avahi:x::
pulse:x::
pulse-access:x::
rtkit:x::
saned:x::
Debian-gdm:x::
lancelot:x::
mysql:x::
ftp:x::
vboxusers:x::
telnetd:x::

第一个字段是组的名称,第二个字段是经过加密的密码,第三个字段是组ID(GID),第四个字段是用户列表。

对于加密后的密码存放在类似/etc/shadow的文件(/etc/gshadow),格式如下:

cdrom:*::lancelot
floppy:*::lancelot
tape:*::
sudo:*::
audio:*::pulse,lancelot
dip:*::lancelot
www-data:*::
backup:*::
operator:*::
list:*::
irc:*::
src:*::
gnats:*::
shadow:*::
utmp:*::telnetd
video:*::lancelot

最后一个字段很明显是用户列表。

接着,我们来看如何通过库函数来获取上面提到的信息。

一、从/etc/shadow获取记录:

 #include <pwd.h>

 struct passwd *getpwnam(const char *name);

 struct passwd *getpwuid(uid_t uid);

getpwnam()是根据提供的登录名返回一个指向对应的密码记录的指针。getpwuid()是根据提供的uid来返回一个指向对应的密码记录的指针。

如果出现错误返回NULL。

PS:对于getpwnam和getpwuid返回的指针都是指向由静态分配而成的内存,因此都是不可重入。

这个应该是练习8-1的答案。

8-1:执行下列代码时,将会发现,尽管这两个用户在密码文件中对应不同的ID,但该程序的输出还是会将同一个数字显示两次。请问为什么?

printf("%ld %ld\n", (long)(getpwnam("avr")->pw_uid), (long)(getpwnam("tsr")->pw_uid));

书本的答案是这样的:getpwnam()的调用在printf()输出之前,那么getpwnam()返回的结果存放在静态分配的缓冲区中,第二个getpwnam()的返回结果会覆盖第一个的结果。

然后我测试了一下,代码如下:

 /*
* =====================================================================================
*
* Filename: tt1.c
*
* Description:
*
* Version: 1.0
* Created: 2014年04月22日 14时56分10秒
* Revision: none
* Compiler: gcc
*
* Author: alan (), alan19920626@gmail.com
* Organization:
*
* =====================================================================================
*/ #include <stdio.h>
#include <pwd.h> int main(int argc, char *argv[]){
printf("%ld %ld\n", (long)(getpwnam("lancelot")->pw_uid), (long)(getpwnam("root")->pw_uid));
return ;
}

测试结果:

lancelot@debian:~/Code/tlpi$ ./a.out
 

然后整个人就凌乱了。。。。。。。。。。。。。。

后来,我把程序改成这样:

 #include <stdio.h>
#include <pwd.h> int main(int argc, char *argv[]){
struct passwd *p1, *p2;
p1 = getpwnam("lancelot");
p2 = getpwnam("root");
printf("%ld %ld\n", p1->pw_uid, p2->pw_uid);
//printf("%ld %ld\n", (long)(getpwnam("lancelot")->pw_uid), (long)(getpwnam("root")->pw_uid));
return ;
}

才能输出相同的值,因为两个指针变量指向的地址是一样的。但是之前那种是正确的,因为函数的参数是一值传递的方式传递,所以不存在题目说的两个值相同。

后来我查找了作者的网站的磡误:http://www.man7.org/tlpi/errata/index.html

发现这条题的题目修改了!!!!!!

这样传递指针,两个输出的名字就是一样的。。。。。。。。。。。。。。

下面是作者的解释:

好吧,以后还要把书上的错误修改。。。。。。。

PS:再次证明不管例子多简单也要试一试。。。。。

二、从/etc/group获取记录

 #include <grp.h>

 struct group *getgrnam(const char *name);

 struct group *getgrgid(gid_t gid);

getgrnam根据提供的组名返回指向组的密码记录的指针,getgrigid则根据提供的组号GID返回该指针。失败调用返回NULL

PS:这两个函数也是不可重入的函数。

三、扫描密码文件和组文件

 #include <pwd.h>

 struct passwd *getpwent(void);

 void setpwent(void);

 void endpwent(void);

getpwent()可以逐条返回记录。setpwent()可以重置为。/etc/passwd文件的起始处。endpwent()可以关闭文件。

四、从/etc/shadow密码文件中获取记录

 #include <shadow.h>

 struct spwd *getspnam(const char *name);

 struct spwd *getspent(void);

 void setspent(void);

 void endspent(void);

getspnam和getspent会返回指向shadow密码记录的指针,失败调用返回NULL。

setspent会重置为文件的起始位置,endspent会关闭文件。

五、密码加密

 #define _XOPEN_SOURCE
#include <unistd.h> char *crypt(const char *key, const key *salt);

#define _XOPEN_SOURCE 是为了获取crypt的声明。

key为输入的密码,salt指向一个两字节的字符串,用来改变DES算法。成功调用返回加密后的密码,失败返回NULL。

---------------------吐槽:好好写博客,写博客的时候思考的感觉真好,要多读书,多code,多思考---------------------------

听同学说有很多厉害的人已经找到实习了,真的后悔大一大二的无作为。正因为后悔,所以要做得更好!!!!

继续努力!!!!!!

---------------------------------------------------------------------------------------------------------------------------------------------------

练习:

8-2: 使用sptwent()、getpwent()和endpwent()来实现getpwnam()。

这题个人觉得很简单,因为getpwent()是逐条查找,查找匹配就输出。输出完应该调用sptwent将文件的偏移量重置为文件的起始位置。结束的时候调用endpwent关闭文件。

 /*
* =====================================================================================
*
* Filename: 8-2.c
*
* Description:
*
* Version: 1.0
* Created: 2014年04月22日 16时48分09秒
* Revision: none
* Compiler: gcc
*
* Author: alan (), alan19920626@gmail.com
* Organization:
*
* =====================================================================================
*/ #include <pwd.h>
#include <string.h>
#include <stdio.h>
#include "tlpi_hdr.h" struct passwd * Getpwnam(const char *name){
struct passwd *pwd;
while((pwd = getpwent()) != NULL){
if(strcmp(pwd->pw_name, name) == ){
setpwent();
return pwd;
}
}
setpwent();
return NULL;
} int main(int argc, char *argv[]){
int i;
struct passwd *p;
if(argc < || strcmp(argv[], "--help") == )
usageErr("%s user-names...", argv[]); for(i = ; i < argc; ++i){
p = Getpwnam((const char *)argv[i]);
if(p == NULL)
printf("%s does not exit\n", argv[i]);
else{
printf("%s, UID: %ld, GID: %ld\n", argv[i], (long)p->pw_uid, (long)p->pw_gid);
}
} endpwent();
exit(EXIT_SUCCESS);
}

测试结果:

lancelot@debian:~/Code/tlpi$ ./a.out lancelot root
lancelot, UID: , GID:
root, UID: , GID:

《Linux/Unix系统编程手册》读书笔记5的更多相关文章

  1. 【鸟哥的Linux私房菜】笔记1

    Linux是什么 从操作系统与cpu架构关系到linux  Richard Mathew Stallman GPL 关于GNU计划 Linux的发展 Linux的核心版本 Linux的特色 Linux ...

  2. 【鸟哥的Linux私房菜】笔记3

    正确地开机 最好不要使用root账号登陆!GNOME图形界面 View items as a list X WindowShell 文本交互界面bash是Shell的名称,Linux的默认壳程序就是b ...

  3. 【鸟哥的Linux私房菜】笔记2

    Linux的应用 学习资源整理 安装记录 >< 1.Linux的应用: 网络服务器 数据库 学术机构的高效运算任务 嵌入式系统 ... 2.挂载与磁盘分区 学习资源整理 学习 1.书上的网 ...

  4. 《鸟哥的Linux私房菜》笔记——02. 关于Linux

    Unix 历史 1969年以前:伟大的梦想--Bell, MIT 与 GE 的「Multics」系统 1969年:Ken Thompson 的小型 file server system 1973年:U ...

  5. 《鸟哥的Linux私房菜》笔记——03. 磁盘分区

    Everything is a file. 常见硬件对应于 Linux 下的文件(/dev目录下) 装置 装置在Linux内的档名 SCSI/SATA/U盘硬盘机 /dev/sd[a-p] U盘 /d ...

  6. 鸟哥的linux私房菜学习笔记 __ 命令与文件的搜寻

    连续输入两次[tab]按键就能够知道使用者有多少命令可以下达.那你知不知道这些命令的完整档名放在哪里?举例来说,ls 这个常用的命令放在哪里呢? 就透过 which 或 type 来找寻吧! 范例一: ...

  7. 【鸟哥的Linux私房菜】笔记

    操作系统核心的功能! 驱动程序与操作系统的关系 2. [计算机组成之组件] 3.CPU实际要处理的数据完全来自于主存储器,这是一个很重要的概念! 4.CPU是整个计算机系统最重要的部分,那么目前世界上 ...

  8. 《鸟哥的Linux私房菜》笔记——04. 简单命令行

    键入命令 [dmtsai@study ~]$ command [-options] parameter1 parameter2 ... 指令 選項 參數(1) 參數(2) 注意:有时也可以使用 + 放 ...

  9. 鸟哥的Linux私房菜学习笔记——文件权限与目录配置

    Linux的文件权限和目录配置 在linux中的每个用户必需属于一个组,不能独立于组外.在linux中每个文件有所有者.所在组.其它组的概念. (1)所有者 一般为文件的创建者,谁创建了该文件,就是天 ...

  10. 鸟哥的Linux私房菜学习笔记(1)

    2014/10/29 1.档案的权限管理分为三个部分: 拥有者.群组.其他 2.ls -al 命令可以看到档案的详细信息 3.档案的属性中由十个部分构成 第一个部分是档案类型 -代表档案.d代表文件夹 ...

随机推荐

  1. 在一台电脑访问另一台电脑的mysql数据库,并增加和剥夺权限

    1.    假设MySQL服务器安装在ip地址为192.168.105.3的主机上面 2.    再假设客户端安装在ip为192.168.105.100的机子上 3. 首先在ip为192.168.10 ...

  2. 【环境】openSUSE安装记录 - 古董本上的windows 7和opensuse双系统

    昨天和朋友交流,提到Linux,他说可以去接触SUSE.我马上打开浏览器搜索了一下,发现SUSE是一个Linux操作系统的企业服务器的发行版,是收费的.朋友说,许多公司都用这个,他曾经给公司安装过SU ...

  3. Excel插件类库的设计思路

    一.插件功能:提供多种读取Excel的方式,如NPOI.Com.Aspose,调用接口一致,包括Excel文件路径,sheet名称.读取是否包含列头(即Excel第一行是否为列头行) 二.实现思路 2 ...

  4. ASP.NET MVC 如何在一个同步方法(非async)方法中等待async方法

    问题 首先,在ASP.NET MVC 环境下对async返回的Task执行Wait()会导致线程死锁.例: public ActionResult Asv2() { //dead lock var t ...

  5. NYOJ-205 求余数 AC 分类: NYOJ 2014-02-02 12:30 201人阅读 评论(0) 收藏

    这题目看一眼以为难度评级出错了,只是一个求余数的题目,,后来才发现,位数小于百万位,,,我还以为是大小小于百万呢,所以借鉴了另一大神的代码, 用大数,重点是同余定理: (a+b)mod m=((a m ...

  6. JavaScript之isNaN()函数讲解

    定义和用法 isNaN() 函数用于检查其参数是否是非数字值. 语法 isNaN(x) 参数 描述 x 必需.要检测的值. 返回值 如果 x 是特殊的非数字值 NaN(或者能被转换为这样的值),返回的 ...

  7. .net深入体验与实战精要--ASP.NET开发大杂烩(转)

    转自:http://www.cnblogs.com/sunhan/p/3371337.html 正巧今天遇到一个获取动态生成table中的一个动态生成的TextBox的值的时候总是findcontro ...

  8. Unity3D研究院之LZMA压缩文件与解压文件

    原地址:http://www.xuanyusong.com/archives/3095 前两天有朋友告诉我Unity的Assetbundle是LZMA压缩的,刚好今天有时间那么就研究研究LZMA.它是 ...

  9. Ogre1.8.1 Basic Tutorial 6 - The Ogre Startup Sequence

    原文地址:http://www.ogre3d.org/tikiwiki/tiki-index.php?page=Basic+Tutorial+6&structure=Tutorials 1. ...

  10. 时序列数据库武斗大会之 OpenTSDB 篇

    [编者按] 刘斌,OneAPM后端研发工程师,拥有10多年编程经验,参与过大型金融.通信以及Android手机操作系的开发,熟悉Linux及后台开发技术.曾参与翻译过<第一本Docker书> ...