I get this error occasionally "Directory /tmp/drush exists, but is not writable." Because some user owns that and other users don't have write access. It looks like this data is ok to share between users and being in /tmp, a globally writable area anyways. I think drush should create its /tmp/drush folder as a globally writable one.

#25 drush-multi-user-1528976-21.patch585 bytesAnkabout
Members fund testing for the Drupal project. Drupal Association Learn more


kotnik’s picture

Assigned: Unassigned » kotnik

Not only this directory should not be writable for anybody, it should not be readable either, since that definitely is security issue.

All other tools create tmp directory per user (with 0700 perms) and so should Drush. For example, Midnight Commander creates /tmp/mc-$USERNAME, Emacs makes /tmp/emacs$UID directories, etc.

koglinjg’s picture

Gotcha, that works too, I just looked at some of the cache data and it didn't look particularly sensitive. Thanks for taking a look at this.

jfine’s picture

Would be great to see a fix for this. It's a bit annoying to have to rm -Rf /tmp/drush*

jfine’s picture

Priority: Minor » Normal
moshe weitzman’s picture

Anyone see a problem with code like this?

function drush_get_username() {
  return drush_is_windows() ? getenv("username") : getenv("USER");
jonhattan’s picture

kotnik’s picture

get_current_user() returns the owner of the php *file*, not who run it, so code in #5 should be fine (if Windows part is okay, I don't know Windows).

moshe weitzman’s picture

Status: Active » Postponed (maintainer needs more info)

Which commands or subsystems are causing these messages? In general, commands should run in a timestamp named directory that gets cleaned up at end of request. See http://api.drush.org/api/drush/includes!filesystem.inc/function/drush_te...

jfine’s picture

I don't think problem isn't with the file name/path. The problem is with the file permissions. In my case drush is installed system wide in /usr/local/lib/drush with a sym link from /usr/local/bin/drush. When the drush command is run /tmp/drush/... is created but it is created with the user/group of the user who executed the drush command and the following permissions drwxr-xr-x. If the next user issues the drush command they will see a permissions issue because /tmp/drush is owned by a different user and does not have group or other writeable permissions. So regardless of the unique path's under the temp directory, they will not be able to be written to based on the permissions of the parent directory.

As an experiment I ran the following command which allowed both users to write to the directories they needed to and I am now able to run drush from multiple users. However since this is /tmp it's going to get cleaned up at some point so this isn't a very useful workaround.

# mkdir /tmp/drush
# mkdir /tmp/drush-env
# chmod ugo+rwx /tmp/drush*

acrollet’s picture

Assigned: kotnik » Unassigned
Status: Postponed (maintainer needs more info) » Needs work

Ran into this and have dug into it a bit. In short, the responsible code is in the drush_directory_cache() function in includes/environment.inc. Basically, if the .drush/cache directory of the user calling drush is not writable, this code will create a cache dir under {system temp dir}/drush/cache. If another user with a non-writable cache dir attempts to run drush dl or similar, they will receive the error reported by OP. This seems to be a bit of an edge case, but I can imagine scenarios where it could occur, for example a shared hosting server with non-writable network mounted home dirs. Steps to reproduce:

as user 1:
chmod a-w ~/.drush/cache
drush dl drupal

as user 2:
chmod a-w ~/.drush/cache
drush dl drupal

Receive following error:

Directory /Users/user2/.drush/cache/default exists, but is not writable. Please check directory permissions.                                     [error]
Directory /private/tmp/drush exists, but is not writable. Please check directory permissions.                                                    [error]
Drush must have a writable cache directory; please insure that one of the following locations is writable: /Users/user2,/tmp                     [error]
file_put_contents(/6.0-dev-commandfiles-0-dab37104d7663fa9b020bdb97741ac0c.cache): failed to open stream: Permission denied cache.inc:433        [warning]

I thought about ginning up a patch, but I'm not sure if the preferred solution is to make /tmp/drush world-writable, or to make per-user cache directories under /tmp.

As a side note, I ran into this because I was using sudo to run drush as the desired user, but the HOME environment variable was not being changed. Thus, drush was trying to use the home dir of the user calling sudo, rather than the user running drush. Using the -H switch with sudo resolves my particular issue.

kotnik’s picture

The best solution is to make per-user cache directories under /tmp.

I'll deal with this if nobody else started.

mc0e’s picture

Priority: Normal » Major

I get the problem as follows

www-data@web:~$ $drush --version
drush version 5.7

www-data@web:~$ rm -rf /tmp/drush/

www-data@web:~$ $drush -r $HTTP_ROOT -l $DOMAIN sql-connect
mysql --database=xxxxxx --host=db --user=drupal6 --password=xxxxxxx

www@web:~$ find /tmp/drush* -maxdepth 3 -ls
31244291    4 drwxr-xr-x   3 www-data www-data     4096 Aug 21 18:40 /tmp/drush
31244292    4 drwxr-xr-x   3 www-data www-data     4096 Aug 21 18:40 /tmp/drush/www-data
31244293    4 drwxr-xr-x   4 www-data www-data     4096 Aug 21 18:40 /tmp/drush/www-data/cache
31244313    4 drwxr-xr-x   2 www-data www-data     4096 Aug 21 18:40 /tmp/drush/www-data/cache/usage
31244294    4 drwxr-xr-x   2 www-data www-data     4096 Aug 21 18:40 /tmp/drush/www-data/cache/default
31244290    4 drwxr-xr-x   2 www-data www-data     4096 Aug 21 18:40 /tmp/drush-env

So, drush has created /tmp/drush and /tmp/drush-enc and left them there. There is a www-data directory within it, but /tmp/drush is not writable by anyone other than www-data, so no other per-user directories can be created by them. Just making the /tmp/drush directory writable is a poor option though because the user who creates it can then mess with the files of other users, potentially including root, and there's a likelyhood that this amounts to a root exploit if root runs drush.

Shared /tmp/drush between users is bad, giving undue control to the owner of that directory, and if owned by root it's a problem when it gets cleaned up as temporary files do. /tmp/drush- is plausible, so long as there's some permissions checks to verify that the current user owns the directory and that it's not writable by anyone else. Maybe better not readable either.

It'd be nice if drush honoured the TMPDIR environment variable. This appears to affect the location of the drush-env temp directory, but not the drush temp directory.

It may be significant that the www-data user does not have write access to its own home directory, but drush should be robust in the face of this.

The predictability of file and directory names may be necessary, but if so then a lot of care is required to avoid race conditions.

Because of the security implications, I've raised the priority of this issue.

Modifying the workaround suggested earlier, I've done this:

chown root:root /tmp/drush*
chmod --reference=/tmp /tmp/drush*
mc0e’s picture

Priority: Major » Normal

For users (including root) who can write to their own home directory, the cache files get stored in ~/.drush/cache. On that basis I'm putting the priority back down again.

Creating a directory at /var/www/.drush and setting it to be owned and writable by www-data doesn't seem to be enough to make www-data use it.

Tested with drush version 6.0-dev. Same behaviour.

mc0e’s picture

The relevant code is in the drush_directory_cache() function in drush/includes/environment.inc

shiff2kl’s picture

It determines the home directory based on the environment variable HOME. So confirm that is set for the desired user. I am using bamboo (similar to jenkins) to run drush cc all and was running into this issue. It runs as the drupal user, however it does not see a HOME env by default. Once I set that, it started working as desired.

# example
export HOME=/home/drupal

moshe weitzman’s picture

Perhaps could do some validation for required ENV variables? Like we do for php version and CLI check.

scor’s picture

same problem here. I add sudo rm -r /tmp/drush* at the top of my scripts as workaround.

moshe weitzman’s picture

Patches are most appreciated here, folks.

Sethie’s picture

Version: » 7.x-5.7

In my server setup, the 'HOME' environment variable is correctly set for the user and the user has write permissions.
The tmp directory for drush still points to /tmp/drush though.

Upon further investigation, it seems that the tmp Drush directory gets cached or something. I have deleted the tmp directory in /tmp/drush and after executing some commands, the cache directory is indeed created in /.drush for user A.
However, when I switch to user B and start executing drush commands, the tmp directory is not sepperately created for this user, but it tries to write in the cache directory of the previous user, user A.

Ankabout’s picture

Is there any fix for this, or any way to get around it manually? I'm on a shared server, and I don't have a way of editing /tmp in any way.

Even a hack would be enough, but like this I can't do any updates with drush.

Ankabout’s picture

I have found a simple solution that seems to work fine on my system.

I basically changed this line of code in environment.inc:
$cache_locations[drush_find_tmp()] = 'drush/' . getenv('USER') . '/cache';
$cache_locations[drush_find_tmp()] = 'drush-' . getenv('USER') . '/cache';

So it now makes a different drush directory under /tmp for every user.

Is this worth making into a patch? Any reason why this is not a good idea?

scor’s picture

sounds like a good idea. It works because no user will ever try to write inside the same /tmp/drush directory, instead they each create their own directory inside /tmp which in theory is writable to all of them. I can't comment on whether the drush maintainers would be comfortable with this solution though. It probably wouldn't hurt to roll a patch to try to get this going on this issue.

moshe weitzman’s picture

Sounds like a good solution to me too. Patches welcome.

Ankabout’s picture

Great! I'll put one together today or tomorrow.

Ankabout’s picture

Attached is a patch that makes the change as described in comment #24.

Anybody’s picture

We've had the same problem and the Patch in #25 works great! It would be nice to have some further comments from the community and add this to the dev-version as soon as possible.

The problem is really bad in multi user environments.

acrollet’s picture

@Anybody: if you've reviewed the patch according to http://drupal.org/patch/review and it passes all standards, you may set the issue to reviewed and tested by the community, which is the necessary next step for inclusion.

Anybody’s picture

Well, we're talking about a very system specific environment so I'd say we should wait for some more feedback from other users. In my case everything is fine and can confirm this as reviewed and testet for MY case. =)

Anyway I'd hope that we can change the status in some days.

jonhattan’s picture

Version: 7.x-5.7 » 8.x-6.x-dev
Component: Miscellaneous » Base system (internal API)

It seems it is getenv('username') in windows.

We need #5

jonhattan’s picture

Status: Needs work » Fixed

Implemented #5 and adapted #25. Committed to both Drush 6.x and 5.x.


Status: Fixed » Closed (fixed)

Automatically closed -- issue fixed for 2 weeks with no activity.

pfrenssen’s picture

Issue summary: View changes
Status: Closed (fixed) » Active

Reopening this. Since this went in I'm having a lot of trouble with permissions on these folders, eg.

Directory /tmp/drush-env exists, but is not writable. Please check directory permissions.
Directory /tmp/drush-pieter exists, but is not writable. Please check directory permissions.
Directory /tmp/drush-http exists, but is not writable. Please check directory permissions.

The problem is that the $USER environment variable is used to determine the user name, but this returns the user that is currently logged into the session, not the user that is actually running the command.

I use sudo -u to execute drush with the user that is relevant to the task at hand, but this does not affect $USER, so the temporary folders are created under the wrong username.

We should use `whoami` instead of $USER. whoami returns the active user:

[pieter@archlinux]$ sudo -u http echo $USER
[pieter@archlinux]$ sudo -u http whoami
helmo’s picture

Status: Active » Closed (won't fix)

This issue was marked closed (won't fix) because Drush has moved to Github.

If desired, you may copy this bug to our Github project and then post a link here to the new issue. Please also change the status of this issue to closed (duplicate).

Please ask support questions on Drupal Answers.

mariacha1’s picture

Since this is the number one result when searching for "/tmp/drush-env" I'm going to throw my fix here in case it helps others.

If you're getting the error:
Directory /tmp/drush-env exists, but is not writable

when trying to set a site alias and you're on shared hosting, it's possible that another user on your server already created a /tmp/drush-env folder with their username. So you can add:

putenv ('TMPDIR=/path/to/custom/dir/tmp');

right under the `<?php` in your aliases.drush.php file.

greg.1.anderson’s picture

Status: Closed (won't fix) » Fixed

I believe that this is fixed by https://github.com/drush-ops/drush/pull/64

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.