When one of my users reported problems deleting files he had uploaded using a PHP script, I quickly discovered all the files being uploaded were owned by the user running the web server:
nobody. This meant only the root user could delete those files.
Apache suEXEC is commonly used to resolve this problem. It allows Apache to run as the user who owns the domain being accessed. This way, files created by PHP would be owned by the user owning the site instead of the default
However, Apache suEXEC only works if you're using CGI as the PHP handler. The PHP5 handler on my server was set to use CGI, but I have PHP4 configured as the default PHP version and it was configured to use DSO. When I tried changing PHP4 to use CGI as the handler, most of the domains on my server displayed this:
Warning: Unexpected character in input: '' (ASCII=15) state=1 in /usr/local/cpanel/cgi-sys/php4 on line 772 Warning: Unexpected character in input: ' in /usr/local/cpanel/cgi-sys/php4 on line 772 Warning: Unexpected character in input: ' in /usr/local/cpanel/cgi-sys/php4 on line 772 Warning: Unexpected character in input: ' in /usr/local/cpanel/cgi-sys/php4 on line 772 Parse error: syntax error, unexpected T_STRING in /usr/local/cpanel/cgi-sys/php4 on line 772
OK, that looks like a problem with cPanel. I don't have time to debug cPanel's problems.
suPHP, like suEXEC, is used to run Apache as the user who owns the domain. I decided to try recompiling Apache and PHP with suPHP enabled to see if that would fix the problem.
File Ownership Hell
suPHP worked, except now the sites using PHP sessions were trying to access stored session data in
/tmp/ that was owned by the user
nobody! So I deleted all the session data and that allowed the PHP sites to create new session data with file ownership of the user owning the domain.
But then I tried accessing my WordPress admin page and started getting permission denied errors in
/wp-content/cache/. Same problem: the cache files that had been created before I enabled suPHP were owned by the user
nobody and now the user who owns my domain couldn't access them. A quick
chown -R raamdev:raamdev /wp-content/cache/ fixed that problem.
Yeah, I could simply
chown -R [user]:[user] /home/[user] for each of the users on the server, but there's something about running a recursive command on files I've never seen, and know nothing about, that makes me uncomfortable.
More suPHP Limitations
I was beginning to worry that this was going to be more difficult than simply enabling suPHP and I wondered how many other sites I'm hosting could have similar problems. I tried accessing one of the high priority sites I'm hosting and discovered it was broken and displaying an "Internal Server Error".
After a little research, I discovered that you cannot use php_value directives in .htaccess files with suPHP. The .htaccess file included with (created by?) Joomla! contained this at the bottom:
#Fix Register Globals php_flag register_globals off
I already knew
register_globals was turned off in the global PHP configuration, so I simply commented out that line and the site started working again.
It was at this point that I concluded it was too risky to just blindly enable suPHP while hosting over 50 domains, many of which I am not at all familiar with what's being used or hosted. I will need to take the time to carefully crawl through all the sites making sure their .htaccess files don't contain anything that might disrupt suPHP and then confirm all the sites are still working properly.
Lesson learned: Setup suPHP before you're hosting 50+ domains.