0

sendmailメーリングリスト(つまり:include:、エイリアスファイルのディレクティブのターゲットになり得るテキストファイル)を取得し、それらを解析して受信者のリストを生成できるツールを探しています。もちろん、ファイルには、コメント、実際のアドレスに加えて「説明的な」名前の受信者、外部アドレスとローカルユーザーおよびその他のエイリアスの混合などを含めることができます。

この解析を行うためのツール、または自分で作成できる正式な仕様のいずれかが存在しますか?それとも、バグが含まれていることがほぼ確実なアドホックなものを作成する必要がありますか?

作業中のサーバーへのrootアクセス権がないため、sendmail -bv機能しません。(もちろん、実際のセットアップとは関係なくユーティリティとして使用する必要がある場合は、いつでも自分のインストールをセットアップできます。)sendmail -bt動作しているように見えますが、使用方法が完全にはわかりません。

4

1 に答える 1

0

これが、この問題を解決するために最終的に使用したPythonコードです。私とは異なる構成のサーバーで動作するように調整する必要があります。

import os
import re
import subprocess

def find_recipients(usernames):
    recipients = {'local': set(), 'external': set(), 'missing_local': set(),
                  'file': set(), 'program': set(), 'error_messages': set()}
    visited_lists = set()
    sendmail = subprocess.Popen(('sendmail', '-bt'), stdin=subprocess.PIPE,
                                stdout=subprocess.PIPE)
    def handle_local_user(username):
        username = username.lower()
        list_path = '/shared/aliases/' + username
        if os.path.isfile(list_path):
            visit_list(list_path)
        elif os.path.isdir('/home/' + username):
            recipients['local'].add(username)
        else:
            recipients['missing_local'].add(username)
    def visit_list(list_path):
        if list_path not in visited_lists:
            visited_lists.add(list_path)
            with open(list_path, 'r') as ml_file:
                for ml_line in ml_file:
                    if not re.match(r'^\s*(#.*)?$', ml_line):
                        if not ml_line.endswith('\n'):
                            ml_line += '\n'
                        sendmail.stdin.write('/parse ' + ml_line)
                        sendmail.stdin.flush()
                        match = None
                        while match is None:
                            match = re.match(r'^mailer ([^,]*), (.*)\n$',
                                             sendmail.stdout.readline())
                        mailer, recipient_info = match.groups()
                        if mailer == 'local':
                            handle_local_user(
                                re.match(r'^user (.+)$',
                                         recipient_info).group(1))
                        elif mailer == 'relay':
                            user, at, domain = re.match(
                                r'^host smtp\.mydomain\.org, user (.*)$',
                                recipient_info).group(1).partition('@')
                            domain = domain.lower()
                            if domain == 'mydomain.org':
                                handle_local_user(user)
                            else:
                                recipients['external'].add(user + at + domain)
                        elif mailer == '*file*':
                            recipients['file'].add(
                                re.match(r'^user (.+)$',
                                         recipient_info).group(1))
                        elif mailer == 'prog':
                            recipients['program'].add(
                                re.match(r'^user (.+)$',
                                         recipient_info).group(1))
                        elif mailer == '*include*':
                            visit_list(re.match(r'^user (.+)$',
                                                recipient_info).group(1))
                        elif mailer == '*error*':
                            raise RuntimeError('address parsing error: ' +
                                               recipient_info)
                        else:
                            raise RuntimeError('unrecognized mailer: ' +
                                               mailer)
    for un in usernames:
        handle_local_user(un)
    sendmail.communicate('/quit')
    return recipients
于 2013-02-06T01:56:15.630 に答える