lienhua34
2014-09-03

通过前面一篇随笔(文件访问权限与进程访问控制),我们知道内核校验文件的访问权限使用的是进程的有效用户 ID 和有效组 ID。但有时我们需要知道当前登录用户对某个文件访问权限。虽然说进程的有效用户 ID 和有效组 ID 通常分别等于当前登录用户 ID 和用户所在组 ID。例如,一个进程可能因设置用户 ID 以另一个用户权限运行,它仍可能想验证当前实际登录的用户是否能否访问一个给定的文件。

access 函数提供了按照实际用户 ID 和实际组 ID 进行访问权限测试的功能。其校验步骤跟之前说的内核校验步骤一致,只是将“有效”改成了“实际”。

#include <unistd.h>

int access(const char *pathname, int mode);

返回值:若成功则返回0,若出错则返回-1.

其中,mode 是表 1 中所列常量的按位或。

表 1: access 函数的 mode 常量,取自 <unistd.h>
mode 说明
R_OK 测试读权限
W_OK 测试写权限
X_OK 测试执行权限
F_OK 测试文件是否存在

例子:

下面程序测试当前登录用户对命令行第一个参数是否具有读权限,然后以只读的方式打开该文件。

#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
int
main(int argc, char *argv[])
{
if (argc != ) {
printf("usage: accessdemo <pathname>");
exit(-);
}
if (access(argv[], R_OK) < ) {
printf("access error for %s: %s\n", argv[], strerror(errno));
} else {
printf("read access OK\n");
}
if (open(argv[], O_RDONLY) < ) {
printf("open error for %s: %s\n", argv[], strerror(errno));
} else {
printf("open for reading OK\n");
}
exit();
}

编译该程序,生成 accessdemo,然后运行该程序,

 lienhua34:demo$ gcc -o accessdemo accessdemo.c
lienhua34:demo$ ls -l accessdemo
-rwxrwxr-x lienhua34 lienhua34 9月 : accessdemo
lienhua34:demo$ ./accessdemo accessdemo
read access OK
open for reading OK
lienhua34:demo$ ls -l /etc/shadow
-rw-r----- root shadow 4月 : /etc/shadow
lienhua34:demo$ ./accessdemo /etc/shadow
access error for /etc/shadow: Permission denied
open error for /etc/shadow: Permission denied
lienhua34:demo$ su
# chown root accessdemo
# chmod u+s accessdemo
# ls -l accessdemo
-rwsrwxr-x root lienhua34 9月 : accessdemo
# exit
exit
lienhua34:demo$ ./accessdemo /etc/shadow
access error for /etc/shadow: Permission denied
open for reading OK

我们来分析一下上面的运行命令序列及其结果。

1. 起先,文件 accessdemo 的所有者是 lienhua34(当前登录用户),运行./accessdemo acessdemo 时,进程的实际用户和有效用户都是lienhua34,则 access 函数和 open 函数都能够成功。(第1到6行)

2. 文件/etc/shadow 的所有者是 root,且其只允许 root 用户读取。此时运行./accessdemo /etc/shadow,进程的实际用户的有效用户都是 lienhua34,则 access 函数和 open 函数都失败了。(第7到11行)

3. 切换后超级用户 root,将文件 accessdemo 的所有者修改为超级用户root(运行命令chown root accessdemo,并设置文件 accessdemo 的设置用户 ID 位(运行命令chmod u+s accessdemo)。(第12到18行)

4. 切换后当前登录用户 lienhua34,此时运行./accessdemo /etc/shadow,进程的实际用户为 lienhua34,但有效用户为超级用户 root(因文件accessdemo 的所有者为 root 且设置了设置用户 ID 位)。此时 access函数校验当前登录用户 lienhua34 对文件/etc/shadow 读权限失败,但open 函数却能够打开文件/etc/shadow(内核用进程的有效用户 ID进行访问权限校验)。(第19到21行)

(done)

UNIX环境编程学习笔记(8)——文件I/O之校验当前登录用户对文件的访问权限的更多相关文章

  1. UNIX环境编程学习笔记(13)——文件I/O之标准I/O流

    lienhua342014-09-29 1 标准 I/O 流 之前学习的都是不带缓冲的 I/O 操作函数,直接针对文件描述符的,每调用一次函数可能都会触发一次系统调用,单次调用可能比较快捷.但是,对于 ...

  2. UNIX环境编程学习笔记(12)——文件I/O之目录操作

    lienhua342014-09-18 1 引言 在 UNIX 系统中,目录是一种特殊的文件类型.我们可以使用 open 函数来打开目录,获取文件描述符,然后调用 stat 函数来获取目录的属性信息, ...

  3. UNIX环境编程学习笔记(10)——文件I/O之硬链接和符号链接

    lienhua342014-09-15 1 文件系统数据结构 UNIX 文件系统通过 i 节点来存储文件的信息.如图 1 所示为一个磁盘柱面上的 i 节点和数据块示意图.其中 i 节点是一个固定长度的 ...

  4. UNIX环境编程学习笔记(9)——文件I/O之文件访问权限的屏蔽和更改

    lienhua342014-09-10 1 文件访问权限 在文件访问权限和进程访问控制中,我们已经讲述过文件访问权限位,为了方便,我们重新列在下面, 表 1: 文件的 9 个访问权限位  st_mod ...

  5. UNIX环境编程学习笔记(7)——文件I/O之文件访问权限与进程访问控制

    lienhua342014-09-02 1 文件的设置用户 ID位 和设置组 ID位 与进程相关联的 ID 如下表所示, 表 1: 与进程相关联的用户 ID 和组 ID 实际用户 ID 我们实际上是谁 ...

  6. UNIX环境编程学习笔记(6)——文件I/O之判断文件类型

    lienhua342014-09-01 1 文件类型 我们平时最常接触的文件类型有普通文件(regular file)和目录(di-rectory file),但是 UNIX 系统提供了多种文件类型: ...

  7. UNIX环境编程学习笔记(4)——文件I/O之dup复制文件描述符

    lienhua342014-08-23 UNIX 提供了两个函数 dup 和 dup2 用于复制一个现存的文件描述符. #include <unistd.h> int dup(int fi ...

  8. UNIX环境编程学习笔记(3)——文件I/O之内核 I/O 数据结构

    lienhua342014-08-27 内核使用三种数据结构表示打开的文件,分别是文件描述符表.文件表和 V 节点表. (1) 每个进程在进程表中都有一个记录项,记录项中包含有一张打开文件描述符表,每 ...

  9. UNIX环境编程学习笔记(2)——文件I/O之不带缓冲的 I/O

    lienhua342014-08-25 1 文件描述符 对于内核而言,所有打开的文件都通过文件描述符引用.文件描述符是一个非负整数.当打开一个现有文件或创建一个新文件时,内核向进程返回一个文件描述符. ...

随机推荐

  1. C#使用BeginInvoke和EndInvoke异步下载和获取返回结果

    场景:为了防止UI卡死,使用异步下载文件 问题:采用多线程下载,关闭窗口后下载线程不能停止,线程操作麻烦. 参考:C#客户端的异步操作: http://www.cnblogs.com/fish-li/ ...

  2. C#使用ActiveMQ实例

    1. ActiveMQ消息总线简介 消息队列(Message Queue,简称MQ),从字面意思上看,本质是个队列,FIFO先入先出,只不过队列中存放的内容是message而已.主要用作不同进程.应用 ...

  3. anconda使用---使用conda管理python环境

    一.动机 最近打算折腾vn.py,但只有py27版本的,因为一向习惯使用最新稳定版的,所以不得不装py27的环境,不得不说 Python的全局锁真的很烦. 身为懒癌患者,必然使用全功能的anacond ...

  4. windows和linux文件的转换

    由于windows与unix系统的换行不一致,因此需要相互之前的格式转换 只需要在linux上执行 dos2unix filename 将windows下的文本文件转换成linux上可以浏览的文件 u ...

  5. rsa.FromXmlString 系统找不到指定的文件

    rsa做加密解密的时候,发布到IIS7 Windows2008上出现异常,提示rsa.FromXmlString找不到指定的文件. 原因是系统安全性问题,做了变更,修改为如下代码即可: System. ...

  6. sqoop 常用命令整理(二)

    26.Validate 它用来比较源数据和目标数据的数量 它有三个接口 Validator. 它有三个接口 Validator. Property: validator Description: Dr ...

  7. 使用JAAS登录kerberos服务器

    java代码: package com.snsprj.jaas0822; import javax.security.auth.*; import javax.security.auth.callba ...

  8. onClickRow 事件

    onClickRow: function (rowIndex, rowData) {                        dgonClickRow(rowData.oldCityCode,r ...

  9. ZARM in Linux & MIUI

    zram是Linux内核的一个模块,之前被称为“compcache”.zram通过在RAM内的压缩快设备上分页,直到必须使用硬盘上的交换空间,以避免在磁盘上进行分页,从而提高性能.由于zram可以用内 ...

  10. 自然语言交流系统 phxnet团队 创新实训 个人博客 (五)

    有关我们这个项目:智能自然语言交流系统,所借鉴的技术有: 第一:我们使用了科大讯飞的在线语音转换,涉及的有文本传给云端服务器的文字转换成语音和本地的语音上传给服务器转换成文字. 涉及的相关的代码有: ...