OutlookとIMAPのフォルダ事情

OutlookでIMAPメールサーバを登録した時に表示されるフォルダがいまいちなことがある

その原因についていろんな調べてみた

まだアクセスしたことないけどメールが届いているユーザのメールボックス状態とそのときのディレクトリ

# doveadm mailbox list -u testuser3
INBOX
# ls -aF /var/vmail/testuser3/Maildir/
./    dovecot-uidlist               dovecot.index.log       tmp/
../   dovecot-uidvalidity           dovecot.list.index.log
cur/  dovecot-uidvalidity.68eef53b  new/
#

このときのINBOXフォルダの実態はどこかになるかを確認すると下記の様になっており、各ユーザのメールボックスのroot がINBOXとなっている、ということがわかる。

# doveadm mailbox path -u testuser3 INBOX
/var/vmail/testuser3/Maildir
#

次に、OutlookにIMAPサーバ設定を追加してログインしてみる

上記のようなメールボックスが表示される

doveadmコマンドで確認すると日本語名のメールボックスが確認できる

# doveadm mailbox list -u testuser3
迷惑メール
下書き
削除済みアイテム
送信済みアイテム
INBOX
#

実際に作られているディレクトリを確認すると、日本語文字列ではない修正UTF-7と呼ばれるものになっている。(UTF-8ベースではなくUTF-7ベースなのかは2000年以前のsendmailでは8bit目を取り扱えないシステムも存在していたため7bitで表現できる範囲に収める必要があった。これを引き継いで7bit範囲内に収まるUTF-7を採用したと思われる)

# ls -aF /var/vmail/testuser3/Maildir/
 ./                            dovecot-uidvalidity.68eef53f
'.&Tgtm+DBN-'/                 dovecot.index.cache
'.&UkqWZG4IMH8wojCkMMYw4A-'/   dovecot.index.log
'.&j,dg0TDhMPww6w-'/           dovecot.list.index.log
'.&kAFP4W4IMH8wojCkMMYw4A-'/   dovecot.mailbox.log
 ../                           new/
 cur/                          subscriptions
 dovecot-uidlist               tmp/
 dovecot-uidvalidity
#

この修正UTF-7が何を表しているかというのは、doveadmコマンドに-7,-8オプションを付与することで確認できる

# doveadm mailbox list -u testuser3 -7
&j,dg0TDhMPww6w-
&Tgtm+DBN-
&UkqWZG4IMH8wojCkMMYw4A-
&kAFP4W4IMH8wojCkMMYw4A-
INBOX
# doveadm mailbox list -u testuser3 -8
迷惑メール
下書き
削除済みアイテム
送信済みアイテム
INBOX
#

それぞれのメールボックスがどう変換されるのかを具体的に確認するのであれば、下記の様に「doveadm mailbox mutf7 -7 “文字列”」「doveadm mailbox mutf7 -8 “文字列”」と実行する

# doveadm mailbox mutf7 -7 "&j,dg0TDhMPww6w-"
迷惑メール
# doveadm mailbox mutf7 -8 "迷惑メール"
&j,dg0TDhMPww6w-
#

というわけで、Outlookで最初にIMAPメールを取りに行くと日本語でメールフォルダを作成する、ということがわかった。

Outlook形式メールボックスをThunderbirdメールで使う方法

同じユーザアカウントをThunderbirdメールで取得してみると、下記の様に表示される

じゃあ、下書き/削除済みアイテム/送信済みアイテムがOutlookと相互同期がとれているのかというと、そうはなっていなかった。

Thunderbirdの[アカウント設定]-[送信控えと特別なフォルダー]を見てみると、下記に様に、送信済みは「ローカルフォルダー」、下書きも「ローカルフォルダー」となっている。

これをどちらも各ユーザを指定する

かと思ったのですが、上記を設定しても、実際にメール送信や下書き保存してから設定を確認すると「ローカルフォルダー」に戻ります。

ただしい設定は「その他のフォルダーを指定する」を選んで、手動でフォルダを指定することでした

これで解決かと思ったのですが、「ゴミ箱」と「迷惑メール」についての設定がありません。

ゴミ箱は[サーバー設定]-[サーバー設定]にある「メッセージを削除する時」でゴミ箱を指定

迷惑メールは[迷惑メール]-[移動先と保存期間]で設定します。

で・・・ここまでの設定を行った段階でdoveadmコマンドでメールボックスを確認してみたところ、設定中にThunderbirdが「Junk」と「Trash」を別に作ってしまったようです。

# doveadm mailbox list -u testuser3
Junk
Trash
迷惑メール
下書き
削除済みアイテム
送信済みアイテム
INBOX
#

Thunderbirdメール上のメールボックス表示も「迷惑メール」が2種類、「ゴミ箱」と「削除済みアイテム」が両方ある、という状態に

Outlook側も「ゴミ箱」と「削除済みアイテム」が両方ある、という状態

これの解消についてはThunderbirdであればアカウント名の右クリックメニューから「購読」

表示される一覧の「Junk」と「Trash」のチェックを外します

下記の様に表示されます。

IMAPの購読設定はOutlook側で行うこともできます。受信トレイの右クリックメニューから「IMAPフォルダ」を選び、[クエリ]をクリックすると、下記の様にフォルダが表示されます。

「Junk」と「Trash」をそれぞれ「購読取り消し」を選んで適用します

Outlook側の表示も下記の様になります。(フォルダが残ったままの場合は一度Outlookを起動し直す)

日本語版Outlookと英語版Outlookは共存できるのか?

Outlookで自動的に作成されるのは日本語名のフォルダになっている。

じゃあ、英語環境ではどうなのか?と英語版Outlook環境を作成して、日本語版Outlook/Thunderbirdでアクセス済みのアカウントを設定してみた。

英語名のフォルダが別に作成されてしまうという事態に

# doveadm mailbox list -u testuser3
Drafts
Sent Items
Junk
Trash
迷惑メール
下書き
削除済みアイテム
送信済みアイテム
INBOX
#

英語Outlookでメール送信/下書きをすると、英語名フォルダに保存され、日本語環境のモノと同期がとれず、それぞれ別に保存されていることを確認

日本語Outlookでフォルダを確認すると下記の状態

OutlookのIMAPフォルダーでの購読状況は下記の様にどちらも共通(INBOX/受信ボックスはどちらも共通)

で・・・Thunderbirdメールの場合、とてもややこしい状態になっています

じゃあ、日本語Outlookと英語Outlookでメールボックス名を共通化することができるのか?

下書きの保存については「Change where sent email messages are saved」に記載があった

[ファイル]-[オプション]の「メール」にある「メッセージの保存」で下書きの保存場所を設定できる・・・のかと思ったら

選択できるものが、それぞれ英語/日本語でOutlookが作成したものだけとなっており、それ以外の場所が設定できないようだ。

Thunderbirdログイン後に日本語Outlookからアクセス

初回ログインはThunderbirdから行って、次に日本語Outlookからアクセスした場合の状態について確認

まずはサーバ上の初期状態を確認

# doveadm mailbox list -u testuser2
INBOX
# ls -aF testuser2/Maildir/
./  ../  cur/  dovecot.list.index.log  new/  tmp/
#

Thunderbirdに設定を入れた直後は「受信トレイ」と「ゴミ箱」のみ

# doveadm mailbox list -u testuser2
Trash
INBOX
# ls -aF testuser2/Maildir/
./       dovecot-keywords              dovecot.index.cache     new/
../      dovecot-uidlist               dovecot.index.log       subscriptions
.Trash/  dovecot-uidvalidity           dovecot.list.index.log  tmp/
cur/     dovecot-uidvalidity.68ef30a8  dovecot.mailbox.log
#

このときのThunderbird設定を確認すると[サーバー設定]-[サーバ設定]の「メッセージを削除する時」はIMAPのフォルダーになっている

それに対して[送信控えと特別なフォルダー]は、ローカルフォルダーになっている。

これを下記の設定にしても、しばらくするとローカルフォルダ設定に戻る。

動作を確認すると、ゴミ箱については、確かにTrashフォルダにメールが移動されていることを確認できた。

この状態で、OutlookでIMAP設定を行うと下記の様になった。

# doveadm mailbox list -u testuser2
迷惑メール
下書き
送信済みアイテム
Trash
INBOX
# ls -aF testuser2/Maildir/
 ./                            dovecot-uidvalidity
'.&Tgtm+DBN-'/                 dovecot-uidvalidity.68ef30ab
'.&j,dg0TDhMPww6w-'/           dovecot.index.cache
'.&kAFP4W4IMH8wojCkMMYw4A-'/   dovecot.index.log
 ../                           dovecot.list.index.log
 .Trash/                       dovecot.mailbox.log
 cur/                          new/
 dovecot-keywords              subscriptions
 dovecot-uidlist               tmp/
#

Thunderbirdで作成されたUI上は「ごみ箱」となっていた「Trash」フォルダは、Outlook側では「Trash」と表示され、Outlook側でメールを削除すると「Trash」フォルダにメールが移動する、ということが確認できた。

つまり、「受信トレイ」と「ゴミ箱」については、ThunderbirdとOutlookとで共通利用が可能なようだ

Outlook側で作成したフォルダが追加されたあとのThunderbird側は下記の表示となった。

このときに、Outlook側と動作を揃えるためにアカウント設定では以下の様に「その他のフォルダーを指定する」の方を選んで設定する。

下記の様にフォルダーに色がついたりする

英語版Outlookで初回ログインした場合

英語版Outlookで初回ログインした場合

# doveadm mailbox list -u testuser4
Junk Email
Drafts
Deleted Items
Sent Items
INBOX
# ls -aF testuser4/Maildir/
 ./                 cur/                           dovecot.list.index.log
 ../                dovecot-uidlist                dovecot.mailbox.log
'.Deleted Items'/   dovecot-uidvalidity            new/
 .Drafts/           dovecot-uidvalidity.68ef371e   subscriptions
'.Junk Email'/      dovecot.index.cache            tmp/
'.Sent Items'/      dovecot.index.log
#

この状態ではThunderbirdメールから見ると以下の状態となっていた

# doveadm mailbox list -u testuser4
Trash
Junk Email
Drafts
Deleted Items
Sent Items
INBOX
#

このとき、thunderbirdの設定は下記となっており、下書きについては、自動的に「その他のフォルダー」の方で設定されている。

しかし、Thunderbirdでメールの送信と下書き保存を行ってみると送信済みは

この状態では、英語outlookとThunderbirdではゴミ箱と送信済みの同期がとれていない状態となっていた。

英語版Outlook「Deleted Items」とThunderbird「Trash」がIMAP上の別フォルダ。
英語版Outlook「Sent Items」はIMAP上だが、Thunderbirdの「送信済みトレイ/送信済みアイテム」はローカル

続いて日本語Outlookで設定をすると下記となり、この場合はフォルダ名が英語表示ではあるものの内容は英語版Outlookと同期がとれている。

dovecotの設定調整で共有化できるのか?

ここまでのところで判明した問題点

・OutlookはIMAPアクセスした時に規定のフォルダがないと新規作成する
・英語版Outlookで作ったフォルダは日本語版Outlookでも共通で使えるが、逆は別物となる
・ThunderbirdでIMAPアクセスした時は、ゴミ箱(Trash)しか作成しない

dovecotの設定で /etc/dovecot/conf.d/15-mailboxes.conf内で下記ような設定がある

namespace inbox {
  # These mailboxes are widely used and could perhaps be created automatically:
  mailbox Drafts {
    special_use = \Drafts
  }
  mailbox Junk {
    special_use = \Junk
  }
  mailbox Trash {
    special_use = \Trash
  }

  # For \Sent mailboxes there are two widely used names. We'll mark both of
  # them as \Sent. User typically deletes one of them if duplicates are created.
  mailbox Sent {
    special_use = \Sent
  }
  mailbox "Sent Messages" {
    special_use = \Sent
  }

special_use というのは RFC6154「IMAP LIST Extension for Special-Use Mailboxes」で定義されている特殊な役割をもつものとなっていて「\Drafts(下書き)」「\Junk(迷惑メール)」「\Trash(ゴミ箱)」「\Sent(送信済みアイテム)」の設定となっている。

すでに行われている設定をみると、「Sent」と「Sent Messages」は同じ「\Sent」を指す、という設定になっているように見える

この設定をこれまでに出てきたものに対して適用することで解決できるのでは?ということで並べると・・・

\Drafts 候補
下書き
Drafts

\Junk 候補
迷惑メール
Junk
Junk Email

\Trash 候補
削除済みアイテム
Trash
Deleted Items

\Sent 候補
送信済みアイテム
Sent Items

これを /etc/dovecot/conf.d/15-mailboxes.conf に設定してdovecot再起動

##
## Mailbox definitions
##

# Each mailbox is specified in a separate mailbox section. The section name
# specifies the mailbox name. If it has spaces, you can put the name
# "in quotes". These sections can contain the following mailbox settings:
#
# auto:
#   Indicates whether the mailbox with this name is automatically created
#   implicitly when it is first accessed. The user can also be automatically
#   subscribed to the mailbox after creation. The following values are
#   defined for this setting:
#
#     no        - Never created automatically.
#     create    - Automatically created, but no automatic subscription.
#     subscribe - Automatically created and subscribed.
#
# special_use:
#   A space-separated list of SPECIAL-USE flags (RFC 6154) to use for the
#   mailbox. There are no validity checks, so you could specify anything
#   you want in here, but it's not a good idea to use flags other than the
#   standard ones specified in the RFC:
#
#     \All       - This (virtual) mailbox presents all messages in the
#                  user's message store.
#     \Archive   - This mailbox is used to archive messages.
#     \Drafts    - This mailbox is used to hold draft messages.
#     \Flagged   - This (virtual) mailbox presents all messages in the
#                  user's message store marked with the IMAP \Flagged flag.
#     \Important - This (virtual) mailbox presents all messages in the
#                  user's message store deemed important to user.
#     \Junk      - This mailbox is where messages deemed to be junk mail
#                  are held.
#     \Sent      - This mailbox is used to hold copies of messages that
#                  have been sent.
#     \Trash     - This mailbox is used to hold messages that have been
#                  deleted.
#
# comment:
#   Defines a default comment or note associated with the mailbox. This
#   value is accessible through the IMAP METADATA mailbox entries
#   "/shared/comment" and "/private/comment". Users with sufficient
#   privileges can override the default value for entries with a custom
#   value.

# NOTE: Assumes "namespace inbox" has been defined in 10-mail.conf.
namespace inbox {
  # These mailboxes are widely used and could perhaps be created automatically:
  mailbox Drafts {
    special_use = \Drafts
  }
  mailbox "下書き" {
    special_use = \Drafts
  }
  mailbox Junk {
    special_use = \Junk
  }
  mailbox "迷惑メール" {
    special_use = \Junk
  }
  mailbox "Junk Email" {
    special_use = \Junk
  }
  mailbox Trash {
    special_use = \Trash
  }
  mailbox "削除済みアイテム" {
    special_use = \Trash
  }
  mailbox "Deleted Items" {
    special_use = \Trash
  }

  # For \Sent mailboxes there are two widely used names. We'll mark both of
  # them as \Sent. User typically deletes one of them if duplicates are created.
  mailbox Sent {
    special_use = \Sent
  }
  mailbox "Sent Messages" {
    special_use = \Sent
  }
  mailbox "送信済みアイテム" {
    special_use = \Sent
  }
  mailbox "Sent Items" {
    special_use = \Sent
  }

  # If you have a virtual "All messages" mailbox:
  #mailbox virtual/All {
  #  special_use = \All
  #  comment = All my messages
  #}

  # If you have a virtual "Flagged" mailbox:
  #mailbox virtual/Flagged {
  #  special_use = \Flagged
  #  comment = All my flagged messages
  #}

  # If you have a virtual "Important" mailbox:
  #mailbox virtual/Important {
  #  special_use = \Important
  #  comment = All my important messages
  #}
}

初期状態

# doveadm mailbox list -u testuser5
INBOX
# ls -aF testuser5/Maildir/
./  ../  cur/  new/  tmp/
#

日本語Outlookで最初に作成した場合

日本語Outlookでログイン

# doveadm mailbox list -u testuser5
迷惑メール
下書き
削除済みアイテム
送信済みアイテム
INBOX
# ls -aF testuser5/Maildir/
 ./                            dovecot-uidvalidity.68ef4b2b
'.&Tgtm+DBN-'/                 dovecot.index.cache
'.&UkqWZG4IMH8wojCkMMYw4A-'/   dovecot.index.log
'.&j,dg0TDhMPww6w-'/           dovecot.list.index.log
'.&kAFP4W4IMH8wojCkMMYw4A-'/   dovecot.mailbox.log
 ../                           new/
 cur/                          subscriptions
 dovecot-uidlist               tmp/
 dovecot-uidvalidity
#

続いて英語Outlookでログインした場合

# doveadm mailbox list -u testuser5
迷惑メール
下書き
削除済みアイテム
送信済みアイテム
INBOX
# ls -aF testuser5/Maildir/
 ./                            dovecot-uidvalidity.68ef4b2b
'.&Tgtm+DBN-'/                 dovecot.index.cache
'.&UkqWZG4IMH8wojCkMMYw4A-'/   dovecot.index.log
'.&j,dg0TDhMPww6w-'/           dovecot.list.index.log
'.&kAFP4W4IMH8wojCkMMYw4A-'/   dovecot.mailbox.log
 ../                           new/
 cur/                          subscriptions
 dovecot-uidlist               tmp/
 dovecot-uidvalidity
#

英語版Outlookであっても、日本語文字列でのフォルダが見えており、ゴミ箱/下書き/送信済みアイテムの内容が日本語版Outlookと同期がとれていることを確認できた。

Thunderbirdで設定すると以下の状態で見れる

Thunderbirdの[サーバー設定]の「メールを削除するとき」の初期値は下記となっていて、ちゃんと選択されてるのか?という感じでしたが、メールを削除すると、IMAP上のTrashに移動してることを確認しました

[送信控えと特別なフォルダー]は下記

日本語版Outlook、英語版Outlook、Thunderbirdメールのそれぞれで同期がとれたように見える。

英語Outlookで最初に作成した場合

英語Outlookで最初にアクセスした場合に作成されるもの

# doveadm mailbox list -u testuser5
Junk Email
Drafts
Deleted Items
Sent Items
INBOX
# ls -aF testuser5/Maildir/
 ./                 cur/                           dovecot.list.index.log
 ../                dovecot-uidlist                dovecot.mailbox.log
'.Deleted Items'/   dovecot-uidvalidity            new/
 .Drafts/           dovecot-uidvalidity.68ef4f73   subscriptions
'.Junk Email'/      dovecot.index.cache            tmp/
'.Sent Items'/      dovecot.index.log
#

続いて日本語Outlookでログイン

実際に作成されているメールボックスは英語のまま

# doveadm mailbox list -u testuser5
Junk Email
Drafts
Deleted Items
Sent Items
INBOX
# ls -aF testuser5/Maildir/
 ./                 cur/                           dovecot.list.index.log
 ../                dovecot-uidlist                dovecot.mailbox.log
'.Deleted Items'/   dovecot-uidvalidity            new/
 .Drafts/           dovecot-uidvalidity.68ef4f73   subscriptions
'.Junk Email'/      dovecot.index.cache            tmp/
'.Sent Items'/      dovecot.index.log
#

最後にThunderbirdは下記状態で、特に問題は無い状態となっていた。

日本語Outlookで作成された「削除済みアイテム」の選択表示がおかしかったが、英語文字列の場合は特に問題ないようだ。

Thunderbirdで最初にアクセスした場合

Thuderbirdで最初にアクセスした場合は下記の様になった

# doveadm mailbox list -u testuser5
Trash
INBOX
# ls -aF testuser5/Maildir/
./       dovecot-keywords              dovecot.index.cache     new/
../      dovecot-uidlist               dovecot.index.log       subscriptions
.Trash/  dovecot-uidvalidity           dovecot.list.index.log  tmp/
cur/     dovecot-uidvalidity.68ef52a1  dovecot.mailbox.log
#

このとき、設定は、ゴミ箱はIMAP上を使用するが、「送信済みアイテム」と「下書き」についてはローカルに保存する設定になっていた。

この状態で、日本語Outlookからアクセスすると、日本語名で作成される

# doveadm mailbox list -u testuser5
迷惑メール
下書き
送信済みアイテム
Trash
# ls -aF testuser5/Maildir/
 ./                            dovecot-uidvalidity
'.&Tgtm+DBN-'/                 dovecot-uidvalidity.68ef52a4
'.&j,dg0TDhMPww6w-'/           dovecot.index.cache
'.&kAFP4W4IMH8wojCkMMYw4A-'/   dovecot.index.log
 ../                           dovecot.list.index.log
 .Trash/                       dovecot.mailbox.log
 cur/                          new/
 dovecot-keywords              subscriptions
 dovecot-uidlist               tmp/
#

改めてthunderbird側で確認すると、下記の状態に変更されているが下書きと送信済みアイテムの同期が出来ていない

設定を確認すると、アイコンの絵がそれっぽく表示されているだけで、設定自体は手動で変更する必要があった。

これを下記に変更したところ同期が行われるようになった

設定追加

RFC6154を読むと、special useとして定義さえている文字列には「\Archive」「\Flagged」とゴミ箱/迷惑メールを含めて全メールを表示する「\All」がある模様

「\Archive」は、Outlookの各メールの右クリックメニューにある「Archive/アーカイブ」で保存される先として使用される。

# doveadm mailbox list -u testuser4
Archive
Junk
Trash
Junk Email
Drafts
Deleted Items
Sent Items
INBOX
# ls -aF testuser4/Maildir/
 ./                 .Trash/                        dovecot.list.index
 ../                cur/                           dovecot.list.index.log
 .Archive/          dovecot-keywords               dovecot.list.index.log.2
'.Deleted Items'/   dovecot-uidlist                dovecot.mailbox.log
 .Drafts/           dovecot-uidvalidity            new/
 .Junk/             dovecot-uidvalidity.68ef3721   subscriptions
'.Junk Email'/      dovecot.index.cache            tmp/
'.Sent Items'/      dovecot.index.log
#

上記のように「Archive」フォルダが作成される。このフォルダについては日本語Outlook環境でも英語表記Archiveでアーカイブ動作をした。

次に、最初に日本語Outlook環境で「アーカイブ」した場合は、日本語で作成される

# doveadm mailbox list -u testuser5
アーカイブ
迷惑メール
下書き
送信済みアイテム
Trash
INBOX
#

英語Outlookでアーカイブを行おうとすると、日本語アーカイブフォルダは認めてくれていない

/etc/dovecot/conf.d/15-mailboxes.confに下記設定を追加してdovecot再起動

  mailbox Archive {
    special_use = \Archive
  }
  mailbox "アーカイブ" {
    special_use = \Archive
  }

これで問題無くなるかと思ったのですが、引き続き”Archive”を新規作成するダイアログが表示される状態に・・・

アーカイブの動作が謎だ・・・

パソコン変更時のThunderbirdの移行手法メモ

Thuderbirdでメールを受信している環境で、パソコンを新しくした。

その際に、メールアカウントが複数あるのでパスワードの再入力したくないなぁ、と思ってたのですが、ThunderbirdのGUI操作でやるとパスワード入力が発生したのでメモとして残しておく

移行元パソコンでの操作として、Thuderbirdの[ツール]-[設定とデータのエクスポート]を開く

そうすると下記のような画面が開く

「プロファイルフォルダーを開く」を選択するとエクスプローラーで Thuderbirdのメールデータが入っている場所が開く

上記では C:\Users\ユーザ名\AppData\Roaming\Thunderbird\Profiles\s0k7246v.default というフォルダになっているが、最後の部分は環境によって異なる。(なお、どのユーザでも共通して使えるやりかたとしては、エクスプローラのアドレスのところに「%AppData%\Thunderbird\Profiles」と入力するというのがある。)

で、この表示されたプロファイルフォルダーのところだけを新しいパソコンにもっていって、[ツール]-[設定とデータのインポート]から読み込ませたところ、パスワードを聞いてきました。

で・・・エクスプローラで開いたパスを C:\Users\ユーザ名\AppData\Roaming\Thunderbird (一般名「%AppData%\Thunderbird」)に変更すると、下記のようにいろいろ設定ファイルがあることがわかる。

profiles.ini とinstalls.ini の中身を確認するとどちらも相対的なパス指定となっているので、新旧パソコンでユーザ名が異なっていても問題なさそう。

[Install8216C80C92C4E828]
Default=Profiles/s0k7246v.default

[InstallD78BF5DD33499EC2]
Default=Profiles/s0k7246v.default

[Profile0]
Name=default
IsRelative=1
Path=Profiles/s0k7246v.default
Default=1

[General]
StartWithLastProfile=1
Version=2

ということで、「%AppData%\Thunderbird」を丸ごとコピーすれば、メールデータ、メールサーバ設定情報+パスワードもそのまま移行できることを確認しました。

dovecot / postfix と Active Directory連携時の動作調査手法

dovecot / postfix と Active Directoryを連携させようと設定してみたところ、最初はうまく動かなかった。

この動かない原因をどうやって調べていくか、というのを解説してるものがなく、非常に難儀したのでメモ書きとして残す

dovecot, postfixの現在の設定を確認

RHEL9の場合、 /etc/dovecot および /etc/postfix に設定ファイル群があるが、コメントやサブディレクトリにあるファイルとの結合により、最終的な設定が何になっているのかわかりにくい

「doveconf」および「postconf」を実行することで最終的な設定を確認することができる

また、デフォルト値と異なる部分は何かを「doveconf -n」「postconf -n」を実行することで確認できる。

なお、doveconfの場合、ssh_keyなど一部のパラメータについては「doveconf -P」と-Pオプションをつけないと実際の値が表示されない

dovecotのログ出力を増やす

ログ出力を増やすための設定がいろいろあった(Dovecot Logging)ため、 /etc/dovecot/conf.d/99-debug.conf と1つのファイルにまとめて必要ない場合は /etc/dovecot/conf.d/99-debug._conf と.conf という名前じゃなくすることで無効化できるようにした

[root@mail dovecot]# cat /etc/dovecot/conf.d/99-debug.conf
auth_debug=yes
auth_debug_passwords=yes
auth_verbose=yes
auth_verbose_passwords=yes
verbose_proctitle=yes
verbose_ssl=yes

[root@mail dovecot]#

設定後は「systemctl restart dovecot」で設定を有効にする

なお「doveadm log find」を実行するとdovecotのログがどのファイルに出力されているかを確認することができる

[root@mail dovecot]# doveadm log find
Looking for log files from /var/log
Debug: /var/log/maillog
Info: /var/log/maillog
Warning: /var/log/maillog
Error: /var/log/maillog
Fatal: /var/log/maillog
[root@mail dovecot]#

LDAP検索のログを増やす

dovecotの場合は dovecot本体への auth_verbose=yes 設定だけでLDAPでどういったqueryを投げているかも確認できる

ただ、もっと詳細を確認したい、という場合 /etc/dovecot/dovecot-ldap.conf.ext などのLDAP接続情報を書いたファイルに「debug_level」を追加することでログを増やすこともできる。

dovecot Common LDAP Settings for both auth and sieve
iredmail Turn on debug mode in Dovecot

dovecot標準値は「debug_level=0」。ログを増やす場合は「debug_level=1」、最大量に増やす場合は「debug_level=-1」とする

postfixの場合も同様に LDAP接続情報を書いたファイル /etc/postfix/ldap-mailbox.cf などに「debuglevel」を追加することでログを増やすことができる。

postfix ldap_table – Postfix LDAP client configuration

postfix標準値は「debuglevel=0」。増やす場合は「debuglevel=1」から最大量は「debuglevel=10」とする

postfixのログ出力を増やす

Postfix Debugging Howto に記載があるが正直めんどい

/etc/postfix/master.cf の smtpd起動に関して「-v」オプションか「-D」オプションをつける、という形となる。

とはいえ、postfix/dovecotを組み合わせた場合、ActiveDirectory/LDAP側の処理をdovecot側で行うということもあるので、まずはdovecot側の動作がちゃんとするのを先に確認したほうがよい。

dovecotでの認証確認

dovecotで認証動作を確認する場合、まずは「doveadm auth login ユーザ名」を実行する

[root@mail ~]# doveadm auth login testuser1@adsample.local
Password: <パスワード入力>
passdb: testuser1@adsample.local auth succeeded
extra fields:
  user=testuser1@adsample.local
  uid=1000
  gid=1000
userdb extra fields:
  testuser1@adsample.local
  uid=1000
  gid=1000
  auth_mech=PLAIN
[root@mail ~]#

なお、「doveadm auth login testuser1@adsample.local パスワード」とパスワードをつけて実行すると入力しないで済むので検証時は便利(ログに残るので一時なパスワードにすること)

ただし、このdoveadm auth loginコマンドは模擬的に確認しているだけで、実際にログイン処理は行っていないようで、テストしたユーザのディレクトリがない場合でもディレクトリが作成されない。(ちゃんとログインした場合は自動的に作成される)

ldapsearchコマンドを使った検証

doveadm auth loginコマンドでうまく認証が実行できない場合、 ldapsearchコマンドを使って原因を調査していったりする。

その場合、 /etc/dovecot/conf.d/99-debug.conf の設定を有効にしてから行う。

期待通りに動作していない場合、ログにある下記のような「ldap」「base=~」「filter=~」という記述に注目する

May  2 11:18:59 mail dovecot[959]: auth-worker(1542): Debug: conn unix:auth-worker (pid=1541,uid=97): Server accepted connection (fd=14)
May  2 11:18:59 mail dovecot[959]: auth-worker(1542): Debug: conn unix:auth-worker (pid=1541,uid=97): Sending version handshake
May  2 11:18:59 mail dovecot[959]: auth-worker(1542): Debug: conn unix:auth-worker (pid=1541,uid=97): auth-worker<1>: Handling LIST request
May  2 11:18:59 mail dovecot[959]: auth-worker(1542): Debug: conn unix:auth-worker (pid=1541,uid=97): auth-worker<1>: ldap(): Performing userdb lookup
May  2 11:18:59 mail dovecot[959]: auth-worker(1542): Debug: conn unix:auth-worker (pid=1541,uid=97): auth-worker<1>: ldap: iterate: base=cn=Users,dc=adsample,dc=local scope=subtree filter=(objectClass=posixAccount) fields=uid
May  2 11:18:59 mail dovecot[959]: auth-worker(1542): Debug: conn unix:auth-worker (pid=1541,uid=97): auth-worker<1>: ldap(): Finished userdb lookup
May  2 11:18:59 mail dovecot[959]: auth-worker(1542): Debug: conn unix:auth-worker (pid=1541,uid=97): auth-worker<1>: Finished

上記の場合注目するのは以下の部分

base=cn=Users,dc=adsample,dc=local scope=subtree filter=(objectClass=posixAccount) fields=uid

これをldapsearchコマンドに与える

-bオプションの後ろにbase=の後ろにある「cn=Users,dc=adsample,dc=local」
-sオプションの後ろにscope=の「subtree」
そしてfilterの「objectClass=posixAccount」

ldapsearch -x -H ldaps://192.168.122.10 -D "cn=vmail,cn=Users,dc=adsample,dc=local" -w "パスワード" -b "dc=adsample,dc=local" -s subtree objectClass=posixAccount

この出力結果を確認し、fields=で指定した「uid」という項目があるかを確認します

なければfilterで指定した条件が不適切、ということとなる

fieldsで適切かなぁ、というものが出るまでfilterの条件式の調整と、fieldsで選ぶ項目の調整を行う

各ユーザで取得できるLDAPの情報が何かを調べる場合は下記のようにuserPrincipalName、もしくはsAMAccountName で検索して確認する

ldapsearch -x -H ldaps://192.168.122.10 -D "cn=vmail,cn=Users,dc=adsample,dc=local" -w "パスワード" -b "dc=adsample,dc=local" -s subtree userPrincipalName=testuser2@adsample.local

ldapsearchが1000件表示ぐらいで止まってしまう

openldapでの仕様で1000件で出力を止めるため。

「-E pr=1000/noprompt」オプションを付けると無視できる

ldapsearch -x -H ldaps://192.168.122.10 -D "cn=vmail,cn=Users,dc=adsample,dc=local" -w "パスワード" -b "dc=adsample,dc=local" -s subtree sAMAccountName -E pr=1000/noprompt

なお-Eオプションの意味は下記

   -E [!]ext[=extparam]

          Specify general extensions with -e and search extensions with -E.  ´!´ indicates
          criticality.

          General extensions:
            [!]assert=<filter>    (an RFC 4515 Filter)
            !authzid=<authzid>    ("dn:<dn>" or "u:<user>")
            [!]bauthzid           (RFC 3829 authzid control)
            [!]chaining[=<resolve>[/<cont>]]
            [!]manageDSAit
            [!]noop
            ppolicy
            [!]postread[=<attrs>] (a comma-separated attribute list)
            [!]preread[=<attrs>]  (a comma-separated attribute list)
            [!]relax
            sessiontracking[=<username>]
            abandon,cancel,ignore (SIGINT sends abandon/cancel,
            or ignores response; if critical, doesn't wait for SIGINT.
            not really controls)

          Search extensions:
            !dontUseCopy
            [!]domainScope                       (domain scope)
            [!]mv=<filter>                       (matched values filter)
            [!]pr=<size>[/prompt|noprompt]       (paged results/prompt)
            [!]sss=[-]<attr[:OID]>[/[-]<attr[:OID]>...]  (server side sorting)
            [!]subentries[=true|false]           (subentries)
            [!]sync=ro[/<cookie>]                (LDAP Sync refreshOnly)
                    rp[/<cookie>][/<slimit>]     (LDAP Sync refreshAndPersist)
            [!]vlv=<before>/<after>(/<offset>/<count>|:<value>)  (virtual list view)
            [!]deref=derefAttr:attr[,attr[...]][;derefAttr:attr[,attr[...]]]
            [!]<oid>[=:<value>|::<b64value>]

ldapsearchで特定に値があるエントリのみ出力

LDAPでmailアトリビュートが設定されているアカウント名とメールアドレスだけを出力させたい場合

ldapsearch -x -H ldaps://192.168.122.10 -D "cn=vmail,cn=Users,dc=adsample,dc=local" -w "パスワード" -b "dc=adsample,dc=local" -s subtree mail=* sAMAccountName mail

-s substreeの後の語句がfilterで検索条件。「mail=*」はmailに値がなんでもいいのであれば良い、ということ

続く「sAMAccountName mail」が出力させたいattiribute名。いくつでも列挙可

mail=*の部分の条件を複雑化させることもできる

doveadmでメールボックスの状態確認

dovecotで認識しているメールボックスの状態を確認する「doveadm mailbox status」コマンド

全ユーザについてとりあえず全ステータスをとる場合はfieldをallにすればいい、というので「doveadm mailbox status -A all ‘*’」を実行してみる

[root@mail ~]# doveadm mailbox status -A all '*'
testuser1@adsample.local Trash messages=0 recent=0 uidnext=2 uidvalidity=1745978754 unseen=0 highestmodseq=5 vsize=0 guid=40b0b82833051c68570600003a0de1d0 firstsaved=never
testuser1@adsample.local INBOX messages=16 recent=0 uidnext=18 uidvalidity=1745978753 unseen=0 highestmodseq=22 vsize=613873 guid=3fa5f40281851168ee0500003a0de1d0 firstsaved=1746666817
testuser2@adsample.local Drafts messages=4 recent=0 uidnext=5 uidvalidity=1745978410 unseen=0 highestmodseq=9 vsize=2313 guid=fe4beb08b4d91268980500003a0de1d0 firstsaved=1746066862
testuser2@adsample.local Sent messages=28 recent=0 uidnext=35 uidvalidity=1745978409 unseen=0 highestmodseq=37 vsize=10545 guid=a28a5e0b7c201268cb0600003a0de1d0 firstsaved=1746018428
testuser2@adsample.local Trash messages=0 recent=0 uidnext=12 uidvalidity=1745978408 unseen=0 highestmodseq=11 vsize=0 guid=ab2c081a361e1268260600003a0de1d0 firstsaved=never
testuser2@adsample.local INBOX messages=9 recent=0 uidnext=15 uidvalidity=1745978407 unseen=0 highestmodseq=33 vsize=10810 guid=7e51333727841168d30500003a0de1d0 firstsaved=1746084330
testuser3@adsample.local INBOX messages=2 recent=2 uidnext=3 uidvalidity=1746166331 unseen=2 highestmodseq=3 vsize=1330 guid=7d83dc163b621468950800003a0de1d0 firstsaved=1746166331
[root@mail ~]#

ん?? vsizeは表示されていない?…マニュアルを再度確認すると -tオプションで messages, recent, unseen, vsizeだけを表示できるとのこと

[root@mail ~]# doveadm mailbox status -A all '*' -t
testuser1@adsample.local messages=16 recent=0 unseen=0 vsize=613873
testuser2@adsample.local messages=41 recent=0 unseen=0 vsize=23668
testuser3@adsample.local messages=2 recent=2 unseen=2 vsize=1330
testuser4@adsample.local messages=0 recent=0 unseen=0 vsize=0
vmail@adsample.local messages=0 recent=0 unseen=0 vsize=0
[root@mail ~]#

messages: メール総数
recent: Recentフラグがついてるメール数(新着メール=まだメールソフトに取り込んでない)
unseen: 未読メール数
vsize: メールの総容量(バイト)

dovecotの起動プロセス数確認

メールソフトからpop3/imapで接続すると、dovecot/pop3やdovecot/imapプロセスが起動する

例えば雑にpsコマンドの結果をとってみるとこんな感じ

[root@mail ~]# ps -ef|grep imap
vmail       2096    2088  0 17:36 ?        00:00:00 dovecot/imap [testuser2@adsample.local 192.168.122.1 IDLE]
vmail       2097    2088  0 17:36 ?        00:00:00 dovecot/imap [testuser2@adsample.local 192.168.122.1]
dovenull    2099    2088  0 17:37 ?        00:00:00 dovecot/imap-login [192.168.122.1 TLS proxy]
vmail       2101    2088  0 17:37 ?        00:00:00 dovecot/imap [testuser1@adsample.local 192.168.122.1 IDLE]
root        2118    1441  0 17:45 pts/0    00:00:00 grep --color=auto imap
[root@mail ~]#

これをdovecot側のコマンドで状態取得する場合は「doveadm service status サービス名」で取得する

[root@mail ~]# doveadm service status imap
name: imap
process_count: 3
process_avail: 0
process_limit: 1024
client_limit: 1
throttle_secs: 0
exit_failure_last: 0
exit_failures_in_sec: 0
last_drop_warning: 0
listen_pending: n
listening: y
doveadm_stop: n
process_total: 4
[root@mail ~]# doveadm service status imap-login
name: imap-login
process_count: 1
process_avail: 0
process_limit: 100
client_limit: 1
throttle_secs: 0
exit_failure_last: 0
exit_failures_in_sec: 0
last_drop_warning: 0
listen_pending: n
listening: y
doveadm_stop: n
process_total: 4
[root@mail ~]#

IMAPの場合、メールクライアントの実装によっては接続が維持されるのでprocess_limitの値に抵触しないかを注意する必要がある

Service Limits

Then client_limit needs to be set high enough to be able to serve all the needed connections (max connections=process_limit * client_limit).

acvite directory連携のdovecotでdoveadm quota get -Aが動かない

dovecot 2.2.19以降で登場した各ユーザのメールフォルダ内にあるindexファイルを使ったquotaを設定しようとした際に発見した出来事です。

doveadm quota get -Aの動作

doveadm quotaのマニュアルを見ると「doveadm quota get -A」を実行すると全ユーザの結果が表示されそうな気がするので実行してみたがされない

[root@mail dovecot]# doveadm quota get -A
Username Quota name Type Value Limit                                                   %
[root@mail dovecot]#

dovecotにdebug系ログ出力を有効にした状態での /var/log/maillog には下記のログ

May  2 11:18:59 mail dovecot[959]: auth: Debug: Loading modules from directory: /usr/lib64/dovecot/auth
May  2 11:18:59 mail dovecot[959]: auth: Debug: Module loaded: /usr/lib64/dovecot/auth/lib20_auth_var_expand_crypt.so
May  2 11:18:59 mail dovecot[959]: auth: Debug: Module loaded: /usr/lib64/dovecot/auth/libdriver_sqlite.so
May  2 11:18:59 mail dovecot[959]: auth: Debug: Loading modules from directory: /usr/lib64/dovecot/auth
May  2 11:18:59 mail dovecot[959]: auth: Debug: Module loaded: /usr/lib64/dovecot/auth/libauthdb_ldap.so
May  2 11:18:59 mail dovecot[959]: auth: Debug: Read auth token secret from /run/dovecot/auth-token-secret.dat
May  2 11:18:59 mail dovecot[959]: auth: Debug: ldap(/etc/dovecot/dovecot-ldap.conf.ext): LDAP initialization took 22 msecs
May  2 11:18:59 mail dovecot[959]: auth: Debug: master in: LIST#0111
May  2 11:18:59 mail dovecot[959]: auth-worker(1542): Debug: Loading modules from directory: /usr/lib64/dovecot/auth
May  2 11:18:59 mail dovecot[959]: auth-worker(1542): Debug: Module loaded: /usr/lib64/dovecot/auth/lib20_auth_var_expand_crypt.so
May  2 11:18:59 mail dovecot[959]: auth-worker(1542): Debug: Module loaded: /usr/lib64/dovecot/auth/libdriver_sqlite.so
May  2 11:18:59 mail dovecot[959]: auth-worker(1542): Debug: Loading modules from directory: /usr/lib64/dovecot/auth
May  2 11:18:59 mail dovecot[959]: auth-worker(1542): Debug: Module loaded: /usr/lib64/dovecot/auth/libauthdb_ldap.so
May  2 11:18:59 mail dovecot[959]: auth-worker(1542): Debug: ldap(/etc/dovecot/dovecot-ldap.conf.ext): LDAP initialization took 14 msecs
May  2 11:18:59 mail dovecot[959]: auth-worker(1542): Debug: conn unix:auth-worker (pid=1541,uid=97): Server accepted connection (fd=14)
May  2 11:18:59 mail dovecot[959]: auth-worker(1542): Debug: conn unix:auth-worker (pid=1541,uid=97): Sending version handshake
May  2 11:18:59 mail dovecot[959]: auth-worker(1542): Debug: conn unix:auth-worker (pid=1541,uid=97): auth-worker<1>: Handling LIST request
May  2 11:18:59 mail dovecot[959]: auth-worker(1542): Debug: conn unix:auth-worker (pid=1541,uid=97): auth-worker<1>: ldap(): Performing userdb lookup
May  2 11:18:59 mail dovecot[959]: auth-worker(1542): Debug: conn unix:auth-worker (pid=1541,uid=97): auth-worker<1>: ldap: iterate: base=cn=Users,dc=adsample,dc=local scope=subtree filter=(objectClass=posixAccount) fields=uid
May  2 11:18:59 mail dovecot[959]: auth-worker(1542): Debug: conn unix:auth-worker (pid=1541,uid=97): auth-worker<1>: ldap(): Finished userdb lookup
May  2 11:18:59 mail dovecot[959]: auth-worker(1542): Debug: conn unix:auth-worker (pid=1541,uid=97): auth-worker<1>: Finished

「objectClass=posixAccount」でフィルターをかけているが、Active DirectoryベースのLDAPサーバ標準では posixAccountは存在していないため、フィルター文字列を変える必要がある、という話である

確認のためldapsearchコマンドで出力がないことを確認

[root@mail dovecot]# ldapsearch -x -H ldaps://192.168.122.10 -D "cn=vmail,cn=Users,dc=adsample,dc=local" -w "パスワード" -b "dc=adsample,dc=local" -s subtree objectClass=posixAccount
# extended LDIF
#
# LDAPv3
# base <dc=adsample,dc=local> with scope subtree
# filter: objectClass=posixAccount
# requesting: ALL
#

# search reference
ref: ldaps://ForestDnsZones.adsample.local/DC=ForestDnsZones,DC=adsample,DC=lo
 cal

# search reference
ref: ldaps://DomainDnsZones.adsample.local/DC=DomainDnsZones,DC=adsample,DC=lo
 cal

# search reference
ref: ldaps://adsample.local/CN=Configuration,DC=adsample,DC=local

# search result
search: 2
result: 0 Success

# numResponses: 4
# numReferences: 3
[root@mail dovecot]#

どこの設定を変えればいいのか調べていくと userdb_ldap_iterate_fieldsuserdb_ldap_iterate_filter で行っているので /etc/dovecot/dovecot-ldap.conf.ext に iterate_filter と iterate_attrs の設定を行う、ということがわかる

うまいことユーザ一覧っぽいのを取得するにはどうすればいいかな、とldapsearchコマンドをこねくり回して「ldapsearch -x -H ldaps://192.168.122.10 -D “cn=vmail,cn=Users,dc=adsample,dc=local” -w “パスワード” -b “dc=adsample,dc=local” -s subtree objectClass=user userPrincipalName」とすればいいかな、というのがわかった。

この結果をもとに、/etc/dovecot/dovecot-ldap.conf.ext に以下を追加してみたところおおむね期待通りの動作となった

iterate_filter=objectClass=user
iterate_attrs=userPrincipalName=user

これは、”objectClass=user”に該当するオブジェクトを表示させたあと、 userPrincipalName の値を dovecot上の user として認識させる、という意味合いの設定となる。

doveadm quota get -Aの実行結果

[root@mail dovecot]# doveadm quota get -A
Username                 Quota name Type    Value Limit                                          %
testuser1@adsample.local User quota STORAGE     9 10240                                          0
testuser1@adsample.local User quota MESSAGE    13     -                                          0
testuser2@adsample.local User quota STORAGE    14 10240                                          0
testuser2@adsample.local User quota MESSAGE    31     -                                          0
testuser3@adsample.local User quota STORAGE     0 10240                                          0
testuser3@adsample.local User quota MESSAGE     0     -                                          0
testuser4@adsample.local User quota STORAGE     0 10240                                          0
testuser4@adsample.local User quota MESSAGE     0     -                                          0
vmail@adsample.local     User quota STORAGE     0 10240                                          0
vmail@adsample.local     User quota MESSAGE     0     -                                          0
[root@mail dovecot]#

/etc/dovecot/conf.d/90-quota.conf を編集し、容量制限を1MBに変更

<略>
plugin {
  # 10MB quota limit
  quota = count:User quota
  quota_rule = *:storage=1M

  # This is required - it uses "virtual sizes" rather than "physical sizes"
  # for quota counting:
  quota_vsizes = yes
}

この状態でメールを送って容量を増やして確認・・・

[root@mail dovecot]# doveadm quota get -A
Username                 Quota name Type    Value Limit                                          %
testuser1@adsample.local User quota STORAGE   895  1024                                         87
testuser1@adsample.local User quota MESSAGE    16     -                                          0
testuser2@adsample.local User quota STORAGE   907  1024                                         88
testuser2@adsample.local User quota MESSAGE    38     -                                          0
testuser3@adsample.local User quota STORAGE     0  1024                                          0
testuser3@adsample.local User quota MESSAGE     0     -                                          0
testuser4@adsample.local User quota STORAGE     0  1024                                          0
testuser4@adsample.local User quota MESSAGE     0     -                                          0
vmail@adsample.local     User quota STORAGE     0  1024                                          0
vmail@adsample.local     User quota MESSAGE     0     -                                          0
[root@mail dovecot]#

2025/08/21 追記

動作試験のため、Active DirectoryにPowerShellのNew-Aduserコマンドを使って6万アカウントを作成した。

for($I=0;$I -lt 60000; $I++){
    $count="{0:000000}" -f $I
    $username="h"+$count
    New-Aduser -emailaddress $username"@adsample.local" -SamAccountName $username -Name $username -DisplayName $username -GivenName $username -UserPrincipalName $username"@adsample.local"
}

そして、doveadm quota get -Aを実行したところ約1000件表示したところでエラー発生

# doveadm quota get -A|head -20
Username  Quota name Type    Value Limit                    %
h000000   User quota STORAGE     0  5120                    0
h000000   User quota MESSAGE     0     -                    0
h000001   User quota STORAGE     0  5120                    0
h000001   User quota MESSAGE     0     -                    0
h000002   User quota STORAGE     0  5120                    0
h000002   User quota MESSAGE     0     -                    0
<略>
h000999   User quota STORAGE     0  5120                    0
h000999   User quota MESSAGE     0     -                    0
doveadm(2465): Error: auth-master: userdb list: User listing returned failure
doveadm: Error: Failed to iterate through some users
#

この時、ログには以下が出力されていた

Aug 21 17:38:30 rhel9 dovecot[1135]: auth-worker(2463): Error: conn unix:auth-worker (pid=2462,uid=97): auth-worker<2>: ldap(): ldap_search(base=cn=Users,dc=adsample,dc=local filter=objectClass=user) failed: Size limit exceeded

これはopenldapの仕様で1000件までしか表示してくれないため、という制限だった。

dovecotのソースファイルを確認してみたけど、 ldap検索時のsizelimitについて解除できるような設定が見当たらなかった。

で、doveadmコマンドのqoutaについてdocを確認すると-Fオプションで確認したいユーザを列挙したファイルを与えて取得ができることがわかった

-F file
Execute the command for all the users in the file.  This is similar to the -A option, but instead of getting the list of users from the userdb, they are read from the given file.  The file contains one username per line.

ldapsearchコマンドによるユーザ名一覧作成についても1000件制限がかかるが、「-E pr=1000/noprompt」オプションを付けると解除されるため、全ユーザ一覧の取得ができる。

元の一覧作成で以下を使っていた場合

ldapsearch -x -H ldaps://192.168.122.10 -D "cn=vmail,cn=Users,dc=adsample,dc=local" -w "パスワード" -b "dc=adsample,dc=local" -s subtree objectClass=user userPrincipalName

下記の様に実行すると userPrincipalName だけを取得できる

ldapsearch -x -H ldaps://192.168.122.10 -D "cn=vmail,cn=Users,dc=adsample,dc=local" -w "パスワード" -b "dc=adsample,dc=local" -s subtree objectClass=user userPrincipalName  -E "pr=1000/noprompt" |grep "userPrincipalName:" | awk '{ print $2 }'

これをファイルに保存して「doveadm quota get -F ファイル名」を実行することで対応可能となる。

で、これをスクリプト化したいわけですが、スクリプトに直接パスワードを書くのではなく、 /etc/dovecot/dovecot-ldap.conf.ext に書いたヤツを流用してくれるとうれしいわけです。

概ねこんな感じでしょうか?(注:これを使う場合、例えば「dn=」のあとにスペースがあるとエラーになります)

#/bin/bash
# dovecotのLDAP設定が書いてあるファイル
ldapconf=/etc/dovecot/dovecot-ldap.conf.ext

### 一時ファイル関連の処理
# 一時ファイルを作る
tmpfile=$(mktemp)
# 生成した一時ファイルを削除する
function rm_tmpfile {
  [[ -f "$tmpfile" ]] && rm -f "$tmpfile"
}
# 正常終了したとき
trap rm_tmpfile EXIT
# 異常終了したとき
trap 'trap - EXIT; rm_tmpfile; exit -1' INT PIPE TERM

### 実際の処理
# 設定ファイルから値を読み込み
tmpuris=`grep "^uris=" $ldapconf|awk -Fis= '{ print $2 }'`
tmpdn=`grep "^dn=" $ldapconf|awk -Fdn= '{ print $2 }'`
tmpdnpass=`grep "^dnpass=" $ldapconf|awk -Fss= '{ print $2 }'`
tmpbase=`grep "^base=" $ldapconf|awk -Fse= '{ print $2 }'`
tmpfilter=`grep "^iterate_filter=" $ldapconf|awk -Fer= '{ print $2 }'`

ldapsearch -x -H "$tmpuris" -D "$tmpdn" -w "$tmpdnpass" -b "$tmpbase" -s subtree $tmpfilter userPrincipalName  -E "pr=1000/noprompt" |grep "userPrincipalName:" | awk '{ print $2 }' > $tmpfile
doveadm quota get -F $tmpfile

一時ファイルを作成するあたりの処理は晴耕雨読Bashで一時ファイルを作る方法」のものを使用しました。

postfixとactive directoryを連携させるときのLDA向け設定を検証した

postfix/dovecotを使ったメールサーバを作成する際、そのサーバ上でユーザ向けメールサービスを提供する場合にLDA設定を行う必要がある。

調べると dovecot-lda を使って保存するのがよさそうではある

参考資料
 dovecot側 「Dovecot LDA」「Dovecot LDA Examples」「Dovecot LDA with Postfix

ただ、これをActive Directory/LDAPと連携させる場合の記述についてがいまいちはっきりしない。

ベースとするのは「Dovecot LDA with Postfix」の「Virtual users」にある記述で、/etc/postfix/master.cf に dovecotの記述を追加して、 /etc/postfix/main.cf に dovecot_destination_recipient_limit , virtual_mailbox_domains , virtual_transport の設定を追加する、と読める。

ただ、これだけだとメールを格納する場所について書いてないなぁ、と思いつつ試してみた

その結果、 virtual_transport=dovecot を設定した場合は、 postfix側で “virtual_mailbox_maps= ldap:/etc/postfix/ldap-mailbox.cf”とか”virtual_mailbox_base= /var/vmail”とかの設定を入れて /etc/postfix/ldap-mailbox.cf でLDAPに関する設定を書いたりする必要なく、dovecot側で行ったLDAP連携設定をもとにdovecot側で処理してくれる、ということが分かった

で・・・これの確認をするための副産物として、 virtual_transport=dovecotとしているのに virtual_mailbox_maps= ldap:/etc/postfix/ldap-mailbox.cf とかpostfix側でLDAPを直接見に行くような設定をしてしまうとどうなるの?というのを確認していた(意図せずに・・・

gihyoにあるそろそろLDAPにしてみないか?第15回「FDS+Postfixでメールサーバ管理」と「デージーネットのOSS postLDAPadmin Appendix」を参照しつついろいろ検討

まず、今回、/etc/postfix/master.cf の最下行にdovecotに関する2行を追加した

[root@mail postfix]# tail /etc/postfix/master.cf
#
#scalemail-backend unix -       n       n       -       2       pipe
#  flags=R user=scalemail argv=/usr/lib/scalemail/bin/scalemail-store
#  ${nexthop} ${user} ${extension}
#
#mailman   unix  -       n       n       -       -       pipe
#  flags=FRX user=list argv=/usr/lib/mailman/bin/postfix-to-mailman.py
#  ${nexthop} ${user}
dovecot   unix  -       n       n       -       -       pipe
  flags=DRhu user=vmail:vmail argv=/usr/libexec/dovecot/dovecot-lda -f ${sender} -d ${recipient}
[root@mail postfix]#

そして、/etc/postfix/main.cf には以下を追加した

[root@mail postfix]# tail -10 /etc/postfix/main.cf
#
#
virtual_mailbox_domains = adsample.local
virtual_mailbox_maps= ldap:/etc/postfix/ldap-mailbox.cf
virtual_mailbox_base= /var/vmail
virtual_uid_maps= static:1000
virtual_gid_maps= static:1000
virtual_transport= dovecot
dovecot_destination_recipient_limit = 1

[root@mail postfix]#

で、postfix側のLDAP連携設定は以下とした

[root@mail postfix]# cat /etc/postfix/ldap-mailbox.cf
#server_host=192.168.122.10
server_host=ldaps://192.168.122.10
#server_port=636
#search_base=dc=adsample,dc=local
search_base=cn=Users,dc=adsample,dc=local
scope=sub
#query_filter = (&(objectClass=user)(mail=%s))
query_filter = (&(objectClass=user)(userPrincipalName=%s))
result_attribute = samAccountName
result_filter = /var/mail/%s/Maildir/

bind=yes
bind_dn=vmail@adsample.local
bind_pw=パスワード
version=3
#start_tls=yes
#debuglevel=10
[root@mail postfix]#

とりあえず「debuglevel=10」というのは調査中に有効にしていた値

virtual_mailbox_maps で取得できる情報として期待されているものは メールを保存するディレクトリ名 の模様

コメントとなっている「query_filter = (&(objectClass=user)(mail=%s))」はActive Directoryベースだとmailってないので使わない。ユーザ名のみの場合は「samAccountName=%s」、ドメイン名付きの場合は「userPrincipalName=%s」かな、というところで設定

取得できてるかどうかは「postmap -q ユーザ名 ldap:/~」で確認(パッケージ postfix-ldap がインストールされていない場合、”postmap: fatal: unsupported dictionary type: ldap”というエラーになる)

[root@mail ~]# postmap -q testuser1@adsample.local ldap:/etc/postfix/ldap-mailbox.cf
/var/mail/testuser1/Maildir/
[root@mail ~]#

想定しているディレクトリ名が出力されればOK

-vオプションをつけると検索内容の詳細が確認できる。

[root@mail ~]# postmap -v -q testuser1@adsample.local ldap:/etc/postfix/ldap-mailbox.cf
postmap: name_mask: all
postmap: inet_addr_local: configured 2 IPv4 addresses
postmap: inet_addr_local: configured 2 IPv6 addresses
postmap: dict_ldap_open: Using LDAP source /etc/postfix/_ldap-mailbox.cf
postmap: cfg_get_str: /etc/postfix/_ldap-mailbox.cf: server_host = ldaps://192.168.122.10
postmap: cfg_get_int: /etc/postfix/_ldap-mailbox.cf: server_port = 389
postmap: cfg_get_int: /etc/postfix/_ldap-mailbox.cf: version = 3
postmap: dict_ldap_open: /etc/postfix/_ldap-mailbox.cf server_host URL is ldaps://192.168.122.10
postmap: cfg_get_str: /etc/postfix/_ldap-mailbox.cf: scope = sub
postmap: cfg_get_str: /etc/postfix/_ldap-mailbox.cf: search_base = cn=Users,dc=adsample,dc=local
postmap: cfg_get_int: /etc/postfix/_ldap-mailbox.cf: timeout = 10
postmap: cfg_get_str: /etc/postfix/_ldap-mailbox.cf: query_filter = (&(objectClass=user)(userPrincipalName=%s))
postmap: cfg_get_str: /etc/postfix/_ldap-mailbox.cf: result_format = <NULL>
postmap: cfg_get_str: /etc/postfix/_ldap-mailbox.cf: result_filter = /var/mail/%s/Maildir/
postmap: cfg_get_str: /etc/postfix/_ldap-mailbox.cf: domain =
postmap: cfg_get_str: /etc/postfix/_ldap-mailbox.cf: terminal_result_attribute =
postmap: cfg_get_str: /etc/postfix/_ldap-mailbox.cf: leaf_result_attribute =
postmap: cfg_get_str: /etc/postfix/_ldap-mailbox.cf: result_attribute = samAccountName
postmap: cfg_get_str: /etc/postfix/_ldap-mailbox.cf: special_result_attribute =
postmap: cfg_get_str: /etc/postfix/_ldap-mailbox.cf: bind = yes
postmap: cfg_get_str: /etc/postfix/_ldap-mailbox.cf: bind_dn = vmail@adsample.local
postmap: cfg_get_str: /etc/postfix/_ldap-mailbox.cf: bind_pw = パスワード
postmap: cfg_get_bool: /etc/postfix/_ldap-mailbox.cf: cache = off
postmap: cfg_get_int: /etc/postfix/_ldap-mailbox.cf: cache_expiry = -1
postmap: cfg_get_int: /etc/postfix/_ldap-mailbox.cf: cache_size = -1
postmap: cfg_get_int: /etc/postfix/_ldap-mailbox.cf: recursion_limit = 1000
postmap: cfg_get_int: /etc/postfix/_ldap-mailbox.cf: expansion_limit = 0
postmap: cfg_get_int: /etc/postfix/_ldap-mailbox.cf: size_limit = 0
postmap: cfg_get_int: /etc/postfix/_ldap-mailbox.cf: dereference = 0
postmap: cfg_get_bool: /etc/postfix/_ldap-mailbox.cf: chase_referrals = off
postmap: cfg_get_bool: /etc/postfix/_ldap-mailbox.cf: start_tls = off
postmap: cfg_get_bool: /etc/postfix/_ldap-mailbox.cf: tls_require_cert = off
postmap: cfg_get_str: /etc/postfix/_ldap-mailbox.cf: tls_ca_cert_file =
postmap: cfg_get_str: /etc/postfix/_ldap-mailbox.cf: tls_ca_cert_dir =
postmap: cfg_get_str: /etc/postfix/_ldap-mailbox.cf: tls_cert =
postmap: cfg_get_str: /etc/postfix/_ldap-mailbox.cf: tls_key =
postmap: cfg_get_str: /etc/postfix/_ldap-mailbox.cf: tls_random_file =
postmap: cfg_get_str: /etc/postfix/_ldap-mailbox.cf: tls_cipher_suite =
postmap: cfg_get_int: /etc/postfix/_ldap-mailbox.cf: debuglevel = 0
postmap: dict_open: ldap:/etc/postfix/_ldap-mailbox.cf
postmap: dict_ldap_lookup: In dict_ldap_lookup
postmap: dict_ldap_lookup: No existing connection for LDAP source /etc/postfix/_ldap-mailbox.cf, reopening
postmap: dict_ldap_connect: Connecting to server ldaps://192.168.122.10
postmap: dict_ldap_connect: Actual Protocol version used is 3.
postmap: dict_ldap_connect: Binding to server ldaps://192.168.122.10 with dn vmail@adsample.local
postmap: dict_ldap_connect: Successful bind to server ldaps://192.168.122.10 with dn vmail@adsample.local
postmap: dict_ldap_connect: Cached connection handle for LDAP source /etc/postfix/_ldap-mailbox.cf
postmap: dict_ldap_lookup: /etc/postfix/_ldap-mailbox.cf: Searching with filter (&(objectClass=user)(userPrincipalName=testuser1@adsample.local))
postmap: dict_ldap_get_values[1]: Search found 1 match(es)
postmap: dict_ldap_get_values[1]: search returned 1 value(s) for requested result attribute sAMAccountName
postmap: dict_ldap_get_values[1]: Leaving dict_ldap_get_values
postmap: dict_ldap_lookup: Search returned /var/mail/testuser1/Maildir/
/var/mail/testuser1/Maildir/
postmap: dict_ldap_close: Closed connection handle for LDAP source /etc/postfix/_ldap-mailbox.cf
[root@mail ~]#

それっぽい動作をすることを確認して、postfixを再起動してみたところ”virtual_transport= dovecot”設定を無視して postfix側でLDAPを見に行くことを確認。(/etc/postfix/ldap-mailbox.cfにdebuglevel=10を設定すると、 /var/log/maillog に詳細ログが出ているので)

どうやら、2025年5月時点では postfix/dovecotでActive Directory連携するときは、postfix側ではLDAP連携をする必要はないようだ(aliasなどをAD側で設定している場合は別)

最終的に行った設定内容

結局のところ「Dovecot LDA with Postfix」の Virutal users記載ベースで/etc/postfix/master.cfの末尾にdovecot用設定2行追加。(元ネタでは /usr/local/libexec以下にあるけどRHEL9では/usr/libexecという違いに注意)

[root@mail ~]# tail /etc/postfix/master.cf
#
#scalemail-backend unix -       n       n       -       2       pipe
#  flags=R user=scalemail argv=/usr/lib/scalemail/bin/scalemail-store
#  ${nexthop} ${user} ${extension}
#
#mailman   unix  -       n       n       -       -       pipe
#  flags=FRX user=list argv=/usr/lib/mailman/bin/postfix-to-mailman.py
#  ${nexthop} ${user}
dovecot   unix  -       n       n       -       -       pipe
  flags=DRhu user=vmail:vmail argv=/usr/libexec/dovecot/dovecot-lda -f ${sender} -d ${recipient}
[root@mail ~]#

/etc/postfix/main.cf に以下を追加

[root@mail ~]# tail -5 /etc/postfix/main.cf
#
virtual_mailbox_domains = adsample.local
virtual_transport= dovecot
dovecot_destination_recipient_limit = 1
[root@mail ~]#

なお、この時にdovecot側のLDAP連携設定は以下となっている。(メールソフト側でIMAP/POP3用に入力するユーザ名をドメイン名付きにしたい場合はuserPrincipalName、ユーザ名のみにしたい場合は samAccountName を使う)

[root@mail ~]# cat /etc/dovecot/dovecot-ldap.conf.ext
dn= cn=vmail,cn=Users,dc=adsample,dc=local
dnpass= パスワード
#pass_filter= (samAccountName=%u)
#user_filter= (samAccountName=%u)
user_filter= (userPrincipalName=%u)
pass_filter= (userPrincipalName=%u)
user_attrs = =uid=1000, =gid=1000
pass_attrs = =uid=1000, =gid=1000

auth_bind=yes
uris=ldaps://192.168.122.10
base= cn=Users,dc=adsample,dc=local
scope=subtree

[root@mail ~]# cat /etc/dovecot/conf.d/auth-ldap.conf.ext
# Authentication for LDAP users. Included from 10-auth.conf.
#
# <doc/wiki/AuthDatabase.LDAP.txt>

passdb {
  driver = ldap

  # Path for LDAP configuration file, see example-config/dovecot-ldap.conf.ext
  args = /etc/dovecot/dovecot-ldap.conf.ext
}

# "prefetch" user database means that the passdb already provided the
# needed information and there's no need to do a separate userdb lookup.
# <doc/wiki/UserDatabase.Prefetch.txt>
#userdb {
#  driver = prefetch
#}

userdb {
  driver = ldap
  args = /etc/dovecot/dovecot-ldap.conf.ext

  # Default fields can be used to specify defaults that LDAP may override
  #default_fields = home=/home/virtual/%u
  default_fields = uid=vmail gid=vmail
}

# If you don't have any user-specific settings, you can avoid the userdb LDAP
# lookup by using userdb static instead of userdb ldap, for example:
# <doc/wiki/UserDatabase.Static.txt>
#userdb {
  #driver = static
  #args = uid=vmail gid=vmail home=/var/vmail/%u
#}
[root@mail ~]#

また /etc/dovecot/conf.d/10-mail.conf に mail_location = maildir:/var/mail/%n/Maildir という設定を追加している。

[root@mail ~]# diff -u /etc/dovecot/conf.d/10-mail.conf.org /etc/dovecot/conf.d/10-mail.conf
--- /etc/dovecot/conf.d/10-mail.conf.org        2025-04-25 03:13:54.044373479 +0900
+++ /etc/dovecot/conf.d/10-mail.conf    2025-04-30 10:59:12.661404241 +0900
@@ -27,7 +27,7 @@
 #
 # <doc/wiki/MailLocation.txt>
 #
-#mail_location =
+mail_location = maildir:/var/mail/%n/Maildir

 # If you need to set multiple mailbox locations or want to change default
 # namespace settings, you can do it by defining namespace sections.
[root@mail ~]#

エラー対処

/var/log/maillog を見てたら下記のようなpermission問題があった

May  1 18:28:19 mail dovecot[924]: auth: Debug: userdb out: USER#0111#011testuser2@adsample.local#011uid=1000#011gid=1000
May  1 18:28:19 mail dovecot[2244]: lda(testuser2@adsample.local)&lt;2244>&lt;/OWMMLM+E2jECAAAOg3h0A>: msgid=&lt;9da96806-84e5-4f26-9752-acf16b48d4dc@adsample.local>: saved mail to INBOX
May  1 18:28:19 mail postfix/pipe[2238]: AD3C12037F14: to=&lt;testuser2@adsample.local>, orig_to=&lt;testuser2@adosakana.local>, relay=dovecot, delay=0.13, delays=0.02/0/0/0.11, dsn=2.0.0, status=sent (delivered via dovecot service (lda(testuser2@adsample.local): Error: net_connect_unix(/run/dovecot/stats-writer) failed: Permission))
May  1 18:28:19 mail postfix/qmgr[2205]: AD3C12037F14: removed

エラー対処を調べると2019年1月のiredmailフォーラムの「Re: Error: net_connect_unix(/var/run/dovecot/stats-writer) failed」 が出てくる

これだと /etc/dovecot/dovecot.conf に直接追加しているが、 /etc/dovecot/conf.d/に新しいファイルを作って追加することにした

[root@mail conf.d]# vi /etc/dovecot/conf.d/12-stat.conf
[root@mail conf.d]# cat /etc/dovecot/conf.d/12-stat.conf
service stats {
    unix_listener stats-reader {
        user = vmail
        group = vmail
        mode = 0660
    }

    unix_listener stats-writer {
        user = vmail
        group = vmail
        mode = 0660
    }
}
[root@mail conf.d]# systemctl restart dovecot
[root@mail conf.d]#

これで出力されなくなった


メール送信時の細かい設定について

/etc/dovecot/dovecot-ldap.conf.ext と /etc/dovecot/conf.d/auth-ldap.conf.ext のそれぞれでuid/gidに関する設定を入れているが、それぞれの必要性について再検証

というのは、設定してるなかで、片方だけ設定を入れているとmissingログが出てたから両方入れた・・・はずだったんだけど、それって正しいの?という検証

まずは/etc/dovecot/conf.d/99-debug.conf にdebugログ出力設定を書いて 実施

[root@mail ~]# cat /etc/dovecot/conf.d/99-debug.conf
auth_debug=yes
auth_debug_passwords=yes
auth_verbose=yes
auth_verbose_passwords=yes
verbose_proctitle=yes
verbose_ssl=yes

[root@mail ~]#

ケース1

conf.d/auth-ldap.conf.ext に 「default_fields = uid=vmail gid=vmail」
dovecot-ldap.conf.ext で user_atrrs,pass_attrsの設定なし

この時メールを送信すると以下のような”result: uid missing”, “result: homeDirectory missing; uidNumber missing; gidNumber missing”ログがある

May  2 09:45:39 mail dovecot[1564]: auth: Debug: client in: AUTH#0111#011PLAIN#011service=imap#011session=BnUjeBw0hcjAqHoB#011lip=192.168.122.12#011rip=192.168.122.1#011lport=143#011rport=51333
May  2 09:45:39 mail dovecot[1564]: auth: Debug: client passdb out: CONT#0111
May  2 09:45:39 mail dovecot[1564]: auth: Debug: client in: CONT#0111#011AHRlc3R1c2VyMkBhZHNhbXBsZS5sb2NhbABkaWdpdGFsMTIzQSM= (previous base64 data may contain sensitive data)
May  2 09:45:39 mail dovecot[1564]: auth: Debug: ldap(testuser2@adsample.local,192.168.122.1,<BnUjeBw0hcjAqHoB>): Performing passdb lookup
May  2 09:45:39 mail dovecot[1564]: auth: Debug: ldap(testuser2@adsample.local,192.168.122.1,<BnUjeBw0hcjAqHoB>): bind search: base=cn=Users,dc=adsample,dc=local filter=(userPrincipalName=testuser2@adsample.local)
May  2 09:45:39 mail dovecot[1564]: auth: Debug: ldap(testuser2@adsample.local,192.168.122.1,<BnUjeBw0hcjAqHoB>): no fields returned by the server
May  2 09:45:39 mail dovecot[1564]: auth: Debug: ldap(testuser2@adsample.local,192.168.122.1,<BnUjeBw0hcjAqHoB>): result:  uid missing
May  2 09:45:39 mail dovecot[1564]: auth: Debug: ldap(testuser2@adsample.local,192.168.122.1,<BnUjeBw0hcjAqHoB>): Finished passdb lookup
May  2 09:45:39 mail dovecot[1564]: auth: Debug: auth(testuser2@adsample.local,192.168.122.1,<BnUjeBw0hcjAqHoB>): Auth request finished
May  2 09:45:39 mail dovecot[1564]: auth: Debug: client passdb out: OK#0111#011user=testuser2@adsample.local
May  2 09:45:39 mail dovecot[1564]: auth: Debug: master in: REQUEST#0112287206401#0111566#0111#011bef1c5eb0e8a2b05cf297e143bfb1cc6#011session_pid=1569#011request_auth_token
May  2 09:45:39 mail dovecot[1564]: auth: Debug: ldap(testuser2@adsample.local,192.168.122.1,<BnUjeBw0hcjAqHoB>): Performing userdb lookup
May  2 09:45:39 mail dovecot[1564]: auth: Debug: ldap(testuser2@adsample.local,192.168.122.1,<BnUjeBw0hcjAqHoB>): user search: base=cn=Users,dc=adsample,dc=local scope=subtree filter=(userPrincipalName=testuser2@adsample.local) fields=homeDirectory,uidNumber,gidNumber
May  2 09:45:39 mail dovecot[1564]: auth: Debug: ldap(testuser2@adsample.local,192.168.122.1,<BnUjeBw0hcjAqHoB>): no fields returned by the server
May  2 09:45:39 mail dovecot[1564]: auth: Debug: ldap(testuser2@adsample.local,192.168.122.1,<BnUjeBw0hcjAqHoB>): result:  homeDirectory missing; uidNumber missing; gidNumber missing
May  2 09:45:39 mail dovecot[1564]: auth: Debug: ldap(testuser2@adsample.local,192.168.122.1,<BnUjeBw0hcjAqHoB>): Finished userdb lookup
May  2 09:45:39 mail dovecot[1564]: auth: Debug: master userdb out: USER#0112287206401#011testuser2@adsample.local#011uid=1000#011gid=1000#011auth_mech=PLAIN#011auth_token=aaa072efd8fc1ceb4051c9c51b1fdbc9437e7f81

ケース2

conf.d/auth-ldap.conf.ext に default_fields 設定なし
dovecot-ldap.conf.ext で “user_attrs = =uid=1000, =gid=1000″,”pass_attrs = =uid=1000, =gid=1000” 設定あり

この場合、ログに xxx missing が出ない?

May  2 09:54:48 mail dovecot[959]: auth: Debug: client in: CONT#0111#011AHRlc3R1c2VyMkBhZHNhbXBsZS5sb2NhbABkaWdpdGFsMTIzQSM= (previous base64 data may contain sensitive data)
May  2 09:54:48 mail dovecot[959]: auth: Debug: ldap(testuser2@adsample.local,192.168.122.1,<D2PcmBw0S8rAqHoB>): Performing passdb lookup
May  2 09:54:48 mail dovecot[959]: auth: Debug: ldap(testuser2@adsample.local,192.168.122.1,<D2PcmBw0S8rAqHoB>): bind search: base=cn=Users,dc=adsample,dc=local filter=(userPrincipalName=testuser2@adsample.local)
May  2 09:54:48 mail dovecot[959]: auth: Debug: master in: USER#0111#011testuser1@adsample.local#011service=lda
May  2 09:54:48 mail dovecot[959]: auth: Debug: ldap(testuser1@adsample.local): Performing userdb lookup
May  2 09:54:48 mail dovecot[959]: auth: Debug: ldap(testuser1@adsample.local): user search: base=cn=Users,dc=adsample,dc=local scope=subtree filter=(userPrincipalName=testuser1@adsample.local) fields=
May  2 09:54:48 mail dovecot[959]: auth: Debug: ldap(testuser2@adsample.local,192.168.122.1,<D2PcmBw0S8rAqHoB>): result: objectClass=top,top,top,top cn=testuser2 givenName=testuser2 distinguishedName=CN=testuser2,CN=Users,DC=adsample,DC=local instanceType=4 whenCreated=20250417094639.0Z whenChanged=20250430015944.0Z displayName=testuser2 uSNCreated=12616 uSNChanged=40983 name=testuser2 objectGUID=�u&#016$|-E�Z#034\O?�#036 userAccountControl=66048 badPwdCount=0 codePage=0 countryCode=0 badPasswordTime=133893655225944004 lastLogoff=0 lastLogon=133894260848965097 pwdLastSet=133893567990887154 primaryGroupID=513 objectSid=<no values> accountExpires=9223372036854775807 logonCount=16 sAMAccountName=testuser2 sAMAccountType=805306368 userPrincipalName=testuser2@adsample.local objectCategory=CN=Person,CN=Schema,CN=Configuration,DC=adsample,DC=local dSCorePropagationData=20250418015428.0Z,20250418015428.0Z lastLogonTimestamp=133904519848472342; objectGUID,uSNCreated,objectCategory,objectClass,primaryGroupID,cn,givenName,objectSid,sAMAccountType,dSCorePropagationData,userAccountControl,name,codePage,lastLogon,logonCount,countryCode,lastLogoff,uSNChanged,pwdLastSet,distinguishedName,sAMAccountName,whenChanged,userPrincipalName,instanceType,badPwdCount,accountExpires,whenCreated,displayName,badPasswordTime,lastLogonTimestamp unused
May  2 09:54:48 mail dovecot[959]: auth: Debug: ldap(testuser1@adsample.local): result: objectClass=top,top,top,top cn=testuser1 givenName=testuser1 distinguishedName=CN=testuser1,CN=Users,DC=adsample,DC=local instanceType=4 whenCreated=20250417094618.0Z whenChanged=20250425001141.0Z displayName=testuser1 uSNCreated=12609 uSNChanged=36883 name=testuser1 objectGUID=#037��#�!#020F�j#020#010��#011x userAccountControl=66048 badPwdCount=0 codePage=0 countryCode=0 badPasswordTime=133900339076624909 lastLogoff=0 lastLogon=133900339256453379 pwdLastSet=133893567784742554 primaryGroupID=513 objectSid=<no values> accountExpires=9223372036854775807 logonCount=0 sAMAccountName=testuser1 sAMAccountType=805306368 userPrincipalName=testuser1@adsample.local objectCategory=CN=Person,CN=Schema,CN=Configuration,DC=adsample,DC=local dSCorePropagationData=20250418015428.0Z,20250418015428.0Z lastLogonTimestamp=133900135017739905 mail=testuser1@example.com; objectGUID,uSNCreated,objectCategory,objectClass,primaryGroupID,cn,givenName,objectSid,sAMAccountType,dSCorePropagationData,userAccountControl,name,mail,codePage,lastLogon,logonCount,countryCode,lastLogoff,uSNChanged,pwdLastSet,distinguishedName,sAMAccountName,whenChanged,userPrincipalName,instanceType,badPwdCount,accountExpires,whenCreated,displayName,badPasswordTime,lastLogonTimestamp unused
May  2 09:54:48 mail dovecot[959]: auth: Debug: ldap(testuser1@adsample.local): Finished userdb lookup
May  2 09:54:48 mail dovecot[959]: auth: Debug: userdb out: USER#0111#011testuser1@adsample.local#011uid=1000#011gid=1000
May  2 09:54:48 mail dovecot[959]: auth: Debug: ldap(testuser2@adsample.local,192.168.122.1,<D2PcmBw0S8rAqHoB>): Finished passdb lookup
May  2 09:54:48 mail dovecot[959]: auth: Debug: auth(testuser2@adsample.local,192.168.122.1,<D2PcmBw0S8rAqHoB>): Auth request finished
May  2 09:54:48 mail dovecot[959]: auth: Debug: client passdb out: OK#0111#011user=testuser2@adsample.local#011uid=1000#011gid=1000
May  2 09:54:48 mail dovecot[1423]: lda(testuser1@adsample.local)<1423><jFPYJdgXFGiPBQAAOg3h0A>: msgid=<c923fd79-8135-46e3-aa56-afd1a1282ff8@adsample.local>: saved mail to INBOX
May  2 09:54:48 mail postfix/pipe[1422]: 7FF342020373: to=<testuser1@adsample.local>, orig_to=<testuser1@adosakana.local>, relay=dovecot, delay=0.15, delays=0.03/0.01/0/0.12, dsn=2.0.0, status=sent (delivered via dovecot service)
May  2 09:54:48 mail postfix/qmgr[884]: 7FF342020373: removed
May  2 09:54:48 mail dovecot[959]: auth: Debug: master in: REQUEST#0113980787713#0111424#0111#011d2548dbb496c7cf3c62e2637869d2d69#011session_pid=1425#011request_auth_token
May  2 09:54:48 mail dovecot[959]: auth: Debug: ldap(testuser2@adsample.local,192.168.122.1,<D2PcmBw0S8rAqHoB>): Performing userdb lookup
May  2 09:54:48 mail dovecot[959]: auth: Debug: ldap(testuser2@adsample.local,192.168.122.1,<D2PcmBw0S8rAqHoB>): user search: base=cn=Users,dc=adsample,dc=local scope=subtree filter=(userPrincipalName=testuser2@adsample.local) fields=
May  2 09:54:48 mail dovecot[959]: auth: Debug: ldap(testuser2@adsample.local,192.168.122.1,<D2PcmBw0S8rAqHoB>): result: objectClass=top,top,top,top cn=testuser2 givenName=testuser2 distinguishedName=CN=testuser2,CN=Users,DC=adsample,DC=local instanceType=4 whenCreated=20250417094639.0Z whenChanged=20250430015944.0Z displayName=testuser2 uSNCreated=12616 uSNChanged=40983 name=testuser2 objectGUID=�u&#016$|-E�Z#034\O?�#036 userAccountControl=66048 badPwdCount=0 codePage=0 countryCode=0 badPasswordTime=133893655225944004 lastLogoff=0 lastLogon=133894260848965097 pwdLastSet=133893567990887154 primaryGroupID=513 objectSid=<no values> accountExpires=9223372036854775807 logonCount=16 sAMAccountName=testuser2 sAMAccountType=805306368 userPrincipalName=testuser2@adsample.local objectCategory=CN=Person,CN=Schema,CN=Configuration,DC=adsample,DC=local dSCorePropagationData=20250418015428.0Z,20250418015428.0Z lastLogonTimestamp=133904519848472342; objectGUID,uSNCreated,objectCategory,objectClass,primaryGroupID,cn,givenName,objectSid,sAMAccountType,dSCorePropagationData,userAccountControl,name,codePage,lastLogon,logonCount,countryCode,lastLogoff,uSNChanged,pwdLastSet,distinguishedName,sAMAccountName,whenChanged,userPrincipalName,instanceType,badPwdCount,accountExpires,whenCreated,displayName,badPasswordTime,lastLogonTimestamp unused
May  2 09:54:48 mail dovecot[959]: auth: Debug: ldap(testuser2@adsample.local,192.168.122.1,<D2PcmBw0S8rAqHoB>): Finished userdb lookup
May  2 09:54:48 mail dovecot[959]: auth: Debug: master userdb out: USER#0113980787713#011testuser2@adsample.local#011uid=1000#011gid=1000#011auth_mech=PLAIN#011auth_token=68518eb1e5a886522b5dcabaae828704633386c9

missing 出力がない??

そもそも、同じログレベル出力なのに、出力された内容に差がありすぎるんですが・・・

dovecot-ldap.conf.ext に “user_attrs = =uid=1000, =gid=1000″,”pass_attrs = =uid=1000, =gid=1000” を設定するだけでいける?