1 /* $NetBSD: postconf.c,v 1.1.1.8 2014/07/06 19:27:53 tron Exp $ */ 2 3 /*++ 4 /* NAME 5 /* postconf 1 6 /* SUMMARY 7 /* Postfix configuration utility 8 /* SYNOPSIS 9 /* .fi 10 /* \fBManaging main.cf:\fR 11 /* 12 /* \fBpostconf\fR [\fB-dfhnopvx\fR] [\fB-c \fIconfig_dir\fR] 13 /* [\fB-C \fIclass,...\fR] [\fIparameter ...\fR] 14 /* 15 /* \fBpostconf\fR [\fB-epv\fR] [\fB-c \fIconfig_dir\fR] 16 /* \fIparameter\fB=\fIvalue ...\fR 17 /* 18 /* \fBpostconf\fR \fB-#\fR [\fB-pv\fR] [\fB-c \fIconfig_dir\fR] 19 /* \fIparameter ...\fR 20 /* 21 /* \fBpostconf\fR \fB-X\fR [\fB-pv\fR] [\fB-c \fIconfig_dir\fR] 22 /* \fIparameter ...\fR 23 /* 24 /* \fBManaging master.cf service entries:\fR 25 /* 26 /* \fBpostconf\fR \fB-M\fR [\fB-fovx\fR] [\fB-c \fIconfig_dir\fR] 27 /* [\fIservice\fR[\fB/\fItype\fR]\fI ...\fR] 28 /* 29 /* \fBpostconf\fR \fB-M\fR [\fB-ev\fR] [\fB-c \fIconfig_dir\fR] 30 /* \fIservice\fB/\fItype\fB=\fIvalue ...\fR 31 /* 32 /* \fBpostconf\fR \fB-M#\fR [\fB-v\fR] [\fB-c \fIconfig_dir\fR] 33 /* \fIservice\fB/\fItype ...\fR 34 /* 35 /* \fBpostconf\fR \fB-MX\fR [\fB-v\fR] [\fB-c \fIconfig_dir\fR] 36 /* \fIservice\fB/\fItype ...\fR 37 /* 38 /* \fBManaging master.cf service fields:\fR 39 /* 40 /* \fBpostconf\fR \fB-F\fR [\fB-fovx\fR] [\fB-c \fIconfig_dir\fR] 41 /* [\fIservice\fR[\fB/\fItype\fR[\fB/\fIfield\fR]]\fI ...\fR] 42 /* 43 /* \fBpostconf\fR \fB-F\fR [\fB-ev\fR] [\fB-c \fIconfig_dir\fR] 44 /* \fIservice\fB/\fItype\fB/\fIfield\fB=\fIvalue ...\fR 45 /* 46 /* \fBManaging master.cf service parameters:\fR 47 /* 48 /* \fBpostconf\fR \fB-P\fR [\fB-fovx\fR] [\fB-c \fIconfig_dir\fR] 49 /* [\fIservice\fR[\fB/\fItype\fR[\fB/\fIparameter\fR]]\fI ...\fR] 50 /* 51 /* \fBpostconf\fR \fB-P\fR [\fB-ev\fR] [\fB-c \fIconfig_dir\fR] 52 /* \fIservice\fB/\fItype\fB/\fIparameter\fB=\fIvalue ...\fR 53 /* 54 /* \fBpostconf\fR \fB-PX\fR [\fB-v\fR] [\fB-c \fIconfig_dir\fR] 55 /* \fIservice\fB/\fItype\fB/\fIparameter ...\fR 56 /* 57 /* \fBManaging bounce message templates:\fR 58 /* 59 /* \fBpostconf\fR \fB-b\fR [\fB-v\fR] [\fB-c \fIconfig_dir\fR] 60 /* [\fItemplate_file\fR] 61 /* 62 /* \fBpostconf\fR \fB-t\fR [\fB-v\fR] [\fB-c \fIconfig_dir\fR] 63 /* [\fItemplate_file\fR] 64 /* 65 /* \fBManaging other configuration:\fR 66 /* 67 /* \fBpostconf\fR \fB-a\fR|\fB-A\fR|\fB-l\fR|\fB-m\fR [\fB-v\fR] 68 /* [\fB-c \fIconfig_dir\fR] 69 /* DESCRIPTION 70 /* By default, the \fBpostconf\fR(1) command displays the 71 /* values of \fBmain.cf\fR configuration parameters, and warns 72 /* about possible mis-typed parameter names (Postfix 2.9 and later). 73 /* It can also change \fBmain.cf\fR configuration 74 /* parameter values, or display other configuration information 75 /* about the Postfix mail system. 76 /* 77 /* Options: 78 /* .IP \fB-a\fR 79 /* List the available SASL server plug-in types. The SASL 80 /* plug-in type is selected with the \fBsmtpd_sasl_type\fR 81 /* configuration parameter by specifying one of the names 82 /* listed below. 83 /* .RS 84 /* .IP \fBcyrus\fR 85 /* This server plug-in is available when Postfix is built with 86 /* Cyrus SASL support. 87 /* .IP \fBdovecot\fR 88 /* This server plug-in uses the Dovecot authentication server, 89 /* and is available when Postfix is built with any form of SASL 90 /* support. 91 /* .RE 92 /* .IP 93 /* This feature is available with Postfix 2.3 and later. 94 /* .IP \fB-A\fR 95 /* List the available SASL client plug-in types. The SASL 96 /* plug-in type is selected with the \fBsmtp_sasl_type\fR or 97 /* \fBlmtp_sasl_type\fR configuration parameters by specifying 98 /* one of the names listed below. 99 /* .RS 100 /* .IP \fBcyrus\fR 101 /* This client plug-in is available when Postfix is built with 102 /* Cyrus SASL support. 103 /* .RE 104 /* .IP 105 /* This feature is available with Postfix 2.3 and later. 106 /* .IP "\fB-b\fR [\fItemplate_file\fR]" 107 /* Display the message text that appears at the beginning of 108 /* delivery status notification (DSN) messages, replacing 109 /* $\fBname\fR expressions with actual values as described in 110 /* \fBbounce\fR(5). 111 /* 112 /* To override the built-in templates, specify a template file 113 /* name at the end of the \fBpostconf\fR(1) command line, or 114 /* specify a file name in \fBmain.cf\fR with the 115 /* \fBbounce_template_file\fR parameter. 116 /* 117 /* To force selection of the built-in templates, specify an 118 /* empty template file name on the \fBpostconf\fR(1) command 119 /* line (in shell language: ""). 120 /* 121 /* This feature is available with Postfix 2.3 and later. 122 /* .IP "\fB-c \fIconfig_dir\fR" 123 /* The \fBmain.cf\fR configuration file is in the named directory 124 /* instead of the default configuration directory. 125 /* .IP "\fB-C \fIclass,...\fR" 126 /* When displaying \fBmain.cf\fR parameters, select only 127 /* parameters from the specified class(es): 128 /* .RS 129 /* .IP \fBbuiltin\fR 130 /* Parameters with built-in names. 131 /* .IP \fBservice\fR 132 /* Parameters with service-defined names (the first field of 133 /* a \fBmaster.cf\fR entry plus a Postfix-defined suffix). 134 /* .IP \fBuser\fR 135 /* Parameters with user-defined names. 136 /* .IP \fBall\fR 137 /* All the above classes. 138 /* .RE 139 /* .IP 140 /* The default is as if "\fB-C all\fR" is 141 /* specified. 142 /* 143 /* This feature is available with Postfix 2.9 and later. 144 /* .IP \fB-d\fR 145 /* Print \fBmain.cf\fR default parameter settings instead of 146 /* actual settings. 147 /* Specify \fB-df\fR to fold long lines for human readability 148 /* (Postfix 2.9 and later). 149 /* .IP \fB-e\fR 150 /* Edit the \fBmain.cf\fR configuration file, and update 151 /* parameter settings with the "\fIname=value\fR" pairs on the 152 /* \fBpostconf\fR(1) command line. 153 /* 154 /* With \fB-M\fR, edit the \fBmaster.cf\fR configuration file, 155 /* and replace one or more service entries with new values as 156 /* specified with "\fIservice/type=value\fR" on the \fBpostconf\fR(1) 157 /* command line. 158 /* 159 /* With \fB-F\fR, edit the \fBmaster.cf\fR configuration file, 160 /* and replace one or more service fields with new values as 161 /* specied with "\fIservice/type/field=value\fR" on the 162 /* \fBpostconf\fR(1) command line. Currently, the "command" 163 /* field contains the command name and command arguments. this 164 /* may change in the near future, so that the "command" field 165 /* contains only the command name, and a new "arguments" 166 /* pseudofield contains the command arguments. 167 /* 168 /* With \fB-P\fR, edit the \fBmaster.cf\fR configuration file, 169 /* and add or update one or more service parameter settings 170 /* (-o parameter=value settings) with new values as specied 171 /* with "\fIservice/type/parameter=value\fR" on the \fBpostconf\fR(1) 172 /* command line. 173 /* 174 /* In all cases the file is copied to a temporary file then 175 /* renamed into place. Specify quotes to protect special 176 /* characters and whitespace on the \fBpostconf\fR(1) command 177 /* line. 178 /* 179 /* The \fB-e\fR option is no longer needed with Postfix version 180 /* 2.8 and later. 181 /* .IP \fB-f\fR 182 /* Fold long lines when printing \fBmain.cf\fR or \fBmaster.cf\fR 183 /* configuration file entries, for human readability. 184 /* 185 /* This feature is available with Postfix 2.9 and later. 186 /* .IP \fB-F\fR 187 /* Show \fBmaster.cf\fR per-entry field settings (by default 188 /* all services and all fields), formatted as one 189 /* "\fIservice/type/field=value\fR" per line. Specify \fB-Ff\fR 190 /* to fold long lines. 191 /* 192 /* Specify one or more "\fIservice/type/field\fR" instances 193 /* on the \fBpostconf\fR(1) command line to limit the output 194 /* to fields of interest. Trailing parameter name or service 195 /* type fields that are omitted will be handled as "*" wildcard 196 /* fields. 197 /* 198 /* This feature is available with Postfix 2.11 and later. 199 /* .IP \fB-h\fR 200 /* Show parameter or attribute values without the "\fIname\fR 201 /* = " label that normally precedes the value. 202 /* .IP \fB-l\fR 203 /* List the names of all supported mailbox locking methods. 204 /* Postfix supports the following methods: 205 /* .RS 206 /* .IP \fBflock\fR 207 /* A kernel-based advisory locking method for local files only. 208 /* This locking method is available on systems with a BSD 209 /* compatible library. 210 /* .IP \fBfcntl\fR 211 /* A kernel-based advisory locking method for local and remote 212 /* files. 213 /* .IP \fBdotlock\fR 214 /* An application-level locking method. An application locks 215 /* a file named \fIfilename\fR by creating a file named 216 /* \fIfilename\fB.lock\fR. The application is expected to 217 /* remove its own lock file, as well as stale lock files that 218 /* were left behind after abnormal program termination. 219 /* .RE 220 /* .IP \fB-m\fR 221 /* List the names of all supported lookup table types. In 222 /* Postfix configuration files, lookup tables are specified 223 /* as \fItype\fB:\fIname\fR, where \fItype\fR is one of the 224 /* types listed below. The table \fIname\fR syntax depends on 225 /* the lookup table type as described in the DATABASE_README 226 /* document. 227 /* .RS 228 /* .IP \fBbtree\fR 229 /* A sorted, balanced tree structure. Available on systems 230 /* with support for Berkeley DB databases. 231 /* .IP \fBcdb\fR 232 /* A read-optimized structure with no support for incremental 233 /* updates. Available on systems with support for CDB databases. 234 /* .IP \fBcidr\fR 235 /* A table that associates values with Classless Inter-Domain 236 /* Routing (CIDR) patterns. This is described in \fBcidr_table\fR(5). 237 /* .IP \fBdbm\fR 238 /* An indexed file type based on hashing. Available on systems 239 /* with support for DBM databases. 240 /* .IP \fBenviron\fR 241 /* The UNIX process environment array. The lookup key is the 242 /* variable name. Originally implemented for testing, someone 243 /* may find this useful someday. 244 /* .IP \fBfail\fR 245 /* A table that reliably fails all requests. The lookup table 246 /* name is used for logging. This table exists to simplify 247 /* Postfix error tests. 248 /* .IP \fBhash\fR 249 /* An indexed file type based on hashing. Available on systems 250 /* with support for Berkeley DB databases. 251 /* .IP \fBinternal\fR 252 /* A non-shared, in-memory hash table. Its content are lost 253 /* when a process terminates. 254 /* .IP "\fBlmdb\fR" 255 /* OpenLDAP LMDB database (a memory-mapped, persistent file). 256 /* Available on systems with support for LMDB databases. This 257 /* is described in \fBlmdb_table\fR(5). 258 /* .IP "\fBldap\fR (read-only)" 259 /* LDAP database client. This is described in \fBldap_table\fR(5). 260 /* .IP "\fBmemcache\fR" 261 /* Memcache database client. This is described in 262 /* \fBmemcache_table\fR(5). 263 /* .IP "\fBmysql\fR (read-only)" 264 /* MySQL database client. Available on systems with support 265 /* for MySQL databases. This is described in \fBmysql_table\fR(5). 266 /* .IP "\fBpcre\fR (read-only)" 267 /* A lookup table based on Perl Compatible Regular Expressions. 268 /* The file format is described in \fBpcre_table\fR(5). 269 /* .IP "\fBpgsql\fR (read-only)" 270 /* PostgreSQL database client. This is described in 271 /* \fBpgsql_table\fR(5). 272 /* .IP "\fBproxy\fR" 273 /* Postfix \fBproxymap\fR(8) client for shared access to Postfix 274 /* databases. The table name syntax is \fItype\fB:\fIname\fR. 275 /* .IP "\fBregexp\fR (read-only)" 276 /* A lookup table based on regular expressions. The file format 277 /* is described in \fBregexp_table\fR(5). 278 /* .IP \fBsdbm\fR 279 /* An indexed file type based on hashing. Available on systems 280 /* with support for SDBM databases. 281 /* .IP "\fBsocketmap\fR (read-only)" 282 /* Sendmail-style socketmap client. The table name is 283 /* \fBinet\fR:\fIhost\fR:\fIport\fR:\fIname\fR for a TCP/IP 284 /* server, or \fBunix\fR:\fIpathname\fR:\fIname\fR for a 285 /* UNIX-domain server. This is described in \fBsocketmap_table\fR(5). 286 /* .IP "\fBsqlite\fR (read-only)" 287 /* SQLite database. This is described in \fBsqlite_table\fR(5). 288 /* .IP "\fBstatic\fR (read-only)" 289 /* A table that always returns its name as lookup result. For 290 /* example, \fBstatic:foobar\fR always returns the string 291 /* \fBfoobar\fR as lookup result. 292 /* .IP "\fBtcp\fR (read-only)" 293 /* TCP/IP client. The protocol is described in \fBtcp_table\fR(5). 294 /* .IP "\fBtexthash\fR (read-only)" 295 /* Produces similar results as hash: files, except that you 296 /* don't need to run the \fBpostmap\fR(1) command before you 297 /* can use the file, and that it does not detect changes after 298 /* the file is read. 299 /* .IP "\fBunix\fR (read-only)" 300 /* A limited view of the UNIX authentication database. The 301 /* following tables are implemented: 302 /* .RS 303 /*. IP \fBunix:passwd.byname\fR 304 /* The table is the UNIX password database. The key is a login 305 /* name. The result is a password file entry in \fBpasswd\fR(5) 306 /* format. 307 /* .IP \fBunix:group.byname\fR 308 /* The table is the UNIX group database. The key is a group 309 /* name. The result is a group file entry in \fBgroup\fR(5) 310 /* format. 311 /* .RE 312 /* .RE 313 /* .IP 314 /* Other table types may exist depending on how Postfix was 315 /* built. 316 /* .IP \fB-M\fR 317 /* Show \fBmaster.cf\fR file contents instead of \fBmain.cf\fR 318 /* file contents. Specify \fB-Mf\fR to fold long lines for 319 /* human readability. 320 /* 321 /* Specify zero or more arguments, each with a \fIservice-name\fR 322 /* or \fIservice-name/service-type\fR pair, where \fIservice-name\fR 323 /* is the first field of a master.cf entry and \fIservice-type\fR 324 /* is one of (\fBinet\fR, \fBunix\fR, \fBfifo\fR, or \fBpass\fR). 325 /* 326 /* If \fIservice-name\fR or \fIservice-name/service-type\fR 327 /* is specified, only the matching master.cf entries will be 328 /* output. For example, "\fBpostconf -Mf smtp\fR" will output 329 /* all services named "smtp", and "\fBpostconf -Mf smtp/inet\fR" 330 /* will output only the smtp service that listens on the 331 /* network. Trailing service type fields that are omitted 332 /* will be handled as "*" wildcard fields. 333 /* 334 /* This feature is available with Postfix 2.9 and later. The 335 /* syntax was changed from "\fIname.type\fR" to "\fIname/type\fR", 336 /* and "*" wildcard support was added with Postfix 2.11. 337 /* .IP \fB-n\fR 338 /* Show only configuration parameters that have explicit 339 /* \fIname=value\fR settings in \fBmain.cf\fR. Specify \fB-nf\fR 340 /* to fold long lines for human readability (Postfix 2.9 and 341 /* later). 342 /* .IP "\fB-o \fIname=value\fR" 343 /* Override \fBmain.cf\fR parameter settings. 344 /* 345 /* This feature is available with Postfix 2.10 and later. 346 /* .IP \fB-p\fR 347 /* Show \fBmain.cf\fR parameter settings. This is the default. 348 /* 349 /* This feature is available with Postfix 2.11 and later. 350 /* .IP \fB-P\fR 351 /* Show \fBmaster.cf\fR service parameter settings (by default 352 /* all services and all parameters). formatted as one 353 /* "\fIservice/type/parameter=value\fR" per line. Specify 354 /* \fB-Pf\fR to fold long lines. 355 /* 356 /* Specify one or more "\fIservice/type/parameter\fR" instances 357 /* on the \fBpostconf\fR(1) command line to limit the output 358 /* to parameters of interest. Trailing parameter name or 359 /* service type fields that are omitted will be handled as "*" 360 /* wildcard fields. 361 /* 362 /* This feature is available with Postfix 2.11 and later. 363 /* .IP "\fB-t\fR [\fItemplate_file\fR]" 364 /* Display the templates for text that appears at the beginning 365 /* of delivery status notification (DSN) messages, without 366 /* expanding $\fBname\fR expressions. 367 /* 368 /* To override the built-in templates, specify a template file 369 /* name at the end of the \fBpostconf\fR(1) command line, or 370 /* specify a file name in \fBmain.cf\fR with the 371 /* \fBbounce_template_file\fR parameter. 372 /* 373 /* To force selection of the built-in templates, specify an 374 /* empty template file name on the \fBpostconf\fR(1) command 375 /* line (in shell language: ""). 376 /* 377 /* This feature is available with Postfix 2.3 and later. 378 /* .IP \fB-v\fR 379 /* Enable verbose logging for debugging purposes. Multiple 380 /* \fB-v\fR options make the software increasingly verbose. 381 /* .IP \fB-x\fR 382 /* Expand \fI$name\fR in \fBmain.cf\fR or \fBmaster.cf\fR 383 /* parameter values. The expansion is recursive. 384 /* 385 /* This feature is available with Postfix 2.10 and later. 386 /* .IP \fB-X\fR 387 /* Edit the \fBmain.cf\fR configuration file, and remove the 388 /* parameters named on the \fBpostconf\fR(1) command line. 389 /* Specify a list of parameter names, not "\fIname=value\fR" 390 /* pairs. 391 /* 392 /* With \fB-M\fR, edit the \fBmaster.cf\fR configuration file, 393 /* and remove one or more service entries as specified with 394 /* "\fIservice/type\fR" on the \fBpostconf\fR(1) command line. 395 /* 396 /* With \fB-P\fR, edit the \fBmaster.cf\fR configuration file, 397 /* and remove one or more service parameter settings (-o 398 /* parameter=value settings) as specied with 399 /* "\fIservice/type/parameter\fR" on the \fBpostconf\fR(1) 400 /* command line. 401 /* 402 /* In all cases the file is copied to a temporary file then 403 /* renamed into place. Specify quotes to protect special 404 /* characters on the \fBpostconf\fR(1) command line. 405 /* 406 /* There is no \fBpostconf\fR(1) command to perform the reverse 407 /* operation. 408 /* 409 /* This feature is available with Postfix 2.10 and later. 410 /* Support for -M and -P was added with Postfix 2.11. 411 /* .IP \fB-#\fR 412 /* Edit the \fBmain.cf\fR configuration file, and comment out 413 /* the parameters named on the \fBpostconf\fR(1) command line, 414 /* so that those parameters revert to their default values. 415 /* Specify a list of parameter names, not "\fIname=value\fR" 416 /* pairs. 417 /* 418 /* With \fB-M\fR, edit the \fBmaster.cf\fR configuration file, 419 /* and comment out one or more service entries as specified 420 /* with "\fIservice/type\fR" on the \fBpostconf\fR(1) command 421 /* line. 422 /* 423 /* In all cases the file is copied to a temporary file then 424 /* renamed into place. Specify quotes to protect special 425 /* characters on the \fBpostconf\fR(1) command line. 426 /* 427 /* There is no \fBpostconf\fR(1) command to perform the reverse 428 /* operation. 429 /* 430 /* This feature is available with Postfix 2.6 and later. Support 431 /* for -M was added with Postfix 2.11. 432 /* DIAGNOSTICS 433 /* Problems are reported to the standard error stream. 434 /* ENVIRONMENT 435 /* .ad 436 /* .fi 437 /* .IP \fBMAIL_CONFIG\fR 438 /* Directory with Postfix configuration files. 439 /* CONFIGURATION PARAMETERS 440 /* .ad 441 /* .fi 442 /* The following \fBmain.cf\fR parameters are especially 443 /* relevant to this program. 444 /* 445 /* The text below provides only a parameter summary. See 446 /* \fBpostconf\fR(5) for more details including examples. 447 /* .IP "\fBconfig_directory (see 'postconf -d' output)\fR" 448 /* The default location of the Postfix main.cf and master.cf 449 /* configuration files. 450 /* .IP "\fBbounce_template_file (empty)\fR" 451 /* Pathname of a configuration file with bounce message templates. 452 /* FILES 453 /* /etc/postfix/main.cf, Postfix configuration parameters 454 /* /etc/postfix/master.cf, Postfix master daemon configuration 455 /* SEE ALSO 456 /* bounce(5), bounce template file format master(5), master.cf 457 /* configuration file syntax postconf(5), main.cf configuration 458 /* file syntax 459 /* README FILES 460 /* .ad 461 /* .fi 462 /* Use "\fBpostconf readme_directory\fR" or "\fBpostconf 463 /* html_directory\fR" to locate this information. 464 /* .na 465 /* .nf 466 /* DATABASE_README, Postfix lookup table overview 467 /* LICENSE 468 /* .ad 469 /* .fi 470 /* The Secure Mailer license must be distributed with this 471 /* software. 472 /* AUTHOR(S) 473 /* Wietse Venema 474 /* IBM T.J. Watson Research 475 /* P.O. Box 704 476 /* Yorktown Heights, NY 10598, USA 477 /*--*/ 478 479 /* System library. */ 480 481 #include <sys_defs.h> 482 #include <sys/stat.h> 483 #include <stdlib.h> 484 485 /* Utility library. */ 486 487 #include <msg.h> 488 #include <msg_vstream.h> 489 #include <dict.h> 490 #include <htable.h> 491 #include <vstring.h> 492 #include <vstream.h> 493 #include <stringops.h> 494 #include <name_mask.h> 495 #include <warn_stat.h> 496 #include <mymalloc.h> 497 498 /* Global library. */ 499 500 #include <mail_params.h> 501 #include <mail_conf.h> 502 #include <mail_version.h> 503 #include <mail_run.h> 504 #include <mail_dict.h> 505 506 /* Application-specific. */ 507 508 #include <postconf.h> 509 510 /* 511 * Global storage. See postconf.h for description. 512 */ 513 PCF_PARAM_TABLE *pcf_param_table; 514 PCF_MASTER_ENT *pcf_master_table; 515 int pcf_cmd_mode = PCF_DEF_MODE; 516 517 /* 518 * Application fingerprinting. 519 */ 520 MAIL_VERSION_STAMP_DECLARE; 521 522 /* 523 * This program has so many command-line options that we have to implement a 524 * compatibility matrix to weed out the conflicting option combinations, and 525 * to alert the user about option combinations that have no effect. 526 */ 527 528 /* 529 * Options that are mutually-exclusive. First entry must specify the major 530 * modes. Other entries specify conflicts between option modifiers. 531 */ 532 static const int pcf_incompat_options[] = { 533 /* Major modes. */ 534 PCF_SHOW_SASL_SERV | PCF_SHOW_SASL_CLNT | PCF_EXP_DSN_TEMPL \ 535 |PCF_SHOW_LOCKS | PCF_SHOW_MAPS | PCF_DUMP_DSN_TEMPL | PCF_MAIN_PARAM \ 536 |PCF_MASTER_ENTRY | PCF_MASTER_FLD | PCF_MASTER_PARAM, 537 /* Modifiers. */ 538 PCF_SHOW_DEFS | PCF_EDIT_CONF | PCF_SHOW_NONDEF | PCF_COMMENT_OUT \ 539 |PCF_EDIT_EXCL, 540 PCF_FOLD_LINE | PCF_EDIT_CONF | PCF_COMMENT_OUT | PCF_EDIT_EXCL, 541 PCF_SHOW_EVAL | PCF_EDIT_CONF | PCF_COMMENT_OUT | PCF_EDIT_EXCL, 542 PCF_MAIN_OVER | PCF_SHOW_DEFS | PCF_EDIT_CONF | PCF_COMMENT_OUT \ 543 |PCF_EDIT_EXCL, 544 PCF_HIDE_NAME | PCF_EDIT_CONF | PCF_COMMENT_OUT | PCF_EDIT_EXCL, 545 0, 546 }; 547 548 /* 549 * Options, and the only options that they are compatible with. There must 550 * be one entry for each major mode. Other entries specify compatibility 551 * between option modifiers. 552 */ 553 static const int pcf_compat_options[][2] = { 554 /* Major modes. */ 555 {PCF_SHOW_SASL_SERV, 0}, 556 {PCF_SHOW_SASL_CLNT, 0}, 557 {PCF_EXP_DSN_TEMPL, 0}, 558 {PCF_SHOW_LOCKS, 0}, 559 {PCF_SHOW_MAPS, 0,}, 560 {PCF_DUMP_DSN_TEMPL, 0}, 561 {PCF_MAIN_PARAM, (PCF_EDIT_CONF | PCF_EDIT_EXCL | PCF_COMMENT_OUT \ 562 |PCF_FOLD_LINE | PCF_HIDE_NAME | PCF_PARAM_CLASS \ 563 |PCF_SHOW_EVAL | PCF_SHOW_DEFS | PCF_SHOW_NONDEF \ 564 |PCF_MAIN_OVER)}, 565 {PCF_MASTER_ENTRY, (PCF_EDIT_CONF | PCF_EDIT_EXCL | PCF_COMMENT_OUT \ 566 |PCF_FOLD_LINE | PCF_MAIN_OVER | PCF_SHOW_EVAL)}, 567 {PCF_MASTER_FLD, (PCF_EDIT_CONF | PCF_FOLD_LINE | PCF_HIDE_NAME \ 568 |PCF_MAIN_OVER | PCF_SHOW_EVAL)}, 569 {PCF_MASTER_PARAM, (PCF_EDIT_CONF | PCF_EDIT_EXCL | PCF_FOLD_LINE \ 570 |PCF_HIDE_NAME | PCF_MAIN_OVER | PCF_SHOW_EVAL)}, 571 /* Modifiers. */ 572 {PCF_PARAM_CLASS, (PCF_MAIN_PARAM | PCF_SHOW_DEFS | PCF_SHOW_NONDEF)}, 573 0, 574 }; 575 576 /* 577 * Compatibility to string conversion support. 578 */ 579 static const NAME_MASK pcf_compat_names[] = { 580 "-a", PCF_SHOW_SASL_SERV, 581 "-A", PCF_SHOW_SASL_CLNT, 582 "-b", PCF_EXP_DSN_TEMPL, 583 "-C", PCF_PARAM_CLASS, 584 "-d", PCF_SHOW_DEFS, 585 "-e", PCF_EDIT_CONF, 586 "-f", PCF_FOLD_LINE, 587 "-F", PCF_MASTER_FLD, 588 "-h", PCF_HIDE_NAME, 589 "-l", PCF_SHOW_LOCKS, 590 "-m", PCF_SHOW_MAPS, 591 "-M", PCF_MASTER_ENTRY, 592 "-n", PCF_SHOW_NONDEF, 593 "-o", PCF_MAIN_OVER, 594 "-p", PCF_MAIN_PARAM, 595 "-P", PCF_MASTER_PARAM, 596 "-t", PCF_DUMP_DSN_TEMPL, 597 "-x", PCF_SHOW_EVAL, 598 "-X", PCF_EDIT_EXCL, 599 "-#", PCF_COMMENT_OUT, 600 0, 601 }; 602 603 /* usage - enumerate parameters without compatibility info */ 604 605 static void usage(const char *progname) 606 { 607 msg_fatal("usage: %s" 608 " [-a (server SASL types)]" 609 " [-A (client SASL types)]" 610 " [-b (bounce templates)]" 611 " [-c config_dir]" 612 " [-c param_class]" 613 " [-d (parameter defaults)]" 614 " [-e (edit configuration)]" 615 " [-f (fold lines)]" 616 " [-F (master.cf fields)]" 617 " [-h (no names)]" 618 " [-l (lock types)]" 619 " [-m (map types)]" 620 " [-M (master.cf)]" 621 " [-n (non-default parameters)]" 622 " [-o name=value (override parameter value)]" 623 " [-p (main.cf, default)]" 624 " [-P (master.cf parameters)]" 625 " [-t (bounce templates)]" 626 " [-v (verbose)]" 627 " [-x (expand parameter values)]" 628 " [-X (exclude)]" 629 " [-# (comment-out)]" 630 " [name...]", progname); 631 } 632 633 /* pcf_check_exclusive_options - complain about mutually-exclusive options */ 634 635 static void pcf_check_exclusive_options(int optval) 636 { 637 const char *myname = "pcf_check_exclusive_options"; 638 const int *op; 639 int oval; 640 unsigned mask; 641 642 for (op = pcf_incompat_options; (oval = *op) != 0; op++) { 643 oval &= optval; 644 for (mask = ~0; (mask & oval) != 0; mask >>= 1) { 645 if ((mask & oval) != oval) 646 msg_fatal("specify one of %s", 647 str_name_mask(myname, pcf_compat_names, oval)); 648 } 649 } 650 } 651 652 /* pcf_check_compat_options - complain about incompatible options */ 653 654 static void pcf_check_compat_options(int optval) 655 { 656 const char *myname = "pcf_check_compat_options"; 657 VSTRING *buf1 = vstring_alloc(10); 658 VSTRING *buf2 = vstring_alloc(10); 659 const int (*op)[2]; 660 int excess; 661 662 for (op = pcf_compat_options; op[0][0] != 0; op++) { 663 if ((optval & *op[0]) != 0 664 && (excess = (optval & ~((*op)[0] | (*op)[1]))) != 0) 665 msg_fatal("with option %s, do not specify %s", 666 str_name_mask_opt(buf1, myname, pcf_compat_names, 667 (*op)[0], NAME_MASK_NUMBER), 668 str_name_mask_opt(buf2, myname, pcf_compat_names, 669 excess, NAME_MASK_NUMBER)); 670 } 671 vstring_free(buf1); 672 vstring_free(buf2); 673 } 674 675 /* main */ 676 677 int main(int argc, char **argv) 678 { 679 int ch; 680 int fd; 681 struct stat st; 682 ARGV *ext_argv = 0; 683 int param_class = PCF_PARAM_MASK_CLASS; 684 static const NAME_MASK param_class_table[] = { 685 "builtin", PCF_PARAM_FLAG_BUILTIN, 686 "service", PCF_PARAM_FLAG_SERVICE, 687 "user", PCF_PARAM_FLAG_USER, 688 "all", PCF_PARAM_MASK_CLASS, 689 0, 690 }; 691 ARGV *override_params = 0; 692 693 /* 694 * Fingerprint executables and core dumps. 695 */ 696 MAIL_VERSION_STAMP_ALLOCATE; 697 698 /* 699 * Be consistent with file permissions. 700 */ 701 umask(022); 702 703 /* 704 * To minimize confusion, make sure that the standard file descriptors 705 * are open before opening anything else. XXX Work around for 44BSD where 706 * fstat can return EBADF on an open file descriptor. 707 */ 708 for (fd = 0; fd < 3; fd++) 709 if (fstat(fd, &st) == -1 710 && (close(fd), open("/dev/null", O_RDWR, 0)) != fd) 711 msg_fatal("open /dev/null: %m"); 712 713 /* 714 * Set up logging. 715 */ 716 msg_vstream_init(argv[0], VSTREAM_ERR); 717 718 /* 719 * Parse JCL. 720 */ 721 while ((ch = GETOPT(argc, argv, "aAbc:C:deEfFhlmMno:pPtvxX#")) > 0) { 722 switch (ch) { 723 case 'a': 724 pcf_cmd_mode |= PCF_SHOW_SASL_SERV; 725 break; 726 case 'A': 727 pcf_cmd_mode |= PCF_SHOW_SASL_CLNT; 728 break; 729 case 'b': 730 pcf_cmd_mode |= PCF_EXP_DSN_TEMPL; 731 if (ext_argv) 732 msg_fatal("specify one of -b and -t"); 733 ext_argv = argv_alloc(2); 734 argv_add(ext_argv, "bounce", "-SVnexpand_templates", (char *) 0); 735 break; 736 case 'c': 737 if (setenv(CONF_ENV_PATH, optarg, 1) < 0) 738 msg_fatal("out of memory"); 739 break; 740 case 'C': 741 param_class = name_mask_opt("-C option", param_class_table, 742 optarg, NAME_MASK_ANY_CASE | NAME_MASK_FATAL); 743 break; 744 case 'd': 745 pcf_cmd_mode |= PCF_SHOW_DEFS; 746 break; 747 case 'e': 748 pcf_cmd_mode |= PCF_EDIT_CONF; 749 break; 750 case 'f': 751 pcf_cmd_mode |= PCF_FOLD_LINE; 752 break; 753 case 'F': 754 pcf_cmd_mode |= PCF_MASTER_FLD; 755 break; 756 case '#': 757 pcf_cmd_mode |= PCF_COMMENT_OUT; 758 break; 759 case 'h': 760 pcf_cmd_mode |= PCF_HIDE_NAME; 761 break; 762 case 'l': 763 pcf_cmd_mode |= PCF_SHOW_LOCKS; 764 break; 765 case 'm': 766 pcf_cmd_mode |= PCF_SHOW_MAPS; 767 break; 768 case 'M': 769 pcf_cmd_mode |= PCF_MASTER_ENTRY; 770 break; 771 case 'n': 772 pcf_cmd_mode |= PCF_SHOW_NONDEF; 773 break; 774 case 'o': 775 pcf_cmd_mode |= PCF_MAIN_OVER; 776 if (override_params == 0) 777 override_params = argv_alloc(2); 778 argv_add(override_params, optarg, (char *) 0); 779 break; 780 case 'p': 781 pcf_cmd_mode |= PCF_MAIN_PARAM; 782 break; 783 case 'P': 784 pcf_cmd_mode |= PCF_MASTER_PARAM; 785 break; 786 case 't': 787 pcf_cmd_mode |= PCF_DUMP_DSN_TEMPL; 788 if (ext_argv) 789 msg_fatal("specify one of -b and -t"); 790 ext_argv = argv_alloc(2); 791 argv_add(ext_argv, "bounce", "-SVndump_templates", (char *) 0); 792 break; 793 case 'x': 794 pcf_cmd_mode |= PCF_SHOW_EVAL; 795 break; 796 case 'X': 797 /* This is irreversible, therefore require two-finger action. */ 798 pcf_cmd_mode |= PCF_EDIT_EXCL; 799 break; 800 case 'v': 801 msg_verbose++; 802 break; 803 default: 804 usage(argv[0]); 805 } 806 } 807 808 /* 809 * Make all options explicit, before checking their compatibility. 810 */ 811 #define PCF_MAIN_OR_MASTER \ 812 (PCF_MAIN_PARAM | PCF_MASTER_ENTRY | PCF_MASTER_FLD | PCF_MASTER_PARAM) 813 814 if ((pcf_cmd_mode & pcf_incompat_options[0]) == 0) 815 pcf_cmd_mode |= PCF_MAIN_PARAM; 816 if ((pcf_cmd_mode & PCF_MAIN_OR_MASTER) 817 && argv[optind] && strchr(argv[optind], '=')) 818 pcf_cmd_mode |= PCF_EDIT_CONF; 819 820 /* 821 * Sanity check. 822 */ 823 pcf_check_exclusive_options(pcf_cmd_mode); 824 pcf_check_compat_options(pcf_cmd_mode); 825 826 if ((pcf_cmd_mode & PCF_EDIT_CONF) && argc == optind) 827 msg_fatal("-e requires name=value argument"); 828 829 /* 830 * Display bounce template information and exit. 831 */ 832 if (ext_argv) { 833 if (argv[optind]) { 834 if (argv[optind + 1]) 835 msg_fatal("options -b and -t require at most one template file"); 836 argv_add(ext_argv, "-o", 837 concatenate(VAR_BOUNCE_TMPL, "=", 838 argv[optind], (char *) 0), 839 (char *) 0); 840 } 841 /* Grr... */ 842 argv_add(ext_argv, "-o", 843 concatenate(VAR_QUEUE_DIR, "=", ".", (char *) 0), 844 (char *) 0); 845 mail_conf_read(); 846 mail_run_replace(var_daemon_dir, ext_argv->argv); 847 /* NOTREACHED */ 848 } 849 850 /* 851 * If showing map types, show them and exit 852 */ 853 if (pcf_cmd_mode & PCF_SHOW_MAPS) { 854 mail_dict_init(); 855 pcf_show_maps(); 856 } 857 858 /* 859 * If showing locking methods, show them and exit 860 */ 861 else if (pcf_cmd_mode & PCF_SHOW_LOCKS) { 862 pcf_show_locks(); 863 } 864 865 /* 866 * If showing master.cf entries, show them and exit 867 */ 868 else if ((pcf_cmd_mode & (PCF_MASTER_ENTRY | PCF_MASTER_FLD | PCF_MASTER_PARAM)) 869 && !(pcf_cmd_mode & (PCF_EDIT_CONF | PCF_EDIT_EXCL | PCF_COMMENT_OUT))) { 870 pcf_read_master(PCF_FAIL_ON_OPEN_ERROR); 871 pcf_read_parameters(); 872 if (override_params) 873 pcf_set_parameters(override_params->argv); 874 pcf_register_builtin_parameters(basename(argv[0]), getpid()); 875 pcf_register_service_parameters(); 876 pcf_register_user_parameters(); 877 if (pcf_cmd_mode & PCF_MASTER_FLD) 878 pcf_show_master_fields(VSTREAM_OUT, pcf_cmd_mode, argc - optind, 879 argv + optind); 880 else if (pcf_cmd_mode & PCF_MASTER_PARAM) 881 pcf_show_master_params(VSTREAM_OUT, pcf_cmd_mode, argc - optind, 882 argv + optind); 883 else 884 pcf_show_master_entries(VSTREAM_OUT, pcf_cmd_mode, argc - optind, 885 argv + optind); 886 } 887 888 /* 889 * If showing SASL plug-in types, show them and exit 890 */ 891 else if (pcf_cmd_mode & PCF_SHOW_SASL_SERV) { 892 pcf_show_sasl(PCF_SHOW_SASL_SERV); 893 } else if (pcf_cmd_mode & PCF_SHOW_SASL_CLNT) { 894 pcf_show_sasl(PCF_SHOW_SASL_CLNT); 895 } 896 897 /* 898 * Edit main.cf or master.cf. 899 */ 900 else if (pcf_cmd_mode & (PCF_EDIT_CONF | PCF_COMMENT_OUT | PCF_EDIT_EXCL)) { 901 if (optind == argc) 902 msg_fatal("missing service argument"); 903 if (pcf_cmd_mode & (PCF_MASTER_ENTRY | PCF_MASTER_FLD | PCF_MASTER_PARAM)) { 904 pcf_edit_master(pcf_cmd_mode, argc - optind, argv + optind); 905 } else { 906 pcf_edit_main(pcf_cmd_mode, argc - optind, argv + optind); 907 } 908 } 909 910 /* 911 * If showing non-default values, read main.cf. 912 */ 913 else { 914 if ((pcf_cmd_mode & PCF_SHOW_DEFS) == 0) { 915 pcf_read_parameters(); 916 if (override_params) 917 pcf_set_parameters(override_params->argv); 918 } 919 pcf_register_builtin_parameters(basename(argv[0]), getpid()); 920 921 /* 922 * Add service-dependent parameters (service names from master.cf) 923 * and user-defined parameters ($name macros in parameter values in 924 * main.cf and master.cf, but only if those names have a name=value 925 * in main.cf or master.cf). 926 */ 927 pcf_read_master(PCF_WARN_ON_OPEN_ERROR); 928 pcf_register_service_parameters(); 929 if ((pcf_cmd_mode & PCF_SHOW_DEFS) == 0) 930 pcf_register_user_parameters(); 931 932 /* 933 * Show the requested values. 934 */ 935 pcf_show_parameters(VSTREAM_OUT, pcf_cmd_mode, param_class, 936 argv + optind); 937 938 /* 939 * Flag unused parameters. This makes no sense with "postconf -d", 940 * because that ignores all the user-specified parameters and 941 * user-specified macro expansions in main.cf. 942 */ 943 if ((pcf_cmd_mode & PCF_SHOW_DEFS) == 0) { 944 pcf_flag_unused_main_parameters(); 945 pcf_flag_unused_master_parameters(); 946 } 947 } 948 vstream_fflush(VSTREAM_OUT); 949 exit(0); 950 } 951