1 /* $NetBSD: postqueue.c,v 1.6 2026/05/09 18:49:19 christos Exp $ */ 2 3 /*++ 4 /* NAME 5 /* postqueue 1 6 /* SUMMARY 7 /* Postfix queue control 8 /* SYNOPSIS 9 /* .ti -4 10 /* \fBTo flush the mail queue\fR: 11 /* 12 /* \fBpostqueue\fR [\fB-v\fR] [\fB-c \fIconfig_dir\fR] \fB-f\fR 13 /* 14 /* \fBpostqueue\fR [\fB-v\fR] [\fB-c \fIconfig_dir\fR] \fB-i \fIqueue_id\fR 15 /* 16 /* \fBpostqueue\fR [\fB-v\fR] [\fB-c \fIconfig_dir\fR] \fB-s \fIsite\fR 17 /* 18 /* .ti -4 19 /* \fBTo list the mail queue\fR: 20 /* 21 /* \fBpostqueue\fR [\fB-v\fR] [\fB-c \fIconfig_dir\fR] \fB-j\fR 22 /* 23 /* \fBpostqueue\fR [\fB-v\fR] [\fB-c \fIconfig_dir\fR] \fB-p\fR 24 /* DESCRIPTION 25 /* The \fBpostqueue\fR(1) command implements the Postfix user interface 26 /* for queue management. It implements operations that are 27 /* traditionally available via the \fBsendmail\fR(1) command. 28 /* See the \fBpostsuper\fR(1) command for queue operations 29 /* that require super-user privileges such as deleting a message 30 /* from the queue or changing the status of a message. 31 /* 32 /* The following options are recognized: 33 /* .IP "\fB-c \fIconfig_dir\fR" 34 /* The \fBmain.cf\fR configuration file is in the named directory 35 /* instead of the default configuration directory. See also the 36 /* MAIL_CONFIG environment setting below. 37 /* .IP \fB-f\fR 38 /* Flush the queue: attempt to deliver all queued mail. 39 /* 40 /* This option implements the traditional "\fBsendmail -q\fR" command, 41 /* by contacting the Postfix \fBqmgr\fR(8) daemon. 42 /* 43 /* Warning: flushing undeliverable mail frequently will result in 44 /* poor delivery performance of all other mail. 45 /* .IP "\fB-i \fIqueue_id\fR" 46 /* Schedule immediate delivery of deferred mail with the 47 /* specified queue ID. 48 /* 49 /* This option implements the traditional \fBsendmail -qI\fR 50 /* command, by contacting the \fBflush\fR(8) server. 51 /* 52 /* This feature is available with Postfix version 2.4 and later. 53 /* .IP "\fB-j\fR" 54 /* Produce a queue listing in JSON LINES format, based on 55 /* output from the showq(8) daemon. See "\fBJSON OBJECT 56 /* FORMAT\fR" below for details. 57 /* 58 /* This feature is available in Postfix 3.1 and later. 59 /* .IP \fB-p\fR 60 /* Produce a traditional sendmail-style queue listing. 61 /* This option implements the traditional \fBmailq\fR command, 62 /* by contacting the Postfix \fBshowq\fR(8) daemon. 63 /* 64 /* Each queue entry shows the queue file ID, message 65 /* size, arrival time, sender, and the recipients that still need to 66 /* be delivered. If mail could not be delivered upon the last attempt, 67 /* the reason for failure is shown. With Postfix >= 3.11, the output 68 /* may also show bounced recipients that are pending the creation 69 /* of a non-delivery status notification message that will be 70 /* returned to the sender. 71 /* 72 /* The queue ID string is followed by an optional status character: 73 /* .RS 74 /* .IP \fB*\fR 75 /* The message is in the \fBactive\fR queue, i.e. the message is 76 /* selected for delivery. 77 /* .IP \fB!\fR 78 /* The message is in the \fBhold\fR queue, i.e. no further delivery 79 /* attempt will be made until the mail is taken off hold. 80 /* .IP \fB#\fR 81 /* The message is forced to expire. See the \fBpostsuper\fR(1) 82 /* options \fB-e\fR or \fB-f\fR. 83 /* .sp 84 /* This feature is available in Postfix 3.5 and later. 85 /* .RE 86 /* .IP "\fB-s \fIsite\fR" 87 /* Schedule immediate delivery of all mail that is queued for the named 88 /* \fIsite\fR. A numerical site must be specified as a valid RFC 5321 89 /* address literal enclosed in [], just like in email addresses. 90 /* The site must be eligible for the "fast flush" service. 91 /* See \fBflush\fR(8) for more information about the "fast flush" 92 /* service. 93 /* 94 /* This option implements the traditional "\fBsendmail -qR\fIsite\fR" 95 /* command, by contacting the Postfix \fBflush\fR(8) daemon. 96 /* .IP \fB-v\fR 97 /* Enable verbose logging for debugging purposes. Multiple \fB-v\fR 98 /* options make the software increasingly verbose. As of Postfix 2.3, 99 /* this option is available for the super-user only. 100 /* JSON OBJECT FORMAT 101 /* .ad 102 /* .fi 103 /* Each JSON object represents one queue file; it is emitted 104 /* as a single text line followed by a newline character. 105 /* 106 /* Object members have string values unless indicated otherwise. 107 /* Programs should ignore object members that are not listed 108 /* here; the list of members is expected to grow over time. 109 /* .IP \fBqueue_name\fR 110 /* The name of the queue where the message was found. Note 111 /* that the contents of the mail queue may change while it is 112 /* being listed; some messages may appear more than once, and 113 /* some messages may be missed. 114 /* .IP \fBqueue_id\fR 115 /* The queue file name. The queue_id may be reused within a 116 /* Postfix instance unless "enable_long_queue_ids = true" and 117 /* time is monotonic. Even then, the queue_id is not expected 118 /* to be unique between different Postfix instances. Management 119 /* tools that require a unique name should combine the queue_id 120 /* with the myhostname setting of the Postfix instance. 121 /* .IP \fBarrival_time\fR 122 /* The number of seconds since the start of the UNIX epoch. 123 /* .IP \fBmessage_size\fR 124 /* The number of bytes in the message header and body. This 125 /* number does not include message envelope information. It 126 /* is approximately equal to the number of bytes that would 127 /* be transmitted via SMTP including the <CR><LF> line endings. 128 /* .IP "\fBforced_expire\fR (Postfix >= 3.5) 129 /* The message is forced to expire (\fBtrue\fR or \fBfalse\fR). 130 /* See the \fBpostsuper\fR(1) options \fB-e\fR or \fB-f\fR. 131 /* .IP \fBsender\fR 132 /* The envelope sender address. 133 /* .IP \fBrecipients\fR 134 /* An array containing zero or more objects with members: 135 /* .RS 136 /* .IP \fBaddress\fR 137 /* One recipient address. 138 /* .IP "\fBorig_address\fR (Postfix >= 3.11)" 139 /* One original recipient address. 140 /* .IP \fBdelay_reason\fR 141 /* If present, the reason for delayed delivery. Delayed 142 /* recipients may have no delay reason, for example, while 143 /* delivery is in progress, or after the system was stopped 144 /* before it could record the reason. 145 /* .IP "\fBbounce_reason\fR (Postfix >= 3.11)" 146 /* If present, the reason why this recipient was bounced. The 147 /* recipient is still pending the creation of a non-delivery status 148 /* notification message that will be returned to the sender. 149 /* .RE 150 /* SECURITY 151 /* .ad 152 /* .fi 153 /* This program is designed to run with set-group ID privileges, so 154 /* that it can connect to Postfix daemon processes. 155 /* STANDARDS 156 /* RFC 7159 (JSON notation) 157 /* DIAGNOSTICS 158 /* Problems are logged to \fBsyslogd\fR(8) or \fBpostlogd\fR(8), 159 /* and to the standard error stream. 160 /* ENVIRONMENT 161 /* .ad 162 /* .fi 163 /* .IP MAIL_CONFIG 164 /* Directory with the \fBmain.cf\fR file. In order to avoid exploitation 165 /* of set-group ID privileges, a non-default directory is allowed only 166 /* if: 167 /* .RS 168 /* .IP \(bu 169 /* The name is listed in the default \fBmain.cf\fR file with the 170 /* \fBalternate_config_directories\fR or 171 /* \fBmulti_instance_directories\fR configuration parameter. 172 /* .IP \(bu 173 /* The command is invoked by the super-user. 174 /* .RE 175 /* CONFIGURATION PARAMETERS 176 /* .ad 177 /* .fi 178 /* The following \fBmain.cf\fR parameters are especially relevant to 179 /* this program. 180 /* The text below provides only a parameter summary. See 181 /* \fBpostconf\fR(5) for more details including examples. 182 /* .IP "\fBalternate_config_directories (empty)\fR" 183 /* A list of non-default Postfix configuration directories that may 184 /* be specified with "-c config_directory" on the command line (in the 185 /* case of \fBsendmail\fR(1), with the "-C" option), or via the MAIL_CONFIG 186 /* environment parameter. 187 /* .IP "\fBconfig_directory (see 'postconf -d' output)\fR" 188 /* The default location of the Postfix main.cf and master.cf 189 /* configuration files. 190 /* .IP "\fBcommand_directory (see 'postconf -d' output)\fR" 191 /* The location of all postfix administrative commands. 192 /* .IP "\fBfast_flush_domains ($relay_domains)\fR" 193 /* Optional list of destinations that are eligible for per-destination 194 /* logfiles with mail that is queued to those destinations. 195 /* .IP "\fBimport_environment (see 'postconf -d' output)\fR" 196 /* The list of environment variables that a privileged Postfix 197 /* process will import from a non-Postfix parent process, or name=value 198 /* environment overrides. 199 /* .IP "\fBqueue_directory (see 'postconf -d' output)\fR" 200 /* The location of the Postfix top-level queue directory. 201 /* .IP "\fBsyslog_facility (mail)\fR" 202 /* The syslog facility of Postfix logging. 203 /* .IP "\fBsyslog_name (see 'postconf -d' output)\fR" 204 /* A prefix that is prepended to the process name in syslog 205 /* records, so that, for example, "smtpd" becomes "prefix/smtpd". 206 /* .IP "\fBtrigger_timeout (10s)\fR" 207 /* The time limit for sending a trigger to a Postfix daemon (for 208 /* example, the \fBpickup\fR(8) or \fBqmgr\fR(8) daemon). 209 /* .PP 210 /* Available in Postfix version 2.2 and later: 211 /* .IP "\fBauthorized_flush_users (static:anyone)\fR" 212 /* List of users who are authorized to flush the queue. 213 /* .IP "\fBauthorized_mailq_users (static:anyone)\fR" 214 /* List of users who are authorized to view the queue. 215 /* FILES 216 /* /var/spool/postfix, mail queue 217 /* SEE ALSO 218 /* qmgr(8), queue manager 219 /* showq(8), list mail queue 220 /* flush(8), fast flush service 221 /* sendmail(1), Sendmail-compatible user interface 222 /* postsuper(1), privileged queue operations 223 /* postlogd(8), Postfix logging 224 /* syslogd(8), system logging 225 /* README FILES 226 /* .ad 227 /* .fi 228 /* Use "\fBpostconf readme_directory\fR" or 229 /* "\fBpostconf html_directory\fR" to locate this information. 230 /* .na 231 /* .nf 232 /* ETRN_README, Postfix ETRN howto 233 /* LICENSE 234 /* .ad 235 /* .fi 236 /* The Secure Mailer license must be distributed with this software. 237 /* HISTORY 238 /* .ad 239 /* .fi 240 /* The postqueue command was introduced with Postfix version 1.1. 241 /* AUTHOR(S) 242 /* Wietse Venema 243 /* IBM T.J. Watson Research 244 /* P.O. Box 704 245 /* Yorktown Heights, NY 10598, USA 246 /* 247 /* Wietse Venema 248 /* Google, Inc. 249 /* 111 8th Avenue 250 /* New York, NY 10011, USA 251 /*--*/ 252 253 /* System library. */ 254 255 #include <sys_defs.h> 256 #include <sys/stat.h> 257 #include <unistd.h> 258 #include <string.h> 259 #include <stdlib.h> 260 #include <signal.h> 261 #include <sysexits.h> 262 #include <errno.h> 263 264 /* Utility library. */ 265 266 #include <msg.h> 267 #include <mymalloc.h> 268 #include <clean_env.h> 269 #include <vstream.h> 270 #include <msg_vstream.h> 271 #include <argv.h> 272 #include <safe.h> 273 #include <connect.h> 274 #include <valid_hostname.h> 275 #include <warn_stat.h> 276 #include <events.h> 277 #include <stringops.h> 278 279 /* Global library. */ 280 281 #include <mail_proto.h> 282 #include <mail_params.h> 283 #include <mail_version.h> 284 #include <mail_conf.h> 285 #include <mail_task.h> 286 #include <mail_run.h> 287 #include <mail_flush.h> 288 #include <mail_queue.h> 289 #include <flush_clnt.h> 290 #include <smtp_stream.h> 291 #include <user_acl.h> 292 #include <valid_mailhost_addr.h> 293 #include <mail_dict.h> 294 #include <mail_parm_split.h> 295 #include <maillog_client.h> 296 297 /* Application-specific. */ 298 299 #include <postqueue.h> 300 301 /* 302 * WARNING WARNING WARNING 303 * 304 * This software is designed to run set-gid. In order to avoid exploitation of 305 * privilege, this software should not run any external commands, nor should 306 * it take any information from the user, unless that information can be 307 * properly sanitized. To get an idea of how much information a process can 308 * inherit from a potentially hostile user, examine all the members of the 309 * process structure (typically, in /usr/include/sys/proc.h): the current 310 * directory, open files, timers, signals, environment, command line, umask, 311 * and so on. 312 */ 313 314 /* 315 * Modes of operation. 316 * 317 * XXX To support flush by recipient domain, or for destinations that have no 318 * mapping to logfile, the server has to defend against resource exhaustion 319 * attacks. A malicious user could fork off a postqueue client that starts 320 * an expensive requests and then kills the client immediately; this way she 321 * could create a high Postfix load on the system without ever exceeding her 322 * own per-user process limit. To prevent this, either the server needs to 323 * establish frequent proof of client liveliness with challenge/response, or 324 * the client needs to restrict expensive requests to privileged users only. 325 * 326 * We don't have this problem with queue listings. The showq server detects an 327 * EPIPE error after reporting a few queue entries. 328 */ 329 #define PQ_MODE_DEFAULT 0 /* noop */ 330 #define PQ_MODE_MAILQ_LIST 1 /* list mail queue */ 331 #define PQ_MODE_FLUSH_QUEUE 2 /* flush queue */ 332 #define PQ_MODE_FLUSH_SITE 3 /* flush site */ 333 #define PQ_MODE_FLUSH_FILE 4 /* flush message */ 334 #define PQ_MODE_JSON_LIST 5 /* JSON-format queue listing */ 335 336 /* 337 * Silly little macros (SLMs). 338 */ 339 #define STR vstring_str 340 341 /* 342 * Queue manipulation access lists. 343 */ 344 char *var_flush_acl; 345 char *var_showq_acl; 346 347 static const CONFIG_STR_TABLE str_table[] = { 348 VAR_FLUSH_ACL, DEF_FLUSH_ACL, &var_flush_acl, 0, 0, 349 VAR_SHOWQ_ACL, DEF_SHOWQ_ACL, &var_showq_acl, 0, 0, 350 0, 351 }; 352 353 /* showq_client - run the appropriate showq protocol client */ 354 355 static void showq_client(int mode, VSTREAM *showq) 356 { 357 if (attr_scan(showq, ATTR_FLAG_STRICT, 358 RECV_ATTR_STREQ(MAIL_ATTR_PROTO, MAIL_ATTR_PROTO_SHOWQ), 359 ATTR_TYPE_END) != 0) 360 msg_fatal_status(EX_SOFTWARE, "malformed showq server response"); 361 switch (mode) { 362 case PQ_MODE_MAILQ_LIST: 363 showq_compat(showq); 364 break; 365 case PQ_MODE_JSON_LIST: 366 showq_json(showq); 367 break; 368 default: 369 msg_panic("show_queue: unknown mode %d", mode); 370 } 371 } 372 373 /* show_queue - show queue status */ 374 375 static void show_queue(int mode) 376 { 377 const char *errstr; 378 VSTREAM *showq; 379 int n; 380 uid_t uid = getuid(); 381 382 if (uid != 0 && uid != var_owner_uid 383 && (errstr = check_user_acl_byuid(VAR_SHOWQ_ACL, var_showq_acl, 384 uid)) != 0) 385 msg_fatal_status(EX_NOPERM, 386 "User %s(%ld) is not allowed to view the mail queue", 387 errstr, (long) uid); 388 389 /* 390 * Connect to the show queue service. 391 */ 392 if ((showq = mail_connect(MAIL_CLASS_PUBLIC, var_showq_service, BLOCKING)) != 0) { 393 showq_client(mode, showq); 394 if (vstream_fclose(showq)) 395 msg_warn("close: %m"); 396 } 397 398 /* 399 * Don't assume that the mail system is down when the user has 400 * insufficient permission to access the showq socket. 401 */ 402 else if (errno == EACCES || errno == EPERM) { 403 msg_fatal_status(EX_SOFTWARE, 404 "Connect to the %s %s service: %m", 405 var_mail_name, var_showq_service); 406 } 407 408 /* 409 * When the mail system is down, the superuser can still access the queue 410 * directly. Just run the showq program in stand-alone mode. 411 */ 412 else if (geteuid() == 0) { 413 char *showq_path; 414 ARGV *argv; 415 int stat; 416 417 msg_warn("Mail system is down -- accessing queue directly" 418 " (Connect to the %s %s service: %m)", 419 var_mail_name, var_showq_service); 420 showq_path = concatenate(var_daemon_dir, "/", var_showq_service, 421 (char *) 0); 422 argv = argv_alloc(6); 423 argv_add(argv, showq_path, "-u", "-S", (char *) 0); 424 for (n = 0; n < msg_verbose; n++) 425 argv_add(argv, "-v", (char *) 0); 426 argv_terminate(argv); 427 if ((showq = vstream_popen(O_RDONLY, 428 CA_VSTREAM_POPEN_ARGV(argv->argv), 429 CA_VSTREAM_POPEN_END)) == 0) { 430 stat = -1; 431 } else { 432 showq_client(mode, showq); 433 stat = vstream_pclose(showq); 434 } 435 argv_free(argv); 436 myfree(showq_path); 437 if (stat != 0) 438 msg_fatal_status(stat < 0 ? EX_OSERR : EX_SOFTWARE, 439 "Error running %s", showq_path); 440 } 441 442 /* 443 * When the mail system is down, unprivileged users are stuck, because by 444 * design the mail system contains no set_uid programs. The only way for 445 * an unprivileged user to cross protection boundaries is to talk to the 446 * showq daemon. 447 */ 448 else { 449 msg_fatal_status(EX_UNAVAILABLE, 450 "Queue report unavailable - mail system is down" 451 " (Connect to the %s %s service: %m)", 452 var_mail_name, var_showq_service); 453 } 454 } 455 456 /* flush_queue - force delivery */ 457 458 static void flush_queue(void) 459 { 460 const char *errstr; 461 uid_t uid = getuid(); 462 463 if (uid != 0 && uid != var_owner_uid 464 && (errstr = check_user_acl_byuid(VAR_FLUSH_ACL, var_flush_acl, 465 uid)) != 0) 466 msg_fatal_status(EX_NOPERM, 467 "User %s(%ld) is not allowed to flush the mail queue", 468 errstr, (long) uid); 469 470 /* 471 * Trigger the flush queue service. 472 */ 473 if (mail_flush_deferred() < 0) 474 msg_fatal_status(EX_UNAVAILABLE, 475 "Cannot flush mail queue - mail system is down"); 476 if (mail_flush_maildrop() < 0) 477 msg_fatal_status(EX_UNAVAILABLE, 478 "Cannot flush mail queue - mail system is down"); 479 event_drain(2); 480 } 481 482 /* flush_site - flush mail for site */ 483 484 static void flush_site(const char *site) 485 { 486 int status; 487 const char *errstr; 488 uid_t uid = getuid(); 489 490 if (uid != 0 && uid != var_owner_uid 491 && (errstr = check_user_acl_byuid(VAR_FLUSH_ACL, var_flush_acl, 492 uid)) != 0) 493 msg_fatal_status(EX_NOPERM, 494 "User %s(%ld) is not allowed to flush the mail queue", 495 errstr, (long) uid); 496 497 flush_init(); 498 499 switch (status = flush_send_site(site)) { 500 case FLUSH_STAT_OK: 501 exit(0); 502 case FLUSH_STAT_BAD: 503 msg_fatal_status(EX_USAGE, "Invalid request: \"%s\"", site); 504 case FLUSH_STAT_FAIL: 505 msg_fatal_status(EX_UNAVAILABLE, 506 "Cannot flush mail queue - mail system is down"); 507 case FLUSH_STAT_DENY: 508 msg_fatal_status(EX_UNAVAILABLE, 509 "Flush service is not configured for destination \"%s\"", 510 site); 511 default: 512 msg_fatal_status(EX_SOFTWARE, 513 "Unknown flush server reply status %d", status); 514 } 515 } 516 517 /* flush_file - flush mail with specific queue ID */ 518 519 static void flush_file(const char *queue_id) 520 { 521 int status; 522 const char *errstr; 523 uid_t uid = getuid(); 524 525 if (uid != 0 && uid != var_owner_uid 526 && (errstr = check_user_acl_byuid(VAR_FLUSH_ACL, var_flush_acl, 527 uid)) != 0) 528 msg_fatal_status(EX_NOPERM, 529 "User %s(%ld) is not allowed to flush the mail queue", 530 errstr, (long) uid); 531 532 switch (status = flush_send_file(queue_id)) { 533 case FLUSH_STAT_OK: 534 exit(0); 535 case FLUSH_STAT_BAD: 536 msg_fatal_status(EX_USAGE, "Invalid request: \"%s\"", queue_id); 537 case FLUSH_STAT_FAIL: 538 msg_fatal_status(EX_UNAVAILABLE, 539 "Cannot flush mail queue - mail system is down"); 540 default: 541 msg_fatal_status(EX_SOFTWARE, 542 "Unexpected flush server reply status %d", status); 543 } 544 } 545 546 /* unavailable - sanitize exit status from library run-time errors */ 547 548 static void unavailable(void) 549 { 550 exit(EX_UNAVAILABLE); 551 } 552 553 /* usage - scream and die */ 554 555 static NORETURN usage(void) 556 { 557 msg_fatal_status(EX_USAGE, "usage: postqueue -f | postqueue -i queueid | postqueue -j | postqueue -p | postqueue -s site"); 558 } 559 560 MAIL_VERSION_STAMP_DECLARE; 561 562 /* main - the main program */ 563 564 int main(int argc, char **argv) 565 { 566 struct stat st; 567 int c; 568 int fd; 569 int mode = PQ_MODE_DEFAULT; 570 char *site_to_flush = 0; 571 char *id_to_flush = 0; 572 ARGV *import_env; 573 int bad_site; 574 575 /* 576 * Fingerprint executables and core dumps. 577 */ 578 MAIL_VERSION_STAMP_ALLOCATE; 579 580 /* 581 * Be consistent with file permissions. 582 */ 583 umask(022); 584 585 /* 586 * To minimize confusion, make sure that the standard file descriptors 587 * are open before opening anything else. XXX Work around for 44BSD where 588 * fstat can return EBADF on an open file descriptor. 589 */ 590 for (fd = 0; fd < 3; fd++) 591 if (fstat(fd, &st) == -1 592 && (close(fd), open("/dev/null", O_RDWR, 0)) != fd) 593 msg_fatal_status(EX_UNAVAILABLE, "open /dev/null: %m"); 594 595 /* 596 * Initialize. Set up logging. Read the global configuration file after 597 * parsing command-line arguments. Censor the process name: it is 598 * provided by the user. 599 */ 600 argv[0] = "postqueue"; 601 msg_vstream_init(argv[0], VSTREAM_ERR); 602 msg_cleanup(unavailable); 603 maillog_client_init(mail_task("postqueue"), MAILLOG_CLIENT_FLAG_NONE); 604 set_mail_conf_str(VAR_PROCNAME, var_procname = mystrdup(argv[0])); 605 606 /* 607 * Check the Postfix library version as soon as we enable logging. 608 */ 609 MAIL_VERSION_CHECK; 610 611 /* 612 * Parse JCL. This program is set-gid and must sanitize all command-line 613 * parameters. The configuration directory argument is validated by the 614 * mail configuration read routine. Don't do complex things until we have 615 * completed initializations. 616 */ 617 while ((c = GETOPT(argc, argv, "c:fi:jps:v")) > 0) { 618 switch (c) { 619 case 'c': /* non-default configuration */ 620 if (setenv(CONF_ENV_PATH, optarg, 1) < 0) 621 msg_fatal_status(EX_UNAVAILABLE, "out of memory"); 622 break; 623 case 'f': /* flush queue */ 624 if (mode != PQ_MODE_DEFAULT) 625 usage(); 626 mode = PQ_MODE_FLUSH_QUEUE; 627 break; 628 case 'i': /* flush queue file */ 629 if (mode != PQ_MODE_DEFAULT) 630 usage(); 631 mode = PQ_MODE_FLUSH_FILE; 632 id_to_flush = optarg; 633 break; 634 case 'j': 635 if (mode != PQ_MODE_DEFAULT) 636 usage(); 637 mode = PQ_MODE_JSON_LIST; 638 break; 639 case 'p': /* traditional mailq */ 640 if (mode != PQ_MODE_DEFAULT) 641 usage(); 642 mode = PQ_MODE_MAILQ_LIST; 643 break; 644 case 's': /* flush site */ 645 if (mode != PQ_MODE_DEFAULT) 646 usage(); 647 mode = PQ_MODE_FLUSH_SITE; 648 site_to_flush = optarg; 649 break; 650 case 'v': 651 if (geteuid() == 0) 652 msg_verbose++; 653 break; 654 default: 655 usage(); 656 } 657 } 658 if (argc > optind) 659 usage(); 660 661 /* 662 * Further initialization... 663 */ 664 mail_conf_read(); 665 /* Re-evaluate mail_task() after reading main.cf. */ 666 maillog_client_init(mail_task("postqueue"), MAILLOG_CLIENT_FLAG_NONE); 667 mail_dict_init(); /* proxy, sql, ldap */ 668 get_mail_conf_str_table(str_table); 669 670 /* 671 * This program is designed to be set-gid, which makes it a potential 672 * target for attack. Strip and optionally override the process 673 * environment so that we don't have to trust the C library. 674 */ 675 import_env = mail_parm_split(VAR_IMPORT_ENVIRON, var_import_environ); 676 clean_env(import_env->argv); 677 argv_free(import_env); 678 679 if (chdir(var_queue_dir)) 680 msg_fatal_status(EX_UNAVAILABLE, "chdir %s: %m", var_queue_dir); 681 682 signal(SIGPIPE, SIG_IGN); 683 684 /* End of initializations. */ 685 686 /* 687 * Further input validation. 688 */ 689 if (site_to_flush != 0) { 690 bad_site = 0; 691 if (*site_to_flush == '[') { 692 bad_site = !valid_mailhost_literal(site_to_flush, DONT_GRIPE); 693 } else { 694 bad_site = !valid_hostname(site_to_flush, DONT_GRIPE); 695 } 696 if (bad_site) 697 msg_fatal_status(EX_USAGE, 698 "Cannot flush mail queue - invalid destination: \"%.100s%s\"", 699 site_to_flush, strlen(site_to_flush) > 100 ? "..." : ""); 700 } 701 if (id_to_flush != 0) { 702 if (!mail_queue_id_ok(id_to_flush)) 703 msg_fatal_status(EX_USAGE, 704 "Cannot flush queue ID - invalid name: \"%.100s%s\"", 705 id_to_flush, strlen(id_to_flush) > 100 ? "..." : ""); 706 } 707 708 /* 709 * Start processing. 710 */ 711 switch (mode) { 712 default: 713 msg_panic("unknown operation mode: %d", mode); 714 /* NOTREACHED */ 715 case PQ_MODE_MAILQ_LIST: 716 case PQ_MODE_JSON_LIST: 717 show_queue(mode); 718 exit(0); 719 break; 720 case PQ_MODE_FLUSH_SITE: 721 flush_site(site_to_flush); 722 exit(0); 723 break; 724 case PQ_MODE_FLUSH_FILE: 725 flush_file(id_to_flush); 726 exit(0); 727 break; 728 case PQ_MODE_FLUSH_QUEUE: 729 flush_queue(); 730 exit(0); 731 break; 732 case PQ_MODE_DEFAULT: 733 usage(); 734 /* NOTREACHED */ 735 } 736 } 737