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