gpt4 book ai didi

c - www-data 调用读取文件的程序

转载 作者:行者123 更新时间:2023-11-30 16:30:55 25 4
gpt4 key购买 nike

在 Ubuntu 16.04.3 LTS 服务器上,网页调用运行可执行文件的 PHP 脚本。即使对于属于 root 的可执行文件(这些可执行文件的访问模式为 0755),这也可以正常工作。

但是,当网页调用 PHP 脚本来运行可执行文件,并且该可执行文件尝试打开文件进行读取时,程序会运行但无法打开该文件。

需要进行哪些更改才能使 Apache (www-data) 可以运行打开文件进行读取的可执行文件(我用 C 语言编写)?

我们将可执行文件称为ExecutableFile。要打开进行读取的文件可以称为 FileToRead,它位于名为 DirectoryContainingFileToRead 的目录中。该目录与 ExecutableFile 位于同一目录中。

ExecutableFile 在命令行中被赋予 FileToRead。它知道查找 DirectoryContainingFileToRead。如果找到它,它将引用该文件计算结果。如果找不到,程序将计算默认结果。

PHP 使用其 exec() 函数调用可执行文件,如下所示:

$data = exec('./ExecutableFile FileToRead OtherArgument 2>&1');

这是我已经尝试过的方法,但没有成功:

  1. 更改相关文件的所有权。可执行文件的模式为 755。DirectoryContainingFileToRead 的模式为 755。FileToRead 的模式为 644。

    chown www-data.www-data ExecutableFile
    chown www-data.www-data DirectoryContainingFileToRead
    chown www-data.www-data DirectoryContainingFileToRead/FileToRead

这不会产生任何变化。 (如上所述,其他不尝试打开文件的可执行文件在被 www-data 调用时仍然会运行,即使它们属于 root.root。这些可执行文件已为每个人启用了读取和执行权限。)

  • 与上面相同,但将组保留为 root:

    chown www-data.root ExecutableFile
    chown www-data.root DirectoryContainingFileToRead
    chown www-data.root DirectoryContainingFileToRead/FileToRead
  • 这不会产生任何变化。返回默认结果。

  • 保留所有文件的 root 属性并仅更改 ExecutableFile 上的粘滞位:

    chown root.root ExecutableFile
    chown root.root DirectoryContainingFileToRead
    chown root.root DirectoryContainingFileToRead/FileToRead
    chmod +s ExecutableFile
  • 这不会产生任何变化:可执行文件仍将运行,但不会打开文件。

  • 更改所有相关文件的粘滞位:

    chown root.root ExecutableFile
    chown root.root DirectoryContainingFileToRead
    chown root.root DirectoryContainingFileToRead/FileToRead
    chmod +s ExecutableFileName
    chmod +s DirectoryContainingFileToRead
    chmod +s DirectoryContainingFileToRead/FileToRead
  • 这不会产生任何变化:程序运行但不打开文件。返回默认结果。

  • 将所有文件的所有者更改为 www-data 并仅为 ExecutableFile 设置粘滞位:

    chown www-data.root ExecutableFile
    chown www-data.root DirectoryContainingFileToRead
    chown www-data.root DirectoryContainingFileToRead/FileToRead
    chmod +s ExecutableFileName
  • 相同的默认结果。

  • 重新编译程序以使用setuid(0);在尝试打开文件之前:

    FILE* fp;
    char fpath[64];
    int currentUID = getuid(); // Save given UID
    sprintf(fpath, "./DirectoryContainingFileToRead/%s", FileToRead);
    if(setuid(0) < 0) // Briefly become root
    {
    printf("Unable to become root\n");
    exit(1);
    }
    fp = fopen(fpath, "rb");
    if(fp == NULL)
    {
    // Proceed without use of the file
    }
    else
    {
    // Make use of the file
    fclose(fp);
    }
    if(setuid(currentUID) < 0) // Resume being yourself
    {
    printf("Unable to resume given identity\n");
    exit(1);
    }
  • 当尝试成为 root 时,此退出。 ExecutableFile 有 755 个。DirectoryContainingFileToRead 有 755 个。FileToRead 有 644 个。

  • 与尝试 6 相同,但也像尝试一样在可执行文件上设置粘滞位。

    chmod +s ExecutableFile
  • 这至少会在不退出的情况下运行,但结果表明它没有打开文件。

  • 与尝试 6 相同,但在所有涉及的文件上设置粘滞位:

    chmod +s ExecutableFileName
    chmod +s DirectoryContainingFileToRead
    chmod +s DirectoryContainingFileToRead/FileToRead
  • 同样,这至少会运行,但结果表明不允许该程序访问该文件。

    我为此感到抓狂。我一整天都在研究这个问题。我查阅了有关 StackOverflow、维基百科、Tanenbaum 和 Bos 的现代操作系统的其他讨论。所有这些消息来源都表明权限受到威胁,但我尝试的解决方案在实践中都不起作用。任何见解将不胜感激。

    最佳答案

    天哪。这背后有一个愚蠢的疏忽:

    如果我使用要读取的文件的绝对路径,一切正常,如下所示:

    sprintf(fpath, "/var/long/path/DirectoryContainingFileToRead/%s", FileToRead);

    不需要粘性位。我什至不需要chown任何东西:ExecutableFile、DirectoryContainingFileToRead 和 FileToRead 都属于 root。只需确保可执行文件和目录已被启用的任何人读取和执行。要读取的文件应该可供任何人读取。

    需要明确的是,PHP 调用如下:

    $data = exec('../../ExecutableFile FileToRead OtherArgument 2>&1');

    我在原来的帖子中省略了 PHP 使用的相对路径,认为它不相关。事实上,有必要彻底认识这个问题。

    PHP 命令中的相对路径。 C 代码中的绝对路径。

    这么多浪费的烦恼......

    关于c - www-data 调用读取文件的程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50847856/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com