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