Safe Mode GID
Some commercial web hosting providers run their servers with PHP Safe Mode turned on. This can cause difficulties for programs, including PmWiki and Qdig, that write files and then try to read those files.
A Safe Mode warning looks like this:
Warning: ... SAFE MODE Restriction in effect. The script whose uid is XXXX is not allowed to access ... owned by uid XXX in ... on line XXXX
The easiest way for PmWiki to work on a server running in Safe Mode is to turn safe_mode_gid on, which a server administrator can do by adding
safe_mode_gid = On
to the server's PHP configuration file (php.ini) and restarting the web server daemon.
A good web hosting provider should be willing to do this for you because the security benefit probably exceeds the security risk for them, considering
- files written in ordinary (non-SetGID) still will be blocked, and
- you won't need to put world-writable files in your web document tree.
With Safe Mode turned on and the most common server configuration (running PHP as a server module and default safe_mode settings) the server will not bee able to open files that the server itself has written! The reason is because the UID of the files does not match the UID of the PmWiki script.
You can work around this limitation by using SetGID (by performing the default PmWiki installation routine) and then telling Safe Mode to compare the GID instead of the UID when it opens a file.
Under ordinary conditions, when you're running PHP as a web server module, files created by the script will have the server daemon's ownership (UID) and group ownership (GID) by default. If another user (such as "apache", "httpd", "www", or "nobody") writes files in your directories, then you cannot modify or delete the files unless they are world-writable.
Serving world-writable files, or especially files from a world-writable directory has obvious security drawbacks.
How the SetGID Bit Helps
To allow both the PmWiki script and you to modify and delete files that are written by the script, the PmWiki installation instructions direct you to temporarily set the permissions of wiki's directory to "2777" (drwxrwsrwx). This means "world-writable with the setGID bit enabled".
While the wiki's directory has "2777" permissions PmWiki can create writable subdirectories for storing wiki pages (wiki.d/) and / 0r uploads (uploads/). Be sure to re-set permissions on the wiki's directory to something like "0755" (drwxr-xr-x, non-world-writabile) once this is done! The new subdirectories created by PmWiki have
- ownership by the server's UID, just like normal
- group ownership by your GID, because the setGID bit is enabled and
- the setGID bit set.
drwxrwsr-x servers-UID your-GID wiki.d/ drwxrwsr-x servers-UID your-GID uploads/
Since these directories have the setGID bit turned on, any subsequent directories PmWiki creates will have similar permissions and ownership. Files Qdig creates in these directories will have similar ownership and group ownership, but will be readable and writable by both the server daemon and you:
-rw-rw-rw- servers-UID your-GID some-file-PmWiki-created
(Probably to reduce support requests, PmWiki creates world-writable files by default. See below for a way to change that.)
How Safe Mode Gets In The Way
Here's where safe_mode comes in: With safe_mode enabled, by default the server does a "UID compare check" to make sure files belong to your UID before opening them. Files written by the server don't have the same UID as the PmWiki script does, so the server refuses to open them. From the PHP Manual:
How to Get Safe Mode Out Of The Way
safe_mode_gid = On
to the server's PHP configuration file (php.ini) and restart the web server daemon.
In my (Hagan Fox's) testing (on Mandrake and Debian), turning on safe_mode_gid has worked as advertised, solving the server-can't-read-files-it-created problem completely.
To cause PmWiki to write file that are not world-writable is easy. Just put
## Set a file-creation mask umask(002);
in your local/config.php file. If you are extra-paranoid you can use "007" in place of "002" so files will not be world-readable either.
Other Options Besides Enabling safe_mode_gid
Another way around the server-can't-read problem is to run PHP via CGI instead of as a module. When you do that, files created by the script will have your UID and the server will read them.
You can also get things working by setting 777 (world writable) permissions and accepting the security risks that go along with that.