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