From 7540d5329188282920a071b844c355eaebb59516 Mon Sep 17 00:00:00 2001 From: Baptiste Daroussin Date: Thu, 28 Oct 2021 10:16:54 +0200 Subject: [PATCH] statctrl: use file descriptors instead of manipulating memory --- include/statctrl.h | 4 +++- src/listcontrol.c | 19 ++++++++++--------- src/mlmmj-maintd.c | 2 +- src/mlmmj-process.c | 26 +++++++++++++------------- src/mlmmj-send.c | 8 ++++---- src/mlmmj-sub.c | 6 +++--- src/mlmmj-unsub.c | 2 +- src/prepstdreply.c | 2 +- src/send_digest.c | 2 +- src/statctrl.c | 20 ++++++++++++++------ 10 files changed, 51 insertions(+), 40 deletions(-) diff --git a/include/statctrl.h b/include/statctrl.h index b48f2347..fcaf4002 100644 --- a/include/statctrl.h +++ b/include/statctrl.h @@ -24,6 +24,8 @@ #ifndef STATCTRL_H #define STATCTRL_H -int statctrl(const char *listdir, const char *ctrlstr); +#include "mlmmj.h" + +int statctrl(struct mlmmj_list *list, const char *ctrlstr); #endif /* STATCTRL_H */ diff --git a/src/listcontrol.c b/src/listcontrol.c index 8134d0d7..ff34ae02 100644 --- a/src/listcontrol.c +++ b/src/listcontrol.c @@ -1,4 +1,5 @@ /* Copyright (C) 2003 Mads Martin Joergensen + * Copyright (C) 2021 Baptiste Daroussin * * $Id$ * @@ -132,12 +133,12 @@ int listcontrol(struct email_container *fromemails, struct mlmmj_list *list, char *queuefilename; /* A closed list doesn't allow subscribtion and unsubscription */ - closedlist = statctrl(list->dir, "closedlist"); + closedlist = statctrl(list, "closedlist"); /* A closed list "sub" only dissallows subscription, not unsub. */ - closedlistsub = statctrl(list->dir, "closedlistsub"); + closedlistsub = statctrl(list, "closedlistsub"); - nosubconfirm = statctrl(list->dir, "nosubconfirm"); + nosubconfirm = statctrl(list, "nosubconfirm"); #if 0 log_error(LOG_ARGS, "controlstr = [%s]\n", controlstr); @@ -217,7 +218,7 @@ int listcontrol(struct email_container *fromemails, struct mlmmj_list *list, " Ignoring mail"); return -1; } - if (statctrl(list->dir, "nodigestsub")) { + if (statctrl(list, "nodigestsub")) { errno = 0; log_error(LOG_ARGS, "A subscribe-digest request was" " denied"); @@ -265,7 +266,7 @@ int listcontrol(struct email_container *fromemails, struct mlmmj_list *list, " Ignoring mail"); return -1; } - if (statctrl(list->dir, "nonomailsub")) { + if (statctrl(list, "nonomailsub")) { errno = 0; log_error(LOG_ARGS, "A subscribe-nomail request was" " denied"); @@ -313,7 +314,7 @@ int listcontrol(struct email_container *fromemails, struct mlmmj_list *list, " Ignoring mail"); return -1; } - if (statctrl(list->dir, "nodigestsub")) { + if (statctrl(list, "nodigestsub")) { errno = 0; log_error(LOG_ARGS, "A subscribe-both request was" " denied"); @@ -831,14 +832,14 @@ permit: /* listname+get-INDEX@domain.tld */ case CTRL_GET: - noget = statctrl(list->dir, "noget"); + noget = statctrl(list, "noget"); if(noget) { errno = 0; log_error(LOG_ARGS, "A get request was sent to a list" " with the noget option set. Ignoring mail"); return -1; } - subonlyget = statctrl(list->dir, "subonlyget"); + subonlyget = statctrl(list, "subonlyget"); if(subonlyget) { if(is_subbed(list->dir, fromemails->emaillist[0], 0) == SUB_NONE) { @@ -880,7 +881,7 @@ permit: /* listname+list@domain.tld */ case CTRL_LIST: - if(statctrl(list->dir, "nolistsubsemail")) + if(statctrl(list, "nolistsubsemail")) return -1; owner_idx = -1; owners = ctrlvalues(list->dir, "owner"); diff --git a/src/mlmmj-maintd.c b/src/mlmmj-maintd.c index f741b929..16dca9f4 100644 --- a/src/mlmmj-maintd.c +++ b/src/mlmmj-maintd.c @@ -828,7 +828,7 @@ int run_digests(struct mlmmj_list *list, const char *mlmmjsend) int fd, indexfd, lock; size_t lenbuf, lenstr; - if (statctrl(list->dir, "noarchive")) { + if (statctrl(list, "noarchive")) { return 0; } diff --git a/src/mlmmj-process.c b/src/mlmmj-process.c index a874e17e..88797a17 100644 --- a/src/mlmmj-process.c +++ b/src/mlmmj-process.c @@ -141,7 +141,7 @@ static void newmoderated(struct mlmmj_list *list, const char *mailfilename, printf("mailfilename = [%s], mailbasename = [%s]\n", mailfilename, mailbasename); #endif - if(statctrl(list->dir, "ifmodsendonlymodmoderate")) + if(statctrl(list, "ifmodsendonlymodmoderate")) efromismod = efromsender; if(!is_moderator(list->dir, efromismod, &moderators)) @@ -178,7 +178,7 @@ static void newmoderated(struct mlmmj_list *list, const char *mailfilename, /* we might need to exec more than one mlmmj-send */ - notifymod = !efromismod && statctrl(list->dir,"notifymod"); + notifymod = !efromismod && statctrl(list,"notifymod"); if (notifymod) { childpid = fork(); @@ -672,7 +672,7 @@ int main(int argc, char **argv) findaddress = 1; } - addrtocc = !(statctrl(list.dir, "tocc")); + addrtocc = !(statctrl(&list, "tocc")); if(addrtocc || findaddress) { listaddrs = ctrlvalues(list.dir, "listaddress"); @@ -840,7 +840,7 @@ int main(int argc, char **argv) if(st.st_size > maxmailsize) { - if (statctrl(list.dir, "nomaxmailsizedenymails")) { + if (statctrl(&list, "nomaxmailsizedenymails")) { errno = 0; log_error(LOG_ARGS, "Discarding %s due to" " size limit (%d bytes too big)", @@ -882,7 +882,7 @@ int main(int argc, char **argv) * discard and exit. Also don't in case of it being turned off */ if ((strcasecmp(list.addr, posteraddr) == 0) || - statctrl(list.dir, "notoccdenymails")) { + statctrl(&list, "notoccdenymails")) { log_error(LOG_ARGS, "Discarding %s because list" " address was not in To: or Cc:," " and From: was the list or" @@ -905,7 +905,7 @@ int main(int argc, char **argv) posteraddr, list.dir); if (accret == DENY) { if ((strcasecmp(list.addr, posteraddr) == 0) || - statctrl(list.dir, "noaccessdenymails")) { + statctrl(&list, "noaccessdenymails")) { log_error(LOG_ARGS, "Discarding %s because" " it was denied by an access" " rule, and From: was the list" @@ -942,9 +942,9 @@ int main(int argc, char **argv) } } - subonlypost = statctrl(list.dir, "subonlypost"); - modonlypost = statctrl(list.dir, "modonlypost"); - modnonsubposts = statctrl(list.dir, "modnonsubposts"); + subonlypost = statctrl(&list, "subonlypost"); + modonlypost = statctrl(&list, "modonlypost"); + modnonsubposts = statctrl(&list, "modnonsubposts"); /* modnonsubposts implies subonlypost if modonlypost is not set */ if (modnonsubposts && !modonlypost) subonlypost = 1; @@ -975,9 +975,9 @@ int main(int argc, char **argv) modreason = MODNONMODPOSTS; } else { if((subonlypost && - statctrl(list.dir, "nosubonlydenymails")) || + statctrl(&list, "nosubonlydenymails")) || (modonlypost && - statctrl(list.dir, "nomodonlydenymails"))) { + statctrl(&list, "nomodonlydenymails"))) { log_error(LOG_ARGS, "Discarding %s because" " no{sub|mod}onlydenymails was set", mailfile); @@ -999,13 +999,13 @@ int main(int argc, char **argv) } if(!send && !moderated) { - if(statctrl(list.dir, "moderated")) { + if(statctrl(&list, "moderated")) { moderated = 1; modreason = MODERATED; } } - notmetoo = statctrl(list.dir, "notmetoo"); + notmetoo = statctrl(&list, "notmetoo"); if(moderated) { mqueuename = concatstr(3, list.dir, "/moderation/", diff --git a/src/mlmmj-send.c b/src/mlmmj-send.c index 617ad486..c34c751f 100644 --- a/src/mlmmj-send.c +++ b/src/mlmmj-send.c @@ -925,7 +925,7 @@ int main(int argc, char **argv) verp = ctrlvalue(list.dir, "verp"); if(verp == NULL) - if(statctrl(list.dir, "verp") == 1) + if(statctrl(&list, "verp") == 1) verp = mystrdup(""); maxverprecipsstr = ctrlvalue(list.dir, "maxverprecips"); @@ -972,7 +972,7 @@ int main(int argc, char **argv) } memmailsizestr = ctrlvalue(list.dir, "memorymailsize"); - ctrlarchive = statctrl(list.dir, "noarchive"); + ctrlarchive = statctrl(&list, "noarchive"); if(memmailsizestr) { memmailsize = strtol(memmailsizestr, NULL, 10); myfree(memmailsizestr); @@ -1029,7 +1029,7 @@ int main(int argc, char **argv) } break; case '3': - addtohdr = statctrl(list.dir, "addtohdr"); + addtohdr = statctrl(&list, "addtohdr"); case '4': /* sending mails to subfile */ if((subfd = open(subfilename, O_RDONLY)) < 0) { log_error(LOG_ARGS, "Could not open '%s':", @@ -1046,7 +1046,7 @@ int main(int argc, char **argv) bounceaddr = bounce_from_adr(to_addr, archivefilename, &list); break; default: /* normal list mail -- now handled when forking */ - addtohdr = statctrl(list.dir, "addtohdr"); + addtohdr = statctrl(&list, "addtohdr"); break; } diff --git a/src/mlmmj-sub.c b/src/mlmmj-sub.c index 0e2b03c6..67e381f9 100644 --- a/src/mlmmj-sub.c +++ b/src/mlmmj-sub.c @@ -158,7 +158,7 @@ static void moderate_sub(struct mlmmj_list *list, const char *subaddr, /* we might need to exec more than one mlmmj-send */ - nosubmodmails = statctrl(list->dir,"nosubmodmails"); + nosubmodmails = statctrl(list,"nosubmodmails"); if (nosubmodmails) childpid = -1; @@ -793,7 +793,7 @@ int main(int argc, char **argv) address, mlmmjsend, typesub, reasonsub); if(modstr == NULL && subbed == SUB_NONE && !force && - statctrl(list.dir, "submod")) { + statctrl(&list, "submod")) { moderate_sub(&list, address, mlmmjsend, typesub, reasonsub); } @@ -834,7 +834,7 @@ int main(int argc, char **argv) } notifysub = !quiet && reasonsub != SUB_SWITCH && - statctrl(list.dir, "notifysub"); + statctrl(&list, "notifysub"); /* Notify list owner about subscription */ if (notifysub) diff --git a/src/mlmmj-unsub.c b/src/mlmmj-unsub.c index 7841d177..33cb1782 100644 --- a/src/mlmmj-unsub.c +++ b/src/mlmmj-unsub.c @@ -685,7 +685,7 @@ int main(int argc, char **argv) typesub, reasonsub); } - notifysub = !quiet && statctrl(list.dir, "notifysub"); + notifysub = !quiet && statctrl(&list, "notifysub"); /* Notify list owner about subscription */ if (notifysub) diff --git a/src/prepstdreply.c b/src/prepstdreply.c index c0e4e6b7..15f09a22 100644 --- a/src/prepstdreply.c +++ b/src/prepstdreply.c @@ -760,7 +760,7 @@ static int handle_conditional(text *txt, char **line_p, char **pos_p, if (strcasecmp(token, txt->type) == 0) matches = 1; } else if (tgt == CONTROL) { - if (statctrl(list->dir, token)) + if (statctrl(list, token)) matches = 1; } if ((matches && !neg) || (!matches && neg)) { diff --git a/src/send_digest.c b/src/send_digest.c index c941d0ab..8e52161d 100644 --- a/src/send_digest.c +++ b/src/send_digest.c @@ -401,7 +401,7 @@ errdighdrs: return -1; } - if ((txt != NULL) && !statctrl(list->dir, "nodigesttext")) { + if ((txt != NULL) && !statctrl(list, "nodigesttext")) { tmp = concatstr(3, "\n--", boundary, "\nContent-Type: text/plain; charset=UTF-8" diff --git a/src/statctrl.c b/src/statctrl.c index c07625e4..b6f578db 100644 --- a/src/statctrl.c +++ b/src/statctrl.c @@ -1,4 +1,5 @@ /* Copyright (C) 2004 Mads Martin Joergensen + * Copyright (C) 2021 Baptiste Daroussin * * $Id$ * @@ -23,22 +24,29 @@ #include #include +#include #include #include +#include -#include "strgen.h" +#include "mlmmj.h" #include "statctrl.h" #include "log_error.h" -int statctrl(const char *listdir, const char *ctrlstr) +int statctrl(struct mlmmj_list *list, const char *ctrlstr) { - char *filename = concatstr(3, listdir, "/control/", ctrlstr); - - if (access(filename, F_OK) == -1) { + if (list->controlfd == -1) + list->controlfd = openat(list->fd, "control", O_DIRECTORY|O_CLOEXEC); + if (list->controlfd == -1) { + log_error(LOG_ARGS, "Unable to open %s/control", list->dir); + errx(EXIT_FAILURE, "Unable to open %s/control", list->dir); + } + + if (faccessat(list->controlfd, ctrlstr, F_OK, 0) == -1) { if(errno == ENOENT) return 0; log_error(LOG_ARGS, "Could not stat %s/control/%s. " - "Bailing out.", listdir, ctrlstr); + "Bailing out.", list->dir, ctrlstr); exit(EXIT_FAILURE); } -- 2.47.3