]> git.ipfire.org Git - thirdparty/mlmmj.git/commitdiff
Add rejection of posts and obstruction of subscriptions.
authorBen Schmidt <none@none>
Mon, 23 Jan 2012 06:02:18 +0000 (17:02 +1100)
committerBen Schmidt <none@none>
Mon, 23 Jan 2012 06:02:18 +0000 (17:02 +1100)
ChangeLog
man/mlmmj-sub.1
src/listcontrol.c
src/mlmmj-process.c
src/mlmmj-sub.c

index 6b926686b719c8d55160a9222a5766e01bd079de..ab168b5950e13181708776630a0eaaac77170f39 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,4 @@
+ o Add rejection of posts and obstruction of subscriptions.
  o Avoid bogus error messages when logging that the list address has been
    found in To: or CC: headers.
  o Escape dashes in man pages.
index c958ac5f5b6d6fb4d044dced9e85d9276261b9f7..5c7fb7415d182beb498ec998464927d2569e92c4 100644 (file)
@@ -20,7 +20,7 @@ mlmmj-sub \- subscribe address to a mailinglist run by mlmmj
 .HP
 \fB\-L\fR: Full path to list directory
 .HP
-\fB\-m\fR: Subscriber moderation string
+\fB\-m\fR: Moderation string
 .HP
 \fB\-n\fR: Subscribe to nomail version of the list
 .HP
index 931dab189732710c77b7a6bc03b9b2a67165f7d9..52f57283952359e04667b415f1fd9a75a8dd890b 100644 (file)
@@ -62,6 +62,10 @@ enum ctrl_e {
        CTRL_CONFUNSUB_NOMAIL,
        CTRL_CONFUNSUB,
        CTRL_BOUNCES,
+       CTRL_RELEASE,
+       CTRL_REJECT,
+       CTRL_PERMIT,
+       CTRL_OBSTRUCT,
        CTRL_MODERATE,
        CTRL_HELP,
        CTRL_FAQ,
@@ -92,6 +96,10 @@ static struct ctrl_command ctrl_commands[] = {
        { "confunsub-nomail",   1 },
        { "confunsub",          1 },
        { "bounces",            1 },
+       { "release",            1 },
+       { "reject",             1 },
+       { "permit",             1 },
+       { "obstruct",           1 },
        { "moderate",           1 },
        { "help",               0 },
        { "faq",                0 },
@@ -106,7 +114,8 @@ int listcontrol(struct email_container *fromemails, const char *listdir,
                const char *mlmmjbounce, const char *mailname)
 {
        char *bouncenr, *tmpstr;
-       char *param = NULL, *conffilename, *moderatefilename, *omitfilename;
+       char *param = NULL, *conffilename, *moderatefilename, *gatekeepfilename;
+       char *omitfilename;
        char *omit = NULL;
        char *c, *archivefilename, *sendfilename;
        const char *subswitch;
@@ -612,31 +621,31 @@ int listcontrol(struct email_container *fromemails, const char *listdir,
                exit(EXIT_FAILURE);
                break;
 
-       /* listname+moderate-COOKIE@domain.tld */
+       /* listname+release-COOKIE@domain.tld */
+       case CTRL_RELEASE:
+       /* DEPRECATED: listname+moderate-COOKIE@domain.tld */
+       /* DEPRECATED: listname+moderate-subscribeCOOKIE@domain.tld */
        case CTRL_MODERATE:
-               /* TODO Add accept/reject parameter to moderate */
-               moderatefilename = concatstr(3, listdir, "/moderation/", param);
-
-               /* Subscriber moderation */
+               /* Subscriber moderation; DEPRECATED */
                if(strncmp(param, "subscribe", 9) == 0) {
-                       log_oper(listdir, OPLOGFNAME, "%s moderated %s",
-                               fromemails->emaillist[0], moderatefilename);
-                       execlp(mlmmjsub, mlmmjsub,
-                                       "-L", listdir,
-                                       "-m", param,
-                                       "-c", (char *)NULL);
+                       tmpstr = mystrdup(param + 9);
+                       myfree(param);
+                       param = tmpstr;
+                       goto permit;
                }
 
-               sendfilename = concatstr(2, moderatefilename, ".sending");
+               moderatefilename = concatstr(3, listdir, "/moderation/", param);
                if(stat(moderatefilename, &stbuf) < 0) {
                        myfree(moderatefilename);
                        /* no mail to moderate */
                        errno = 0;
-                       log_error(LOG_ARGS, "A moderate request was"
+                       log_error(LOG_ARGS, "A release request was"
                                " sent with a mismatching cookie."
                                " Ignoring mail");
                        return -1;
                }
+
+               sendfilename = concatstr(2, moderatefilename, ".sending");
                /* Rename it to avoid mail being sent twice */
                if(rename(moderatefilename, sendfilename) < 0) {
                        log_error(LOG_ARGS, "Could not rename to .sending");
@@ -658,9 +667,11 @@ int listcontrol(struct email_container *fromemails, const char *listdir,
                        myfree(omitfilename);
                }
 
-               log_oper(listdir, OPLOGFNAME, "%s moderated %s",
-                               fromemails->emaillist[0], moderatefilename);
                myfree(moderatefilename);
+
+               log_oper(listdir, OPLOGFNAME, "%s released %s",
+                               fromemails->emaillist[0], param);
+
                if (omit != NULL)
                        execlp(mlmmjsend, mlmmjsend,
                                        "-L", listdir,
@@ -675,6 +686,80 @@ int listcontrol(struct email_container *fromemails, const char *listdir,
                exit(EXIT_FAILURE);
                break;
 
+       /* listname+reject-COOKIE@domain.tld */
+       case CTRL_REJECT:
+               moderatefilename = concatstr(3, listdir, "/moderation/", param);
+               if(stat(moderatefilename, &stbuf) < 0) {
+                       myfree(moderatefilename);
+                       /* no mail to moderate */
+                       errno = 0;
+                       log_error(LOG_ARGS, "A reject request was"
+                               " sent with a mismatching cookie."
+                               " Ignoring mail");
+                       return -1;
+               }
+               log_oper(listdir, OPLOGFNAME, "%s rejected %s",
+                       fromemails->emaillist[0], param);
+               myfree(param);
+               if (unlink(moderatefilename) != 0) {
+                       log_error(LOG_ARGS, "Could not unlink %s",
+                                       moderatefilename);
+                       myfree(moderatefilename);
+                       exit(EXIT_FAILURE);
+               }
+               myfree(moderatefilename);
+               break;
+
+       /* listname+permit-COOKIE@domain.tld */
+       case CTRL_PERMIT:
+permit:
+               gatekeepfilename = concatstr(3, listdir,
+                               "/moderation/subscribe", param);
+               if(stat(gatekeepfilename, &stbuf) < 0) {
+                       myfree(gatekeepfilename);
+                       /* no mail to moderate */
+                       errno = 0;
+                       log_error(LOG_ARGS, "A permit request was"
+                               " sent with a mismatching cookie."
+                               " Ignoring mail");
+                       return -1;
+               }
+               log_oper(listdir, OPLOGFNAME, "%s permitted %s",
+                       fromemails->emaillist[0], param);
+               execlp(mlmmjsub, mlmmjsub,
+                               "-L", listdir,
+                               "-m", param,
+                               "-c", (char *)NULL);
+               log_error(LOG_ARGS, "execlp() of '%s' failed",
+                                       mlmmjsub);
+               exit(EXIT_FAILURE);
+               break;
+
+       /* listname+obstruct-COOKIE@domain.tld */
+       case CTRL_OBSTRUCT:
+               gatekeepfilename = concatstr(3, listdir,
+                               "/moderation/subscribe", param);
+               if(stat(gatekeepfilename, &stbuf) < 0) {
+                       myfree(gatekeepfilename);
+                       /* no mail to moderate */
+                       errno = 0;
+                       log_error(LOG_ARGS, "An obstruct request was"
+                               " sent with a mismatching cookie."
+                               " Ignoring mail");
+                       return -1;
+               }
+               log_oper(listdir, OPLOGFNAME, "%s obstructed %s",
+                       fromemails->emaillist[0], param);
+               myfree(param);
+               if (unlink(gatekeepfilename) != 0) {
+                       log_error(LOG_ARGS, "Could not unlink %s",
+                                       gatekeepfilename);
+                       myfree(gatekeepfilename);
+                       exit(EXIT_FAILURE);
+               }
+               myfree(gatekeepfilename);
+               break;
+
        /* listname+help@domain.tld */
        case CTRL_HELP:
                if(!strchr(fromemails->emaillist[0], '@')) {
index 5a45ece69793b07b9b24c2b0e186adc3f7ba1739..a8894c9bf4e4f7a8c99ac787c8ccbd6845cf76ec 100644 (file)
@@ -96,7 +96,7 @@ static void newmoderated(const char *listdir, const char *mailfilename,
        text *txt;
        memory_lines_state *mls;
        char *queuefilename = NULL, *moderatorsfilename, *efromismod = NULL;
-       char *mailbasename = mybasename(mailfilename), *tmp, *to;
+       char *mailbasename = mybasename(mailfilename), *tmp, *to, *reject;
        int moderatorsfd, foundaddr = 0, notifymod = 0, status;
        pid_t childpid, pid;
 #if 0
@@ -138,7 +138,9 @@ static void newmoderated(const char *listdir, const char *mailfilename,
        myfree(moderators);
 
        listdelim = getlistdelim(listdir);
-       replyto = concatstr(6, listname, listdelim, "moderate-", mailbasename,
+       replyto = concatstr(6, listname, listdelim, "release-", mailbasename,
+                           "@", listfqdn);
+       reject = concatstr(6, listname, listdelim, "reject-", mailbasename,
                            "@", listfqdn);
 
        from = concatstr(4, listname, listdelim, "owner@", listfqdn);
@@ -155,6 +157,7 @@ static void newmoderated(const char *listdir, const char *mailfilename,
        register_unformatted(txt, "posteraddr", posteraddr);
        register_unformatted(txt, "moderateaddr", replyto); /* DEPRECATED */
        register_unformatted(txt, "releaseaddr", replyto);
+       register_unformatted(txt, "rejectaddr", reject);
        register_unformatted(txt, "moderators", "%moderators%"); /* DEPRECATED */
        register_formatted(txt, "moderators",
                        rewind_memory_lines, get_memory_line, mls);
index 811db7a13bea5486257b42bf50227d8459461705..506b7d4db2e1e29ccd1a41fdde96879d5c78a849 100644 (file)
@@ -74,8 +74,8 @@ void moderate_sub(const char *listdir, const char *listaddr,
        text *txt;
        memory_lines_state *mls;
        char *a = NULL, *queuefilename, *from, *listname, *listfqdn, *str;
-       char *modfilename, *randomstr, *mods, *to, *replyto, *moderators = NULL;
-       char *modfilebase;
+       char *modfilename, *mods, *to, *replyto, *moderators = NULL;
+       char *cookie, *obstruct;
        struct strlist *submods;
        pid_t childpid, pid;
 
@@ -93,25 +93,24 @@ void moderate_sub(const char *listdir, const char *listaddr,
                        break;
        }
        
-       randomstr = random_str();
-       modfilename = concatstr(3, listdir, "/moderation/subscribe",
-                       randomstr);
-       myfree(randomstr);
-
-       fd = open(modfilename, O_RDWR|O_CREAT|O_EXCL, S_IRUSR|S_IWUSR);
-       while(fd < 0 && errno == EEXIST) {
-               myfree(modfilename);
-               randomstr = random_str();
+       for (;;) {
+               cookie = random_str();
                modfilename = concatstr(3, listdir, "/moderation/subscribe",
-                               randomstr);
-               myfree(randomstr);
+                               cookie);
                fd = open(modfilename, O_RDWR|O_CREAT|O_EXCL, S_IRUSR|S_IWUSR);
+               if (fd < 0) {
+                       if (errno == EEXIST) {
+                               myfree(cookie);
+                               myfree(modfilename);
+                               continue;
+                       }
+                       log_error(LOG_ARGS, "could not create %s"
+                                       "ignoring request: %s", str);
+                       exit(EXIT_FAILURE);
+               }
+               break;
        }
-       if(fd < 0) {
-               log_error(LOG_ARGS, "could not create %s"
-                               "ignoring request: %s", str);
-               exit(EXIT_FAILURE);
-       }
+
        if(writen(fd, str, strlen(str)) < 0) {
                log_error(LOG_ARGS, "could not write to %s"
                                "ignoring request: %s", str);
@@ -144,13 +143,14 @@ void moderate_sub(const char *listdir, const char *listaddr,
        listdelim = getlistdelim(listdir);
        listfqdn = genlistfqdn(listaddr);
        listname = genlistname(listaddr);
-       modfilebase = mybasename(modfilename);
 
        from = concatstr(4, listname, listdelim, "owner@", listfqdn);
        to = concatstr(3, listname, "-moderators@", listfqdn);
-       replyto = concatstr(6, listname, listdelim, "moderate-", modfilebase,
+       replyto = concatstr(6, listname, listdelim, "permit-", cookie,
                        "@", listfqdn);
-       myfree(modfilebase);
+       obstruct = concatstr(6, listname, listdelim, "obstruct-", cookie,
+                       "@", listfqdn);
+       myfree(cookie);
        for(i = 0; i < submods->count; i++) {
                printf("%s", submods->strs[i]);
                str = moderators;
@@ -166,7 +166,8 @@ void moderate_sub(const char *listdir, const char *listaddr,
        register_unformatted(txt, "subaddr", subaddr);
        register_unformatted(txt, "moderateaddr", replyto); /* DEPRECATED */
        register_unformatted(txt, "permitaddr", replyto);
-       register_unformatted(txt, "moderators", "%gatekeepers"); /* DEPRECATED */
+       register_unformatted(txt, "obstructaddr", obstruct);
+       register_unformatted(txt, "moderators", "%gatekeepers%"); /* DEPRECATED */
        register_formatted(txt, "gatekeepers",
                        rewind_memory_lines, get_memory_line, mls);
        queuefilename = prepstdreply(txt, listdir, "$listowner$", to, replyto);
@@ -241,8 +242,11 @@ void getaddrandtype(const char *listdir, const char *modstr,
 {
        int fd;
        char *readaddr, *readtype, *modfilename;
-               
-       modfilename = concatstr(3, listdir, "/moderation/", modstr);
+
+       if (strncmp(modstr, "subscribe", 9) == 0)
+                       modstr += 9;
+
+       modfilename = concatstr(3, listdir, "/moderation/subscribe", modstr);
 
        fd = open(modfilename, O_RDONLY);
        if(fd < 0) {