d87a56f3d6e5562cc44f313ace3366d0318ba38a
[exim.git] / src / src / readconf.c
1 /*************************************************
2 *     Exim - an Internet mail transport agent    *
3 *************************************************/
4
5 /* Copyright (c) The Exim Maintainers 2020 - 2023 */
6 /* Copyright (c) University of Cambridge 1995 - 2018 */
7 /* See the file NOTICE for conditions of use and distribution. */
8 /* SPDX-License-Identifier: GPL-2.0-or-later */
9
10 /* Functions for reading the configuration file, and for displaying
11 overall configuration values. Thanks to Brian Candler for the original
12 implementation of the conditional .ifdef etc. */
13
14 #include "exim.h"
15
16 #ifdef MACRO_PREDEF
17 # include "macro_predef.h"
18 #endif
19
20 #define READCONF_DEBUG  if (FALSE)      /* Change to TRUE to enable */
21
22
23 static uschar * syslog_facility_str;
24 static void fn_smtp_receive_timeout(const uschar *, const uschar *, unsigned);
25
26 /*************************************************
27 *           Main configuration options           *
28 *************************************************/
29
30 /* The list of options that can be set in the main configuration file. This
31 must be in alphabetic order because it is searched by binary chop. */
32
33 static optionlist optionlist_config[] = {
34   { "*set_exim_group",          opt_bool|opt_hidden, {&exim_gid_set} },
35   { "*set_exim_user",           opt_bool|opt_hidden, {&exim_uid_set} },
36   { "*set_system_filter_group", opt_bool|opt_hidden, {&system_filter_gid_set} },
37   { "*set_system_filter_user",  opt_bool|opt_hidden, {&system_filter_uid_set} },
38   { "accept_8bitmime",          opt_bool,        {&accept_8bitmime} },
39   { "acl_not_smtp",             opt_stringptr,   {&acl_not_smtp} },
40 #ifdef WITH_CONTENT_SCAN
41   { "acl_not_smtp_mime",        opt_stringptr,   {&acl_not_smtp_mime} },
42 #endif
43   { "acl_not_smtp_start",       opt_stringptr,   {&acl_not_smtp_start} },
44   { "acl_smtp_auth",            opt_stringptr,   {&acl_smtp_auth} },
45   { "acl_smtp_connect",         opt_stringptr,   {&acl_smtp_connect} },
46   { "acl_smtp_data",            opt_stringptr,   {&acl_smtp_data} },
47 #ifndef DISABLE_PRDR
48   { "acl_smtp_data_prdr",       opt_stringptr,   {&acl_smtp_data_prdr} },
49 #endif
50 #ifndef DISABLE_DKIM
51   { "acl_smtp_dkim",            opt_stringptr,   {&acl_smtp_dkim} },
52 #endif
53   { "acl_smtp_etrn",            opt_stringptr,   {&acl_smtp_etrn} },
54   { "acl_smtp_expn",            opt_stringptr,   {&acl_smtp_expn} },
55   { "acl_smtp_helo",            opt_stringptr,   {&acl_smtp_helo} },
56   { "acl_smtp_mail",            opt_stringptr,   {&acl_smtp_mail} },
57   { "acl_smtp_mailauth",        opt_stringptr,   {&acl_smtp_mailauth} },
58 #ifdef WITH_CONTENT_SCAN
59   { "acl_smtp_mime",            opt_stringptr,   {&acl_smtp_mime} },
60 #endif
61   { "acl_smtp_notquit",         opt_stringptr,   {&acl_smtp_notquit} },
62   { "acl_smtp_predata",         opt_stringptr,   {&acl_smtp_predata} },
63   { "acl_smtp_quit",            opt_stringptr,   {&acl_smtp_quit} },
64   { "acl_smtp_rcpt",            opt_stringptr,   {&acl_smtp_rcpt} },
65 #ifndef DISABLE_TLS
66   { "acl_smtp_starttls",        opt_stringptr,   {&acl_smtp_starttls} },
67 #endif
68   { "acl_smtp_vrfy",            opt_stringptr,   {&acl_smtp_vrfy} },
69   { "add_environment",          opt_stringptr,   {&add_environment} },
70   { "admin_groups",             opt_gidlist,     {&admin_groups} },
71   { "allow_domain_literals",    opt_bool,        {&allow_domain_literals} },
72   { "allow_mx_to_ip",           opt_bool,        {&allow_mx_to_ip} },
73   { "allow_utf8_domains",       opt_bool,        {&allow_utf8_domains} },
74   { "auth_advertise_hosts",     opt_stringptr,   {&auth_advertise_hosts} },
75   { "auto_thaw",                opt_time,        {&auto_thaw} },
76 #ifdef WITH_CONTENT_SCAN
77   { "av_scanner",               opt_stringptr,   {&av_scanner} },
78 #endif
79   { "bi_command",               opt_stringptr,   {&bi_command} },
80 #ifdef EXPERIMENTAL_BRIGHTMAIL
81   { "bmi_config_file",          opt_stringptr,   {&bmi_config_file} },
82 #endif
83   { "bounce_message_file",      opt_stringptr,   {&bounce_message_file} },
84   { "bounce_message_text",      opt_stringptr,   {&bounce_message_text} },
85   { "bounce_return_body",       opt_bool,        {&bounce_return_body} },
86   { "bounce_return_linesize_limit", opt_mkint,   {&bounce_return_linesize_limit} },
87   { "bounce_return_message",    opt_bool,        {&bounce_return_message} },
88   { "bounce_return_size_limit", opt_mkint,       {&bounce_return_size_limit} },
89   { "bounce_sender_authentication",opt_stringptr,{&bounce_sender_authentication} },
90   { "callout_domain_negative_expire", opt_time,  {&callout_cache_domain_negative_expire} },
91   { "callout_domain_positive_expire", opt_time,  {&callout_cache_domain_positive_expire} },
92   { "callout_negative_expire",  opt_time,        {&callout_cache_negative_expire} },
93   { "callout_positive_expire",  opt_time,        {&callout_cache_positive_expire} },
94   { "callout_random_local_part",opt_stringptr,   {&callout_random_local_part} },
95   { "check_log_inodes",         opt_int,         {&check_log_inodes} },
96   { "check_log_space",          opt_Kint,        {&check_log_space} },
97   { "check_rfc2047_length",     opt_bool,        {&check_rfc2047_length} },
98   { "check_spool_inodes",       opt_int,         {&check_spool_inodes} },
99   { "check_spool_space",        opt_Kint,        {&check_spool_space} },
100   { "chunking_advertise_hosts", opt_stringptr,   {&chunking_advertise_hosts} },
101   { "commandline_checks_require_admin", opt_bool,{&commandline_checks_require_admin} },
102   { "daemon_smtp_port",         opt_stringptr|opt_hidden, {&daemon_smtp_port} },
103   { "daemon_smtp_ports",        opt_stringptr,   {&daemon_smtp_port} },
104   { "daemon_startup_retries",   opt_int,         {&daemon_startup_retries} },
105   { "daemon_startup_sleep",     opt_time,        {&daemon_startup_sleep} },
106 #ifdef EXPERIMENTAL_DCC
107   { "dcc_direct_add_header",    opt_bool,        {&dcc_direct_add_header} },
108   { "dccifd_address",           opt_stringptr,   {&dccifd_address} },
109   { "dccifd_options",           opt_stringptr,   {&dccifd_options} },
110 #endif
111   { "debug_store",              opt_bool,        {&debug_store} },
112   { "delay_warning",            opt_timelist,    {&delay_warning} },
113   { "delay_warning_condition",  opt_stringptr,   {&delay_warning_condition} },
114   { "deliver_drop_privilege",   opt_bool,        {&deliver_drop_privilege} },
115   { "deliver_queue_load_max",   opt_fixed,       {&deliver_queue_load_max} },
116   { "delivery_date_remove",     opt_bool,        {&delivery_date_remove} },
117 #ifdef ENABLE_DISABLE_FSYNC
118   { "disable_fsync",            opt_bool,        {&disable_fsync} },
119 #endif
120   { "disable_ipv6",             opt_bool,        {&disable_ipv6} },
121 #ifndef DISABLE_DKIM
122   { "dkim_verify_hashes",       opt_stringptr,   {&dkim_verify_hashes} },
123   { "dkim_verify_keytypes",     opt_stringptr,   {&dkim_verify_keytypes} },
124   { "dkim_verify_min_keysizes", opt_stringptr,   {&dkim_verify_min_keysizes} },
125   { "dkim_verify_minimal",      opt_bool,        {&dkim_verify_minimal} },
126   { "dkim_verify_signers",      opt_stringptr,   {&dkim_verify_signers} },
127 #endif
128 #ifdef SUPPORT_DMARC
129   { "dmarc_forensic_sender",    opt_stringptr,   {&dmarc_forensic_sender} },
130   { "dmarc_history_file",       opt_stringptr,   {&dmarc_history_file} },
131   { "dmarc_tld_file",           opt_stringptr,   {&dmarc_tld_file} },
132 #endif
133   { "dns_again_means_nonexist", opt_stringptr,   {&dns_again_means_nonexist} },
134   { "dns_check_names_pattern",  opt_stringptr,   {&check_dns_names_pattern} },
135   { "dns_cname_loops",          opt_int,         {&dns_cname_loops} },
136   { "dns_csa_search_limit",     opt_int,         {&dns_csa_search_limit} },
137   { "dns_csa_use_reverse",      opt_bool,        {&dns_csa_use_reverse} },
138   { "dns_dnssec_ok",            opt_int,         {&dns_dnssec_ok} },
139   { "dns_ipv4_lookup",          opt_stringptr,   {&dns_ipv4_lookup} },
140   { "dns_retrans",              opt_time,        {&dns_retrans} },
141   { "dns_retry",                opt_int,         {&dns_retry} },
142   { "dns_trust_aa",             opt_stringptr,   {&dns_trust_aa} },
143   { "dns_use_edns0",            opt_int,         {&dns_use_edns0} },
144  /* This option is now a no-op, retained for compatibility */
145   { "drop_cr",                  opt_bool,        {&drop_cr} },
146 /*********************************************************/
147   { "dsn_advertise_hosts",      opt_stringptr,   {&dsn_advertise_hosts} },
148   { "dsn_from",                 opt_stringptr,   {&dsn_from} },
149   { "envelope_to_remove",       opt_bool,        {&envelope_to_remove} },
150   { "errors_copy",              opt_stringptr,   {&errors_copy} },
151   { "errors_reply_to",          opt_stringptr,   {&errors_reply_to} },
152 #ifndef DISABLE_EVENT
153   { "event_action",             opt_stringptr,   {&event_action} },
154 #endif
155   { "exim_group",               opt_gid,         {&exim_gid} },
156   { "exim_path",                opt_stringptr,   {&exim_path} },
157   { "exim_user",                opt_uid,         {&exim_uid} },
158   { "exim_version",             opt_stringptr,   {&version_string} },
159   { "extra_local_interfaces",   opt_stringptr,   {&extra_local_interfaces} },
160   { "extract_addresses_remove_arguments", opt_bool, {&extract_addresses_remove_arguments} },
161   { "finduser_retries",         opt_int,         {&finduser_retries} },
162   { "freeze_tell",              opt_stringptr,   {&freeze_tell} },
163   { "gecos_name",               opt_stringptr,   {&gecos_name} },
164   { "gecos_pattern",            opt_stringptr,   {&gecos_pattern} },
165 #ifndef DISABLE_TLS
166   { "gnutls_allow_auto_pkcs11", opt_bool,        {&gnutls_allow_auto_pkcs11} },
167   { "gnutls_compat_mode",       opt_bool,        {&gnutls_compat_mode} },
168 #endif
169   { "header_line_maxsize",      opt_int,         {&header_line_maxsize} },
170   { "header_maxsize",           opt_int,         {&header_maxsize} },
171   { "headers_charset",          opt_stringptr,   {&headers_charset} },
172   { "helo_accept_junk_hosts",   opt_stringptr,   {&helo_accept_junk_hosts} },
173   { "helo_allow_chars",         opt_stringptr,   {&helo_allow_chars} },
174   { "helo_lookup_domains",      opt_stringptr,   {&helo_lookup_domains} },
175   { "helo_try_verify_hosts",    opt_stringptr,   {&helo_try_verify_hosts} },
176   { "helo_verify_hosts",        opt_stringptr,   {&helo_verify_hosts} },
177   { "hold_domains",             opt_stringptr,   {&hold_domains} },
178   { "host_lookup",              opt_stringptr,   {&host_lookup} },
179   { "host_lookup_order",        opt_stringptr,   {&host_lookup_order} },
180   { "host_reject_connection",   opt_stringptr,   {&host_reject_connection} },
181   { "hosts_connection_nolog",   opt_stringptr,   {&hosts_connection_nolog} },
182 #ifdef SUPPORT_PROXY
183   { "hosts_proxy",              opt_stringptr,   {&hosts_proxy} },
184 #endif
185 #ifndef DISABLE_TLS
186   { "hosts_require_alpn",       opt_stringptr,   {&hosts_require_alpn} },
187 #endif
188   { "hosts_require_helo",       opt_stringptr,   {&hosts_require_helo} },
189   { "hosts_treat_as_local",     opt_stringptr,   {&hosts_treat_as_local} },
190 #ifdef EXPERIMENTAL_XCLIENT
191   { "hosts_xclient",            opt_stringptr,   {&hosts_xclient} },
192 #endif
193 #ifdef LOOKUP_IBASE
194   { "ibase_servers",            opt_stringptr,   {&ibase_servers} },
195 #endif
196   { "ignore_bounce_errors_after", opt_time,      {&ignore_bounce_errors_after} },
197   { "ignore_fromline_hosts",    opt_stringptr,   {&ignore_fromline_hosts} },
198   { "ignore_fromline_local",    opt_bool,        {&ignore_fromline_local} },
199   { "keep_environment",         opt_stringptr,   {&keep_environment} },
200   { "keep_malformed",           opt_time,        {&keep_malformed} },
201 #ifdef LOOKUP_LDAP
202   { "ldap_ca_cert_dir",         opt_stringptr,   {&eldap_ca_cert_dir} },
203   { "ldap_ca_cert_file",        opt_stringptr,   {&eldap_ca_cert_file} },
204   { "ldap_cert_file",           opt_stringptr,   {&eldap_cert_file} },
205   { "ldap_cert_key",            opt_stringptr,   {&eldap_cert_key} },
206   { "ldap_cipher_suite",        opt_stringptr,   {&eldap_cipher_suite} },
207   { "ldap_default_servers",     opt_stringptr,   {&eldap_default_servers} },
208   { "ldap_require_cert",        opt_stringptr,   {&eldap_require_cert} },
209   { "ldap_start_tls",           opt_bool,        {&eldap_start_tls} },
210   { "ldap_version",             opt_int,         {&eldap_version} },
211 #endif
212 #ifndef DISABLE_ESMTP_LIMITS
213   { "limits_advertise_hosts", opt_stringptr, {&limits_advertise_hosts} },
214 #endif
215   { "local_from_check",         opt_bool,        {&local_from_check} },
216   { "local_from_prefix",        opt_stringptr,   {&local_from_prefix} },
217   { "local_from_suffix",        opt_stringptr,   {&local_from_suffix} },
218   { "local_interfaces",         opt_stringptr,   {&local_interfaces} },
219 #ifdef HAVE_LOCAL_SCAN
220   { "local_scan_timeout",       opt_time,        {&local_scan_timeout} },
221 #endif
222   { "local_sender_retain",      opt_bool,        {&local_sender_retain} },
223   { "localhost_number",         opt_stringptr,   {&host_number_string} },
224   { "log_file_path",            opt_stringptr,   {&log_file_path} },
225   { "log_selector",             opt_stringptr,   {&log_selector_string} },
226   { "log_timezone",             opt_bool,        {&log_timezone} },
227   { "lookup_open_max",          opt_int,         {&lookup_open_max} },
228   { "max_username_length",      opt_int,         {&max_username_length} },
229   { "message_body_newlines",    opt_bool,        {&message_body_newlines} },
230   { "message_body_visible",     opt_mkint,       {&message_body_visible} },
231   { "message_id_header_domain", opt_stringptr,   {&message_id_domain} },
232   { "message_id_header_text",   opt_stringptr,   {&message_id_text} },
233   { "message_logs",             opt_bool,        {&message_logs} },
234   { "message_size_limit",       opt_stringptr,   {&message_size_limit} },
235 #ifdef SUPPORT_MOVE_FROZEN_MESSAGES
236   { "move_frozen_messages",     opt_bool,        {&move_frozen_messages} },
237 #endif
238   { "mua_wrapper",              opt_bool,        {&mua_wrapper} },
239 #ifdef LOOKUP_MYSQL
240   { "mysql_servers",            opt_stringptr,   {&mysql_servers} },
241 #endif
242   { "never_users",              opt_uidlist,     {&never_users} },
243   { "notifier_socket",          opt_stringptr,   {&notifier_socket} },
244 #ifndef DISABLE_TLS
245   { "openssl_options",          opt_stringptr,   {&openssl_options} },
246 #endif
247 #ifdef LOOKUP_ORACLE
248   { "oracle_servers",           opt_stringptr,   {&oracle_servers} },
249 #endif
250   { "panic_coredump",           opt_bool,        {&panic_coredump} },
251   { "percent_hack_domains",     opt_stringptr,   {&percent_hack_domains} },
252 #ifdef EXIM_PERL
253   { "perl_at_start",            opt_bool,        {&opt_perl_at_start} },
254   { "perl_startup",             opt_stringptr,   {&opt_perl_startup} },
255   { "perl_taintmode",           opt_bool,        {&opt_perl_taintmode} },
256 #endif
257 #ifdef LOOKUP_PGSQL
258   { "pgsql_servers",            opt_stringptr,   {&pgsql_servers} },
259 #endif
260   { "pid_file_path",            opt_stringptr,   {&pid_file_path} },
261   { "pipelining_advertise_hosts", opt_stringptr, {&pipelining_advertise_hosts} },
262 #ifndef DISABLE_PIPE_CONNECT
263   { "pipelining_connect_advertise_hosts", opt_stringptr,
264                                                  {&pipe_connect_advertise_hosts} },
265 #endif
266 #ifndef DISABLE_PRDR
267   { "prdr_enable",              opt_bool,        {&prdr_enable} },
268 #endif
269   { "preserve_message_logs",    opt_bool,        {&preserve_message_logs} },
270   { "primary_hostname",         opt_stringptr,   {&primary_hostname} },
271   { "print_topbitchars",        opt_bool,        {&print_topbitchars} },
272   { "process_log_path",         opt_stringptr,   {&process_log_path} },
273   { "prod_requires_admin",      opt_bool,        {&prod_requires_admin} },
274 #ifdef SUPPORT_PROXY
275   { "proxy_protocol_timeout",   opt_time,        {&proxy_protocol_timeout} },
276 #endif
277   { "qualify_domain",           opt_stringptr,   {&qualify_domain_sender} },
278   { "qualify_recipient",        opt_stringptr,   {&qualify_domain_recipient} },
279   { "queue_domains",            opt_stringptr,   {&queue_domains} },
280 #ifndef DISABLE_QUEUE_RAMP
281   { "queue_fast_ramp",          opt_bool,        {&queue_fast_ramp} },
282 #endif
283   { "queue_list_requires_admin",opt_bool,        {&queue_list_requires_admin} },
284   { "queue_only",               opt_bool,        {&queue_only} },
285   { "queue_only_file",          opt_stringptr,   {&queue_only_file} },
286   { "queue_only_load",          opt_fixed,       {&queue_only_load} },
287   { "queue_only_load_latch",    opt_bool,        {&queue_only_load_latch} },
288   { "queue_only_override",      opt_bool,        {&queue_only_override} },
289   { "queue_run_in_order",       opt_bool,        {&queue_run_in_order} },
290   { "queue_run_max",            opt_stringptr,   {&queue_run_max} },
291   { "queue_smtp_domains",       opt_stringptr,   {&queue_smtp_domains} },
292   { "receive_timeout",          opt_time,        {&receive_timeout} },
293   { "received_header_text",     opt_stringptr,   {&received_header_text} },
294   { "received_headers_max",     opt_int,         {&received_headers_max} },
295   { "recipient_unqualified_hosts", opt_stringptr, {&recipient_unqualified_hosts} },
296   { "recipients_max",           opt_stringptr,   {&recipients_max} },
297   { "recipients_max_reject",    opt_bool,        {&recipients_max_reject} },
298 #ifdef LOOKUP_REDIS
299   { "redis_servers",            opt_stringptr,   {&redis_servers} },
300 #endif
301   { "remote_max_parallel",      opt_int,         {&remote_max_parallel} },
302   { "remote_sort_domains",      opt_stringptr,   {&remote_sort_domains} },
303   { "retry_data_expire",        opt_time,        {&retry_data_expire} },
304   { "retry_interval_max",       opt_time,        {&retry_interval_max} },
305   { "return_path_remove",       opt_bool,        {&return_path_remove} },
306   { "return_size_limit",        opt_mkint|opt_hidden, {&bounce_return_size_limit} },
307   { "rfc1413_hosts",            opt_stringptr,   {&rfc1413_hosts} },
308   { "rfc1413_query_timeout",    opt_time,        {&rfc1413_query_timeout} },
309   { "sender_unqualified_hosts", opt_stringptr,   {&sender_unqualified_hosts} },
310   { "slow_lookup_log",          opt_int,         {&slow_lookup_log} },
311   { "smtp_accept_keepalive",    opt_bool,        {&smtp_accept_keepalive} },
312   { "smtp_accept_max",          opt_int,         {&smtp_accept_max} },
313   { "smtp_accept_max_nonmail",  opt_int,         {&smtp_accept_max_nonmail} },
314   { "smtp_accept_max_nonmail_hosts", opt_stringptr, {&smtp_accept_max_nonmail_hosts} },
315   { "smtp_accept_max_per_connection", opt_stringptr,   {&smtp_accept_max_per_connection} },
316   { "smtp_accept_max_per_host", opt_stringptr,   {&smtp_accept_max_per_host} },
317   { "smtp_accept_queue",        opt_int,         {&smtp_accept_queue} },
318   { "smtp_accept_queue_per_connection", opt_int, {&smtp_accept_queue_per_connection} },
319   { "smtp_accept_reserve",      opt_int,         {&smtp_accept_reserve} },
320   { "smtp_active_hostname",     opt_stringptr,   {&raw_active_hostname} },
321   { "smtp_backlog_monitor",     opt_int,         {&smtp_backlog_monitor} },
322   { "smtp_banner",              opt_stringptr,   {&smtp_banner} },
323   { "smtp_check_spool_space",   opt_bool,        {&smtp_check_spool_space} },
324   { "smtp_connect_backlog",     opt_int,         {&smtp_connect_backlog} },
325   { "smtp_enforce_sync",        opt_bool,        {&smtp_enforce_sync} },
326   { "smtp_etrn_command",        opt_stringptr,   {&smtp_etrn_command} },
327   { "smtp_etrn_serialize",      opt_bool,        {&smtp_etrn_serialize} },
328   { "smtp_load_reserve",        opt_fixed,       {&smtp_load_reserve} },
329   { "smtp_max_synprot_errors",  opt_int,         {&smtp_max_synprot_errors} },
330   { "smtp_max_unknown_commands",opt_int,         {&smtp_max_unknown_commands} },
331   { "smtp_ratelimit_hosts",     opt_stringptr,   {&smtp_ratelimit_hosts} },
332   { "smtp_ratelimit_mail",      opt_stringptr,   {&smtp_ratelimit_mail} },
333   { "smtp_ratelimit_rcpt",      opt_stringptr,   {&smtp_ratelimit_rcpt} },
334   { "smtp_receive_timeout",     opt_func,        {.fn = &fn_smtp_receive_timeout} },
335   { "smtp_reserve_hosts",       opt_stringptr,   {&smtp_reserve_hosts} },
336   { "smtp_return_error_details",opt_bool,        {&smtp_return_error_details} },
337 #ifdef SUPPORT_I18N
338   { "smtputf8_advertise_hosts", opt_stringptr,   {&smtputf8_advertise_hosts} },
339 #endif
340 #ifdef WITH_CONTENT_SCAN
341   { "spamd_address",            opt_stringptr,   {&spamd_address} },
342 #endif
343 #ifdef SUPPORT_SPF
344   { "spf_guess",                opt_stringptr,   {&spf_guess} },
345   { "spf_smtp_comment_template",opt_stringptr,   {&spf_smtp_comment_template} },
346 #endif
347   { "split_spool_directory",    opt_bool,        {&split_spool_directory} },
348   { "spool_directory",          opt_stringptr,   {&spool_directory} },
349   { "spool_wireformat",         opt_bool,        {&spool_wireformat} },
350 #ifdef LOOKUP_SQLITE
351   { "sqlite_dbfile",            opt_stringptr,   {&sqlite_dbfile} },
352   { "sqlite_lock_timeout",      opt_int,         {&sqlite_lock_timeout} },
353 #endif
354   { "strict_acl_vars",          opt_bool,        {&strict_acl_vars} },
355   { "strip_excess_angle_brackets", opt_bool,     {&strip_excess_angle_brackets} },
356   { "strip_trailing_dot",       opt_bool,        {&strip_trailing_dot} },
357   { "syslog_duplication",       opt_bool,        {&syslog_duplication} },
358   { "syslog_facility",          opt_stringptr,   {&syslog_facility_str} },
359   { "syslog_pid",               opt_bool,        {&syslog_pid} },
360   { "syslog_processname",       opt_stringptr,   {&syslog_processname} },
361   { "syslog_timestamp",         opt_bool,        {&syslog_timestamp} },
362   { "system_filter",            opt_stringptr,   {&system_filter} },
363   { "system_filter_directory_transport", opt_stringptr,{&system_filter_directory_transport} },
364   { "system_filter_file_transport",opt_stringptr,{&system_filter_file_transport} },
365   { "system_filter_group",      opt_gid,         {&system_filter_gid} },
366   { "system_filter_pipe_transport",opt_stringptr,{&system_filter_pipe_transport} },
367   { "system_filter_reply_transport",opt_stringptr,{&system_filter_reply_transport} },
368   { "system_filter_user",       opt_uid,         {&system_filter_uid} },
369   { "tcp_nodelay",              opt_bool,        {&tcp_nodelay} },
370 #ifdef USE_TCP_WRAPPERS
371   { "tcp_wrappers_daemon_name", opt_stringptr,   {&tcp_wrappers_daemon_name} },
372 #endif
373   { "timeout_frozen_after",     opt_time,        {&timeout_frozen_after} },
374   { "timezone",                 opt_stringptr,   {&timezone_string} },
375   { "tls_advertise_hosts",      opt_stringptr,   {&tls_advertise_hosts} },
376 #ifndef DISABLE_TLS
377   { "tls_alpn",                 opt_stringptr,   {&tls_alpn} },
378   { "tls_certificate",          opt_stringptr,   {&tls_certificate} },
379   { "tls_crl",                  opt_stringptr,   {&tls_crl} },
380   { "tls_dh_max_bits",          opt_int,         {&tls_dh_max_bits} },
381   { "tls_dhparam",              opt_stringptr,   {&tls_dhparam} },
382   { "tls_eccurve",              opt_stringptr,   {&tls_eccurve} },
383 # ifndef DISABLE_OCSP
384   { "tls_ocsp_file",            opt_stringptr,   {&tls_ocsp_file} },
385 # endif
386   { "tls_on_connect_ports",     opt_stringptr,   {&tls_in.on_connect_ports} },
387   { "tls_privatekey",           opt_stringptr,   {&tls_privatekey} },
388   { "tls_remember_esmtp",       opt_bool,        {&tls_remember_esmtp} },
389   { "tls_require_ciphers",      opt_stringptr,   {&tls_require_ciphers} },
390 # ifndef DISABLE_TLS_RESUME
391   { "tls_resumption_hosts",     opt_stringptr,   {&tls_resumption_hosts} },
392 # endif
393   { "tls_try_verify_hosts",     opt_stringptr,   {&tls_try_verify_hosts} },
394   { "tls_verify_certificates",  opt_stringptr,   {&tls_verify_certificates} },
395   { "tls_verify_hosts",         opt_stringptr,   {&tls_verify_hosts} },
396 #endif
397   { "trusted_groups",           opt_gidlist,     {&trusted_groups} },
398   { "trusted_users",            opt_uidlist,     {&trusted_users} },
399   { "unknown_login",            opt_stringptr,   {&unknown_login} },
400   { "unknown_username",         opt_stringptr,   {&unknown_username} },
401   { "untrusted_set_sender",     opt_stringptr,   {&untrusted_set_sender} },
402   { "uucp_from_pattern",        opt_stringptr,   {&uucp_from_pattern} },
403   { "uucp_from_sender",         opt_stringptr,   {&uucp_from_sender} },
404   { "warn_message_file",        opt_stringptr,   {&warn_message_file} },
405   { "write_rejectlog",          opt_bool,        {&write_rejectlog} },
406 };
407
408 #ifndef MACRO_PREDEF
409 static int optionlist_config_size = nelem(optionlist_config);
410 #endif
411
412
413 #ifdef MACRO_PREDEF
414
415 static void
416 fn_smtp_receive_timeout(const uschar * name, const uschar * str, unsigned flags) {/*Dummy*/}
417
418 void
419 options_main(void)
420 {
421 options_from_list(optionlist_config, nelem(optionlist_config), US"MAIN", NULL);
422 }
423
424 void
425 options_auths(void)
426 {
427 uschar buf[EXIM_DRIVERNAME_MAX];
428
429 options_from_list(optionlist_auths, optionlist_auths_size, US"AUTHENTICATORS", NULL);
430
431 for (struct auth_info * ai = auths_available; ai->driver_name[0]; ai++)
432   {
433   spf(buf, sizeof(buf), US"_DRIVER_AUTHENTICATOR_%T", ai->driver_name);
434   builtin_macro_create(buf);
435   options_from_list(ai->options, (unsigned)*ai->options_count, US"AUTHENTICATOR", ai->driver_name);
436
437   if (ai->macros_create) (ai->macros_create)();
438   }
439 }
440
441 void
442 options_logging(void)
443 {
444 uschar buf[EXIM_DRIVERNAME_MAX];
445
446 for (bit_table * bp = log_options; bp < log_options + log_options_count; bp++)
447   {
448   spf(buf, sizeof(buf), US"_LOG_%T", bp->name);
449   builtin_macro_create(buf);
450   }
451 }
452
453
454 #else   /*!MACRO_PREDEF*/
455
456 extern char **environ;
457
458 static void save_config_line(const uschar* line);
459 static void save_config_position(const uschar *file, int line);
460 static void print_config(BOOL admin, BOOL terse);
461
462
463 #define CSTATE_STACK_SIZE 10
464
465 const uschar *config_directory = NULL;
466
467
468 /* Structure for chain (stack) of .included files */
469
470 typedef struct config_file_item {
471   struct config_file_item *next;
472   const uschar *filename;
473   const uschar *directory;
474   FILE *file;
475   int lineno;
476 } config_file_item;
477
478 /* Structure for chain of configuration lines (-bP config) */
479
480 typedef struct config_line_item {
481   struct config_line_item *next;
482   uschar *line;
483 } config_line_item;
484
485 static config_line_item* config_lines;
486
487 /* Structure of table of conditional words and their state transitions */
488
489 typedef struct cond_item {
490   uschar *name;
491   int    namelen;
492   int    action1;
493   int    action2;
494   int    pushpop;
495 } cond_item;
496
497 /* Structure of table of syslog facility names and values */
498
499 typedef struct syslog_fac_item {
500   uschar *name;
501   int    value;
502 } syslog_fac_item;
503
504 /* constants */
505 static const uschar * const hidden = US"<value not displayable>";
506
507 /* Static variables */
508
509 static config_file_item *config_file_stack = NULL;  /* For includes */
510
511 static uschar *syslog_facility_str  = NULL;
512 static uschar next_section[24];
513 static uschar time_buffer[24];
514
515 /* State variables for conditional loading (.ifdef / .else / .endif) */
516
517 static int cstate = 0;
518 static int cstate_stack_ptr = -1;
519 static int cstate_stack[CSTATE_STACK_SIZE];
520
521 /* Table of state transitions for handling conditional inclusions. There are
522 four possible state transitions:
523
524   .ifdef true
525   .ifdef false
526   .elifdef true  (or .else)
527   .elifdef false
528
529 .endif just causes the previous cstate to be popped off the stack */
530
531 static int next_cstate[3][4] =
532   {
533   /* State 0: reading from file, or reading until next .else or .endif */
534   { 0, 1, 2, 2 },
535   /* State 1: condition failed, skipping until next .else or .endif */
536   { 2, 2, 0, 1 },
537   /* State 2: skipping until .endif */
538   { 2, 2, 2, 2 },
539   };
540
541 /* Table of conditionals and the states to set. For each name, there are four
542 values: the length of the name (to save computing it each time), the state to
543 set if a macro was found in the line, the state to set if a macro was not found
544 in the line, and a stack manipulation setting which is:
545
546   -1   pull state value off the stack
547    0   don't alter the stack
548   +1   push value onto stack, before setting new state
549 */
550
551 static cond_item cond_list[] = {
552   { US"ifdef",    5, 0, 1,  1 },
553   { US"ifndef",   6, 1, 0,  1 },
554   { US"elifdef",  7, 2, 3,  0 },
555   { US"elifndef", 8, 3, 2,  0 },
556   { US"else",     4, 2, 2,  0 },
557   { US"endif",    5, 0, 0, -1 }
558 };
559
560 static int cond_list_size = sizeof(cond_list)/sizeof(cond_item);
561
562 /* Table of syslog facility names and their values */
563
564 static syslog_fac_item syslog_list[] = {
565   { US"mail",   LOG_MAIL },
566   { US"user",   LOG_USER },
567   { US"news",   LOG_NEWS },
568   { US"uucp",   LOG_UUCP },
569   { US"local0", LOG_LOCAL0 },
570   { US"local1", LOG_LOCAL1 },
571   { US"local2", LOG_LOCAL2 },
572   { US"local3", LOG_LOCAL3 },
573   { US"local4", LOG_LOCAL4 },
574   { US"local5", LOG_LOCAL5 },
575   { US"local6", LOG_LOCAL6 },
576   { US"local7", LOG_LOCAL7 },
577   { US"daemon", LOG_DAEMON }
578 };
579
580 static int syslog_list_size = sizeof(syslog_list)/sizeof(syslog_fac_item);
581
582
583 #define opt_fn_print            BIT(0)
584 #define opt_fn_print_label      BIT(1)
585
586
587 /*************************************************
588 *         Find the name of an option             *
589 *************************************************/
590
591 /* This function is to aid debugging. Various functions take arguments that are
592 pointer variables in the options table or in option tables for various drivers.
593 For debugging output, it is useful to be able to find the name of the option
594 which is currently being processed. This function finds it, if it exists, by
595 searching the table(s) for a value with the given content.
596
597 Arguments:   a value that is presumed to be in the table above
598 Returns:     the option name, or an empty string
599 */
600
601 const uschar *
602 readconf_find_option(void * listptr)
603 {
604 uschar * list = * USS listptr;
605 const uschar * name = NULL, * drname = NULL;
606
607 for (optionlist * o = optionlist_config;               /* main-config options */
608      o < optionlist_config + optionlist_config_size; o++)
609   if (listptr == o->v.value)
610     return US o->name;
611
612 for (router_instance * r = routers; r; r = r->next)
613   if (router_name && Ustrcmp(r->name, router_name) == 0)
614   {
615   const router_info * ri = r->info;
616
617   /* Check for a listptr match first */
618
619   for (optionlist * o = optionlist_routers;             /* generic options */
620       o < optionlist_routers + optionlist_routers_size; o++)
621     if (  (o->type & opt_mask) == opt_stringptr
622        && listptr == CS r + o->v.offset)
623       return US o->name;
624
625   for (optionlist * o = ri->options;                    /* private options */
626       o < ri->options + *ri->options_count; o++)
627     if (  (o->type & opt_mask) == opt_stringptr
628        && listptr == CS (r->options_block) + o->v.offset)
629       return US o->name;
630
631   /* Check for a list addr match, unless null */
632
633   if (!list) continue;
634
635   for (optionlist * o = optionlist_routers;             /* generic options */
636       o < optionlist_routers + optionlist_routers_size; o++)
637     if (  (o->type & opt_mask) == opt_stringptr
638        && list == * USS(CS r + o->v.offset))
639       if (name) return string_sprintf("DUP: %s %s vs. %s %s",
640         drname, name, r->name, o->name);
641       else { name = US o->name; drname = r->name; }
642
643   for (optionlist * o = ri->options;                    /* private options */
644       o < ri->options + *ri->options_count; o++)
645     if (  (o->type & opt_mask) == opt_stringptr
646        && list == * USS(CS (r->options_block) + o->v.offset))
647       if (name) return string_sprintf("DUP: %s %s vs. %s %s",
648         drname, name, r->name, o->name);
649       else { name = US o->name; drname = r->name; }
650   }
651
652 for (transport_instance * t = transports; t; t = t->next)
653   if (transport_name && Ustrcmp(t->name, transport_name) == 0)
654   {
655   const transport_info * ti = t->info;
656
657   /* Check for a listptr match first */
658
659   for (optionlist * o = optionlist_transports;          /* generic options */
660       o < optionlist_transports + optionlist_transports_size; o++)
661     if (  (o->type & opt_mask) == opt_stringptr
662        && listptr == CS t + o->v.offset)
663       return US o->name;
664
665   for (optionlist * o = ti->options;                    /* private options */
666       o < ti->options + *ti->options_count; o++)
667     if (  (o->type & opt_mask) == opt_stringptr
668        && listptr == CS t->options_block + o->v.offset)
669       return US o->name;
670
671   /* Check for a list addr match, unless null */
672
673   if (!list) continue;
674
675   for (optionlist * o = optionlist_transports;          /* generic options */
676       o < optionlist_transports + optionlist_transports_size; o++)
677     if (  (o->type & opt_mask) == opt_stringptr
678        && list == * USS(CS t + o->v.offset))
679       if (name) return string_sprintf("DUP: %s %s vs. %s %s",
680         drname, name, t->name, o->name);
681       else { name = US o->name; drname = t->name; }
682
683   for (optionlist * o = ti->options;                    /* private options */
684       o < ti->options + *ti->options_count; o++)
685     if (  (o->type & opt_mask) == opt_stringptr
686        && list == * USS(CS t->options_block + o->v.offset))
687       if (name) return string_sprintf("DUP: %s %s vs. %s %s",
688         drname, name, t->name, o->name);
689       else { name = US o->name; drname = t->name; }
690   }
691
692 return name ? name : US"";
693 }
694
695
696
697
698 /*************************************************
699 *       Deal with an assignment to a macro       *
700 *************************************************/
701
702 /* We have a new definition; append to the list.
703
704 Args:
705  name   Name of the macro; will be copied
706  val    Expansion result for the macro; will be copied
707 */
708
709 macro_item *
710 macro_create(const uschar * name, const uschar * val, BOOL command_line)
711 {
712 macro_item * m = store_get(sizeof(macro_item), GET_UNTAINTED);
713
714 READCONF_DEBUG fprintf(stderr, "%s: '%s' '%s'\n", __FUNCTION__, name, val);
715 m->next = NULL;
716 m->command_line = command_line;
717 m->namelen = Ustrlen(name);
718 m->replen = Ustrlen(val);
719 m->name = string_copy(name);
720 m->replacement = string_copy(val);
721 if (mlast)
722   mlast->next = m;
723 else
724   macros = m;
725 mlast = m;
726 if (!macros_user)
727   macros_user = m;
728 return m;
729 }
730
731
732 /* This function is called when a line that starts with an upper case letter is
733 encountered. The argument "line" should contain a complete logical line, and
734 start with the first letter of the macro name. The macro name and the
735 replacement text are extracted and stored. Redefinition of existing,
736 non-command line, macros is permitted using '==' instead of '='.
737
738 Arguments:
739   s            points to the start of the logical line
740
741 Returns:       FALSE iff fatal error
742 */
743
744 BOOL
745 macro_read_assignment(uschar *s)
746 {
747 uschar name[EXIM_DRIVERNAME_MAX];
748 int namelen = 0;
749 BOOL redef = FALSE;
750 macro_item *m;
751
752 while (isalnum(*s) || *s == '_')
753   {
754   if (namelen >= sizeof(name) - 1)
755     {
756     log_write(0, LOG_PANIC|LOG_CONFIG_IN,
757       "macro name too long (maximum is " SIZE_T_FMT " characters)", sizeof(name) - 1);
758     return FALSE;
759     }
760   name[namelen++] = *s++;
761   }
762 name[namelen] = 0;
763
764 Uskip_whitespace(&s);
765 if (*s++ != '=')
766   {
767   log_write(0, LOG_PANIC|LOG_CONFIG_IN, "malformed macro definition");
768   return FALSE;
769   }
770
771 if (*s == '=')
772   {
773   redef = TRUE;
774   s++;
775   }
776 Uskip_whitespace(&s);
777
778 /* If an existing macro of the same name was defined on the command line, we
779 just skip this definition. It's an error to attempt to redefine a macro without
780 redef set to TRUE, or to redefine a macro when it hasn't been defined earlier.
781 It is also an error to define a macro whose name begins with the name of a
782 previously defined macro.  This is the requirement that make using a tree
783 for macros hard; we must check all macros for the substring.  Perhaps a
784 sorted list, and a bsearch, would work?
785 Note: it is documented that the other way round works. */
786
787 for (m = macros; m; m = m->next)
788   {
789   if (Ustrcmp(m->name, name) == 0)
790     {
791     if (!m->command_line && !redef)
792       {
793       log_write(0, LOG_CONFIG|LOG_PANIC, "macro \"%s\" is already "
794        "defined (use \"==\" if you want to redefine it)", name);
795       return FALSE;
796       }
797     break;
798     }
799
800   if (m->namelen < namelen && Ustrstr(name, m->name) != NULL)
801     {
802     log_write(0, LOG_CONFIG|LOG_PANIC, "\"%s\" cannot be defined as "
803       "a macro because previously defined macro \"%s\" is a substring",
804       name, m->name);
805     return FALSE;
806     }
807
808   /* We cannot have this test, because it is documented that a substring
809   macro is permitted (there is even an example).
810   *
811   * if (m->namelen > namelen && Ustrstr(m->name, name) != NULL)
812   *   log_write(0, LOG_CONFIG|LOG_PANIC_DIE, "\"%s\" cannot be defined as "
813   *     "a macro because it is a substring of previously defined macro \"%s\"",
814   *     name, m->name);
815   */
816   }
817
818 /* Check for an overriding command-line definition. */
819
820 if (m && m->command_line) return TRUE;
821
822 /* Redefinition must refer to an existing macro. */
823
824 if (redef)
825   if (m)
826     {
827     m->replen = Ustrlen(s);
828     m->replacement = string_copy(s);
829     }
830   else
831     {
832     log_write(0, LOG_CONFIG|LOG_PANIC, "can't redefine an undefined macro "
833       "\"%s\"", name);
834     return FALSE;
835     }
836
837 /* We have a new definition. */
838 else
839   (void) macro_create(name, s, FALSE);
840 return TRUE;
841 }
842
843
844
845
846
847 /* Process line for macros. The line is in big_buffer starting at offset len.
848 Expand big_buffer if needed.  Handle definitions of new macros, and
849 macro expansions, rewriting the line in the buffer.
850
851 Arguments:
852  len            Offset in buffer of start of line
853  newlen         Pointer to offset of end of line, updated on return
854  macro_found    Pointer to return that a macro was expanded
855
856 Return: pointer to first nonblank char in line
857 */
858
859 uschar *
860 macros_expand(int len, int * newlen, BOOL * macro_found)
861 {
862 uschar * ss = big_buffer + len;
863 uschar * s;
864
865 /* Find the true start of the physical line - leading spaces are always
866 ignored. */
867
868 Uskip_whitespace(&ss);
869
870 /* Process the physical line for macros. If this is the start of the logical
871 line, skip over initial text at the start of the line if it starts with an
872 upper case character followed by a sequence of name characters and an equals
873 sign, because that is the definition of a new macro, and we don't do
874 replacement therein. */
875
876 s = ss;
877 if (len == 0 && isupper(*s))
878   {
879   while (isalnum(*s) || *s == '_') s++;
880   if (Uskip_whitespace(&s) != '=') s = ss;          /* Not a macro definition */
881   }
882
883 /* Skip leading chars which cannot start a macro name, to avoid multiple
884 pointless rescans in Ustrstr calls. */
885
886 while (*s && !isupper(*s) && !(*s == '_' && isupper(s[1]))) s++;
887
888 /* For each defined macro, scan the line (from after XXX= if present),
889 replacing all occurrences of the macro. */
890
891 *macro_found = FALSE;
892 if (*s) for (macro_item * m = *s == '_' ? macros : macros_user; m; m = m->next)
893   {
894   uschar * p, *pp;
895   uschar * t;
896
897   while (*s && !isupper(*s) && !(*s == '_' && isupper(s[1]))) s++;
898   if (!*s) break;
899
900   t = s;
901   while ((p = Ustrstr(t, m->name)) != NULL)
902     {
903     int moveby;
904
905     READCONF_DEBUG fprintf(stderr, "%s: matched '%s' in '%.*s'\n", __FUNCTION__,
906       m->name, (int) Ustrlen(ss)-1, ss);
907     /* Expand the buffer if necessary */
908
909     while (*newlen - m->namelen + m->replen + 1 > big_buffer_size)
910       {
911       int newsize = big_buffer_size + BIG_BUFFER_SIZE;
912       uschar *newbuffer = store_malloc(newsize);
913       memcpy(newbuffer, big_buffer, *newlen + 1);
914       p = newbuffer  + (p - big_buffer);
915       s = newbuffer  + (s - big_buffer);
916       ss = newbuffer + (ss - big_buffer);
917       t = newbuffer  + (t - big_buffer);
918       big_buffer_size = newsize;
919       store_free(big_buffer);
920       big_buffer = newbuffer;
921       }
922
923     /* Shuffle the remaining characters up or down in the buffer before
924     copying in the replacement text. Don't rescan the replacement for this
925     same macro. */
926
927     pp = p + m->namelen;
928     if ((moveby = m->replen - m->namelen) != 0)
929       {
930       memmove(p + m->replen, pp, (big_buffer + *newlen) - pp + 1);
931       *newlen += moveby;
932       }
933     Ustrncpy(p, m->replacement, m->replen);
934     t = p + m->replen;
935     while (*t && !isupper(*t) && !(*t == '_' && isupper(t[1]))) t++;
936     *macro_found = TRUE;
937     }
938   }
939
940 /* An empty macro replacement at the start of a line could mean that ss no
941 longer points to the first non-blank character. */
942
943 Uskip_whitespace(&ss);
944 return ss;
945 }
946
947 /*************************************************
948 *            Read configuration line             *
949 *************************************************/
950
951 /* A logical line of text is read from the configuration file into the big
952 buffer, taking account of macros, .includes, and continuations. The size of
953 big_buffer is increased if necessary. The count of configuration lines is
954 maintained. Physical input lines starting with # (ignoring leading white space,
955 and after macro replacement) and empty logical lines are always ignored.
956 Leading and trailing spaces are removed.
957
958 If we hit a line of the form "begin xxxx", the xxxx is placed in the
959 next_section vector, and the function returns NULL, indicating the end of a
960 configuration section. On end-of-file, NULL is returned with next_section
961 empty.
962
963 Arguments:      none
964
965 Returns:        a pointer to the first non-blank in the line,
966                 or NULL if eof or end of section is reached
967 */
968
969 static uschar *
970 get_config_line(void)
971 {
972 int startoffset = 0;         /* To first non-blank char in logical line */
973 int len = 0;                 /* Of logical line so far */
974 int newlen;
975 uschar *s, *ss;
976 BOOL macro_found;
977
978 /* Loop for handling continuation lines, skipping comments, and dealing with
979 .include files. */
980
981 for (;;)
982   {
983   if (Ufgets(big_buffer+len, big_buffer_size-len, config_file) == NULL)
984     {
985     if (config_file_stack != NULL)    /* EOF inside .include */
986       {
987       (void)fclose(config_file);
988       config_file = config_file_stack->file;
989       config_filename = config_file_stack->filename;
990       config_directory = config_file_stack->directory;
991       config_lineno = config_file_stack->lineno;
992       config_file_stack = config_file_stack->next;
993       if (config_lines)
994         save_config_position(config_filename, config_lineno);
995       continue;
996       }
997
998     /* EOF at top level */
999
1000     if (cstate_stack_ptr >= 0)
1001       log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN,
1002         "Unexpected end of configuration file: .endif missing");
1003
1004     if (len != 0) break;        /* EOF after continuation */
1005     next_section[0] = 0;        /* EOF at start of logical line */
1006     return NULL;
1007     }
1008
1009   config_lineno++;
1010   newlen = len + Ustrlen(big_buffer + len);
1011
1012   if (config_lines && config_lineno == 1)
1013     save_config_position(config_filename, config_lineno);
1014
1015   /* Handle pathologically long physical lines - yes, it did happen - by
1016   extending big_buffer at this point. The code also copes with very long
1017   logical lines. */
1018
1019   while (newlen == big_buffer_size - 1 && big_buffer[newlen - 1] != '\n')
1020     {
1021     uschar *newbuffer;
1022     big_buffer_size += BIG_BUFFER_SIZE;
1023     newbuffer = store_malloc(big_buffer_size);
1024
1025     /* This use of strcpy is OK because we know that the string in the old
1026     buffer is shorter than the new buffer. */
1027
1028     Ustrcpy(newbuffer, big_buffer);
1029     store_free(big_buffer);
1030     big_buffer = newbuffer;
1031     if (Ufgets(big_buffer+newlen, big_buffer_size-newlen, config_file) == NULL)
1032       break;
1033     newlen += Ustrlen(big_buffer + newlen);
1034     }
1035
1036   ss = macros_expand(len, &newlen, &macro_found);
1037
1038   /* Check for comment lines - these are physical lines. */
1039
1040   if (*ss == '#') continue;
1041
1042   /* Handle conditionals, which are also applied to physical lines. Conditions
1043   are of the form ".ifdef ANYTEXT" and are treated as true if any macro
1044   expansion occurred on the rest of the line. A preliminary test for the leading
1045   '.' saves effort on most lines. */
1046
1047   if (*ss == '.')
1048     {
1049     int i;
1050
1051     /* Search the list of conditional directives */
1052
1053     for (i = 0; i < cond_list_size; i++)
1054       {
1055       int n;
1056       cond_item *c = cond_list+i;
1057       if (Ustrncmp(ss+1, c->name, c->namelen) != 0) continue;
1058
1059       /* The following character must be white space or end of string */
1060
1061       n = ss[1 + c->namelen];
1062       if (n != ' ' && n != 't' && n != '\n' && n != 0) break;
1063
1064       /* .ifdef and .ifndef push the current state onto the stack, then set
1065       a new one from the table. Stack overflow is an error */
1066
1067       if (c->pushpop > 0)
1068         {
1069         if (cstate_stack_ptr >= CSTATE_STACK_SIZE - 1)
1070           log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN,
1071             ".%s nested too deeply", c->name);
1072         cstate_stack[++cstate_stack_ptr] = cstate;
1073         cstate = next_cstate[cstate][macro_found? c->action1 : c->action2];
1074         }
1075
1076       /* For any of the others, stack underflow is an error. The next state
1077       comes either from the stack (.endif) or from the table. */
1078
1079       else
1080         {
1081         if (cstate_stack_ptr < 0)
1082           log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN,
1083             ".%s without matching .ifdef", c->name);
1084         cstate = (c->pushpop < 0)? cstate_stack[cstate_stack_ptr--] :
1085           next_cstate[cstate][macro_found? c->action1 : c->action2];
1086         }
1087
1088       /* Having dealt with a directive, break the loop */
1089
1090       break;
1091       }
1092
1093     /* If we have handled a conditional directive, continue with the next
1094     physical line. Otherwise, fall through. */
1095
1096     if (i < cond_list_size) continue;
1097     }
1098
1099   /* If the conditional state is not 0 (actively using these lines), ignore
1100   this input line. */
1101
1102   if (cstate != 0) continue;  /* Conditional skip */
1103
1104   /* Handle .include lines - these are also physical lines. */
1105
1106   if (Ustrncmp(ss, ".include", 8) == 0 &&
1107        (isspace(ss[8]) ||
1108          (Ustrncmp(ss+8, "_if_exists", 10) == 0 && isspace(ss[18]))))
1109     {
1110     uschar *t;
1111     int include_if_exists = isspace(ss[8]) ? 0 : 10;
1112     config_file_item *save;
1113     struct stat statbuf;
1114
1115     ss += 9 + include_if_exists;
1116     Uskip_whitespace(&ss);
1117     t = ss + Ustrlen(ss);
1118     while (t > ss && isspace(t[-1])) t--;
1119     if (*ss == '\"' && t[-1] == '\"')
1120       {
1121       ss++;
1122       t--;
1123       }
1124     *t = 0;
1125
1126     /* We allow relative file names. For security reasons currently
1127     relative names not allowed with .include_if_exists. For .include_if_exists
1128     we need to check the permissions/ownership of the containing folder */
1129     if (*ss != '/')
1130       if (include_if_exists) log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, ".include specifies a non-"
1131           "absolute path \"%s\"", ss);
1132       else
1133         {
1134         gstring * g = string_append(NULL, 3, config_directory, "/", ss);
1135         ss = string_from_gstring(g);
1136         }
1137
1138     if (include_if_exists != 0 && (Ustat(ss, &statbuf) != 0)) continue;
1139
1140     if (config_lines)
1141       save_config_position(config_filename, config_lineno);
1142     save = store_get(sizeof(config_file_item), GET_UNTAINTED);
1143     save->next = config_file_stack;
1144     config_file_stack = save;
1145     save->file = config_file;
1146     save->filename = config_filename;
1147     save->directory = config_directory;
1148     save->lineno = config_lineno;
1149
1150     if (!(config_file = Ufopen(ss, "rb")))
1151       log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, "failed to open included "
1152         "configuration file %s", ss);
1153
1154     config_filename = string_copy(ss);
1155     config_directory = string_copyn(ss, CUstrrchr(ss, '/') - ss);
1156     config_lineno = 0;
1157     continue;
1158     }
1159
1160   /* If this is the start of the logical line, remember where the non-blank
1161   data starts. Otherwise shuffle down continuation lines to remove leading
1162   white space. */
1163
1164   if (len == 0)
1165     startoffset = ss - big_buffer;
1166   else
1167     {
1168     s = big_buffer + len;
1169     if (ss > s)
1170       {
1171       memmove(s, ss, (newlen - len) -  (ss - s) + 1);
1172       newlen -= ss - s;
1173       }
1174     }
1175
1176   /* Accept the new addition to the line. Remove trailing white space. */
1177
1178   len = newlen;
1179   while (len > 0 && isspace(big_buffer[len-1])) len--;
1180   big_buffer[len] = 0;
1181
1182   /* We are done if the line does not end in backslash and contains some data.
1183   Empty logical lines are ignored. For continuations, remove the backslash and
1184   go round the loop to read the continuation line. */
1185
1186   if (len > 0)
1187     {
1188     if (big_buffer[len-1] != '\\') break;   /* End of logical line */
1189     big_buffer[--len] = 0;                  /* Remove backslash */
1190     }
1191   }     /* Loop for reading multiple physical lines */
1192
1193 /* We now have a logical line. Test for the end of a configuration section (or,
1194 more accurately, for the start of the next section). Place the name of the next
1195 section in next_section, and return NULL. If the name given is longer than
1196 next_section, truncate it. It will be unrecognized later, because all the known
1197 section names do fit. Leave space for pluralizing. */
1198
1199 s = big_buffer + startoffset;            /* First non-space character */
1200
1201 if (config_lines)
1202   save_config_line(s);
1203
1204 if (strncmpic(s, US"begin ", 6) == 0)
1205   {
1206   s += 6;
1207   Uskip_whitespace(&s);
1208   if (big_buffer + len - s > sizeof(next_section) - 2)
1209     s[sizeof(next_section) - 2] = 0;
1210   Ustrcpy(next_section, s);
1211   return NULL;
1212   }
1213
1214 /* Return the first non-blank character. */
1215
1216 return s;
1217 }
1218
1219
1220
1221 /*************************************************
1222 *             Read a name                        *
1223 *************************************************/
1224
1225 /* The yield is the pointer to the next uschar. Names longer than the
1226 output space are silently truncated. This function is also used from acl.c when
1227 parsing ACLs.
1228
1229 Arguments:
1230   name      where to put the name
1231   len       length of name
1232   s         input pointer
1233
1234 Returns:    new input pointer
1235 */
1236
1237 const uschar *
1238 readconf_readname(uschar * name, int len, const uschar * s)
1239 {
1240 int p = 0;
1241 BOOL broken = FALSE;
1242
1243 if (isalpha(Uskip_whitespace(&s)))
1244   while (isalnum(*s) || *s == '_')
1245     {
1246     if (p < len-1) name[p++] = *s;
1247     else {
1248       broken = TRUE;
1249       break;
1250     }
1251     s++;
1252     }
1253
1254 name[p] = 0;
1255 if (broken) {
1256   log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN,
1257             "exim item name too long (>%d), unable to use \"%s\" (truncated)",
1258             len, name);
1259 }
1260 Uskip_whitespace(&s);
1261 return s;
1262 }
1263
1264
1265
1266
1267 /*************************************************
1268 *          Read a time value                     *
1269 *************************************************/
1270
1271 /* This function is also called from outside, to read argument
1272 time values. The format of a time value is:
1273
1274   [<n>w][<n>d][<n>h][<n>m][<n>s]
1275
1276 as long as at least one is present. If a format error is encountered,
1277 return a negative value. The value must be terminated by the given
1278 terminator.
1279
1280 Arguments:
1281   s             input pointer
1282   terminator    required terminating character
1283   return_msec   if TRUE, allow fractional seconds and return milliseconds
1284
1285 Returns:        the time value, or -1 on syntax error
1286                 value is seconds if return_msec is FALSE
1287                 value is milliseconds if return_msec is TRUE
1288 */
1289
1290 int
1291 readconf_readtime(const uschar *s, int terminator, BOOL return_msec)
1292 {
1293 int yield = 0;
1294 for (;;)
1295   {
1296   int value, count;
1297   double fraction;
1298
1299   if (!isdigit(*s)) return -1;
1300   (void)sscanf(CCS s, "%d%n", &value, &count);
1301   s += count;
1302
1303   switch (*s)
1304     {
1305     case 'w': value *= 7;
1306     case 'd': value *= 24;
1307     case 'h': value *= 60;
1308     case 'm': value *= 60;
1309     case 's': s++;
1310     break;
1311
1312     case '.':
1313     if (!return_msec) return -1;
1314     (void)sscanf(CCS s, "%lf%n", &fraction, &count);
1315     s += count;
1316     if (*s++ != 's') return -1;
1317     yield += (int)(fraction * 1000.0);
1318     break;
1319
1320     default: return -1;
1321     }
1322
1323   if (return_msec) value *= 1000;
1324   yield += value;
1325   if (*s == terminator) return yield;
1326   }
1327 /* Control never reaches here. */
1328 }
1329
1330
1331
1332 /*************************************************
1333 *          Read a fixed point value              *
1334 *************************************************/
1335
1336 /* The value is returned *1000
1337
1338 Arguments:
1339   s           input pointer
1340   terminator  required terminator
1341
1342 Returns:      the value, or -1 on error
1343 */
1344
1345 static int
1346 readconf_readfixed(const uschar *s, int terminator)
1347 {
1348 int yield = 0;
1349 int value, count;
1350 if (!isdigit(*s)) return -1;
1351 (void)sscanf(CS  s, "%d%n", &value, &count);
1352 s += count;
1353 yield = value * 1000;
1354 if (*s == '.')
1355   {
1356   int m = 100;
1357   while (isdigit((*(++s))))
1358     {
1359     yield += (*s - '0') * m;
1360     m /= 10;
1361     }
1362   }
1363
1364 return (*s == terminator)? yield : (-1);
1365 }
1366
1367
1368
1369 /*************************************************
1370 *            Find option in list                 *
1371 *************************************************/
1372
1373 /* The lists are always in order, so binary chop can be used.
1374
1375 Arguments:
1376   name      the option name to search for
1377   ol        the first entry in the option list
1378   last      one more than the offset of the last entry in the option list
1379
1380 Returns:    pointer to an option entry, or NULL if not found
1381 */
1382
1383 static optionlist *
1384 find_option(const uschar *name, optionlist *ol, int last)
1385 {
1386 int first = 0;
1387 while (last > first)
1388   {
1389   int middle = (first + last)/2;
1390   int c = Ustrcmp(name, ol[middle].name);
1391
1392   if (c == 0) return ol + middle;
1393   else if (c > 0) first = middle + 1;
1394   else last = middle;
1395   }
1396 return NULL;
1397 }
1398
1399
1400
1401 /*************************************************
1402 *      Find a set flag in option list            *
1403 *************************************************/
1404
1405 /* Because some versions of Unix make no restrictions on the values of uids and
1406 gids (even negative ones), we cannot represent "unset" by a special value.
1407 There is therefore a separate boolean variable for each one indicating whether
1408 a value is set or not. This function returns a pointer to the boolean, given
1409 the original option name. It is a major disaster if the flag cannot be found.
1410
1411 Arguments:
1412   name          the name of the uid or gid option
1413   oltop         points to the start of the relevant option list
1414   last          one more than the offset of the last item in the option list
1415   data_block    NULL when reading main options => data values in the option
1416                   list are absolute addresses; otherwise they are byte offsets
1417                   in data_block (used for driver options)
1418
1419 Returns:        a pointer to the boolean flag.
1420 */
1421
1422 static BOOL *
1423 get_set_flag(const uschar *name, optionlist *oltop, int last, void *data_block)
1424 {
1425 optionlist *ol;
1426 uschar name2[EXIM_DRIVERNAME_MAX];
1427 sprintf(CS name2, "*set_%.50s", name);
1428 if (!(ol = find_option(name2, oltop, last)))
1429   log_write(0, LOG_MAIN|LOG_PANIC_DIE,
1430     "Exim internal error: missing set flag for %s", name);
1431 return data_block
1432   ? (BOOL *)(US data_block + ol->v.offset) : (BOOL *)ol->v.value;
1433 }
1434
1435
1436
1437
1438 /*************************************************
1439 *    Output extra characters message and die     *
1440 *************************************************/
1441
1442 /* Called when an option line has junk on the end. Sometimes this is because
1443 the sysadmin thinks comments are permitted.
1444
1445 Arguments:
1446   s          points to the extra characters
1447   t1..t3     strings to insert in the log message
1448
1449 Returns:     doesn't return; dies
1450 */
1451
1452 static void
1453 extra_chars_error(const uschar *s, const uschar *t1, const uschar *t2, const uschar *t3)
1454 {
1455 uschar *comment = US"";
1456 if (*s == '#') comment = US" (# is comment only at line start)";
1457 log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN,
1458   "extra characters follow %s%s%s%s", t1, t2, t3, comment);
1459 }
1460
1461
1462
1463 /*************************************************
1464 *              Read rewrite information          *
1465 *************************************************/
1466
1467 /* Each line of rewrite information contains:
1468
1469 .  A complete address in the form user@domain, possibly with
1470    leading * for each part; or alternatively, a regex.
1471
1472 .  A replacement string (which will be expanded).
1473
1474 .  An optional sequence of one-letter flags, indicating which
1475    headers etc. to apply this rule to.
1476
1477 All this is decoded and placed into a control block. The OR of the flags is
1478 maintained in a common word.
1479
1480 Arguments:
1481   p           points to the string that makes up the rule
1482   existflags  points to the overall flag word
1483   isglobal    TRUE if reading global rewrite rules
1484
1485 Returns:      the control block for the parsed rule.
1486 */
1487
1488 static rewrite_rule *
1489 readconf_one_rewrite(const uschar *p, int *existflags, BOOL isglobal)
1490 {
1491 rewrite_rule * next = store_get(sizeof(rewrite_rule), GET_UNTAINTED);
1492
1493 next->next = NULL;
1494 next->key = string_dequote(&p);
1495
1496 Uskip_whitespace(&p);
1497 if (!*p)
1498   log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN,
1499     "missing rewrite replacement string");
1500
1501 next->flags = 0;
1502 next->replacement = string_dequote(&p);
1503
1504 while (*p) switch (*p++)
1505   {
1506   case ' ': case '\t': break;
1507
1508   case 'q': next->flags |= rewrite_quit; break;
1509   case 'w': next->flags |= rewrite_whole; break;
1510
1511   case 'h': next->flags |= rewrite_all_headers; break;
1512   case 's': next->flags |= rewrite_sender; break;
1513   case 'f': next->flags |= rewrite_from; break;
1514   case 't': next->flags |= rewrite_to;   break;
1515   case 'c': next->flags |= rewrite_cc;   break;
1516   case 'b': next->flags |= rewrite_bcc;  break;
1517   case 'r': next->flags |= rewrite_replyto; break;
1518
1519   case 'E': next->flags |= rewrite_all_envelope; break;
1520   case 'F': next->flags |= rewrite_envfrom; break;
1521   case 'T': next->flags |= rewrite_envto; break;
1522
1523   case 'Q': next->flags |= rewrite_qualify; break;
1524   case 'R': next->flags |= rewrite_repeat; break;
1525
1526   case 'S':
1527   next->flags |= rewrite_smtp;
1528   if (next->key[0] != '^' && Ustrncmp(next->key, "\\N^", 3) != 0)
1529     log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN,
1530       "rewrite rule has the S flag but is not a regular expression");
1531   break;
1532
1533   default:
1534   log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN,
1535     "unknown rewrite flag character '%c' "
1536     "(could be missing quotes round replacement item)", p[-1]);
1537   break;
1538   }
1539
1540 /* If no action flags are set, set all the "normal" rewrites. */
1541
1542 if ((next->flags & (rewrite_all | rewrite_smtp)) == 0)
1543   next->flags |= isglobal? rewrite_all : rewrite_all_headers;
1544
1545 /* Remember which exist, for optimization, and return the rule */
1546
1547 *existflags |= next->flags;
1548 return next;
1549 }
1550
1551
1552
1553
1554 /*************************************************
1555 *          Read global rewrite information       *
1556 *************************************************/
1557
1558 /* Each line is a single rewrite rule; it is parsed into a control block
1559 by readconf_one_rewrite(), and its flags are ORed into the global flag
1560 word rewrite_existflags. */
1561
1562 void
1563 readconf_rewrites(void)
1564 {
1565 rewrite_rule **chain = &global_rewrite_rules;
1566 uschar *p;
1567
1568 while ((p = get_config_line()) != NULL)
1569   {
1570   rewrite_rule *next = readconf_one_rewrite(p, &rewrite_existflags, TRUE);
1571   *chain = next;
1572   chain = &(next->next);
1573   }
1574 }
1575
1576
1577
1578 /*************************************************
1579 *               Read a string                    *
1580 *************************************************/
1581
1582 /* Strings are read into the normal store pool. As long we aren't too
1583 near the end of the current block, the string will just use what is necessary
1584 on the top of the stacking pool, because string_cat() uses the extension
1585 mechanism.
1586
1587 Argument:
1588   s         the rest of the input line
1589   name      the option name (for errors)
1590
1591 Returns:    pointer to the string
1592 */
1593
1594 static uschar *
1595 read_string(const uschar *s, const uschar *name)
1596 {
1597 uschar *yield;
1598 const uschar *ss;
1599
1600 if (*s != '\"') return string_copy(s);
1601
1602 ss = s;
1603 yield = string_dequote(&s);
1604
1605 if (s == ss+1 || s[-1] != '\"')
1606   log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN,
1607     "missing quote at end of string value for %s", name);
1608
1609 if (*s != 0) extra_chars_error(s, US"string value for ", name, US"");
1610
1611 return yield;
1612 }
1613
1614
1615 /*************************************************
1616 *            Custom-handler options              *
1617 *************************************************/
1618 static void
1619 fn_smtp_receive_timeout(const uschar * name, const uschar * str, unsigned flags)
1620 {
1621 if (flags & opt_fn_print)
1622   {
1623   if (flags & opt_fn_print_label) printf("%s = ", name);
1624   printf("%s\n", smtp_receive_timeout_s
1625     ? string_printing2(smtp_receive_timeout_s, SP_TAB)
1626     : readconf_printtime(smtp_receive_timeout));
1627   }
1628 else if (*str == '$')
1629   smtp_receive_timeout_s = string_copy(str);
1630 else
1631   {
1632   /* "smtp_receive_timeout",     opt_time,        &smtp_receive_timeout */
1633   smtp_receive_timeout = readconf_readtime(str, 0, FALSE);
1634   if (smtp_receive_timeout < 0)
1635     log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, "invalid time value for %s",
1636       name);
1637   }
1638 }
1639
1640 /*************************************************
1641 *            Handle option line                  *
1642 *************************************************/
1643
1644 /* This function is called from several places to process a line containing the
1645 setting of an option. The first argument is the line to be decoded; it has been
1646 checked not to be empty and not to start with '#'. Trailing newlines and white
1647 space have been removed. The second argument is a pointer to the list of
1648 variable names that are to be recognized, together with their types and
1649 locations, and the third argument gives the number of entries in the list.
1650
1651 The fourth argument is a pointer to a data block. If it is NULL, then the data
1652 values in the options list are absolute addresses. Otherwise, they are byte
1653 offsets in the data block.
1654
1655 String option data may continue onto several lines; this function reads further
1656 data from config_file if necessary.
1657
1658 The yield of this function is normally zero. If a string continues onto
1659 multiple lines, then the data value is permitted to be followed by a comma
1660 or a semicolon (for use in drivers) and the yield is that character.
1661
1662 Arguments:
1663   buffer        contains the configuration line to be handled
1664   oltop         points to the start of the relevant option list
1665   last          one more than the offset of the last item in the option list
1666   data_block    NULL when reading main options => data values in the option
1667                   list are absolute addresses; otherwise they are byte offsets
1668                   in data_block when they have opt_public set; otherwise
1669                   they are byte offsets in data_block->options_block.
1670   unknown_txt   format string to use in panic message for unknown option;
1671                   must contain %s for option name
1672                 if given as NULL, don't panic on unknown option
1673
1674 Returns:        TRUE if an option was read successfully,
1675                 FALSE false for an unknown option if unknown_txt == NULL,
1676                   otherwise panic and die on an unknown option
1677 */
1678
1679 static BOOL
1680 readconf_handle_option(uschar *buffer, optionlist *oltop, int last,
1681   void *data_block, uschar *unknown_txt)
1682 {
1683 int ptr = 0;
1684 int offset = 0;
1685 int count, type, value;
1686 int issecure = 0;
1687 uid_t uid;
1688 gid_t gid;
1689 BOOL boolvalue = TRUE;
1690 BOOL freesptr = TRUE;
1691 optionlist *ol, *ol2;
1692 struct passwd *pw;
1693 rmark reset_point;
1694 int intbase = 0;
1695 uschar *inttype = US"";
1696 uschar *sptr;
1697 const uschar * s = buffer;
1698 uschar **str_target;
1699 uschar name[EXIM_DRIVERNAME_MAX];
1700 uschar name2[EXIM_DRIVERNAME_MAX];
1701
1702 /* There may be leading spaces; thereafter, we expect an option name starting
1703 with a letter. */
1704
1705 if (!isalpha( Uskip_whitespace(&s) ))
1706   log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, "option setting expected: %s", s);
1707
1708 /* Read the name of the option, and skip any subsequent white space. If
1709 it turns out that what we read was "hide", set the flag indicating that
1710 this is a secure option, and loop to read the next word. */
1711
1712 for (int n = 0; n < 2; n++)
1713   {
1714   while (isalnum(*s) || *s == '_')
1715     {
1716     if (ptr < sizeof(name)-1) name[ptr++] = *s;
1717     s++;
1718     }
1719   name[ptr] = 0;
1720   Uskip_whitespace(&s);
1721   if (Ustrcmp(name, "hide") != 0) break;
1722   issecure = opt_secure;
1723   ptr = 0;
1724   }
1725
1726 /* Deal with "no_" or "not_" here for booleans */
1727
1728 if (Ustrncmp(name, "no_", 3) == 0)
1729   {
1730   boolvalue = FALSE;
1731   offset = 3;
1732   }
1733
1734 if (Ustrncmp(name, "not_", 4) == 0)
1735   {
1736   boolvalue = FALSE;
1737   offset = 4;
1738   }
1739
1740 /* Search the list for the given name. A non-existent name, or an option that
1741 is set twice, is a disaster. */
1742
1743 if (!(ol = find_option(name + offset, oltop, last)))
1744   {
1745   if (!unknown_txt) return FALSE;
1746   log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, CS unknown_txt, name);
1747   }
1748
1749 if ((ol->type & opt_set)  && !(ol->type & (opt_rep_con | opt_rep_str)))
1750   log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN,
1751     "\"%s\" option set for the second time", name);
1752
1753 ol->type |= opt_set | issecure;
1754 type = ol->type & opt_mask;
1755
1756 /* Types with data values must be followed by '='; the "no[t]_" prefix
1757 applies only to boolean values. */
1758
1759 if (type < opt_bool || type > opt_bool_last)
1760   {
1761   if (offset != 0)
1762     log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN,
1763       "negation prefix applied to a non-boolean option");
1764   if (!*s)
1765     log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN,
1766       "unexpected end of line (data missing) after %s", name);
1767   if (*s != '=')
1768     log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, "missing \"=\" after %s", name);
1769   }
1770
1771 /* If a boolean wasn't preceded by "no[t]_" it can be followed by = and
1772 true/false/yes/no, or, in the case of opt_expand_bool, a general string that
1773 ultimately expands to one of those values. */
1774
1775 else if (*s && (offset != 0 || *s != '='))
1776   extra_chars_error(s, US"boolean option ", name, US"");
1777
1778 /* Skip white space after = */
1779
1780 if (*s == '=') while (isspace(*++s));
1781
1782 /* If there is a data block and the opt_public flag is not set, change
1783 the data block pointer to the private options block. */
1784
1785 if (data_block && !(ol->type & opt_public))
1786   data_block = (void *)(((driver_instance *)data_block)->options_block);
1787
1788 /* Now get the data according to the type. */
1789
1790 switch (type)
1791   {
1792   /* If a string value is not enclosed in quotes, it consists of
1793   the rest of the current line, verbatim. Otherwise, string escapes
1794   are processed.
1795
1796   A transport is specified as a string, which is then looked up in the
1797   list of transports. A search type is specified as one of a number of
1798   known strings.
1799
1800   A set or rewrite rules for a driver is specified as a string, which is
1801   then parsed into a suitable chain of control blocks.
1802
1803   Uids and gids are specified as strings which are then looked up in the
1804   passwd file. Lists of uids and gids are similarly specified as colon-
1805   separated strings. */
1806
1807   case opt_stringptr:
1808   case opt_uid:
1809   case opt_gid:
1810   case opt_expand_uid:
1811   case opt_expand_gid:
1812   case opt_uidlist:
1813   case opt_gidlist:
1814   case opt_rewrite:
1815
1816     reset_point = store_mark();
1817     sptr = read_string(s, name);
1818
1819     /* Having read a string, we now have several different ways of using it,
1820     depending on the data type, so do another switch. If keeping the actual
1821     string is not required (because it is interpreted), freesptr is set TRUE,
1822     and at the end we reset the pool. */
1823
1824     switch (type)
1825       {
1826       /* If this was a string, set the variable to point to the new string,
1827       and set the flag so its store isn't reclaimed. If it was a list of rewrite
1828       rules, we still keep the string (for printing), and parse the rules into a
1829       control block and flags word. */
1830
1831       case opt_stringptr:
1832         str_target = data_block ? USS (US data_block + ol->v.offset)
1833                                 : USS ol->v.value;
1834         if (ol->type & opt_rep_con)
1835           {
1836           uschar * saved_condition;
1837           /* We already have a condition, we're conducting a crude hack to let
1838           multiple condition rules be chained together, despite storing them in
1839           text form. */
1840           *str_target = string_copy_perm( (saved_condition = *str_target)
1841             ? string_sprintf("${if and{{bool_lax{%s}}{bool_lax{%s}}}}",
1842                 saved_condition, sptr)
1843             : sptr,
1844             FALSE);
1845           /* TODO(pdp): there is a memory leak here and just below
1846           when we set 3 or more conditions; I still don't
1847           understand the store mechanism enough to know
1848           what's the safe way to free content from an earlier store.
1849           AFAICT, stores stack, so freeing an early stored item also stores
1850           all data alloc'd after it.  If we knew conditions were adjacent,
1851           we could survive that, but we don't.  So I *think* we need to take
1852           another bit from opt_type to indicate "malloced"; this seems like
1853           quite a hack, especially for this one case.  It also means that
1854           we can't ever reclaim the store from the *first* condition.
1855
1856           Because we only do this once, near process start-up, I'm prepared to
1857           let this slide for the time being, even though it rankles.  */
1858           }
1859         else if (ol->type & opt_rep_str)
1860           {
1861           uschar sep_o =
1862             Ustrncmp(name, "headers_add", 11) == 0      ? '\n'
1863             : Ustrncmp(name, "set", 3) == 0             ? ';'
1864             : ':';
1865           int    sep_i = -(int)sep_o;
1866           const uschar * list = sptr;
1867           uschar * s;
1868           gstring * list_o = NULL;
1869
1870           if (*str_target)
1871             {
1872             list_o = string_get(Ustrlen(*str_target) + Ustrlen(sptr));
1873             list_o = string_cat(list_o, *str_target);
1874             }
1875
1876           while ((s = string_nextinlist(&list, &sep_i, NULL, 0)))
1877             list_o = string_append_listele(list_o, sep_o, s);
1878
1879           if (list_o)
1880             *str_target = string_copy_perm(string_from_gstring(list_o), FALSE);
1881           }
1882         else
1883           {
1884           *str_target = sptr;
1885           freesptr = FALSE;
1886           }
1887         break;
1888
1889       case opt_rewrite:
1890         if (data_block)
1891           *USS (US data_block + ol->v.offset) = sptr;
1892         else
1893           *USS ol->v.value = sptr;
1894         freesptr = FALSE;
1895         if (type == opt_rewrite)
1896           {
1897           int sep = 0;
1898           int *flagptr;
1899           uschar *p = sptr;
1900           rewrite_rule **chain;
1901           optionlist *ol3;
1902
1903           sprintf(CS name2, "*%.50s_rules", name);
1904           ol2 = find_option(name2, oltop, last);
1905           sprintf(CS name2, "*%.50s_flags", name);
1906           ol3 = find_option(name2, oltop, last);
1907
1908           if (!ol2 || !ol3)
1909             log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN,
1910               "rewrite rules not available for driver");
1911
1912           if (data_block)
1913             {
1914             chain = (rewrite_rule **)(US data_block + ol2->v.offset);
1915             flagptr = (int *)(US data_block + ol3->v.offset);
1916             }
1917           else
1918             {
1919             chain = (rewrite_rule **)ol2->v.value;
1920             flagptr = (int *)ol3->v.value;
1921             }
1922
1923           /* This will trap if sptr is tainted. Not sure if that can happen */
1924           while ((p = string_nextinlist(CUSS &sptr, &sep, big_buffer, BIG_BUFFER_SIZE)))
1925             {
1926             rewrite_rule *next = readconf_one_rewrite(p, flagptr, FALSE);
1927             *chain = next;
1928             chain = &(next->next);
1929             }
1930
1931           if ((*flagptr & (rewrite_all_envelope | rewrite_smtp)) != 0)
1932             log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, "rewrite rule specifies a "
1933               "non-header rewrite - not allowed at transport time -");
1934           }
1935         break;
1936
1937       /* If it was an expanded uid, see if there is any expansion to be
1938       done by checking for the presence of a $ character. If there is, save it
1939       in the corresponding *expand_user option field. Otherwise, fall through
1940       to treat it as a fixed uid. Ensure mutual exclusivity of the two kinds
1941       of data. */
1942
1943       case opt_expand_uid:
1944         sprintf(CS name2, "*expand_%.50s", name);
1945         if ((ol2 = find_option(name2, oltop, last)))
1946           {
1947           uschar *ss = (Ustrchr(sptr, '$') != NULL) ? sptr : NULL;
1948
1949           if (data_block)
1950             *(USS(US data_block + ol2->v.offset)) = ss;
1951           else
1952             *(USS ol2->v.value) = ss;
1953
1954           if (ss)
1955             {
1956             *(get_set_flag(name, oltop, last, data_block)) = FALSE;
1957             freesptr = FALSE;
1958             break;
1959             }
1960           }
1961
1962       /* Look up a fixed uid, and also make use of the corresponding gid
1963       if a passwd entry is returned and the gid has not been set. */
1964
1965       case opt_uid:
1966         if (!route_finduser(sptr, &pw, &uid))
1967           log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, "user %s was not found", sptr);
1968         if (data_block)
1969           *(uid_t *)(US data_block + ol->v.offset) = uid;
1970         else
1971           *(uid_t *)ol->v.value = uid;
1972
1973         /* Set the flag indicating a fixed value is set */
1974
1975         *(get_set_flag(name, oltop, last, data_block)) = TRUE;
1976
1977         /* Handle matching gid if we have a passwd entry: done by finding the
1978         same name with terminating "user" changed to "group"; if not found,
1979         ignore. Also ignore if the value is already set. */
1980
1981         if (pw == NULL) break;
1982         Ustrcpy(name+Ustrlen(name)-4, US"group");
1983         ol2 = find_option(name, oltop, last);
1984         if (ol2 && ((ol2->type & opt_mask) == opt_gid ||
1985             (ol2->type & opt_mask) == opt_expand_gid))
1986           {
1987           BOOL *set_flag = get_set_flag(name, oltop, last, data_block);
1988           if (!*set_flag)
1989             {
1990             if (data_block)
1991               *((gid_t *)(US data_block + ol2->v.offset)) = pw->pw_gid;
1992             else
1993               *((gid_t *)ol2->v.value) = pw->pw_gid;
1994             *set_flag = TRUE;
1995             }
1996           }
1997         break;
1998
1999       /* If it was an expanded gid, see if there is any expansion to be
2000       done by checking for the presence of a $ character. If there is, save it
2001       in the corresponding *expand_user option field. Otherwise, fall through
2002       to treat it as a fixed gid. Ensure mutual exclusivity of the two kinds
2003       of data. */
2004
2005       case opt_expand_gid:
2006         sprintf(CS name2, "*expand_%.50s", name);
2007         if ((ol2 = find_option(name2, oltop, last)))
2008           {
2009           uschar *ss = (Ustrchr(sptr, '$') != NULL) ? sptr : NULL;
2010
2011           if (data_block)
2012             *(USS(US data_block + ol2->v.offset)) = ss;
2013           else
2014             *(USS ol2->v.value) = ss;
2015
2016           if (ss)
2017             {
2018             *(get_set_flag(name, oltop, last, data_block)) = FALSE;
2019             freesptr = FALSE;
2020             break;
2021             }
2022           }
2023
2024       /* Handle freestanding gid */
2025
2026       case opt_gid:
2027         if (!route_findgroup(sptr, &gid))
2028           log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, "group %s was not found", sptr);
2029         if (data_block)
2030           *((gid_t *)(US data_block + ol->v.offset)) = gid;
2031         else
2032           *((gid_t *)ol->v.value) = gid;
2033         *(get_set_flag(name, oltop, last, data_block)) = TRUE;
2034         break;
2035
2036       /* If it was a uid list, look up each individual entry, and build
2037       a vector of uids, with a count in the first element. Put the vector
2038       in malloc store so we can free the string. (We are reading into
2039       permanent store already.) */
2040
2041       case opt_uidlist:
2042         {
2043         int count = 1;
2044         uid_t *list;
2045         int ptr = 0;
2046         const uschar *p;
2047         const uschar *op = expand_string (sptr);
2048
2049         if (op == NULL)
2050           log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, "failed to expand %s: %s",
2051             name, expand_string_message);
2052
2053         p = op;
2054         if (*p != 0) count++;
2055         while (*p != 0) if (*p++ == ':' && *p != 0) count++;
2056         list = store_malloc(count*sizeof(uid_t));
2057         list[ptr++] = (uid_t)(count - 1);
2058
2059         if (data_block)
2060           *((uid_t **)(US data_block + ol->v.offset)) = list;
2061         else
2062           *((uid_t **)ol->v.value) = list;
2063
2064         p = op;
2065         while (count-- > 1)
2066           {
2067           int sep = 0;
2068           /* If p is tainted we trap.  Not sure that can happen */
2069           (void)string_nextinlist(&p, &sep, big_buffer, BIG_BUFFER_SIZE);
2070           if (!route_finduser(big_buffer, NULL, &uid))
2071             log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, "user %s was not found",
2072               big_buffer);
2073           list[ptr++] = uid;
2074           }
2075         break;
2076         }
2077
2078       /* If it was a gid list, look up each individual entry, and build
2079       a vector of gids, with a count in the first element. Put the vector
2080       in malloc store so we can free the string. (We are reading into permanent
2081       store already.) */
2082
2083       case opt_gidlist:
2084         {
2085         int count = 1;
2086         gid_t *list;
2087         int ptr = 0;
2088         const uschar *p;
2089         const uschar *op = expand_string (sptr);
2090
2091         if (!op)
2092           log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, "failed to expand %s: %s",
2093             name, expand_string_message);
2094
2095         p = op;
2096         if (*p != 0) count++;
2097         while (*p != 0) if (*p++ == ':' && *p != 0) count++;
2098         list = store_malloc(count*sizeof(gid_t));
2099         list[ptr++] = (gid_t)(count - 1);
2100
2101         if (data_block)
2102           *((gid_t **)(US data_block + ol->v.offset)) = list;
2103         else
2104           *((gid_t **)ol->v.value) = list;
2105
2106         p = op;
2107         while (count-- > 1)
2108           {
2109           int sep = 0;
2110           /* If p is tainted we trap.  Not sure that can happen */
2111           (void)string_nextinlist(&p, &sep, big_buffer, BIG_BUFFER_SIZE);
2112           if (!route_findgroup(big_buffer, &gid))
2113             log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, "group %s was not found",
2114               big_buffer);
2115           list[ptr++] = gid;
2116           }
2117         break;
2118         }
2119       }
2120
2121     /* Release store if the value of the string doesn't need to be kept. */
2122
2123     if (freesptr) reset_point = store_reset(reset_point);
2124     break;
2125
2126   /* Expanded boolean: if no characters follow, or if there are no dollar
2127   characters, this is a fixed-valued boolean, and we fall through. Otherwise,
2128   save the string for later expansion in the alternate place. */
2129
2130   case opt_expand_bool:
2131     if (*s && Ustrchr(s, '$') != 0)
2132       {
2133       sprintf(CS name2, "*expand_%.50s", name);
2134       if ((ol2 = find_option(name2, oltop, last)))
2135         {
2136         reset_point = store_mark();
2137         sptr = read_string(s, name);
2138         if (data_block)
2139           *(USS(US data_block + ol2->v.offset)) = sptr;
2140         else
2141           *(USS ol2->v.value) = sptr;
2142         freesptr = FALSE;
2143         break;
2144         }
2145       }
2146     /* Fall through */
2147
2148   /* Boolean: if no characters follow, the value is boolvalue. Otherwise
2149   look for yes/not/true/false. Some booleans are stored in a single bit in
2150   a single int. There's a special fudge for verify settings; without a suffix
2151   they set both xx_sender and xx_recipient. The table points to the sender
2152   value; search subsequently for the recipient. There's another special case:
2153   opt_bool_set also notes when a boolean has been set. */
2154
2155   case opt_bool:
2156   case opt_bit:
2157   case opt_bool_verify:
2158   case opt_bool_set:
2159     if (*s)
2160       {
2161       s = readconf_readname(name2, EXIM_DRIVERNAME_MAX, s);
2162       if (strcmpic(name2, US"true") == 0 || strcmpic(name2, US"yes") == 0)
2163         boolvalue = TRUE;
2164       else if (strcmpic(name2, US"false") == 0 || strcmpic(name2, US"no") == 0)
2165         boolvalue = FALSE;
2166       else log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN,
2167         "\"%s\" is not a valid value for the \"%s\" option", name2, name);
2168       if (*s != 0) extra_chars_error(s, string_sprintf("\"%s\" ", name2),
2169         US"for boolean option ", name);
2170       }
2171
2172     /* Handle single-bit type. */
2173
2174     if (type == opt_bit)
2175       {
2176       int bit = 1 << ((ol->type >> 16) & 31);
2177       int * ptr = data_block
2178         ? (int *)(US data_block + ol->v.offset)
2179         : (int *)ol->v.value;
2180       if (boolvalue) *ptr |= bit; else *ptr &= ~bit;
2181       break;
2182       }
2183
2184     /* Handle full BOOL types */
2185
2186     if (data_block)
2187       *((BOOL *)(US data_block + ol->v.offset)) = boolvalue;
2188     else
2189       *((BOOL *)ol->v.value) = boolvalue;
2190
2191     /* Verify fudge */
2192
2193     if (type == opt_bool_verify)
2194       {
2195       sprintf(CS name2, "%.50s_recipient", name + offset);
2196       if ((ol2 = find_option(name2, oltop, last)))
2197         if (data_block)
2198           *((BOOL *)(US data_block + ol2->v.offset)) = boolvalue;
2199         else
2200           *((BOOL *)ol2->v.value) = boolvalue;
2201       }
2202
2203     /* Note that opt_bool_set type is set, if there is somewhere to do so */
2204
2205     else if (type == opt_bool_set)
2206       {
2207       sprintf(CS name2, "*set_%.50s", name + offset);
2208       if ((ol2 = find_option(name2, oltop, last)))
2209         if (data_block)
2210           *((BOOL *)(US data_block + ol2->v.offset)) = TRUE;
2211         else
2212           *((BOOL *)ol2->v.value) = TRUE;
2213       }
2214     break;
2215
2216   /* Octal integer */
2217
2218   case opt_octint:
2219     intbase = 8;
2220     inttype = US"octal ";
2221
2222   /*  Integer: a simple(ish) case; allow octal and hex formats, and
2223   suffixes K, M, G, and T.  The different types affect output, not input. */
2224
2225   case opt_mkint:
2226   case opt_int:
2227      {
2228       uschar *endptr;
2229       long int lvalue;
2230
2231       errno = 0;
2232       lvalue = strtol(CS s, CSS &endptr, intbase);
2233
2234       if (endptr == s)
2235         log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, "%sinteger expected for %s",
2236           inttype, name);
2237
2238       if (errno != ERANGE && *endptr)
2239         {
2240         uschar * mp = US"TtGgMmKk\0";   /* YyZzEePpTtGgMmKk */
2241
2242         if ((mp = Ustrchr(mp, *endptr)))
2243           {
2244           endptr++;
2245           do
2246             {
2247             if (lvalue > INT_MAX/1024 || lvalue < INT_MIN/1024)
2248               {
2249               errno = ERANGE;
2250               break;
2251               }
2252             lvalue *= 1024;
2253             }
2254           while (*(mp += 2));
2255           }
2256         }
2257
2258       if (errno == ERANGE || lvalue > INT_MAX || lvalue < INT_MIN)
2259         log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN,
2260           "absolute value of integer \"%s\" is too large (overflow)", s);
2261
2262       if (Uskip_whitespace(&endptr))
2263         extra_chars_error(endptr, inttype, US"integer value for ", name);
2264
2265       value = (int)lvalue;
2266      }
2267
2268     if (data_block)
2269       *(int *)(US data_block + ol->v.offset) = value;
2270     else
2271       *(int *)ol->v.value = value;
2272     break;
2273
2274   /*  Integer held in K: again, allow formats and suffixes as above. */
2275
2276   case opt_Kint:
2277     {
2278     uschar *endptr;
2279     errno = 0;
2280     int_eximarith_t lvalue = strtol(CS s, CSS &endptr, intbase);
2281
2282     if (endptr == s)
2283       log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, "%sinteger expected for %s",
2284         inttype, name);
2285
2286     if (errno != ERANGE && *endptr)
2287       {
2288       uschar * mp = US"ZzEePpTtGgMmKk\0";       /* YyZzEePpTtGgMmKk */
2289
2290       if ((mp = Ustrchr(mp, *endptr)))
2291         {
2292         endptr++;
2293         while (*(mp += 2))
2294           {
2295           if (lvalue > EXIM_ARITH_MAX/1024 || lvalue < EXIM_ARITH_MIN/1024)
2296             {
2297             errno = ERANGE;
2298             break;
2299             }
2300           lvalue *= 1024;
2301           }
2302         }
2303       else
2304         lvalue = (lvalue + 512)/1024;
2305       }
2306
2307     if (errno == ERANGE) log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN,
2308       "absolute value of integer \"%s\" is too large (overflow)", s);
2309
2310     if (Uskip_whitespace(&endptr))
2311       extra_chars_error(endptr, inttype, US"integer value for ", name);
2312
2313     if (data_block)
2314       *(int_eximarith_t *)(US data_block + ol->v.offset) = lvalue;
2315     else
2316       *(int_eximarith_t *)ol->v.value = lvalue;
2317     break;
2318     }
2319
2320   /*  Fixed-point number: held to 3 decimal places. */
2321
2322   case opt_fixed:
2323     if (sscanf(CS s, "%d%n", &value, &count) != 1)
2324       log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN,
2325         "fixed-point number expected for %s", name);
2326
2327     if (value < 0) log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN,
2328       "integer \"%s\" is too large (overflow)", s);
2329
2330     value *= 1000;
2331
2332     if (value < 0) log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN,
2333       "integer \"%s\" is too large (overflow)", s);
2334
2335     /* We get a coverity error here for using count, as it derived
2336     from the tainted buffer pointed to by s, as parsed by sscanf().
2337     By the definition of sscanf we must be accessing between start
2338     and end of s (assuming it is nul-terminated...) so ignore the error.  */
2339     /* coverity[tainted_data] */
2340     if (s[count] == '.')
2341       {
2342       int d = 100;
2343       while (isdigit(s[++count]))
2344         {
2345         value += (s[count] - '0') * d;
2346         d /= 10;
2347         }
2348       }
2349
2350     while (isspace(s[count])) count++;
2351
2352     if (s[count] != 0)
2353       extra_chars_error(s+count, US"fixed-point value for ", name, US"");
2354
2355     if (data_block)
2356       *((int *)(US data_block + ol->v.offset)) = value;
2357     else
2358       *((int *)ol->v.value) = value;
2359     break;
2360
2361   /* There's a special routine to read time values. */
2362
2363   case opt_time:
2364     value = readconf_readtime(s, 0, FALSE);
2365     if (value < 0)
2366       log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, "invalid time value for %s",
2367         name);
2368     if (data_block)
2369       *((int *)(US data_block + ol->v.offset)) = value;
2370     else
2371       *((int *)ol->v.value) = value;
2372     break;
2373
2374   /* A time list is a list of colon-separated times, with the first
2375   element holding the size of the list and the second the number of
2376   entries used. */
2377
2378   case opt_timelist:
2379     {
2380     int count = 0;
2381     int * list = data_block
2382       ? (int *)(US data_block + ol->v.offset)
2383       : (int *)ol->v.value;
2384
2385     if (*s != 0) for (count = 1; count <= list[0] - 2; count++)
2386       {
2387       int terminator = 0;
2388       uschar *snext = Ustrchr(s, ':');
2389       if (snext != NULL)
2390         {
2391         uschar *ss = snext;
2392         while (ss > s && isspace(ss[-1])) ss--;
2393         terminator = *ss;
2394         }
2395       value = readconf_readtime(s, terminator, FALSE);
2396       if (value < 0)
2397         log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, "invalid time value for %s",
2398           name);
2399       if (count > 1 && value <= list[count])
2400         log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN,
2401           "time value out of order for %s", name);
2402       list[count+1] = value;
2403       if (snext == NULL) break;
2404       s = snext + 1;
2405       Uskip_whitespace(&s);
2406       }
2407
2408     if (count > list[0] - 2)
2409       log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, "too many time values for %s",
2410         name);
2411     if (count > 0 && list[2] == 0) count = 0;
2412     list[1] = count;
2413     break;
2414     }
2415
2416   case opt_func:
2417     ol->v.fn(name, s, 0);
2418     break;
2419   }
2420
2421 return TRUE;
2422 }
2423
2424
2425
2426 /*************************************************
2427 *               Print a time value               *
2428 *************************************************/
2429
2430 /*
2431 Argument:  a time value in seconds
2432 Returns:   pointer to a fixed buffer containing the time as a string,
2433            in readconf_readtime() format
2434 */
2435
2436 uschar *
2437 readconf_printtime(int t)
2438 {
2439 int s, m, h, d, w;
2440 uschar *p = time_buffer;
2441
2442 if (t < 0) *p++ = '-', t = -t;
2443
2444 s = t % 60;
2445 t /= 60;
2446 m = t % 60;
2447 t /= 60;
2448 h = t % 24;
2449 t /= 24;
2450 d = t % 7;
2451 w = t/7;
2452
2453 if (w > 0) p += sprintf(CS p, "%dw", w);
2454 if (d > 0) p += sprintf(CS p, "%dd", d);
2455 if (h > 0) p += sprintf(CS p, "%dh", h);
2456 if (m > 0) p += sprintf(CS p, "%dm", m);
2457 if (s > 0 || p == time_buffer) sprintf(CS p, "%ds", s);
2458
2459 return time_buffer;
2460 }
2461
2462
2463
2464 /*************************************************
2465 *      Print an individual option value          *
2466 *************************************************/
2467
2468 /* This is used by the -bP option, so prints to the standard output.
2469 The entire options list is passed in as an argument, because some options come
2470 in pairs - typically uid/gid settings, which can either be explicit numerical
2471 values, or strings to be expanded later. If the numerical value is unset,
2472 search for "*expand_<name>" to see if there is a string equivalent.
2473
2474 Arguments:
2475   ol             option entry, or NULL for an unknown option
2476   name           option name
2477   options_block  NULL for main configuration options; otherwise points to
2478                    a driver block; if the option doesn't have opt_public
2479                    set, then options_block->options_block is where the item
2480                    resides.
2481   oltop          points to the option list in which ol exists
2482   last           one more than the offset of the last entry in optop
2483   no_labels      do not show "foo = " at the start.
2484
2485 Returns:         boolean success
2486 */
2487
2488 static BOOL
2489 print_ol(optionlist *ol, const uschar *name, void *options_block,
2490   optionlist *oltop, int last, BOOL no_labels)
2491 {
2492 struct passwd *pw;
2493 struct group *gr;
2494 optionlist *ol2;
2495 void *value;
2496 uid_t *uidlist;
2497 gid_t *gidlist;
2498 uschar *s;
2499 uschar name2[EXIM_DRIVERNAME_MAX];
2500
2501 if (!ol)
2502   {
2503   printf("%s is not a known option\n", name);
2504   return FALSE;
2505   }
2506
2507 /* Non-admin callers cannot see options that have been flagged secure by the
2508 "hide" prefix. */
2509
2510 if (!f.admin_user && ol->type & opt_secure)
2511   {
2512   if (no_labels)
2513     printf("%s\n", CCS hidden);
2514   else
2515     printf("%s = %s\n", name, CCS hidden);
2516   return TRUE;
2517   }
2518
2519 /* Else show the value of the option */
2520
2521 value = ol->v.value;
2522 if (options_block)
2523   {
2524   if (!(ol->type & opt_public))
2525     options_block = (void *)(((driver_instance *)options_block)->options_block);
2526   value = (void *)(US options_block + (long int)value);
2527   }
2528
2529 switch(ol->type & opt_mask)
2530   {
2531   case opt_stringptr:
2532   case opt_rewrite:        /* Show the text value */
2533     s = *(USS value);
2534     if (!no_labels) printf("%s = ", name);
2535     printf("%s\n", s ? string_printing2(s, SP_TAB) : US"");
2536     break;
2537
2538   case opt_int:
2539     if (!no_labels) printf("%s = ", name);
2540     printf("%d\n", *((int *)value));
2541     break;
2542
2543   case opt_mkint:
2544     {
2545     int x = *((int *)value);
2546     if (x != 0 && (x & 1023) == 0)
2547       {
2548       int c = 'K';
2549       x >>= 10;
2550       if ((x & 1023) == 0)
2551         {
2552         c = 'M';
2553         x >>= 10;
2554         }
2555       if (!no_labels) printf("%s = ", name);
2556       printf("%d%c\n", x, c);
2557       }
2558     else
2559       {
2560       if (!no_labels) printf("%s = ", name);
2561       printf("%d\n", x);
2562       }
2563     }
2564     break;
2565
2566   case opt_Kint:
2567     {
2568     int_eximarith_t x = *((int_eximarith_t *)value);
2569     if (!no_labels) printf("%s = ", name);
2570     if (x == 0) printf("0\n");
2571     else if ((x & ((1<<30)-1)) == 0) printf(PR_EXIM_ARITH "T\n", x >> 30);
2572     else if ((x & ((1<<20)-1)) == 0) printf(PR_EXIM_ARITH "G\n", x >> 20);
2573     else if ((x & ((1<<10)-1)) == 0) printf(PR_EXIM_ARITH "M\n", x >> 10);
2574     else printf(PR_EXIM_ARITH "K\n", x);
2575     }
2576     break;
2577
2578   case opt_octint:
2579     if (!no_labels) printf("%s = ", name);
2580     printf("%#o\n", *((int *)value));
2581     break;
2582
2583   /* Can be negative only when "unset", in which case integer */
2584
2585   case opt_fixed:
2586     {
2587     int x = *((int *)value);
2588     int f = x % 1000;
2589     int d = 100;
2590     if (x < 0) printf("%s =\n", name); else
2591       {
2592       if (!no_labels) printf("%s = ", name);
2593       printf("%d.", x/1000);
2594       do
2595         {
2596         printf("%d", f/d);
2597         f %= d;
2598         d /= 10;
2599         }
2600       while (f != 0);
2601       printf("\n");
2602       }
2603     }
2604     break;
2605
2606   /* If the numerical value is unset, try for the string value */
2607
2608   case opt_expand_uid:
2609     if (! *get_set_flag(name, oltop, last, options_block))
2610       {
2611       sprintf(CS name2, "*expand_%.50s", name);
2612       if ((ol2 = find_option(name2, oltop, last)))
2613         {
2614         if (options_block)
2615           s = *USS (US options_block + ol2->v.offset);
2616         else
2617           s = *USS ol2->v.value;
2618         if (!no_labels) printf("%s = ", name);
2619         printf("%s\n", s ? string_printing(s) : US"");
2620         break;
2621         }
2622       }
2623
2624     /* Else fall through */
2625
2626   case opt_uid:
2627     if (!no_labels) printf("%s = ", name);
2628     if (! *get_set_flag(name, oltop, last, options_block))
2629       printf("\n");
2630     else
2631       if ((pw = getpwuid(*((uid_t *)value))))
2632         printf("%s\n", pw->pw_name);
2633       else
2634         printf("%ld\n", (long int)(*((uid_t *)value)));
2635     break;
2636
2637   /* If the numerical value is unset, try for the string value */
2638
2639   case opt_expand_gid:
2640     if (! *get_set_flag(name, oltop, last, options_block))
2641       {
2642       sprintf(CS name2, "*expand_%.50s", name);
2643       if (  (ol2 = find_option(name2, oltop, last))
2644          && (ol2->type & opt_mask) == opt_stringptr)
2645         {
2646         if (options_block)
2647           s = *USS (US options_block + ol2->v.offset);
2648         else
2649           s = *USS ol2->v.value;
2650         if (!no_labels) printf("%s = ", name);
2651         printf("%s\n", s ? string_printing(s) : US"");
2652         break;
2653         }
2654       }
2655
2656     /* Else fall through */
2657
2658   case opt_gid:
2659     if (!no_labels) printf("%s = ", name);
2660     if (! *get_set_flag(name, oltop, last, options_block))
2661       printf("\n");
2662     else
2663       if ((gr = getgrgid(*((int *)value))))
2664         printf("%s\n", gr->gr_name);
2665       else
2666          printf("%ld\n", (long int)(*((int *)value)));
2667     break;
2668
2669   case opt_uidlist:
2670     uidlist = *((uid_t **)value);
2671     if (!no_labels) printf("%s =", name);
2672     if (uidlist)
2673       {
2674       uschar sep = no_labels ? '\0' : ' ';
2675       for (int i = 1; i <= (int)(uidlist[0]); i++)
2676         {
2677         uschar *name = NULL;
2678         if ((pw = getpwuid(uidlist[i]))) name = US pw->pw_name;
2679         if (sep != '\0') printf("%c", sep);
2680         if (name) printf("%s", name);
2681         else printf("%ld", (long int)(uidlist[i]));
2682         sep = ':';
2683         }
2684       }
2685     printf("\n");
2686     break;
2687
2688   case opt_gidlist:
2689     gidlist = *((gid_t **)value);
2690     if (!no_labels) printf("%s =", name);
2691     if (gidlist)
2692       {
2693       uschar sep = no_labels ? '\0' : ' ';
2694       for (int i = 1; i <= (int)(gidlist[0]); i++)
2695         {
2696         uschar *name = NULL;
2697         if ((gr = getgrgid(gidlist[i]))) name = US gr->gr_name;
2698         if (sep != '\0') printf("%c", sep);
2699         if (name) printf("%s", name);
2700         else printf("%ld", (long int)(gidlist[i]));
2701         sep = ':';
2702         }
2703       }
2704     printf("\n");
2705     break;
2706
2707   case opt_time:
2708     if (!no_labels) printf("%s = ", name);
2709     printf("%s\n", readconf_printtime(*((int *)value)));
2710     break;
2711
2712   case opt_timelist:
2713     {
2714     int *list = (int *)value;
2715     if (!no_labels) printf("%s = ", name);
2716     for (int i = 0; i < list[1]; i++)
2717       printf("%s%s", i == 0 ? "" : ":", readconf_printtime(list[i+2]));
2718     printf("\n");
2719     }
2720     break;
2721
2722   case opt_bit:
2723     printf("%s%s\n", (*((int *)value)) & (1 << ((ol->type >> 16) & 31))
2724       ? "" : "no_", name);
2725     break;
2726
2727   case opt_expand_bool:
2728     sprintf(CS name2, "*expand_%.50s", name);
2729     if ((ol2 = find_option(name2, oltop, last)) && ol2->v.value)
2730       {
2731       if (options_block)
2732         s = *USS (US options_block + ol2->v.offset);
2733       else
2734         s = *USS ol2->v.value;
2735       if (s)
2736         {
2737         if (!no_labels) printf("%s = ", name);
2738         printf("%s\n", string_printing(s));
2739         break;
2740         }
2741       /* s == NULL => string not set; fall through */
2742       }
2743
2744     /* Fall through */
2745
2746   case opt_bool:
2747   case opt_bool_verify:
2748   case opt_bool_set:
2749     printf("%s%s\n", *((BOOL *)value) ? "" : "no_", name);
2750     break;
2751
2752   case opt_func:
2753     ol->v.fn(name, NULL, no_labels ? opt_fn_print : opt_fn_print|opt_fn_print_label);
2754     break;
2755   }
2756 return TRUE;
2757 }
2758
2759
2760
2761 /*************************************************
2762 *        Print value from main configuration     *
2763 *************************************************/
2764
2765 /* This function, called as a result of encountering the -bP option,
2766 causes the value of any main configuration variable to be output if the
2767 second argument is NULL. There are some special values:
2768
2769   all                print all main configuration options
2770   config_file        print the name of the configuration file
2771                      (configure_file will still work, for backward
2772                      compatibility)
2773   routers            print the routers' configurations
2774   transports         print the transports' configuration
2775   authenticators     print the authenticators' configuration
2776   macros             print the macros' configuration
2777   router_list        print a list of router names
2778   transport_list     print a list of transport names
2779   authenticator_list print a list of authentication mechanism names
2780   macro_list         print a list of macro names
2781   +name              print a named list item
2782   local_scan         print the local_scan options
2783   config             print the configuration as it is parsed
2784   environment        print the used execution environment
2785
2786 If the second argument is not NULL, it must be one of "router", "transport",
2787 "authenticator" or "macro" in which case the first argument identifies the
2788 driver whose options are to be printed.
2789
2790 Arguments:
2791   name        option name if type == NULL; else driver name
2792   type        NULL or driver type name, as described above
2793   no_labels   avoid the "foo = " at the start of an item
2794
2795 Returns:      Boolean success
2796 */
2797
2798 BOOL
2799 readconf_print(const uschar * name, const uschar * type, BOOL no_labels)
2800 {
2801 BOOL names_only = FALSE;
2802 optionlist *ol2 = NULL;
2803 driver_instance *d = NULL;
2804 int size = 0;
2805
2806 if (!type)
2807   {
2808   if (*name == '+')
2809     {
2810     tree_node *t;
2811     BOOL found = FALSE;
2812     static uschar *types[] = { US"address", US"domain", US"host",
2813       US"localpart" };
2814     static tree_node **anchors[] = { &addresslist_anchor, &domainlist_anchor,
2815       &hostlist_anchor, &localpartlist_anchor };
2816
2817     for (int i = 0; i < 4; i++)
2818       if ((t = tree_search(*(anchors[i]), name+1)))
2819         {
2820         namedlist_block * nb = t->data.ptr;
2821         const uschar * s = nb->hide ? hidden : nb->string;
2822         found = TRUE;
2823         if (no_labels)
2824           printf("%s\n", CCS s);
2825         else
2826           printf("%slist %s = %s\n", types[i], name+1, CCS s);
2827         }
2828
2829     if (!found)
2830       printf("no address, domain, host, or local part list called \"%s\" "
2831         "exists\n", name+1);
2832
2833     return found;
2834     }
2835
2836   if (  Ustrcmp(name, "configure_file") == 0
2837      || Ustrcmp(name, "config_file") == 0)
2838     {
2839     printf("%s\n", CS config_main_filename);
2840     return TRUE;
2841     }
2842
2843   if (Ustrcmp(name, "all") == 0)
2844     {
2845     for (optionlist * ol = optionlist_config;
2846          ol < optionlist_config + nelem(optionlist_config); ol++)
2847       if (!(ol->type & opt_hidden))
2848         (void) print_ol(ol, US ol->name, NULL,
2849                   optionlist_config, nelem(optionlist_config),
2850                   no_labels);
2851     return TRUE;
2852     }
2853
2854   if (Ustrcmp(name, "local_scan") == 0)
2855     {
2856 #ifndef LOCAL_SCAN_HAS_OPTIONS
2857     printf("local_scan() options are not supported\n");
2858     return FALSE;
2859 #else
2860     for (optionlist * ol = local_scan_options;
2861          ol < local_scan_options + local_scan_options_count; ol++)
2862       (void) print_ol(ol, US ol->name, NULL, local_scan_options,
2863                   local_scan_options_count, no_labels);
2864     return TRUE;
2865 #endif
2866     }
2867
2868   if (Ustrcmp(name, "config") == 0)
2869     {
2870     print_config(f.admin_user, no_labels);
2871     return TRUE;
2872     }
2873
2874   if (Ustrcmp(name, "routers") == 0)
2875     {
2876     type = US"router";
2877     name = NULL;
2878     }
2879   else if (Ustrcmp(name, "transports") == 0)
2880     {
2881     type = US"transport";
2882     name = NULL;
2883     }
2884   else if (Ustrcmp(name, "authenticators") == 0)
2885     {
2886     type = US"authenticator";
2887     name = NULL;
2888     }
2889   else if (Ustrcmp(name, "macros") == 0)
2890     {
2891     type = US"macro";
2892     name = NULL;
2893     }
2894   else if (Ustrcmp(name, "router_list") == 0)
2895     {
2896     type = US"router";
2897     name = NULL;
2898     names_only = TRUE;
2899     }
2900   else if (Ustrcmp(name, "transport_list") == 0)
2901     {
2902     type = US"transport";
2903     name = NULL;
2904     names_only = TRUE;
2905     }
2906   else if (Ustrcmp(name, "authenticator_list") == 0)
2907     {
2908     type = US"authenticator";
2909     name = NULL;
2910     names_only = TRUE;
2911     }
2912   else if (Ustrcmp(name, "macro_list") == 0)
2913     {
2914     type = US"macro";
2915     name = NULL;
2916     names_only = TRUE;
2917     }
2918   else if (Ustrcmp(name, "environment") == 0)
2919     {
2920     if (environ)
2921       {
2922       uschar ** p;
2923       for (p = USS environ; *p; p++) ;
2924       qsort(environ, p - USS environ, sizeof(*p), string_compare_by_pointer);
2925
2926       for (p = USS environ; *p; p++)
2927         {
2928         uschar * q;
2929         if (no_labels && (q = Ustrchr(*p, '='))) *q  = '\0';
2930         puts(CS *p);
2931         }
2932       }
2933     return TRUE;
2934     }
2935
2936   else
2937     return print_ol(find_option(name,
2938                       optionlist_config, nelem(optionlist_config)),
2939       name, NULL, optionlist_config, nelem(optionlist_config), no_labels);
2940   }
2941
2942 /* Handle the options for a router or transport. Skip options that are flagged
2943 as hidden. Some of these are options with names starting with '*', used for
2944 internal alternative representations of other options (which the printing
2945 function will sort out). Others are synonyms kept for backward compatibility.
2946 */
2947
2948 if (Ustrcmp(type, "router") == 0)
2949   {
2950   d = (driver_instance *)routers;
2951   ol2 = optionlist_routers;
2952   size = optionlist_routers_size;
2953   }
2954 else if (Ustrcmp(type, "transport") == 0)
2955   {
2956   d = (driver_instance *)transports;
2957   ol2 = optionlist_transports;
2958   size = optionlist_transports_size;
2959   }
2960 else if (Ustrcmp(type, "authenticator") == 0)
2961   {
2962   d = (driver_instance *)auths;
2963   ol2 = optionlist_auths;
2964   size = optionlist_auths_size;
2965   }
2966
2967 else if (Ustrcmp(type, "macro") == 0)
2968   {
2969   /* People store passwords in macros and they were previously not available
2970   for printing.  So we have an admin_users restriction. */
2971   if (!f.admin_user)
2972     {
2973     fprintf(stderr, "exim: permission denied; not admin\n");
2974     return FALSE;
2975     }
2976   for (macro_item * m = macros; m; m = m->next)
2977     if (!name || Ustrcmp(name, m->name) == 0)
2978       {
2979       if (names_only)
2980         printf("%s\n", CS m->name);
2981       else if (no_labels)
2982         printf("%s\n", CS m->replacement);
2983       else
2984         printf("%s=%s\n", CS m->name, CS m->replacement);
2985       if (name)
2986         return TRUE;
2987       }
2988   if (!name) return TRUE;
2989
2990   printf("%s %s not found\n", type, name);
2991   return FALSE;
2992   }
2993
2994 if (names_only)
2995   {
2996   for (; d; d = d->next) printf("%s\n", CS d->name);
2997   return TRUE;
2998   }
2999
3000 /* Either search for a given driver, or print all of them */
3001
3002 for (; d; d = d->next)
3003   {
3004   BOOL rc = FALSE;
3005   if (!name)
3006     printf("\n%s %s:\n", d->name, type);
3007   else if (Ustrcmp(d->name, name) != 0) continue;
3008
3009   for (optionlist * ol = ol2; ol < ol2 + size; ol++)
3010     if (!(ol->type & opt_hidden))
3011       rc |= print_ol(ol, US ol->name, d, ol2, size, no_labels);
3012
3013   for (optionlist * ol = d->info->options;
3014        ol < d->info->options + *(d->info->options_count); ol++)
3015     if (!(ol->type & opt_hidden))
3016       rc |= print_ol(ol, US ol->name, d, d->info->options,
3017                     *d->info->options_count, no_labels);
3018
3019   if (name) return rc;
3020   }
3021 if (!name) return TRUE;
3022
3023 printf("%s %s not found\n", type, name);
3024 return FALSE;
3025 }
3026
3027
3028
3029 /*************************************************
3030 *          Read a named list item                *
3031 *************************************************/
3032
3033 /* This function reads a name and a list (i.e. string). The name is used to
3034 save the list in a tree, sorted by its name. Each entry also has a number,
3035 which can be used for caching tests, but if the string contains any expansion
3036 items other than $key, the number is set negative to inhibit caching. This
3037 mechanism is used for domain, host, and address lists that are referenced by
3038 the "+name" syntax.
3039
3040 Arguments:
3041   anchorp     points to the tree anchor
3042   numberp     points to the current number for this tree
3043   max         the maximum number permitted
3044   s           the text of the option line, starting immediately after the name
3045                 of the list type
3046   tname       the name of the list type, for messages
3047   hide        do not output value on "-bP"
3048
3049 Returns:      nothing
3050 */
3051
3052 static void
3053 read_named_list(tree_node **anchorp, int *numberp, int max, uschar *s,
3054   uschar *tname, BOOL hide)
3055 {
3056 BOOL forcecache = FALSE;
3057 uschar *ss;
3058 tree_node *t;
3059 namedlist_block * nb = store_get_perm(sizeof(namedlist_block), FALSE);
3060
3061 if (Ustrncmp(s, "_cache", 6) == 0)
3062   {
3063   forcecache = TRUE;
3064   s += 6;
3065   }
3066
3067 if (!isspace(*s))
3068   log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, "unrecognized configuration line");
3069
3070 if (*numberp >= max)
3071  log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, "too many named %ss (max is %d)\n",
3072    tname, max);
3073
3074 Uskip_whitespace(&s);
3075 ss = s;
3076 while (isalnum(*s) || *s == '_') s++;
3077 t = store_get(sizeof(tree_node) + s-ss, ss);
3078 Ustrncpy(t->name, ss, s-ss);
3079 t->name[s-ss] = 0;
3080 Uskip_whitespace(&s);
3081
3082 if (!tree_insertnode(anchorp, t))
3083   log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN,
3084     "duplicate name \"%s\" for a named %s", t->name, tname);
3085
3086 t->data.ptr = nb;
3087 nb->number = *numberp;
3088 *numberp += 1;
3089 nb->hide = hide;
3090
3091 if (*s++ != '=') log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN,
3092   "missing '=' after \"%s\"", t->name);
3093 Uskip_whitespace(&s);
3094 nb->string = read_string(s, t->name);
3095 nb->cache_data = NULL;
3096
3097 /* Check the string for any expansions; if any are found, mark this list
3098 uncacheable unless the user has explicited forced caching. */
3099
3100 if (!forcecache && Ustrchr(nb->string, '$') != NULL) nb->number = -1;
3101 }
3102
3103
3104
3105
3106 /*************************************************
3107 *        Unpick data for a rate limit            *
3108 *************************************************/
3109
3110 /* This function is called to unpick smtp_ratelimit_{mail,rcpt} into four
3111 separate values.
3112
3113 Arguments:
3114   s            string, in the form t,b,f,l
3115                where t is the threshold (integer)
3116                b is the initial delay (time)
3117                f is the multiplicative factor (fixed point)
3118                k is the maximum time (time)
3119   threshold    where to store threshold
3120   base         where to store base in milliseconds
3121   factor       where to store factor in milliseconds
3122   limit        where to store limit
3123
3124 Returns:       nothing (panics on error)
3125 */
3126
3127 static void
3128 unpick_ratelimit(uschar *s, int *threshold, int *base, double *factor,
3129   int *limit)
3130 {
3131 uschar bstring[16], lstring[16];
3132
3133 if (sscanf(CS s, "%d, %15[0123456789smhdw.], %lf, %15s", threshold, bstring,
3134     factor, lstring) == 4)
3135   {
3136   *base = readconf_readtime(bstring, 0, TRUE);
3137   *limit = readconf_readtime(lstring, 0, TRUE);
3138   if (*base >= 0 && *limit >= 0) return;
3139   }
3140 log_write(0, LOG_MAIN|LOG_PANIC_DIE, "malformed ratelimit data: %s", s);
3141 }
3142
3143
3144
3145
3146 /*************************************************
3147 *         Read main configuration options        *
3148 *************************************************/
3149
3150 /* This function is the first to be called for configuration reading. It
3151 opens the configuration file and reads general configuration settings until
3152 it reaches the end of the configuration section. The file is then left open so
3153 that the remaining configuration data can subsequently be read if needed for
3154 this run of Exim.
3155
3156 The configuration file must be owned either by root or exim, and be writeable
3157 only by root or uid/gid exim. The values for Exim's uid and gid can be changed
3158 in the config file, so the test is done on the compiled in values. A slight
3159 anomaly, to be carefully documented.
3160
3161 The name of the configuration file is taken from a list that is included in the
3162 binary of Exim. It can be altered from the command line, but if that is done,
3163 root privilege is immediately withdrawn unless the caller is root or exim.
3164 The first file on the list that exists is used.
3165
3166 For use on multiple systems that share file systems, first look for a
3167 configuration file whose name has the current node name on the end. If that is
3168 not found, try the generic name. For really contorted configurations, that run
3169 multiple Exims with different uid settings, first try adding the effective uid
3170 before the node name. These complications are going to waste resources on most
3171 systems. Therefore they are available only when requested by compile-time
3172 options. */
3173
3174 void
3175 readconf_main(BOOL nowarn)
3176 {
3177 int sep = 0;
3178 struct stat statbuf;
3179 uschar * s, * filename;
3180 const uschar * list = config_main_filelist;
3181
3182 /* Loop through the possible file names */
3183
3184 /* Should never be a tainted list */
3185 while((filename = string_nextinlist(&list, &sep, big_buffer, big_buffer_size)))
3186   {
3187
3188   /* Cut out all the fancy processing unless specifically wanted */
3189
3190 #if defined(CONFIGURE_FILE_USE_NODE) || defined(CONFIGURE_FILE_USE_EUID)
3191   uschar *suffix = filename + Ustrlen(filename);
3192
3193   /* Try for the node-specific file if a node name exists */
3194
3195 # ifdef CONFIGURE_FILE_USE_NODE
3196   struct utsname uts;
3197   if (uname(&uts) >= 0)
3198     {
3199 #  ifdef CONFIGURE_FILE_USE_EUID
3200     sprintf(CS suffix, ".%ld.%.256s", (long int)original_euid, uts.nodename);
3201     if (!(config_file = Ufopen(filename, "rb")))
3202 #  endif  /* CONFIGURE_FILE_USE_EUID */
3203       {
3204       sprintf(CS suffix, ".%.256s", uts.nodename);
3205       config_file = Ufopen(filename, "rb");
3206       }
3207     }
3208 # endif  /* CONFIGURE_FILE_USE_NODE */
3209
3210   /* Otherwise, try the generic name, possibly with the euid added */
3211
3212 # ifdef CONFIGURE_FILE_USE_EUID
3213   if (!config_file)
3214     {
3215     sprintf(CS suffix, ".%ld", (long int)original_euid);
3216     config_file = Ufopen(filename, "rb");
3217     }
3218 # endif  /* CONFIGURE_FILE_USE_EUID */
3219
3220   /* Finally, try the unadorned name */
3221
3222   if (!config_file)
3223     {
3224     *suffix = 0;
3225     config_file = Ufopen(filename, "rb");
3226     }
3227 #else  /* if neither defined */
3228
3229   /* This is the common case when the fancy processing is not included. */
3230
3231   config_file = Ufopen(filename, "rb");
3232 #endif
3233
3234   /* If the file does not exist, continue to try any others. For any other
3235   error, break out (and die). */
3236
3237   if (config_file || errno != ENOENT) break;
3238   }
3239
3240 /* On success, save the name for verification; config_filename is used when
3241 logging configuration errors (it changes for .included files) whereas
3242 config_main_filename is the name shown by -bP. Failure to open a configuration
3243 file is a serious disaster. */
3244
3245 if (config_file)
3246   {
3247   uschar *last_slash = Ustrrchr(filename, '/');
3248   config_filename = config_main_filename = string_copy(filename);
3249
3250   /* The config_main_directory we need for the $config_dir expansion.
3251   config_main_filename we need for $config_file expansion.
3252   And config_dir is the directory of the current configuration, used for
3253   relative .includes. We do need to know it's name, as we change our working
3254   directory later. */
3255
3256   if (filename[0] == '/')
3257     config_main_directory = last_slash == filename ? US"/" : string_copyn(filename, last_slash - filename);
3258   else
3259     {
3260     /* relative configuration file name: working dir + / + basename(filename) */
3261
3262     uschar buf[PATH_MAX];
3263     gstring * g;
3264
3265     if (os_getcwd(buf, PATH_MAX) == NULL)
3266       {
3267       perror("exim: getcwd");
3268       exit(EXIT_FAILURE);
3269       }
3270     g = string_cat(NULL, buf);
3271
3272     /* If the dir does not end with a "/", append one */
3273     if (gstring_last_char(g) != '/')
3274       g = string_catn(g, US"/", 1);
3275
3276     /* If the config file contains a "/", extract the directory part */
3277     if (last_slash)
3278       g = string_catn(g, filename, last_slash - filename);
3279
3280     config_main_directory = string_from_gstring(g);
3281     }
3282   config_directory = config_main_directory;
3283   }
3284 else
3285   if (!filename)
3286     log_write(0, LOG_MAIN|LOG_PANIC_DIE, "non-existent configuration file(s): "
3287       "%s", config_main_filelist);
3288   else
3289     log_write(0, LOG_MAIN|LOG_PANIC_DIE, "%s",
3290       string_open_failed("configuration file %s", filename));
3291
3292 /* Now, once we found and opened our configuration file, we change the directory
3293 to a safe place. Later we change to $spool_directory. */
3294
3295 if (Uchdir("/") < 0)
3296   {
3297   perror("exim: chdir `/': ");
3298   exit(EXIT_FAILURE);
3299   }
3300
3301 /* Check the status of the file we have opened, if we have retained root
3302 privileges and the file isn't /dev/null (which *should* be 0666). */
3303
3304 if (f.trusted_config && Ustrcmp(filename, US"/dev/null"))
3305   {
3306   if (fstat(fileno(config_file), &statbuf) != 0)
3307     log_write(0, LOG_MAIN|LOG_PANIC_DIE, "failed to stat configuration file %s",
3308       big_buffer);
3309
3310   if (    statbuf.st_uid != root_uid            /* owner not root */
3311 #ifdef CONFIGURE_OWNER
3312        && statbuf.st_uid != config_uid          /* owner not the special one */
3313 #endif
3314      ||                                         /* or */
3315           statbuf.st_gid != root_gid            /* group not root & */
3316 #ifdef CONFIGURE_GROUP
3317        && statbuf.st_gid != config_gid          /* group not the special one */
3318 #endif
3319        && (statbuf.st_mode & 020) != 0          /* group writeable  */
3320      ||                                         /* or */
3321        (statbuf.st_mode & 2) != 0               /* world writeable  */
3322      )
3323     log_write(0, LOG_MAIN|LOG_PANIC_DIE, "Exim configuration file %s has the "
3324       "wrong owner, group, or mode", big_buffer);
3325
3326   /* Do a dummy store-allocation of a size related to the (toplevel) file size.
3327   This assumes we will need this much storage to handle all the allocations
3328   during startup; it won't help when .include is being used.  When it does, it
3329   will cut down on the number of store blocks (and malloc calls, and sbrk
3330   syscalls).  It also assume we're on the relevant pool. */
3331
3332   if (statbuf.st_size > 8192)
3333     {
3334     rmark r = store_mark();
3335     void * dummy = store_get((int)statbuf.st_size, GET_UNTAINTED);
3336     store_reset(r);
3337     }
3338   }
3339
3340 /* Process the main configuration settings. They all begin with a lower case
3341 letter. If we see something starting with an upper case letter, it is taken as
3342 a macro definition. */
3343
3344 while ((s = get_config_line()))
3345   {
3346   BOOL hide;
3347   uschar * t;
3348
3349   if (config_lineno == 1 && Ustrstr(s, "\xef\xbb\xbf") == s)
3350     log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN,
3351       "found unexpected BOM (Byte Order Mark)");
3352
3353   if (isupper(*s))
3354     {
3355     if (!macro_read_assignment(s)) exim_exit(EXIT_FAILURE);
3356     continue;
3357     }
3358
3359   t = (hide = Ustrncmp(s, "hide", 4) == 0 && isspace(s[4])) ? s + 5 : s;
3360
3361   if (Ustrncmp(t, "domainlist", 10) == 0)
3362     read_named_list(&domainlist_anchor, &domainlist_count,
3363       MAX_NAMED_LIST, t+10, US"domain list", hide);
3364
3365   else if (Ustrncmp(t, "hostlist", 8) == 0)
3366     read_named_list(&hostlist_anchor, &hostlist_count,
3367       MAX_NAMED_LIST, t+8, US"host list", hide);
3368
3369   else if (Ustrncmp(t, "addresslist", 11) == 0)
3370     read_named_list(&addresslist_anchor, &addresslist_count,
3371       MAX_NAMED_LIST, t+11, US"address list", hide);
3372
3373   else if (Ustrncmp(t, "localpartlist", 13) == 0)
3374     read_named_list(&localpartlist_anchor, &localpartlist_count,
3375       MAX_NAMED_LIST, t+13, US"local part list", hide);
3376
3377   else
3378     (void) readconf_handle_option(s, optionlist_config, optionlist_config_size,
3379       NULL, US"main option \"%s\" unknown");
3380   }
3381
3382
3383 /* If local_sender_retain is set, local_from_check must be unset. */
3384
3385 if (local_sender_retain && local_from_check)
3386   log_write(0, LOG_MAIN|LOG_PANIC_DIE, "both local_from_check and "
3387     "local_sender_retain are set; this combination is not allowed");
3388
3389 /* If the timezone string is empty, set it to NULL, implying no TZ variable
3390 wanted. */
3391
3392 if (timezone_string && !*timezone_string) timezone_string = NULL;
3393
3394 /* The max retry interval must not be greater than 24 hours. */
3395
3396 if (retry_interval_max > 24*60*60) retry_interval_max = 24*60*60;
3397
3398 /* remote_max_parallel must be > 0 */
3399
3400 if (remote_max_parallel <= 0) remote_max_parallel = 1;
3401
3402 /* Save the configured setting of freeze_tell, so we can re-instate it at the
3403 start of a new SMTP message. */
3404
3405 freeze_tell_config = freeze_tell;
3406
3407 /* The primary host name may be required for expansion of spool_directory
3408 and log_file_path, so make sure it is set asap. It is obtained from uname(),
3409 but if that yields an unqualified value, make a FQDN by using gethostbyname to
3410 canonize it. Some people like upper case letters in their host names, so we
3411 don't force the case. */
3412
3413 if (!primary_hostname)
3414   {
3415   const uschar * hostname;
3416   struct utsname uts;
3417
3418   if (uname(&uts) < 0)
3419     log_write(0, LOG_MAIN|LOG_PANIC_DIE, "uname() failed to yield host name");
3420   hostname = US uts.nodename;
3421
3422   if (Ustrchr(hostname, '.') == NULL)
3423     {
3424     int af = AF_INET;
3425     struct hostent *hostdata;
3426
3427 #if HAVE_IPV6
3428     if (  !disable_ipv6
3429        && (  !dns_ipv4_lookup
3430           || match_isinlist(hostname, CUSS &dns_ipv4_lookup, 0, NULL, NULL,
3431             MCL_DOMAIN, TRUE, NULL) != OK))
3432       af = AF_INET6;
3433 #endif
3434
3435     for (;;)
3436       {
3437 #if HAVE_IPV6
3438 # if HAVE_GETIPNODEBYNAME
3439         int error_num;
3440         hostdata = getipnodebyname(CS hostname, af, 0, &error_num);
3441         #else
3442         hostdata = gethostbyname2(CS hostname, af);
3443 # endif
3444 #else
3445       hostdata = gethostbyname(CS hostname);
3446 #endif
3447
3448       if (hostdata)
3449         { hostname = US hostdata->h_name; break; }
3450
3451       if (af == AF_INET) break;
3452       af = AF_INET;
3453       }
3454     }
3455
3456   primary_hostname = string_copy(hostname);
3457   }
3458
3459 /* Set up default value for smtp_active_hostname */
3460
3461 smtp_active_hostname = primary_hostname;
3462
3463 /* If spool_directory wasn't set in the build-time configuration, it must have
3464 got set above. Of course, writing to the log may not work if log_file_path is
3465 not set, but it will at least get to syslog or somewhere, with any luck. */
3466
3467 if (!*spool_directory)
3468   log_write(0, LOG_MAIN|LOG_PANIC_DIE, "spool_directory undefined: cannot "
3469     "proceed");
3470
3471 /* Expand the spool directory name; it may, for example, contain the primary
3472 host name. Same comment about failure. */
3473
3474 if (!(s = expand_string(spool_directory)))
3475   log_write(0, LOG_MAIN|LOG_PANIC_DIE, "failed to expand spool_directory "
3476     "\"%s\": %s", spool_directory, expand_string_message);
3477 spool_directory = s;
3478
3479 /* Expand log_file_path, which must contain "%s" in any component that isn't
3480 the null string or "syslog". It is also allowed to contain one instance of %D
3481 or %M. However, it must NOT contain % followed by anything else. */
3482
3483 if (*log_file_path)
3484   {
3485   const uschar *ss, *sss;
3486   int sep = ':';                       /* Fixed for log file path */
3487   if (!(s = expand_string(log_file_path)))
3488     log_write(0, LOG_MAIN|LOG_PANIC_DIE, "failed to expand log_file_path "
3489       "\"%s\": %s", log_file_path, expand_string_message);
3490
3491   ss = s;
3492   /* should never be a tainted list */
3493   while ((sss = string_nextinlist(&ss, &sep, big_buffer, big_buffer_size)))
3494     {
3495     uschar *t;
3496     if (sss[0] == 0 || Ustrcmp(sss, "syslog") == 0) continue;
3497     if (!(t = Ustrstr(sss, "%s")))
3498       log_write(0, LOG_MAIN|LOG_PANIC_DIE, "log_file_path \"%s\" does not "
3499         "contain \"%%s\"", sss);
3500     *t = 'X';
3501     if ((t = Ustrchr(sss, '%')))
3502       if ((t[1] != 'D' && t[1] != 'M') || Ustrchr(t+2, '%') != NULL)
3503         log_write(0, LOG_MAIN|LOG_PANIC_DIE, "log_file_path \"%s\" contains "
3504           "unexpected \"%%\" character", s);
3505     }
3506
3507   log_file_path = s;
3508   }
3509
3510 /* Interpret syslog_facility into an integer argument for 'ident' param to
3511 openlog(). Default is LOG_MAIL set in globals.c. Allow the user to omit the
3512 leading "log_". */
3513
3514 if (syslog_facility_str)
3515   {
3516   int i;
3517   uschar * s = syslog_facility_str;
3518
3519   if ((Ustrlen(syslog_facility_str) >= 4) &&
3520         (strncmpic(syslog_facility_str, US"log_", 4) == 0))
3521     s += 4;
3522
3523   for (i = 0; i < syslog_list_size; i++)
3524     if (strcmpic(s, syslog_list[i].name) == 0)
3525       {
3526       syslog_facility = syslog_list[i].value;
3527       break;
3528       }
3529
3530   if (i >= syslog_list_size)
3531     log_write(0, LOG_PANIC_DIE|LOG_CONFIG,
3532       "failed to interpret syslog_facility \"%s\"", syslog_facility_str);
3533   }
3534
3535 /* Expand pid_file_path */
3536
3537 if (*pid_file_path)
3538   {
3539   const uschar * t = expand_cstring(pid_file_path);
3540   if (!t)
3541     log_write(0, LOG_MAIN|LOG_PANIC_DIE, "failed to expand pid_file_path "
3542       "\"%s\": %s", pid_file_path, expand_string_message);
3543   pid_file_path = t;
3544   }
3545
3546 /* Set default value of process_log_path */
3547
3548 if (!process_log_path || !*process_log_path)
3549   process_log_path = string_sprintf("%s/exim-process.info", spool_directory);
3550
3551 /* Compile the regex for matching a UUCP-style "From_" line in an incoming
3552 message. */
3553
3554 regex_From = regex_must_compile(uucp_from_pattern, MCS_NOFLAGS, TRUE);
3555
3556 /* Unpick the SMTP rate limiting options, if set */
3557
3558 if (smtp_ratelimit_mail)
3559   unpick_ratelimit(smtp_ratelimit_mail, &smtp_rlm_threshold,
3560     &smtp_rlm_base, &smtp_rlm_factor, &smtp_rlm_limit);
3561
3562 if (smtp_ratelimit_rcpt)
3563   unpick_ratelimit(smtp_ratelimit_rcpt, &smtp_rlr_threshold,
3564     &smtp_rlr_base, &smtp_rlr_factor, &smtp_rlr_limit);
3565
3566 /* The qualify domains default to the primary host name */
3567
3568 if (!qualify_domain_sender)
3569   qualify_domain_sender = primary_hostname;
3570 if (!qualify_domain_recipient)
3571   qualify_domain_recipient = qualify_domain_sender;
3572
3573 /* Setting system_filter_user in the configuration sets the gid as well if a
3574 name is given, but a numerical value does not. */
3575
3576 if (system_filter_uid_set && !system_filter_gid_set)
3577   {
3578   struct passwd *pw = getpwuid(system_filter_uid);
3579   if (!pw)
3580     log_write(0, LOG_MAIN|LOG_PANIC_DIE, "Failed to look up uid %ld",
3581       (long int)system_filter_uid);
3582   system_filter_gid = pw->pw_gid;
3583   system_filter_gid_set = TRUE;
3584   }
3585
3586 /* If the errors_reply_to field is set, check that it is syntactically valid
3587 and ensure it contains a domain. */
3588
3589 if (errors_reply_to)
3590   {
3591   uschar *errmess;
3592   int start, end, domain;
3593   uschar *recipient = parse_extract_address(errors_reply_to, &errmess,
3594     &start, &end, &domain, FALSE);
3595
3596   if (!recipient)
3597     log_write(0, LOG_PANIC_DIE|LOG_CONFIG,
3598       "error in errors_reply_to (%s): %s", errors_reply_to, errmess);
3599
3600   if (!domain)
3601     log_write(0, LOG_PANIC_DIE|LOG_CONFIG,
3602       "errors_reply_to (%s) does not contain a domain", errors_reply_to);
3603   }
3604
3605 /* If smtp_accept_queue or smtp_accept_max_per_host is set, then
3606 smtp_accept_max must also be set. */
3607
3608 if (smtp_accept_max == 0 && (smtp_accept_queue > 0 || smtp_accept_max_per_host))
3609   log_write(0, LOG_PANIC_DIE|LOG_CONFIG,
3610     "smtp_accept_max must be set if smtp_accept_queue or "
3611     "smtp_accept_max_per_host is set");
3612
3613 /* Set up the host number if anything is specified. It is an expanded string
3614 so that it can be computed from the host name, for example. We do this last
3615 so as to ensure that everything else is set up before the expansion. */
3616
3617 if (host_number_string)
3618   {
3619   long int n;
3620   uschar *end;
3621   uschar *s = expand_string(host_number_string);
3622
3623   if (!s)
3624     log_write(0, LOG_MAIN|LOG_PANIC_DIE,
3625         "failed to expand localhost_number \"%s\": %s",
3626         host_number_string, expand_string_message);
3627   n = Ustrtol(s, &end, 0);
3628   if (Uskip_whitespace(&end))
3629     log_write(0, LOG_PANIC_DIE|LOG_CONFIG,
3630       "localhost_number value is not a number: %s", s);
3631   if (n > LOCALHOST_MAX)
3632     log_write(0, LOG_PANIC_DIE|LOG_CONFIG,
3633       "localhost_number is greater than the maximum allowed value (%d)",
3634         LOCALHOST_MAX);
3635   host_number = n;
3636   }
3637
3638 #ifndef DISABLE_TLS
3639 /* If tls_verify_hosts is set, tls_verify_certificates must also be set */
3640
3641 if ((tls_verify_hosts || tls_try_verify_hosts) && !tls_verify_certificates)
3642   log_write(0, LOG_PANIC_DIE|LOG_CONFIG,
3643     "tls_%sverify_hosts is set, but tls_verify_certificates is not set",
3644     tls_verify_hosts ? "" : "try_");
3645
3646 /* Magic number: at time of writing, 1024 has been the long-standing value
3647 used by so many clients, and what Exim used to use always, that it makes
3648 sense to just min-clamp this max-clamp at that. */
3649 if (tls_dh_max_bits < 1024)
3650   log_write(0, LOG_PANIC_DIE|LOG_CONFIG,
3651       "tls_dh_max_bits is too small, must be at least 1024 for interop");
3652
3653 /* If openssl_options is set, validate it */
3654 if (openssl_options)
3655   {
3656 # ifdef USE_GNUTLS
3657   log_write(0, LOG_PANIC_DIE|LOG_CONFIG,
3658     "openssl_options is set but we're using GnuTLS");
3659 # else
3660   long dummy;
3661   if (!tls_openssl_options_parse(openssl_options, &dummy))
3662     log_write(0, LOG_PANIC_DIE|LOG_CONFIG,
3663       "openssl_options parse error: %s", openssl_options);
3664 # endif
3665   }
3666 #endif  /*DISABLE_TLS*/
3667
3668 if (!nowarn && !keep_environment && environ && *environ)
3669   log_write(0, LOG_MAIN,
3670       "Warning: purging the environment.\n"
3671       " Suggested action: use keep_environment.");
3672 }
3673
3674
3675
3676 /*************************************************
3677 *          Initialize one driver                 *
3678 *************************************************/
3679
3680 /* This is called once the driver's generic options, if any, have been read.
3681 We can now find the driver, set up defaults for the private options, and
3682 unset any "set" bits in the private options table (which might have been
3683 set by another incarnation of the same driver).
3684
3685 Arguments:
3686   d                   pointer to driver instance block, with generic
3687                         options filled in
3688   drivers_available   vector of available drivers
3689   size_of_info        size of each block in drivers_available
3690   class               class of driver, for error message
3691
3692 Returns:              pointer to the driver info block
3693 */
3694
3695 static driver_info *
3696 init_driver(driver_instance *d, driver_info *drivers_available,
3697   int size_of_info, uschar *class)
3698 {
3699 for (driver_info * dd = drivers_available; dd->driver_name[0] != 0;
3700      dd = (driver_info *)((US dd) + size_of_info))
3701   if (Ustrcmp(d->driver_name, dd->driver_name) == 0)
3702     {
3703     int len = dd->options_len;
3704     d->info = dd;
3705     d->options_block = store_get_perm(len, FALSE);
3706     memcpy(d->options_block, dd->options_block, len);
3707     for (int i = 0; i < *(dd->options_count); i++)
3708       dd->options[i].type &= ~opt_set;
3709     return dd;
3710     }
3711
3712 log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN,
3713   "%s %s: cannot find %s driver \"%s\"", class, d->name, class, d->driver_name);
3714
3715 return NULL;   /* never obeyed */
3716 }
3717
3718
3719
3720
3721 static void
3722 driver_init_fini(driver_instance * d, const uschar * class)
3723 {
3724 if (!d->driver_name)
3725   log_write(0, LOG_PANIC_DIE|LOG_CONFIG,
3726     "no driver defined for %s \"%s\"", class, d->name);
3727 (d->info->init)(d);
3728 }
3729
3730
3731 /*************************************************
3732 *             Initialize driver list             *
3733 *************************************************/
3734
3735 /* This function is called for routers, transports, and authentication
3736 mechanisms. It reads the data from the current point in the configuration file
3737 up to the end of the section, and sets up a chain of instance blocks according
3738 to the file's contents. The file will already have been opened by a call to
3739 readconf_main, and must be left open for subsequent reading of further data.
3740
3741 Any errors cause a panic crash. Note that the blocks with names driver_info and
3742 driver_instance must map the first portions of all the _info and _instance
3743 blocks for this shared code to work.
3744
3745 Arguments:
3746   class                      "router", "transport", or "authenticator"
3747   anchor                     &routers, &transports, &auths
3748   drivers_available          available drivers
3749   size_of_info               size of each info block
3750   instance_default           points to default data for an instance
3751   instance_size              size of instance block
3752   driver_optionlist          generic option list
3753   driver_optionlist_count    count of generic option list
3754
3755 Returns:                     nothing
3756 */
3757
3758 void
3759 readconf_driver_init(
3760   uschar *class,
3761   driver_instance **anchor,
3762   driver_info *drivers_available,
3763   int size_of_info,
3764   void *instance_default,
3765   int  instance_size,
3766   optionlist *driver_optionlist,
3767   int  driver_optionlist_count)
3768 {
3769 driver_instance ** p = anchor;
3770 driver_instance * d = NULL;
3771 uschar * buffer;
3772
3773 while ((buffer = get_config_line()))
3774   {
3775   uschar name[EXIM_DRIVERNAME_MAX];
3776   const uschar * s;
3777
3778   /* Read the first name on the line and test for the start of a new driver. A
3779   macro definition indicates the end of the previous driver. If this isn't the
3780   start of a new driver, the line will be re-read. */
3781
3782   s = readconf_readname(name, sizeof(name), buffer);
3783
3784   /* Handle macro definition, first finishing off the initialization of the
3785   previous driver, if any. */
3786
3787   if (isupper(*name) && *s == '=')
3788     {
3789     if (d)
3790       {
3791       /* s is using big_buffer, so this call had better not */
3792       driver_init_fini(d, class);
3793       d = NULL;
3794       }
3795     if (!macro_read_assignment(buffer)) exim_exit(EXIT_FAILURE);
3796     continue;
3797     }
3798
3799   /* If the line starts with a name terminated by a colon, we are at the
3800   start of the definition of a new driver. The rest of the line must be
3801   blank. */
3802
3803   if (*s++ == ':')
3804     {
3805     /* Finish off initializing the previous driver. */
3806
3807     if (d)
3808       driver_init_fini(d, class);
3809
3810     /* Check that we haven't already got a driver of this name */
3811
3812     for (d = *anchor; d; d = d->next)
3813       if (Ustrcmp(name, d->name) == 0)
3814         log_write(0, LOG_PANIC_DIE|LOG_CONFIG,
3815           "there are two %ss called \"%s\"", class, name);
3816
3817     /* Set up a new driver instance data block on the chain, with
3818     its default values installed. */
3819
3820     d = store_get_perm(instance_size, FALSE);
3821     memcpy(d, instance_default, instance_size);
3822     *p = d;
3823     p = &d->next;
3824     d->name = string_copy(name);
3825     d->srcfile = config_filename;
3826     d->srcline = config_lineno; 
3827
3828     /* Clear out the "set" bits in the generic options */
3829
3830     for (int i = 0; i < driver_optionlist_count; i++)
3831       driver_optionlist[i].type &= ~opt_set;
3832
3833     /* Check nothing more on this line, then do the next loop iteration. */
3834
3835     Uskip_whitespace(&s);
3836     if (*s) extra_chars_error(s, US"driver name ", name, US"");
3837     continue;
3838     }
3839
3840   /* Not the start of a new driver. Give an error if we have not set up a
3841   current driver yet. */
3842
3843   if (!d)
3844     log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, "%s name missing", class);
3845
3846   /* First look to see if this is a generic option; if it is "driver",
3847   initialize the driver. If is it not a generic option, we can look for a
3848   private option provided that the driver has been previously set up. */
3849
3850   if (readconf_handle_option(buffer, driver_optionlist,
3851         driver_optionlist_count, d, NULL))
3852     {
3853     if (!d->info && d->driver_name)
3854       init_driver(d, drivers_available, size_of_info, class);
3855     }
3856
3857   /* Handle private options - pass the generic block because some may
3858   live therein. A flag with each option indicates if it is in the public
3859   block. */
3860
3861   else if (d->info)
3862     readconf_handle_option(buffer, d->info->options,
3863       *(d->info->options_count), d, US"option \"%s\" unknown");
3864
3865   /* The option is not generic and the driver name has not yet been given. */
3866
3867   else log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, "option \"%s\" unknown "
3868     "(\"driver\" must be specified before any private options)", name);
3869   }
3870
3871 /* Run the initialization function for the final driver. */
3872
3873 if (d)
3874   driver_init_fini(d, class);
3875 }
3876
3877
3878
3879 /*************************************************
3880 *            Check driver dependency             *
3881 *************************************************/
3882
3883 /* This function is passed a driver instance and a string. It checks whether
3884 any of the string options for the driver contains the given string as an
3885 expansion variable.
3886
3887 Arguments:
3888   d        points to a driver instance block
3889   s        the string to search for
3890
3891 Returns:   TRUE if a dependency is found
3892 */
3893
3894 BOOL
3895 readconf_depends(driver_instance *d, uschar *s)
3896 {
3897 int count = *(d->info->options_count);
3898 uschar *ss;
3899
3900 for (optionlist * ol = d->info->options; ol < d->info->options + count; ol++)
3901   if ((ol->type & opt_mask) == opt_stringptr)
3902     {
3903     void * options_block = ol->type & opt_public ? (void *)d : d->options_block;
3904     uschar * value = *USS(US options_block + ol->v.offset);
3905
3906     if (value && (ss = Ustrstr(value, s)) != NULL)
3907       {
3908       if (ss <= value || (ss[-1] != '$' && ss[-1] != '{') ||
3909         isalnum(ss[Ustrlen(s)])) continue;
3910       DEBUG(D_transport) debug_printf("driver %s: \"%s\" option depends on %s\n",
3911         d->name, ol->name, s);
3912       return TRUE;
3913       }
3914     }
3915
3916 DEBUG(D_transport) debug_printf("driver %s does not depend on %s\n", d->name, s);
3917 return FALSE;
3918 }
3919
3920
3921
3922
3923 /*************************************************
3924 *      Decode an error type for retries          *
3925 *************************************************/
3926
3927 /* This function is global because it is also called from the main
3928 program when testing retry information. It decodes strings such as "quota_7d"
3929 into numerical error codes.
3930
3931 Arguments:
3932   pp           points to start of text
3933   p            points past end of text
3934   basic_errno  points to an int to receive the main error number
3935   more_errno   points to an int to receive the secondary error data
3936
3937 Returns:       NULL if decoded correctly; else points to error text
3938 */
3939
3940 uschar *
3941 readconf_retry_error(const uschar *pp, const uschar *p,
3942   int *basic_errno, int *more_errno)
3943 {
3944 int len;
3945 const uschar *q = pp;
3946 while (q < p && *q != '_') q++;
3947 len = q - pp;
3948
3949 if (len == 5 && strncmpic(pp, US"quota", len) == 0)
3950   {
3951   *basic_errno = ERRNO_EXIMQUOTA;
3952   if (q != p && (*more_errno = readconf_readtime(q+1, *p, FALSE)) < 0)
3953       return US"bad time value";
3954   }
3955
3956 else if (len == 7 && strncmpic(pp, US"refused", len) == 0)
3957   {
3958   *basic_errno = ECONNREFUSED;
3959   if (q != p)
3960     {
3961     if (strncmpic(q+1, US"MX", p-q-1) == 0) *more_errno = 'M';
3962     else if (strncmpic(q+1, US"A", p-q-1) == 0) *more_errno = 'A';
3963     else return US"A or MX expected after \"refused\"";
3964     }
3965   }
3966
3967 else if (len == 7 && strncmpic(pp, US"timeout", len) == 0)
3968   {
3969   *basic_errno = ETIMEDOUT;
3970   if (q != p)
3971     {
3972     int i;
3973     int xlen = p - q - 1;
3974     const uschar *x = q + 1;
3975
3976     static uschar *extras[] =
3977       { US"A", US"MX", US"connect", US"connect_A",  US"connect_MX" };
3978     static int values[] =
3979       { 'A',   'M',    RTEF_CTOUT,  RTEF_CTOUT|'A', RTEF_CTOUT|'M' };
3980
3981     for (i = 0; i < nelem(extras); i++)
3982       if (strncmpic(x, extras[i], xlen) == 0)
3983         {
3984         *more_errno = values[i];
3985         break;
3986         }
3987
3988     if (i >= nelem(extras))
3989       if (strncmpic(x, US"DNS", xlen) == 0)
3990         log_write(0, LOG_MAIN|LOG_PANIC, "\"timeout_dns\" is no longer "
3991           "available in retry rules (it has never worked) - treated as "
3992           "\"timeout\"");
3993       else
3994         return US"\"A\", \"MX\", or \"connect\" expected after \"timeout\"";
3995     }
3996   }
3997
3998 else if (strncmpic(pp, US"mail_4", 6) == 0 ||
3999          strncmpic(pp, US"rcpt_4", 6) == 0 ||
4000          strncmpic(pp, US"data_4", 6) == 0)
4001   {
4002   BOOL bad = FALSE;
4003   int x = 255;                           /* means "any 4xx code" */
4004   if (p != pp + 8) bad = TRUE; else
4005     {
4006     int a = pp[6], b = pp[7];
4007     if (isdigit(a))
4008       {
4009       x = (a - '0') * 10;
4010       if (isdigit(b)) x += b - '0';
4011       else if (b == 'x') x += 100;
4012       else bad = TRUE;
4013       }
4014     else if (a != 'x' || b != 'x') bad = TRUE;
4015     }
4016
4017   if (bad)
4018     return string_sprintf("%.4s_4 must be followed by xx, dx, or dd, where "
4019       "x is literal and d is any digit", pp);
4020
4021   *basic_errno = *pp == 'm' ? ERRNO_MAIL4XX :
4022                  *pp == 'r' ? ERRNO_RCPT4XX : ERRNO_DATA4XX;
4023   *more_errno = x << 8;
4024   }
4025
4026 else if (len == 4 && strncmpic(pp, US"auth", len) == 0 &&
4027          strncmpic(q+1, US"failed", p-q-1) == 0)
4028   *basic_errno = ERRNO_AUTHFAIL;
4029
4030 else if (strncmpic(pp, US"lost_connection", p - pp) == 0)
4031   *basic_errno = ERRNO_SMTPCLOSED;
4032
4033 else if (strncmpic(pp, US"tls_required", p - pp) == 0)
4034   *basic_errno = ERRNO_TLSREQUIRED;
4035
4036 else if (strncmpic(pp, US"lookup", p - pp) == 0)
4037   *basic_errno = ERRNO_UNKNOWNHOST;
4038
4039 else if (len != 1 || Ustrncmp(pp, "*", 1) != 0)
4040   return string_sprintf("unknown or malformed retry error \"%.*s\"", (int) (p-pp), pp);
4041
4042 return NULL;
4043 }
4044
4045
4046
4047
4048 /*************************************************
4049 *                Read retry information          *
4050 *************************************************/
4051
4052 /* Each line of retry information contains:
4053
4054 .  A domain name pattern or an address pattern;
4055
4056 .  An error name, possibly with additional data, or *;
4057
4058 .  An optional sequence of retry items, each consisting of an identifying
4059    letter, a cutoff time, and optional parameters.
4060
4061 All this is decoded and placed into a control block. */
4062
4063
4064 /* Subroutine to read an argument, preceded by a comma and terminated
4065 by comma, semicolon, whitespace, or newline. The types are: 0 = time value,
4066 1 = fixed point number (returned *1000).
4067
4068 Arguments:
4069   paddr     pointer to pointer to current character; updated
4070   type      0 => read a time; 1 => read a fixed point number
4071
4072 Returns:    time in seconds or fixed point number * 1000
4073 */
4074
4075 static int
4076 retry_arg(const uschar ** paddr, int type)
4077 {
4078 const uschar * p = *paddr, * pp;
4079
4080 if (*p++ != ',') log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, "comma expected");
4081
4082 Uskip_whitespace(&p);
4083 pp = p;
4084 while (isalnum(*p) || (type == 1 && *p == '.')) p++;
4085
4086 if (*p && !isspace(*p) && *p != ',' && *p != ';')
4087   log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, "comma or semicolon expected");
4088
4089 *paddr = p;
4090 switch (type)
4091   {
4092   case 0: return readconf_readtime(pp, *p, FALSE);
4093   case 1: return readconf_readfixed(pp, *p);
4094   }
4095 return 0;    /* Keep picky compilers happy */
4096 }
4097
4098 /* The function proper */
4099
4100 void
4101 readconf_retries(void)
4102 {
4103 retry_config **chain = &retries;
4104 retry_config *next;
4105 const uschar *p;
4106
4107 while ((p = get_config_line()))
4108   {
4109   retry_rule **rchain;
4110   const uschar *pp;
4111   uschar *error;
4112
4113   next = store_get(sizeof(retry_config), GET_UNTAINTED);
4114   next->next = NULL;
4115   *chain = next;
4116   chain = &(next->next);
4117   next->basic_errno = next->more_errno = 0;
4118   next->senders = NULL;
4119   next->rules = NULL;
4120   rchain = &(next->rules);
4121
4122   next->pattern = string_dequote(&p);
4123   Uskip_whitespace(&p);
4124   pp = p;
4125   while (mac_isgraph(*p)) p++;
4126   if (p - pp <= 0) log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN,
4127     "missing error type in retry rule");
4128
4129   /* Test error names for things we understand. */
4130
4131   if ((error = readconf_retry_error(pp, p, &next->basic_errno,
4132        &next->more_errno)))
4133     log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, "%s", error);
4134
4135   /* There may be an optional address list of senders to be used as another
4136   constraint on the rule. This was added later, so the syntax is a bit of a
4137   fudge. Anything that is not a retry rule starting "F," or "G," is treated as
4138   an address list. */
4139
4140   Uskip_whitespace(&p);
4141   if (Ustrncmp(p, "senders", 7) == 0)
4142     {
4143     p += 7;
4144     Uskip_whitespace(&p);
4145     if (*p++ != '=') log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN,
4146       "\"=\" expected after \"senders\" in retry rule");
4147     Uskip_whitespace(&p);
4148     next->senders = string_dequote(&p);
4149     }
4150
4151   /* Now the retry rules. Keep the maximum timeout encountered. */
4152
4153   Uskip_whitespace(&p);
4154
4155   while (*p)
4156     {
4157     retry_rule * rule = store_get(sizeof(retry_rule), GET_UNTAINTED);
4158     *rchain = rule;
4159     rchain = &(rule->next);
4160     rule->next = NULL;
4161     rule->rule = toupper(*p++);
4162     rule->timeout = retry_arg(&p, 0);
4163     if (rule->timeout > retry_maximum_timeout)
4164       retry_maximum_timeout = rule->timeout;
4165
4166     switch (rule->rule)
4167       {
4168       case 'F':   /* Fixed interval */
4169         rule->p1 = retry_arg(&p, 0);
4170         break;
4171
4172       case 'G':   /* Geometrically increasing intervals */
4173       case 'H':   /* Ditto, but with randomness */
4174         rule->p1 = retry_arg(&p, 0);
4175         rule->p2 = retry_arg(&p, 1);
4176         break;
4177
4178       default:
4179         log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, "unknown retry rule letter");
4180         break;
4181       }
4182
4183     if (rule->timeout <= 0 || rule->p1 <= 0 ||
4184           (rule->rule != 'F' && rule->p2 < 1000))
4185       log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN,
4186         "bad parameters for retry rule");
4187
4188     if (Uskip_whitespace(&p) == ';')
4189       {
4190       p++;
4191       Uskip_whitespace(&p);
4192       }
4193     else if (*p)
4194       log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, "semicolon expected");
4195     }
4196   }
4197 }
4198
4199
4200
4201 /*************************************************
4202 *         Initialize authenticators              *
4203 *************************************************/
4204
4205 /* Read the authenticators section of the configuration file.
4206
4207 Arguments:   none
4208 Returns:     nothing
4209 */
4210
4211 static void
4212 auths_init(void)
4213 {
4214 #ifndef DISABLE_PIPE_CONNECT
4215 int nauths = 0;
4216 #endif
4217
4218 readconf_driver_init(US"authenticator",
4219   (driver_instance **)(&auths),      /* chain anchor */
4220   (driver_info *)auths_available,    /* available drivers */
4221   sizeof(auth_info),                 /* size of info block */
4222   &auth_defaults,                    /* default values for generic options */
4223   sizeof(auth_instance),             /* size of instance block */
4224   optionlist_auths,                  /* generic options */
4225   optionlist_auths_size);
4226
4227 for (auth_instance * au = auths; au; au = au->next)
4228   {
4229   if (!au->public_name)
4230     log_write(0, LOG_PANIC_DIE|LOG_CONFIG, "no public name specified for "
4231       "the %s authenticator", au->name);
4232
4233   for (auth_instance * bu = au->next; bu; bu = bu->next)
4234     if (strcmpic(au->public_name, bu->public_name) == 0)
4235       if (  au->client && bu->client
4236          || au->server && bu->server)
4237         log_write(0, LOG_PANIC_DIE|LOG_CONFIG, "two %s authenticators "
4238           "(%s and %s) have the same public name (%s)",
4239           au->client && bu->client ? US"client" : US"server",
4240           au->name, bu->name, au->public_name);
4241 #ifndef DISABLE_PIPE_CONNECT
4242   nauths++;
4243 #endif
4244   }
4245 #ifndef DISABLE_PIPE_CONNECT
4246 f.smtp_in_early_pipe_no_auth = nauths > 16;
4247 #endif
4248 }
4249
4250
4251 /* For error messages, a string describing the config location associated
4252 with current processing.  NULL if we are not in an authenticator. */
4253
4254 uschar *
4255 authenticator_current_name(void)
4256 {
4257 if (!authenticator_name) return NULL;
4258 return string_sprintf(" (authenticator %s, %s %d)", authenticator_name, driver_srcfile, driver_srcline);
4259 }
4260
4261
4262
4263
4264
4265 /*************************************************
4266 *             Read ACL information               *
4267 *************************************************/
4268
4269 /* If this run of Exim is not doing something that involves receiving a
4270 message, we can just skip over the ACL information. No need to parse it.
4271
4272 First, we have a function for acl_read() to call back to get the next line. We
4273 need to remember the line we passed, because at the end it will contain the
4274 name of the next ACL. */
4275
4276 static uschar *acl_line;
4277
4278 static uschar *
4279 acl_callback(void)
4280 {
4281 acl_line = get_config_line();
4282 return acl_line;
4283 }
4284
4285
4286 /* Now the main function:
4287
4288 Arguments:    none
4289 Returns:      nothing
4290 */
4291
4292 static void
4293 readconf_acl(void)
4294 {
4295 /* Read each ACL and add it into the tree. Macro (re)definitions are allowed
4296 between ACLs. */
4297
4298 acl_line = get_config_line();
4299
4300 while(acl_line)
4301   {
4302   uschar name[EXIM_DRIVERNAME_MAX];
4303   tree_node * node;
4304   uschar * error;
4305   const uschar * p = readconf_readname(name, sizeof(name), acl_line);
4306
4307   if (isupper(*name) && *p == '=')
4308     {
4309     if (!macro_read_assignment(acl_line)) exim_exit(EXIT_FAILURE);
4310     acl_line = get_config_line();
4311     continue;
4312     }
4313
4314   if (*p != ':' || name[0] == 0)
4315     log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, "missing or malformed ACL name");
4316
4317   node = store_get_perm(sizeof(tree_node) + Ustrlen(name), name);
4318   Ustrcpy(node->name, name);
4319   if (!tree_insertnode(&acl_anchor, node))
4320     log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN,
4321       "there are two ACLs called \"%s\"", name);
4322
4323   node->data.ptr = acl_read(acl_callback, &error);
4324
4325   if (node->data.ptr == NULL && error != NULL)
4326     log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, "error in ACL: %s", error);
4327   }
4328 }
4329
4330
4331
4332 /*************************************************
4333 *     Read configuration for local_scan()        *
4334 *************************************************/
4335
4336 /* This function is called after "begin local_scan" is encountered in the
4337 configuration file. If the local_scan() function allows for configuration
4338 options, we can process them. Otherwise, we expire in a panic.
4339
4340 Arguments:  none
4341 Returns:    nothing
4342 */
4343
4344 static void
4345 local_scan_init(void)
4346 {
4347 #ifndef LOCAL_SCAN_HAS_OPTIONS
4348 log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, "local_scan() options not supported: "
4349   "(LOCAL_SCAN_HAS_OPTIONS not defined in Local/Makefile)");
4350 #else
4351
4352 uschar *p;
4353 while ((p = get_config_line()))
4354   (void) readconf_handle_option(p, local_scan_options, local_scan_options_count,
4355     NULL, US"local_scan option \"%s\" unknown");
4356 #endif
4357 }
4358
4359
4360
4361 /*************************************************
4362 *     Read rest of configuration (after main)    *
4363 *************************************************/
4364
4365 /* This function reads the rest of the runtime configuration, after the main
4366 configuration. It is called only when actually needed. Each subsequent section
4367 of the configuration starts with a line of the form
4368
4369   begin name
4370
4371 where the name is "routers", "transports", etc. A section is terminated by
4372 hitting the next "begin" line, and the next name is left in next_section.
4373 Because it may confuse people as to whether the names are singular or plural,
4374 we add "s" if it's missing. There is always enough room in next_section for
4375 this. This function is basically just a switch.
4376
4377 Arguments:   none
4378 Returns:     nothing
4379 */
4380
4381 static uschar *section_list[] = {
4382   US"acls",
4383   US"authenticators",
4384   US"local_scans",
4385   US"retrys",
4386   US"rewrites",
4387   US"routers",
4388   US"transports"};
4389
4390 void
4391 readconf_rest(void)
4392 {
4393 int had = 0;
4394
4395 while(next_section[0] != 0)
4396   {
4397   int bit;
4398   int first = 0;
4399   int last = nelem(section_list);
4400   int mid = last/2;
4401   int n = Ustrlen(next_section);
4402
4403   if (tolower(next_section[n-1]) != 's') Ustrcpy(next_section+n, US"s");
4404
4405   for (;;)
4406     {
4407     int c = strcmpic(next_section, section_list[mid]);
4408     if (c == 0) break;
4409     if (c > 0) first = mid + 1; else last = mid;
4410     if (first >= last)
4411       log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN,
4412         "\"%.*s\" is not a known configuration section name", n, next_section);
4413     mid = (last + first)/2;
4414     }
4415
4416   bit = 1 << mid;
4417   if (((had ^= bit) & bit) == 0)
4418     log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN,
4419       "\"%.*s\" section is repeated in the configuration file", n,
4420         next_section);
4421
4422   switch(mid)
4423     {
4424     case 0: readconf_acl(); break;
4425     case 1: auths_init(); break;
4426     case 2: local_scan_init(); break;
4427     case 3: readconf_retries(); break;
4428     case 4: readconf_rewrites(); break;
4429     case 5: route_init(); break;
4430     case 6: transport_init(); break;
4431     }
4432   }
4433
4434 (void)fclose(config_file);
4435 }
4436
4437 /* Init the storage for the pre-parsed config lines */
4438 void
4439 readconf_save_config(const uschar *s)
4440 {
4441 save_config_line(string_sprintf("# Exim Configuration (%s)",
4442   f.running_in_test_harness ? US"X" : s));
4443 }
4444
4445 static void
4446 save_config_position(const uschar *file, int line)
4447 {
4448 save_config_line(string_sprintf("# %d \"%s\"", line, file));
4449 }
4450
4451 /* Append a pre-parsed logical line to the config lines store,
4452 this operates on a global (static) list that holds all the pre-parsed
4453 config lines, we do no further processing here, output formatting and
4454 honouring of <hide> or macros will be done during output */
4455
4456 static void
4457 save_config_line(const uschar* line)
4458 {
4459 static config_line_item *current;
4460 config_line_item *next;
4461
4462 next = (config_line_item*) store_get(sizeof(config_line_item), GET_UNTAINTED);
4463 next->line = string_copy(line);
4464 next->next = NULL;
4465
4466 if (!config_lines) config_lines = next;
4467 else current->next = next;
4468
4469 current = next;
4470 }
4471
4472 /* List the parsed config lines, care about nice formatting and
4473 hide the <hide> values unless we're the admin user */
4474 void
4475 print_config(BOOL admin, BOOL terse)
4476 {
4477 const int TS = terse ? 0 : 2;
4478 int indent = 0;
4479 rmark r = NULL;
4480
4481 for (const config_line_item * i = config_lines; i; i = i->next)
4482   {
4483   uschar * current, * p;
4484
4485   if (r) store_reset(r);
4486   r = store_mark();
4487
4488   /* skip over to the first non-space */
4489   current = string_copy(i->line);
4490   if (!Uskip_whitespace(&current))
4491     continue;
4492
4493   /* Collapse runs of spaces. We stop this if we encounter one of the
4494   following characters: "'$, as this may indicate careful formatting */
4495
4496   for (p = current; *p; p++) if (isspace(*p))
4497     {
4498     uschar * next = p;
4499     if (*p != ' ') *p = ' ';
4500
4501     Uskip_whitespace(&p);
4502
4503     if (next - p > 1)
4504       memmove(p+1, next, Ustrlen(next)+1);
4505
4506     if (*next == '"' || *next == '\'' || *next == '$')
4507       break;
4508     }
4509
4510   /* # lines */
4511   if (current[0] == '#')
4512     puts(CCS current);
4513
4514   /* begin lines are left aligned */
4515   else if (Ustrncmp(current, "begin", 5) == 0 && isspace(current[5]))
4516     {
4517     if (!terse) puts("");
4518     puts(CCS current);
4519     indent = TS;
4520     }
4521
4522   /* router/acl/transport block names */
4523   else if (current[Ustrlen(current)-1] == ':' && !Ustrchr(current, '='))
4524     {
4525     if (!terse) puts("");
4526     printf("%*s%s\n", TS, "", current);
4527     indent = 2 * TS;
4528     }
4529
4530   /* hidden lines (all MACROS or lines prefixed with "hide") */
4531   else if (  !admin
4532           && (  isupper(*current)
4533              || Ustrncmp(current, "hide", 4) == 0 && isspace(current[4])
4534              )
4535           )
4536     {
4537     if ((p = Ustrchr(current, '=')))
4538       {
4539       *p = '\0';
4540       printf("%*s%s= %s\n", indent, "", current, CCS hidden);
4541       }
4542     /* e.g.: hide split_spool_directory */
4543     else
4544       printf("%*s\n", indent, CCS hidden);
4545     }
4546
4547   else
4548     /* rest is public */
4549     printf("%*s%s\n", indent, "", current);
4550   }
4551 if (r) store_reset(r);
4552 }
4553
4554 #endif  /*!MACRO_PREDEF*/
4555 /* vi: aw ai sw=2
4556 */
4557 /* End of readconf.c */