postfixadminでメールボックスを削除する(PostfixAdmin2.1.0)

PostfixAdminはWeb上でアカウントが管理できる点で非常に便利なのですが、PHPスクリプトで実行しているために多くの場合でメールボックスが削除できないという問題が生じます。
で、これを解決するための方法がこのサイトで公開されていてとても助かったと思っていたのですが、どうやら私の環境ではPostfixAdminを実行するサーバとメールを管理するサーバが異なる環境だとこの方法が使えないということに(涙
そこで、この作業をデータベースで行えるようにしてみました。
基本的な作業は全く同じで、削除するメールボックスのパスをファイルではなくデータベースに記録しているというだけです。

作成日:2008.03.26
更新日:2012.02.04
----------------------------------------------------------------------
2012.02.04 - ・文章を一部訂正。
----------------------------------------------------------------------

前提条件
これを行ったときの構成になります。
■環境
  ・PostfixAdmin2.1.0(PHPスクリプト)

今回は改変する部分がPostfixAdminだけしかありませんのでそれ以外は特に問題ないと思います。

ページのトップへ

データベースへテーブルの追加
まず、削除するメールボックスのパスを格納するためのテーブルを追加します。
追加するファイルを"DATABASE_MYSQL_EXTEND.TXT"として以下のよう内容で作成します。
"DATABASE_MYSQL_EXTEND.TXT"
(色分け:書換追記コメント)
#
# Postfix Admin用追加テーブル
#

#
# データベースの選択(PostfixAdmin用のデータベースを指定します。)
#
USE postfix;

#
# Table structure for table admin
#
CREATE TABLE delbox (
  path varchar(255) NOT NULL default ''
) TYPE=MyISAM COMMENT='Postfix Admin - Delete Mailbox';

このファイルをコマンドライン上でMySQLへ適用するのですが、phpMyAdminが導入していればコピー&ペーストでテーブル作成できるのでその方が楽かもしれません。
とりあえずここではコマンドライン上での適用を行います。
(色分け:入力値コマンドラインコメント)
# mysql -u root [-p] < DATABASE_MYSQL.TXT
ページのトップへ

該当ファイルの編集
まずはpostfixadminのシステム管理者にあたる"admin/delete.php"ファイルを書き換えます。
"admin/delete.php"
(色分け:書換追記コメント)
 89:         $url = "list-virtual.php?domain=$fDomain";
 90:         db_log ($CONF['admin_email'], $fDomain, "delete alias", $fDelete);
 91:      }
 92:   
 93:      $result = db_query ("SELECT * FROM mailbox WHERE username='$fDelete' AND domain='$fDomain'");
 94:      if ($result['rows'] == 1)
 95:      {
   : // delboxテーブルに登録するための削除予定のメールボックスのパスを取得 $row = db_array ($result['result']); $maildir = $row['maildir'];
   :
 96:         $result = db_query ("DELETE FROM mailbox WHERE username='$fDelete' AND domain='$fDomain'");
 97:         if ($result['rows'] != 1)
 98:         {
 99:            $error = 1;
100:            $tMessage = $PALANG['pDelete_delete_error'] . "$fDelete (mailbox)!";
101:         }
102:         else
103:         {
104:            $url = "list-virtual.php?domain=$fDomain";
105:            db_query ("DELETE FROM vacation WHERE email='$fDelete' AND domain='$fDomain'");
106:            db_log ($CONF['admin_email'], $fDomain, "delete mailbox", $fDelete);
   :
   : // 削除予定のメールボックスのパスをdelboxテーブルに登録 db_query("INSERT INTO delbox (path) VALUES ('$maildir')");
108:         }
109:      }
110:   }
次に、ドメイン管理者用のファイルも同様に書き換えておきます。
管理者だけしか使わない環境であればこの作業はしなくても特に動作上の問題は無いと思います。
"delete.php"
(色分け:書換追記コメント)
48:      {
49:         db_log ($SESSID_USERNAME, $fDomain, "delete alias", $fDelete);
50:      }
51:   
52:      $result = db_query ("SELECT * FROM mailbox WHERE username='$fDelete' AND domain='$fDomain'");
53:      if ($result['rows'] == 1)
54:      {
  : // delboxテーブルに登録するための削除予定のメールボックスのパスを取得 $row = db_array ($result['result']); $maildir = $row['maildir'];
  :
55:         $result = db_query ("DELETE FROM mailbox WHERE username='$fDelete' AND domain='$fDomain'");
56:         if ($result['rows'] != 1)
57:         {
58:            $error = 1;
59:            $tMessage = $PALANG['pDelete_delete_error'] . "$fDelete (mailbox)!";
60:         }
61:         else
62:         {
63:            db_query ("DELETE FROM vacation WHERE email='$fDelete' AND domain='$fDomain'");
64:            db_log ($SESSID_USERNAME, $fDomain, "delete mailbox", $fDelete);
  :
  : // 削除予定のメールボックスのパスをdelboxテーブルに登録 db_query("INSERT INTO delbox (path) VALUES ('$maildir')");
65:         }
66:      }
67:   }
ページのトップへ

削除するスクリプトの作成とcronの登録
テーブルに登録されたメールボックスを削除するために定期的にCronで実行させるためのスクリプトを作成します。
"/usr/local/etc/postfix/pa_db_delbox.sh"
#!/bin/sh
#---------------------------------------------------------------------
# PostfixAdmin用 メールボックス削除スクリプト(DB版)
#---------------------------------------------------------------------
# 【概要】
#   PostfixAdminを使ったメールシステムにおいて、メールアドレスの削除
#   したときにパーミッションの影響でメールボックスが削除できない問題
#   を解決するスクリプト。
#
# 【使用法】
#   pa_db_delbox.sh [-dh]
#
# 【戻り値】
#   0 --- 正常
#   1 --- 異常
#
# 【必要条件】
#   ・PostfixAdminデータベースにdelboxテーブルが作成されていること
#
# [更新履歴]
#  2007/8/19  ・初版
#
##------------------------------------------------------------------##
##【初期値設定】
##------------------------------------------------------------------##
## データベースユーザ
db_user="mailmanager"

## データベースユーザーのパスワード
db_password="mailmanager"

## データベース名
db_dbname="postfix"

## メールボックスのルートパス
mailbox_root="/usr/local/virtual"



db_query_deletet=""
db_query_select="SELECT * FROM delbox"
delete_column=0
mailbox_fullpath=""
tmp_listfile="/tmp/delbox.lst.$$$"

mysql_command="/usr/local/bin/mysql"
mysql_flags="--user=${db_user} --password=${db_password} --database=${db_dbname} --batch --silent"

##------------------------------------------------------------------##
##【プログラム処理】
##------------------------------------------------------------------##
cp /dev/null "${tmp_listfile}"


###  Mysqlが返すエラーコード  ###
# 0 : 正常
# 1 : 構文エラー
# 2 : コマンドライン上でのエラー

# 削除ディレクトリのパスデータの取得
${mysql_command} ${mysql_flags} --execute="${db_query_select}" > "${tmp_listfile}"

if [ $? -eq 0 -a -s "${tmp_listfile}" ]
then
    for path in `cat "${tmp_listfile}"`
    do
        delete_column=0
        mailbox_fullpath="${mailbox_root}/${path}"

        if [ -d "${mailbox_fullpath}" ]
        then
            rm -r "${mailbox_fullpath}"
            if [ $? -eq 0 -a ! -d "${mailbox_fullpath}" ]
            then
                delete_column=1
            fi
        else
            delete_column=1
        fi
        
        if [ ${delete_column} -eq 1 ]
        then
            db_query_deletet="DELETE FROM delbox WHERE CONVERT(path USING utf8) = '${path}' LIMIT 1"
            ${mysql_command} ${mysql_flags} --execute="${db_query_deletet}" > /dev/null
        fi
    done
fi
rm "${tmp_listfile}"
それが終わればCronに以下の文を追加します。 ちなみにこのスクリプトファイルには実行権限を付けるのを忘れないようにしてください。
"/etc/crontab"
(色分け:書換追記コメント)
0       *       *       *       *       root    /usr/local/etc/postfix/pa_db_delbox.sh
(この場合1時間おきに実行)
ページのトップへ

動作確認&起動方法
まず、メールボックスの新規作成を行いますが、このときWelcomeメールを送信するようにしておかないとディレクトリが作成されませんのでCronで実行したときに削除できたかどうかが分かりませんので必ず行います。
あとはメールボックスを削除してテーブルに登録されているかの確認と、Cronで指定した時間でメールボックスとテーブルの該当データが削除されるか確認して問題がなければ終わりです。
ページのトップへ

参考にしたサイト
PostfixAdminのイケてないところ
 (基本的な考え方を参考にさせていただきました)
ページのトップへ