プロジェクト

全般

プロフィール

Bug(バグ) #1331

PHPのsafe modeを使用している環境でmail_envelope_fromを設定するとメールが送信できない

kei tomonaga13年以上前に追加. 8年以上前に更新.

ステータス:
Fixed(完了)
優先度:
High(高め)
担当者:
対象バージョン:
開始日:
2010-07-13
期日:
進捗率:

100%

3.6 で発生するか:
Yes
3.8 で発生するか:
Unknown (未調査)

説明

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となる。


関連するチケット

関連している OpenPNE 3 - Backport(バックポート) #2188: PHPのsafe modeを使用している環境でmail_envelope_fromを設定するとメールが送信できない Fixed(完了) 2011-06-10
関連している OpenPNE 3 - Bug(バグ) #2279: Apacheモジュール版PHP で safe mode を有効にしている環境では cache ディレクトリ以下に作成されたファイルの一部が読み込めない New(新規) 2011-07-19
関連している OpenPNE 3 - Backport(バックポート) #2522: PHPのsafe modeを使用している環境でmail_envelope_fromを設定するとメールが送信できない Fixed(完了) 2010-07-13
関連している OpenPNE 3 - Bug(バグ) #795: 3.2.2、3.4.1のインストールに問題発生 Won't fix(対応せず) 2010-03-04

関係しているリビジョン

リビジョン 44abf9ed (差分)
Rimpei Ogawa12年以上前に追加

fixed fatal error while sending e-mails on safe_mode environment (refs #1331)

履歴

#1 Rimpei Ogawa13年以上前に更新

  • 3.6 で発生するかYes にセット

#2 Kousuke Ebihara13年以上前に更新

  • 優先度Normal(通常) から High(高め) に変更

safe mode による不具合の可能性などが考えられます

#3 Kousuke Ebihara13年以上前に更新

  • [QA]バグ通知済いいえ にセット

#4 Kousuke Ebihara13年以上前に更新

  • [QA]バグ通知済いいえ から はい に変更

#5 Kousuke Ebihara13年以上前に更新

  • プロジェクトopAuthMailAddressPlugin から OpenPNE 3 に変更

#6 Kousuke Ebihara13年以上前に更新

  • 対象バージョンOpenPNE 3.7.0 にセット

#7 Shingo Yamadaほぼ13年前に更新

  • 担当者Masato Nagasawa にセット

#8 Masato Nagasawaほぼ13年前に更新

  • 担当者 を削除 (Masato Nagasawa)

報告された情報からでは原因の特定が難しいため、保留とさせてください。

#9 Shingo Yamadaほぼ13年前に更新

  • ステータスNew(新規) から Accepted(着手) に変更
  • 担当者Shingo Yamada にセット

調査します。
まず「CORESERVER.jp Bプラン」にて再現するかの確認を行います。

#10 Rimpei Ogawa12年以上前に更新

  • 担当者Shingo Yamada から Rimpei Ogawa に変更

再現調査引き継ぎます。

#11 Rimpei Ogawa12年以上前に更新

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 Rimpei Ogawa12年以上前に更新

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 を動作させるためにやったこと

  1. キャッシュディレクトリ下に作成されうるサブディレクトリをあらかじめ作成し、webディレクトリのPHPスクリプトファイルの所有者と一致させた
    • safe_mode のファイルアクセスの制限を回避するため、キャッシュディレクトリ下に作成されうるすべてのサブディレクトリの所有者がwebディレクトリのPHPスクリプトファイルの所有者と一致している必要がある
    • PHPスクリプトファイルの所有者がPHP実行ユーザーと異なる状態で動作させる場合、キャッシュディレクトリ下にあらかじめPHPスクリプトファイルの所有者がサブディレクトリを作成しておく必要がある
      • 今回は招待メールの送信に必要なキャッシュディレクトリのみを事前に作成した状態で検証を行った
      • ただし、この方法でOpenPNEの全機能を正常に動作させるためには、キャッシュディレクトリ下に作成されうるすべてのサブディレクトリを事前に推測する必要があり、非常に困難である
    • PHPスクリプトファイルの所有者の方をPHPの実行ユーザーにする方法を取る場合
      • CORESERVER においては Apache 経由でディレクトリ、ファイルの所有者を変更する必要がある(未検証)
  2. 初期状態の include_path が "." のみになるようにした
    • CORESERVER 側の設定にあらかじめ含まれている /usr/local/lib/php への realpath() 関数の適用で Warning が発生したため
    • config/ProjectConfiguration.class.php の冒頭に以下の記述を追加した
      set_include_path('.');
  3. セッションストレージの設定を DB に変更した(これはおそらく必須ではない)
    • # config/OpenPNE.yml
      session_storage:
        name: "database" 
        options:
      

#13 Rimpei Ogawa12年以上前に更新

  • 題名OpenPNE 3.5.2で招待メールが送信できません から PHPのsafe modeを使用している環境でmail_envelope_fromを設定するとメールが送信できない に変更

Subject および Description を更新

#14 Shingo Yamada12年以上前に更新

ただ、safe mode が有効な環境での動作のためにはこのメール送信の問題以外にも、後述の「【補足2】CORESERVER の safe mode 下で OpenPNE を動作させるためにやったこと」の内容やその他にも対処が必要と思われるため、safe mode が有効な環境のみで発生する不具合をどこまで対応するかは検討が必要かもしれません。

上記の #1331 の 「【補足2】」で指摘されている問題は、 #2279 で調査を進めます。

#15 Shingo Yamada12年以上前に更新

@ogawa
#note-12 に添付のパッチの適用をお願いします。

パッチの適用とともに、 safe_mode が有効な環境では mail_envelope_from の設定が無効になる旨を OpenPNE.yml.sample に追記する必要があります。

#16 Rimpei Ogawa12年以上前に更新

  • ステータスAccepted(着手) から Pending Review(レビュー待ち) に変更
  • 進捗率0 から 50 に変更

#17 Shingo Yamada12年以上前に更新

  • 360対象beta13 にセット

#18 Kousuke Ebihara12年以上前に更新

  • ステータスPending Review(レビュー待ち) から Pending Testing(テスト待ち) に変更
  • 進捗率50 から 70 に変更

#19 Mutsumi Imamura12年以上前に更新

  • ステータスPending Testing(テスト待ち) から Fixed(完了) に変更
  • 進捗率70 から 100 に変更

#20 kaoru n8年以上前に更新

  • 3.8 で発生するかUnknown (未調査) にセット

他の形式にエクスポート: Atom PDF