Chinaunix首页 | 论坛 | 博客
  • 博客访问: 110900
  • 博文数量: 12
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 244
  • 用 户 组: 普通用户
  • 注册时间: 2014-12-02 11:07
个人简介

联系方式:825988516@qq.com 业精于勤荒于嬉 行成于思毁于随

文章分类
文章存档

2014年(12)

我的朋友

分类: LINUX

2014-12-03 17:05:28

概述

简介

第一遍拜读《UNIX环境高级编程》时,没有深究细节,目的只是对全书有一个整体的了解,以便划分出知识点,逐个击破。在专研第四章时,对里面提到的进程的实际用户ID、实际组ID、有效用户ID、有效组ID、保存设置-用户-ID、保存设置-组-ID这六个概念似懂非懂,这里以专题的形式将自己的学习经历整理成文,一方面加深自己的理解和记忆,另一方面希望帮助和我有相同疑惑的同行朋友少走弯路。

参考资料

UNIX环境高级编程》第四章 文件和目录

LinuxUNIX Shell编程指南》第一章 文件安全与权限

理论部分

为了让大部分读者都能轻松的阅读和理解,这里结合《UNIX环境高级编程》加上我个人的验证和理解再重复一下相关的概念。

 

为了讲清楚实际用户ID、实际组ID、有效用户ID、有效组ID、保存设置-用户-ID、保存设置--ID这六个概念,这里需要引入两个新的概念,就是:设置-用户-ID和设置-组-ID。

 

关于设置-用户-ID和设置--IDLinuxUNIX Shell编程指南中如是说:设置-用户-ID意味着如果某个用户对属于自己的文件设置了这种权限(chmod u+x file),那么其它用户在执行这一文件时也会具有其属主的权限。设置--ID意味着如果某个用户对属于自己的文件设置了这种权限(chmod g+x file),那么其它用户在执行这文件本时也会具有其同组用户的权限。

 

可能看到这里,你对上面的“具有其属主的权限”和“具有其同组用户的权限”这两句话还是不太理解,别急,耐心接着往下看,你会找到答案的。

 

实际用户ID、实际组ID、有效用户ID、有效组ID、保存设置-用户-ID、保存设置--ID这六个概念是针对进程而言的,而设置-用户-ID、设置--ID这两个概念是正对文件而言的。

预置条件

root身份创建两个用户,一个user1,一个user2,用户user1属于组user1,用户user2属于组user2。用户user2编写了一段名为proc.c的程序,编译为名为proc的二进制文件。用户user1执行用户user2编译生成的proc二进制文件。

二进制文件proce的功能如下:

1、  调用getuid()getgid()geteuid()getegid()打印进程的实际用户ID、实际组ID、有效用户ID、有效组ID

2、  向用户user2创建的文本文件user2.txt中写入一个字符串。

进程的实际用户ID和实际组ID

UNIX环境高级编程如是说:实际用户I D和实际组I D标识我们究竟是谁。这两个字段在登录时取自口令文件中的登录项。

 

我如是说:从前提中可以看到,二进制文件proc由用户user2创建,由用户user1执行。从后面的实例可以看到,进程的有效用户ID和有效组ID和二进制文件由谁创建没有关系,和二进制文件由谁执行有关系,这也符合UNIX环境高级高级编程的解释。

进程的有效用户ID和有效组ID

二进制文件proc的一个功能是打开用户user2创建的一个文本文件user2.txt,并写入一个字符串。用户user2可以正常写入,用户user1写入时错误为:Permission denied。

 

UNIX环境高级编程如是说:有效用户I D,有效组I D决定了我们的文件访问权。进程的有效用户I D通常就是实际用户I D,有效组I D通常是实际组I D。这解释了为什么用户user1执行proc时会报错,因为进程proc由用户user1执行,通常进程proc对文件的访问权限与user1对文件的访问权限一样,也就是proc的有效用户ID等于proc的实际用户ID等于用户user1ID,明显用户user1没有对user2.txt的写权限。

 

我如是说:UNIX环境高级编程中只说通常“进程的有效用户ID就是实际用户ID”,也就是说存在例外的情况,以user2身份,执行“chmod u+s proc”,用户user1再执行二进制文件就不会有错误输出,可以正常写入内容。

读到这里再来理解前面提到的两句话“具有其属主的权限”和“具有其同组用户的权限”,本质就是进程的有效用户ID变成其二进制文件属主的用户ID,组ID也一样。

进程的保存设置-用户-ID和保存设置--ID

UNIX环境高级编程用了不少的篇幅来阐述这两个概念,说明这个概念不是很好理解。但也不要被吓住,只要理解了setuid这个系统调用,这个问题也就清楚了,理解一个系统调用,对于程序员的你来讲,应该手到擒来了吧。

 

proc.c中加入如下代码片段:

502user1的用户ID503user2的用户ID504不知道是什么,执行结果显示第三个setuid调用失败了,这是为什么?

 

UNIX环境高级编程如是说:

1.若进程具有超级用户特权,则s e t u i d函数将实际用户I D、有效用户I D,以及保存的设

-用户-I D设置为u i d

2.若进程没有超级用户特权,但是u i d等于实际用户I D或保存的设置-用户- I D,则s e t u i d只将有效用户I D设置为u i d。不改变实际用户I D和保存的设置-用户- I D

3.如果上面两个条件都不满足,则e r r n o设置为E P E R M,并返回出错。

 

如果是超级用户当然是拥有所有权限,只要是有效的用户ID,调用setuid正如1中描述的那样。这里的user1user2都不是超级用户,这里符合第二条规则,“保存设置-用户-ID”理解为“保存”+“设置用户ID”,在setuid调用的时候,把入参和实际用户ID和保存设置-用户-ID比较,如果不和二者中的其中一个相等,则接口调用失败。

 

这样做有什么用?

用户user1执行完需要user2才有权限的任务后,恢复进程的有效用户IDuser1的用户ID,等需要执行user2才有权限的任务时,又可以将进程的有效用户ID设置为user2userID,这样互相切换,而不会导致setuid调用失败。

实践部分

创建用户和文件

root身份创建用户:

useradd –m user1

useradd –m user2

user2身份创建文件:

touch proc.c

touch user2.txt

编辑proc.c,写入如下内容:

编译proc.cproc

gcc -g -o proc proc.c

用户user2执行proc

用户user1执行proc

用户user2执行如下命令:

chmod u+s proc

chmod g+s proc

用户user1再次执行proc

阅读(7620) | 评论(0) | 转发(1) |
给主人留下些什么吧!~~