1 /*        $NetBSD: postconf.c,v 1.5 2025/02/25 19:15: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-dfhHnopqvx\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-foqvx\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-fhHoqvx\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-fhHoqvx\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 "\fBmongodb\fR"
299 /*        MongoDB database client. This is described in
300 /*        \fBmongodb_table\fR(5).
301 /*
302 /*        This feature is available with Postfix 3.9 and later.
303 /* .IP "\fBmysql\fR (read-only)"
304 /*        MySQL database client.  Available on systems with support
305 /*        for MySQL databases.  This is described in \fBmysql_table\fR(5).
306 /* .IP "\fBpcre\fR (read-only)"
307 /*        A lookup table based on Perl Compatible Regular Expressions.
308 /*        The file format is described in \fBpcre_table\fR(5).
309 /* .IP "\fBpgsql\fR (read-only)"
310 /*        PostgreSQL database client. This is described in
311 /*        \fBpgsql_table\fR(5).
312 /*
313 /*        This feature is available with Postfix 2.1 and later.
314 /* .IP "\fBpipemap\fR (read-only)"
315 /*        A lookup table that constructs a pipeline of tables.  Example:
316 /*        "\fBpipemap:{\fItype_1:name_1,  ..., type_n:name_n\fB}\fR".
317 /*        Each "pipemap:" query is given to the first table.  Each
318 /*        lookup result becomes the query for the next table in the
319 /*        pipeline, and the last table produces the final result.
320 /*        When any table lookup produces no result, the pipeline
321 /*        produces no result. The first and last characters of the
322 /*        "pipemap:" table name must be "\fB{\fR" and "\fB}\fR".
323 /*        Within these, individual maps are separated with comma or
324 /*        whitespace.
325 /*
326 /*        This feature is available with Postfix 3.0 and later.
327 /* .IP "\fBproxy\fR"
328 /*        Postfix \fBproxymap\fR(8) client for shared access to Postfix
329 /*        databases. The table name syntax is \fItype\fB:\fIname\fR.
330 /*
331 /*        This feature is available with Postfix 2.0 and later.
332 /* .IP "\fBrandmap\fR (read-only)"
333 /*        An in-memory table that performs random selection. Example:
334 /*        "\fBrandmap:{\fIresult_1, ..., result_n\fB}\fR". Each table query
335 /*        returns a random choice from the specified results. The first
336 /*        and last characters of the "randmap:" table name must be
337 /*        "\fB{\fR" and "\fB}\fR".  Within these, individual results
338 /*        are separated with comma or whitespace. To give a specific
339 /*        result more weight, specify it multiple times.
340 /*
341 /*        This feature is available with Postfix 3.0 and later.
342 /* .IP "\fBregexp\fR (read-only)"
343 /*        A lookup table based on regular expressions. The file format
344 /*        is described in \fBregexp_table\fR(5).
345 /* .IP \fBsdbm\fR
346 /*        An indexed file type based on hashing.  Available on systems
347 /*        with support for SDBM databases.
348 /*
349 /*        This feature is available with Postfix 2.2 and later.
350 /* .IP "\fBsocketmap\fR (read-only)"
351 /*        Sendmail-style socketmap client. The table name is
352 /*        \fBinet\fR:\fIhost\fR:\fIport\fR:\fIname\fR for a TCP/IP
353 /*        server, or \fBunix\fR:\fIpathname\fR:\fIname\fR for a
354 /*        UNIX-domain server. This is described in \fBsocketmap_table\fR(5).
355 /*
356 /*        This feature is available with Postfix 2.10 and later.
357 /* .IP "\fBsqlite\fR (read-only)"
358 /*        SQLite database. This is described in \fBsqlite_table\fR(5).
359 /*
360 /*        This feature is available with Postfix 2.8 and later.
361 /* .IP "\fBstatic\fR (read-only)"
362 /*        A table that always returns its name as lookup result. For
363 /*        example, \fBstatic:foobar\fR always returns the string
364 /*        \fBfoobar\fR as lookup result. Specify "\fBstatic:{ \fItext
365 /*        with whitespace\fB }\fR" when the result contains whitespace;
366 /*        this form ignores whitespace after the opening "\fB{\fR"
367 /*        and before the closing
368 /*        "\fB}\fR". See also the \fIinline:\fR map.
369 /*
370 /*        The form "\fBstatic:{\fItext\fB}\fR is available with Postfix
371 /*        3.0 and later.
372 /* .IP "\fBtcp\fR (read-only)"
373 /*        TCP/IP client. The protocol is described in \fBtcp_table\fR(5).
374 /* .IP "\fBtexthash\fR (read-only)"
375 /*        Produces similar results as hash: files, except that you
376 /*        don't need to run the \fBpostmap\fR(1) command before you
377 /*        can use the file, and that it does not detect changes after
378 /*        the file is read.
379 /*
380 /*        This feature is available with Postfix 2.8 and later.
381 /* .IP "\fBunionmap\fR (read-only)"
382 /*        A table that sends each query to multiple lookup tables and
383 /*        that concatenates all found results, separated by comma.
384 /*        The table name syntax is the same as for \fBpipemap\fR.
385 /*
386 /*        This feature is available with Postfix 3.0 and later.
387 /* .IP "\fBunix\fR (read-only)"
388 /*        A limited view of the UNIX authentication database. The
389 /*        following tables are implemented:
390 /* .RS
391 /*. IP \fBunix:passwd.byname\fR
392 /*        The table is the UNIX password database. The key is a login
393 /*        name.  The result is a password file entry in \fBpasswd\fR(5)
394 /*        format.
395 /* .IP \fBunix:group.byname\fR
396 /*        The table is the UNIX group database. The key is a group
397 /*        name.  The result is a group file entry in \fBgroup\fR(5)
398 /*        format.
399 /* .RE
400 /* .RE
401 /* .IP
402 /*        Other table types may exist depending on how Postfix was
403 /*        built.
404 /* .IP \fB-M\fR
405 /*        Show \fBmaster.cf\fR file contents instead of \fBmain.cf\fR
406 /*        file contents.  Specify \fB-Mf\fR to fold long lines for
407 /*        human readability.
408 /*
409 /*        Specify zero or more arguments, each with a \fIservice-name\fR
410 /*        or \fIservice-name/service-type\fR pair, where \fIservice-name\fR
411 /*        is the first field of a master.cf entry and \fIservice-type\fR
412 /*        is one of (\fBinet\fR, \fBunix\fR, \fBfifo\fR, or \fBpass\fR).
413 /*
414 /*        If \fIservice-name\fR or \fIservice-name/service-type\fR
415 /*        is specified, only the matching master.cf entries will be
416 /*        output. For example, "\fBpostconf -Mf smtp\fR" will output
417 /*        all services named "smtp", and "\fBpostconf -Mf smtp/inet\fR"
418 /*        will output only the smtp service that listens on the
419 /*        network.  Trailing service type fields that are omitted
420 /*        will be handled as "*" wildcard fields.
421 /*
422 /*        This feature is available with Postfix 2.9 and later. The
423 /*        syntax was changed from "\fIname.type\fR" to "\fIname/type\fR",
424 /*        and "*" wildcard support was added with Postfix 2.11.
425 /* .IP \fB-n\fR
426 /*        Show only configuration parameters that have explicit
427 /*        \fIname=value\fR settings in \fBmain.cf\fR.  Specify \fB-nf\fR
428 /*        to fold long lines for human readability (Postfix 2.9 and
429 /*        later). To show settings that differ from built-in defaults
430 /*        only, use the following bash syntax:
431 /* .nf
432 /*            LANG=C comm -23 <(postconf -n) <(postconf -d)
433 /* .fi
434 /*        Replace "-23" with "-12" to show settings that duplicate
435 /*        built-in defaults.
436 /* .IP "\fB-o \fIname=value\fR"
437 /*        Override \fBmain.cf\fR parameter settings.  This lets you see
438 /*        the effect changing a parameter would have when it is used in
439 /*        other configuration parameters, e.g.:
440 /*        .nf
441 /*            postconf -x -o stress=yes
442 /*        .fi
443 /*
444 /*        This feature is available with Postfix 2.10 and later.
445 /* .IP \fB-p\fR
446 /*        Show \fBmain.cf\fR parameter settings. This is the default.
447 /*
448 /*        This feature is available with Postfix 2.11 and later.
449 /* .IP \fB-P\fR
450 /*        Show \fBmaster.cf\fR service parameter settings (by default
451 /*        all services and all parameters), formatted as
452 /*        "\fIservice/type/parameter=value\fR", one per line.  Specify
453 /*        \fB-Pf\fR to fold long lines.
454 /*
455 /*        Specify one or more "\fIservice/type/parameter\fR" instances
456 /*        on the \fBpostconf\fR(1) command line to limit the output
457 /*        to parameters of interest.  Trailing parameter name or
458 /*        service type fields that are omitted will be handled as "*"
459 /*        wildcard fields.
460 /*
461 /*        This feature is available with Postfix 2.11 and later.
462 /* .IP \fB-q\fR
463 /*        Do not log warnings for deprecated or unused parameters.
464 /*
465 /*        This feature is available with Postfix 3.9 and later.
466 /* .IP "\fB-t\fR [\fItemplate_file\fR]"
467 /*        Display the templates for text that appears at the beginning
468 /*        of delivery status notification (DSN) messages, without
469 /*        expanding $\fBname\fR expressions.
470 /*
471 /*        To override the \fBbounce_template_file\fR parameter setting,
472 /*        specify a template file name at the end of the "\fBpostconf
473 /*        -t\fR" command line. Specify an empty file name to display
474 /*        built-in templates (in shell language: "").
475 /*
476 /*        This feature is available with Postfix 2.3 and later.
477 /* .IP "\fB-T \fImode\fR"
478 /*        If Postfix is compiled without TLS support, the \fB-T\fR option
479 /*        produces no output.  Otherwise, if an invalid \fImode\fR is specified,
480 /*        the \fB-T\fR option reports an error and exits with a non-zero status
481 /*        code. The valid modes are:
482 /* .RS
483 /* .IP \fBcompile-version\fR
484 /*        Output the OpenSSL version that Postfix was compiled with
485 /*        (i.e. the OpenSSL version in a header file). The output
486 /*        format is the same as with the command "\fBopenssl version\fR".
487 /* .IP \fBrun-version\fR
488 /*        Output the OpenSSL version that Postfix is linked with at
489 /*        runtime (i.e. the OpenSSL version in a shared library).
490 /* .IP \fBpublic-key-algorithms\fR
491 /*        Output the lower-case names of the supported public-key
492 /*        algorithms, one per-line.
493 /* .RE
494 /* .IP
495 /*        This feature is available with Postfix 3.1 and later.
496 /* .IP \fB-v\fR
497 /*        Enable verbose logging for debugging purposes. Multiple
498 /*        \fB-v\fR options make the software increasingly verbose.
499 /* .IP \fB-x\fR
500 /*        Expand \fI$name\fR in \fBmain.cf\fR or \fBmaster.cf\fR
501 /*        parameter values. The expansion is recursive.
502 /*
503 /*        This feature is available with Postfix 2.10 and later.
504 /* .IP \fB-X\fR
505 /*        Edit the \fBmain.cf\fR configuration file, and remove the
506 /*        parameters named on the \fBpostconf\fR(1) command line.
507 /*        Specify a list of parameter names, not "\fIname=value\fR"
508 /*        pairs.
509 /*
510 /*        With \fB-M\fR, edit the \fBmaster.cf\fR configuration file,
511 /*        and remove one or more service entries as specified with
512 /*        "\fIservice/type\fR" on the \fBpostconf\fR(1) command line.
513 /*
514 /*        With \fB-P\fR, edit the \fBmaster.cf\fR configuration file,
515 /*        and remove one or more service parameter settings (-o
516 /*        parameter=value settings) as specified with
517 /*        "\fIservice/type/parameter\fR" on the \fBpostconf\fR(1)
518 /*        command line.
519 /*
520 /*        In all cases the file is copied to a temporary file then
521 /*        renamed into place.  Specify quotes to protect special
522 /*        characters on the \fBpostconf\fR(1) command line.
523 /*
524 /*        There is no \fBpostconf\fR(1) command to perform the reverse
525 /*        operation.
526 /*
527 /*        This feature is available with Postfix 2.10 and later.
528 /*        Support for -M and -P was added with Postfix 2.11.
529 /* .IP \fB-#\fR
530 /*        Edit the \fBmain.cf\fR configuration file, and comment out
531 /*        the parameters named on the \fBpostconf\fR(1) command line,
532 /*        so that those parameters revert to their default values.
533 /*        Specify a list of parameter names, not "\fIname=value\fR"
534 /*        pairs.
535 /*
536 /*        With \fB-M\fR, edit the \fBmaster.cf\fR configuration file,
537 /*        and comment out one or more service entries as specified
538 /*        with "\fIservice/type\fR" on the \fBpostconf\fR(1) command
539 /*        line.
540 /*
541 /*        In all cases the file is copied to a temporary file then
542 /*        renamed into place.  Specify quotes to protect special
543 /*        characters on the \fBpostconf\fR(1) command line.
544 /*
545 /*        There is no \fBpostconf\fR(1) command to perform the reverse
546 /*        operation.
547 /*
548 /*        This feature is available with Postfix 2.6 and later. Support
549 /*        for -M was added with Postfix 2.11.
550 /* DIAGNOSTICS
551 /*        Problems are reported to the standard error stream.
552 /* ENVIRONMENT
553 /* .ad
554 /* .fi
555 /* .IP \fBMAIL_CONFIG\fR
556 /*        Directory with Postfix configuration files.
557 /* CONFIGURATION PARAMETERS
558 /* .ad
559 /* .fi
560 /*        The following \fBmain.cf\fR parameters are especially
561 /*        relevant to this program.
562 /*
563 /*        The text below provides only a parameter summary. See
564 /*        \fBpostconf\fR(5) for more details including examples.
565 /* .IP "\fBconfig_directory (see 'postconf -d' output)\fR"
566 /*        The default location of the Postfix main.cf and master.cf
567 /*        configuration files.
568 /* .IP "\fBbounce_template_file (empty)\fR"
569 /*        Pathname of a configuration file with bounce message templates.
570 /* FILES
571 /*        /etc/postfix/main.cf, Postfix configuration parameters
572 /*        /etc/postfix/master.cf, Postfix master daemon configuration
573 /* SEE ALSO
574 /*        bounce(5), bounce template file format
575 /*        master(5), master.cf configuration file syntax
576 /*        postconf(5), main.cf configuration file syntax
577 /* README FILES
578 /* .ad
579 /* .fi
580 /*        Use "\fBpostconf readme_directory\fR" or "\fBpostconf
581 /*        html_directory\fR" to locate this information.
582 /* .na
583 /* .nf
584 /*        DATABASE_README, Postfix lookup table overview
585 /* LICENSE
586 /* .ad
587 /* .fi
588 /*        The Secure Mailer license must be distributed with this
589 /*        software.
590 /* AUTHOR(S)
591 /*        Wietse Venema
592 /*        IBM T.J. Watson Research
593 /*        P.O. Box 704
594 /*        Yorktown Heights, NY 10598, USA
595 /*
596 /*        Wietse Venema
597 /*        Google, Inc.
598 /*        111 8th Avenue
599 /*        New York, NY 10011, USA
600 /*--*/
601 
602 /* System library. */
603 
604 #include <sys_defs.h>
605 #include <sys/stat.h>
606 #include <stdlib.h>
607 
608 /* Utility library. */
609 
610 #include <msg.h>
611 #include <msg_vstream.h>
612 #include <dict.h>
613 #include <htable.h>
614 #include <vstring.h>
615 #include <vstream.h>
616 #include <stringops.h>
617 #include <name_mask.h>
618 #include <warn_stat.h>
619 #include <mymalloc.h>
620 
621 /* Global library. */
622 
623 #include <mail_params.h>
624 #include <mail_conf.h>
625 #include <mail_version.h>
626 #include <mail_run.h>
627 #include <mail_dict.h>
628 #include <compat_level.h>
629 
630 /* Application-specific. */
631 
632 #include <postconf.h>
633 
634  /*
635   * Global storage. See postconf.h for description.
636   */
637 PCF_PARAM_TABLE *pcf_param_table;
638 PCF_MASTER_ENT *pcf_master_table;
639 int     pcf_cmd_mode = PCF_DEF_MODE;
640 
641  /*
642   * Application fingerprinting.
643   */
644 MAIL_VERSION_STAMP_DECLARE;
645 
646  /*
647   * This program has so many command-line options that we have to implement a
648   * compatibility matrix to weed out the conflicting option combinations, and
649   * to alert the user about option combinations that have no effect.
650   */
651 
652  /*
653   * Options that are mutually-exclusive. First entry must specify the major
654   * modes. Other entries specify conflicts between option modifiers.
655   */
656 static const int pcf_incompat_options[] = {
657     /* Major modes. */
658     PCF_SHOW_SASL_SERV | PCF_SHOW_SASL_CLNT | PCF_EXP_DSN_TEMPL \
659     |PCF_SHOW_LOCKS | PCF_SHOW_MAPS | PCF_DUMP_DSN_TEMPL | PCF_MAIN_PARAM \
660     |PCF_MASTER_ENTRY | PCF_MASTER_FLD | PCF_MASTER_PARAM | PCF_SHOW_TLS,
661     /* Modifiers. */
662     PCF_SHOW_DEFS | PCF_EDIT_CONF | PCF_SHOW_NONDEF | PCF_COMMENT_OUT \
663     |PCF_EDIT_EXCL,
664     PCF_FOLD_LINE | PCF_EDIT_CONF | PCF_COMMENT_OUT | PCF_EDIT_EXCL,
665     PCF_SHOW_EVAL | PCF_EDIT_CONF | PCF_COMMENT_OUT | PCF_EDIT_EXCL,
666     PCF_MAIN_OVER | PCF_SHOW_DEFS | PCF_EDIT_CONF | PCF_COMMENT_OUT \
667     |PCF_EDIT_EXCL,
668     PCF_HIDE_NAME | PCF_EDIT_CONF | PCF_COMMENT_OUT | PCF_EDIT_EXCL \
669     |PCF_HIDE_VALUE,
670     0,
671 };
672 
673  /*
674   * Options, and the only options that they are compatible with. There must
675   * be one entry for each major mode. Other entries specify compatibility
676   * between option modifiers.
677   */
678 static const int pcf_compat_options[][2] = {
679     /* Major modes. */
680     {PCF_SHOW_SASL_SERV, 0},
681     {PCF_SHOW_SASL_CLNT, 0},
682     {PCF_EXP_DSN_TEMPL, 0},
683     {PCF_SHOW_LOCKS, 0},
684     {PCF_SHOW_MAPS, 0,},
685     {PCF_SHOW_TLS, 0,},
686     {PCF_DUMP_DSN_TEMPL, 0},
687     {PCF_MAIN_PARAM, (PCF_EDIT_CONF | PCF_EDIT_EXCL | PCF_COMMENT_OUT \
688                           |PCF_FOLD_LINE | PCF_HIDE_NAME | PCF_PARAM_CLASS \
689                           |PCF_SHOW_EVAL | PCF_SHOW_DEFS | PCF_SHOW_NONDEF \
690                           |PCF_MAIN_OVER | PCF_HIDE_VALUE)},
691     {PCF_MASTER_ENTRY, (PCF_EDIT_CONF | PCF_EDIT_EXCL | PCF_COMMENT_OUT \
692                               |PCF_FOLD_LINE | PCF_MAIN_OVER | PCF_SHOW_EVAL)},
693     {PCF_MASTER_FLD, (PCF_EDIT_CONF | PCF_FOLD_LINE | PCF_HIDE_NAME \
694                           |PCF_MAIN_OVER | PCF_SHOW_EVAL | PCF_HIDE_VALUE)},
695     {PCF_MASTER_PARAM, (PCF_EDIT_CONF | PCF_EDIT_EXCL | PCF_FOLD_LINE \
696                               |PCF_HIDE_NAME | PCF_MAIN_OVER | PCF_SHOW_EVAL \
697                               |PCF_HIDE_VALUE)},
698     /* Modifiers. */
699     {PCF_PARAM_CLASS, (PCF_MAIN_PARAM | PCF_SHOW_DEFS | PCF_SHOW_NONDEF)},
700     0,
701 };
702 
703  /*
704   * Compatibility to string conversion support.
705   */
706 static const NAME_MASK pcf_compat_names[] = {
707     "-a", PCF_SHOW_SASL_SERV,
708     "-A", PCF_SHOW_SASL_CLNT,
709     "-b", PCF_EXP_DSN_TEMPL,
710     "-C", PCF_PARAM_CLASS,
711     "-d", PCF_SHOW_DEFS,
712     "-e", PCF_EDIT_CONF,
713     "-f", PCF_FOLD_LINE,
714     "-F", PCF_MASTER_FLD,
715     "-h", PCF_HIDE_NAME,
716     "-H", PCF_HIDE_VALUE,
717     "-l", PCF_SHOW_LOCKS,
718     "-m", PCF_SHOW_MAPS,
719     "-M", PCF_MASTER_ENTRY,
720     "-n", PCF_SHOW_NONDEF,
721     "-o", PCF_MAIN_OVER,
722     "-p", PCF_MAIN_PARAM,
723     "-P", PCF_MASTER_PARAM,
724     "-t", PCF_DUMP_DSN_TEMPL,
725     "-T", PCF_SHOW_TLS,
726     "-x", PCF_SHOW_EVAL,
727     "-X", PCF_EDIT_EXCL,
728     "-#", PCF_COMMENT_OUT,
729     0,
730 };
731 
732 /* usage - enumerate parameters without compatibility info */
733 
usage(const char * progname)734 static void usage(const char *progname)
735 {
736     msg_fatal("usage: %s"
737                 " [-a (server SASL types)]"
738                 " [-A (client SASL types)]"
739                 " [-b (bounce templates)]"
740                 " [-c config_dir]"
741                 " [-c param_class]"
742                 " [-d (parameter defaults)]"
743                 " [-e (edit configuration)]"
744                 " [-f (fold lines)]"
745                 " [-F (master.cf fields)]"
746                 " [-h (no names)]"
747                 " [-H (no values)]"
748                 " [-l (lock types)]"
749                 " [-m (map types)]"
750                 " [-M (master.cf)]"
751                 " [-n (non-default parameters)]"
752                 " [-o name=value (override parameter value)]"
753                 " [-p (main.cf, default)]"
754                 " [-P (master.cf parameters)]"
755                 " [-t (bounce templates)]"
756                 " [-T compile-version|run-version|public-key-algorithms]"
757                 " [-v (verbose)]"
758                 " [-x (expand parameter values)]"
759                 " [-X (exclude)]"
760                 " [-# (comment-out)]"
761                 " [name...]", progname);
762 }
763 
764 /* pcf_check_exclusive_options - complain about mutually-exclusive options */
765 
pcf_check_exclusive_options(int optval)766 static void pcf_check_exclusive_options(int optval)
767 {
768     const char *myname = "pcf_check_exclusive_options";
769     const int *op;
770     int     oval;
771     unsigned mask;
772 
773     for (op = pcf_incompat_options; (oval = *op) != 0; op++) {
774           oval &= optval;
775           for (mask = ~0U; (mask & oval) != 0; mask >>= 1) {
776               if ((mask & oval) != oval)
777                     msg_fatal("specify one of %s",
778                                 str_name_mask(myname, pcf_compat_names, oval));
779           }
780     }
781 }
782 
783 /* pcf_check_compat_options - complain about incompatible options */
784 
pcf_check_compat_options(int optval)785 static void pcf_check_compat_options(int optval)
786 {
787     const char *myname = "pcf_check_compat_options";
788     VSTRING *buf1 = vstring_alloc(10);
789     VSTRING *buf2 = vstring_alloc(10);
790     const int (*op)[2];
791     int     excess;
792 
793     optval &= ~PCF_DEF_MODE;
794 
795     for (op = pcf_compat_options; op[0][0] != 0; op++) {
796           if ((optval & *op[0]) != 0
797               && (excess = (optval & ~((*op)[0] | (*op)[1]))) != 0)
798               msg_fatal("with option %s, do not specify %s",
799                           str_name_mask_opt(buf1, myname, pcf_compat_names,
800                                                   (*op)[0], NAME_MASK_NUMBER),
801                           str_name_mask_opt(buf2, myname, pcf_compat_names,
802                                                   excess, NAME_MASK_NUMBER));
803     }
804     vstring_free(buf1);
805     vstring_free(buf2);
806 }
807 
808 /* main */
809 
main(int argc,char ** argv)810 int     main(int argc, char **argv)
811 {
812     int     ch;
813     int     fd;
814     struct stat st;
815     ARGV   *ext_argv = 0;
816     int     param_class = PCF_PARAM_MASK_CLASS;
817     static const NAME_MASK param_class_table[] = {
818           "builtin", PCF_PARAM_FLAG_BUILTIN,
819           "service", PCF_PARAM_FLAG_SERVICE,
820           "user", PCF_PARAM_FLAG_USER,
821           "all", PCF_PARAM_MASK_CLASS,
822           0,
823     };
824     ARGV   *override_params = 0;
825     const char *pcf_tls_arg = 0;
826 
827     /*
828      * Fingerprint executables and core dumps.
829      */
830     MAIL_VERSION_STAMP_ALLOCATE;
831 
832     /*
833      * Be consistent with file permissions.
834      */
835     umask(022);
836 
837     /*
838      * To minimize confusion, make sure that the standard file descriptors
839      * are open before opening anything else. XXX Work around for 44BSD where
840      * fstat can return EBADF on an open file descriptor.
841      */
842     for (fd = 0; fd < 3; fd++)
843           if (fstat(fd, &st) == -1
844               && (close(fd), open("/dev/null", O_RDWR, 0)) != fd)
845               msg_fatal("open /dev/null: %m");
846 
847     /*
848      * Set up logging.
849      */
850     msg_vstream_init(argv[0], VSTREAM_ERR);
851 
852     /*
853      * Check the Postfix library version as soon as we enable logging.
854      */
855     MAIL_VERSION_CHECK;
856 
857     /*
858      * Parse JCL.
859      */
860     while ((ch = GETOPT(argc, argv, "aAbc:C:deEfFhHlmMno:pPqtT:vxX#")) > 0) {
861           switch (ch) {
862           case 'a':
863               pcf_cmd_mode |= PCF_SHOW_SASL_SERV;
864               break;
865           case 'A':
866               pcf_cmd_mode |= PCF_SHOW_SASL_CLNT;
867               break;
868           case 'b':
869               pcf_cmd_mode |= PCF_EXP_DSN_TEMPL;
870               if (ext_argv)
871                     msg_fatal("specify one of -b and -t");
872               ext_argv = argv_alloc(2);
873               argv_add(ext_argv, "bounce", "-SVnexpand_templates", (char *) 0);
874               break;
875           case 'c':
876               if (setenv(CONF_ENV_PATH, optarg, 1) < 0)
877                     msg_fatal("out of memory");
878               break;
879           case 'C':
880               param_class = name_mask_opt("-C option", param_class_table,
881                                     optarg, NAME_MASK_ANY_CASE | NAME_MASK_FATAL);
882               break;
883           case 'd':
884               pcf_cmd_mode |= PCF_SHOW_DEFS;
885               break;
886           case 'e':
887               pcf_cmd_mode |= PCF_EDIT_CONF;
888               break;
889           case 'f':
890               pcf_cmd_mode |= PCF_FOLD_LINE;
891               break;
892           case 'F':
893               pcf_cmd_mode |= PCF_MASTER_FLD;
894               break;
895           case '#':
896               pcf_cmd_mode |= PCF_COMMENT_OUT;
897               break;
898           case 'h':
899               pcf_cmd_mode |= PCF_HIDE_NAME;
900               break;
901           case 'H':
902               pcf_cmd_mode |= PCF_HIDE_VALUE;
903               break;
904           case 'l':
905               pcf_cmd_mode |= PCF_SHOW_LOCKS;
906               break;
907           case 'm':
908               pcf_cmd_mode |= PCF_SHOW_MAPS;
909               break;
910           case 'M':
911               pcf_cmd_mode |= PCF_MASTER_ENTRY;
912               break;
913           case 'n':
914               pcf_cmd_mode |= PCF_SHOW_NONDEF;
915               break;
916           case 'o':
917               pcf_cmd_mode |= PCF_MAIN_OVER;
918               if (override_params == 0)
919                     override_params = argv_alloc(2);
920               argv_add(override_params, optarg, (char *) 0);
921               break;
922           case 'p':
923               pcf_cmd_mode |= PCF_MAIN_PARAM;
924               break;
925           case 'P':
926               pcf_cmd_mode |= PCF_MASTER_PARAM;
927               break;
928           case 'q':
929               pcf_cmd_mode &= ~(PCF_WARN_UNUSED_DEPRECATED);
930               break;
931           case 't':
932               pcf_cmd_mode |= PCF_DUMP_DSN_TEMPL;
933               if (ext_argv)
934                     msg_fatal("specify one of -b and -t");
935               ext_argv = argv_alloc(2);
936               argv_add(ext_argv, "bounce", "-SVndump_templates", (char *) 0);
937               break;
938           case 'T':
939               if (pcf_cmd_mode & PCF_SHOW_TLS)
940                     msg_fatal("At most one -T <mode> option may be specified");
941               pcf_cmd_mode |= PCF_SHOW_TLS;
942               pcf_tls_arg = optarg;
943               break;
944           case 'x':
945               pcf_cmd_mode |= PCF_SHOW_EVAL;
946               break;
947           case 'X':
948               /* This is irreversible, therefore require two-finger action. */
949               pcf_cmd_mode |= PCF_EDIT_EXCL;
950               break;
951           case 'v':
952               msg_verbose++;
953               break;
954           default:
955               usage(argv[0]);
956           }
957     }
958 
959     /*
960      * For consistency with mail_params_init().
961      */
962     compat_level_relop_register();
963 
964     /*
965      * We don't enforce import_environment consistency in this program.
966      *
967      * We don't extract import_environment from main.cf, because the postconf
968      * command must be able to extract parameter settings from main.cf before
969      * all installation parameters such as mail_owner or setgid_group have a
970      * legitimate value.
971      *
972      * We would need the functionality of mail_params_init() including all the
973      * side effects of populating the CONFIG_DICT with default values so that
974      * $name expansion works correctly, but excluding all the parameter value
975      * sanity checks so that it would not abort at installation time.
976      */
977 
978     /*
979      * Make all options explicit, before checking their compatibility.
980      */
981 #define PCF_MAIN_OR_MASTER \
982           (PCF_MAIN_PARAM | PCF_MASTER_ENTRY | PCF_MASTER_FLD | PCF_MASTER_PARAM)
983 
984     if ((pcf_cmd_mode & pcf_incompat_options[0]) == 0)
985           pcf_cmd_mode |= PCF_MAIN_PARAM;
986     if ((pcf_cmd_mode & PCF_MAIN_OR_MASTER)
987           && argv[optind] && strchr(argv[optind], '='))
988           pcf_cmd_mode |= PCF_EDIT_CONF;
989 
990     /*
991      * Sanity check.
992      */
993     pcf_check_exclusive_options(pcf_cmd_mode);
994     pcf_check_compat_options(pcf_cmd_mode);
995 
996     if ((pcf_cmd_mode & PCF_EDIT_CONF) && argc == optind)
997           msg_fatal("-e requires name=value argument");
998 
999     /*
1000      * Display bounce template information and exit.
1001      */
1002     if (ext_argv) {
1003           if (argv[optind]) {
1004               if (argv[optind + 1])
1005                     msg_fatal("options -b and -t require at most one template file");
1006               argv_add(ext_argv, "-o",
1007                          concatenate(VAR_BOUNCE_TMPL, "=",
1008                                          argv[optind], (char *) 0),
1009                          (char *) 0);
1010           }
1011           /* Grr... */
1012           argv_add(ext_argv, "-o",
1013                      concatenate(VAR_QUEUE_DIR, "=", ".", (char *) 0),
1014                      (char *) 0);
1015           mail_conf_read();
1016           mail_run_replace(var_daemon_dir, ext_argv->argv);
1017           /* NOTREACHED */
1018     }
1019 
1020     /*
1021      * If showing map types, show them and exit
1022      */
1023     if (pcf_cmd_mode & PCF_SHOW_MAPS) {
1024           mail_conf_read();
1025           mail_dict_init();
1026           pcf_show_maps();
1027     }
1028 
1029     /*
1030      * If showing locking methods, show them and exit
1031      */
1032     else if (pcf_cmd_mode & PCF_SHOW_LOCKS) {
1033           pcf_show_locks();
1034     }
1035 
1036     /*
1037      * If showing master.cf entries, show them and exit
1038      */
1039     else if ((pcf_cmd_mode & (PCF_MASTER_ENTRY | PCF_MASTER_FLD | PCF_MASTER_PARAM))
1040     && !(pcf_cmd_mode & (PCF_EDIT_CONF | PCF_EDIT_EXCL | PCF_COMMENT_OUT))) {
1041           pcf_read_master(PCF_FAIL_ON_OPEN_ERROR);
1042           pcf_read_parameters();
1043           if (override_params)
1044               pcf_set_parameters(override_params->argv);
1045           pcf_register_builtin_parameters(basename(argv[0]), getpid());
1046           pcf_register_service_parameters();
1047           pcf_register_user_parameters(pcf_cmd_mode);
1048           if (pcf_cmd_mode & PCF_MASTER_FLD)
1049               pcf_show_master_fields(VSTREAM_OUT, pcf_cmd_mode, argc - optind,
1050                                            argv + optind);
1051           else if (pcf_cmd_mode & PCF_MASTER_PARAM)
1052               pcf_show_master_params(VSTREAM_OUT, pcf_cmd_mode, argc - optind,
1053                                            argv + optind);
1054           else
1055               pcf_show_master_entries(VSTREAM_OUT, pcf_cmd_mode, argc - optind,
1056                                             argv + optind);
1057           if (pcf_cmd_mode & PCF_WARN_UNUSED_DEPRECATED)
1058               pcf_flag_unused_master_parameters();
1059     }
1060 
1061     /*
1062      * If showing SASL plug-in types, show them and exit
1063      */
1064     else if (pcf_cmd_mode & PCF_SHOW_SASL_SERV) {
1065           pcf_show_sasl(PCF_SHOW_SASL_SERV);
1066     } else if (pcf_cmd_mode & PCF_SHOW_SASL_CLNT) {
1067           pcf_show_sasl(PCF_SHOW_SASL_CLNT);
1068     }
1069 
1070     /*
1071      * Show TLS info and exit.
1072      */
1073     else if (pcf_cmd_mode & PCF_SHOW_TLS) {
1074           pcf_show_tls(pcf_tls_arg);
1075     }
1076 
1077     /*
1078      * Edit main.cf or master.cf.
1079      */
1080     else if (pcf_cmd_mode & (PCF_EDIT_CONF | PCF_COMMENT_OUT | PCF_EDIT_EXCL)) {
1081           if (optind == argc)
1082               msg_fatal("missing service argument");
1083           if (pcf_cmd_mode & (PCF_MASTER_ENTRY | PCF_MASTER_FLD | PCF_MASTER_PARAM)) {
1084               pcf_edit_master(pcf_cmd_mode, argc - optind, argv + optind);
1085           } else {
1086               pcf_edit_main(pcf_cmd_mode, argc - optind, argv + optind);
1087           }
1088     }
1089 
1090     /*
1091      * If showing non-default values, read main.cf.
1092      */
1093     else {
1094           if ((pcf_cmd_mode & PCF_SHOW_DEFS) == 0) {
1095               pcf_read_parameters();
1096               if (override_params)
1097                     pcf_set_parameters(override_params->argv);
1098           }
1099           pcf_register_builtin_parameters(basename(argv[0]), getpid());
1100 
1101           /*
1102            * Add service-dependent parameters (service names from master.cf)
1103            * and user-defined parameters ($name macros in parameter values in
1104            * main.cf and master.cf, but only if those names have a name=value
1105            * in main.cf or master.cf).
1106            */
1107           pcf_read_master(PCF_WARN_ON_OPEN_ERROR);
1108           pcf_register_service_parameters();
1109           if ((pcf_cmd_mode & PCF_SHOW_DEFS) == 0)
1110               pcf_register_user_parameters(pcf_cmd_mode);
1111 
1112           /*
1113            * Show the requested values.
1114            */
1115           pcf_show_parameters(VSTREAM_OUT, pcf_cmd_mode, param_class,
1116                                   argv + optind);
1117 
1118           /*
1119            * Flag unused or deprecated parameters. This makes no sense with
1120            * "postconf -d", because that ignores all the user-specified
1121            * parameters and user-specified macro expansions in main.cf.
1122            */
1123           if ((pcf_cmd_mode & PCF_SHOW_DEFS) == 0
1124               && (pcf_cmd_mode & PCF_WARN_UNUSED_DEPRECATED) != 0) {
1125               pcf_flag_unused_main_parameters();
1126               pcf_flag_unused_master_parameters();
1127           }
1128     }
1129     vstream_fflush(VSTREAM_OUT);
1130     exit(0);
1131 }
1132