SafeModeGID


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

Quick Answer

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.

Detailed Explanation

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.

Background

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.

or

 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:

By default, Safe Mode does a UID compare check when opening files. If you want to relax this to a GID compare, then turn on safe_mode_gid.

How to Get Safe Mode Out Of The Way

Add

 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.


Et Cetera

Avoiding Writing Writables

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.

Comments

 0: 00.00 00.00 config start
 1: 00.01 00.01 config end
 2: 00.21 00.20 MarkupToHTML begin
 3: 00.22 00.21 ReadApprovedUrls SiteAdmin.ApprovedUrls begin
 4: 00.23 00.21 ReadApprovedUrls SiteAdmin.ApprovedUrls end
 5: 00.29 00.27 MarkupToHTML end
 6: 00.29 00.28 MarkupToHTML begin
 7: 00.31 00.29 MarkupToHTML end
 8: 00.31 00.29 MarkupToHTML begin
 9: 00.31 00.30 MarkupToHTML end
10: 00.31 00.30 now
Peak memory: 3,739,072 bytes