# HG changeset patch # User Ben Schmidt # Date 1327338504 -39600 # Node ID c6fe438f3e601d230b3b4f10822a71443401b9f9 # Parent fabf3a96132ffc985e63fa47690f46aa7ae48637 Fix access logic so subonlypost doesn't override a send access rule. diff -r fabf3a96132f -r c6fe438f3e60 ChangeLog --- a/ChangeLog Tue Jan 24 15:43:53 2012 +1100 +++ b/ChangeLog Tue Jan 24 04:08:24 2012 +1100 @@ -1,3 +1,4 @@ + o Fix access logic so subonlypost doesn't override a send access rule. o Make +unsubscribe remove the requester from all versions of the list. o Make mlmmj-unsub default to removing the requester from all versions of the list. diff -r fabf3a96132f -r c6fe438f3e60 README.access --- a/README.access Tue Jan 24 15:43:53 2012 +1100 +++ b/README.access Tue Jan 24 04:08:24 2012 +1100 @@ -28,7 +28,7 @@ rules. The action "send" will send the mail unconditionally. It will not be -moderated. +moderated, nor subject to subonlypost, nor modnonsubposts. The action "deny" will not send the mail to the mailing list, but will send a rejection mail to the sender. @@ -42,7 +42,7 @@ function as moderators in listdir/control/moderators -The flow through the access system is like this: +The flow through the access system is something like this: deny +------+ +----------------->| deny | @@ -58,12 +58,15 @@ +--------+ +------+ confirm +------+ | | ^ ^ ^ | | | yes | | - | | allow +------------+ no | | - | +-------------->| moderation |-------+ | - | +------------+ | + | | allow +--------------+ no | | + | +-------------->| moderation * |-----+ | + | +--------------+ | | send | +------------------------------------------+ +* modnonsubposts is also processed here, and subonlypost (the flow + may be to deny or discard for subonlypost without modnonsubposts). + First a simple example. This rule set will reject any mail that is NOT plain text, or has a subject that contains "BayStar", and allow anything else: diff -r fabf3a96132f -r c6fe438f3e60 TUNABLES --- a/TUNABLES Tue Jan 24 15:43:53 2012 +1100 +++ b/TUNABLES Tue Jan 24 04:08:24 2012 +1100 @@ -47,8 +47,8 @@ · modnonsubposts (boolean) - When this file is present and subonlypost is enabled, all postings from - people who are not subscribed to the list will be moderated. + When this file is present, all postings from people who are not subscribed + to the list will be moderated. · prefix (normal) diff -r fabf3a96132f -r c6fe438f3e60 src/mlmmj-process.c --- a/src/mlmmj-process.c Tue Jan 24 15:43:53 2012 +1100 +++ b/src/mlmmj-process.c Tue Jan 24 04:08:24 2012 +1100 @@ -416,13 +416,11 @@ int main(int argc, char **argv) { - int i, j, opt, noprocess = 0, moderated = 0; + int i, j, opt, noprocess = 0, moderated = 0, send = 0; enum modreason modreason; int hdrfd, footfd, rawmailfd, donemailfd, omitfd; - int subonlypost = 0, addrtocc = 1, intocc = 0, modnonsubposts = 0; + int addrtocc = 1, intocc = 0; int maxmailsize = 0; - int notoccdenymails = 0, noaccessdenymails = 0, nosubonlydenymails = 0; - int nomaxmailsizedenymails = 0; int notmetoo = 0; char *listdir = NULL, *mailfile = NULL, *headerfilename = NULL; char *footerfilename = NULL, *donemailname = NULL; @@ -751,8 +749,7 @@ if(st.st_size > maxmailsize) { - nomaxmailsizedenymails = statctrl(listdir, "nomaxmailsizedenymails"); - if (nomaxmailsizedenymails) { + if (statctrl(listdir, "nomaxmailsizedenymails")) { errno = 0; log_error(LOG_ARGS, "Discarding %s due to" " size limit (%d bytes too big)", @@ -849,14 +846,12 @@ for(i = 0; i < alternates->count; i++) myfree(alternates->strs[i]); - notoccdenymails = statctrl(listdir, "notoccdenymails"); - if(addrtocc && !intocc) { /* Don't send a mail about denial to the list, but silently * discard and exit. Also don't in case of it being turned off */ if ((strcasecmp(listaddr, posteraddr) == 0) || - notoccdenymails) { + statctrl(listdir, "notoccdenymails")) { log_error(LOG_ARGS, "Discarding %s because list" " address was not in To: or Cc:," " and From: was the list or" @@ -898,85 +893,6 @@ exit(EXIT_FAILURE); } - subonlypost = statctrl(listdir, "subonlypost"); - if(subonlypost) { - /* Don't send a mail about denial to the list, but silently - * discard and exit. */ - if (strcasecmp(listaddr, posteraddr) == 0) { - log_error(LOG_ARGS, "Discarding %s because" - " subonlypost was set and From: was" - " the list address", - mailfile); - myfree(listaddr); - unlink(donemailname); - myfree(donemailname); - exit(EXIT_SUCCESS); - } - if(is_subbed(listdir, posteraddr) == SUB_NONE) { - modnonsubposts = statctrl(listdir, - "modnonsubposts"); - if(modnonsubposts) { - moderated = 1; - modreason = MODNONSUBPOSTS; - goto startaccess; - } - - nosubonlydenymails = statctrl(listdir, - "nosubonlydenymails"); - - if(nosubonlydenymails) { - log_error(LOG_ARGS, "Discarding %s because" - " subonlypost and" - " nosubonlydenymails was set", - mailfile); - myfree(listaddr); - unlink(donemailname); - myfree(donemailname); - exit(EXIT_SUCCESS); - } - listdelim = getlistdelim(listdir); - listname = genlistname(listaddr); - listfqdn = genlistfqdn(listaddr); - fromaddr = concatstr(4, listname, listdelim, - "bounces-help@", listfqdn); - txt = open_text(listdir, "deny", "post", - "subonlypost", NULL, "subonlypost"); - MY_ASSERT(txt); - register_unformatted(txt, "subject", subject); - register_unformatted(txt, "posteraddr", posteraddr); - register_originalmail(txt, donemailname); - queuefilename = prepstdreply(txt, listdir, - "$listowner$", posteraddr, NULL); - MY_ASSERT(queuefilename) - close_text(txt); - myfree(listaddr); - myfree(listdelim); - myfree(listname); - myfree(listfqdn); - unlink(donemailname); - myfree(donemailname); - execlp(mlmmjsend, mlmmjsend, - "-l", "1", - "-T", posteraddr, - "-F", fromaddr, - "-m", queuefilename, (char *)NULL); - - log_error(LOG_ARGS, "execlp() of '%s' failed", mlmmjsend); - exit(EXIT_FAILURE); - } - } - -startaccess: - - if(!moderated) { - if(statctrl(listdir, "moderated")) { - moderated = 1; - modreason = MODERATED; - } - } - - noaccessdenymails = statctrl(listdir, "noaccessdenymails"); - access_rules = ctrlvalues(listdir, "access"); if (access_rules) { enum action accret; @@ -986,7 +902,7 @@ posteraddr, listdir); if (accret == DENY) { if ((strcasecmp(listaddr, posteraddr) == 0) || - noaccessdenymails) { + statctrl(listdir, "noaccessdenymails")) { log_error(LOG_ARGS, "Discarding %s because" " it was denied by an access" " rule, and From: was the list" @@ -1048,12 +964,81 @@ myfree(discardname); exit(EXIT_SUCCESS); } else if (accret == SEND) { - moderated = 0; + send = 1; } else if (accret == ALLOW) { /* continue processing as normal */ } } + if(!send && (statctrl(listdir, "subonlypost") || + statctrl(listdir, "modnonsubposts"))) { + /* Don't send a mail about denial to the list, but silently + * discard and exit. */ + if (strcasecmp(listaddr, posteraddr) == 0) { + log_error(LOG_ARGS, "Discarding %s because" + " subonlypost was set and From: was" + " the list address", + mailfile); + myfree(listaddr); + unlink(donemailname); + myfree(donemailname); + exit(EXIT_SUCCESS); + } + if(is_subbed(listdir, posteraddr) == SUB_NONE) { + if(statctrl(listdir, "modnonsubposts")) { + moderated = 1; + modreason = MODNONSUBPOSTS; + } else { + if(statctrl(listdir, "nosubonlydenymails")) { + log_error(LOG_ARGS, "Discarding %s because" + " subonlypost and" + " nosubonlydenymails was set", + mailfile); + myfree(listaddr); + unlink(donemailname); + myfree(donemailname); + exit(EXIT_SUCCESS); + } + listdelim = getlistdelim(listdir); + listname = genlistname(listaddr); + listfqdn = genlistfqdn(listaddr); + fromaddr = concatstr(4, listname, listdelim, + "bounces-help@", listfqdn); + txt = open_text(listdir, "deny", "post", + "subonlypost", NULL, "subonlypost"); + MY_ASSERT(txt); + register_unformatted(txt, "subject", subject); + register_unformatted(txt, "posteraddr", posteraddr); + register_originalmail(txt, donemailname); + queuefilename = prepstdreply(txt, listdir, + "$listowner$", posteraddr, NULL); + MY_ASSERT(queuefilename) + close_text(txt); + myfree(listaddr); + myfree(listdelim); + myfree(listname); + myfree(listfqdn); + unlink(donemailname); + myfree(donemailname); + execlp(mlmmjsend, mlmmjsend, + "-l", "1", + "-T", posteraddr, + "-F", fromaddr, + "-m", queuefilename, (char *)NULL); + + log_error(LOG_ARGS, "execlp() of '%s' failed", mlmmjsend); + exit(EXIT_FAILURE); + } + } + } + + if(!send && !moderated) { + if(statctrl(listdir, "moderated")) { + moderated = 1; + modreason = MODERATED; + } + } + notmetoo = statctrl(listdir, "notmetoo"); if(moderated) {