PHP - rmdir (permission denied)

2019-02-18 23:59发布

问题:

I have an easy script to create and delete a folder, but when I try to delete a folder, it brings up and error.

The code:

<?php
if ($_POST['hidden']) {
$key = "../g_test/uploads";
$new_folder = $_POST['nazevS'];
$new_dir_path = $key."/".$new_folder;
$dir = mkdir($new_dir_path);    
if($dir)
chmod ($new_dir_path, 0777); 
}
if ($_POST['hiddenSS']) {
$key = "../g_test/uploads";
$new_folder = $_POST['nazevS'];
rmdir($key."/".$new_folder);
}
?>

The error msg:

Warning: rmdir(../g_test/uploads/) [function.rmdir]: Permission denied in /home/free/howto.cz/m/mousemys/root/www/g_test/upload.php on line 51

Does anyone know how to delete the folder (hopefuly with everything inside) ? Also if you see any other improvments, the code could have, feel free to tell me. :-)

Thanks, Mike.

回答1:

Generally speaking PHP scripts on Unix/Linux run as user "nobody", meaning they need the "all" privileges so it's a permissions problem with the directory. Also, to delete a file or directory in Linux/Unix you need write privileges on the parent directory. That might be your problem.

If you have problems with the files or directories you create, use chmod() on them to set the right permissions.

Also it might not be empty.

Also, it's worth mentioning that

$new_folder = $_POST['nazevS'];
$new_dir_path = $key."/".$new_folder;

is really bad from a security point of view. Sanitize that input.



回答2:

For the purpose of this answer, I will put the security risks of allowing any and all uploads in a directory aside. I know it's not secure, but I feel this issue is outside the scope of the original question.

As everybody said, it can be a permission problem. But since you've created the directory in your code (which is most likely running as the same user when deleted). It doubt it is that.

To delete a directory, you need to make sure that:

  1. You have proper permissions (as everyone pointed out).

  2. All directory handles must be closed prior to deletion.
    (leaving handles open can cause Permission denied errors)

  3. The directory must be empty. rmdir() only deletes the directory, not the files inside. So it can't do its job if there is still stuff inside.

To fix number 2, it is extremely simple. If you are using something like this:

$hd = opendir($mydir);

Close your handle prior to deletion:

closedir($hd);

For number 3, what you want to do is called a recursive delete. You can use the following function to achieve this:

function force_rmdir($path) {
  if (!file_exists($path)) return false;

  if (is_file($path) || is_link($path)) {
    return unlink($path);
  }

  if (is_dir($path)) {
    $path = rtrim($path, DIR_SEPARATOR) . DIR_SEPARATOR;

    $result = true;

    $dir = new DirectoryIterator($path);

    foreach ($dir as $file) {
      if (!$file->isDot()) {
        $result &= force_rmdir($path . $file->getFilename(), false, $sizeErased);
      }
    }

    $result &= rmdir($path);
    return $result;
  }
}


回答3:

It looks like you need access rights on the folder you're trying to edit.

To change this:

chmod ug+rw /home/free/howto.cz/m/mousemys/root/www/g_test/

or maybe you'll need to do

sudo chmod ug+rw /home/free/howto.cz/m/mousemys/root/www/g_test/

Make sure that this is what you want to do and that your application is secure. Don't give write rights to any application since it could lead to security issues.



回答4:

The webserver requires write access to the folder you're trying to delete. You can provide this with:

chgrp -R www-data g_test/uploads
chmod g+w g_test/uploads

where www-data is the user that the webserver runs under (may be apache or some variation depending on your OS and server installation). After this you can run rmdir (or rm -r if the directory isn't empty).

Also, keep in mind that giving the web server the ability to write to a directory posses security problems. In certain situations, this could allow a malicious user to run arbitrary code (i.e. take over your machine), or modify your website (i.e. server spyware).

For these reasons, you should only give dirs write perms that:

  • absolutely need them
  • don't contain source code
  • are outside the dir containing scripts
  • owned by the server

In this setup on a production machine, you could set up a separate directory just for this type of file, that only Apache can write to. If you have to deploy files to this directory, use sudo or the root account to do so to limit the accounts that have access.

For a more complete description of what I mean, have a look at the security tips section in the Apache documentation.