PostfixAdminはWeb上でアカウントが管理できる点で非常に便利なのですが、PHPスクリプトで実行しているために多くの場合でメールボックスが削除できないという問題が生じます。
で、これを解決するための方法がこのサイトで公開されています。
ただ、この方法ではPostfixAdminとメールサーバと違うサーバ上で実行することができないということになってしまいますのでここで行っていることをデータベースで行うようにしてみました。
基本的な流れは殆ど同じで削除するメールボックスのパスをファイルに記録するのではなく予め用意したテーブルに記録するのが違うだけであとは同様にcronを使って定期的に削除するという感になります。

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

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

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

#
# データベースの選択
#
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のイケてないところ
 (基本的に考え方を参考にさせていただきました)
ページのトップへ