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