diff options
Diffstat (limited to 'gnu/dist/postfix/src/postqueue/postqueue.c')
| -rw-r--r-- | gnu/dist/postfix/src/postqueue/postqueue.c | 56 |
1 files changed, 38 insertions, 18 deletions
diff --git a/gnu/dist/postfix/src/postqueue/postqueue.c b/gnu/dist/postfix/src/postqueue/postqueue.c index 7fba3c61d5b..12b4581c168 100644 --- a/gnu/dist/postfix/src/postqueue/postqueue.c +++ b/gnu/dist/postfix/src/postqueue/postqueue.c @@ -104,6 +104,7 @@ #include <stdlib.h> #include <signal.h> #include <sysexits.h> +#include <errno.h> /* Utility library. */ @@ -171,16 +172,29 @@ static void show_queue(void) * a program that terminates early. */ if ((showq = mail_connect(MAIL_CLASS_PUBLIC, MAIL_SERVICE_SHOWQ, BLOCKING)) != 0) { - while ((n = vstream_fread(showq, buf, sizeof(buf))) > 0) + while ((n = vstream_fread(showq, buf, sizeof(buf))) > 0) { if (vstream_fwrite(VSTREAM_OUT, buf, n) != n - || vstream_fflush(VSTREAM_OUT) != 0) + || vstream_fflush(VSTREAM_OUT) != 0) { + if (errno == EPIPE) + break; msg_fatal("write error: %m"); - - if (vstream_fclose(showq)) + } + } + if (vstream_fclose(showq) && errno != EPIPE) msg_warn("close: %m"); } /* + * Don't assume that the mail system is down when the user has + * insufficient permission to access the showq socket. + */ + else if (errno == EACCES) { + msg_fatal_status(EX_SOFTWARE, + "Connect to the %s %s service: %m", + var_mail_name, MAIL_SERVICE_SHOWQ); + } + + /* * When the mail system is down, the superuser can still access the queue * directly. Just run the showq program in stand-alone mode. */ @@ -251,7 +265,7 @@ static void flush_site(const char *site) static NORETURN usage(void) { - msg_fatal_status(EX_USAGE, "usage: specify one of -f, -p, or -s"); + msg_fatal_status(EX_USAGE, "usage: postqueue -f | postqueue -p | postqueue -s site"); } /* main - the main program */ @@ -266,6 +280,7 @@ int main(int argc, char **argv) char *site_to_flush = 0; ARGV *import_env; char *last; + int bad_site; /* * Be consistent with file permissions. @@ -315,7 +330,6 @@ int main(int argc, char **argv) usage(); mode = PQ_MODE_MAILQ_LIST; break; - break; case 's': /* flush site */ if (mode != PQ_MODE_DEFAULT) usage(); @@ -329,6 +343,8 @@ int main(int argc, char **argv) usage(); } } + if (argc > optind) + usage(); /* * Further initialization... @@ -336,12 +352,17 @@ int main(int argc, char **argv) mail_conf_read(); /* - * Strip the environment so we don't have to trust the C library. + * This program is designed to be set-gid, which makes it a potential + * target for attack. If not running as root, strip the environment so we + * don't have to trust the C library. If running as root, don't strip the + * environment so that showq can receive non-default configuration + * directory info when the mail system is down. */ - import_env = argv_split(var_import_environ, ", \t\r\n"); - clean_env(import_env->argv); - argv_free(import_env); - + if (geteuid() != 0) { + import_env = argv_split(var_import_environ, ", \t\r\n"); + clean_env(import_env->argv); + argv_free(import_env); + } if (chdir(var_queue_dir)) msg_fatal_status(EX_UNAVAILABLE, "chdir %s: %m", var_queue_dir); @@ -353,21 +374,20 @@ int main(int argc, char **argv) * Further input validation. */ if (site_to_flush != 0) { + bad_site = 0; if (*site_to_flush == '[' && *(last = site_to_flush + strlen(site_to_flush) - 1) == ']') { *last = 0; - if (!valid_hostaddr(site_to_flush + 1, DONT_GRIPE)) - site_to_flush = 0; + bad_site = !valid_hostaddr(site_to_flush + 1, DONT_GRIPE); *last = ']'; } else { - if (!valid_hostname(site_to_flush, DONT_GRIPE) - && !valid_hostaddr(site_to_flush, DONT_GRIPE)) - site_to_flush = 0; + bad_site = (!valid_hostname(site_to_flush, DONT_GRIPE) + && !valid_hostaddr(site_to_flush, DONT_GRIPE)); } - if (site_to_flush == 0) + if (bad_site) msg_fatal_status(EX_USAGE, "Cannot flush mail queue - invalid destination: \"%.100s%s\"", - optarg, strlen(optarg) > 100 ? "..." : ""); + site_to_flush, strlen(site_to_flush) > 100 ? "..." : ""); } /* |
