ACL: bsearch for controls
[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 *saved_condition, *strtemp;
1466 uschar **str_target;
1467 uschar name[64];
1468 uschar name2[64];
1469
1470 /* There may be leading spaces; thereafter, we expect an option name starting
1471 with a letter. */
1472
1473 while (isspace(*s)) s++;
1474 if (!isalpha(*s))
1475   log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, "option setting expected: %s", s);
1476
1477 /* Read the name of the option, and skip any subsequent white space. If
1478 it turns out that what we read was "hide", set the flag indicating that
1479 this is a secure option, and loop to read the next word. */
1480
1481 for (n = 0; n < 2; n++)
1482   {
1483   while (isalnum(*s) || *s == '_')
1484     {
1485     if (ptr < sizeof(name)-1) name[ptr++] = *s;
1486     s++;
1487     }
1488   name[ptr] = 0;
1489   while (isspace(*s)) s++;
1490   if (Ustrcmp(name, "hide") != 0) break;
1491   issecure = opt_secure;
1492   ptr = 0;
1493   }
1494
1495 /* Deal with "no_" or "not_" here for booleans */
1496
1497 if (Ustrncmp(name, "no_", 3) == 0)
1498   {
1499   boolvalue = FALSE;
1500   offset = 3;
1501   }
1502
1503 if (Ustrncmp(name, "not_", 4) == 0)
1504   {
1505   boolvalue = FALSE;
1506   offset = 4;
1507   }
1508
1509 /* Search the list for the given name. A non-existent name, or an option that
1510 is set twice, is a disaster. */
1511
1512 if (!(ol = find_option(name + offset, oltop, last)))
1513   {
1514   if (unknown_txt == NULL) return FALSE;
1515   log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, CS unknown_txt, name);
1516   }
1517
1518 if ((ol->type & opt_set)  && !(ol->type & (opt_rep_con | opt_rep_str)))
1519   log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN,
1520     "\"%s\" option set for the second time", name);
1521
1522 ol->type |= opt_set | issecure;
1523 type = ol->type & opt_mask;
1524
1525 /* Types with data values must be followed by '='; the "no[t]_" prefix
1526 applies only to boolean values. */
1527
1528 if (type < opt_bool || type > opt_bool_last)
1529   {
1530   if (offset != 0)
1531     log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN,
1532       "negation prefix applied to a non-boolean option");
1533   if (*s == 0)
1534     log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN,
1535       "unexpected end of line (data missing) after %s", name);
1536   if (*s != '=')
1537     log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, "missing \"=\" after %s", name);
1538   }
1539
1540 /* If a boolean wasn't preceded by "no[t]_" it can be followed by = and
1541 true/false/yes/no, or, in the case of opt_expand_bool, a general string that
1542 ultimately expands to one of those values. */
1543
1544 else if (*s != 0 && (offset != 0 || *s != '='))
1545   extra_chars_error(s, US"boolean option ", name, US"");
1546
1547 /* Skip white space after = */
1548
1549 if (*s == '=') while (isspace((*(++s))));
1550
1551 /* If there is a data block and the opt_public flag is not set, change
1552 the data block pointer to the private options block. */
1553
1554 if (data_block != NULL && (ol->type & opt_public) == 0)
1555   data_block = (void *)(((driver_instance *)data_block)->options_block);
1556
1557 /* Now get the data according to the type. */
1558
1559 switch (type)
1560   {
1561   /* If a string value is not enclosed in quotes, it consists of
1562   the rest of the current line, verbatim. Otherwise, string escapes
1563   are processed.
1564
1565   A transport is specified as a string, which is then looked up in the
1566   list of transports. A search type is specified as one of a number of
1567   known strings.
1568
1569   A set or rewrite rules for a driver is specified as a string, which is
1570   then parsed into a suitable chain of control blocks.
1571
1572   Uids and gids are specified as strings which are then looked up in the
1573   passwd file. Lists of uids and gids are similarly specified as colon-
1574   separated strings. */
1575
1576   case opt_stringptr:
1577   case opt_uid:
1578   case opt_gid:
1579   case opt_expand_uid:
1580   case opt_expand_gid:
1581   case opt_uidlist:
1582   case opt_gidlist:
1583   case opt_rewrite:
1584
1585   reset_point = sptr = read_string(s, name);
1586
1587   /* Having read a string, we now have several different ways of using it,
1588   depending on the data type, so do another switch. If keeping the actual
1589   string is not required (because it is interpreted), freesptr is set TRUE,
1590   and at the end we reset the pool. */
1591
1592   switch (type)
1593     {
1594     /* If this was a string, set the variable to point to the new string,
1595     and set the flag so its store isn't reclaimed. If it was a list of rewrite
1596     rules, we still keep the string (for printing), and parse the rules into a
1597     control block and flags word. */
1598
1599     case opt_stringptr:
1600     if (data_block == NULL)
1601       str_target = (uschar **)(ol->value);
1602     else
1603       str_target = (uschar **)((uschar *)data_block + (long int)(ol->value));
1604     if (ol->type & opt_rep_con)
1605       {
1606       /* We already have a condition, we're conducting a crude hack to let
1607       multiple condition rules be chained together, despite storing them in
1608       text form. */
1609       saved_condition = *str_target;
1610       strtemp = string_sprintf("${if and{{bool_lax{%s}}{bool_lax{%s}}}}",
1611           saved_condition, sptr);
1612       *str_target = string_copy_malloc(strtemp);
1613       /* TODO(pdp): there is a memory leak here and just below
1614       when we set 3 or more conditions; I still don't
1615       understand the store mechanism enough to know
1616       what's the safe way to free content from an earlier store.
1617       AFAICT, stores stack, so freeing an early stored item also stores
1618       all data alloc'd after it.  If we knew conditions were adjacent,
1619       we could survive that, but we don't.  So I *think* we need to take
1620       another bit from opt_type to indicate "malloced"; this seems like
1621       quite a hack, especially for this one case.  It also means that
1622       we can't ever reclaim the store from the *first* condition.
1623
1624       Because we only do this once, near process start-up, I'm prepared to
1625       let this slide for the time being, even though it rankles.  */
1626       }
1627     else if (ol->type & opt_rep_str)
1628       {
1629       uschar sep_o = Ustrncmp(name, "headers_add", 11)==0 ? '\n' : ':';
1630       int    sep_i = -(int)sep_o;
1631       const uschar * list = sptr;
1632       uschar * s;
1633       uschar * list_o = *str_target;
1634
1635       while ((s = string_nextinlist(&list, &sep_i, NULL, 0)))
1636         list_o = string_append_listele(list_o, sep_o, s);
1637       if (list_o)
1638         *str_target = string_copy_malloc(list_o);
1639       }
1640     else
1641       {
1642       *str_target = sptr;
1643       freesptr = FALSE;
1644       }
1645     break;
1646
1647     case opt_rewrite:
1648     if (data_block == NULL)
1649       *((uschar **)(ol->value)) = sptr;
1650     else
1651       *((uschar **)((uschar *)data_block + (long int)(ol->value))) = sptr;
1652     freesptr = FALSE;
1653     if (type == opt_rewrite)
1654       {
1655       int sep = 0;
1656       int *flagptr;
1657       uschar *p = sptr;
1658       rewrite_rule **chain;
1659       optionlist *ol3;
1660
1661       sprintf(CS name2, "*%.50s_rules", name);
1662       ol2 = find_option(name2, oltop, last);
1663       sprintf(CS name2, "*%.50s_flags", name);
1664       ol3 = find_option(name2, oltop, last);
1665
1666       if (ol2 == NULL || ol3 == NULL)
1667         log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN,
1668           "rewrite rules not available for driver");
1669
1670       if (data_block == NULL)
1671         {
1672         chain = (rewrite_rule **)(ol2->value);
1673         flagptr = (int *)(ol3->value);
1674         }
1675       else
1676         {
1677         chain = (rewrite_rule **)((uschar *)data_block + (long int)(ol2->value));
1678         flagptr = (int *)((uschar *)data_block + (long int)(ol3->value));
1679         }
1680
1681       while ((p = string_nextinlist(CUSS &sptr, &sep, big_buffer, BIG_BUFFER_SIZE)))
1682         {
1683         rewrite_rule *next = readconf_one_rewrite(p, flagptr, FALSE);
1684         *chain = next;
1685         chain = &(next->next);
1686         }
1687
1688       if ((*flagptr & (rewrite_all_envelope | rewrite_smtp)) != 0)
1689         log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, "rewrite rule specifies a "
1690           "non-header rewrite - not allowed at transport time -");
1691       }
1692     break;
1693
1694     /* If it was an expanded uid, see if there is any expansion to be
1695     done by checking for the presence of a $ character. If there is, save it
1696     in the corresponding *expand_user option field. Otherwise, fall through
1697     to treat it as a fixed uid. Ensure mutual exclusivity of the two kinds
1698     of data. */
1699
1700     case opt_expand_uid:
1701     sprintf(CS name2, "*expand_%.50s", name);
1702     ol2 = find_option(name2, oltop, last);
1703     if (ol2 != NULL)
1704       {
1705       uschar *ss = (Ustrchr(sptr, '$') != NULL)? sptr : NULL;
1706
1707       if (data_block == NULL)
1708         *((uschar **)(ol2->value)) = ss;
1709       else
1710         *((uschar **)((uschar *)data_block + (long int)(ol2->value))) = ss;
1711
1712       if (ss != NULL)
1713         {
1714         *(get_set_flag(name, oltop, last, data_block)) = FALSE;
1715         freesptr = FALSE;
1716         break;
1717         }
1718       }
1719
1720     /* Look up a fixed uid, and also make use of the corresponding gid
1721     if a passwd entry is returned and the gid has not been set. */
1722
1723     case opt_uid:
1724     if (!route_finduser(sptr, &pw, &uid))
1725       log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, "user %s was not found", sptr);
1726     if (data_block == NULL)
1727       *((uid_t *)(ol->value)) = uid;
1728     else
1729       *((uid_t *)((uschar *)data_block + (long int)(ol->value))) = uid;
1730
1731     /* Set the flag indicating a fixed value is set */
1732
1733     *(get_set_flag(name, oltop, last, data_block)) = TRUE;
1734
1735     /* Handle matching gid if we have a passwd entry: done by finding the
1736     same name with terminating "user" changed to "group"; if not found,
1737     ignore. Also ignore if the value is already set. */
1738
1739     if (pw == NULL) break;
1740     Ustrcpy(name+Ustrlen(name)-4, "group");
1741     ol2 = find_option(name, oltop, last);
1742     if (ol2 != NULL && ((ol2->type & opt_mask) == opt_gid ||
1743         (ol2->type & opt_mask) == opt_expand_gid))
1744       {
1745       BOOL *set_flag = get_set_flag(name, oltop, last, data_block);
1746       if (! *set_flag)
1747         {
1748         if (data_block == NULL)
1749           *((gid_t *)(ol2->value)) = pw->pw_gid;
1750         else
1751           *((gid_t *)((uschar *)data_block + (long int)(ol2->value))) = pw->pw_gid;
1752         *set_flag = TRUE;
1753         }
1754       }
1755     break;
1756
1757     /* If it was an expanded gid, see if there is any expansion to be
1758     done by checking for the presence of a $ character. If there is, save it
1759     in the corresponding *expand_user option field. Otherwise, fall through
1760     to treat it as a fixed gid. Ensure mutual exclusivity of the two kinds
1761     of data. */
1762
1763     case opt_expand_gid:
1764     sprintf(CS name2, "*expand_%.50s", name);
1765     ol2 = find_option(name2, oltop, last);
1766     if (ol2 != NULL)
1767       {
1768       uschar *ss = (Ustrchr(sptr, '$') != NULL)? sptr : NULL;
1769
1770       if (data_block == NULL)
1771         *((uschar **)(ol2->value)) = ss;
1772       else
1773         *((uschar **)((uschar *)data_block + (long int)(ol2->value))) = ss;
1774
1775       if (ss != NULL)
1776         {
1777         *(get_set_flag(name, oltop, last, data_block)) = FALSE;
1778         freesptr = FALSE;
1779         break;
1780         }
1781       }
1782
1783     /* Handle freestanding gid */
1784
1785     case opt_gid:
1786     if (!route_findgroup(sptr, &gid))
1787       log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, "group %s was not found", sptr);
1788     if (data_block == NULL)
1789       *((gid_t *)(ol->value)) = gid;
1790     else
1791       *((gid_t *)((uschar *)data_block + (long int)(ol->value))) = gid;
1792     *(get_set_flag(name, oltop, last, data_block)) = TRUE;
1793     break;
1794
1795     /* If it was a uid list, look up each individual entry, and build
1796     a vector of uids, with a count in the first element. Put the vector
1797     in malloc store so we can free the string. (We are reading into
1798     permanent store already.) */
1799
1800     case opt_uidlist:
1801       {
1802       int count = 1;
1803       uid_t *list;
1804       int ptr = 0;
1805       const uschar *p;
1806       const uschar *op = expand_string (sptr);
1807
1808       if (op == NULL)
1809         log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, "failed to expand %s: %s",
1810           name, expand_string_message);
1811
1812       p = op;
1813       if (*p != 0) count++;
1814       while (*p != 0) if (*p++ == ':' && *p != 0) count++;
1815       list = store_malloc(count*sizeof(uid_t));
1816       list[ptr++] = (uid_t)(count - 1);
1817
1818       if (data_block == NULL)
1819         *((uid_t **)(ol->value)) = list;
1820       else
1821         *((uid_t **)((uschar *)data_block + (long int)(ol->value))) = list;
1822
1823       p = op;
1824       while (count-- > 1)
1825         {
1826         int sep = 0;
1827         (void)string_nextinlist(&p, &sep, big_buffer, BIG_BUFFER_SIZE);
1828         if (!route_finduser(big_buffer, NULL, &uid))
1829           log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, "user %s was not found",
1830             big_buffer);
1831         list[ptr++] = uid;
1832         }
1833       }
1834     break;
1835
1836     /* If it was a gid list, look up each individual entry, and build
1837     a vector of gids, with a count in the first element. Put the vector
1838     in malloc store so we can free the string. (We are reading into permanent
1839     store already.) */
1840
1841     case opt_gidlist:
1842       {
1843       int count = 1;
1844       gid_t *list;
1845       int ptr = 0;
1846       const uschar *p;
1847       const uschar *op = expand_string (sptr);
1848
1849       if (op == NULL)
1850         log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, "failed to expand %s: %s",
1851           name, expand_string_message);
1852
1853       p = op;
1854       if (*p != 0) count++;
1855       while (*p != 0) if (*p++ == ':' && *p != 0) count++;
1856       list = store_malloc(count*sizeof(gid_t));
1857       list[ptr++] = (gid_t)(count - 1);
1858
1859       if (data_block == NULL)
1860         *((gid_t **)(ol->value)) = list;
1861       else
1862         *((gid_t **)((uschar *)data_block + (long int)(ol->value))) = list;
1863
1864       p = op;
1865       while (count-- > 1)
1866         {
1867         int sep = 0;
1868         (void)string_nextinlist(&p, &sep, big_buffer, BIG_BUFFER_SIZE);
1869         if (!route_findgroup(big_buffer, &gid))
1870           log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, "group %s was not found",
1871             big_buffer);
1872         list[ptr++] = gid;
1873         }
1874       }
1875     break;
1876     }
1877
1878   /* Release store if the value of the string doesn't need to be kept. */
1879
1880   if (freesptr) store_reset(reset_point);
1881   break;
1882
1883   /* Expanded boolean: if no characters follow, or if there are no dollar
1884   characters, this is a fixed-valued boolean, and we fall through. Otherwise,
1885   save the string for later expansion in the alternate place. */
1886
1887   case opt_expand_bool:
1888   if (*s != 0 && Ustrchr(s, '$') != 0)
1889     {
1890     sprintf(CS name2, "*expand_%.50s", name);
1891     ol2 = find_option(name2, oltop, last);
1892     if (ol2 != NULL)
1893       {
1894       reset_point = sptr = read_string(s, name);
1895       if (data_block == NULL)
1896         *((uschar **)(ol2->value)) = sptr;
1897       else
1898         *((uschar **)((uschar *)data_block + (long int)(ol2->value))) = sptr;
1899       freesptr = FALSE;
1900       break;
1901       }
1902     }
1903   /* Fall through */
1904
1905   /* Boolean: if no characters follow, the value is boolvalue. Otherwise
1906   look for yes/not/true/false. Some booleans are stored in a single bit in
1907   a single int. There's a special fudge for verify settings; without a suffix
1908   they set both xx_sender and xx_recipient. The table points to the sender
1909   value; search subsequently for the recipient. There's another special case:
1910   opt_bool_set also notes when a boolean has been set. */
1911
1912   case opt_bool:
1913   case opt_bit:
1914   case opt_bool_verify:
1915   case opt_bool_set:
1916   if (*s != 0)
1917     {
1918     s = readconf_readname(name2, 64, s);
1919     if (strcmpic(name2, US"true") == 0 || strcmpic(name2, US"yes") == 0)
1920       boolvalue = TRUE;
1921     else if (strcmpic(name2, US"false") == 0 || strcmpic(name2, US"no") == 0)
1922       boolvalue = FALSE;
1923     else log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN,
1924       "\"%s\" is not a valid value for the \"%s\" option", name2, name);
1925     if (*s != 0) extra_chars_error(s, string_sprintf("\"%s\" ", name2),
1926       US"for boolean option ", name);
1927     }
1928
1929   /* Handle single-bit type. */
1930
1931   if (type == opt_bit)
1932     {
1933     int bit = 1 << ((ol->type >> 16) & 31);
1934     int *ptr = (data_block == NULL)?
1935       (int *)(ol->value) :
1936       (int *)((uschar *)data_block + (long int)ol->value);
1937     if (boolvalue) *ptr |= bit; else *ptr &= ~bit;
1938     break;
1939     }
1940
1941   /* Handle full BOOL types */
1942
1943   if (data_block == NULL)
1944     *((BOOL *)(ol->value)) = boolvalue;
1945   else
1946     *((BOOL *)((uschar *)data_block + (long int)(ol->value))) = boolvalue;
1947
1948   /* Verify fudge */
1949
1950   if (type == opt_bool_verify)
1951     {
1952     sprintf(CS name2, "%.50s_recipient", name + offset);
1953     ol2 = find_option(name2, oltop, last);
1954     if (ol2 != NULL)
1955       {
1956       if (data_block == NULL)
1957         *((BOOL *)(ol2->value)) = boolvalue;
1958       else
1959         *((BOOL *)((uschar *)data_block + (long int)(ol2->value))) = boolvalue;
1960       }
1961     }
1962
1963   /* Note that opt_bool_set type is set, if there is somewhere to do so */
1964
1965   else if (type == opt_bool_set)
1966     {
1967     sprintf(CS name2, "*set_%.50s", name + offset);
1968     ol2 = find_option(name2, oltop, last);
1969     if (ol2 != NULL)
1970       {
1971       if (data_block == NULL)
1972         *((BOOL *)(ol2->value)) = TRUE;
1973       else
1974         *((BOOL *)((uschar *)data_block + (long int)(ol2->value))) = TRUE;
1975       }
1976     }
1977   break;
1978
1979   /* Octal integer */
1980
1981   case opt_octint:
1982   intbase = 8;
1983   inttype = US"octal ";
1984
1985   /*  Integer: a simple(ish) case; allow octal and hex formats, and
1986   suffixes K, M and G. The different types affect output, not input. */
1987
1988   case opt_mkint:
1989   case opt_int:
1990     {
1991     uschar *endptr;
1992     long int lvalue;
1993
1994     errno = 0;
1995     lvalue = strtol(CS s, CSS &endptr, intbase);
1996
1997     if (endptr == s)
1998       log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, "%sinteger expected for %s",
1999         inttype, name);
2000
2001     if (errno != ERANGE)
2002       if (tolower(*endptr) == 'k')
2003         {
2004         if (lvalue > INT_MAX/1024 || lvalue < INT_MIN/1024) errno = ERANGE;
2005           else lvalue *= 1024;
2006         endptr++;
2007         }
2008       else if (tolower(*endptr) == 'm')
2009         {
2010         if (lvalue > INT_MAX/(1024*1024) || lvalue < INT_MIN/(1024*1024))
2011           errno = ERANGE;
2012         else lvalue *= 1024*1024;
2013         endptr++;
2014         }
2015       else if (tolower(*endptr) == 'g')
2016         {
2017         if (lvalue > INT_MAX/(1024*1024*1024) || lvalue < INT_MIN/(1024*1024*1024))
2018           errno = ERANGE;
2019         else lvalue *= 1024*1024*1024;
2020         endptr++;
2021         }
2022
2023     if (errno == ERANGE || lvalue > INT_MAX || lvalue < INT_MIN)
2024       log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN,
2025         "absolute value of integer \"%s\" is too large (overflow)", s);
2026
2027     while (isspace(*endptr)) endptr++;
2028     if (*endptr != 0)
2029       extra_chars_error(endptr, inttype, US"integer value for ", name);
2030
2031     value = (int)lvalue;
2032     }
2033
2034   if (data_block == NULL)
2035     *((int *)(ol->value)) = value;
2036   else
2037     *((int *)((uschar *)data_block + (long int)(ol->value))) = value;
2038   break;
2039
2040   /*  Integer held in K: again, allow octal and hex formats, and suffixes K, M
2041   and G. */
2042   /*XXX consider moving to int_eximarith_t (but mind the overflow test 0415) */
2043
2044   case opt_Kint:
2045     {
2046     uschar *endptr;
2047     errno = 0;
2048     value = strtol(CS s, CSS &endptr, intbase);
2049
2050     if (endptr == s)
2051       log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, "%sinteger expected for %s",
2052         inttype, name);
2053
2054     if (errno != ERANGE)
2055       if (tolower(*endptr) == 'g')
2056         {
2057         if (value > INT_MAX/(1024*1024) || value < INT_MIN/(1024*1024))
2058           errno = ERANGE;
2059         else
2060           value *= 1024*1024;
2061         endptr++;
2062         }
2063       else if (tolower(*endptr) == 'm')
2064         {
2065         if (value > INT_MAX/1024 || value < INT_MIN/1024)
2066           errno = ERANGE;
2067         else
2068           value *= 1024;
2069         endptr++;
2070         }
2071       else if (tolower(*endptr) == 'k')
2072         endptr++;
2073       else
2074         value = (value + 512)/1024;
2075
2076     if (errno == ERANGE) log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN,
2077       "absolute value of integer \"%s\" is too large (overflow)", s);
2078
2079     while (isspace(*endptr)) endptr++;
2080     if (*endptr != 0)
2081       extra_chars_error(endptr, inttype, US"integer value for ", name);
2082     }
2083
2084   if (data_block == NULL)
2085     *((int *)(ol->value)) = value;
2086   else
2087     *((int *)((uschar *)data_block + (long int)(ol->value))) = value;
2088   break;
2089
2090   /*  Fixed-point number: held to 3 decimal places. */
2091
2092   case opt_fixed:
2093   if (sscanf(CS s, "%d%n", &value, &count) != 1)
2094     log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN,
2095       "fixed-point number expected for %s", name);
2096
2097   if (value < 0) log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN,
2098     "integer \"%s\" is too large (overflow)", s);
2099
2100   value *= 1000;
2101
2102   if (value < 0) log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN,
2103     "integer \"%s\" is too large (overflow)", s);
2104
2105   if (s[count] == '.')
2106     {
2107     int d = 100;
2108     while (isdigit(s[++count]))
2109       {
2110       value += (s[count] - '0') * d;
2111       d /= 10;
2112       }
2113     }
2114
2115   while (isspace(s[count])) count++;
2116
2117   if (s[count] != 0)
2118     extra_chars_error(s+count, US"fixed-point value for ", name, US"");
2119
2120   if (data_block == NULL)
2121     *((int *)(ol->value)) = value;
2122   else
2123     *((int *)((uschar *)data_block + (long int)(ol->value))) = value;
2124   break;
2125
2126   /* There's a special routine to read time values. */
2127
2128   case opt_time:
2129   value = readconf_readtime(s, 0, FALSE);
2130   if (value < 0)
2131     log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, "invalid time value for %s",
2132       name);
2133   if (data_block == NULL)
2134     *((int *)(ol->value)) = value;
2135   else
2136     *((int *)((uschar *)data_block + (long int)(ol->value))) = value;
2137   break;
2138
2139   /* A time list is a list of colon-separated times, with the first
2140   element holding the size of the list and the second the number of
2141   entries used. */
2142
2143   case opt_timelist:
2144     {
2145     int count = 0;
2146     int *list = (data_block == NULL)?
2147       (int *)(ol->value) :
2148       (int *)((uschar *)data_block + (long int)(ol->value));
2149
2150     if (*s != 0) for (count = 1; count <= list[0] - 2; count++)
2151       {
2152       int terminator = 0;
2153       uschar *snext = Ustrchr(s, ':');
2154       if (snext != NULL)
2155         {
2156         uschar *ss = snext;
2157         while (ss > s && isspace(ss[-1])) ss--;
2158         terminator = *ss;
2159         }
2160       value = readconf_readtime(s, terminator, FALSE);
2161       if (value < 0)
2162         log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, "invalid time value for %s",
2163           name);
2164       if (count > 1 && value <= list[count])
2165         log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN,
2166           "time value out of order for %s", name);
2167       list[count+1] = value;
2168       if (snext == NULL) break;
2169       s = snext + 1;
2170       while (isspace(*s)) s++;
2171       }
2172
2173     if (count > list[0] - 2)
2174       log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, "too many time values for %s",
2175         name);
2176     if (count > 0 && list[2] == 0) count = 0;
2177     list[1] = count;
2178     break;
2179     }
2180
2181   case opt_func:
2182     {
2183     void (*fn)() = ol->value;
2184     fn(name, s);
2185     break;
2186     }
2187   }
2188
2189 return TRUE;
2190 }
2191
2192
2193
2194 /*************************************************
2195 *               Print a time value               *
2196 *************************************************/
2197
2198 /*
2199 Argument:  a time value in seconds
2200 Returns:   pointer to a fixed buffer containing the time as a string,
2201            in readconf_readtime() format
2202 */
2203
2204 uschar *
2205 readconf_printtime(int t)
2206 {
2207 int s, m, h, d, w;
2208 uschar *p = time_buffer;
2209
2210 if (t < 0)
2211   {
2212   *p++ = '-';
2213   t = -t;
2214   }
2215
2216 s = t % 60;
2217 t /= 60;
2218 m = t % 60;
2219 t /= 60;
2220 h = t % 24;
2221 t /= 24;
2222 d = t % 7;
2223 w = t/7;
2224
2225 if (w > 0) { sprintf(CS p, "%dw", w); while (*p) p++; }
2226 if (d > 0) { sprintf(CS p, "%dd", d); while (*p) p++; }
2227 if (h > 0) { sprintf(CS p, "%dh", h); while (*p) p++; }
2228 if (m > 0) { sprintf(CS p, "%dm", m); while (*p) p++; }
2229 if (s > 0 || p == time_buffer) sprintf(CS p, "%ds", s);
2230
2231 return time_buffer;
2232 }
2233
2234
2235
2236 /*************************************************
2237 *      Print an individual option value          *
2238 *************************************************/
2239
2240 /* This is used by the -bP option, so prints to the standard output.
2241 The entire options list is passed in as an argument, because some options come
2242 in pairs - typically uid/gid settings, which can either be explicit numerical
2243 values, or strings to be expanded later. If the numerical value is unset,
2244 search for "*expand_<name>" to see if there is a string equivalent.
2245
2246 Arguments:
2247   ol             option entry, or NULL for an unknown option
2248   name           option name
2249   options_block  NULL for main configuration options; otherwise points to
2250                    a driver block; if the option doesn't have opt_public
2251                    set, then options_block->options_block is where the item
2252                    resides.
2253   oltop          points to the option list in which ol exists
2254   last           one more than the offset of the last entry in optop
2255   no_labels      do not show "foo = " at the start.
2256
2257 Returns:         nothing
2258 */
2259
2260 static void
2261 print_ol(optionlist *ol, uschar *name, void *options_block,
2262   optionlist *oltop, int last, BOOL no_labels)
2263 {
2264 struct passwd *pw;
2265 struct group *gr;
2266 optionlist *ol2;
2267 void *value;
2268 uid_t *uidlist;
2269 gid_t *gidlist;
2270 uschar *s;
2271 uschar name2[64];
2272
2273 if (ol == NULL)
2274   {
2275   printf("%s is not a known option\n", name);
2276   return;
2277   }
2278
2279 /* Non-admin callers cannot see options that have been flagged secure by the
2280 "hide" prefix. */
2281
2282 if (!admin_user && (ol->type & opt_secure) != 0)
2283   {
2284   if (no_labels)
2285     printf("%s\n", hidden);
2286   else
2287     printf("%s = %s\n", name, hidden);
2288   return;
2289   }
2290
2291 /* Else show the value of the option */
2292
2293 value = ol->value;
2294 if (options_block != NULL)
2295   {
2296   if ((ol->type & opt_public) == 0)
2297     options_block = (void *)(((driver_instance *)options_block)->options_block);
2298   value = (void *)((uschar *)options_block + (long int)value);
2299   }
2300
2301 switch(ol->type & opt_mask)
2302   {
2303   case opt_stringptr:
2304   case opt_rewrite:        /* Show the text value */
2305   s = *((uschar **)value);
2306   if (!no_labels) printf("%s = ", name);
2307   printf("%s\n", (s == NULL)? US"" : string_printing2(s, FALSE));
2308   break;
2309
2310   case opt_int:
2311   if (!no_labels) printf("%s = ", name);
2312   printf("%d\n", *((int *)value));
2313   break;
2314
2315   case opt_mkint:
2316     {
2317     int x = *((int *)value);
2318     if (x != 0 && (x & 1023) == 0)
2319       {
2320       int c = 'K';
2321       x >>= 10;
2322       if ((x & 1023) == 0)
2323         {
2324         c = 'M';
2325         x >>= 10;
2326         }
2327       if (!no_labels) printf("%s = ", name);
2328       printf("%d%c\n", x, c);
2329       }
2330     else
2331       {
2332       if (!no_labels) printf("%s = ", name);
2333       printf("%d\n", x);
2334       }
2335     }
2336   break;
2337
2338   case opt_Kint:
2339     {
2340     int x = *((int *)value);
2341     if (!no_labels) printf("%s = ", name);
2342     if (x == 0) printf("0\n");
2343       else if ((x & 1023) == 0) printf("%dM\n", x >> 10);
2344         else printf("%dK\n", x);
2345     }
2346   break;
2347
2348   case opt_octint:
2349   if (!no_labels) printf("%s = ", name);
2350   printf("%#o\n", *((int *)value));
2351   break;
2352
2353   /* Can be negative only when "unset", in which case integer */
2354
2355   case opt_fixed:
2356     {
2357     int x = *((int *)value);
2358     int f = x % 1000;
2359     int d = 100;
2360     if (x < 0) printf("%s =\n", name); else
2361       {
2362       if (!no_labels) printf("%s = ", name);
2363       printf("%d.", x/1000);
2364       do
2365         {
2366         printf("%d", f/d);
2367         f %= d;
2368         d /= 10;
2369         }
2370       while (f != 0);
2371       printf("\n");
2372       }
2373     }
2374   break;
2375
2376   /* If the numerical value is unset, try for the string value */
2377
2378   case opt_expand_uid:
2379   if (! *get_set_flag(name, oltop, last, options_block))
2380     {
2381     sprintf(CS name2, "*expand_%.50s", name);
2382     ol2 = find_option(name2, oltop, last);
2383     if (ol2 != NULL)
2384       {
2385       void *value2 = ol2->value;
2386       if (options_block != NULL)
2387         value2 = (void *)((uschar *)options_block + (long int)value2);
2388       s = *((uschar **)value2);
2389       if (!no_labels) printf("%s = ", name);
2390       printf("%s\n", (s == NULL)? US"" : string_printing(s));
2391       break;
2392       }
2393     }
2394
2395   /* Else fall through */
2396
2397   case opt_uid:
2398   if (!no_labels) printf("%s = ", name);
2399   if (! *get_set_flag(name, oltop, last, options_block))
2400     printf("\n");
2401   else
2402     {
2403     pw = getpwuid(*((uid_t *)value));
2404     if (pw == NULL)
2405       printf("%ld\n", (long int)(*((uid_t *)value)));
2406     else printf("%s\n", pw->pw_name);
2407     }
2408   break;
2409
2410   /* If the numerical value is unset, try for the string value */
2411
2412   case opt_expand_gid:
2413   if (! *get_set_flag(name, oltop, last, options_block))
2414     {
2415     sprintf(CS name2, "*expand_%.50s", name);
2416     ol2 = find_option(name2, oltop, last);
2417     if (ol2 != NULL && (ol2->type & opt_mask) == opt_stringptr)
2418       {
2419       void *value2 = ol2->value;
2420       if (options_block != NULL)
2421         value2 = (void *)((uschar *)options_block + (long int)value2);
2422       s = *((uschar **)value2);
2423       if (!no_labels) printf("%s = ", name);
2424       printf("%s\n", (s == NULL)? US"" : string_printing(s));
2425       break;
2426       }
2427     }
2428
2429   /* Else fall through */
2430
2431   case opt_gid:
2432   if (!no_labels) printf("%s = ", name);
2433   if (! *get_set_flag(name, oltop, last, options_block))
2434     printf("\n");
2435   else
2436     {
2437     gr = getgrgid(*((int *)value));
2438     if (gr == NULL)
2439        printf("%ld\n", (long int)(*((int *)value)));
2440     else printf("%s\n", gr->gr_name);
2441     }
2442   break;
2443
2444   case opt_uidlist:
2445   uidlist = *((uid_t **)value);
2446   if (!no_labels) printf("%s =", name);
2447   if (uidlist != NULL)
2448     {
2449     int i;
2450     uschar sep = ' ';
2451     if (no_labels) sep = '\0';
2452     for (i = 1; i <= (int)(uidlist[0]); i++)
2453       {
2454       uschar *name = NULL;
2455       pw = getpwuid(uidlist[i]);
2456       if (pw != NULL) name = US pw->pw_name;
2457       if (sep != '\0') printf("%c", sep);
2458       if (name != NULL) printf("%s", name);
2459         else printf("%ld", (long int)(uidlist[i]));
2460       sep = ':';
2461       }
2462     }
2463   printf("\n");
2464   break;
2465
2466   case opt_gidlist:
2467   gidlist = *((gid_t **)value);
2468   if (!no_labels) printf("%s =", name);
2469   if (gidlist != NULL)
2470     {
2471     int i;
2472     uschar sep = ' ';
2473     if (no_labels) sep = '\0';
2474     for (i = 1; i <= (int)(gidlist[0]); i++)
2475       {
2476       uschar *name = NULL;
2477       gr = getgrgid(gidlist[i]);
2478       if (gr != NULL) name = US gr->gr_name;
2479       if (sep != '\0') printf("%c", sep);
2480       if (name != NULL) printf("%s", name);
2481         else printf("%ld", (long int)(gidlist[i]));
2482       sep = ':';
2483       }
2484     }
2485   printf("\n");
2486   break;
2487
2488   case opt_time:
2489   if (!no_labels) printf("%s = ", name);
2490   printf("%s\n", readconf_printtime(*((int *)value)));
2491   break;
2492
2493   case opt_timelist:
2494     {
2495     int i;
2496     int *list = (int *)value;
2497     if (!no_labels) printf("%s = ", name);
2498     for (i = 0; i < list[1]; i++)
2499       printf("%s%s", (i == 0)? "" : ":", readconf_printtime(list[i+2]));
2500     printf("\n");
2501     }
2502   break;
2503
2504   case opt_bit:
2505   printf("%s%s\n", ((*((int *)value)) & (1 << ((ol->type >> 16) & 31)))?
2506     "" : "no_", name);
2507   break;
2508
2509   case opt_expand_bool:
2510   sprintf(CS name2, "*expand_%.50s", name);
2511   ol2 = find_option(name2, oltop, last);
2512   if (ol2 != NULL && ol2->value != NULL)
2513     {
2514     void *value2 = ol2->value;
2515     if (options_block != NULL)
2516       value2 = (void *)((uschar *)options_block + (long int)value2);
2517     s = *((uschar **)value2);
2518     if (s != NULL)
2519       {
2520       if (!no_labels) printf("%s = ", name);
2521       printf("%s\n", string_printing(s));
2522       break;
2523       }
2524     /* s == NULL => string not set; fall through */
2525     }
2526
2527   /* Fall through */
2528
2529   case opt_bool:
2530   case opt_bool_verify:
2531   case opt_bool_set:
2532   printf("%s%s\n", (*((BOOL *)value))? "" : "no_", name);
2533   break;
2534   }
2535 }
2536
2537
2538
2539 /*************************************************
2540 *        Print value from main configuration     *
2541 *************************************************/
2542
2543 /* This function, called as a result of encountering the -bP option,
2544 causes the value of any main configuration variable to be output if the
2545 second argument is NULL. There are some special values:
2546
2547   all                print all main configuration options
2548   config_file        print the name of the configuration file
2549                      (configure_file will still work, for backward
2550                      compatibility)
2551   routers            print the routers' configurations
2552   transports         print the transports' configuration
2553   authenticators     print the authenticators' configuration
2554   macros             print the macros' configuration
2555   router_list        print a list of router names
2556   transport_list     print a list of transport names
2557   authenticator_list print a list of authentication mechanism names
2558   macro_list         print a list of macro names
2559   +name              print a named list item
2560   local_scan         print the local_scan options
2561   config             print the configuration as it is parsed
2562   environment        print the used execution environment
2563
2564 If the second argument is not NULL, it must be one of "router", "transport",
2565 "authenticator" or "macro" in which case the first argument identifies the
2566 driver whose options are to be printed.
2567
2568 Arguments:
2569   name        option name if type == NULL; else driver name
2570   type        NULL or driver type name, as described above
2571   no_labels   avoid the "foo = " at the start of an item
2572
2573 Returns:      nothing
2574 */
2575
2576 void
2577 readconf_print(uschar *name, uschar *type, BOOL no_labels)
2578 {
2579 BOOL names_only = FALSE;
2580 optionlist *ol;
2581 optionlist *ol2 = NULL;
2582 driver_instance *d = NULL;
2583 macro_item *m;
2584 int size = 0;
2585
2586 if (type == NULL)
2587   {
2588   if (*name == '+')
2589     {
2590     int i;
2591     tree_node *t;
2592     BOOL found = FALSE;
2593     static uschar *types[] = { US"address", US"domain", US"host",
2594       US"localpart" };
2595     static tree_node **anchors[] = { &addresslist_anchor, &domainlist_anchor,
2596       &hostlist_anchor, &localpartlist_anchor };
2597
2598     for (i = 0; i < 4; i++)
2599       {
2600       t = tree_search(*(anchors[i]), name+1);
2601       if (t != NULL)
2602         {
2603         found = TRUE;
2604         if (no_labels)
2605           printf("%s\n", ((namedlist_block *)(t->data.ptr))->string);
2606         else
2607           printf("%slist %s = %s\n", types[i], name+1,
2608             ((namedlist_block *)(t->data.ptr))->string);
2609         }
2610       }
2611
2612     if (!found)
2613       printf("no address, domain, host, or local part list called \"%s\" "
2614         "exists\n", name+1);
2615
2616     return;
2617     }
2618
2619   if (  Ustrcmp(name, "configure_file") == 0
2620      || Ustrcmp(name, "config_file") == 0)
2621     {
2622     printf("%s\n", CS config_main_filename);
2623     return;
2624     }
2625
2626   if (Ustrcmp(name, "all") == 0)
2627     {
2628     for (ol = optionlist_config;
2629          ol < optionlist_config + optionlist_config_size; ol++)
2630       {
2631       if ((ol->type & opt_hidden) == 0)
2632         print_ol(ol, US ol->name, NULL,
2633             optionlist_config, optionlist_config_size,
2634             no_labels);
2635       }
2636     return;
2637     }
2638
2639   if (Ustrcmp(name, "local_scan") == 0)
2640     {
2641     #ifndef LOCAL_SCAN_HAS_OPTIONS
2642     printf("local_scan() options are not supported\n");
2643     #else
2644     for (ol = local_scan_options;
2645          ol < local_scan_options + local_scan_options_count; ol++)
2646       {
2647       print_ol(ol, US ol->name, NULL, local_scan_options,
2648         local_scan_options_count, no_labels);
2649       }
2650     #endif
2651     return;
2652     }
2653
2654   if (Ustrcmp(name, "config") == 0)
2655     {
2656     print_config(admin_user, no_labels);
2657     return;
2658     }
2659
2660   if (Ustrcmp(name, "routers") == 0)
2661     {
2662     type = US"router";
2663     name = NULL;
2664     }
2665   else if (Ustrcmp(name, "transports") == 0)
2666     {
2667     type = US"transport";
2668     name = NULL;
2669     }
2670
2671   else if (Ustrcmp(name, "authenticators") == 0)
2672     {
2673     type = US"authenticator";
2674     name = NULL;
2675     }
2676
2677   else if (Ustrcmp(name, "macros") == 0)
2678     {
2679     type = US"macro";
2680     name = NULL;
2681     }
2682
2683   else if (Ustrcmp(name, "router_list") == 0)
2684     {
2685     type = US"router";
2686     name = NULL;
2687     names_only = TRUE;
2688     }
2689
2690   else if (Ustrcmp(name, "transport_list") == 0)
2691     {
2692     type = US"transport";
2693     name = NULL;
2694     names_only = TRUE;
2695     }
2696
2697   else if (Ustrcmp(name, "authenticator_list") == 0)
2698     {
2699     type = US"authenticator";
2700     name = NULL;
2701     names_only = TRUE;
2702     }
2703
2704   else if (Ustrcmp(name, "macro_list") == 0)
2705     {
2706     type = US"macro";
2707     name = NULL;
2708     names_only = TRUE;
2709     }
2710
2711   else if (Ustrcmp(name, "environment") == 0)
2712     {
2713     if (environ)
2714       {
2715       uschar ** p;
2716       for (p = USS environ; *p; p++) ;
2717       qsort(environ, p - USS environ, sizeof(*p), string_compare_by_pointer);
2718
2719       for (p = USS environ; *p; p++)
2720         {
2721         uschar * q;
2722         if (no_labels && (q = Ustrchr(*p, '='))) *q  = '\0';
2723         puts(CS *p);
2724         }
2725       }
2726     return;
2727     }
2728
2729   else
2730     {
2731     print_ol(find_option(name, optionlist_config, optionlist_config_size),
2732       name, NULL, optionlist_config, optionlist_config_size, no_labels);
2733     return;
2734     }
2735   }
2736
2737 /* Handle the options for a router or transport. Skip options that are flagged
2738 as hidden. Some of these are options with names starting with '*', used for
2739 internal alternative representations of other options (which the printing
2740 function will sort out). Others are synonyms kept for backward compatibility.
2741 */
2742
2743 if (Ustrcmp(type, "router") == 0)
2744   {
2745   d = (driver_instance *)routers;
2746   ol2 = optionlist_routers;
2747   size = optionlist_routers_size;
2748   }
2749 else if (Ustrcmp(type, "transport") == 0)
2750   {
2751   d = (driver_instance *)transports;
2752   ol2 = optionlist_transports;
2753   size = optionlist_transports_size;
2754   }
2755 else if (Ustrcmp(type, "authenticator") == 0)
2756   {
2757   d = (driver_instance *)auths;
2758   ol2 = optionlist_auths;
2759   size = optionlist_auths_size;
2760   }
2761
2762 else if (Ustrcmp(type, "macro") == 0)
2763   {
2764   /* People store passwords in macros and they were previously not available
2765   for printing.  So we have an admin_users restriction. */
2766   if (!admin_user)
2767     {
2768     fprintf(stderr, "exim: permission denied\n");
2769     exit(EXIT_FAILURE);
2770     }
2771   for (m = macros; m != NULL; m = m->next)
2772     {
2773     if (name == NULL || Ustrcmp(name, m->name) == 0)
2774       {
2775       if (names_only)
2776         printf("%s\n", CS m->name);
2777       else
2778         printf("%s=%s\n", CS m->name, CS m->replacement);
2779       if (name != NULL)
2780         return;
2781       }
2782     }
2783   if (name != NULL)
2784     printf("%s %s not found\n", type, name);
2785   return;
2786   }
2787
2788 if (names_only)
2789   {
2790   for (; d != NULL; d = d->next) printf("%s\n", CS d->name);
2791   return;
2792   }
2793
2794 /* Either search for a given driver, or print all of them */
2795
2796 for (; d != NULL; d = d->next)
2797   {
2798   if (name == NULL)
2799     printf("\n%s %s:\n", d->name, type);
2800   else if (Ustrcmp(d->name, name) != 0) continue;
2801
2802   for (ol = ol2; ol < ol2 + size; ol++)
2803     {
2804     if ((ol->type & opt_hidden) == 0)
2805       print_ol(ol, US ol->name, d, ol2, size, no_labels);
2806     }
2807
2808   for (ol = d->info->options;
2809        ol < d->info->options + *(d->info->options_count); ol++)
2810     {
2811     if ((ol->type & opt_hidden) == 0)
2812       print_ol(ol, US ol->name, d, d->info->options, *(d->info->options_count), no_labels);
2813     }
2814   if (name != NULL) return;
2815   }
2816 if (name != NULL) printf("%s %s not found\n", type, name);
2817 }
2818
2819
2820
2821 /*************************************************
2822 *          Read a named list item                *
2823 *************************************************/
2824
2825 /* This function reads a name and a list (i.e. string). The name is used to
2826 save the list in a tree, sorted by its name. Each entry also has a number,
2827 which can be used for caching tests, but if the string contains any expansion
2828 items other than $key, the number is set negative to inhibit caching. This
2829 mechanism is used for domain, host, and address lists that are referenced by
2830 the "+name" syntax.
2831
2832 Arguments:
2833   anchorp     points to the tree anchor
2834   numberp     points to the current number for this tree
2835   max         the maximum number permitted
2836   s           the text of the option line, starting immediately after the name
2837                 of the list type
2838   tname       the name of the list type, for messages
2839
2840 Returns:      nothing
2841 */
2842
2843 static void
2844 read_named_list(tree_node **anchorp, int *numberp, int max, uschar *s,
2845   uschar *tname)
2846 {
2847 BOOL forcecache = FALSE;
2848 uschar *ss;
2849 tree_node *t;
2850 namedlist_block *nb = store_get(sizeof(namedlist_block));
2851
2852 if (Ustrncmp(s, "_cache", 6) == 0)
2853   {
2854   forcecache = TRUE;
2855   s += 6;
2856   }
2857
2858 if (!isspace(*s))
2859   log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, "unrecognized configuration line");
2860
2861 if (*numberp >= max)
2862  log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, "too many named %ss (max is %d)\n",
2863    tname, max);
2864
2865 while (isspace(*s)) s++;
2866 ss = s;
2867 while (isalnum(*s) || *s == '_') s++;
2868 t = store_get(sizeof(tree_node) + s-ss);
2869 Ustrncpy(t->name, ss, s-ss);
2870 t->name[s-ss] = 0;
2871 while (isspace(*s)) s++;
2872
2873 if (!tree_insertnode(anchorp, t))
2874   log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN,
2875     "duplicate name \"%s\" for a named %s", t->name, tname);
2876
2877 t->data.ptr = nb;
2878 nb->number = *numberp;
2879 *numberp += 1;
2880
2881 if (*s++ != '=') log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN,
2882   "missing '=' after \"%s\"", t->name);
2883 while (isspace(*s)) s++;
2884 nb->string = read_string(s, t->name);
2885 nb->cache_data = NULL;
2886
2887 /* Check the string for any expansions; if any are found, mark this list
2888 uncacheable unless the user has explicited forced caching. */
2889
2890 if (!forcecache && Ustrchr(nb->string, '$') != NULL) nb->number = -1;
2891 }
2892
2893
2894
2895
2896 /*************************************************
2897 *        Unpick data for a rate limit            *
2898 *************************************************/
2899
2900 /* This function is called to unpick smtp_ratelimit_{mail,rcpt} into four
2901 separate values.
2902
2903 Arguments:
2904   s            string, in the form t,b,f,l
2905                where t is the threshold (integer)
2906                b is the initial delay (time)
2907                f is the multiplicative factor (fixed point)
2908                k is the maximum time (time)
2909   threshold    where to store threshold
2910   base         where to store base in milliseconds
2911   factor       where to store factor in milliseconds
2912   limit        where to store limit
2913
2914 Returns:       nothing (panics on error)
2915 */
2916
2917 static void
2918 unpick_ratelimit(uschar *s, int *threshold, int *base, double *factor,
2919   int *limit)
2920 {
2921 uschar bstring[16], lstring[16];
2922
2923 if (sscanf(CS s, "%d, %15[0123456789smhdw.], %lf, %15s", threshold, bstring,
2924     factor, lstring) == 4)
2925   {
2926   *base = readconf_readtime(bstring, 0, TRUE);
2927   *limit = readconf_readtime(lstring, 0, TRUE);
2928   if (*base >= 0 && *limit >= 0) return;
2929   }
2930 log_write(0, LOG_MAIN|LOG_PANIC_DIE, "malformed ratelimit data: %s", s);
2931 }
2932
2933
2934
2935
2936 /*************************************************
2937 *       Drop privs for checking TLS config      *
2938 *************************************************/
2939
2940 /* We want to validate TLS options during readconf, but do not want to be
2941 root when we call into the TLS library, in case of library linkage errors
2942 which cause segfaults; before this check, those were always done as the Exim
2943 runtime user and it makes sense to continue with that.
2944
2945 Assumes:  tls_require_ciphers has been set, if it will be
2946           exim_user has been set, if it will be
2947           exim_group has been set, if it will be
2948
2949 Returns:  bool for "okay"; false will cause caller to immediately exit.
2950 */
2951
2952 #ifdef SUPPORT_TLS
2953 static BOOL
2954 tls_dropprivs_validate_require_cipher(BOOL nowarn)
2955 {
2956 const uschar *errmsg;
2957 pid_t pid;
2958 int rc, status;
2959 void (*oldsignal)(int);
2960
2961 /* If TLS will never be used, no point checking ciphers */
2962
2963 if (  !tls_advertise_hosts
2964    || !*tls_advertise_hosts
2965    || Ustrcmp(tls_advertise_hosts, ":") == 0
2966    )
2967   return TRUE;
2968 else if (!nowarn && !tls_certificate)
2969   log_write(0, LOG_MAIN,
2970     "Warning: No server certificate defined; will use a selfsigned one.\n"
2971     " Suggested action: either install a certificate or change tls_advertise_hosts option");
2972
2973 oldsignal = signal(SIGCHLD, SIG_DFL);
2974
2975 fflush(NULL);
2976 if ((pid = fork()) < 0)
2977   log_write(0, LOG_MAIN|LOG_PANIC_DIE, "fork failed for TLS check");
2978
2979 if (pid == 0)
2980   {
2981   /* in some modes, will have dropped privilege already */
2982   if (!geteuid())
2983     exim_setugid(exim_uid, exim_gid, FALSE,
2984         US"calling tls_validate_require_cipher");
2985
2986   errmsg = tls_validate_require_cipher();
2987   if (errmsg)
2988     {
2989     log_write(0, LOG_PANIC_DIE|LOG_CONFIG,
2990         "tls_require_ciphers invalid: %s", errmsg);
2991     }
2992   fflush(NULL);
2993   _exit(0);
2994   }
2995
2996 do {
2997   rc = waitpid(pid, &status, 0);
2998 } while (rc < 0 && errno == EINTR);
2999
3000 DEBUG(D_tls)
3001   debug_printf("tls_validate_require_cipher child %d ended: status=0x%x\n",
3002       (int)pid, status);
3003
3004 signal(SIGCHLD, oldsignal);
3005
3006 return status == 0;
3007 }
3008 #endif /* SUPPORT_TLS */
3009
3010
3011
3012
3013 /*************************************************/
3014 /* Create compile-time feature macros */
3015 static void
3016 readconf_features(void)
3017 {
3018 /* Probably we could work out a static initialiser for wherever
3019 macros are stored, but this will do for now. Some names are awkward
3020 due to conflicts with other common macros. */
3021
3022 #ifdef SUPPORT_CRYPTEQ
3023   read_macro_assignment(US"_HAVE_CRYPTEQ=y");
3024 #endif
3025 #if HAVE_ICONV
3026   read_macro_assignment(US"_HAVE_ICONV=y");
3027 #endif
3028 #if HAVE_IPV6
3029   read_macro_assignment(US"_HAVE_IPV6=y");
3030 #endif
3031 #ifdef HAVE_SETCLASSRESOURCES
3032   read_macro_assignment(US"_HAVE_SETCLASSRESOURCES=y");
3033 #endif
3034 #ifdef SUPPORT_PAM
3035   read_macro_assignment(US"_HAVE_PAM=y");
3036 #endif
3037 #ifdef EXIM_PERL
3038   read_macro_assignment(US"_HAVE_PERL=y");
3039 #endif
3040 #ifdef EXPAND_DLFUNC
3041   read_macro_assignment(US"_HAVE_DLFUNC=y");
3042 #endif
3043 #ifdef USE_TCP_WRAPPERS
3044   read_macro_assignment(US"_HAVE_TCPWRAPPERS=y");
3045 #endif
3046 #ifdef SUPPORT_TLS
3047   read_macro_assignment(US"_HAVE_TLS=y");
3048 # ifdef USE_GNUTLS
3049   read_macro_assignment(US"_HAVE_GNUTLS=y");
3050 # else
3051   read_macro_assignment(US"_HAVE_OPENSSL=y");
3052 # endif
3053 #endif
3054 #ifdef SUPPORT_TRANSLATE_IP_ADDRESS
3055   read_macro_assignment(US"_HAVE_TRANSLATE_IP_ADDRESS=y");
3056 #endif
3057 #ifdef SUPPORT_MOVE_FROZEN_MESSAGES
3058   read_macro_assignment(US"_HAVE_MOVE_FROZEN_MESSAGES=y");
3059 #endif
3060 #ifdef WITH_CONTENT_SCAN
3061   read_macro_assignment(US"_HAVE_CONTENT_SCANNING=y");
3062 #endif
3063 #ifndef DISABLE_DKIM
3064   read_macro_assignment(US"_HAVE_DKIM=y");
3065 #endif
3066 #ifndef DISABLE_DNSSEC
3067   read_macro_assignment(US"_HAVE_DNSSEC=y");
3068 #endif
3069 #ifndef DISABLE_EVENT
3070   read_macro_assignment(US"_HAVE_Event=y");
3071 #endif
3072 #ifdef SUPPORT_I18N
3073   read_macro_assignment(US"_HAVE_I18N=y");
3074 #endif
3075 #ifndef DISABLE_OCSP
3076   read_macro_assignment(US"_HAVE_OCSP=y");
3077 #endif
3078 #ifndef DISABLE_PRDR
3079   read_macro_assignment(US"_HAVE_PRDR=y");
3080 #endif
3081 #ifdef SUPPORT_PROXY
3082   read_macro_assignment(US"_HAVE_PROXY=y");
3083 #endif
3084 #ifdef SUPPORT_SOCKS
3085   read_macro_assignment(US"_HAVE_SOCKS=y");
3086 #endif
3087 #ifdef EXPERIMENTAL_LMDB
3088   read_macro_assignment(US"_HAVE_LMDB=y");
3089 #endif
3090 #ifdef EXPERIMENTAL_SPF
3091   read_macro_assignment(US"_HAVE_SPF=y");
3092 #endif
3093 #ifdef EXPERIMENTAL_SRS
3094   read_macro_assignment(US"_HAVE_SRS=y");
3095 #endif
3096 #ifdef EXPERIMENTAL_BRIGHTMAIL
3097   read_macro_assignment(US"_HAVE_BRIGHTMAIL=y");
3098 #endif
3099 #ifdef EXPERIMENTAL_DANE
3100   read_macro_assignment(US"_HAVE_DANE=y");
3101 #endif
3102 #ifdef EXPERIMENTAL_DCC
3103   read_macro_assignment(US"_HAVE_DCC=y");
3104 #endif
3105 #ifdef EXPERIMENTAL_DMARC
3106   read_macro_assignment(US"_HAVE_DMARC=y");
3107 #endif
3108 #ifdef EXPERIMENTAL_DSN_INFO
3109   read_macro_assignment(US"_HAVE_DSN_INFO=y");
3110 #endif
3111
3112 #ifdef LOOKUP_LSEARCH
3113   read_macro_assignment(US"_HAVE_LKUP_LSEARCH=y");
3114 #endif
3115 #ifdef LOOKUP_CDB
3116   read_macro_assignment(US"_HAVE_LKUP_CDB=y");
3117 #endif
3118 #ifdef LOOKUP_DBM
3119   read_macro_assignment(US"_HAVE_LKUP_DBM=y");
3120 #endif
3121 #ifdef LOOKUP_DNSDB
3122   read_macro_assignment(US"_HAVE_LKUP_DNSDB=y");
3123 #endif
3124 #ifdef LOOKUP_DSEARCH
3125   read_macro_assignment(US"_HAVE_LKUP_DSEARCH=y");
3126 #endif
3127 #ifdef LOOKUP_IBASE
3128   read_macro_assignment(US"_HAVE_LKUP_IBASE=y");
3129 #endif
3130 #ifdef LOOKUP_LDAP
3131   read_macro_assignment(US"_HAVE_LKUP_LDAP=y");
3132 #endif
3133 #ifdef EXPERIMENTAL_LMDB
3134   read_macro_assignment(US"_HAVE_LKUP_LMDB=y");
3135 #endif
3136 #ifdef LOOKUP_MYSQL
3137   read_macro_assignment(US"_HAVE_LKUP_MYSQL=y");
3138 #endif
3139 #ifdef LOOKUP_NIS
3140   read_macro_assignment(US"_HAVE_LKUP_NIS=y");
3141 #endif
3142 #ifdef LOOKUP_NISPLUS
3143   read_macro_assignment(US"_HAVE_LKUP_NISPLUS=y");
3144 #endif
3145 #ifdef LOOKUP_ORACLE
3146   read_macro_assignment(US"_HAVE_LKUP_ORACLE=y");
3147 #endif
3148 #ifdef LOOKUP_PASSWD
3149   read_macro_assignment(US"_HAVE_LKUP_PASSWD=y");
3150 #endif
3151 #ifdef LOOKUP_PGSQL
3152   read_macro_assignment(US"_HAVE_LKUP_PGSQL=y");
3153 #endif
3154 #ifdef LOOKUP_REDIS
3155   read_macro_assignment(US"_HAVE_LKUP_REDIS=y");
3156 #endif
3157 #ifdef LOOKUP_SQLITE
3158   read_macro_assignment(US"_HAVE_LKUP_SQLITE=y");
3159 #endif
3160 #ifdef LOOKUP_TESTDB
3161   read_macro_assignment(US"_HAVE_LKUP_TESTDB=y");
3162 #endif
3163 #ifdef LOOKUP_WHOSON
3164   read_macro_assignment(US"_HAVE_LKUP_WHOSON=y");
3165 #endif
3166
3167 #ifdef AUTH_CRAM_MD5
3168   read_macro_assignment(US"_HAVE_AUTH_CRAM_MD5=y");
3169 #endif
3170 #ifdef AUTH_CYRUS_SASL
3171   read_macro_assignment(US"_HAVE_AUTH_CYRUS_SASL=y");
3172 #endif
3173 #ifdef AUTH_DOVECOT
3174   read_macro_assignment(US"_HAVE_AUTH_DOVECOT=y");
3175 #endif
3176 #ifdef AUTH_GSASL
3177   read_macro_assignment(US"_HAVE_AUTH_GSASL=y");
3178 #endif
3179 #ifdef AUTH_HEIMDAL_GSSAPI
3180   read_macro_assignment(US"_HAVE_AUTH_HEIMDAL_GSSAPI=y");
3181 #endif
3182 #ifdef AUTH_PLAINTEXT
3183   read_macro_assignment(US"_HAVE_AUTH_PLAINTEXT=y");
3184 #endif
3185 #ifdef AUTH_SPA
3186   read_macro_assignment(US"_HAVE_AUTH_SPA=y");
3187 #endif
3188 #ifdef AUTH_TLS
3189   read_macro_assignment(US"_HAVE_AUTH_TLS=y");
3190 #endif
3191
3192 #ifdef ROUTER_ACCEPT
3193   read_macro_assignment(US"_HAVE_RTR_ACCEPT=y");
3194 #endif
3195 #ifdef ROUTER_DNSLOOKUP
3196   read_macro_assignment(US"_HAVE_RTR_DNSLOOKUP=y");
3197 #endif
3198 #ifdef ROUTER_IPLITERAL
3199   read_macro_assignment(US"_HAVE_RTR_IPLITERAL=y");
3200 #endif
3201 #ifdef ROUTER_IPLOOKUP
3202   read_macro_assignment(US"_HAVE_RTR_IPLOOKUP=y");
3203 #endif
3204 #ifdef ROUTER_MANUALROUTE
3205   read_macro_assignment(US"_HAVE_RTR_MANUALROUTE=y");
3206 #endif
3207 #ifdef ROUTER_QUERYPROGRAM
3208   read_macro_assignment(US"_HAVE_RTR_QUERYPROGRAM=y");
3209 #endif
3210 #ifdef ROUTER_REDIRECT
3211   read_macro_assignment(US"_HAVE_RTR_REDRCT=y");
3212 #endif
3213
3214 #ifdef TRANSPORT_APPENDFILE
3215   read_macro_assignment(US"_HAVE_TPT_APPENDFILE=y");
3216 # ifdef SUPPORT_MAILDIR
3217   read_macro_assignment(US"_HAVE_TPT_APPEND_MAILDR=y");
3218 # endif
3219 # ifdef SUPPORT_MAILSTORE
3220   read_macro_assignment(US"_HAVE_TPT_APPEND_MAILSTORE=y");
3221 # endif
3222 # ifdef SUPPORT_MBX
3223   read_macro_assignment(US"_HAVE_TPT_APPEND_MBX=y");
3224 # endif
3225 #endif
3226 #ifdef TRANSPORT_AUTOREPLY
3227   read_macro_assignment(US"_HAVE_TPT_AUTOREPLY=y");
3228 #endif
3229 #ifdef TRANSPORT_LMTP
3230   read_macro_assignment(US"_HAVE_TPT_LMTP=y");
3231 #endif
3232 #ifdef TRANSPORT_PIPE
3233   read_macro_assignment(US"_HAVE_TPT_PIPE=y");
3234 #endif
3235 #ifdef TRANSPORT_SMTP
3236   read_macro_assignment(US"_HAVE_TPT_SMTP=y");
3237 #endif
3238 }
3239
3240
3241 /*************************************************
3242 *         Read main configuration options        *
3243 *************************************************/
3244
3245 /* This function is the first to be called for configuration reading. It
3246 opens the configuration file and reads general configuration settings until
3247 it reaches the end of the configuration section. The file is then left open so
3248 that the remaining configuration data can subsequently be read if needed for
3249 this run of Exim.
3250
3251 The configuration file must be owned either by root or exim, and be writeable
3252 only by root or uid/gid exim. The values for Exim's uid and gid can be changed
3253 in the config file, so the test is done on the compiled in values. A slight
3254 anomaly, to be carefully documented.
3255
3256 The name of the configuration file is taken from a list that is included in the
3257 binary of Exim. It can be altered from the command line, but if that is done,
3258 root privilege is immediately withdrawn unless the caller is root or exim.
3259 The first file on the list that exists is used.
3260
3261 For use on multiple systems that share file systems, first look for a
3262 configuration file whose name has the current node name on the end. If that is
3263 not found, try the generic name. For really contorted configurations, that run
3264 multiple Exims with different uid settings, first try adding the effective uid
3265 before the node name. These complications are going to waste resources on most
3266 systems. Therefore they are available only when requested by compile-time
3267 options. */
3268
3269 void
3270 readconf_main(BOOL nowarn)
3271 {
3272 int sep = 0;
3273 struct stat statbuf;
3274 uschar *s, *filename;
3275 const uschar *list = config_main_filelist;
3276
3277 /* First create compile-time feature macros */
3278 readconf_features();
3279
3280 /* Loop through the possible file names */
3281
3282 while((filename = string_nextinlist(&list, &sep, big_buffer, big_buffer_size))
3283        != NULL)
3284   {
3285
3286   /* Cut out all the fancy processing unless specifically wanted */
3287
3288   #if defined(CONFIGURE_FILE_USE_NODE) || defined(CONFIGURE_FILE_USE_EUID)
3289   uschar *suffix = filename + Ustrlen(filename);
3290
3291   /* Try for the node-specific file if a node name exists */
3292
3293   #ifdef CONFIGURE_FILE_USE_NODE
3294   struct utsname uts;
3295   if (uname(&uts) >= 0)
3296     {
3297     #ifdef CONFIGURE_FILE_USE_EUID
3298     sprintf(CS suffix, ".%ld.%.256s", (long int)original_euid, uts.nodename);
3299     config_file = Ufopen(filename, "rb");
3300     if (config_file == NULL)
3301     #endif  /* CONFIGURE_FILE_USE_EUID */
3302       {
3303       sprintf(CS suffix, ".%.256s", uts.nodename);
3304       config_file = Ufopen(filename, "rb");
3305       }
3306     }
3307   #endif  /* CONFIGURE_FILE_USE_NODE */
3308
3309   /* Otherwise, try the generic name, possibly with the euid added */
3310
3311   #ifdef CONFIGURE_FILE_USE_EUID
3312   if (config_file == NULL)
3313     {
3314     sprintf(CS suffix, ".%ld", (long int)original_euid);
3315     config_file = Ufopen(filename, "rb");
3316     }
3317   #endif  /* CONFIGURE_FILE_USE_EUID */
3318
3319   /* Finally, try the unadorned name */
3320
3321   if (config_file == NULL)
3322     {
3323     *suffix = 0;
3324     config_file = Ufopen(filename, "rb");
3325     }
3326   #else  /* if neither defined */
3327
3328   /* This is the common case when the fancy processing is not included. */
3329
3330   config_file = Ufopen(filename, "rb");
3331   #endif
3332
3333   /* If the file does not exist, continue to try any others. For any other
3334   error, break out (and die). */
3335
3336   if (config_file != NULL || errno != ENOENT) break;
3337   }
3338
3339 /* Now, once we found and opened our configuration file, we change the directory
3340 to a safe place. Later we change to $spool_directory. */
3341
3342 if (Uchdir("/") < 0)
3343   {
3344   perror("exim: chdir `/': ");
3345   exit(EXIT_FAILURE);
3346   }
3347
3348 /* On success, save the name for verification; config_filename is used when
3349 logging configuration errors (it changes for .included files) whereas
3350 config_main_filename is the name shown by -bP. Failure to open a configuration
3351 file is a serious disaster. */
3352
3353 if (config_file != NULL)
3354   {
3355   uschar *p;
3356   config_filename = config_main_filename = string_copy(filename);
3357
3358   p = Ustrrchr(filename, '/');
3359   config_main_directory = p ? string_copyn(filename, p - filename)
3360                             : string_copy(US".");
3361   }
3362 else
3363   {
3364   if (filename == NULL)
3365     log_write(0, LOG_MAIN|LOG_PANIC_DIE, "non-existent configuration file(s): "
3366       "%s", config_main_filelist);
3367   else
3368     log_write(0, LOG_MAIN|LOG_PANIC_DIE, "%s", string_open_failed(errno,
3369       "configuration file %s", filename));
3370   }
3371
3372 /* Check the status of the file we have opened, if we have retained root
3373 privileges and the file isn't /dev/null (which *should* be 0666). */
3374
3375 if (trusted_config && Ustrcmp(filename, US"/dev/null"))
3376   {
3377   if (fstat(fileno(config_file), &statbuf) != 0)
3378     log_write(0, LOG_MAIN|LOG_PANIC_DIE, "failed to stat configuration file %s",
3379       big_buffer);
3380
3381   if ((statbuf.st_uid != root_uid                /* owner not root */
3382        #ifdef CONFIGURE_OWNER
3383        && statbuf.st_uid != config_uid           /* owner not the special one */
3384        #endif
3385          ) ||                                    /* or */
3386       (statbuf.st_gid != root_gid                /* group not root & */
3387        #ifdef CONFIGURE_GROUP
3388        && statbuf.st_gid != config_gid           /* group not the special one */
3389        #endif
3390        && (statbuf.st_mode & 020) != 0) ||       /* group writeable  */
3391                                                  /* or */
3392       ((statbuf.st_mode & 2) != 0))              /* world writeable  */
3393
3394     log_write(0, LOG_MAIN|LOG_PANIC_DIE, "Exim configuration file %s has the "
3395       "wrong owner, group, or mode", big_buffer);
3396   }
3397
3398 /* Process the main configuration settings. They all begin with a lower case
3399 letter. If we see something starting with an upper case letter, it is taken as
3400 a macro definition. */
3401
3402 while ((s = get_config_line()) != NULL)
3403   {
3404   if (isupper(s[0])) read_macro_assignment(s);
3405
3406   else if (Ustrncmp(s, "domainlist", 10) == 0)
3407     read_named_list(&domainlist_anchor, &domainlist_count,
3408       MAX_NAMED_LIST, s+10, US"domain list");
3409
3410   else if (Ustrncmp(s, "hostlist", 8) == 0)
3411     read_named_list(&hostlist_anchor, &hostlist_count,
3412       MAX_NAMED_LIST, s+8, US"host list");
3413
3414   else if (Ustrncmp(s, US"addresslist", 11) == 0)
3415     read_named_list(&addresslist_anchor, &addresslist_count,
3416       MAX_NAMED_LIST, s+11, US"address list");
3417
3418   else if (Ustrncmp(s, US"localpartlist", 13) == 0)
3419     read_named_list(&localpartlist_anchor, &localpartlist_count,
3420       MAX_NAMED_LIST, s+13, US"local part list");
3421
3422   else
3423     (void) readconf_handle_option(s, optionlist_config, optionlist_config_size,
3424       NULL, US"main option \"%s\" unknown");
3425   }
3426
3427
3428 /* If local_sender_retain is set, local_from_check must be unset. */
3429
3430 if (local_sender_retain && local_from_check)
3431   log_write(0, LOG_MAIN|LOG_PANIC_DIE, "both local_from_check and "
3432     "local_sender_retain are set; this combination is not allowed");
3433
3434 /* If the timezone string is empty, set it to NULL, implying no TZ variable
3435 wanted. */
3436
3437 if (timezone_string != NULL && *timezone_string == 0) timezone_string = NULL;
3438
3439 /* The max retry interval must not be greater than 24 hours. */
3440
3441 if (retry_interval_max > 24*60*60) retry_interval_max = 24*60*60;
3442
3443 /* remote_max_parallel must be > 0 */
3444
3445 if (remote_max_parallel <= 0) remote_max_parallel = 1;
3446
3447 /* Save the configured setting of freeze_tell, so we can re-instate it at the
3448 start of a new SMTP message. */
3449
3450 freeze_tell_config = freeze_tell;
3451
3452 /* The primary host name may be required for expansion of spool_directory
3453 and log_file_path, so make sure it is set asap. It is obtained from uname(),
3454 but if that yields an unqualified value, make a FQDN by using gethostbyname to
3455 canonize it. Some people like upper case letters in their host names, so we
3456 don't force the case. */
3457
3458 if (primary_hostname == NULL)
3459   {
3460   const uschar *hostname;
3461   struct utsname uts;
3462   if (uname(&uts) < 0)
3463     log_write(0, LOG_MAIN|LOG_PANIC_DIE, "uname() failed to yield host name");
3464   hostname = US uts.nodename;
3465
3466   if (Ustrchr(hostname, '.') == NULL)
3467     {
3468     int af = AF_INET;
3469     struct hostent *hostdata;
3470
3471     #if HAVE_IPV6
3472     if (!disable_ipv6 && (dns_ipv4_lookup == NULL ||
3473          match_isinlist(hostname, CUSS &dns_ipv4_lookup, 0, NULL, NULL,
3474             MCL_DOMAIN, TRUE, NULL) != OK))
3475       af = AF_INET6;
3476     #else
3477     af = AF_INET;
3478     #endif
3479
3480     for (;;)
3481       {
3482       #if HAVE_IPV6
3483         #if HAVE_GETIPNODEBYNAME
3484         int error_num;
3485         hostdata = getipnodebyname(CS hostname, af, 0, &error_num);
3486         #else
3487         hostdata = gethostbyname2(CS hostname, af);
3488         #endif
3489       #else
3490       hostdata = gethostbyname(CS hostname);
3491       #endif
3492
3493       if (hostdata != NULL)
3494         {
3495         hostname = US hostdata->h_name;
3496         break;
3497         }
3498
3499       if (af == AF_INET) break;
3500       af = AF_INET;
3501       }
3502     }
3503
3504   primary_hostname = string_copy(hostname);
3505   }
3506
3507 /* Set up default value for smtp_active_hostname */
3508
3509 smtp_active_hostname = primary_hostname;
3510
3511 /* If spool_directory wasn't set in the build-time configuration, it must have
3512 got set above. Of course, writing to the log may not work if log_file_path is
3513 not set, but it will at least get to syslog or somewhere, with any luck. */
3514
3515 if (*spool_directory == 0)
3516   log_write(0, LOG_MAIN|LOG_PANIC_DIE, "spool_directory undefined: cannot "
3517     "proceed");
3518
3519 /* Expand the spool directory name; it may, for example, contain the primary
3520 host name. Same comment about failure. */
3521
3522 s = expand_string(spool_directory);
3523 if (s == NULL)
3524   log_write(0, LOG_MAIN|LOG_PANIC_DIE, "failed to expand spool_directory "
3525     "\"%s\": %s", spool_directory, expand_string_message);
3526 spool_directory = s;
3527
3528 /* Expand log_file_path, which must contain "%s" in any component that isn't
3529 the null string or "syslog". It is also allowed to contain one instance of %D
3530 or %M. However, it must NOT contain % followed by anything else. */
3531
3532 if (*log_file_path != 0)
3533   {
3534   const uschar *ss, *sss;
3535   int sep = ':';                       /* Fixed for log file path */
3536   s = expand_string(log_file_path);
3537   if (s == NULL)
3538     log_write(0, LOG_MAIN|LOG_PANIC_DIE, "failed to expand log_file_path "
3539       "\"%s\": %s", log_file_path, expand_string_message);
3540
3541   ss = s;
3542   while ((sss = string_nextinlist(&ss,&sep,big_buffer,big_buffer_size)) != NULL)
3543     {
3544     uschar *t;
3545     if (sss[0] == 0 || Ustrcmp(sss, "syslog") == 0) continue;
3546     t = Ustrstr(sss, "%s");
3547     if (t == NULL)
3548       log_write(0, LOG_MAIN|LOG_PANIC_DIE, "log_file_path \"%s\" does not "
3549         "contain \"%%s\"", sss);
3550     *t = 'X';
3551     t = Ustrchr(sss, '%');
3552     if (t != NULL)
3553       {
3554       if ((t[1] != 'D' && t[1] != 'M') || Ustrchr(t+2, '%') != NULL)
3555         log_write(0, LOG_MAIN|LOG_PANIC_DIE, "log_file_path \"%s\" contains "
3556           "unexpected \"%%\" character", s);
3557       }
3558     }
3559
3560   log_file_path = s;
3561   }
3562
3563 /* Interpret syslog_facility into an integer argument for 'ident' param to
3564 openlog(). Default is LOG_MAIL set in globals.c. Allow the user to omit the
3565 leading "log_". */
3566
3567 if (syslog_facility_str != NULL)
3568   {
3569   int i;
3570   uschar *s = syslog_facility_str;
3571
3572   if ((Ustrlen(syslog_facility_str) >= 4) &&
3573         (strncmpic(syslog_facility_str, US"log_", 4) == 0))
3574     s += 4;
3575
3576   for (i = 0; i < syslog_list_size; i++)
3577     {
3578     if (strcmpic(s, syslog_list[i].name) == 0)
3579       {
3580       syslog_facility = syslog_list[i].value;
3581       break;
3582       }
3583     }
3584
3585   if (i >= syslog_list_size)
3586     {
3587     log_write(0, LOG_PANIC_DIE|LOG_CONFIG,
3588       "failed to interpret syslog_facility \"%s\"", syslog_facility_str);
3589     }
3590   }
3591
3592 /* Expand pid_file_path */
3593
3594 if (*pid_file_path != 0)
3595   {
3596   s = expand_string(pid_file_path);
3597   if (s == NULL)
3598     log_write(0, LOG_MAIN|LOG_PANIC_DIE, "failed to expand pid_file_path "
3599       "\"%s\": %s", pid_file_path, expand_string_message);
3600   pid_file_path = s;
3601   }
3602
3603 /* Set default value of process_log_path */
3604
3605 if (process_log_path == NULL || *process_log_path =='\0')
3606   process_log_path = string_sprintf("%s/exim-process.info", spool_directory);
3607
3608 /* Compile the regex for matching a UUCP-style "From_" line in an incoming
3609 message. */
3610
3611 regex_From = regex_must_compile(uucp_from_pattern, FALSE, TRUE);
3612
3613 /* Unpick the SMTP rate limiting options, if set */
3614
3615 if (smtp_ratelimit_mail != NULL)
3616   {
3617   unpick_ratelimit(smtp_ratelimit_mail, &smtp_rlm_threshold,
3618     &smtp_rlm_base, &smtp_rlm_factor, &smtp_rlm_limit);
3619   }
3620
3621 if (smtp_ratelimit_rcpt != NULL)
3622   {
3623   unpick_ratelimit(smtp_ratelimit_rcpt, &smtp_rlr_threshold,
3624     &smtp_rlr_base, &smtp_rlr_factor, &smtp_rlr_limit);
3625   }
3626
3627 /* The qualify domains default to the primary host name */
3628
3629 if (qualify_domain_sender == NULL)
3630   qualify_domain_sender = primary_hostname;
3631 if (qualify_domain_recipient == NULL)
3632   qualify_domain_recipient = qualify_domain_sender;
3633
3634 /* Setting system_filter_user in the configuration sets the gid as well if a
3635 name is given, but a numerical value does not. */
3636
3637 if (system_filter_uid_set && !system_filter_gid_set)
3638   {
3639   struct passwd *pw = getpwuid(system_filter_uid);
3640   if (pw == NULL)
3641     log_write(0, LOG_MAIN|LOG_PANIC_DIE, "Failed to look up uid %ld",
3642       (long int)system_filter_uid);
3643   system_filter_gid = pw->pw_gid;
3644   system_filter_gid_set = TRUE;
3645   }
3646
3647 /* If the errors_reply_to field is set, check that it is syntactically valid
3648 and ensure it contains a domain. */
3649
3650 if (errors_reply_to != NULL)
3651   {
3652   uschar *errmess;
3653   int start, end, domain;
3654   uschar *recipient = parse_extract_address(errors_reply_to, &errmess,
3655     &start, &end, &domain, FALSE);
3656
3657   if (recipient == NULL)
3658     log_write(0, LOG_PANIC_DIE|LOG_CONFIG,
3659       "error in errors_reply_to (%s): %s", errors_reply_to, errmess);
3660
3661   if (domain == 0)
3662     log_write(0, LOG_PANIC_DIE|LOG_CONFIG,
3663       "errors_reply_to (%s) does not contain a domain", errors_reply_to);
3664   }
3665
3666 /* If smtp_accept_queue or smtp_accept_max_per_host is set, then
3667 smtp_accept_max must also be set. */
3668
3669 if (smtp_accept_max == 0 &&
3670     (smtp_accept_queue > 0 || smtp_accept_max_per_host != NULL))
3671   log_write(0, LOG_PANIC_DIE|LOG_CONFIG,
3672     "smtp_accept_max must be set if smtp_accept_queue or "
3673     "smtp_accept_max_per_host is set");
3674
3675 /* Set up the host number if anything is specified. It is an expanded string
3676 so that it can be computed from the host name, for example. We do this last
3677 so as to ensure that everything else is set up before the expansion. */
3678
3679 if (host_number_string != NULL)
3680   {
3681   long int n;
3682   uschar *end;
3683   uschar *s = expand_string(host_number_string);
3684   if (s == NULL)
3685     log_write(0, LOG_MAIN|LOG_PANIC_DIE,
3686         "failed to expand localhost_number \"%s\": %s",
3687         host_number_string, expand_string_message);
3688   n = Ustrtol(s, &end, 0);
3689   while (isspace(*end)) end++;
3690   if (*end != 0)
3691     log_write(0, LOG_PANIC_DIE|LOG_CONFIG,
3692       "localhost_number value is not a number: %s", s);
3693   if (n > LOCALHOST_MAX)
3694     log_write(0, LOG_PANIC_DIE|LOG_CONFIG,
3695       "localhost_number is greater than the maximum allowed value (%d)",
3696         LOCALHOST_MAX);
3697   host_number = n;
3698   }
3699
3700 #ifdef SUPPORT_TLS
3701 /* If tls_verify_hosts is set, tls_verify_certificates must also be set */
3702
3703 if ((tls_verify_hosts != NULL || tls_try_verify_hosts != NULL) &&
3704      tls_verify_certificates == NULL)
3705   log_write(0, LOG_PANIC_DIE|LOG_CONFIG,
3706     "tls_%sverify_hosts is set, but tls_verify_certificates is not set",
3707     (tls_verify_hosts != NULL)? "" : "try_");
3708
3709 /* This also checks that the library linkage is working and we can call
3710 routines in it, so call even if tls_require_ciphers is unset */
3711 if (!tls_dropprivs_validate_require_cipher(nowarn))
3712   exit(1);
3713
3714 /* Magic number: at time of writing, 1024 has been the long-standing value
3715 used by so many clients, and what Exim used to use always, that it makes
3716 sense to just min-clamp this max-clamp at that. */
3717 if (tls_dh_max_bits < 1024)
3718   log_write(0, LOG_PANIC_DIE|LOG_CONFIG,
3719       "tls_dh_max_bits is too small, must be at least 1024 for interop");
3720
3721 /* If openssl_options is set, validate it */
3722 if (openssl_options != NULL)
3723   {
3724 # ifdef USE_GNUTLS
3725   log_write(0, LOG_PANIC_DIE|LOG_CONFIG,
3726     "openssl_options is set but we're using GnuTLS");
3727 # else
3728   long dummy;
3729   if (!(tls_openssl_options_parse(openssl_options, &dummy)))
3730     log_write(0, LOG_PANIC_DIE|LOG_CONFIG,
3731       "openssl_options parse error: %s", openssl_options);
3732 # endif
3733   }
3734 #endif  /*SUPPORT_TLS*/
3735
3736 if (!nowarn && !keep_environment && environ && *environ)
3737   log_write(0, LOG_MAIN,
3738       "Warning: purging the environment.\n"
3739       " Suggested action: use keep_environment.");
3740 }
3741
3742
3743
3744 /*************************************************
3745 *          Initialize one driver                 *
3746 *************************************************/
3747
3748 /* This is called once the driver's generic options, if any, have been read.
3749 We can now find the driver, set up defaults for the private options, and
3750 unset any "set" bits in the private options table (which might have been
3751 set by another incarnation of the same driver).
3752
3753 Arguments:
3754   d                   pointer to driver instance block, with generic
3755                         options filled in
3756   drivers_available   vector of available drivers
3757   size_of_info        size of each block in drivers_available
3758   class               class of driver, for error message
3759
3760 Returns:              pointer to the driver info block
3761 */
3762
3763 static driver_info *
3764 init_driver(driver_instance *d, driver_info *drivers_available,
3765   int size_of_info, uschar *class)
3766 {
3767 driver_info *dd;
3768
3769 for (dd = drivers_available; dd->driver_name[0] != 0;
3770      dd = (driver_info *)(((uschar *)dd) + size_of_info))
3771   {
3772   if (Ustrcmp(d->driver_name, dd->driver_name) == 0)
3773     {
3774     int i;
3775     int len = dd->options_len;
3776     d->info = dd;
3777     d->options_block = store_get(len);
3778     memcpy(d->options_block, dd->options_block, len);
3779     for (i = 0; i < *(dd->options_count); i++)
3780       dd->options[i].type &= ~opt_set;
3781     return dd;
3782     }
3783   }
3784
3785 log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN,
3786   "%s %s: cannot find %s driver \"%s\"", class, d->name, class, d->driver_name);
3787
3788 return NULL;   /* never obeyed */
3789 }
3790
3791
3792
3793
3794 /*************************************************
3795 *             Initialize driver list             *
3796 *************************************************/
3797
3798 /* This function is called for routers, transports, and authentication
3799 mechanisms. It reads the data from the current point in the configuration file
3800 up to the end of the section, and sets up a chain of instance blocks according
3801 to the file's contents. The file will already have been opened by a call to
3802 readconf_main, and must be left open for subsequent reading of further data.
3803
3804 Any errors cause a panic crash. Note that the blocks with names driver_info and
3805 driver_instance must map the first portions of all the _info and _instance
3806 blocks for this shared code to work.
3807
3808 Arguments:
3809   class                      "router", "transport", or "authenticator"
3810   anchor                     &routers, &transports, &auths
3811   drivers_available          available drivers
3812   size_of_info               size of each info block
3813   instance_default           points to default data for an instance
3814   instance_size              size of instance block
3815   driver_optionlist          generic option list
3816   driver_optionlist_count    count of generic option list
3817
3818 Returns:                     nothing
3819 */
3820
3821 void
3822 readconf_driver_init(
3823   uschar *class,
3824   driver_instance **anchor,
3825   driver_info *drivers_available,
3826   int size_of_info,
3827   void *instance_default,
3828   int  instance_size,
3829   optionlist *driver_optionlist,
3830   int  driver_optionlist_count)
3831 {
3832 driver_instance **p = anchor;
3833 driver_instance *d = NULL;
3834 uschar *buffer;
3835
3836 while ((buffer = get_config_line()) != NULL)
3837   {
3838   uschar name[64];
3839   uschar *s;
3840
3841   /* Read the first name on the line and test for the start of a new driver. A
3842   macro definition indicates the end of the previous driver. If this isn't the
3843   start of a new driver, the line will be re-read. */
3844
3845   s = readconf_readname(name, sizeof(name), buffer);
3846
3847   /* Handle macro definition, first finishing off the initialization of the
3848   previous driver, if any. */
3849
3850   if (isupper(*name) && *s == '=')
3851     {
3852     if (d)
3853       {
3854       if (!d->driver_name)
3855         log_write(0, LOG_PANIC_DIE|LOG_CONFIG,
3856           "no driver defined for %s \"%s\"", class, d->name);
3857       (d->info->init)(d);
3858       d = NULL;
3859       }
3860     read_macro_assignment(buffer);
3861     continue;
3862     }
3863
3864   /* If the line starts with a name terminated by a colon, we are at the
3865   start of the definition of a new driver. The rest of the line must be
3866   blank. */
3867
3868   if (*s++ == ':')
3869     {
3870     int i;
3871
3872     /* Finish off initializing the previous driver. */
3873
3874     if (d)
3875       {
3876       if (!d->driver_name)
3877         log_write(0, LOG_PANIC_DIE|LOG_CONFIG,
3878           "no driver defined for %s \"%s\"", class, d->name);
3879       (d->info->init)(d);
3880       }
3881
3882     /* Check that we haven't already got a driver of this name */
3883
3884     for (d = *anchor; d; d = d->next)
3885       if (Ustrcmp(name, d->name) == 0)
3886         log_write(0, LOG_PANIC_DIE|LOG_CONFIG,
3887           "there are two %ss called \"%s\"", class, name);
3888
3889     /* Set up a new driver instance data block on the chain, with
3890     its default values installed. */
3891
3892     d = store_get(instance_size);
3893     memcpy(d, instance_default, instance_size);
3894     *p = d;
3895     p = &d->next;
3896     d->name = string_copy(name);
3897
3898     /* Clear out the "set" bits in the generic options */
3899
3900     for (i = 0; i < driver_optionlist_count; i++)
3901       driver_optionlist[i].type &= ~opt_set;
3902
3903     /* Check nothing more on this line, then do the next loop iteration. */
3904
3905     while (isspace(*s)) s++;
3906     if (*s != 0) extra_chars_error(s, US"driver name ", name, US"");
3907     continue;
3908     }
3909
3910   /* Not the start of a new driver. Give an error if we have not set up a
3911   current driver yet. */
3912
3913   if (!d)
3914     log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, "%s name missing", class);
3915
3916   /* First look to see if this is a generic option; if it is "driver",
3917   initialize the driver. If is it not a generic option, we can look for a
3918   private option provided that the driver has been previously set up. */
3919
3920   if (readconf_handle_option(buffer, driver_optionlist,
3921         driver_optionlist_count, d, NULL))
3922     {
3923     if (!d->info && d->driver_name)
3924       init_driver(d, drivers_available, size_of_info, class);
3925     }
3926
3927   /* Handle private options - pass the generic block because some may
3928   live therein. A flag with each option indicates if it is in the public
3929   block. */
3930
3931   else if (d->info)
3932     readconf_handle_option(buffer, d->info->options,
3933       *(d->info->options_count), d, US"option \"%s\" unknown");
3934
3935   /* The option is not generic and the driver name has not yet been given. */
3936
3937   else log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, "option \"%s\" unknown "
3938     "(\"driver\" must be specified before any private options)", name);
3939   }
3940
3941 /* Run the initialization function for the final driver. */
3942
3943 if (d)
3944   {
3945   if (!d->driver_name)
3946     log_write(0, LOG_PANIC_DIE|LOG_CONFIG,
3947       "no driver defined for %s \"%s\"", class, d->name);
3948   (d->info->init)(d);
3949   }
3950 }
3951
3952
3953
3954 /*************************************************
3955 *            Check driver dependency             *
3956 *************************************************/
3957
3958 /* This function is passed a driver instance and a string. It checks whether
3959 any of the string options for the driver contains the given string as an
3960 expansion variable.
3961
3962 Arguments:
3963   d        points to a driver instance block
3964   s        the string to search for
3965
3966 Returns:   TRUE if a dependency is found
3967 */
3968
3969 BOOL
3970 readconf_depends(driver_instance *d, uschar *s)
3971 {
3972 int count = *(d->info->options_count);
3973 optionlist *ol;
3974 uschar *ss;
3975
3976 for (ol = d->info->options; ol < d->info->options + count; ol++)
3977   {
3978   void *options_block;
3979   uschar *value;
3980   int type = ol->type & opt_mask;
3981   if (type != opt_stringptr) continue;
3982   options_block = ((ol->type & opt_public) == 0)? d->options_block : (void *)d;
3983   value = *(uschar **)((uschar *)options_block + (long int)(ol->value));
3984   if (value != NULL && (ss = Ustrstr(value, s)) != NULL)
3985     {
3986     if (ss <= value || (ss[-1] != '$' && ss[-1] != '{') ||
3987       isalnum(ss[Ustrlen(s)])) continue;
3988     DEBUG(D_transport) debug_printf("driver %s: \"%s\" option depends on %s\n",
3989       d->name, ol->name, s);
3990     return TRUE;
3991     }
3992   }
3993
3994 DEBUG(D_transport) debug_printf("driver %s does not depend on %s\n", d->name, s);
3995 return FALSE;
3996 }
3997
3998
3999
4000
4001 /*************************************************
4002 *      Decode an error type for retries          *
4003 *************************************************/
4004
4005 /* This function is global because it is also called from the main
4006 program when testing retry information. It decodes strings such as "quota_7d"
4007 into numerical error codes.
4008
4009 Arguments:
4010   pp           points to start of text
4011   p            points past end of text
4012   basic_errno  points to an int to receive the main error number
4013   more_errno   points to an int to receive the secondary error data
4014
4015 Returns:       NULL if decoded correctly; else points to error text
4016 */
4017
4018 uschar *
4019 readconf_retry_error(const uschar *pp, const uschar *p,
4020   int *basic_errno, int *more_errno)
4021 {
4022 int len;
4023 const uschar *q = pp;
4024 while (q < p && *q != '_') q++;
4025 len = q - pp;
4026
4027 if (len == 5 && strncmpic(pp, US"quota", len) == 0)
4028   {
4029   *basic_errno = ERRNO_EXIMQUOTA;
4030   if (q != p && (*more_errno = readconf_readtime(q+1, *p, FALSE)) < 0)
4031       return US"bad time value";
4032   }
4033
4034 else if (len == 7 && strncmpic(pp, US"refused", len) == 0)
4035   {
4036   *basic_errno = ECONNREFUSED;
4037   if (q != p)
4038     {
4039     if (strncmpic(q+1, US"MX", p-q-1) == 0) *more_errno = 'M';
4040     else if (strncmpic(q+1, US"A", p-q-1) == 0) *more_errno = 'A';
4041     else return US"A or MX expected after \"refused\"";
4042     }
4043   }
4044
4045 else if (len == 7 && strncmpic(pp, US"timeout", len) == 0)
4046   {
4047   *basic_errno = ETIMEDOUT;
4048   if (q != p)
4049     {
4050     int i;
4051     int xlen = p - q - 1;
4052     const uschar *x = q + 1;
4053
4054     static uschar *extras[] =
4055       { US"A", US"MX", US"connect", US"connect_A",  US"connect_MX" };
4056     static int values[] =
4057       { 'A',   'M',    RTEF_CTOUT,  RTEF_CTOUT|'A', RTEF_CTOUT|'M' };
4058
4059     for (i = 0; i < sizeof(extras)/sizeof(uschar *); i++)
4060       if (strncmpic(x, extras[i], xlen) == 0)
4061         {
4062         *more_errno = values[i];
4063         break;
4064         }
4065
4066     if (i >= sizeof(extras)/sizeof(uschar *))
4067       if (strncmpic(x, US"DNS", xlen) == 0)
4068         log_write(0, LOG_MAIN|LOG_PANIC, "\"timeout_dns\" is no longer "
4069           "available in retry rules (it has never worked) - treated as "
4070           "\"timeout\"");
4071       else
4072         return US"\"A\", \"MX\", or \"connect\" expected after \"timeout\"";
4073     }
4074   }
4075
4076 else if (strncmpic(pp, US"mail_4", 6) == 0 ||
4077          strncmpic(pp, US"rcpt_4", 6) == 0 ||
4078          strncmpic(pp, US"data_4", 6) == 0)
4079   {
4080   BOOL bad = FALSE;
4081   int x = 255;                           /* means "any 4xx code" */
4082   if (p != pp + 8) bad = TRUE; else
4083     {
4084     int a = pp[6], b = pp[7];
4085     if (isdigit(a))
4086       {
4087       x = (a - '0') * 10;
4088       if (isdigit(b)) x += b - '0';
4089       else if (b == 'x') x += 100;
4090       else bad = TRUE;
4091       }
4092     else if (a != 'x' || b != 'x') bad = TRUE;
4093     }
4094
4095   if (bad)
4096     return string_sprintf("%.4s_4 must be followed by xx, dx, or dd, where "
4097       "x is literal and d is any digit", pp);
4098
4099   *basic_errno = *pp == 'm' ? ERRNO_MAIL4XX :
4100                  *pp == 'r' ? ERRNO_RCPT4XX : ERRNO_DATA4XX;
4101   *more_errno = x << 8;
4102   }
4103
4104 else if (len == 4 && strncmpic(pp, US"auth", len) == 0 &&
4105          strncmpic(q+1, US"failed", p-q-1) == 0)
4106   *basic_errno = ERRNO_AUTHFAIL;
4107
4108 else if (strncmpic(pp, US"lost_connection", p - pp) == 0)
4109   *basic_errno = ERRNO_SMTPCLOSED;
4110
4111 else if (strncmpic(pp, US"tls_required", p - pp) == 0)
4112   *basic_errno = ERRNO_TLSREQUIRED;
4113
4114 else if (strncmpic(pp, US"lookup", p - pp) == 0)
4115   *basic_errno = ERRNO_UNKNOWNHOST;
4116
4117 else if (len != 1 || Ustrncmp(pp, "*", 1) != 0)
4118   return string_sprintf("unknown or malformed retry error \"%.*s\"", (int) (p-pp), pp);
4119
4120 return NULL;
4121 }
4122
4123
4124
4125
4126 /*************************************************
4127 *                Read retry information          *
4128 *************************************************/
4129
4130 /* Each line of retry information contains:
4131
4132 .  A domain name pattern or an address pattern;
4133
4134 .  An error name, possibly with additional data, or *;
4135
4136 .  An optional sequence of retry items, each consisting of an identifying
4137    letter, a cutoff time, and optional parameters.
4138
4139 All this is decoded and placed into a control block. */
4140
4141
4142 /* Subroutine to read an argument, preceded by a comma and terminated
4143 by comma, semicolon, whitespace, or newline. The types are: 0 = time value,
4144 1 = fixed point number (returned *1000).
4145
4146 Arguments:
4147   paddr     pointer to pointer to current character; updated
4148   type      0 => read a time; 1 => read a fixed point number
4149
4150 Returns:    time in seconds or fixed point number * 1000
4151 */
4152
4153 static int
4154 retry_arg(const uschar **paddr, int type)
4155 {
4156 const uschar *p = *paddr;
4157 const uschar *pp;
4158
4159 if (*p++ != ',') log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, "comma expected");
4160
4161 while (isspace(*p)) p++;
4162 pp = p;
4163 while (isalnum(*p) || (type == 1 && *p == '.')) p++;
4164
4165 if (*p != 0 && !isspace(*p) && *p != ',' && *p != ';')
4166   log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, "comma or semicolon expected");
4167
4168 *paddr = p;
4169 switch (type)
4170   {
4171   case 0: return readconf_readtime(pp, *p, FALSE);
4172   case 1: return readconf_readfixed(pp, *p);
4173   }
4174 return 0;    /* Keep picky compilers happy */
4175 }
4176
4177 /* The function proper */
4178
4179 void
4180 readconf_retries(void)
4181 {
4182 retry_config **chain = &retries;
4183 retry_config *next;
4184 const uschar *p;
4185
4186 while ((p = get_config_line()))
4187   {
4188   retry_rule **rchain;
4189   const uschar *pp;
4190   uschar *error;
4191
4192   next = store_get(sizeof(retry_config));
4193   next->next = NULL;
4194   *chain = next;
4195   chain = &(next->next);
4196   next->basic_errno = next->more_errno = 0;
4197   next->senders = NULL;
4198   next->rules = NULL;
4199   rchain = &(next->rules);
4200
4201   next->pattern = string_dequote(&p);
4202   while (isspace(*p)) p++;
4203   pp = p;
4204   while (mac_isgraph(*p)) p++;
4205   if (p - pp <= 0) log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN,
4206     "missing error type in retry rule");
4207
4208   /* Test error names for things we understand. */
4209
4210   if ((error = readconf_retry_error(pp, p, &next->basic_errno,
4211        &next->more_errno)))
4212     log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, "%s", error);
4213
4214   /* There may be an optional address list of senders to be used as another
4215   constraint on the rule. This was added later, so the syntax is a bit of a
4216   fudge. Anything that is not a retry rule starting "F," or "G," is treated as
4217   an address list. */
4218
4219   while (isspace(*p)) p++;
4220   if (Ustrncmp(p, "senders", 7) == 0)
4221     {
4222     p += 7;
4223     while (isspace(*p)) p++;
4224     if (*p++ != '=') log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN,
4225       "\"=\" expected after \"senders\" in retry rule");
4226     while (isspace(*p)) p++;
4227     next->senders = string_dequote(&p);
4228     }
4229
4230   /* Now the retry rules. Keep the maximum timeout encountered. */
4231
4232   while (isspace(*p)) p++;
4233
4234   while (*p != 0)
4235     {
4236     retry_rule *rule = store_get(sizeof(retry_rule));
4237     *rchain = rule;
4238     rchain = &(rule->next);
4239     rule->next = NULL;
4240     rule->rule = toupper(*p++);
4241     rule->timeout = retry_arg(&p, 0);
4242     if (rule->timeout > retry_maximum_timeout)
4243       retry_maximum_timeout = rule->timeout;
4244
4245     switch (rule->rule)
4246       {
4247       case 'F':   /* Fixed interval */
4248         rule->p1 = retry_arg(&p, 0);
4249         break;
4250
4251       case 'G':   /* Geometrically increasing intervals */
4252       case 'H':   /* Ditto, but with randomness */
4253         rule->p1 = retry_arg(&p, 0);
4254         rule->p2 = retry_arg(&p, 1);
4255         break;
4256
4257       default:
4258         log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, "unknown retry rule letter");
4259         break;
4260       }
4261
4262     if (rule->timeout <= 0 || rule->p1 <= 0 ||
4263           (rule->rule != 'F' && rule->p2 < 1000))
4264       log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN,
4265         "bad parameters for retry rule");
4266
4267     while (isspace(*p)) p++;
4268     if (*p == ';')
4269       {
4270       p++;
4271       while (isspace(*p)) p++;
4272       }
4273     else if (*p != 0)
4274       log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, "semicolon expected");
4275     }
4276   }
4277 }
4278
4279
4280
4281 /*************************************************
4282 *         Initialize authenticators              *
4283 *************************************************/
4284
4285 /* Read the authenticators section of the configuration file.
4286
4287 Arguments:   none
4288 Returns:     nothing
4289 */
4290
4291 static void
4292 auths_init(void)
4293 {
4294 auth_instance *au, *bu;
4295 readconf_driver_init(US"authenticator",
4296   (driver_instance **)(&auths),      /* chain anchor */
4297   (driver_info *)auths_available,    /* available drivers */
4298   sizeof(auth_info),                 /* size of info block */
4299   &auth_defaults,                    /* default values for generic options */
4300   sizeof(auth_instance),             /* size of instance block */
4301   optionlist_auths,                  /* generic options */
4302   optionlist_auths_size);
4303
4304 for (au = auths; au; au = au->next)
4305   {
4306   if (!au->public_name)
4307     log_write(0, LOG_PANIC_DIE|LOG_CONFIG, "no public name specified for "
4308       "the %s authenticator", au->name);
4309
4310   for (bu = au->next; bu; bu = bu->next)
4311     if (strcmpic(au->public_name, bu->public_name) == 0)
4312       if ((au->client && bu->client) || (au->server && bu->server))
4313         log_write(0, LOG_PANIC_DIE|LOG_CONFIG, "two %s authenticators "
4314           "(%s and %s) have the same public name (%s)",
4315           au->client ? US"client" : US"server", au->name, bu->name,
4316           au->public_name);
4317   }
4318 }
4319
4320
4321
4322
4323 /*************************************************
4324 *             Read ACL information               *
4325 *************************************************/
4326
4327 /* If this run of Exim is not doing something that involves receiving a
4328 message, we can just skip over the ACL information. No need to parse it.
4329
4330 First, we have a function for acl_read() to call back to get the next line. We
4331 need to remember the line we passed, because at the end it will contain the
4332 name of the next ACL. */
4333
4334 static uschar *acl_line;
4335
4336 static uschar *
4337 acl_callback(void)
4338 {
4339 acl_line = get_config_line();
4340 return acl_line;
4341 }
4342
4343
4344 /* Now the main function:
4345
4346 Arguments:    none
4347 Returns:      nothing
4348 */
4349
4350 static void
4351 readconf_acl(void)
4352 {
4353 uschar *p;
4354
4355 /* Read each ACL and add it into the tree. Macro (re)definitions are allowed
4356 between ACLs. */
4357
4358 acl_line = get_config_line();
4359
4360 while(acl_line != NULL)
4361   {
4362   uschar name[64];
4363   tree_node *node;
4364   uschar *error;
4365
4366   p = readconf_readname(name, sizeof(name), acl_line);
4367   if (isupper(*name) && *p == '=')
4368     {
4369     read_macro_assignment(acl_line);
4370     acl_line = get_config_line();
4371     continue;
4372     }
4373
4374   if (*p != ':' || name[0] == 0)
4375     log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, "missing or malformed ACL name");
4376
4377   node = store_get(sizeof(tree_node) + Ustrlen(name));
4378   Ustrcpy(node->name, name);
4379   if (!tree_insertnode(&acl_anchor, node))
4380     log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN,
4381       "there are two ACLs called \"%s\"", name);
4382
4383   node->data.ptr = acl_read(acl_callback, &error);
4384
4385   if (node->data.ptr == NULL && error != NULL)
4386     log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, "error in ACL: %s", error);
4387   }
4388 }
4389
4390
4391
4392 /*************************************************
4393 *     Read configuration for local_scan()        *
4394 *************************************************/
4395
4396 /* This function is called after "begin local_scan" is encountered in the
4397 configuration file. If the local_scan() function allows for configuration
4398 options, we can process them. Otherwise, we expire in a panic.
4399
4400 Arguments:  none
4401 Returns:    nothing
4402 */
4403
4404 static void
4405 local_scan_init(void)
4406 {
4407 #ifndef LOCAL_SCAN_HAS_OPTIONS
4408 log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, "local_scan() options not supported: "
4409   "(LOCAL_SCAN_HAS_OPTIONS not defined in Local/Makefile)");
4410 #else
4411
4412 uschar *p;
4413 while ((p = get_config_line()) != NULL)
4414   {
4415   (void) readconf_handle_option(p, local_scan_options, local_scan_options_count,
4416     NULL, US"local_scan option \"%s\" unknown");
4417   }
4418 #endif
4419 }
4420
4421
4422
4423 /*************************************************
4424 *     Read rest of configuration (after main)    *
4425 *************************************************/
4426
4427 /* This function reads the rest of the runtime configuration, after the main
4428 configuration. It is called only when actually needed. Each subsequent section
4429 of the configuration starts with a line of the form
4430
4431   begin name
4432
4433 where the name is "routers", "transports", etc. A section is terminated by
4434 hitting the next "begin" line, and the next name is left in next_section.
4435 Because it may confuse people as to whether the names are singular or plural,
4436 we add "s" if it's missing. There is always enough room in next_section for
4437 this. This function is basically just a switch.
4438
4439 Arguments:   none
4440 Returns:     nothing
4441 */
4442
4443 static uschar *section_list[] = {
4444   US"acls",
4445   US"authenticators",
4446   US"local_scans",
4447   US"retrys",
4448   US"rewrites",
4449   US"routers",
4450   US"transports"};
4451
4452 void
4453 readconf_rest(void)
4454 {
4455 int had = 0;
4456
4457 while(next_section[0] != 0)
4458   {
4459   int bit;
4460   int first = 0;
4461   int last = sizeof(section_list) / sizeof(uschar *);
4462   int mid = last/2;
4463   int n = Ustrlen(next_section);
4464
4465   if (tolower(next_section[n-1]) != 's') Ustrcpy(next_section+n, "s");
4466
4467   for (;;)
4468     {
4469     int c = strcmpic(next_section, section_list[mid]);
4470     if (c == 0) break;
4471     if (c > 0) first = mid + 1; else last = mid;
4472     if (first >= last)
4473       log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN,
4474         "\"%.*s\" is not a known configuration section name", n, next_section);
4475     mid = (last + first)/2;
4476     }
4477
4478   bit = 1 << mid;
4479   if (((had ^= bit) & bit) == 0)
4480     log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN,
4481       "\"%.*s\" section is repeated in the configuration file", n,
4482         next_section);
4483
4484   switch(mid)
4485     {
4486     case 0: readconf_acl(); break;
4487     case 1: auths_init(); break;
4488     case 2: local_scan_init(); break;
4489     case 3: readconf_retries(); break;
4490     case 4: readconf_rewrites(); break;
4491     case 5: route_init(); break;
4492     case 6: transport_init(); break;
4493     }
4494   }
4495
4496 (void)fclose(config_file);
4497 }
4498
4499 /* Init the storage for the pre-parsed config lines */
4500 void
4501 readconf_save_config(const uschar *s)
4502 {
4503   save_config_line(string_sprintf("# Exim Configuration (%s)",
4504     running_in_test_harness ? US"X" : s));
4505 }
4506
4507 static void
4508 save_config_position(const uschar *file, int line)
4509 {
4510   save_config_line(string_sprintf("# %d \"%s\"", line, file));
4511 }
4512
4513 /* Append a pre-parsed logical line to the config lines store,
4514 this operates on a global (static) list that holds all the pre-parsed
4515 config lines, we do no further processing here, output formatting and
4516 honouring of <hide> or macros will be done during output */
4517 static void
4518 save_config_line(const uschar* line)
4519 {
4520 static config_line_item *current;
4521 config_line_item *next;
4522
4523 next = (config_line_item*) store_get(sizeof(config_line_item));
4524 next->line = string_copy(line);
4525 next->next = NULL;
4526
4527 if (!config_lines) config_lines = next;
4528 else current->next = next;
4529
4530 current = next;
4531 }
4532
4533 /* List the parsed config lines, care about nice formatting and
4534 hide the <hide> values unless we're the admin user */
4535 void
4536 print_config(BOOL admin, BOOL terse)
4537 {
4538 config_line_item *i;
4539 const int TS = terse ? 0 : 2;
4540 int indent = 0;
4541
4542 for (i = config_lines; i; i = i->next)
4543   {
4544   uschar *current;
4545   uschar *p;
4546
4547   /* skip over to the first non-space */
4548   for (current = i->line; *current && isspace(*current); ++current)
4549     ;
4550
4551   if (*current == '\0')
4552     continue;
4553
4554   /* Collapse runs of spaces. We stop this if we encounter one of the
4555    * following characters: "'$, as this may indicate careful formatting */
4556   for (p = current; *p; ++p)
4557     {
4558     uschar *next;
4559     if (!isspace(*p)) continue;
4560     if (*p != ' ') *p = ' ';
4561
4562     for (next = p; isspace(*next); ++next)
4563       ;
4564
4565     if (next - p > 1)
4566       memmove(p+1, next, Ustrlen(next)+1);
4567
4568     if (*next == '"' || *next == '\'' || *next == '$')
4569       break;
4570     }
4571
4572   /* # lines */
4573   if (current[0] == '#')
4574     puts(CCS current);
4575
4576   /* begin lines are left aligned */
4577   else if (Ustrncmp(current, "begin", 5) == 0 && isspace(current[5]))
4578     {
4579     if (!terse) puts("");
4580     puts(CCS current);
4581     indent = TS;
4582     }
4583
4584   /* router/acl/transport block names */
4585   else if (current[Ustrlen(current)-1] == ':' && !Ustrchr(current, '='))
4586     {
4587     if (!terse) puts("");
4588     printf("%*s%s\n", TS, "", current);
4589     indent = 2 * TS;
4590     }
4591
4592   /* hidden lines (all MACROS or lines prefixed with "hide") */
4593   else if (  !admin
4594           && (  isupper(*current)
4595              || Ustrncmp(current, "hide", 4) == 0 && isspace(current[4])
4596              )
4597           )
4598     {
4599     if ((p = Ustrchr(current, '=')))
4600       {
4601       *p = '\0';
4602       printf("%*s%s= %s\n", indent, "", current, hidden);
4603       }
4604     /* e.g.: hide split_spool_directory */
4605     else
4606       printf("%*s\n", indent, hidden);
4607     }
4608
4609   else
4610     /* rest is public */
4611     printf("%*s%s\n", indent, "", current);
4612   }
4613 }
4614
4615 /* vi: aw ai sw=2
4616 */
4617 /* End of readconf.c */