I'm using imagecache in conjunction with imce and bueditor. Inserting images into nodes is done via php theme function call, which looks like that:

<?php print theme('imagecache', 'small', 'MyImage.jpg', 'MyText', 'MyText');?>

I've given all users including anonymous users the right "view imagecache small" (and other sizes). The Theming function generates the correct image path /files/imagecache/small/MyImage.jpg. But the images aren't shown for anonymous users. Using the path directly generates an "access denied" error.

After a while i got this working by setting directory attributes to "775" manually for all imagecache directories. But I think this should be done programmatically depending on the defined access rights. Or how can this be managed otherways?

Best regards,
Boris Böhne

CommentFileSizeAuthor
#10 imagecache-folder-permission-fix.patch1.14 KBB-Prod
Support from Acquia helps fund testing for Drupal Acquia logo

Comments

dman’s picture

On install, imagecache creates its own files/imagecache directory.
When a preset is made, imagecache creates subfolders and files there. It can because it has drupal file permissions. Those folders do get created with whatever you have configured on your server.

If you have an odd suid for the apache user (eg, You can create folders that you don't have permission to write to yourself) then you've got system problems. Normally you'll have 755 out-of-the-box and may consider choosing 775 instead.

Only if you had backed up, restored, or created the imagecache folder with other permissions would this stop working. It certainly can go wrong if you are copying between servers without then repairing permissions for files/* as needed

It's got nothing to do with anon/public permissions. Actually imagecache cannot restrict direct file access to those files unless you are using private filesystem.

Can you confirm that this becomes a problem for you on a fresh system with file settings configured correctly? Or that it really is connected with anon requests and not registered user requests?

drubb’s picture

Thanks,

you're really fast...

I've just done the following test to reproduce the problem: I've created a new preset called "test". ImageCache creates the appropriate folder when first called using this preset, e.g. /files/imagecache/test/MyImage.jpg. But the new folder "test" is created with attribute 744 instead of 755. And so the contained images aren't accessible (they get 775, by the way).

You're right, this has nothing to do with drupal access rights. It's just a wrong directory attribute. But why? Server misconfiguration? Other modules with own directory management (e.g. imce, webfm) seem to work fine.

dman’s picture

Well, apache user rights are a server config issue, but there's a few approaches and reasons for them.
If it really does norrow down than far, then I think a permissions correction chmod() could be added to imagecache ... but I thought it largely used the existing Drupal file methods. like drupal_check_directory()

If not, you are probably right and it should.

I've not seen a problem, as my www-data user just gets it right without an override thanks to umask.

drubb’s picture

I've taken a look at your source code, and that's the way you're creating the directories:

if (!file_check_directory($dir) && !mkdir($dir, 0775, true)) { 
 ...

So there's a hardcoded mode 775 which should work. But I think you can't rely on this mode being created because it may be modified by the current umask, which you don't know. php.net suggests two ways to solve this problem:

a) reset umask temporarily:

$oldmask = umask();
if (!file_check_directory($dir) && !mkdir($dir, 0775, true) &&  !umask($oldmask)) { 
 ...

b) use a chmod after directory creation (considered the better way):

if (!file_check_directory($dir) && !mkdir($dir, 0775, true) && !chmod($dir, 0775)) { 
 ...

Perhaps you should patch imagecache this way. I'm not sure my boolean logic is correct, it's rather late in germany...

dman’s picture

It looks like that line should instead use file_check_directory() With the 'create' flag set on. That way it becomes Drupal Core's problem.

file_check_directory() internally then uses the chmod() to fix it, as you suggest.

Yeah, I think that's a good answer.

drubb’s picture

Sounds good to me... Thx!

yultyyev’s picture

Version: 5.x-2.1 » 6.x-2.0-beta9

it looks strange, but after copying my drupal site to the new hosting (via ssh), i get error in that place

if (!file_check_directory($dir) && !mkdir($dir, 0775, true)) {
...

(warning: mkdir() [function.mkdir]: Permission denied in /home/www/site.com/sites/all/modules/imagecache/imagecache.module on line 526.)
I change chmod of "files" directory and some subfolders to 775 but it is still don't work...

p.s. drupal 6 and imagecache 6.2

drubb’s picture

I've had this problem recently with a newly created D6 site. All imagecache directories were created with attribute 744 and thus not accessible. So file_check_directory obviously doesn't do the job. I fixed it using a very simple workaround: instead of patching imagecache module I've added just one line to my drupal settings.php file:

umask(022);

As 022 is the "default" umask value for php, imagecache and other module directories are now created with attribute 755, as it should be.

BUT I don't know about possible side effects of this solution (it's not recommended to change umask via scripts), so be careful!

shark’s picture

Version: 6.x-2.0-beta9 » 6.x-2.0-beta10

Perhaps this is now a Core issue, but if the goal is for directories created by imagecache to be writeable by group (chmod 0775), the chmod has to happen for each directory recursively.

In other words, part of the problem is that imagecache builds up the path and mkdir() creates all components of the path, and subsequently each component is screwed up by the server's umask setting, and then the chmod() only fixes the directory at the bottom of the path.

Here's the file_check_directory from Drupal's include/file.inc:

function file_check_directory(&$directory, $mode = 0, $form_item = NULL) {
  $directory = rtrim($directory, '/\\');

  // Check if directory exists.
  if (!is_dir($directory)) {
    if (($mode & FILE_CREATE_DIRECTORY) && @mkdir($directory)) {
      drupal_set_message(t('The directory %directory has been created.', array('%directory' => $directory)));
      @chmod($directory, 0775);  // Necessary for non-webserver users.
...

As a concrete example: if the path passed in is "imagecache/default/pictures" and the imagecache/ directory doesn't exist yet, mkdir() will create imagecache/, imagecache/default, and imagecache/default/pictures, and then the chmod() will only apply to imagecache/default/pictures.

In my case, umask is 022, so so imagecache/ and imagecache/default are 0755 and while imagecache/default/pictures is the desired 0775.

I imagine the reason this issue seems to come up with ImageCache more than other modules is because it is creating deeper directory trees than most others.

B-Prod’s picture

Status: Active » Needs review
FileSize
1.14 KB

This could do the trick.

juanjo_vlc’s picture

I think the mode must be the system umask or a configurable one, never hardcoded, in example, I'm on a shared hosting, every site has is own user, but all sites shares the group, so, i don't want group write permission on any folder.
It's possible?

baff’s picture

I did not grant permission to view any preset to any role. But everyone can see all presets.

vunger’s picture

I used ImageCache to make thumbnail versions of my images, for an image gallery. The thumbnails do not display for anonymous users; in fact, none of the images are displaying for anonymous users. I tried changing the permissions and got an error every time I tried to submit the permissions form. Deactivating ImageCache and ImageAPi made the error go away.

I've tried the patch and it failed to apply.

drewish’s picture

baff, you need to use private file transfers if you want that control.

fizk’s picture

Status: Needs review » Closed (fixed)

Please reopen if this is still an issue with ImageCache 6.x-2.0-rc1.