X-Git-Url: https://git.exim.org/exim.git/blobdiff_plain/20395676aba7fa5eb9a2c5e0b9f582ec2b3e71e4..1d28cc061677bd07d9bed48dd84bd5c590247043:/src/src/transports/appendfile.c diff --git a/src/src/transports/appendfile.c b/src/src/transports/appendfile.c index 5d957b62e..c39c07c9f 100644 --- a/src/src/transports/appendfile.c +++ b/src/src/transports/appendfile.c @@ -2,9 +2,10 @@ * Exim - an Internet mail transport agent * *************************************************/ +/* Copyright (c) The Exim maintainers 2020 - 2022 */ /* Copyright (c) University of Cambridge 1995 - 2020 */ -/* Copyright (c) The Exim maintainers 2020 */ /* See the file NOTICE for conditions of use and distribution. */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ #include "../exim.h" @@ -174,9 +175,6 @@ Arguments: Returns: OK, FAIL, or DEFER */ -void -open_logs(void); - static int appendfile_transport_setup(transport_instance *tblock, address_item *addrlist, transport_feedback *dummy, uid_t uid, gid_t gid, uschar **errmsg) @@ -186,14 +184,6 @@ appendfile_transport_options_block *ob = uschar *q = ob->quota; double default_value = 0.0; -addrlist = addrlist; /* Keep picky compilers happy */ -dummy = dummy; -uid = uid; -gid = gid; - -/* we can't wait until we're not privileged anymore */ -open_logs(); - if (ob->expand_maildir_use_size_file) ob->maildir_use_size_file = expand_check_condition(ob->expand_maildir_use_size_file, US"`maildir_use_size_file` in transport", tblock->name); @@ -435,7 +425,7 @@ if ((s = ob->create_file_string ) && *s) else if (Ustrcmp(s, "inhome") == 0) val = create_inhome; else log_write(0, LOG_PANIC_DIE|LOG_CONFIG, - "invalid value given for \"file_create\" for the %s transport: '%s'", + "invalid value given for \"create_file\" for the %s transport: '%s'", tblock->name, s); ob->create_file = val; } @@ -662,14 +652,14 @@ the log, because we are running as an unprivileged user here. Arguments: dirname the name of the directory countptr where to add the file count (because this function recurses) - regex a compiled regex to get the size from a name + re a compiled regex to get the size from a name Returns: the sum of the sizes of the stattable files zero if the directory cannot be opened */ off_t -check_dir_size(const uschar * dirname, int *countptr, const pcre *regex) +check_dir_size(const uschar * dirname, int * countptr, const pcre2_code * re) { DIR *dir; off_t sum = 0; @@ -688,22 +678,28 @@ for (struct dirent *ent; ent = readdir(dir); ) /* If there's a regex, try to find the size using it */ - if (regex) + if (re) { - int ovector[6]; - if (pcre_exec(regex, NULL, CS name, Ustrlen(name), 0, 0, ovector,6) >= 2) + pcre2_match_data * md = pcre2_match_data_create(2, pcre_gen_ctx); + int rc = pcre2_match(re, (PCRE2_SPTR)name, PCRE2_ZERO_TERMINATED, + 0, 0, md, pcre_gen_mtc_ctx); + PCRE2_SIZE * ovec = pcre2_get_ovector_pointer(md); + if ( rc >= 0 + && (rc = pcre2_get_ovector_count(md)) >= 2) { uschar *endptr; - off_t size = (off_t)Ustrtod(name + ovector[2], &endptr); - if (endptr == name + ovector[3]) + off_t size = (off_t)Ustrtod(name + ovec[2], &endptr); + if (endptr == name + ovec[3]) { sum += size; DEBUG(D_transport) debug_printf("check_dir_size: size from %s is " OFF_T_FMT "\n", name, size); + /* pcre2_match_data_free(md); gen ctx needs no free */ continue; } } + /* pcre2_match_data_free(md); gen ctx needs no free */ DEBUG(D_transport) debug_printf("check_dir_size: regex did not match %s\n", name); } @@ -722,7 +718,7 @@ for (struct dirent *ent; ent = readdir(dir); ) if ((statbuf.st_mode & S_IFMT) == S_IFREG) sum += statbuf.st_size / statbuf.st_nlink; else if ((statbuf.st_mode & S_IFMT) == S_IFDIR) - sum += check_dir_size(path, &count, regex); + sum += check_dir_size(path, &count, re); } closedir(dir); @@ -1354,7 +1350,7 @@ if (!isdirectory) if (is_tainted(path)) { DEBUG(D_transport) debug_printf("de-tainting path '%s'\n", path); - path = string_copy_taint(path, FALSE); + path = string_copy_taint(path, GET_UNTAINTED); } if (is_tainted(path)) goto tainted_ret_panic; @@ -1368,8 +1364,8 @@ if (!isdirectory) if (ob->create_directory && allow_creation_here) { uschar *p = Ustrrchr(path, '/'); - *p = '\0'; - if (!directory_make(NULL, path, ob->dirmode, FALSE)) + p = string_copyn(path, p - path); + if (!directory_make(NULL, p, ob->dirmode, FALSE)) { addr->basic_errno = errno; addr->message = @@ -1378,7 +1374,6 @@ if (!isdirectory) DEBUG(D_transport) debug_printf("%s transport: %s\n", tblock->name, path); return FALSE; } - *p = '/'; } /* If file_format is set we must check that any existing file matches one of @@ -2176,7 +2171,7 @@ scanning is expensive; for maildirs some fudges have been invented: else { uschar *check_path; /* Default quota check path */ - const pcre *regex = NULL; /* Regex for file size from file name */ + const pcre2_code * re = NULL; /* Regex for file size from file name */ if (!check_creation(string_sprintf("%s/any", path), ob->create_file, deliver_dir)) @@ -2194,7 +2189,7 @@ else if (ob->create_file == create_belowhome) { DEBUG(D_transport) debug_printf("de-tainting path '%s'\n", path); - path = string_copy_taint(path, FALSE); + path = string_copy_taint(path, GET_UNTAINTED); } else goto tainted_ret_panic; @@ -2219,21 +2214,14 @@ else if (ob->quota_value > 0 || THRESHOLD_CHECK || ob->maildir_use_size_file) { - const uschar *error; - int offset; - /* Compile the regex if there is one. */ if (ob->quota_size_regex) { - if (!(regex = pcre_compile(CS ob->quota_size_regex, PCRE_COPT, - CCSS &error, &offset, NULL))) - { - addr->message = string_sprintf("appendfile: regular expression " - "error: %s at offset %d while compiling %s", error, offset, - ob->quota_size_regex); + if (!(re = regex_compile(ob->quota_size_regex, + MCS_NOFLAGS, &addr->message, pcre_gen_cmp_ctx))) return FALSE; - } + DEBUG(D_transport) debug_printf("using regex for file sizes: %s\n", ob->quota_size_regex); } @@ -2305,22 +2293,15 @@ else #ifdef SUPPORT_MAILDIR if (ob->maildir_use_size_file) { - const pcre *dir_regex = NULL; - const uschar *error; - int offset; + const pcre2_code * dir_regex = NULL; if (ob->maildir_dir_regex) { int check_path_len = Ustrlen(check_path); - if (!(dir_regex = pcre_compile(CS ob->maildir_dir_regex, PCRE_COPT, - CCSS &error, &offset, NULL))) - { - addr->message = string_sprintf("appendfile: regular expression " - "error: %s at offset %d while compiling %s", error, offset, - ob->maildir_dir_regex); + if (!(dir_regex = regex_compile(ob->maildir_dir_regex, + MCS_NOFLAGS, &addr->message, pcre_gen_cmp_ctx))) return FALSE; - } DEBUG(D_transport) debug_printf("using regex for maildir directory selection: %s\n", @@ -2336,7 +2317,7 @@ else uschar *s = path + check_path_len; while (*s == '/') s++; s = *s ? string_sprintf("%s/new", s) : US"new"; - if (pcre_exec(dir_regex, NULL, CS s, Ustrlen(s), 0, 0, NULL, 0) < 0) + if (!regex_match(dir_regex, s, -1, NULL)) { disable_quota = TRUE; DEBUG(D_transport) debug_printf("delivery directory does not match " @@ -2357,7 +2338,7 @@ else off_t size; int filecount; - if ((maildirsize_fd = maildir_ensure_sizefile(check_path, ob, regex, dir_regex, + if ((maildirsize_fd = maildir_ensure_sizefile(check_path, ob, re, dir_regex, &size, &filecount)) == -1) { addr->basic_errno = errno; @@ -2382,7 +2363,7 @@ else * (void)unlink(CS string_sprintf("%s/maildirsize", check_path)); * if (THRESHOLD_CHECK) * mailbox_size = maildir_compute_size(check_path, &mailbox_filecount, &old_latest, - * regex, dir_regex, FALSE); + * re, dir_regex, FALSE); * } */ @@ -2404,7 +2385,7 @@ else int filecount = 0; DEBUG(D_transport) debug_printf("quota checks on directory %s\n", check_path); - size = check_dir_size(check_path, &filecount, regex); + size = check_dir_size(check_path, &filecount, re); if (mailbox_size < 0) mailbox_size = size; if (mailbox_filecount < 0) mailbox_filecount = filecount; } @@ -3195,7 +3176,7 @@ else uschar *iptr = expand_string(nametag); if (iptr) { - uschar *etag = store_get(Ustrlen(iptr) + 2, is_tainted(iptr)); + uschar *etag = store_get(Ustrlen(iptr) + 2, iptr); uschar *optr = etag; for ( ; *iptr; iptr++) if (mac_isgraph(*iptr) && *iptr != '/')