Bug(バグ) #1331
PHPのsafe modeを使用している環境でmail_envelope_fromを設定するとメールが送信できない
100%
Description
Overview (現象)¶
PHP の safe mode が有効な環境で、config/OpenPNE.yml の設定で mail_smtp_host を指定せずに mail_envelope_from を指定している場合に、招待メール送信などのメールを送信するアクションを実行すると 500 Internal Server Error が発生する。
エラー内容は以下の通り。
500 | Internal Server Error | Zend_Mail_Transport_Exception Unable to send mail
mail_envelope_from の設定をしていない場合は正常にメールが送信される。
CORESERVER Bプラン、OpenPNE 3.6beta11で現象を確認。詳細は note-12 のコメント。
Causes (原因)¶
safe mode が有効な状態で PHP の mail() 関数に第5引数を指定して実行しているため。
Way to fix (修正内容)¶
safe mode が有効かつ外部のSMTPサーバを利用しない( mail_smtp_host を指定していない)状態では mail_envelope_from の設定が利用できないことを前提とし、その説明を設定ファイルに加え、ソースコード上で safe mode の設定値を取得して有効な場合には mail_envelope_from を利用しないようにした。
元のバグ報告内容¶
http://sns.openpne.jp/communityTopic/6047
OpenPNE 3.5.2を利用していますが、 「友人を招待する」から招待メールを送信しようとすると、 メールアドレスと本文を入力する画面までは出るのですが、 「送信」ボタンを押すと、「500 Internal Server Error」となってしまいました。 デバッグモードで試してみても、Internal Server Errorの画面が出るだけでした。 これはバグなのでしょうか? どうか調査お願い申し上げます。 (1)OpenPNEのバージョン : 3.5.2 (2)サーバー情報 : 「CORESERVER.jp Bプラン」を使用 PHPバージョン:5.2.5 MySQL : 5.1.22-rc (3)エラー概要 : 招待メールを送信するとき、フォーム入力画面は表示されるが、「送信」ボタンを押すとInternal Server Errorとなる。
Related issues
Associated revisions
fixed fatal error while sending e-mails on safe_mode environment (refs #1331)
History
#1
Updated by Rimpei Ogawa over 12 years ago
- 3.6 で発生するか set to Yes
#2
Updated by Kousuke Ebihara over 12 years ago
- Priority changed from Normal(通常) to High(高め)
safe mode による不具合の可能性などが考えられます
#3
Updated by Kousuke Ebihara over 12 years ago
- [QA]バグ通知済 set to No
#4
Updated by Kousuke Ebihara over 12 years ago
- [QA]バグ通知済 changed from No to Yes
#5
Updated by Kousuke Ebihara over 12 years ago
- Project changed from opAuthMailAddressPlugin to OpenPNE 3
#6
Updated by Kousuke Ebihara over 12 years ago
- Target version set to OpenPNE 3.7.0
#7
Updated by Shingo Yamada almost 12 years ago
- Assignee set to Masato Nagasawa
#8
Updated by Masato Nagasawa almost 12 years ago
- Assignee deleted (
Masato Nagasawa)
報告された情報からでは原因の特定が難しいため、保留とさせてください。
#9
Updated by Shingo Yamada almost 12 years ago
- Status changed from New(新規) to Accepted(着手)
- Assignee set to Shingo Yamada
調査します。
まず「CORESERVER.jp Bプラン」にて再現するかの確認を行います。
#10
Updated by Rimpei Ogawa over 11 years ago
- Assignee changed from Shingo Yamada to Rimpei Ogawa
再現調査引き継ぎます。
#11
Updated by Rimpei Ogawa over 11 years ago
CORESERVER Bプラン
b33.coreserver.jp
CGI版PHP
OpenPNE 3.6beta11
で検証してみましたが、報告されている現象は再現できず、招待メールは正常に送信できました。
Safe mode が原因だとにらんでいたため、CGI版ではなくApacheモジュール版PHPで動かすつもりでしたが、以下のようなエラーが出たため一旦あきらめてCGI版で検証を進めました。
Warning: realpath() [function.realpath]: SAFE MODE Restriction in effect. The script whose uid is 10144 is not allowed to access /usr/local/lib/php owned by uid 0 in /virtual/***/lib/vendor/symfony/lib/util/sfToolkit.class.php on line 592 Warning: realpath() [function.realpath]: SAFE MODE Restriction in effect. The script whose uid is 10144 is not allowed to access /usr/local/lib/php owned by uid 0 in /virtual/***/lib/vendor/symfony/lib/util/sfToolkit.class.php on line 592 Warning: realpath() [function.realpath]: SAFE MODE Restriction in effect. The script whose uid is 10144 is not allowed to access /usr/local/lib/php owned by uid 0 in /virtual/***/lib/vendor/symfony/lib/util/sfToolkit.class.php on line 592 Fatal error: Uncaught exception 'sfCacheException' with message 'Failed to write cache file.' in /virtual/***/lib/util/opToolkit.class.php:569
CGI版PHP で動作させるために .htaccess に以下の記述を追加して動作確認しています。
AddHandler application/x-httpd-phpcgi .php
もし、なんとかして safe mode のままで動かしているのであればそれが原因かもしれません。
safe mode の方で動かせるかどうかもう少しやってみる予定です。
参考:
PHPをCGIとして動かす方法について - CORESERVER.JP:コアサーバー
http://www.coreserver.jp/help/index.php/phpcgi/
#12
Updated by Rimpei Ogawa over 11 years ago
CORESERVER BプランのApacheモジュール版PHP(safe_mode=On)で検証した結果を報告します。
config/OpenPNE.yml で mail_smtp_host
を指定せず mail_envelope_from
を指定している場合のみ、メール送信時に以下のエラーが発生した。
500 | Internal Server Error | Zend_Mail_Transport_Exception Unable to send mail
mail_envelope_from
の設定をしていない場合は正常にメールが送信された。
エラーが発生した原因は、safe mode が有効な状態でPHP の mail() 関数に第5引数を指定して実行していることである。
これに関しては safe mode が有効かつ外部のSMTPサーバを利用しない( mail_smtp_host
を指定していない)状態では mail_envelope_from
の設定が利用できないことを前提とし、その説明を設定ファイルに加えるか、ソースコード上で safe mode の設定値を取得して mail_envelope_from
を利用しないようにするかのどちらかもしくは両方の対応をおこなうのが望ましい。
safe_mode による分岐条件を追加するための修正パッチ:
--- a/lib/util/opMailSend.class.php +++ b/lib/util/opMailSend.class.php @@ -32,7 +32,7 @@ class opMailSend $tr = new Zend_Mail_Transport_Smtp($host, sfConfig::get('op_mail_smtp_config', array())); Zend_Mail::setDefaultTransport($tr); } - elseif ($envelopeFrom = sfConfig::get('op_mail_envelope_from')) + elseif ($envelopeFrom = sfConfig::get('op_mail_envelope_from') && !ini_get('safe_mode')) { $tr = new Zend_Mail_Transport_Sendmail('-f'.$envelopeFrom); Zend_Mail::setDefaultTransport($tr);
ただ、safe mode が有効な環境での動作のためにはこのメール送信の問題以外にも、後述の「【補足2】CORESERVER の safe mode 下で OpenPNE を動作させるためにやったこと」の内容やその他にも対処が必要と思われるため、safe mode が有効な環境のみで発生する不具合をどこまで対応するかは検討が必要かもしれません。
CORESERVER においては、 note-11 に書いたように safe mode が無効な状態で動作させることも可能なため、このような環境では safe mode を利用しないことを推奨した方がよいと思います。
【補足1】CORESERVER の safe mode 関連の設定値
safe_mode | On |
safe_mode_gid | Off |
safe_mode_include_dir | /usr/local/lib/php |
safe_mode_exec_dir | /usr/local/php/bin |
safe_mode_allowed_env_vars | PHP_ |
safe_mode_protected_env_vars | LD_LIBRARY_PATH |
【補足2】CORESERVER の safe mode 下で OpenPNE を動作させるためにやったこと
- キャッシュディレクトリ下に作成されうるサブディレクトリをあらかじめ作成し、webディレクトリのPHPスクリプトファイルの所有者と一致させた
- safe_mode のファイルアクセスの制限を回避するため、キャッシュディレクトリ下に作成されうるすべてのサブディレクトリの所有者がwebディレクトリのPHPスクリプトファイルの所有者と一致している必要がある
- PHPスクリプトファイルの所有者がPHP実行ユーザーと異なる状態で動作させる場合、キャッシュディレクトリ下にあらかじめPHPスクリプトファイルの所有者がサブディレクトリを作成しておく必要がある
- 今回は招待メールの送信に必要なキャッシュディレクトリのみを事前に作成した状態で検証を行った
- ただし、この方法でOpenPNEの全機能を正常に動作させるためには、キャッシュディレクトリ下に作成されうるすべてのサブディレクトリを事前に推測する必要があり、非常に困難である
- PHPスクリプトファイルの所有者の方をPHPの実行ユーザーにする方法を取る場合
- CORESERVER においては Apache 経由でディレクトリ、ファイルの所有者を変更する必要がある(未検証)
- 初期状態の include_path が "." のみになるようにした
- CORESERVER 側の設定にあらかじめ含まれている
/usr/local/lib/php
への realpath() 関数の適用で Warning が発生したため - config/ProjectConfiguration.class.php の冒頭に以下の記述を追加した
set_include_path('.');
- CORESERVER 側の設定にあらかじめ含まれている
- セッションストレージの設定を DB に変更した(これはおそらく必須ではない)
# config/OpenPNE.yml session_storage: name: "database" options:
#13
Updated by Rimpei Ogawa over 11 years ago
- Subject changed from OpenPNE 3.5.2で招待メールが送信できません to PHPのsafe modeを使用している環境でmail_envelope_fromを設定するとメールが送信できない
Subject および Description を更新
#14
Updated by Shingo Yamada over 11 years ago
#15
Updated by Shingo Yamada over 11 years ago
@ogawa
#note-12 に添付のパッチの適用をお願いします。
パッチの適用とともに、 safe_mode が有効な環境では mail_envelope_from の設定が無効になる旨を OpenPNE.yml.sample に追記する必要があります。
#16
Updated by Rimpei Ogawa over 11 years ago
- Status changed from Accepted(着手) to Pending Review(レビュー待ち)
- % Done changed from 0 to 50
#17
Updated by Shingo Yamada over 11 years ago
- 360対象 set to beta13
#18
Updated by Kousuke Ebihara over 11 years ago
- Status changed from Pending Review(レビュー待ち) to Pending Testing(テスト待ち)
- % Done changed from 50 to 70
#19
Updated by Mutsumi Imamura over 11 years ago
- Status changed from Pending Testing(テスト待ち) to Fixed(完了)
- % Done changed from 70 to 100
#20
Updated by kaoru n over 7 years ago
- 3.8 で発生するか set to Unknown (未調査)