summaryrefslogtreecommitdiff
path: root/gnu/dist/postfix/src/postqueue/postqueue.c
diff options
context:
space:
mode:
Diffstat (limited to 'gnu/dist/postfix/src/postqueue/postqueue.c')
-rw-r--r--gnu/dist/postfix/src/postqueue/postqueue.c56
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 ? "..." : "");
}
/*