X-Git-Url: https://git.exim.org/exim.git/blobdiff_plain/0d7eb84a5719dda876c4b7def944d721cd259e19..929ba01ccb7fafbe89e4fa60e93ab2b5f4aab1df:/src/src/transports/appendfile.c diff --git a/src/src/transports/appendfile.c b/src/src/transports/appendfile.c index 6874fa746..142d55703 100644 --- a/src/src/transports/appendfile.c +++ b/src/src/transports/appendfile.c @@ -1,10 +1,10 @@ -/* $Cambridge: exim/src/src/transports/appendfile.c,v 1.7 2005/06/07 15:20:56 ph10 Exp $ */ +/* $Cambridge: exim/src/src/transports/appendfile.c,v 1.13 2006/02/21 16:24:20 ph10 Exp $ */ /************************************************* * Exim - an Internet mail transport agent * *************************************************/ -/* Copyright (c) University of Cambridge 1995 - 2005 */ +/* Copyright (c) University of Cambridge 1995 - 2006 */ /* See the file NOTICE for conditions of use and distribution. */ @@ -247,6 +247,8 @@ Arguments: tblock points to the transport instance addrlist addresses about to be delivered (not used) dummy not used (doesn't pass back data) + uid the uid that will be set (not used) + gid the gid that will be set (not used) errmsg where to put an error message Returns: OK, FAIL, or DEFER @@ -254,7 +256,7 @@ Returns: OK, FAIL, or DEFER static int appendfile_transport_setup(transport_instance *tblock, address_item *addrlist, - transport_feedback *dummy, uschar **errmsg) + transport_feedback *dummy, uid_t uid, gid_t gid, uschar **errmsg) { appendfile_transport_options_block *ob = (appendfile_transport_options_block *)(tblock->options_block); @@ -264,6 +266,8 @@ int i; addrlist = addrlist; /* Keep picky compilers happy */ dummy = dummy; +uid = uid; +gid = gid; /* Loop for quota, quota_filecount, quota_warn_threshold, mailbox_size, mailbox_filecount */ @@ -271,6 +275,7 @@ mailbox_filecount */ for (i = 0; i < 5; i++) { double d; + uschar *which = NULL; if (q == NULL) d = default_value; else { @@ -316,33 +321,49 @@ for (i = 0; i < 5; i++) } } + /* Set each value, checking for possible overflow. */ + switch (i) { case 0: + if (d >= 2.0*1024.0*1024.0*1024.0 && sizeof(off_t) <= 4) which = US"quota"; ob->quota_value = (off_t)d; q = ob->quota_filecount; break; case 1: + if (d >= 2.0*1024.0*1024.0*1024.0) which = US"quota_filecount"; ob->quota_filecount_value = (int)d; q = ob->quota_warn_threshold; break; case 2: + if (d >= 2.0*1024.0*1024.0*1024.0 && sizeof(off_t) <= 4) + which = US"quota_warn_threshold"; ob->quota_warn_threshold_value = (off_t)d; q = ob->mailbox_size_string; default_value = -1.0; break; case 3: + if (d >= 2.0*1024.0*1024.0*1024.0 && sizeof(off_t) <= 4) + which = US"mailbox_size";; ob->mailbox_size_value = (off_t)d; q = ob->mailbox_filecount_string; break; case 4: + if (d >= 2.0*1024.0*1024.0*1024.0) which = US"mailbox_filecount"; ob->mailbox_filecount_value = (int)d; break; } + + if (which != NULL) + { + *errmsg = string_sprintf("%s value %.10g is too large (overflow) in " + "%s transport", which, d, tblock->name); + return FAIL; + } } return OK; @@ -559,7 +580,7 @@ uschar buffer[256]; DEBUG(D_transport) debug_printf("notify_comsat called\n"); -sprintf(CS buffer, "%.200s@%.30g\n", user, (double)offset); +sprintf(CS buffer, "%.200s@" OFF_T_FMT "\n", user, offset); if ((sp = getservbyname("biff", "udp")) == NULL) { @@ -602,7 +623,7 @@ for (h = &host; h != NULL; h = h->next) (void)ip_connect(sock, host_af, h->address, ntohs(sp->s_port), 0); rc = send(sock, buffer, Ustrlen(buffer) + 1, 0); - close(sock); + (void)close(sock); if (rc >= 0) break; DEBUG(D_transport) @@ -741,8 +762,8 @@ while ((ent = readdir(dir)) != NULL) { sum += size; DEBUG(D_transport) - debug_printf("check_dir_size: size from %s is %.30g\n", name, - (double)size); + debug_printf("check_dir_size: size from %s is " OFF_T_FMT "\n", name, + size); continue; } } @@ -776,8 +797,8 @@ while ((ent = readdir(dir)) != NULL) closedir(dir); DEBUG(D_transport) - debug_printf("check_dir_size: dir=%s sum=%.30g count=%d\n", dirname, - (double)sum, count); + debug_printf("check_dir_size: dir=%s sum=" OFF_T_FMT " count=%d\n", dirname, + sum, count); *countptr = count; return sum; @@ -909,8 +930,8 @@ size, including CRLFs, which is the size of the input (temporary) file. */ if (fstat(from_fd, &statbuf) < 0) return DEFER; size = statbuf.st_size; -sprintf (CS deliver_out_buffer, "%s,%.30g;%08lx%04x-%08x\015\012", - tod_stamp(tod_mbx), (double)size, 0L, 0, 0); +sprintf (CS deliver_out_buffer, "%s," OFF_T_FMT ";%08lx%04x-%08x\015\012", + tod_stamp(tod_mbx), size, 0L, 0, 0); used = Ustrlen(deliver_out_buffer); /* Rewind the temporary file, and copy it over in chunks. */ @@ -1342,12 +1363,12 @@ else DEBUG(D_transport) { - debug_printf("appendfile: mode=%o notify_comsat=%d quota=%.30g " - "warning=%.30g%s\n" + debug_printf("appendfile: mode=%o notify_comsat=%d quota=" OFF_T_FMT + " warning=" OFF_T_FMT "%s\n" " %s=%s format=%s\n message_prefix=%s\n message_suffix=%s\n " "maildir_use_size_file=%s\n", - mode, ob->notify_comsat, (double)ob->quota_value, - (double)ob->quota_warn_threshold_value, + mode, ob->notify_comsat, ob->quota_value, + ob->quota_warn_threshold_value, ob->quota_warn_threshold_is_percent? "%" : "", isdirectory? "directory" : "file", path, mailbox_formats[mbformat], @@ -1430,7 +1451,7 @@ if (!isdirectory) if (cfd >= 0) { transport_instance *tt = check_file_format(cfd, tblock, addr); - close(cfd); + (void)close(cfd); /* If another transport is indicated, call it and return; if no transport was found, just return - the error data will have been set up.*/ @@ -1622,7 +1643,7 @@ if (!isdirectory) sufficiently worried. */ if ((rc = Ulink(hitchname, lockname)) != 0) fstat(hd, &statbuf); - close(hd); + (void)close(hd); Uunlink(hitchname); if (rc != 0 && statbuf.st_nlink != 2) { @@ -1734,8 +1755,8 @@ if (!isdirectory) /* We have successfully created and opened the file. Ensure that the group and the mode are correct. */ - Uchown(filename, uid, gid); - Uchmod(filename, mode); + (void)Uchown(filename, uid, gid); + (void)Uchmod(filename, mode); } @@ -2002,7 +2023,7 @@ if (!isdirectory) goto RETURN; } - Uchmod(mbx_lockname, 0600); + (void)Uchmod(mbx_lockname, 0600); if (apply_lock(mbx_lockfd, F_WRLCK, ob->use_fcntl, ob->lock_fcntl_timeout, ob->use_flock, ob->lock_flock_timeout) >= 0) @@ -2023,7 +2044,7 @@ if (!isdirectory) DEBUG(D_transport) debug_printf("failed to lock %s: %s\n", mbx_lockname, strerror(errno)); - close(mbx_lockfd); + (void)close(mbx_lockfd); mbx_lockfd = -1; } else @@ -2039,7 +2060,7 @@ if (!isdirectory) DEBUG(D_transport) debug_printf("fcntl(), flock(), or MBX locking failed - retrying\n"); - close(fd); + (void)close(fd); fd = -1; use_lstat = TRUE; /* Reset to use lstat first */ @@ -2415,8 +2436,8 @@ else /* Why are these here? Put in because they are present in the non-maildir directory case above. */ - Uchown(filename, uid, gid); - Uchmod(filename, mode); + (void)Uchown(filename, uid, gid); + (void)Uchmod(filename, mode); } #endif /* SUPPORT_MAILDIR */ @@ -2457,8 +2478,8 @@ else /* Why are these here? Put in because they are present in the non-maildir directory case above. */ - Uchown(filename, uid, gid); - Uchmod(filename, mode); + (void)Uchown(filename, uid, gid); + (void)Uchmod(filename, mode); /* Built a C stream from the open file descriptor. */ @@ -2468,7 +2489,7 @@ else addr->transport_return = PANIC; addr->message = string_sprintf("fdopen of %s (" "for %s transport) failed", filename, tblock->name); - close(fd); + (void)close(fd); Uunlink(filename); return FALSE; } @@ -2486,7 +2507,7 @@ else addr->message = string_sprintf("Expansion of \"%s\" (mailstore " "prefix for %s transport) failed: %s", ob->mailstore_prefix, tblock->name, expand_string_message); - fclose(env_file); + (void)fclose(env_file); Uunlink(filename); return FALSE; } @@ -2515,7 +2536,7 @@ else addr->message = string_sprintf("Expansion of \"%s\" (mailstore " "suffix for %s transport) failed: %s", ob->mailstore_suffix, tblock->name, expand_string_message); - fclose(env_file); + (void)fclose(env_file); Uunlink(filename); return FALSE; } @@ -2549,8 +2570,8 @@ else Uunlink(filename); return FALSE; } - Uchown(dataname, uid, gid); - Uchmod(dataname, mode); + (void)Uchown(dataname, uid, gid); + (void)Uchmod(dataname, mode); } #endif /* SUPPORT_MAILSTORE */ @@ -2559,8 +2580,8 @@ else /* In all cases of writing to a new file, ensure that the file which is going to be renamed has the correct ownership and mode. */ - Uchown(filename, uid, gid); - Uchmod(filename, mode); + (void)Uchown(filename, uid, gid); + (void)Uchmod(filename, mode); } @@ -2582,9 +2603,10 @@ if (ob->quota_value > 0) { DEBUG(D_transport) { - debug_printf("Exim quota = %.30g old size = %.30g this message = %d " - "(%sincluded)\n", (double)ob->quota_value, (double)mailbox_size, - message_size, ob->quota_is_inclusive? "" : "not "); + debug_printf("Exim quota = " OFF_T_FMT " old size = " OFF_T_FMT + " this message = %d (%sincluded)\n", + ob->quota_value, mailbox_size, message_size, + ob->quota_is_inclusive? "" : "not "); debug_printf(" file count quota = %d count = %d\n", ob->quota_filecount_value, mailbox_filecount); } @@ -2731,7 +2753,7 @@ if (temp_file != NULL && ob->mbx_format) /* Preserve errno while closing the temporary file. */ mbx_save_errno = errno; - fclose(temp_file); + (void)fclose(temp_file); errno = mbx_save_errno; } #endif /* SUPPORT_MBX */ @@ -2754,7 +2776,7 @@ if (yield == OK && maildirsize_fd >= 0) maildir_record_length(maildirsize_fd, message_size); maildir_save_errno = errno; /* Preserve errno while closing the file */ -close(maildirsize_fd); +(void)close(maildirsize_fd); errno = maildir_save_errno; #endif /* SUPPORT_MAILDIR */ @@ -2768,9 +2790,11 @@ if (THRESHOLD_CHECK) if (ob->quota_warn_threshold_is_percent) threshold = (off_t)(((double)ob->quota_value * threshold) / 100); DEBUG(D_transport) - debug_printf("quota = %.30g threshold = %.30g old size = %.30g " - "message size = %d\n", - (double)ob->quota_value, (double)threshold, (double)mailbox_size, + debug_printf("quota = " OFF_T_FMT + " threshold = " OFF_T_FMT + " old size = " OFF_T_FMT + " message size = %d\n", + ob->quota_value, threshold, mailbox_size, message_size); if (mailbox_size <= threshold && mailbox_size + message_size > threshold) addr->special_action = SPECIAL_WARN; @@ -2916,7 +2940,7 @@ if (yield != OK) investigated so far have ftruncate(), whereas not all have the F_FREESP fcntl() call (BSDI & FreeBSD do not). */ - if (!isdirectory) ftruncate(fd, saved_size); + if (!isdirectory) (void)ftruncate(fd, saved_size); } /* Handle successful writing - we want the modification time to be now for @@ -3127,7 +3151,7 @@ if (mbx_lockfd >= 0) debug_printf("unlinking MBX lock file %s\n", mbx_lockname); Uunlink(mbx_lockname); } - close(mbx_lockfd); + (void)close(mbx_lockfd); } #endif /* SUPPORT_MBX */