16

I'm trying to make Wordpress work. I currently have this error message:

Could not create directory. /var/www/html/wp-content/upgrade/theme_name

when trying to upload a theme. This is the permissions set to /var/www/html/wp-content/upgrade/

drwxrwxr-x 3 ec2-user apache 4096 Jun 21 00:30 upgrade

chmod 777 upgrade makes the error go away. But that is not considered best practice. However, I think this should work too... why not?

I guess the web server may not be included by the above permissions. What group should I use to allow the web server to write?

(My setup is Amazon EC2, Amazon Linux AMI with httpd)

4 Answers 4

19

I don't know anything about Amazon EC2, but you should be able to:

  1. Retrieve the name of the user running Apache with a command similar to this:

    ps aux | grep apache # The username should be in the first column.
    
  2. Retrieve the groups this user is part of with the groups(1) command:

    groups [USERNAME]
    
3
  • The first column is apache, and groups apache return apache : apache. A line from the first commmand looks like this: apache 11171 0.0 3.4 39984 21516 ? S Jun20 0:02 /usr/sbin/httpd
    – user1995
    Jun 21, 2012 at 11:14
  • 1
    User apache clearly has permissions to write in the directory. You say chmod 777 solves the issue, so I am guessing you're using a different user to upload your themes. I don't know Wordpress very well. According to this answer try changing ownership to user www-data.
    – rahmu
    Jun 21, 2012 at 11:28
  • Thank you for taking the time to look up the article and everything. It was indeed a different user, as I realized Wordpress used FTP to do its work. I found out that user by what was suggested below and then added group apache, found out by step 1, to it. That solved it.
    – user1995
    Jun 21, 2012 at 16:55
2

You may try to use the following command-line method to find out your Apache group names:

WWW_GROUP=`ps axo user,group,comm | egrep '(apache|httpd)' | grep -v ^root | cut -d\  -f 2| uniq`
echo Apache group is: $WWW_GROUP

To get the user, check: How to determine Apache user from the command-line?

1

chmod 777 upgrade makes the error go away.

Well, in that case ls -ld /var/www/html/wp-content/upgrade/theme_name should reveal creator's credentials, which you can use for precise access granting.

And it's better using 1777 (as for /tmp) since at least it guarantees that only owner of a file would be able to unlink it.

3
  • 1
    Make the error go away! Interesting approach to problem solving. This is not a solution, it's a lie.
    – iharob
    Nov 25, 2015 at 14:17
  • What do you call "lie" — citing original author's text? :) or suggestion to at least use 1777 instead of 777? :) or finding out creator ownership and using it for "precise access granting"?
    – poige
    Nov 25, 2015 at 19:54
  • It's a lie to the system, because 777 is not correct in any context I know.
    – iharob
    Nov 25, 2015 at 21:27
0

If you want a one liner for this to stuff in a test or subshell or something, this works well:

ps -ef | egrep '(httpd|apache2|apache)' | grep -v "$(whoami)" | grep -v root | head -n1 | awk '{print $1}' | groups | awk '{print $2}'

In the above, the last command selects the 2nd group, because the first is typically sys, which is not generally useful.

If you want a list of all groups that apache is in, drop the last pipe section awk '{print $2}, like so:

ps -ef | egrep '(httpd|apache2|apache)' | grep -v "$(whoami)" | grep -v root | head -n1 | awk '{print $1}' | groups

If you want the apache username, do the previous and also drop the groups pipe section, like this:

ps -ef | egrep '(httpd|apache2|apache)' | grep -v "$(whoami)" | grep -v root | head -n1 | awk '{print $1}'

I do not suggest making assumptions about the environment unless it is fully under your own control. If you need to programmatically determine the user and are not absolutely certain that it will always run in a specific environment (or are not certain that someone may have changed it to some custom name/group in their apache.conf), then it is practical to have some uniform method to check for it. You can stuff this in a .env file under some common key for localized program access, or alternately echo it into bash_profile or bashrc if you want a consistent variable to check systemwide, perhaps like this:

echo export "WEBSERVER_USERNAME=$(ps -ef | egrep '(httpd|apache2|apache)' | grep -v "$(whoami)" | grep -v root | head -n1 | awk '{print $1}')" >> ~/.bash_profile
echo export "WEBSERVER_USERGROUP=$(ps -ef | egrep '(httpd|apache2|apache)' | grep -v "$(whoami)" | grep -v root | head -n1 | awk '{print $1}' | groups | awk '{print $2}')" >> ~/.bash_profile
source ~/.bash_profile

Elsewhere: ...

# chown a dir to the webserver universally
# for typical 755 directory permission
# Good for production environment web app folders
sudo chown "${WEBSERVER_USERNAME}:${WEBSERVER_USERGROUP}" /path/to/dir

# chown to your user and the webserver usergroup
# for shared 775 cli/http directory perms
# good for dev environment, localhost, or anywhere that
# you have to do a lot of cli file edits to web folders/files
sudo chown "$(whoami):${WEBSERVER_USERGROUP} /path/to/dir

or whatever else you need it for without having to look it up a million times

You must log in to answer this question.