首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >根不起作用

根不起作用
EN

Unix & Linux用户
提问于 2012-01-07 17:48:34
回答 1查看 400关注 0票数 6

一个来自阿普的程序。

代码语言:javascript
运行
复制
#include "apue.h"
#include <fcntl.h>

int main(int argc, char *argv[])
{
    if(argc!=2)
        err_quit("usage: a.out <pathname>");

    if(access(argv[1], R_OK)<0)
        err_ret("access error for %s",argv[1]);
    else
        printf("read access OK\n");
    if (open(argv[1], O_RDONLY)) {
        err_ret("open error for %s", argv[1]);
    } else {
        printf("open for reading OK\n");
    }

    return 0;
}

我将其编译成一个名为4-2的可执行文件,并更改了所有者并设置了suid --这是ls -l的输出:

代码语言:javascript
运行
复制
-rwsr-xr-x 1 root sinners 8490 Jan  7 18:50 4-2*

/etc/shadow

代码语言:javascript
运行
复制
-rw------- 1 root root 421 Jan  4 01:29 /etc/shadow

但当我运行它时:

代码语言:javascript
运行
复制
user% ./4-2 /etc/shadow 
access error for /etc/shadow: Permission denied
open error for /etc/shadow: Permission denied

有人能解释一下为什么我会得到这些accessopen错误吗?

EN

回答 1

Unix & Linux用户

发布于 2012-01-07 18:03:50

引用access() 命令页的话:

检查是使用调用进程的实际UID和GID完成的,而不是在实际尝试文件上的操作(例如打开(2))时执行的有效UID。这允许设置用户ID程序轻松地确定调用用户的权限.

设置用户ID位使得进程的有效UID等于文件所有者,但实际用户ID保持不变(即保持exec()之前的状态)。

可以使用setreuid()修改进程的有效UID和实际UID,也可以使用open()确定权限。我推荐第二种解决方案,特别是因为您已经调用了open()。您可以检查errno是否等于EPERM,以确定open()失败的原因是否是权限不足。

open()的调用在代码中失败,因为您使用来自open()的返回值作为if条件。我想调用实际上是成功的,并返回一个有效的、非零的(已经被stdin获取的)文件描述符,从而使控件进入错误处理分支。if的错误处理分支显示EPERM错误消息,因为这是由于access()调用而发生的最后一个错误。输入错误处理分支的条件应该检查open()是否返回-1。

票数 7
EN
页面原文内容由Unix & Linux提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://unix.stackexchange.com/questions/28543

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档