Here is what I can gather, sorry if it looks like dirty in message body... GLOBAL_PIPELINE from Defaults.py (no mention in mm_cfg.py):
GLOBAL_PIPELINE = [ # These are the modules that do tasks common to all delivery paths. 'SpamDetect', 'Approve', 'Replybot', 'Moderate', 'Hold', 'MimeDel', 'Scrubber', 'Emergency', 'Tagger', 'CalcRecips', 'AvoidDuplicates', 'Cleanse', 'CleanseDKIM', 'CookHeaders', # And now we send the message to the digest mbox file, and to the arch and # news queues. Runners will provide further processing of the message, # specific to those delivery paths. 'ToDigest', 'ToArchive', 'ToUsenet', # Now we'll do a few extra things specific to the member delivery # (outgoing) path, finally leaving the message in the outgoing queue. 'AfterDelivery', 'Acknowledge', 'WrapMessage', 'ToOutgoing', ] Moderate.py: # Copyright (C) 2001-2008 by the Free Software Foundation, Inc. # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, # USA. """Posting moderation filter. """ import re from email.MIMEMessage import MIMEMessage from email.MIMEText import MIMEText from email.Utils import parseaddr from Mailman import mm_cfg from Mailman import Utils from Mailman import Message from Mailman import Errors from Mailman.i18n import _ from Mailman.Handlers import Hold from Mailman.Logging.Syslog import syslog from Mailman.MailList import MailList ^L class ModeratedMemberPost(Hold.ModeratedPost): # BAW: I wanted to use the reason below to differentiate between this # situation and normal ModeratedPost reasons. Greg Ward and Stonewall # Ballard thought the language was too harsh and mentioned offense taken # by some list members. I'd still like this class's reason to be # different than the base class's reason, but we'll use this until someone # can come up with something more clever but inoffensive. # # reason = _('Posts by member are currently quarantined for moderation') pass ^L def process(mlist, msg, msgdata): if msgdata.get('approved'): return # Before anything else, check DMARC if necessary. msgdata['from_is_list'] = 0 dn, addr = parseaddr(msg.get('from')) if addr and mlist.dmarc_moderation_action > 0: if Utils.IsDMARCProhibited(mlist, addr): # Note that for dmarc_moderation_action, 0 = Accept, # 1 = Munge, 2 = Wrap, 3 = Reject, 4 = Discard if mlist.dmarc_moderation_action == 1: msgdata['from_is_list'] = 1 elif mlist.dmarc_moderation_action == 2: msgdata['from_is_list'] = 2 elif mlist.dmarc_moderation_action == 3: # Reject text = mlist.dmarc_moderation_notice if text: text = Utils.wrap(text) else: text = Utils.wrap(_( """You are not allowed to post to this mailing list From: a domain which publishes a DMARC policy of reject or quarantine, and your message has been automatically rejected. If you think that your messages are being rejected in error, contact the mailing list owner at %(listowner)s.""")) raise Errors.RejectMessage, text elif mlist.dmarc_moderation_action == 4: raise Errors.DiscardMessage # Then, is the poster a member or not? for sender in msg.get_senders(): if mlist.isMember(sender): break else: sender = None if sender: # If the member's moderation flag is on, then perform the moderation # action. if mlist.getMemberOption(sender, mm_cfg.Moderate): # Note that for member_moderation_action, 0==Hold, 1=Reject, # 2==Discard if mlist.member_moderation_action == 0: # Hold. BAW: WIBNI we could add the member_moderation_notice # to the notice sent back to the sender? msgdata['sender'] = sender Hold.hold_for_approval(mlist, msg, msgdata, ModeratedMemberPost) elif mlist.member_moderation_action == 1: # Reject text = mlist.member_moderation_notice if text: text = Utils.wrap(text) else: # Use the default RejectMessage notice string text = None raise Errors.RejectMessage, text elif mlist.member_moderation_action == 2: # Discard. BAW: Again, it would be nice if we could send a # discard notice to the sender raise Errors.DiscardMessage else: assert 0, 'bad member_moderation_action' # Should we do anything explict to mark this message as getting past # this point? No, because further pipeline handlers will need to do # their own thing. return else: sender = msg.get_sender() # From here on out, we're dealing with non-members. # From here on out, we're dealing with non-members. listname = mlist.internal_name() if matches_p(sender, mlist.accept_these_nonmembers, listname): return if matches_p(sender, mlist.hold_these_nonmembers, listname): Hold.hold_for_approval(mlist, msg, msgdata, Hold.NonMemberPost) # No return if matches_p(sender, mlist.reject_these_nonmembers, listname): do_reject(mlist) # No return if matches_p(sender, mlist.discard_these_nonmembers, listname): do_discard(mlist, msg) # No return # Okay, so the sender wasn't specified explicitly by any of the non-member # moderation configuration variables. Handle by way of generic non-member # action. assert 0 <= mlist.generic_nonmember_action <= 4 if mlist.generic_nonmember_action == 0 or msgdata.get('fromusenet'): # Accept return elif mlist.generic_nonmember_action == 1: Hold.hold_for_approval(mlist, msg, msgdata, Hold.NonMemberPost) elif mlist.generic_nonmember_action == 2: do_reject(mlist) elif mlist.generic_nonmember_action == 3: do_discard(mlist, msg) ^L def matches_p(sender, nonmembers, listname): # First strip out all the regular expressions and listnames plainaddrs = [addr for addr in nonmembers if not (addr.startswith('^') or addr.startswith('@'))] addrdict = Utils.List2Dict(plainaddrs, foldcase=1) if addrdict.has_key(sender): return 1 # Now do the regular expression matches for are in nonmembers: if are.startswith('^'): try: cre = re.compile(are, re.IGNORECASE) except re.error: continue if cre.search(sender): return 1 elif are.startswith('@'): # XXX Needs to be reviewed for list@domain names. try: if are[1:] == listname: # don't reference your own list syslog('error', '*_these_nonmembers in %s references own list', listname) else: mother = MailList(are[1:], lock=0) if mother.isMember(sender): return 1 except Errors.MMUnknownListError: syslog('error', '*_these_nonmembers in %s references non-existent list %s', listname, are[1:]) return 0 ^L def do_reject(mlist): listowner = mlist.GetOwnerEmail() if mlist.nonmember_rejection_notice: raise Errors.RejectMessage, \ Utils.wrap(_(mlist.nonmember_rejection_notice)) else: raise Errors.RejectMessage, Utils.wrap(_("""\ You are not allowed to post to this mailing list, and your message has been automatically rejected. If you think that your messages are being rejected in error, contact the mailing list owner at %(listowner)s.""")) ^L def do_discard(mlist, msg): sender = msg.get_sender() # Do we forward auto-discards to the list owners? if mlist.forward_auto_discards: lang = mlist.preferred_language varhelp = '%s/?VARHELP=privacy/sender/discard_these_nonmembers' % \ mlist.GetScriptURL('admin', absolute=1) nmsg = Message.UserNotification(mlist.GetOwnerEmail(), mlist.GetBouncesEmail(), _('Auto-discard notification'), lang=lang) nmsg.set_type('multipart/mixed') text = MIMEText(Utils.wrap(_( 'The attached message has been automatically discarded.')), _charset=Utils.GetCharSet(lang)) nmsg.attach(text) nmsg.attach(MIMEMessage(msg)) nmsg.send(mlist) # Discard this sucker raise Errors.DiscardMessage IncomingRunner.py (portion containing Errors.RejectMessage): except Errors.RejectMessage, e: #mlist.BounceMessage(msg, msgdata, e) #return 0 # Log this. syslog('vette', """Message rejected, msgid: %s list: %s, handler: %s, reason: %s""", msg.get('message-id', 'n/a'), mlist.real_name, handler, e.notice()) mlist.BounceMessage(msg, msgdata, e) Christopher Puchalski Corporate IT Security chris.puchal...@raytheon.com -----Original Message----- From: Mailman-Users [mailto:mailman-users-bounces+chris.puchalski=raytheon....@python.org] On Behalf Of Mark Sapiro Sent: Thursday, January 04, 2018 1:24 PM To: mailman-users@python.org Subject: [External] Re: [Mailman-Users] Privacy Filter Unusual Behavior On 01/04/2018 08:34 AM, Chris PUCHALSKI wrote: > It is a Redhat package (mailman-2.1.12-25.el6.x86_64) so not from source. I > have the version locked because I found updates over wrote the customizations > made to the look/feel. Most of the modifications are related to hiding > options from users (to protect themselves) and cosmetic (so it fits company > look/feel). It was working up to some point a few months ago, I know because > I was doing some testing to help a list owner make a private list. I have the > version locked because I found updates over wrote the customizations made to > the look/feel. So I assume from the fact that you are not contradicting any of this: > OK. My understanding is a non-member posts to the list. The non-member gets a > rejection notice. The vette log has an entry like "Message rejected, msgid: > <message-id> ...". The message is also sent to the list member(s). The post > log has an entry like "post to <listname> from <address>, size=..., > message-id=<message-id>, success". > > <listname> is the list in question; <address> is the non-member address and > the <message-id> in the vette log and post log are the same. > > Is all this correct? that my understanding is correct. In that case, I think the issue must be due to your local changes. I can't say any more without seeing your code. Most likely, the issue is in /var/lib/mailman/Mailman/Handlers/Moderate.py. I would like to see a copy of that and also the setting for GLOBAL_PIPELINE in /var/lib/mailman/Mailman/Defaults.py and anything that references GLOBAL_PIPELINE in /var/lib/mailman/Mailman/mm_cfg.py (aka /etc/mailman/mm_cfg.py). Also, I'd like to see the entire "except Errors.RejectMessage" clause in the _dopipeline method of the IncomingRunner class in /var/lib/mailman/Mailman/Queue/IncomingRunner.py. -- Mark Sapiro <m...@msapiro.net> The highway is for gamblers, San Francisco Bay Area, California better use your sense - B. Dylan ------------------------------------------------------ Mailman-Users mailing list Mailman-Users@python.org https://mail.python.org/mailman/listinfo/mailman-users Mailman FAQ: http://wiki.list.org/x/AgA3 Security Policy: http://wiki.list.org/x/QIA9 Searchable Archives: http://www.mail-archive.com/mailman-users%40python.org/ Unsubscribe: https://mail.python.org/mailman/options/mailman-users/chris.puchalski%40raytheon.com ------------------------------------------------------ Mailman-Users mailing list Mailman-Users@python.org https://mail.python.org/mailman/listinfo/mailman-users Mailman FAQ: http://wiki.list.org/x/AgA3 Security Policy: http://wiki.list.org/x/QIA9 Searchable Archives: http://www.mail-archive.com/mailman-users%40python.org/ Unsubscribe: https://mail.python.org/mailman/options/mailman-users/archive%40jab.org