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

时间:2018-06-14 00:02:03

标签: c apache ubuntu permissions chmod

在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. 更改所涉及文件的所有权。 ExecutableFile具有模式755。 DirectoryContainingFileToRead具有模式755。 FileToRead具有模式644。

    chown www-data.www-data ExecutableFile
    chown www-data.www-data DirectoryContainingFileToRead
    chown www-data.www-data DirectoryContainingFileToRead/FileToRead
    
  2. 这不会产生任何变化。 (如上所述,其他不尝试打开文件的可执行文件仍会在被www-data调用时运行,即使它们属于root.root。这些可执行文件具有读取和执行权限。)

    1. 与上述相同,但将该组保留为root:

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

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

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

        1. 更改所有涉及的文件的粘滞位:

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

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

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

            1. 重新编译程序以使用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);
                }
              
            2. 尝试成为root时退出。 ExecutableFile有755. DirectoryContainingFileToRead有755.FileToRead有644。

              1. 与尝试6相同,但也在可执行文件中设置粘滞位。

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

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

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

                  我正在为此撕开我的头发。我整天都在研究这个问题。我已经就StackOverflow,Wikipedia,Tanenbaum&amp; amp; Bos'现代操作系统。所有这些来源都表明权限受到威胁,但我尝试的解决方案都没有在实践中发挥作用。任何见解都将受到赞赏。

1 个答案:

答案 0 :(得分:0)

哦,伙计。这背后是一个愚蠢的疏忽:

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

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

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

要明确,PHP会这样调用:

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

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

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

这么多浪费了加重......