Support»PHP Safe Mode

Qdig And PHP Safe Mode

For security reasons, some commercial web hosting providers run their servers with PHP Safe Mode turned on. This causes difficulties for programs that

  1. write files and directories to disk and then read them, or
  2. execute external programs.

Qdig does #1 most of the time because it creates directories, converted images, and empty .txt caption files in the writable directory tree.

#2 occurs if you choose Image Magick for image conversion.

Safe Mode Warnings

A safe mode warning looks similar to 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

or this:

Warning: is_file() [function.is-file]: SAFE MODE Restriction in effect. The script whose uid is XXX is not allowed to access /usr/bin/convert owned by uid XXX in http://www.example.com/index.php on line XXXX

Quick Answers

Here are quick-and-easy steps to get things working with PHP Safe Mode enabled. To summarize:

  • Enable safe_mode_gid on the server.
  • Use temporary "2777" permissions during installation.
  • For image conversion, use GD.

The Server-Can't-Read Restriction

To avoid the server-can't-access-files-it-has-written error, the server administrator can enable PHP's safe_mode_gid by adding this line

  safe_mode_gid = On

to the the server's PHP configuration file (php.ini) and restarting the web server daemon.

Your web hosting provider should be willing to enable safe_mode_gid (manual page) for you because the security benefit probably exceeds the security risk. This is because

  • files written in ordinary (non-SetGID) directories still will be blocked, and
  • leaving it disabled encourages users to use world-writable directories and files.

Enabling safe_mod_gid, combined with using (temporarily) "2777" (versus "777") permissions for the qdig-files/ directory during setup, will cause your Qdig installation to Just Work as long PHP's GD extension is loaded and available for image conversion.

The External-Programs Restriction

The PHP exec() function's manual page contains the following warning:

With safe mode enabled, all words following the initial command string are treated as a single argument. Thus, echo y | echo x becomes echo "y | echo x".

While it appears the warning is not quite accurate, it's true that a command's arguments are mangled when PHP is running with Safe Mode enabled. For this reason, Image Magick cannot be combined with Safe Mode. GD must be used instead.

Full Explanation

You can run Qdig with PHP Safe Mode enabled. Of course Qdig doesn't need to write files for simple operation, but for automatically creating caption .txt files and writing (readable) resampled thumbnail and alternate-sized images Safe Mode can get in the way.

The Server-Can't-Read Restriction

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 read files that the server itself has written!

Here's why:

When you're running PHP as a module, files written by the script have the server daemon's ownership (UID) and group ownership (GID). If another user (such as "apache", "httpd", "www", or "nobody") writes files in your directories, then you cannot modify or delete the files.

To allow both the Qdig script and you to modify and delete files that are written by the script, the Qdig installation instructions direct you to temporarily set the permissions of the root directory of the writable tree (qdig-files/ by default) to "2777". This means "world-writable with the setGID bit enabled".

When you set "2777" permissions on the qdig-files/ directory and Qdig creates the the writable subdirectories (qdig-files/captions/ and qdig-files/converted-images/) the new directories 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 captions/
  drwxrwsr-x servers-uid your-gid converted-images/

Since these directories have the setGID bit turned on, any subsequent directories Qdig 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-r-- servers-uid your-gid some-file-Qdig-created

or

  -rw-rw---- servers-uid your-gid some-file-Qdig-created

depending on which umask setting you specify.

Here's where safe_mode comes in: With safe_mode enabled, by default the server does a "UID compare check". Files written by the server don't have your UID, 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.

In my testing, turning on safe_mode_gid works as advertised and solves the server-can't-read-files-it-created problem.

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.

Newer Qdig releases will detect that the system has Safe Mode enabled and prefer GD over Image Magick for image conversion if both are enabled and available. Older releases will need the following setting:

  $convert_magick = FALSE;

The External-Programs Restriction

For the reasons mentioned previously, PHP Safe Mode restricts the server so that even if you can execute Image Magick's `convert' command (see below), the parameters are mangled in a way that prohibits using Image Magick and Safe Mode together at this time.

Working With safe_mode_exec_dir

One Safe Mode trouble maker is safe_mode_exec_dir. By default safe_mode_exec_dir is empty, so external programs like `convert' cannot be started.

In my testing, on one (Debian) server I was able to use Image Magick's `convert' command (but not for converting gallery images) by using the following steps:

Create a link to `convert' in /usr/local/bin/ with

  ln -s /usr/bin/convert /usr/local/bin/

Enable starting programs in that directory with a line in php.ini

  safe_mode_exec_dir = "/usr/local/bin"

Restart the web server.
Make Qdig aware of the new location with

  $convert_cmd = '/usr/bin/convert';@@

This also works:

Enable starting /usr/bin programs in php.ini with

  safe_mode_exec_dir = "/usr/local/bin"

Restart the web server.

so does this:

Create a directory for PHP-safe binaries

  mkdir /usr/local/php_safe_bin

Create a link to `convert' in /usr/local/bin/ with

  ln -s /usr/bin/convert /usr/local/php_safe_bin/

Enable starting programs in that directory with a line in php.ini

  safe_mode_exec_dir = "/usr/local/php_safe_bin"

Restart the web server.
Make Qdig aware of the new location with

  $convert_cmd = '/usr/php_safe_bin/convert';@@

The reason for creating a link rather than copying the file is because otherwise system updates will not replace the copy you are using.

For review, the three pertinent settings in php.ini are

  safe_mode = On
  safe_mode_gid = On
  safe_mode_exec_dir = "/path/to/convert/executable"

where only the top two lines are necessary if you are using GD to convert images.

Request for Assistance

If you know how to work around the "escaped arguments" issue when PHP Safe Mode restrictions are in effect, please post an explanation.

When All Else Fails...

If your server administrator is uncooperative your best option is to create your galleries on another machine, perhaps even your desktop computer, and transfer the complete galleries over to the restricted server.