1

I've MAMP running httpd server as _www and I'd like to assign the temporary directory as part of the shell script (bash).

I've tried to use $TMPDIR as per these posts:

however it points to /var/folders/vp/tlt7xf791gl1_v56m0xdmrph0000gn/T/ and this folder has not necessary permissions, so Apache server can't create any files in there.

Based on this:

$ /usr/bin/stat -F $TMPDIR /tmp /private/tmp 
drwx------ 104 kenorb staff 3536 Oct 14 22:21:05 2015 /var/folders/vp/tlt7xf791gl1_v56m0xdmrph0000gn/T//
lrwxr-xr-x 1 root wheel 11 Apr  9 13:08:03 2014 /tmp@ -> private/tmp
drwxrwxrwt 112 root wheel 3808 Oct 14 22:12:04 2015 /private/tmp/

My www user which I care about:

$ id _www
uid=70(_www) gid=70(_www) groups=70(_www),12(everyone),61(localaccounts),401(com.apple.sharepoint.group.1),100(_lpoperator)

I can't use /tmp, because it's linked to my /private/tmp (which name states it's private).

Therefore how do I determine my correct temporary directory on OS X, so I and my httpd server can use it?

I don't want to hardcode value, as the script would be useless when used on different environments (e.g. on non-MAMP environment), so the location can vary.

  • 1
    Are you worried /private is just to "hide" the usual directories from / and not to mean you can't store files there. It's better form to use $TMPDIR instead of /tmp, but writing to /tmp is generally fine on OS X if you prefer using that fixed path... – bmike Oct 14 '15 at 21:28
  • The point of $TMPDIR being in /var/... is that it has the correct permissions - so what users is the directory open for and what user does the script run as? - private just is a historic so that the OS can be on a read only file system and /private is a mount to a local file system that can be written to – Mark Oct 14 '15 at 21:43
3

I would write to /tmp (which is equivalent to writing to /private/tmp ) since it's writable by all users and not just administrative users. It's there for compatibility and for bonus points, your script can clean up files or cut them if they grow too large.

I don't have an authoritative reference to why /private was called that, but it's always been open to writing and isn't restricted like $TMPDIR is from non-admin users.

The real question is what user are you running apache - a member of the ADMIN group or just a normal non-admin user?

Apple documents this in the Secure Coding Guide with the admonition that writing files to publicly readable locations is inherently insecure and that it's better to place files in more protected locations that aren't readable by all users. See the Race Conditions and Secure File Operations section and this link on creating secure temporary files. By using the mkstemp POSIX call you ensure a unique file is created and can control access with umask.

Oddly (to me), mktemp when run by a non-admin user can still make a temp file in $TMPDIR so it's clearly using escalated privileges to hand off that more "secure" file to non-admin users. Pretty cool.

  • Is there any variable or function which can use to determine that folder? Or I've to do conditionally? – kenorb Oct 14 '15 at 21:36
  • @kenorb - which folder? - $TMPDIR is the variable that gives the temporary folder (also TMPDIR is for all users each user has a different one /tmp is shared so you get conflicts between users) – Mark Oct 14 '15 at 21:59
  • @kenorb write to the path /tmp and bob's your uncle. You could make it a variable, but there's no point as it doesn't change. – bmike Oct 14 '15 at 22:23
  • 1
    I think it'll be easier to use /tmp, initially I was confused by the symbolic link which had 0755 on it, but the destination is actually 1777, so I hope it'll work in all cases. Thanks. – kenorb Oct 14 '15 at 22:27
  • You can't change /tmp or /private/tmp but all users can write there. Insecure, but it gets the job done with little muss or fuss. You're on it with the 1777 permissions. – bmike Oct 14 '15 at 22:35
1

As for workaround, I've found so far that php command can determine the right temporary directory from the www perspective (assuming PHP CLI has the same settings as server):

$ php -r "echo ini_get('upload_tmp_dir');"
/Applications/MAMP/tmp/php

It's possible also to use mktemp to check where the temporary files are created for specific user (as $TMPDIR would fail), e.g.:

$ sudo -uwww bash -c 'dirname $(mktemp)'
/tmp

So in summary this could be extended to something like:

#!/usr/bin/env bash
WWW_USER="$(ps axo user,group,comm | egrep "(apache|httpd)" | grep -v ^root | uniq | cut -d\  -f 1)"
PHP="$(which php)"

if [ -n "$PHP" ]; then
  TMP="$(php -r "echo ini_get('upload_tmp_dir');")"
elif [ -n "$WWW_USER" ]; then
  TMP="$(sudo -uwww bash -c 'dirname $(mktemp)')"
elif [ -n "$TMPDIR" ]; then
  TMP="$TMPDIR"
else
  TMP="/tmp"
fi

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .