A module, Take_Control is now available for Drupal 6.x which you can use to change permissions of your files/folders on the server.

Warning: You cannot undo the file permissions that are changed by the script below. Proceed with extreme caution.

Symptom:

  • "Permission Denied" When trying to work with your site over FTP.
  • You cannot modify directories inside the /files folder that were created by Drupal.

Solution:

  • Tell Apache to give you back control of your files.

One side effect of having files created by Drupal (eg the image module), is that your user account might not have ownership of them any more. And you might not be able to delete the or move them around.

There is a workaround though. You can create a small PHP script containing the commands you want to carry out and upload it to the server. Once uploaded, you can run it from your web browser by entering the URL for it. The script will run as the user account the webserver runs as. Be sure to remove the script after you have used it though.

simple case:

Use a drupal PHP-format page (eg just a php code snippet) to run

`chmod -R a+w sites/default/files`;

and you (and the rest of the neighborhood!) should have write access so you can write/delete anything in your files and images directory via shell/FTP again. Modify the command as needed.

If that doesn't work, and particularly if you are trying to uninstall Drupal and want to be able to erase all files, save the following snippet as a php file (e.g. fix.php). It will try to make all directories and files writable in a recursive fashion. If you put this in the root folder of your Drupal installation and run it by going to http://www.example.com/fix.php it should operate on all possible files within your Drupal site. If you put it in your files directory, it will operate there, e.g: http://www.example.com/sites/default/files/fix.php

Important: this code should only be used if you remember to delete it immediately after use. As above, its use may put your site into an insecure state.


file_fix_directory(dirname(__FILE__));

function file_fix_directory($dir, $nomask = array('.', '..')) {
  if (is_dir($dir)) {
     // Try to make each directory world writable.
     if (@chmod($dir, 0777)) {
       echo "<p>Made writable: " . $dir . "</p>";
     }
  }
  if (is_dir($dir) && $handle = opendir($dir)) {
    while (false !== ($file = readdir($handle))) {
      if (!in_array($file, $nomask) && $file[0] != '.') {
        if (is_dir("$dir/$file")) {
          // Recurse into subdirectories
          file_fix_directory("$dir/$file", $nomask);
        }
        else {
          $filename = "$dir/$file";
            // Try to make each file world writable.
            if (@chmod($filename, 0666)) {
              echo "<p>Made writable: " . $filename . "</p>";
            }
        }
      }
    }

    closedir($handle);
  }

}

Documentation for PHP filesystem functions:
http://php.net/manual/ref.filesystem.php

And documentation for the PHP system() function:
http://php.net/manual/function.system.php

With these techniques you should be able to get the webserver to do anything the Unix shell can do. Some hosts however limit your ability to use shell-level commands like this, in which case you must approach them to ask for the appropriate fix.

Take care doing this though. These are the kind of tasks where it pays to practice them on your test instance first - you do have a test instance right?

Comments

screwn91’s picture

I have a problem of putting it back to its original state, well i used the codes

`chmod -R a+w sites/default/files`;

then, every time i open my site, its opening some file... how do i return this to its previous state? please? anybody... HELP... *sniff

(if possible, im a total beginner at this so im very sorry, i need a script... thanks a bunch... *sniff sniff)

joshmiller’s picture

Honestly -- you can't "return it back to normal." The best case scenario: you have a backup. The worse case scenario: You need to reinstall Drupal. Other worse case scenario: You open a standard Drupal install and go through to each file and chmod / chown each file so that it looks identical.

This isn't "Doom and Gloom," but it's not a good place to be.

Josh

archimax’s picture

When I place the php snippet above into a .php file, upload the file to the web server, and enter the file's url into the browser's address bar, I.E. 7 asks me if I want to Open/Save the file and does not execute the page. What could I be missing?

dman’s picture

Your server is not recognising .php as a php file. That's a pretty low-level thing unconfigured in your server admin if that's really the case. However, you also wouldn't be getting Drupal to work with index.php if it was really that broken.
Can't tell much more from your description, as you don't say what the server is or how it's configured.
Try one of the other methods : entering the same code in a drupal node page with php enabled. Or add it to the bottom of your settings.php (temporarily)

archimax’s picture

Thanks for your quick reply.
After a bit of tinkering, I have discovered the problem is specific to the 'https/docs/sites/default/files/' directory.
Placing a simple .php file inside 'https/docs/sites/default/' executes,
but moving the same file into 'https/docs/sites/default/files/' does not.
The permissions on '/default/' and '/files/' are identical (rwx r-x r-x), and I am the owner of both.
'/default/' contains only .php files, whereas '/files/' contains:
.htaccess
files.url
harland_favicon.ico
garland_logo.jpg
My guess is that either '.htaccess' or 'file.url' is interfering with the execution of the .php file.

dman’s picture

OMG yes. Who told you to put it inside /files/ ?
There is explicitly a high-security block to stop user-uploaded code from being executable. For reasons that are easy to guess. :-)
Normally we just drop that php file in the root, run it and remove it.

archimax’s picture

Thanks
I am working on a shared web server, and in this installation Drupal is not able to modify the files it creates inside the /file/ directory, so I was trying to modify the permissions with the php script. Another thread said something about running PHP via suEXE or suPHP having something to do with owner permissions (apache vs. me). I do not have direct access to the server admin., so I was trying to avoid asking someone to help setup suEXE or suPHP until I got the website up and running. Apparently Drupal's use of the files and directories is so interactive that my approach is not going be effective.
(A little knowledge is a dangerous thing.)

I guess I should just ask this question directly: Is the problem that Drupal is having modifying the files and directories it creates on the webserver related to suEXE or suPHP? What do I need to do to eliminate the numerous error messages I receive each time a change is made?

I think I found the answer here: http://drupal.org/node/376912

dman’s picture

This handbook page is to help solve the opposite of your problem.

  • "Permission Denied" When trying to work with your site over FTP.
  • You cannot modify directories inside the /files folder that were created by Drupal.

This happens when Drupal is writing to its file folder, but not letting you change it later.

What you have is a site that's not set up right in the first case - you've created a folder but not given Drupal rights to modify it, and the solution is over here

dadderley’s picture

The Rules module totally rocks!

I could not set up the automated back ups using the Backup/Migrate module because of the permissions regime on the server.
This solved the problem.

I set it up a triggered rule like so:

Event:: Cron maintenance tasks are being performed

Action:: "Execute custom PHP code" using your code:

<?php
`chmod -R a+w sites/default/files`;
?>

Presto! permissions problem solved.

kasunig’s picture

Can we use rm command to delete a file in php? If so, how to delete a file inside the shell which user has selected from php?
Like this...

$result=shell_exec('rm $filename');