]> git.ipfire.org Git - thirdparty/mlmmj.git/commitdiff
is_subbed: do not manipulate memory, prefer file descriptor
authorBaptiste Daroussin <bapt@FreeBSD.org>
Mon, 26 Dec 2022 13:56:23 +0000 (14:56 +0100)
committerBaptiste Daroussin <bapt@FreeBSD.org>
Mon, 26 Dec 2022 13:56:23 +0000 (14:56 +0100)
include/subscriberfuncs.h
src/mlmmj-unsub.c
src/subscriberfuncs.c

index 57f99cca59b9297c7feca772b2836c27e8aaff3e..36a1331c7a0c8bfc09631097ff541e5d7841e6e4 100644 (file)
 #ifndef SUBSCRIBERFUNC_H
 #define SUBSCRIBERFUNC_H
 
+#include <stdbool.h>
+
 off_t find_subscriber(int fd, const char *address);
-int is_subbed_in(const char *subddirname, const char *address);
-enum subtype is_subbed(const char *listdir, const char *address, int both);
+int is_subbed_in(int fd, const char *subddirname, const char *address);
+enum subtype is_subbed(const char *listdir, const char *address, bool both);
 
 #endif /* SUBSCRIBERFUNC_H */
index 9571d649bed6e1dab6d241f5cdd026ac5d73f375..e0ed42340ce9a3c726b0db111ccc7b7b5fac1feb 100644 (file)
@@ -24,6 +24,7 @@
 #include <stdlib.h>
 #include <stdio.h>
 #include <string.h>
+#include <sys/fcntl.h>
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <sys/mman.h>
@@ -292,7 +293,7 @@ int main(int argc, char **argv)
        int nogennotsubscribed = 0;
        int status;
        char *listaddr, *listdelim, *listdir = NULL, *address = NULL;
-       char *mlmmjsend, *bindir, *subdir, *subddirname;
+       char *mlmmjsend, *bindir, *subdir;
        enum subtype typesub = SUB_ALL;
        enum subreason reasonsub = SUB_ADMIN;
        uid_t uid;
@@ -406,23 +407,32 @@ int main(int argc, char **argv)
        }
 
        if (typesub == SUB_ALL) {
-               subbed = is_subbed(listdir, address, 0) != SUB_NONE;
+               subbed = is_subbed(listdir, address, false) != SUB_NONE;
        } else {
                switch(typesub) {
                        default:
                        case SUB_NORMAL:
-                               subdir = "/subscribers.d/";
+                               subdir = "subscribers.d";
                                break;
                        case SUB_DIGEST:
-                               subdir = "/digesters.d/";
+                               subdir = "digesters.d";
                                break;
                        case SUB_NOMAIL:
-                               subdir = "/nomailsubs.d/";
+                               subdir = "nomailsubs.d";
                                break;
                }
-               subddirname = concatstr(2, listdir, subdir);
-               subbed = is_subbed_in(subddirname, address);
-               free(subddirname);
+               int listdirfd = open(listdir, O_DIRECTORY);
+               if (listdirfd == -1) {
+                       log_error(LOG_ARGS, "Could not opendir(%s)", listdir);
+                       exit(EXIT_FAILURE);
+               }
+               int subdirfd = openat(listdirfd, subdir, O_DIRECTORY);
+               if (subdirfd == -1) {
+                       log_error(LOG_ARGS, "Could not opendir(%s/%s)", listdir, subdir);
+                       exit(EXIT_FAILURE);
+               }
+               close(listdirfd);
+               subbed = is_subbed_in(subdirfd, subdir, address);
        }
 
        if(!subbed) {
index c0c99890b36e733ebfa95aa88a922d4849ed7026..8b2499ca46a0351a9d7eb7ee8cf72804af8448aa 100644 (file)
@@ -37,7 +37,6 @@
 #include "mygetline.h"
 #include "log_error.h"
 #include "wrappers.h"
-#include "strgen.h"
 
 char *subtype_strs[] = {
        "normal",
@@ -109,16 +108,16 @@ off_t find_subscriber(int fd, const char *address)
        return (off_t)-1;
 }
 
-int is_subbed_in(const char *subddirname, const char *address)
+int
+is_subbed_in(int dirfd, const char *subdirname, const char *address)
 {
        int retval = 0, subread;
-       char *subreadname;
        off_t suboff;
        DIR *subddir;
        struct dirent *dp;
 
-       if((subddir = opendir(subddirname)) == NULL) {
-               log_error(LOG_ARGS, "Could not opendir(%s)", subddirname);
+       if((subddir = fdopendir(dirfd)) == NULL) {
+               log_error(LOG_ARGS, "Could not opendir(%s)", subdirname);
                exit(EXIT_FAILURE);
        }
 
@@ -128,17 +127,15 @@ int is_subbed_in(const char *subddirname, const char *address)
                if(!strcmp(dp->d_name, ".."))
                        continue;
 
-               subreadname = concatstr(2, subddirname, dp->d_name);
-               subread = open(subreadname, O_RDONLY);
+               subread = openat(dirfd, dp->d_name, O_RDONLY);
                if(subread < 0) {
-                       log_error(LOG_ARGS, "Could not open %s", subreadname);
-                       free(subreadname);
+                       log_error(LOG_ARGS, "Could not open %s/%s",
+                         subdirname, dp->d_name);
                        continue;
                }
 
                suboff = find_subscriber(subread, address);
                close(subread);
-               free(subreadname);
 
                if(suboff == -1) {
                        continue;
@@ -152,32 +149,32 @@ int is_subbed_in(const char *subddirname, const char *address)
        return retval;
 }
 
-enum subtype is_subbed(const char *listdir, const char *address, int both)
+enum subtype
+is_subbed(const char *listdir, const char *address, bool both)
 {
-       int retval;
-       char *subddirname;
        enum subtype typesub = SUB_NONE;
-       
-       subddirname = concatstr(2, listdir, "/subscribers.d/");
-       retval = is_subbed_in(subddirname, address);
-       free(subddirname);
-       if (retval) {
+       int fd, dirfd;
+
+       dirfd = open(listdir, O_DIRECTORY);
+       if (dirfd == -1) {
+               log_error(LOG_ARGS, "Could not opendir()");
+               exit(EXIT_FAILURE);
+       }
+       fd = openat(dirfd, "subscribers.d", O_DIRECTORY);
+       if (fd != -1 && is_subbed_in(fd, "subscribers.d", address)) {
                if (!both) return SUB_NORMAL;
                typesub = SUB_NORMAL;
        }
 
-       subddirname = concatstr(2, listdir, "/digesters.d/");
-       retval = is_subbed_in(subddirname, address);
-       free(subddirname);
-       if (retval) {
+       fd = openat(dirfd, "digesters.d", O_DIRECTORY);
+       if (fd != -1 && is_subbed_in(fd, "digesters.d", address)) {
                if (typesub == SUB_NORMAL) return SUB_BOTH;
                return SUB_DIGEST;
        }
 
-       subddirname = concatstr(2, listdir, "/nomailsubs.d/");
-       retval = is_subbed_in(subddirname, address);
-       free(subddirname);
-       if (retval) return SUB_NOMAIL;
+       fd = openat(dirfd, "nomailsubs.d", O_DIRECTORY);
+       if (fd != -1 && is_subbed_in(fd, "nomailsubs.d", address))
+               return SUB_NOMAIL;
 
        return typesub;
 }