ARC: Fix signing for case when DKIM signing failed
[exim.git] / src / src / readconf.c
1 /*************************************************
2 * Exim - an Internet mail transport agent *
3 *************************************************/
4
5 /* Copyright (c) University of Cambridge 1995 - 2018 */
6 /* See the file NOTICE for conditions of use and distribution. */
7
8 /* Functions for reading the configuration file, and for displaying
9 overall configuration values. Thanks to Brian Candler for the original
10 implementation of the conditional .ifdef etc. */
11
12 #include "exim.h"
13
14 #ifdef MACRO_PREDEF
15 # include "macro_predef.h"
16 #endif
17
18 static uschar * syslog_facility_str;
19 static void fn_smtp_receive_timeout(const uschar *, const uschar *);
20
21 /*************************************************
22 * Main configuration options *
23 *************************************************/
24
25 /* The list of options that can be set in the main configuration file. This
26 must be in alphabetic order because it is searched by binary chop. */
27
28 static optionlist optionlist_config[] = {
29 { "*set_exim_group", opt_bool|opt_hidden, &exim_gid_set },
30 { "*set_exim_user", opt_bool|opt_hidden, &exim_uid_set },
31 { "*set_system_filter_group", opt_bool|opt_hidden, &system_filter_gid_set },
32 { "*set_system_filter_user", opt_bool|opt_hidden, &system_filter_uid_set },
33 { "accept_8bitmime", opt_bool, &accept_8bitmime },
34 { "acl_not_smtp", opt_stringptr, &acl_not_smtp },
35 #ifdef WITH_CONTENT_SCAN
36 { "acl_not_smtp_mime", opt_stringptr, &acl_not_smtp_mime },
37 #endif
38 { "acl_not_smtp_start", opt_stringptr, &acl_not_smtp_start },
39 { "acl_smtp_auth", opt_stringptr, &acl_smtp_auth },
40 { "acl_smtp_connect", opt_stringptr, &acl_smtp_connect },
41 { "acl_smtp_data", opt_stringptr, &acl_smtp_data },
42 #ifndef DISABLE_PRDR
43 { "acl_smtp_data_prdr", opt_stringptr, &acl_smtp_data_prdr },
44 #endif
45 #ifndef DISABLE_DKIM
46 { "acl_smtp_dkim", opt_stringptr, &acl_smtp_dkim },
47 #endif
48 { "acl_smtp_etrn", opt_stringptr, &acl_smtp_etrn },
49 { "acl_smtp_expn", opt_stringptr, &acl_smtp_expn },
50 { "acl_smtp_helo", opt_stringptr, &acl_smtp_helo },
51 { "acl_smtp_mail", opt_stringptr, &acl_smtp_mail },
52 { "acl_smtp_mailauth", opt_stringptr, &acl_smtp_mailauth },
53 #ifdef WITH_CONTENT_SCAN
54 { "acl_smtp_mime", opt_stringptr, &acl_smtp_mime },
55 #endif
56 { "acl_smtp_notquit", opt_stringptr, &acl_smtp_notquit },
57 { "acl_smtp_predata", opt_stringptr, &acl_smtp_predata },
58 { "acl_smtp_quit", opt_stringptr, &acl_smtp_quit },
59 { "acl_smtp_rcpt", opt_stringptr, &acl_smtp_rcpt },
60 #ifdef SUPPORT_TLS
61 { "acl_smtp_starttls", opt_stringptr, &acl_smtp_starttls },
62 #endif
63 { "acl_smtp_vrfy", opt_stringptr, &acl_smtp_vrfy },
64 { "add_environment", opt_stringptr, &add_environment },
65 { "admin_groups", opt_gidlist, &admin_groups },
66 { "allow_domain_literals", opt_bool, &allow_domain_literals },
67 { "allow_mx_to_ip", opt_bool, &allow_mx_to_ip },
68 { "allow_utf8_domains", opt_bool, &allow_utf8_domains },
69 { "auth_advertise_hosts", opt_stringptr, &auth_advertise_hosts },
70 { "auto_thaw", opt_time, &auto_thaw },
71 #ifdef WITH_CONTENT_SCAN
72 { "av_scanner", opt_stringptr, &av_scanner },
73 #endif
74 { "bi_command", opt_stringptr, &bi_command },
75 #ifdef EXPERIMENTAL_BRIGHTMAIL
76 { "bmi_config_file", opt_stringptr, &bmi_config_file },
77 #endif
78 { "bounce_message_file", opt_stringptr, &bounce_message_file },
79 { "bounce_message_text", opt_stringptr, &bounce_message_text },
80 { "bounce_return_body", opt_bool, &bounce_return_body },
81 { "bounce_return_linesize_limit", opt_mkint, &bounce_return_linesize_limit },
82 { "bounce_return_message", opt_bool, &bounce_return_message },
83 { "bounce_return_size_limit", opt_mkint, &bounce_return_size_limit },
84 { "bounce_sender_authentication",opt_stringptr,&bounce_sender_authentication },
85 { "callout_domain_negative_expire", opt_time, &callout_cache_domain_negative_expire },
86 { "callout_domain_positive_expire", opt_time, &callout_cache_domain_positive_expire },
87 { "callout_negative_expire", opt_time, &callout_cache_negative_expire },
88 { "callout_positive_expire", opt_time, &callout_cache_positive_expire },
89 { "callout_random_local_part",opt_stringptr, &callout_random_local_part },
90 { "check_log_inodes", opt_int, &check_log_inodes },
91 { "check_log_space", opt_Kint, &check_log_space },
92 { "check_rfc2047_length", opt_bool, &check_rfc2047_length },
93 { "check_spool_inodes", opt_int, &check_spool_inodes },
94 { "check_spool_space", opt_Kint, &check_spool_space },
95 { "chunking_advertise_hosts", opt_stringptr, &chunking_advertise_hosts },
96 { "commandline_checks_require_admin", opt_bool,&commandline_checks_require_admin },
97 { "daemon_smtp_port", opt_stringptr|opt_hidden, &daemon_smtp_port },
98 { "daemon_smtp_ports", opt_stringptr, &daemon_smtp_port },
99 { "daemon_startup_retries", opt_int, &daemon_startup_retries },
100 { "daemon_startup_sleep", opt_time, &daemon_startup_sleep },
101 #ifdef EXPERIMENTAL_DCC
102 { "dcc_direct_add_header", opt_bool, &dcc_direct_add_header },
103 { "dccifd_address", opt_stringptr, &dccifd_address },
104 { "dccifd_options", opt_stringptr, &dccifd_options },
105 #endif
106 { "debug_store", opt_bool, &debug_store },
107 { "delay_warning", opt_timelist, &delay_warning },
108 { "delay_warning_condition", opt_stringptr, &delay_warning_condition },
109 { "deliver_drop_privilege", opt_bool, &deliver_drop_privilege },
110 { "deliver_queue_load_max", opt_fixed, &deliver_queue_load_max },
111 { "delivery_date_remove", opt_bool, &delivery_date_remove },
112 #ifdef ENABLE_DISABLE_FSYNC
113 { "disable_fsync", opt_bool, &disable_fsync },
114 #endif
115 { "disable_ipv6", opt_bool, &disable_ipv6 },
116 #ifndef DISABLE_DKIM
117 { "dkim_verify_signers", opt_stringptr, &dkim_verify_signers },
118 #endif
119 #ifdef EXPERIMENTAL_DMARC
120 { "dmarc_forensic_sender", opt_stringptr, &dmarc_forensic_sender },
121 { "dmarc_history_file", opt_stringptr, &dmarc_history_file },
122 { "dmarc_tld_file", opt_stringptr, &dmarc_tld_file },
123 #endif
124 { "dns_again_means_nonexist", opt_stringptr, &dns_again_means_nonexist },
125 { "dns_check_names_pattern", opt_stringptr, &check_dns_names_pattern },
126 { "dns_csa_search_limit", opt_int, &dns_csa_search_limit },
127 { "dns_csa_use_reverse", opt_bool, &dns_csa_use_reverse },
128 { "dns_dnssec_ok", opt_int, &dns_dnssec_ok },
129 { "dns_ipv4_lookup", opt_stringptr, &dns_ipv4_lookup },
130 { "dns_retrans", opt_time, &dns_retrans },
131 { "dns_retry", opt_int, &dns_retry },
132 { "dns_trust_aa", opt_stringptr, &dns_trust_aa },
133 { "dns_use_edns0", opt_int, &dns_use_edns0 },
134 /* This option is now a no-op, retained for compatibility */
135 { "drop_cr", opt_bool, &drop_cr },
136 /*********************************************************/
137 { "dsn_advertise_hosts", opt_stringptr, &dsn_advertise_hosts },
138 { "dsn_from", opt_stringptr, &dsn_from },
139 { "envelope_to_remove", opt_bool, &envelope_to_remove },
140 { "errors_copy", opt_stringptr, &errors_copy },
141 { "errors_reply_to", opt_stringptr, &errors_reply_to },
142 #ifndef DISABLE_EVENT
143 { "event_action", opt_stringptr, &event_action },
144 #endif
145 { "exim_group", opt_gid, &exim_gid },
146 { "exim_path", opt_stringptr, &exim_path },
147 { "exim_user", opt_uid, &exim_uid },
148 { "extra_local_interfaces", opt_stringptr, &extra_local_interfaces },
149 { "extract_addresses_remove_arguments", opt_bool, &extract_addresses_remove_arguments },
150 { "finduser_retries", opt_int, &finduser_retries },
151 { "freeze_tell", opt_stringptr, &freeze_tell },
152 { "gecos_name", opt_stringptr, &gecos_name },
153 { "gecos_pattern", opt_stringptr, &gecos_pattern },
154 #ifdef SUPPORT_TLS
155 { "gnutls_allow_auto_pkcs11", opt_bool, &gnutls_allow_auto_pkcs11 },
156 { "gnutls_compat_mode", opt_bool, &gnutls_compat_mode },
157 #endif
158 { "header_line_maxsize", opt_int, &header_line_maxsize },
159 { "header_maxsize", opt_int, &header_maxsize },
160 { "headers_charset", opt_stringptr, &headers_charset },
161 { "helo_accept_junk_hosts", opt_stringptr, &helo_accept_junk_hosts },
162 { "helo_allow_chars", opt_stringptr, &helo_allow_chars },
163 { "helo_lookup_domains", opt_stringptr, &helo_lookup_domains },
164 { "helo_try_verify_hosts", opt_stringptr, &helo_try_verify_hosts },
165 { "helo_verify_hosts", opt_stringptr, &helo_verify_hosts },
166 { "hold_domains", opt_stringptr, &hold_domains },
167 { "host_lookup", opt_stringptr, &host_lookup },
168 { "host_lookup_order", opt_stringptr, &host_lookup_order },
169 { "host_reject_connection", opt_stringptr, &host_reject_connection },
170 { "hosts_connection_nolog", opt_stringptr, &hosts_connection_nolog },
171 #ifdef SUPPORT_PROXY
172 { "hosts_proxy", opt_stringptr, &hosts_proxy },
173 #endif
174 { "hosts_treat_as_local", opt_stringptr, &hosts_treat_as_local },
175 #ifdef LOOKUP_IBASE
176 { "ibase_servers", opt_stringptr, &ibase_servers },
177 #endif
178 { "ignore_bounce_errors_after", opt_time, &ignore_bounce_errors_after },
179 { "ignore_fromline_hosts", opt_stringptr, &ignore_fromline_hosts },
180 { "ignore_fromline_local", opt_bool, &ignore_fromline_local },
181 { "keep_environment", opt_stringptr, &keep_environment },
182 { "keep_malformed", opt_time, &keep_malformed },
183 #ifdef LOOKUP_LDAP
184 { "ldap_ca_cert_dir", opt_stringptr, &eldap_ca_cert_dir },
185 { "ldap_ca_cert_file", opt_stringptr, &eldap_ca_cert_file },
186 { "ldap_cert_file", opt_stringptr, &eldap_cert_file },
187 { "ldap_cert_key", opt_stringptr, &eldap_cert_key },
188 { "ldap_cipher_suite", opt_stringptr, &eldap_cipher_suite },
189 { "ldap_default_servers", opt_stringptr, &eldap_default_servers },
190 { "ldap_require_cert", opt_stringptr, &eldap_require_cert },
191 { "ldap_start_tls", opt_bool, &eldap_start_tls },
192 { "ldap_version", opt_int, &eldap_version },
193 #endif
194 { "local_from_check", opt_bool, &local_from_check },
195 { "local_from_prefix", opt_stringptr, &local_from_prefix },
196 { "local_from_suffix", opt_stringptr, &local_from_suffix },
197 { "local_interfaces", opt_stringptr, &local_interfaces },
198 #ifdef HAVE_LOCAL_SCAN
199 { "local_scan_timeout", opt_time, &local_scan_timeout },
200 #endif
201 { "local_sender_retain", opt_bool, &local_sender_retain },
202 { "localhost_number", opt_stringptr, &host_number_string },
203 { "log_file_path", opt_stringptr, &log_file_path },
204 { "log_selector", opt_stringptr, &log_selector_string },
205 { "log_timezone", opt_bool, &log_timezone },
206 { "lookup_open_max", opt_int, &lookup_open_max },
207 { "max_username_length", opt_int, &max_username_length },
208 { "message_body_newlines", opt_bool, &message_body_newlines },
209 { "message_body_visible", opt_mkint, &message_body_visible },
210 { "message_id_header_domain", opt_stringptr, &message_id_domain },
211 { "message_id_header_text", opt_stringptr, &message_id_text },
212 { "message_logs", opt_bool, &message_logs },
213 { "message_size_limit", opt_stringptr, &message_size_limit },
214 #ifdef SUPPORT_MOVE_FROZEN_MESSAGES
215 { "move_frozen_messages", opt_bool, &move_frozen_messages },
216 #endif
217 { "mua_wrapper", opt_bool, &mua_wrapper },
218 #ifdef LOOKUP_MYSQL
219 { "mysql_servers", opt_stringptr, &mysql_servers },
220 #endif
221 { "never_users", opt_uidlist, &never_users },
222 #ifdef SUPPORT_TLS
223 { "openssl_options", opt_stringptr, &openssl_options },
224 #endif
225 #ifdef LOOKUP_ORACLE
226 { "oracle_servers", opt_stringptr, &oracle_servers },
227 #endif
228 { "percent_hack_domains", opt_stringptr, &percent_hack_domains },
229 #ifdef EXIM_PERL
230 { "perl_at_start", opt_bool, &opt_perl_at_start },
231 { "perl_startup", opt_stringptr, &opt_perl_startup },
232 { "perl_taintmode", opt_bool, &opt_perl_taintmode },
233 #endif
234 #ifdef LOOKUP_PGSQL
235 { "pgsql_servers", opt_stringptr, &pgsql_servers },
236 #endif
237 { "pid_file_path", opt_stringptr, &pid_file_path },
238 { "pipelining_advertise_hosts", opt_stringptr, &pipelining_advertise_hosts },
239 #ifndef DISABLE_PRDR
240 { "prdr_enable", opt_bool, &prdr_enable },
241 #endif
242 { "preserve_message_logs", opt_bool, &preserve_message_logs },
243 { "primary_hostname", opt_stringptr, &primary_hostname },
244 { "print_topbitchars", opt_bool, &print_topbitchars },
245 { "process_log_path", opt_stringptr, &process_log_path },
246 { "prod_requires_admin", opt_bool, &prod_requires_admin },
247 { "qualify_domain", opt_stringptr, &qualify_domain_sender },
248 { "qualify_recipient", opt_stringptr, &qualify_domain_recipient },
249 { "queue_domains", opt_stringptr, &queue_domains },
250 { "queue_list_requires_admin",opt_bool, &queue_list_requires_admin },
251 { "queue_only", opt_bool, &queue_only },
252 { "queue_only_file", opt_stringptr, &queue_only_file },
253 { "queue_only_load", opt_fixed, &queue_only_load },
254 { "queue_only_load_latch", opt_bool, &queue_only_load_latch },
255 { "queue_only_override", opt_bool, &queue_only_override },
256 { "queue_run_in_order", opt_bool, &queue_run_in_order },
257 { "queue_run_max", opt_stringptr, &queue_run_max },
258 { "queue_smtp_domains", opt_stringptr, &queue_smtp_domains },
259 { "receive_timeout", opt_time, &receive_timeout },
260 { "received_header_text", opt_stringptr, &received_header_text },
261 { "received_headers_max", opt_int, &received_headers_max },
262 { "recipient_unqualified_hosts", opt_stringptr, &recipient_unqualified_hosts },
263 { "recipients_max", opt_int, &recipients_max },
264 { "recipients_max_reject", opt_bool, &recipients_max_reject },
265 #ifdef LOOKUP_REDIS
266 { "redis_servers", opt_stringptr, &redis_servers },
267 #endif
268 { "remote_max_parallel", opt_int, &remote_max_parallel },
269 { "remote_sort_domains", opt_stringptr, &remote_sort_domains },
270 { "retry_data_expire", opt_time, &retry_data_expire },
271 { "retry_interval_max", opt_time, &retry_interval_max },
272 { "return_path_remove", opt_bool, &return_path_remove },
273 { "return_size_limit", opt_mkint|opt_hidden, &bounce_return_size_limit },
274 { "rfc1413_hosts", opt_stringptr, &rfc1413_hosts },
275 { "rfc1413_query_timeout", opt_time, &rfc1413_query_timeout },
276 { "sender_unqualified_hosts", opt_stringptr, &sender_unqualified_hosts },
277 { "slow_lookup_log", opt_int, &slow_lookup_log },
278 { "smtp_accept_keepalive", opt_bool, &smtp_accept_keepalive },
279 { "smtp_accept_max", opt_int, &smtp_accept_max },
280 { "smtp_accept_max_nonmail", opt_int, &smtp_accept_max_nonmail },
281 { "smtp_accept_max_nonmail_hosts", opt_stringptr, &smtp_accept_max_nonmail_hosts },
282 { "smtp_accept_max_per_connection", opt_int, &smtp_accept_max_per_connection },
283 { "smtp_accept_max_per_host", opt_stringptr, &smtp_accept_max_per_host },
284 { "smtp_accept_queue", opt_int, &smtp_accept_queue },
285 { "smtp_accept_queue_per_connection", opt_int, &smtp_accept_queue_per_connection },
286 { "smtp_accept_reserve", opt_int, &smtp_accept_reserve },
287 { "smtp_active_hostname", opt_stringptr, &raw_active_hostname },
288 { "smtp_banner", opt_stringptr, &smtp_banner },
289 { "smtp_check_spool_space", opt_bool, &smtp_check_spool_space },
290 { "smtp_connect_backlog", opt_int, &smtp_connect_backlog },
291 { "smtp_enforce_sync", opt_bool, &smtp_enforce_sync },
292 { "smtp_etrn_command", opt_stringptr, &smtp_etrn_command },
293 { "smtp_etrn_serialize", opt_bool, &smtp_etrn_serialize },
294 { "smtp_load_reserve", opt_fixed, &smtp_load_reserve },
295 { "smtp_max_synprot_errors", opt_int, &smtp_max_synprot_errors },
296 { "smtp_max_unknown_commands",opt_int, &smtp_max_unknown_commands },
297 { "smtp_ratelimit_hosts", opt_stringptr, &smtp_ratelimit_hosts },
298 { "smtp_ratelimit_mail", opt_stringptr, &smtp_ratelimit_mail },
299 { "smtp_ratelimit_rcpt", opt_stringptr, &smtp_ratelimit_rcpt },
300 { "smtp_receive_timeout", opt_func, &fn_smtp_receive_timeout },
301 { "smtp_reserve_hosts", opt_stringptr, &smtp_reserve_hosts },
302 { "smtp_return_error_details",opt_bool, &smtp_return_error_details },
303 #ifdef SUPPORT_I18N
304 { "smtputf8_advertise_hosts", opt_stringptr, &smtputf8_advertise_hosts },
305 #endif
306 #ifdef WITH_CONTENT_SCAN
307 { "spamd_address", opt_stringptr, &spamd_address },
308 #endif
309 #ifdef SUPPORT_SPF
310 { "spf_guess", opt_stringptr, &spf_guess },
311 #endif
312 { "split_spool_directory", opt_bool, &split_spool_directory },
313 { "spool_directory", opt_stringptr, &spool_directory },
314 { "spool_wireformat", opt_bool, &spool_wireformat },
315 #ifdef LOOKUP_SQLITE
316 { "sqlite_lock_timeout", opt_int, &sqlite_lock_timeout },
317 #endif
318 #ifdef EXPERIMENTAL_SRS
319 { "srs_config", opt_stringptr, &srs_config },
320 { "srs_hashlength", opt_int, &srs_hashlength },
321 { "srs_hashmin", opt_int, &srs_hashmin },
322 { "srs_maxage", opt_int, &srs_maxage },
323 { "srs_secrets", opt_stringptr, &srs_secrets },
324 { "srs_usehash", opt_bool, &srs_usehash },
325 { "srs_usetimestamp", opt_bool, &srs_usetimestamp },
326 #endif
327 { "strict_acl_vars", opt_bool, &strict_acl_vars },
328 { "strip_excess_angle_brackets", opt_bool, &strip_excess_angle_brackets },
329 { "strip_trailing_dot", opt_bool, &strip_trailing_dot },
330 { "syslog_duplication", opt_bool, &syslog_duplication },
331 { "syslog_facility", opt_stringptr, &syslog_facility_str },
332 { "syslog_pid", opt_bool, &syslog_pid },
333 { "syslog_processname", opt_stringptr, &syslog_processname },
334 { "syslog_timestamp", opt_bool, &syslog_timestamp },
335 { "system_filter", opt_stringptr, &system_filter },
336 { "system_filter_directory_transport", opt_stringptr,&system_filter_directory_transport },
337 { "system_filter_file_transport",opt_stringptr,&system_filter_file_transport },
338 { "system_filter_group", opt_gid, &system_filter_gid },
339 { "system_filter_pipe_transport",opt_stringptr,&system_filter_pipe_transport },
340 { "system_filter_reply_transport",opt_stringptr,&system_filter_reply_transport },
341 { "system_filter_user", opt_uid, &system_filter_uid },
342 { "tcp_nodelay", opt_bool, &tcp_nodelay },
343 #ifdef USE_TCP_WRAPPERS
344 { "tcp_wrappers_daemon_name", opt_stringptr, &tcp_wrappers_daemon_name },
345 #endif
346 { "timeout_frozen_after", opt_time, &timeout_frozen_after },
347 { "timezone", opt_stringptr, &timezone_string },
348 { "tls_advertise_hosts", opt_stringptr, &tls_advertise_hosts },
349 #ifdef SUPPORT_TLS
350 { "tls_certificate", opt_stringptr, &tls_certificate },
351 { "tls_crl", opt_stringptr, &tls_crl },
352 { "tls_dh_max_bits", opt_int, &tls_dh_max_bits },
353 { "tls_dhparam", opt_stringptr, &tls_dhparam },
354 { "tls_eccurve", opt_stringptr, &tls_eccurve },
355 # ifndef DISABLE_OCSP
356 { "tls_ocsp_file", opt_stringptr, &tls_ocsp_file },
357 # endif
358 { "tls_on_connect_ports", opt_stringptr, &tls_in.on_connect_ports },
359 { "tls_privatekey", opt_stringptr, &tls_privatekey },
360 { "tls_remember_esmtp", opt_bool, &tls_remember_esmtp },
361 { "tls_require_ciphers", opt_stringptr, &tls_require_ciphers },
362 { "tls_try_verify_hosts", opt_stringptr, &tls_try_verify_hosts },
363 { "tls_verify_certificates", opt_stringptr, &tls_verify_certificates },
364 { "tls_verify_hosts", opt_stringptr, &tls_verify_hosts },
365 #endif
366 { "trusted_groups", opt_gidlist, &trusted_groups },
367 { "trusted_users", opt_uidlist, &trusted_users },
368 { "unknown_login", opt_stringptr, &unknown_login },
369 { "unknown_username", opt_stringptr, &unknown_username },
370 { "untrusted_set_sender", opt_stringptr, &untrusted_set_sender },
371 { "uucp_from_pattern", opt_stringptr, &uucp_from_pattern },
372 { "uucp_from_sender", opt_stringptr, &uucp_from_sender },
373 { "warn_message_file", opt_stringptr, &warn_message_file },
374 { "write_rejectlog", opt_bool, &write_rejectlog }
375 };
376
377 #ifndef MACRO_PREDEF
378 static int optionlist_config_size = nelem(optionlist_config);
379 #endif
380
381
382 #ifdef MACRO_PREDEF
383
384 static void fn_smtp_receive_timeout(const uschar * name, const uschar * str) {/*Dummy*/}
385
386 void
387 options_main(void)
388 {
389 options_from_list(optionlist_config, nelem(optionlist_config), US"MAIN", NULL);
390 }
391
392 void
393 options_auths(void)
394 {
395 struct auth_info * ai;
396 uschar buf[64];
397
398 options_from_list(optionlist_auths, optionlist_auths_size, US"AUTHENTICATORS", NULL);
399
400 for (ai = auths_available; ai->driver_name[0]; ai++)
401 {
402 spf(buf, sizeof(buf), US"_DRIVER_AUTHENTICATOR_%T", ai->driver_name);
403 builtin_macro_create(buf);
404 options_from_list(ai->options, (unsigned)*ai->options_count, US"AUTHENTICATOR", ai->driver_name);
405 }
406 }
407
408
409 #else /*!MACRO_PREDEF*/
410
411 extern char **environ;
412
413 static void save_config_line(const uschar* line);
414 static void save_config_position(const uschar *file, int line);
415 static void print_config(BOOL admin, BOOL terse);
416
417
418 #define CSTATE_STACK_SIZE 10
419
420 const uschar *config_directory = NULL;
421
422
423 /* Structure for chain (stack) of .included files */
424
425 typedef struct config_file_item {
426 struct config_file_item *next;
427 const uschar *filename;
428 const uschar *directory;
429 FILE *file;
430 int lineno;
431 } config_file_item;
432
433 /* Structure for chain of configuration lines (-bP config) */
434
435 typedef struct config_line_item {
436 struct config_line_item *next;
437 uschar *line;
438 } config_line_item;
439
440 static config_line_item* config_lines;
441
442 /* Structure of table of conditional words and their state transitions */
443
444 typedef struct cond_item {
445 uschar *name;
446 int namelen;
447 int action1;
448 int action2;
449 int pushpop;
450 } cond_item;
451
452 /* Structure of table of syslog facility names and values */
453
454 typedef struct syslog_fac_item {
455 uschar *name;
456 int value;
457 } syslog_fac_item;
458
459 /* constants */
460 static const char * const hidden = "<value not displayable>";
461
462 /* Static variables */
463
464 static config_file_item *config_file_stack = NULL; /* For includes */
465
466 static uschar *syslog_facility_str = NULL;
467 static uschar next_section[24];
468 static uschar time_buffer[24];
469
470 /* State variables for conditional loading (.ifdef / .else / .endif) */
471
472 static int cstate = 0;
473 static int cstate_stack_ptr = -1;
474 static int cstate_stack[CSTATE_STACK_SIZE];
475
476 /* Table of state transitions for handling conditional inclusions. There are
477 four possible state transitions:
478
479 .ifdef true
480 .ifdef false
481 .elifdef true (or .else)
482 .elifdef false
483
484 .endif just causes the previous cstate to be popped off the stack */
485
486 static int next_cstate[3][4] =
487 {
488 /* State 0: reading from file, or reading until next .else or .endif */
489 { 0, 1, 2, 2 },
490 /* State 1: condition failed, skipping until next .else or .endif */
491 { 2, 2, 0, 1 },
492 /* State 2: skipping until .endif */
493 { 2, 2, 2, 2 },
494 };
495
496 /* Table of conditionals and the states to set. For each name, there are four
497 values: the length of the name (to save computing it each time), the state to
498 set if a macro was found in the line, the state to set if a macro was not found
499 in the line, and a stack manipulation setting which is:
500
501 -1 pull state value off the stack
502 0 don't alter the stack
503 +1 push value onto stack, before setting new state
504 */
505
506 static cond_item cond_list[] = {
507 { US"ifdef", 5, 0, 1, 1 },
508 { US"ifndef", 6, 1, 0, 1 },
509 { US"elifdef", 7, 2, 3, 0 },
510 { US"elifndef", 8, 3, 2, 0 },
511 { US"else", 4, 2, 2, 0 },
512 { US"endif", 5, 0, 0, -1 }
513 };
514
515 static int cond_list_size = sizeof(cond_list)/sizeof(cond_item);
516
517 /* Table of syslog facility names and their values */
518
519 static syslog_fac_item syslog_list[] = {
520 { US"mail", LOG_MAIL },
521 { US"user", LOG_USER },
522 { US"news", LOG_NEWS },
523 { US"uucp", LOG_UUCP },
524 { US"local0", LOG_LOCAL0 },
525 { US"local1", LOG_LOCAL1 },
526 { US"local2", LOG_LOCAL2 },
527 { US"local3", LOG_LOCAL3 },
528 { US"local4", LOG_LOCAL4 },
529 { US"local5", LOG_LOCAL5 },
530 { US"local6", LOG_LOCAL6 },
531 { US"local7", LOG_LOCAL7 },
532 { US"daemon", LOG_DAEMON }
533 };
534
535 static int syslog_list_size = sizeof(syslog_list)/sizeof(syslog_fac_item);
536
537
538
539
540 /*************************************************
541 * Find the name of an option *
542 *************************************************/
543
544 /* This function is to aid debugging. Various functions take arguments that are
545 pointer variables in the options table or in option tables for various drivers.
546 For debugging output, it is useful to be able to find the name of the option
547 which is currently being processed. This function finds it, if it exists, by
548 searching the table(s).
549
550 Arguments: a value that is presumed to be in the table above
551 Returns: the option name, or an empty string
552 */
553
554 uschar *
555 readconf_find_option(void *p)
556 {
557 int i;
558 router_instance *r;
559 transport_instance *t;
560
561 for (i = 0; i < nelem(optionlist_config); i++)
562 if (p == optionlist_config[i].value) return US optionlist_config[i].name;
563
564 for (r = routers; r; r = r->next)
565 {
566 router_info *ri = r->info;
567 for (i = 0; i < *ri->options_count; i++)
568 {
569 if ((ri->options[i].type & opt_mask) != opt_stringptr) continue;
570 if (p == CS (r->options_block) + (long int)(ri->options[i].value))
571 return US ri->options[i].name;
572 }
573 }
574
575 for (t = transports; t; t = t->next)
576 {
577 transport_info *ti = t->info;
578 for (i = 0; i < *ti->options_count; i++)
579 {
580 optionlist * op = &ti->options[i];
581 if ((op->type & opt_mask) != opt_stringptr) continue;
582 if (p == ( op->type & opt_public
583 ? CS t
584 : CS t->options_block
585 )
586 + (long int)op->value)
587 return US op->name;
588 }
589 }
590
591 return US"";
592 }
593
594
595
596
597 /*************************************************
598 * Deal with an assignment to a macro *
599 *************************************************/
600
601 /* We have a new definition; append to the list.
602
603 Args:
604 name Name of the macro; will be copied
605 val Expansion result for the macro; will be copied
606 */
607
608 macro_item *
609 macro_create(const uschar * name, const uschar * val, BOOL command_line)
610 {
611 macro_item * m = store_get(sizeof(macro_item));
612
613 /* fprintf(stderr, "%s: '%s' '%s'\n", __FUNCTION__, name, val); */
614 m->next = NULL;
615 m->command_line = command_line;
616 m->namelen = Ustrlen(name);
617 m->replen = Ustrlen(val);
618 m->name = string_copy(name);
619 m->replacement = string_copy(val);
620 if (mlast)
621 mlast->next = m;
622 else
623 macros = m;
624 mlast = m;
625 if (!macros_user)
626 macros_user = m;
627 return m;
628 }
629
630
631 /* This function is called when a line that starts with an upper case letter is
632 encountered. The argument "line" should contain a complete logical line, and
633 start with the first letter of the macro name. The macro name and the
634 replacement text are extracted and stored. Redefinition of existing,
635 non-command line, macros is permitted using '==' instead of '='.
636
637 Arguments:
638 s points to the start of the logical line
639
640 Returns: FALSE iff fatal error
641 */
642
643 BOOL
644 macro_read_assignment(uschar *s)
645 {
646 uschar name[64];
647 int namelen = 0;
648 BOOL redef = FALSE;
649 macro_item *m;
650
651 while (isalnum(*s) || *s == '_')
652 {
653 if (namelen >= sizeof(name) - 1)
654 {
655 log_write(0, LOG_PANIC|LOG_CONFIG_IN,
656 "macro name too long (maximum is " SIZE_T_FMT " characters)", sizeof(name) - 1);
657 return FALSE;
658 }
659 name[namelen++] = *s++;
660 }
661 name[namelen] = 0;
662
663 while (isspace(*s)) s++;
664 if (*s++ != '=')
665 {
666 log_write(0, LOG_PANIC|LOG_CONFIG_IN, "malformed macro definition");
667 return FALSE;
668 }
669
670 if (*s == '=')
671 {
672 redef = TRUE;
673 s++;
674 }
675 while (isspace(*s)) s++;
676
677 /* If an existing macro of the same name was defined on the command line, we
678 just skip this definition. It's an error to attempt to redefine a macro without
679 redef set to TRUE, or to redefine a macro when it hasn't been defined earlier.
680 It is also an error to define a macro whose name begins with the name of a
681 previously defined macro. This is the requirement that make using a tree
682 for macros hard; we must check all macros for the substring. Perhaps a
683 sorted list, and a bsearch, would work?
684 Note: it is documented that the other way round works. */
685
686 for (m = macros; m; m = m->next)
687 {
688 if (Ustrcmp(m->name, name) == 0)
689 {
690 if (!m->command_line && !redef)
691 {
692 log_write(0, LOG_CONFIG|LOG_PANIC, "macro \"%s\" is already "
693 "defined (use \"==\" if you want to redefine it)", name);
694 return FALSE;
695 }
696 break;
697 }
698
699 if (m->namelen < namelen && Ustrstr(name, m->name) != NULL)
700 {
701 log_write(0, LOG_CONFIG|LOG_PANIC, "\"%s\" cannot be defined as "
702 "a macro because previously defined macro \"%s\" is a substring",
703 name, m->name);
704 return FALSE;
705 }
706
707 /* We cannot have this test, because it is documented that a substring
708 macro is permitted (there is even an example).
709 *
710 * if (m->namelen > namelen && Ustrstr(m->name, name) != NULL)
711 * log_write(0, LOG_CONFIG|LOG_PANIC_DIE, "\"%s\" cannot be defined as "
712 * "a macro because it is a substring of previously defined macro \"%s\"",
713 * name, m->name);
714 */
715 }
716
717 /* Check for an overriding command-line definition. */
718
719 if (m && m->command_line) return TRUE;
720
721 /* Redefinition must refer to an existing macro. */
722
723 if (redef)
724 if (m)
725 {
726 m->replen = Ustrlen(s);
727 m->replacement = string_copy(s);
728 }
729 else
730 {
731 log_write(0, LOG_CONFIG|LOG_PANIC, "can't redefine an undefined macro "
732 "\"%s\"", name);
733 return FALSE;
734 }
735
736 /* We have a new definition. */
737 else
738 (void) macro_create(name, s, FALSE);
739 return TRUE;
740 }
741
742
743
744
745
746 /* Process line for macros. The line is in big_buffer starting at offset len.
747 Expand big_buffer if needed. Handle definitions of new macros, and
748 macro expansions, rewriting the line in the buffer.
749
750 Arguments:
751 len Offset in buffer of start of line
752 newlen Pointer to offset of end of line, updated on return
753 macro_found Pointer to return that a macro was expanded
754
755 Return: pointer to first nonblank char in line
756 */
757
758 uschar *
759 macros_expand(int len, int * newlen, BOOL * macro_found)
760 {
761 uschar * ss = big_buffer + len;
762 uschar * s;
763 macro_item * m;
764
765 /* Find the true start of the physical line - leading spaces are always
766 ignored. */
767
768 while (isspace(*ss)) ss++;
769
770 /* Process the physical line for macros. If this is the start of the logical
771 line, skip over initial text at the start of the line if it starts with an
772 upper case character followed by a sequence of name characters and an equals
773 sign, because that is the definition of a new macro, and we don't do
774 replacement therein. */
775
776 s = ss;
777 if (len == 0 && isupper(*s))
778 {
779 while (isalnum(*s) || *s == '_') s++;
780 while (isspace(*s)) s++;
781 if (*s != '=') s = ss; /* Not a macro definition */
782 }
783
784 /* Skip leading chars which cannot start a macro name, to avoid multiple
785 pointless rescans in Ustrstr calls. */
786
787 while (*s && !isupper(*s) && !(*s == '_' && isupper(s[1]))) s++;
788
789 /* For each defined macro, scan the line (from after XXX= if present),
790 replacing all occurrences of the macro. */
791
792 *macro_found = FALSE;
793 if (*s) for (m = *s == '_' ? macros : macros_user; m; m = m->next)
794 {
795 uschar * p, *pp;
796 uschar * t;
797
798 while (*s && !isupper(*s) && !(*s == '_' && isupper(s[1]))) s++;
799 if (!*s) break;
800
801 t = s;
802 while ((p = Ustrstr(t, m->name)) != NULL)
803 {
804 int moveby;
805
806 /* fprintf(stderr, "%s: matched '%s' in '%s'\n", __FUNCTION__, m->name, ss); */
807 /* Expand the buffer if necessary */
808
809 while (*newlen - m->namelen + m->replen + 1 > big_buffer_size)
810 {
811 int newsize = big_buffer_size + BIG_BUFFER_SIZE;
812 uschar *newbuffer = store_malloc(newsize);
813 memcpy(newbuffer, big_buffer, *newlen + 1);
814 p = newbuffer + (p - big_buffer);
815 s = newbuffer + (s - big_buffer);
816 ss = newbuffer + (ss - big_buffer);
817 t = newbuffer + (t - big_buffer);
818 big_buffer_size = newsize;
819 store_free(big_buffer);
820 big_buffer = newbuffer;
821 }
822
823 /* Shuffle the remaining characters up or down in the buffer before
824 copying in the replacement text. Don't rescan the replacement for this
825 same macro. */
826
827 pp = p + m->namelen;
828 if ((moveby = m->replen - m->namelen) != 0)
829 {
830 memmove(p + m->replen, pp, (big_buffer + *newlen) - pp + 1);
831 *newlen += moveby;
832 }
833 Ustrncpy(p, m->replacement, m->replen);
834 t = p + m->replen;
835 while (*t && !isupper(*t) && !(*t == '_' && isupper(t[1]))) t++;
836 *macro_found = TRUE;
837 }
838 }
839
840 /* An empty macro replacement at the start of a line could mean that ss no
841 longer points to the first non-blank character. */
842
843 while (isspace(*ss)) ss++;
844 return ss;
845 }
846
847 /*************************************************
848 * Read configuration line *
849 *************************************************/
850
851 /* A logical line of text is read from the configuration file into the big
852 buffer, taking account of macros, .includes, and continuations. The size of
853 big_buffer is increased if necessary. The count of configuration lines is
854 maintained. Physical input lines starting with # (ignoring leading white space,
855 and after macro replacement) and empty logical lines are always ignored.
856 Leading and trailing spaces are removed.
857
858 If we hit a line of the form "begin xxxx", the xxxx is placed in the
859 next_section vector, and the function returns NULL, indicating the end of a
860 configuration section. On end-of-file, NULL is returned with next_section
861 empty.
862
863 Arguments: none
864
865 Returns: a pointer to the first non-blank in the line,
866 or NULL if eof or end of section is reached
867 */
868
869 static uschar *
870 get_config_line(void)
871 {
872 int startoffset = 0; /* To first non-blank char in logical line */
873 int len = 0; /* Of logical line so far */
874 int newlen;
875 uschar *s, *ss;
876 BOOL macro_found;
877
878 /* Loop for handling continuation lines, skipping comments, and dealing with
879 .include files. */
880
881 for (;;)
882 {
883 if (Ufgets(big_buffer+len, big_buffer_size-len, config_file) == NULL)
884 {
885 if (config_file_stack != NULL) /* EOF inside .include */
886 {
887 (void)fclose(config_file);
888 config_file = config_file_stack->file;
889 config_filename = config_file_stack->filename;
890 config_directory = config_file_stack->directory;
891 config_lineno = config_file_stack->lineno;
892 config_file_stack = config_file_stack->next;
893 if (config_lines)
894 save_config_position(config_filename, config_lineno);
895 continue;
896 }
897
898 /* EOF at top level */
899
900 if (cstate_stack_ptr >= 0)
901 log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN,
902 "Unexpected end of configuration file: .endif missing");
903
904 if (len != 0) break; /* EOF after continuation */
905 next_section[0] = 0; /* EOF at start of logical line */
906 return NULL;
907 }
908
909 config_lineno++;
910 newlen = len + Ustrlen(big_buffer + len);
911
912 if (config_lines && config_lineno == 1)
913 save_config_position(config_filename, config_lineno);
914
915 /* Handle pathologically long physical lines - yes, it did happen - by
916 extending big_buffer at this point. The code also copes with very long
917 logical lines. */
918
919 while (newlen == big_buffer_size - 1 && big_buffer[newlen - 1] != '\n')
920 {
921 uschar *newbuffer;
922 big_buffer_size += BIG_BUFFER_SIZE;
923 newbuffer = store_malloc(big_buffer_size);
924
925 /* This use of strcpy is OK because we know that the string in the old
926 buffer is shorter than the new buffer. */
927
928 Ustrcpy(newbuffer, big_buffer);
929 store_free(big_buffer);
930 big_buffer = newbuffer;
931 if (Ufgets(big_buffer+newlen, big_buffer_size-newlen, config_file) == NULL)
932 break;
933 newlen += Ustrlen(big_buffer + newlen);
934 }
935
936 ss = macros_expand(len, &newlen, &macro_found);
937
938 /* Check for comment lines - these are physical lines. */
939
940 if (*ss == '#') continue;
941
942 /* Handle conditionals, which are also applied to physical lines. Conditions
943 are of the form ".ifdef ANYTEXT" and are treated as true if any macro
944 expansion occured on the rest of the line. A preliminary test for the leading
945 '.' saves effort on most lines. */
946
947 if (*ss == '.')
948 {
949 int i;
950
951 /* Search the list of conditional directives */
952
953 for (i = 0; i < cond_list_size; i++)
954 {
955 int n;
956 cond_item *c = cond_list+i;
957 if (Ustrncmp(ss+1, c->name, c->namelen) != 0) continue;
958
959 /* The following character must be white space or end of string */
960
961 n = ss[1 + c->namelen];
962 if (n != ' ' && n != 't' && n != '\n' && n != 0) break;
963
964 /* .ifdef and .ifndef push the current state onto the stack, then set
965 a new one from the table. Stack overflow is an error */
966
967 if (c->pushpop > 0)
968 {
969 if (cstate_stack_ptr >= CSTATE_STACK_SIZE - 1)
970 log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN,
971 ".%s nested too deeply", c->name);
972 cstate_stack[++cstate_stack_ptr] = cstate;
973 cstate = next_cstate[cstate][macro_found? c->action1 : c->action2];
974 }
975
976 /* For any of the others, stack underflow is an error. The next state
977 comes either from the stack (.endif) or from the table. */
978
979 else
980 {
981 if (cstate_stack_ptr < 0)
982 log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN,
983 ".%s without matching .ifdef", c->name);
984 cstate = (c->pushpop < 0)? cstate_stack[cstate_stack_ptr--] :
985 next_cstate[cstate][macro_found? c->action1 : c->action2];
986 }
987
988 /* Having dealt with a directive, break the loop */
989
990 break;
991 }
992
993 /* If we have handled a conditional directive, continue with the next
994 physical line. Otherwise, fall through. */
995
996 if (i < cond_list_size) continue;
997 }
998
999 /* If the conditional state is not 0 (actively using these lines), ignore
1000 this input line. */
1001
1002 if (cstate != 0) continue; /* Conditional skip */
1003
1004 /* Handle .include lines - these are also physical lines. */
1005
1006 if (Ustrncmp(ss, ".include", 8) == 0 &&
1007 (isspace(ss[8]) ||
1008 (Ustrncmp(ss+8, "_if_exists", 10) == 0 && isspace(ss[18]))))
1009 {
1010 uschar *t;
1011 int include_if_exists = isspace(ss[8])? 0 : 10;
1012 config_file_item *save;
1013 struct stat statbuf;
1014
1015 ss += 9 + include_if_exists;
1016 while (isspace(*ss)) ss++;
1017 t = ss + Ustrlen(ss);
1018 while (t > ss && isspace(t[-1])) t--;
1019 if (*ss == '\"' && t[-1] == '\"')
1020 {
1021 ss++;
1022 t--;
1023 }
1024 *t = 0;
1025
1026 /* We allow relative file names. For security reasons currently
1027 relative names not allowed with .include_if_exists. For .include_if_exists
1028 we need to check the permissions/ownership of the containing folder */
1029 if (*ss != '/')
1030 if (include_if_exists) log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, ".include specifies a non-"
1031 "absolute path \"%s\"", ss);
1032 else
1033 {
1034 gstring * g = string_append(NULL, 3, config_directory, "/", ss);
1035 ss = string_from_gstring(g);
1036 }
1037
1038 if (include_if_exists != 0 && (Ustat(ss, &statbuf) != 0)) continue;
1039
1040 if (config_lines)
1041 save_config_position(config_filename, config_lineno);
1042 save = store_get(sizeof(config_file_item));
1043 save->next = config_file_stack;
1044 config_file_stack = save;
1045 save->file = config_file;
1046 save->filename = config_filename;
1047 save->directory = config_directory;
1048 save->lineno = config_lineno;
1049
1050 if (!(config_file = Ufopen(ss, "rb")))
1051 log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, "failed to open included "
1052 "configuration file %s", ss);
1053
1054 config_filename = string_copy(ss);
1055 config_directory = string_copyn(ss, CUstrrchr(ss, '/') - ss);
1056 config_lineno = 0;
1057 continue;
1058 }
1059
1060 /* If this is the start of the logical line, remember where the non-blank
1061 data starts. Otherwise shuffle down continuation lines to remove leading
1062 white space. */
1063
1064 if (len == 0)
1065 startoffset = ss - big_buffer;
1066 else
1067 {
1068 s = big_buffer + len;
1069 if (ss > s)
1070 {
1071 memmove(s, ss, (newlen - len) - (ss - s) + 1);
1072 newlen -= ss - s;
1073 }
1074 }
1075
1076 /* Accept the new addition to the line. Remove trailing white space. */
1077
1078 len = newlen;
1079 while (len > 0 && isspace(big_buffer[len-1])) len--;
1080 big_buffer[len] = 0;
1081
1082 /* We are done if the line does not end in backslash and contains some data.
1083 Empty logical lines are ignored. For continuations, remove the backslash and
1084 go round the loop to read the continuation line. */
1085
1086 if (len > 0)
1087 {
1088 if (big_buffer[len-1] != '\\') break; /* End of logical line */
1089 big_buffer[--len] = 0; /* Remove backslash */
1090 }
1091 } /* Loop for reading multiple physical lines */
1092
1093 /* We now have a logical line. Test for the end of a configuration section (or,
1094 more accurately, for the start of the next section). Place the name of the next
1095 section in next_section, and return NULL. If the name given is longer than
1096 next_section, truncate it. It will be unrecognized later, because all the known
1097 section names do fit. Leave space for pluralizing. */
1098
1099 s = big_buffer + startoffset; /* First non-space character */
1100
1101 if (config_lines)
1102 save_config_line(s);
1103
1104 if (strncmpic(s, US"begin ", 6) == 0)
1105 {
1106 s += 6;
1107 while (isspace(*s)) s++;
1108 if (big_buffer + len - s > sizeof(next_section) - 2)
1109 s[sizeof(next_section) - 2] = 0;
1110 Ustrcpy(next_section, s);
1111 return NULL;
1112 }
1113
1114 /* Return the first non-blank character. */
1115
1116 return s;
1117 }
1118
1119
1120
1121 /*************************************************
1122 * Read a name *
1123 *************************************************/
1124
1125 /* The yield is the pointer to the next uschar. Names longer than the
1126 output space are silently truncated. This function is also used from acl.c when
1127 parsing ACLs.
1128
1129 Arguments:
1130 name where to put the name
1131 len length of name
1132 s input pointer
1133
1134 Returns: new input pointer
1135 */
1136
1137 uschar *
1138 readconf_readname(uschar *name, int len, uschar *s)
1139 {
1140 int p = 0;
1141 while (isspace(*s)) s++;
1142 if (isalpha(*s))
1143 {
1144 while (isalnum(*s) || *s == '_')
1145 {
1146 if (p < len-1) name[p++] = *s;
1147 s++;
1148 }
1149 }
1150 name[p] = 0;
1151 while (isspace(*s)) s++;
1152 return s;
1153 }
1154
1155
1156
1157
1158 /*************************************************
1159 * Read a time value *
1160 *************************************************/
1161
1162 /* This function is also called from outside, to read argument
1163 time values. The format of a time value is:
1164
1165 [<n>w][<n>d][<n>h][<n>m][<n>s]
1166
1167 as long as at least one is present. If a format error is encountered,
1168 return a negative value. The value must be terminated by the given
1169 terminator.
1170
1171 Arguments:
1172 s input pointer
1173 terminator required terminating character
1174 return_msec if TRUE, allow fractional seconds and return milliseconds
1175
1176 Returns: the time value, or -1 on syntax error
1177 value is seconds if return_msec is FALSE
1178 value is milliseconds if return_msec is TRUE
1179 */
1180
1181 int
1182 readconf_readtime(const uschar *s, int terminator, BOOL return_msec)
1183 {
1184 int yield = 0;
1185 for (;;)
1186 {
1187 int value, count;
1188 double fraction;
1189
1190 if (!isdigit(*s)) return -1;
1191 (void)sscanf(CCS s, "%d%n", &value, &count);
1192 s += count;
1193
1194 switch (*s)
1195 {
1196 case 'w': value *= 7;
1197 case 'd': value *= 24;
1198 case 'h': value *= 60;
1199 case 'm': value *= 60;
1200 case 's': s++;
1201 break;
1202
1203 case '.':
1204 if (!return_msec) return -1;
1205 (void)sscanf(CCS s, "%lf%n", &fraction, &count);
1206 s += count;
1207 if (*s++ != 's') return -1;
1208 yield += (int)(fraction * 1000.0);
1209 break;
1210
1211 default: return -1;
1212 }
1213
1214 if (return_msec) value *= 1000;
1215 yield += value;
1216 if (*s == terminator) return yield;
1217 }
1218 /* Control never reaches here. */
1219 }
1220
1221
1222
1223 /*************************************************
1224 * Read a fixed point value *
1225 *************************************************/
1226
1227 /* The value is returned *1000
1228
1229 Arguments:
1230 s input pointer
1231 terminator required terminator
1232
1233 Returns: the value, or -1 on error
1234 */
1235
1236 static int
1237 readconf_readfixed(const uschar *s, int terminator)
1238 {
1239 int yield = 0;
1240 int value, count;
1241 if (!isdigit(*s)) return -1;
1242 (void)sscanf(CS s, "%d%n", &value, &count);
1243 s += count;
1244 yield = value * 1000;
1245 if (*s == '.')
1246 {
1247 int m = 100;
1248 while (isdigit((*(++s))))
1249 {
1250 yield += (*s - '0') * m;
1251 m /= 10;
1252 }
1253 }
1254
1255 return (*s == terminator)? yield : (-1);
1256 }
1257
1258
1259
1260 /*************************************************
1261 * Find option in list *
1262 *************************************************/
1263
1264 /* The lists are always in order, so binary chop can be used.
1265
1266 Arguments:
1267 name the option name to search for
1268 ol the first entry in the option list
1269 last one more than the offset of the last entry in the option list
1270
1271 Returns: pointer to an option entry, or NULL if not found
1272 */
1273
1274 static optionlist *
1275 find_option(uschar *name, optionlist *ol, int last)
1276 {
1277 int first = 0;
1278 while (last > first)
1279 {
1280 int middle = (first + last)/2;
1281 int c = Ustrcmp(name, ol[middle].name);
1282
1283 if (c == 0) return ol + middle;
1284 else if (c > 0) first = middle + 1;
1285 else last = middle;
1286 }
1287 return NULL;
1288 }
1289
1290
1291
1292 /*************************************************
1293 * Find a set flag in option list *
1294 *************************************************/
1295
1296 /* Because some versions of Unix make no restrictions on the values of uids and
1297 gids (even negative ones), we cannot represent "unset" by a special value.
1298 There is therefore a separate boolean variable for each one indicating whether
1299 a value is set or not. This function returns a pointer to the boolean, given
1300 the original option name. It is a major disaster if the flag cannot be found.
1301
1302 Arguments:
1303 name the name of the uid or gid option
1304 oltop points to the start of the relevant option list
1305 last one more than the offset of the last item in the option list
1306 data_block NULL when reading main options => data values in the option
1307 list are absolute addresses; otherwise they are byte offsets
1308 in data_block (used for driver options)
1309
1310 Returns: a pointer to the boolean flag.
1311 */
1312
1313 static BOOL *
1314 get_set_flag(uschar *name, optionlist *oltop, int last, void *data_block)
1315 {
1316 optionlist *ol;
1317 uschar name2[64];
1318 sprintf(CS name2, "*set_%.50s", name);
1319 ol = find_option(name2, oltop, last);
1320 if (ol == NULL) log_write(0, LOG_MAIN|LOG_PANIC_DIE,
1321 "Exim internal error: missing set flag for %s", name);
1322 return (data_block == NULL)? (BOOL *)(ol->value) :
1323 (BOOL *)(US data_block + (long int)(ol->value));
1324 }
1325
1326
1327
1328
1329 /*************************************************
1330 * Output extra characters message and die *
1331 *************************************************/
1332
1333 /* Called when an option line has junk on the end. Sometimes this is because
1334 the sysadmin thinks comments are permitted.
1335
1336 Arguments:
1337 s points to the extra characters
1338 t1..t3 strings to insert in the log message
1339
1340 Returns: doesn't return; dies
1341 */
1342
1343 static void
1344 extra_chars_error(const uschar *s, const uschar *t1, const uschar *t2, const uschar *t3)
1345 {
1346 uschar *comment = US"";
1347 if (*s == '#') comment = US" (# is comment only at line start)";
1348 log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN,
1349 "extra characters follow %s%s%s%s", t1, t2, t3, comment);
1350 }
1351
1352
1353
1354 /*************************************************
1355 * Read rewrite information *
1356 *************************************************/
1357
1358 /* Each line of rewrite information contains:
1359
1360 . A complete address in the form user@domain, possibly with
1361 leading * for each part; or alternatively, a regex.
1362
1363 . A replacement string (which will be expanded).
1364
1365 . An optional sequence of one-letter flags, indicating which
1366 headers etc. to apply this rule to.
1367
1368 All this is decoded and placed into a control block. The OR of the flags is
1369 maintained in a common word.
1370
1371 Arguments:
1372 p points to the string that makes up the rule
1373 existflags points to the overall flag word
1374 isglobal TRUE if reading global rewrite rules
1375
1376 Returns: the control block for the parsed rule.
1377 */
1378
1379 static rewrite_rule *
1380 readconf_one_rewrite(const uschar *p, int *existflags, BOOL isglobal)
1381 {
1382 rewrite_rule *next = store_get(sizeof(rewrite_rule));
1383
1384 next->next = NULL;
1385 next->key = string_dequote(&p);
1386
1387 while (isspace(*p)) p++;
1388 if (*p == 0)
1389 log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN,
1390 "missing rewrite replacement string");
1391
1392 next->flags = 0;
1393 next->replacement = string_dequote(&p);
1394
1395 while (*p != 0) switch (*p++)
1396 {
1397 case ' ': case '\t': break;
1398
1399 case 'q': next->flags |= rewrite_quit; break;
1400 case 'w': next->flags |= rewrite_whole; break;
1401
1402 case 'h': next->flags |= rewrite_all_headers; break;
1403 case 's': next->flags |= rewrite_sender; break;
1404 case 'f': next->flags |= rewrite_from; break;
1405 case 't': next->flags |= rewrite_to; break;
1406 case 'c': next->flags |= rewrite_cc; break;
1407 case 'b': next->flags |= rewrite_bcc; break;
1408 case 'r': next->flags |= rewrite_replyto; break;
1409
1410 case 'E': next->flags |= rewrite_all_envelope; break;
1411 case 'F': next->flags |= rewrite_envfrom; break;
1412 case 'T': next->flags |= rewrite_envto; break;
1413
1414 case 'Q': next->flags |= rewrite_qualify; break;
1415 case 'R': next->flags |= rewrite_repeat; break;
1416
1417 case 'S':
1418 next->flags |= rewrite_smtp;
1419 if (next->key[0] != '^' && Ustrncmp(next->key, "\\N^", 3) != 0)
1420 log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN,
1421 "rewrite rule has the S flag but is not a regular expression");
1422 break;
1423
1424 default:
1425 log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN,
1426 "unknown rewrite flag character '%c' "
1427 "(could be missing quotes round replacement item)", p[-1]);
1428 break;
1429 }
1430
1431 /* If no action flags are set, set all the "normal" rewrites. */
1432
1433 if ((next->flags & (rewrite_all | rewrite_smtp)) == 0)
1434 next->flags |= isglobal? rewrite_all : rewrite_all_headers;
1435
1436 /* Remember which exist, for optimization, and return the rule */
1437
1438 *existflags |= next->flags;
1439 return next;
1440 }
1441
1442
1443
1444
1445 /*************************************************
1446 * Read global rewrite information *
1447 *************************************************/
1448
1449 /* Each line is a single rewrite rule; it is parsed into a control block
1450 by readconf_one_rewrite(), and its flags are ORed into the global flag
1451 word rewrite_existflags. */
1452
1453 void
1454 readconf_rewrites(void)
1455 {
1456 rewrite_rule **chain = &global_rewrite_rules;
1457 uschar *p;
1458
1459 while ((p = get_config_line()) != NULL)
1460 {
1461 rewrite_rule *next = readconf_one_rewrite(p, &rewrite_existflags, TRUE);
1462 *chain = next;
1463 chain = &(next->next);
1464 }
1465 }
1466
1467
1468
1469 /*************************************************
1470 * Read a string *
1471 *************************************************/
1472
1473 /* Strings are read into the normal store pool. As long we aren't too
1474 near the end of the current block, the string will just use what is necessary
1475 on the top of the stacking pool, because string_cat() uses the extension
1476 mechanism.
1477
1478 Argument:
1479 s the rest of the input line
1480 name the option name (for errors)
1481
1482 Returns: pointer to the string
1483 */
1484
1485 static uschar *
1486 read_string(const uschar *s, const uschar *name)
1487 {
1488 uschar *yield;
1489 const uschar *ss;
1490
1491 if (*s != '\"') return string_copy(s);
1492
1493 ss = s;
1494 yield = string_dequote(&s);
1495
1496 if (s == ss+1 || s[-1] != '\"')
1497 log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN,
1498 "missing quote at end of string value for %s", name);
1499
1500 if (*s != 0) extra_chars_error(s, US"string value for ", name, US"");
1501
1502 return yield;
1503 }
1504
1505
1506 /*************************************************
1507 * Custom-handler options *
1508 *************************************************/
1509 static void
1510 fn_smtp_receive_timeout(const uschar * name, const uschar * str)
1511 {
1512 if (*str == '$')
1513 smtp_receive_timeout_s = string_copy(str);
1514 else
1515 {
1516 /* "smtp_receive_timeout", opt_time, &smtp_receive_timeout */
1517 smtp_receive_timeout = readconf_readtime(str, 0, FALSE);
1518 if (smtp_receive_timeout < 0)
1519 log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, "invalid time value for %s",
1520 name);
1521 }
1522 }
1523
1524 /*************************************************
1525 * Handle option line *
1526 *************************************************/
1527
1528 /* This function is called from several places to process a line containing the
1529 setting of an option. The first argument is the line to be decoded; it has been
1530 checked not to be empty and not to start with '#'. Trailing newlines and white
1531 space have been removed. The second argument is a pointer to the list of
1532 variable names that are to be recognized, together with their types and
1533 locations, and the third argument gives the number of entries in the list.
1534
1535 The fourth argument is a pointer to a data block. If it is NULL, then the data
1536 values in the options list are absolute addresses. Otherwise, they are byte
1537 offsets in the data block.
1538
1539 String option data may continue onto several lines; this function reads further
1540 data from config_file if necessary.
1541
1542 The yield of this function is normally zero. If a string continues onto
1543 multiple lines, then the data value is permitted to be followed by a comma
1544 or a semicolon (for use in drivers) and the yield is that character.
1545
1546 Arguments:
1547 buffer contains the configuration line to be handled
1548 oltop points to the start of the relevant option list
1549 last one more than the offset of the last item in the option list
1550 data_block NULL when reading main options => data values in the option
1551 list are absolute addresses; otherwise they are byte offsets
1552 in data_block when they have opt_public set; otherwise
1553 they are byte offsets in data_block->options_block.
1554 unknown_txt format string to use in panic message for unknown option;
1555 must contain %s for option name
1556 if given as NULL, don't panic on unknown option
1557
1558 Returns: TRUE if an option was read successfully,
1559 FALSE false for an unknown option if unknown_txt == NULL,
1560 otherwise panic and die on an unknown option
1561 */
1562
1563 static BOOL
1564 readconf_handle_option(uschar *buffer, optionlist *oltop, int last,
1565 void *data_block, uschar *unknown_txt)
1566 {
1567 int ptr = 0;
1568 int offset = 0;
1569 int n, count, type, value;
1570 int issecure = 0;
1571 uid_t uid;
1572 gid_t gid;
1573 BOOL boolvalue = TRUE;
1574 BOOL freesptr = TRUE;
1575 optionlist *ol, *ol2;
1576 struct passwd *pw;
1577 void *reset_point;
1578 int intbase = 0;
1579 uschar *inttype = US"";
1580 uschar *sptr;
1581 uschar *s = buffer;
1582 uschar **str_target;
1583 uschar name[64];
1584 uschar name2[64];
1585
1586 /* There may be leading spaces; thereafter, we expect an option name starting
1587 with a letter. */
1588
1589 while (isspace(*s)) s++;
1590 if (!isalpha(*s))
1591 log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, "option setting expected: %s", s);
1592
1593 /* Read the name of the option, and skip any subsequent white space. If
1594 it turns out that what we read was "hide", set the flag indicating that
1595 this is a secure option, and loop to read the next word. */
1596
1597 for (n = 0; n < 2; n++)
1598 {
1599 while (isalnum(*s) || *s == '_')
1600 {
1601 if (ptr < sizeof(name)-1) name[ptr++] = *s;
1602 s++;
1603 }
1604 name[ptr] = 0;
1605 while (isspace(*s)) s++;
1606 if (Ustrcmp(name, "hide") != 0) break;
1607 issecure = opt_secure;
1608 ptr = 0;
1609 }
1610
1611 /* Deal with "no_" or "not_" here for booleans */
1612
1613 if (Ustrncmp(name, "no_", 3) == 0)
1614 {
1615 boolvalue = FALSE;
1616 offset = 3;
1617 }
1618
1619 if (Ustrncmp(name, "not_", 4) == 0)
1620 {
1621 boolvalue = FALSE;
1622 offset = 4;
1623 }
1624
1625 /* Search the list for the given name. A non-existent name, or an option that
1626 is set twice, is a disaster. */
1627
1628 if (!(ol = find_option(name + offset, oltop, last)))
1629 {
1630 if (unknown_txt == NULL) return FALSE;
1631 log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, CS unknown_txt, name);
1632 }
1633
1634 if ((ol->type & opt_set) && !(ol->type & (opt_rep_con | opt_rep_str)))
1635 log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN,
1636 "\"%s\" option set for the second time", name);
1637
1638 ol->type |= opt_set | issecure;
1639 type = ol->type & opt_mask;
1640
1641 /* Types with data values must be followed by '='; the "no[t]_" prefix
1642 applies only to boolean values. */
1643
1644 if (type < opt_bool || type > opt_bool_last)
1645 {
1646 if (offset != 0)
1647 log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN,
1648 "negation prefix applied to a non-boolean option");
1649 if (*s == 0)
1650 log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN,
1651 "unexpected end of line (data missing) after %s", name);
1652 if (*s != '=')
1653 log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, "missing \"=\" after %s", name);
1654 }
1655
1656 /* If a boolean wasn't preceded by "no[t]_" it can be followed by = and
1657 true/false/yes/no, or, in the case of opt_expand_bool, a general string that
1658 ultimately expands to one of those values. */
1659
1660 else if (*s != 0 && (offset != 0 || *s != '='))
1661 extra_chars_error(s, US"boolean option ", name, US"");
1662
1663 /* Skip white space after = */
1664
1665 if (*s == '=') while (isspace((*(++s))));
1666
1667 /* If there is a data block and the opt_public flag is not set, change
1668 the data block pointer to the private options block. */
1669
1670 if (data_block != NULL && (ol->type & opt_public) == 0)
1671 data_block = (void *)(((driver_instance *)data_block)->options_block);
1672
1673 /* Now get the data according to the type. */
1674
1675 switch (type)
1676 {
1677 /* If a string value is not enclosed in quotes, it consists of
1678 the rest of the current line, verbatim. Otherwise, string escapes
1679 are processed.
1680
1681 A transport is specified as a string, which is then looked up in the
1682 list of transports. A search type is specified as one of a number of
1683 known strings.
1684
1685 A set or rewrite rules for a driver is specified as a string, which is
1686 then parsed into a suitable chain of control blocks.
1687
1688 Uids and gids are specified as strings which are then looked up in the
1689 passwd file. Lists of uids and gids are similarly specified as colon-
1690 separated strings. */
1691
1692 case opt_stringptr:
1693 case opt_uid:
1694 case opt_gid:
1695 case opt_expand_uid:
1696 case opt_expand_gid:
1697 case opt_uidlist:
1698 case opt_gidlist:
1699 case opt_rewrite:
1700
1701 reset_point = sptr = read_string(s, name);
1702
1703 /* Having read a string, we now have several different ways of using it,
1704 depending on the data type, so do another switch. If keeping the actual
1705 string is not required (because it is interpreted), freesptr is set TRUE,
1706 and at the end we reset the pool. */
1707
1708 switch (type)
1709 {
1710 /* If this was a string, set the variable to point to the new string,
1711 and set the flag so its store isn't reclaimed. If it was a list of rewrite
1712 rules, we still keep the string (for printing), and parse the rules into a
1713 control block and flags word. */
1714
1715 case opt_stringptr:
1716 str_target = data_block ? USS (US data_block + (long int)(ol->value))
1717 : USS (ol->value);
1718 if (ol->type & opt_rep_con)
1719 {
1720 uschar * saved_condition;
1721 /* We already have a condition, we're conducting a crude hack to let
1722 multiple condition rules be chained together, despite storing them in
1723 text form. */
1724 *str_target = string_copy_malloc( (saved_condition = *str_target)
1725 ? string_sprintf("${if and{{bool_lax{%s}}{bool_lax{%s}}}}",
1726 saved_condition, sptr)
1727 : sptr);
1728 /* TODO(pdp): there is a memory leak here and just below
1729 when we set 3 or more conditions; I still don't
1730 understand the store mechanism enough to know
1731 what's the safe way to free content from an earlier store.
1732 AFAICT, stores stack, so freeing an early stored item also stores
1733 all data alloc'd after it. If we knew conditions were adjacent,
1734 we could survive that, but we don't. So I *think* we need to take
1735 another bit from opt_type to indicate "malloced"; this seems like
1736 quite a hack, especially for this one case. It also means that
1737 we can't ever reclaim the store from the *first* condition.
1738
1739 Because we only do this once, near process start-up, I'm prepared to
1740 let this slide for the time being, even though it rankles. */
1741 }
1742 else if (ol->type & opt_rep_str)
1743 {
1744 uschar sep_o = Ustrncmp(name, "headers_add", 11)==0 ? '\n' : ':';
1745 int sep_i = -(int)sep_o;
1746 const uschar * list = sptr;
1747 uschar * s;
1748 gstring * list_o = NULL;
1749
1750 if (*str_target)
1751 {
1752 list_o = string_get(Ustrlen(*str_target) + Ustrlen(sptr));
1753 list_o = string_cat(list_o, *str_target);
1754 }
1755
1756 while ((s = string_nextinlist(&list, &sep_i, NULL, 0)))
1757 list_o = string_append_listele(list_o, sep_o, s);
1758
1759 if (list_o)
1760 *str_target = string_copy_malloc(string_from_gstring(list_o));
1761 }
1762 else
1763 {
1764 *str_target = sptr;
1765 freesptr = FALSE;
1766 }
1767 break;
1768
1769 case opt_rewrite:
1770 if (data_block)
1771 *USS (US data_block + (long int)(ol->value)) = sptr;
1772 else
1773 *USS (ol->value) = sptr;
1774 freesptr = FALSE;
1775 if (type == opt_rewrite)
1776 {
1777 int sep = 0;
1778 int *flagptr;
1779 uschar *p = sptr;
1780 rewrite_rule **chain;
1781 optionlist *ol3;
1782
1783 sprintf(CS name2, "*%.50s_rules", name);
1784 ol2 = find_option(name2, oltop, last);
1785 sprintf(CS name2, "*%.50s_flags", name);
1786 ol3 = find_option(name2, oltop, last);
1787
1788 if (ol2 == NULL || ol3 == NULL)
1789 log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN,
1790 "rewrite rules not available for driver");
1791
1792 if (data_block == NULL)
1793 {
1794 chain = (rewrite_rule **)(ol2->value);
1795 flagptr = (int *)(ol3->value);
1796 }
1797 else
1798 {
1799 chain = (rewrite_rule **)(US data_block + (long int)(ol2->value));
1800 flagptr = (int *)(US data_block + (long int)(ol3->value));
1801 }
1802
1803 while ((p = string_nextinlist(CUSS &sptr, &sep, big_buffer, BIG_BUFFER_SIZE)))
1804 {
1805 rewrite_rule *next = readconf_one_rewrite(p, flagptr, FALSE);
1806 *chain = next;
1807 chain = &(next->next);
1808 }
1809
1810 if ((*flagptr & (rewrite_all_envelope | rewrite_smtp)) != 0)
1811 log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, "rewrite rule specifies a "
1812 "non-header rewrite - not allowed at transport time -");
1813 }
1814 break;
1815
1816 /* If it was an expanded uid, see if there is any expansion to be
1817 done by checking for the presence of a $ character. If there is, save it
1818 in the corresponding *expand_user option field. Otherwise, fall through
1819 to treat it as a fixed uid. Ensure mutual exclusivity of the two kinds
1820 of data. */
1821
1822 case opt_expand_uid:
1823 sprintf(CS name2, "*expand_%.50s", name);
1824 ol2 = find_option(name2, oltop, last);
1825 if (ol2 != NULL)
1826 {
1827 uschar *ss = (Ustrchr(sptr, '$') != NULL)? sptr : NULL;
1828
1829 if (data_block == NULL)
1830 *((uschar **)(ol2->value)) = ss;
1831 else
1832 *((uschar **)(US data_block + (long int)(ol2->value))) = ss;
1833
1834 if (ss != NULL)
1835 {
1836 *(get_set_flag(name, oltop, last, data_block)) = FALSE;
1837 freesptr = FALSE;
1838 break;
1839 }
1840 }
1841
1842 /* Look up a fixed uid, and also make use of the corresponding gid
1843 if a passwd entry is returned and the gid has not been set. */
1844
1845 case opt_uid:
1846 if (!route_finduser(sptr, &pw, &uid))
1847 log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, "user %s was not found", sptr);
1848 if (data_block == NULL)
1849 *((uid_t *)(ol->value)) = uid;
1850 else
1851 *((uid_t *)(US data_block + (long int)(ol->value))) = uid;
1852
1853 /* Set the flag indicating a fixed value is set */
1854
1855 *(get_set_flag(name, oltop, last, data_block)) = TRUE;
1856
1857 /* Handle matching gid if we have a passwd entry: done by finding the
1858 same name with terminating "user" changed to "group"; if not found,
1859 ignore. Also ignore if the value is already set. */
1860
1861 if (pw == NULL) break;
1862 Ustrcpy(name+Ustrlen(name)-4, "group");
1863 ol2 = find_option(name, oltop, last);
1864 if (ol2 != NULL && ((ol2->type & opt_mask) == opt_gid ||
1865 (ol2->type & opt_mask) == opt_expand_gid))
1866 {
1867 BOOL *set_flag = get_set_flag(name, oltop, last, data_block);
1868 if (! *set_flag)
1869 {
1870 if (data_block == NULL)
1871 *((gid_t *)(ol2->value)) = pw->pw_gid;
1872 else
1873 *((gid_t *)(US data_block + (long int)(ol2->value))) = pw->pw_gid;
1874 *set_flag = TRUE;
1875 }
1876 }
1877 break;
1878
1879 /* If it was an expanded gid, see if there is any expansion to be
1880 done by checking for the presence of a $ character. If there is, save it
1881 in the corresponding *expand_user option field. Otherwise, fall through
1882 to treat it as a fixed gid. Ensure mutual exclusivity of the two kinds
1883 of data. */
1884
1885 case opt_expand_gid:
1886 sprintf(CS name2, "*expand_%.50s", name);
1887 ol2 = find_option(name2, oltop, last);
1888 if (ol2 != NULL)
1889 {
1890 uschar *ss = (Ustrchr(sptr, '$') != NULL)? sptr : NULL;
1891
1892 if (data_block == NULL)
1893 *((uschar **)(ol2->value)) = ss;
1894 else
1895 *((uschar **)(US data_block + (long int)(ol2->value))) = ss;
1896
1897 if (ss != NULL)
1898 {
1899 *(get_set_flag(name, oltop, last, data_block)) = FALSE;
1900 freesptr = FALSE;
1901 break;
1902 }
1903 }
1904
1905 /* Handle freestanding gid */
1906
1907 case opt_gid:
1908 if (!route_findgroup(sptr, &gid))
1909 log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, "group %s was not found", sptr);
1910 if (data_block == NULL)
1911 *((gid_t *)(ol->value)) = gid;
1912 else
1913 *((gid_t *)(US data_block + (long int)(ol->value))) = gid;
1914 *(get_set_flag(name, oltop, last, data_block)) = TRUE;
1915 break;
1916
1917 /* If it was a uid list, look up each individual entry, and build
1918 a vector of uids, with a count in the first element. Put the vector
1919 in malloc store so we can free the string. (We are reading into
1920 permanent store already.) */
1921
1922 case opt_uidlist:
1923 {
1924 int count = 1;
1925 uid_t *list;
1926 int ptr = 0;
1927 const uschar *p;
1928 const uschar *op = expand_string (sptr);
1929
1930 if (op == NULL)
1931 log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, "failed to expand %s: %s",
1932 name, expand_string_message);
1933
1934 p = op;
1935 if (*p != 0) count++;
1936 while (*p != 0) if (*p++ == ':' && *p != 0) count++;
1937 list = store_malloc(count*sizeof(uid_t));
1938 list[ptr++] = (uid_t)(count - 1);
1939
1940 if (data_block == NULL)
1941 *((uid_t **)(ol->value)) = list;
1942 else
1943 *((uid_t **)(US data_block + (long int)(ol->value))) = list;
1944
1945 p = op;
1946 while (count-- > 1)
1947 {
1948 int sep = 0;
1949 (void)string_nextinlist(&p, &sep, big_buffer, BIG_BUFFER_SIZE);
1950 if (!route_finduser(big_buffer, NULL, &uid))
1951 log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, "user %s was not found",
1952 big_buffer);
1953 list[ptr++] = uid;
1954 }
1955 }
1956 break;
1957
1958 /* If it was a gid list, look up each individual entry, and build
1959 a vector of gids, with a count in the first element. Put the vector
1960 in malloc store so we can free the string. (We are reading into permanent
1961 store already.) */
1962
1963 case opt_gidlist:
1964 {
1965 int count = 1;
1966 gid_t *list;
1967 int ptr = 0;
1968 const uschar *p;
1969 const uschar *op = expand_string (sptr);
1970
1971 if (op == NULL)
1972 log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, "failed to expand %s: %s",
1973 name, expand_string_message);
1974
1975 p = op;
1976 if (*p != 0) count++;
1977 while (*p != 0) if (*p++ == ':' && *p != 0) count++;
1978 list = store_malloc(count*sizeof(gid_t));
1979 list[ptr++] = (gid_t)(count - 1);
1980
1981 if (data_block == NULL)
1982 *((gid_t **)(ol->value)) = list;
1983 else
1984 *((gid_t **)(US data_block + (long int)(ol->value))) = list;
1985
1986 p = op;
1987 while (count-- > 1)
1988 {
1989 int sep = 0;
1990 (void)string_nextinlist(&p, &sep, big_buffer, BIG_BUFFER_SIZE);
1991 if (!route_findgroup(big_buffer, &gid))
1992 log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, "group %s was not found",
1993 big_buffer);
1994 list[ptr++] = gid;
1995 }
1996 }
1997 break;
1998 }
1999
2000 /* Release store if the value of the string doesn't need to be kept. */
2001
2002 if (freesptr) store_reset(reset_point);
2003 break;
2004
2005 /* Expanded boolean: if no characters follow, or if there are no dollar
2006 characters, this is a fixed-valued boolean, and we fall through. Otherwise,
2007 save the string for later expansion in the alternate place. */
2008
2009 case opt_expand_bool:
2010 if (*s != 0 && Ustrchr(s, '$') != 0)
2011 {
2012 sprintf(CS name2, "*expand_%.50s", name);
2013 ol2 = find_option(name2, oltop, last);
2014 if (ol2 != NULL)
2015 {
2016 reset_point = sptr = read_string(s, name);
2017 if (data_block == NULL)
2018 *((uschar **)(ol2->value)) = sptr;
2019 else
2020 *((uschar **)(US data_block + (long int)(ol2->value))) = sptr;
2021 freesptr = FALSE;
2022 break;
2023 }
2024 }
2025 /* Fall through */
2026
2027 /* Boolean: if no characters follow, the value is boolvalue. Otherwise
2028 look for yes/not/true/false. Some booleans are stored in a single bit in
2029 a single int. There's a special fudge for verify settings; without a suffix
2030 they set both xx_sender and xx_recipient. The table points to the sender
2031 value; search subsequently for the recipient. There's another special case:
2032 opt_bool_set also notes when a boolean has been set. */
2033
2034 case opt_bool:
2035 case opt_bit:
2036 case opt_bool_verify:
2037 case opt_bool_set:
2038 if (*s != 0)
2039 {
2040 s = readconf_readname(name2, 64, s);
2041 if (strcmpic(name2, US"true") == 0 || strcmpic(name2, US"yes") == 0)
2042 boolvalue = TRUE;
2043 else if (strcmpic(name2, US"false") == 0 || strcmpic(name2, US"no") == 0)
2044 boolvalue = FALSE;
2045 else log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN,
2046 "\"%s\" is not a valid value for the \"%s\" option", name2, name);
2047 if (*s != 0) extra_chars_error(s, string_sprintf("\"%s\" ", name2),
2048 US"for boolean option ", name);
2049 }
2050
2051 /* Handle single-bit type. */
2052
2053 if (type == opt_bit)
2054 {
2055 int bit = 1 << ((ol->type >> 16) & 31);
2056 int *ptr = (data_block == NULL)?
2057 (int *)(ol->value) :
2058 (int *)(US data_block + (long int)ol->value);
2059 if (boolvalue) *ptr |= bit; else *ptr &= ~bit;
2060 break;
2061 }
2062
2063 /* Handle full BOOL types */
2064
2065 if (data_block == NULL)
2066 *((BOOL *)(ol->value)) = boolvalue;
2067 else
2068 *((BOOL *)(US data_block + (long int)(ol->value))) = boolvalue;
2069
2070 /* Verify fudge */
2071
2072 if (type == opt_bool_verify)
2073 {
2074 sprintf(CS name2, "%.50s_recipient", name + offset);
2075 ol2 = find_option(name2, oltop, last);
2076 if (ol2 != NULL)
2077 {
2078 if (data_block == NULL)
2079 *((BOOL *)(ol2->value)) = boolvalue;
2080 else
2081 *((BOOL *)(US data_block + (long int)(ol2->value))) = boolvalue;
2082 }
2083 }
2084
2085 /* Note that opt_bool_set type is set, if there is somewhere to do so */
2086
2087 else if (type == opt_bool_set)
2088 {
2089 sprintf(CS name2, "*set_%.50s", name + offset);
2090 ol2 = find_option(name2, oltop, last);
2091 if (ol2 != NULL)
2092 {
2093 if (data_block == NULL)
2094 *((BOOL *)(ol2->value)) = TRUE;
2095 else
2096 *((BOOL *)(US data_block + (long int)(ol2->value))) = TRUE;
2097 }
2098 }
2099 break;
2100
2101 /* Octal integer */
2102
2103 case opt_octint:
2104 intbase = 8;
2105 inttype = US"octal ";
2106
2107 /* Integer: a simple(ish) case; allow octal and hex formats, and
2108 suffixes K, M and G. The different types affect output, not input. */
2109
2110 case opt_mkint:
2111 case opt_int:
2112 {
2113 uschar *endptr;
2114 long int lvalue;
2115
2116 errno = 0;
2117 lvalue = strtol(CS s, CSS &endptr, intbase);
2118
2119 if (endptr == s)
2120 log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, "%sinteger expected for %s",
2121 inttype, name);
2122
2123 if (errno != ERANGE)
2124 if (tolower(*endptr) == 'k')
2125 {
2126 if (lvalue > INT_MAX/1024 || lvalue < INT_MIN/1024) errno = ERANGE;
2127 else lvalue *= 1024;
2128 endptr++;
2129 }
2130 else if (tolower(*endptr) == 'm')
2131 {
2132 if (lvalue > INT_MAX/(1024*1024) || lvalue < INT_MIN/(1024*1024))
2133 errno = ERANGE;
2134 else lvalue *= 1024*1024;
2135 endptr++;
2136 }
2137 else if (tolower(*endptr) == 'g')
2138 {
2139 if (lvalue > INT_MAX/(1024*1024*1024) || lvalue < INT_MIN/(1024*1024*1024))
2140 errno = ERANGE;
2141 else lvalue *= 1024*1024*1024;
2142 endptr++;
2143 }
2144
2145 if (errno == ERANGE || lvalue > INT_MAX || lvalue < INT_MIN)
2146 log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN,
2147 "absolute value of integer \"%s\" is too large (overflow)", s);
2148
2149 while (isspace(*endptr)) endptr++;
2150 if (*endptr != 0)
2151 extra_chars_error(endptr, inttype, US"integer value for ", name);
2152
2153 value = (int)lvalue;
2154 }
2155
2156 if (data_block == NULL)
2157 *((int *)(ol->value)) = value;
2158 else
2159 *((int *)(US data_block + (long int)(ol->value))) = value;
2160 break;
2161
2162 /* Integer held in K: again, allow octal and hex formats, and suffixes K, M
2163 and G. */
2164 /*XXX consider moving to int_eximarith_t (but mind the overflow test 0415) */
2165
2166 case opt_Kint:
2167 {
2168 uschar *endptr;
2169 errno = 0;
2170 value = strtol(CS s, CSS &endptr, intbase);
2171
2172 if (endptr == s)
2173 log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, "%sinteger expected for %s",
2174 inttype, name);
2175
2176 if (errno != ERANGE)
2177 if (tolower(*endptr) == 'g')
2178 {
2179 if (value > INT_MAX/(1024*1024) || value < INT_MIN/(1024*1024))
2180 errno = ERANGE;
2181 else
2182 value *= 1024*1024;
2183 endptr++;
2184 }
2185 else if (tolower(*endptr) == 'm')
2186 {
2187 if (value > INT_MAX/1024 || value < INT_MIN/1024)
2188 errno = ERANGE;
2189 else
2190 value *= 1024;
2191 endptr++;
2192 }
2193 else if (tolower(*endptr) == 'k')
2194 endptr++;
2195 else
2196 value = (value + 512)/1024;
2197
2198 if (errno == ERANGE) log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN,
2199 "absolute value of integer \"%s\" is too large (overflow)", s);
2200
2201 while (isspace(*endptr)) endptr++;
2202 if (*endptr != 0)
2203 extra_chars_error(endptr, inttype, US"integer value for ", name);
2204 }
2205
2206 if (data_block == NULL)
2207 *((int *)(ol->value)) = value;
2208 else
2209 *((int *)(US data_block + (long int)(ol->value))) = value;
2210 break;
2211
2212 /* Fixed-point number: held to 3 decimal places. */
2213
2214 case opt_fixed:
2215 if (sscanf(CS s, "%d%n", &value, &count) != 1)
2216 log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN,
2217 "fixed-point number expected for %s", name);
2218
2219 if (value < 0) log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN,
2220 "integer \"%s\" is too large (overflow)", s);
2221
2222 value *= 1000;
2223
2224 if (value < 0) log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN,
2225 "integer \"%s\" is too large (overflow)", s);
2226
2227 /* We get a coverity error here for using count, as it derived
2228 from the tainted buffer pointed to by s, as parsed by sscanf().
2229 By the definition of sscanf we must be accessing between start
2230 and end of s (assuming it is nul-terminated...) so ignore the error. */
2231 /* coverity[tainted_data] */
2232 if (s[count] == '.')
2233 {
2234 int d = 100;
2235 while (isdigit(s[++count]))
2236 {
2237 value += (s[count] - '0') * d;
2238 d /= 10;
2239 }
2240 }
2241
2242 while (isspace(s[count])) count++;
2243
2244 if (s[count] != 0)
2245 extra_chars_error(s+count, US"fixed-point value for ", name, US"");
2246
2247 if (data_block == NULL)
2248 *((int *)(ol->value)) = value;
2249 else
2250 *((int *)(US data_block + (long int)(ol->value))) = value;
2251 break;
2252
2253 /* There's a special routine to read time values. */
2254
2255 case opt_time:
2256 value = readconf_readtime(s, 0, FALSE);
2257 if (value < 0)
2258 log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, "invalid time value for %s",
2259 name);
2260 if (data_block == NULL)
2261 *((int *)(ol->value)) = value;
2262 else
2263 *((int *)(US data_block + (long int)(ol->value))) = value;
2264 break;
2265
2266 /* A time list is a list of colon-separated times, with the first
2267 element holding the size of the list and the second the number of
2268 entries used. */
2269
2270 case opt_timelist:
2271 {
2272 int count = 0;
2273 int *list = (data_block == NULL)?
2274 (int *)(ol->value) :
2275 (int *)(US data_block + (long int)(ol->value));
2276
2277 if (*s != 0) for (count = 1; count <= list[0] - 2; count++)
2278 {
2279 int terminator = 0;
2280 uschar *snext = Ustrchr(s, ':');
2281 if (snext != NULL)
2282 {
2283 uschar *ss = snext;
2284 while (ss > s && isspace(ss[-1])) ss--;
2285 terminator = *ss;
2286 }
2287 value = readconf_readtime(s, terminator, FALSE);
2288 if (value < 0)
2289 log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, "invalid time value for %s",
2290 name);
2291 if (count > 1 && value <= list[count])
2292 log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN,
2293 "time value out of order for %s", name);
2294 list[count+1] = value;
2295 if (snext == NULL) break;
2296 s = snext + 1;
2297 while (isspace(*s)) s++;
2298 }
2299
2300 if (count > list[0] - 2)
2301 log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, "too many time values for %s",
2302 name);
2303 if (count > 0 && list[2] == 0) count = 0;
2304 list[1] = count;
2305 break;
2306 }
2307
2308 case opt_func:
2309 {
2310 void (*fn)() = ol->value;
2311 fn(name, s);
2312 break;
2313 }
2314 }
2315
2316 return TRUE;
2317 }
2318
2319
2320
2321 /*************************************************
2322 * Print a time value *
2323 *************************************************/
2324
2325 /*
2326 Argument: a time value in seconds
2327 Returns: pointer to a fixed buffer containing the time as a string,
2328 in readconf_readtime() format
2329 */
2330
2331 uschar *
2332 readconf_printtime(int t)
2333 {
2334 int s, m, h, d, w;
2335 uschar *p = time_buffer;
2336
2337 if (t < 0)
2338 {
2339 *p++ = '-';
2340 t = -t;
2341 }
2342
2343 s = t % 60;
2344 t /= 60;
2345 m = t % 60;
2346 t /= 60;
2347 h = t % 24;
2348 t /= 24;
2349 d = t % 7;
2350 w = t/7;
2351
2352 if (w > 0) p += sprintf(CS p, "%dw", w);
2353 if (d > 0) p += sprintf(CS p, "%dd", d);
2354 if (h > 0) p += sprintf(CS p, "%dh", h);
2355 if (m > 0) p += sprintf(CS p, "%dm", m);
2356 if (s > 0 || p == time_buffer) sprintf(CS p, "%ds", s);
2357
2358 return time_buffer;
2359 }
2360
2361
2362
2363 /*************************************************
2364 * Print an individual option value *
2365 *************************************************/
2366
2367 /* This is used by the -bP option, so prints to the standard output.
2368 The entire options list is passed in as an argument, because some options come
2369 in pairs - typically uid/gid settings, which can either be explicit numerical
2370 values, or strings to be expanded later. If the numerical value is unset,
2371 search for "*expand_<name>" to see if there is a string equivalent.
2372
2373 Arguments:
2374 ol option entry, or NULL for an unknown option
2375 name option name
2376 options_block NULL for main configuration options; otherwise points to
2377 a driver block; if the option doesn't have opt_public
2378 set, then options_block->options_block is where the item
2379 resides.
2380 oltop points to the option list in which ol exists
2381 last one more than the offset of the last entry in optop
2382 no_labels do not show "foo = " at the start.
2383
2384 Returns: boolean success
2385 */
2386
2387 static BOOL
2388 print_ol(optionlist *ol, uschar *name, void *options_block,
2389 optionlist *oltop, int last, BOOL no_labels)
2390 {
2391 struct passwd *pw;
2392 struct group *gr;
2393 optionlist *ol2;
2394 void *value;
2395 uid_t *uidlist;
2396 gid_t *gidlist;
2397 uschar *s;
2398 uschar name2[64];
2399
2400 if (!ol)
2401 {
2402 printf("%s is not a known option\n", name);
2403 return FALSE;
2404 }
2405
2406 /* Non-admin callers cannot see options that have been flagged secure by the
2407 "hide" prefix. */
2408
2409 if (!admin_user && ol->type & opt_secure)
2410 {
2411 if (no_labels)
2412 printf("%s\n", hidden);
2413 else
2414 printf("%s = %s\n", name, hidden);
2415 return TRUE;
2416 }
2417
2418 /* Else show the value of the option */
2419
2420 value = ol->value;
2421 if (options_block)
2422 {
2423 if (!(ol->type & opt_public))
2424 options_block = (void *)(((driver_instance *)options_block)->options_block);
2425 value = (void *)(US options_block + (long int)value);
2426 }
2427
2428 switch(ol->type & opt_mask)
2429 {
2430 case opt_stringptr:
2431 case opt_rewrite: /* Show the text value */
2432 s = *(USS value);
2433 if (!no_labels) printf("%s = ", name);
2434 printf("%s\n", s ? string_printing2(s, FALSE) : US"");
2435 break;
2436
2437 case opt_int:
2438 if (!no_labels) printf("%s = ", name);
2439 printf("%d\n", *((int *)value));
2440 break;
2441
2442 case opt_mkint:
2443 {
2444 int x = *((int *)value);
2445 if (x != 0 && (x & 1023) == 0)
2446 {
2447 int c = 'K';
2448 x >>= 10;
2449 if ((x & 1023) == 0)
2450 {
2451 c = 'M';
2452 x >>= 10;
2453 }
2454 if (!no_labels) printf("%s = ", name);
2455 printf("%d%c\n", x, c);
2456 }
2457 else
2458 {
2459 if (!no_labels) printf("%s = ", name);
2460 printf("%d\n", x);
2461 }
2462 }
2463 break;
2464
2465 case opt_Kint:
2466 {
2467 int x = *((int *)value);
2468 if (!no_labels) printf("%s = ", name);
2469 if (x == 0) printf("0\n");
2470 else if ((x & 1023) == 0) printf("%dM\n", x >> 10);
2471 else printf("%dK\n", x);
2472 }
2473 break;
2474
2475 case opt_octint:
2476 if (!no_labels) printf("%s = ", name);
2477 printf("%#o\n", *((int *)value));
2478 break;
2479
2480 /* Can be negative only when "unset", in which case integer */
2481
2482 case opt_fixed:
2483 {
2484 int x = *((int *)value);
2485 int f = x % 1000;
2486 int d = 100;
2487 if (x < 0) printf("%s =\n", name); else
2488 {
2489 if (!no_labels) printf("%s = ", name);
2490 printf("%d.", x/1000);
2491 do
2492 {
2493 printf("%d", f/d);
2494 f %= d;
2495 d /= 10;
2496 }
2497 while (f != 0);
2498 printf("\n");
2499 }
2500 }
2501 break;
2502
2503 /* If the numerical value is unset, try for the string value */
2504
2505 case opt_expand_uid:
2506 if (! *get_set_flag(name, oltop, last, options_block))
2507 {
2508 sprintf(CS name2, "*expand_%.50s", name);
2509 if ((ol2 = find_option(name2, oltop, last)))
2510 {
2511 void *value2 = ol2->value;
2512 if (options_block)
2513 value2 = (void *)(US options_block + (long int)value2);
2514 s = *(USS value2);
2515 if (!no_labels) printf("%s = ", name);
2516 printf("%s\n", s ? string_printing(s) : US"");
2517 break;
2518 }
2519 }
2520
2521 /* Else fall through */
2522
2523 case opt_uid:
2524 if (!no_labels) printf("%s = ", name);
2525 if (! *get_set_flag(name, oltop, last, options_block))
2526 printf("\n");
2527 else
2528 if ((pw = getpwuid(*((uid_t *)value))))
2529 printf("%s\n", pw->pw_name);
2530 else
2531 printf("%ld\n", (long int)(*((uid_t *)value)));
2532 break;
2533
2534 /* If the numerical value is unset, try for the string value */
2535
2536 case opt_expand_gid:
2537 if (! *get_set_flag(name, oltop, last, options_block))
2538 {
2539 sprintf(CS name2, "*expand_%.50s", name);
2540 if ( (ol2 = find_option(name2, oltop, last))
2541 && (ol2->type & opt_mask) == opt_stringptr)
2542 {
2543 void *value2 = ol2->value;
2544 if (options_block)
2545 value2 = (void *)(US options_block + (long int)value2);
2546 s = *(USS value2);
2547 if (!no_labels) printf("%s = ", name);
2548 printf("%s\n", s ? string_printing(s) : US"");
2549 break;
2550 }
2551 }
2552
2553 /* Else fall through */
2554
2555 case opt_gid:
2556 if (!no_labels) printf("%s = ", name);
2557 if (! *get_set_flag(name, oltop, last, options_block))
2558 printf("\n");
2559 else
2560 if ((gr = getgrgid(*((int *)value))))
2561 printf("%s\n", gr->gr_name);
2562 else
2563 printf("%ld\n", (long int)(*((int *)value)));
2564 break;
2565
2566 case opt_uidlist:
2567 uidlist = *((uid_t **)value);
2568 if (!no_labels) printf("%s =", name);
2569 if (uidlist)
2570 {
2571 int i;
2572 uschar sep = no_labels ? '\0' : ' ';
2573 for (i = 1; i <= (int)(uidlist[0]); i++)
2574 {
2575 uschar *name = NULL;
2576 if ((pw = getpwuid(uidlist[i]))) name = US pw->pw_name;
2577 if (sep != '\0') printf("%c", sep);
2578 if (name) printf("%s", name);
2579 else printf("%ld", (long int)(uidlist[i]));
2580 sep = ':';
2581 }
2582 }
2583 printf("\n");
2584 break;
2585
2586 case opt_gidlist:
2587 gidlist = *((gid_t **)value);
2588 if (!no_labels) printf("%s =", name);
2589 if (gidlist)
2590 {
2591 int i;
2592 uschar sep = no_labels ? '\0' : ' ';
2593 for (i = 1; i <= (int)(gidlist[0]); i++)
2594 {
2595 uschar *name = NULL;
2596 if ((gr = getgrgid(gidlist[i]))) name = US gr->gr_name;
2597 if (sep != '\0') printf("%c", sep);
2598 if (name) printf("%s", name);
2599 else printf("%ld", (long int)(gidlist[i]));
2600 sep = ':';
2601 }
2602 }
2603 printf("\n");
2604 break;
2605
2606 case opt_time:
2607 if (!no_labels) printf("%s = ", name);
2608 printf("%s\n", readconf_printtime(*((int *)value)));
2609 break;
2610
2611 case opt_timelist:
2612 {
2613 int i;
2614 int *list = (int *)value;
2615 if (!no_labels) printf("%s = ", name);
2616 for (i = 0; i < list[1]; i++)
2617 printf("%s%s", i == 0 ? "" : ":", readconf_printtime(list[i+2]));
2618 printf("\n");
2619 }
2620 break;
2621
2622 case opt_bit:
2623 printf("%s%s\n", ((*((int *)value)) & (1 << ((ol->type >> 16) & 31)))?
2624 "" : "no_", name);
2625 break;
2626
2627 case opt_expand_bool:
2628 sprintf(CS name2, "*expand_%.50s", name);
2629 if ((ol2 = find_option(name2, oltop, last)) && ol2->value)
2630 {
2631 void *value2 = ol2->value;
2632 if (options_block)
2633 value2 = (void *)(US options_block + (long int)value2);
2634 s = *(USS value2);
2635 if (s)
2636 {
2637 if (!no_labels) printf("%s = ", name);
2638 printf("%s\n", string_printing(s));
2639 break;
2640 }
2641 /* s == NULL => string not set; fall through */
2642 }
2643
2644 /* Fall through */
2645
2646 case opt_bool:
2647 case opt_bool_verify:
2648 case opt_bool_set:
2649 printf("%s%s\n", (*((BOOL *)value))? "" : "no_", name);
2650 break;
2651 }
2652 return TRUE;
2653 }
2654
2655
2656
2657 /*************************************************
2658 * Print value from main configuration *
2659 *************************************************/
2660
2661 /* This function, called as a result of encountering the -bP option,
2662 causes the value of any main configuration variable to be output if the
2663 second argument is NULL. There are some special values:
2664
2665 all print all main configuration options
2666 config_file print the name of the configuration file
2667 (configure_file will still work, for backward
2668 compatibility)
2669 routers print the routers' configurations
2670 transports print the transports' configuration
2671 authenticators print the authenticators' configuration
2672 macros print the macros' configuration
2673 router_list print a list of router names
2674 transport_list print a list of transport names
2675 authenticator_list print a list of authentication mechanism names
2676 macro_list print a list of macro names
2677 +name print a named list item
2678 local_scan print the local_scan options
2679 config print the configuration as it is parsed
2680 environment print the used execution environment
2681
2682 If the second argument is not NULL, it must be one of "router", "transport",
2683 "authenticator" or "macro" in which case the first argument identifies the
2684 driver whose options are to be printed.
2685
2686 Arguments:
2687 name option name if type == NULL; else driver name
2688 type NULL or driver type name, as described above
2689 no_labels avoid the "foo = " at the start of an item
2690
2691 Returns: Boolean success
2692 */
2693
2694 BOOL
2695 readconf_print(uschar *name, uschar *type, BOOL no_labels)
2696 {
2697 BOOL names_only = FALSE;
2698 optionlist *ol;
2699 optionlist *ol2 = NULL;
2700 driver_instance *d = NULL;
2701 macro_item *m;
2702 int size = 0;
2703
2704 if (!type)
2705 {
2706 if (*name == '+')
2707 {
2708 int i;
2709 tree_node *t;
2710 BOOL found = FALSE;
2711 static uschar *types[] = { US"address", US"domain", US"host",
2712 US"localpart" };
2713 static tree_node **anchors[] = { &addresslist_anchor, &domainlist_anchor,
2714 &hostlist_anchor, &localpartlist_anchor };
2715
2716 for (i = 0; i < 4; i++)
2717 if ((t = tree_search(*(anchors[i]), name+1)))
2718 {
2719 found = TRUE;
2720 if (no_labels)
2721 printf("%s\n", ((namedlist_block *)(t->data.ptr))->string);
2722 else
2723 printf("%slist %s = %s\n", types[i], name+1,
2724 ((namedlist_block *)(t->data.ptr))->string);
2725 }
2726
2727 if (!found)
2728 printf("no address, domain, host, or local part list called \"%s\" "
2729 "exists\n", name+1);
2730
2731 return found;
2732 }
2733
2734 if ( Ustrcmp(name, "configure_file") == 0
2735 || Ustrcmp(name, "config_file") == 0)
2736 {
2737 printf("%s\n", CS config_main_filename);
2738 return TRUE;
2739 }
2740
2741 if (Ustrcmp(name, "all") == 0)
2742 {
2743 for (ol = optionlist_config;
2744 ol < optionlist_config + nelem(optionlist_config); ol++)
2745 if (!(ol->type & opt_hidden))
2746 (void) print_ol(ol, US ol->name, NULL,
2747 optionlist_config, nelem(optionlist_config),
2748 no_labels);
2749 return TRUE;
2750 }
2751
2752 if (Ustrcmp(name, "local_scan") == 0)
2753 {
2754 #ifndef LOCAL_SCAN_HAS_OPTIONS
2755 printf("local_scan() options are not supported\n");
2756 return FALSE;
2757 #else
2758 for (ol = local_scan_options;
2759 ol < local_scan_options + local_scan_options_count; ol++)
2760 (void) print_ol(ol, US ol->name, NULL, local_scan_options,
2761 local_scan_options_count, no_labels);
2762 return TRUE;
2763 #endif
2764 }
2765
2766 if (Ustrcmp(name, "config") == 0)
2767 {
2768 print_config(admin_user, no_labels);
2769 return TRUE;
2770 }
2771
2772 if (Ustrcmp(name, "routers") == 0)
2773 {
2774 type = US"router";
2775 name = NULL;
2776 }
2777 else if (Ustrcmp(name, "transports") == 0)
2778 {
2779 type = US"transport";
2780 name = NULL;
2781 }
2782 else if (Ustrcmp(name, "authenticators") == 0)
2783 {
2784 type = US"authenticator";
2785 name = NULL;
2786 }
2787 else if (Ustrcmp(name, "macros") == 0)
2788 {
2789 type = US"macro";
2790 name = NULL;
2791 }
2792 else if (Ustrcmp(name, "router_list") == 0)
2793 {
2794 type = US"router";
2795 name = NULL;
2796 names_only = TRUE;
2797 }
2798 else if (Ustrcmp(name, "transport_list") == 0)
2799 {
2800 type = US"transport";
2801 name = NULL;
2802 names_only = TRUE;
2803 }
2804 else if (Ustrcmp(name, "authenticator_list") == 0)
2805 {
2806 type = US"authenticator";
2807 name = NULL;
2808 names_only = TRUE;
2809 }
2810 else if (Ustrcmp(name, "macro_list") == 0)
2811 {
2812 type = US"macro";
2813 name = NULL;
2814 names_only = TRUE;
2815 }
2816 else if (Ustrcmp(name, "environment") == 0)
2817 {
2818 if (environ)
2819 {
2820 uschar ** p;
2821 for (p = USS environ; *p; p++) ;
2822 qsort(environ, p - USS environ, sizeof(*p), string_compare_by_pointer);
2823
2824 for (p = USS environ; *p; p++)
2825 {
2826 uschar * q;
2827 if (no_labels && (q = Ustrchr(*p, '='))) *q = '\0';
2828 puts(CS *p);
2829 }
2830 }
2831 return TRUE;
2832 }
2833
2834 else
2835 return print_ol(find_option(name,
2836 optionlist_config, nelem(optionlist_config)),
2837 name, NULL, optionlist_config, nelem(optionlist_config), no_labels);
2838 }
2839
2840 /* Handle the options for a router or transport. Skip options that are flagged
2841 as hidden. Some of these are options with names starting with '*', used for
2842 internal alternative representations of other options (which the printing
2843 function will sort out). Others are synonyms kept for backward compatibility.
2844 */
2845
2846 if (Ustrcmp(type, "router") == 0)
2847 {
2848 d = (driver_instance *)routers;
2849 ol2 = optionlist_routers;
2850 size = optionlist_routers_size;
2851 }
2852 else if (Ustrcmp(type, "transport") == 0)
2853 {
2854 d = (driver_instance *)transports;
2855 ol2 = optionlist_transports;
2856 size = optionlist_transports_size;
2857 }
2858 else if (Ustrcmp(type, "authenticator") == 0)
2859 {
2860 d = (driver_instance *)auths;
2861 ol2 = optionlist_auths;
2862 size = optionlist_auths_size;
2863 }
2864
2865 else if (Ustrcmp(type, "macro") == 0)
2866 {
2867 /* People store passwords in macros and they were previously not available
2868 for printing. So we have an admin_users restriction. */
2869 if (!admin_user)
2870 {
2871 fprintf(stderr, "exim: permission denied\n");
2872 return FALSE;
2873 }
2874 for (m = macros; m; m = m->next)
2875 if (!name || Ustrcmp(name, m->name) == 0)
2876 {
2877 if (names_only)
2878 printf("%s\n", CS m->name);
2879 else
2880 printf("%s=%s\n", CS m->name, CS m->replacement);
2881 if (name)
2882 return TRUE;
2883 }
2884 if (!name) return TRUE;
2885
2886 printf("%s %s not found\n", type, name);
2887 return FALSE;
2888 }
2889
2890 if (names_only)
2891 {
2892 for (; d; d = d->next) printf("%s\n", CS d->name);
2893 return TRUE;
2894 }
2895
2896 /* Either search for a given driver, or print all of them */
2897
2898 for (; d; d = d->next)
2899 {
2900 BOOL rc = FALSE;
2901 if (!name)
2902 printf("\n%s %s:\n", d->name, type);
2903 else if (Ustrcmp(d->name, name) != 0) continue;
2904
2905 for (ol = ol2; ol < ol2 + size; ol++)
2906 if (!(ol->type & opt_hidden))
2907 rc |= print_ol(ol, US ol->name, d, ol2, size, no_labels);
2908
2909 for (ol = d->info->options;
2910 ol < d->info->options + *(d->info->options_count); ol++)
2911 if (!(ol->type & opt_hidden))
2912 rc |= print_ol(ol, US ol->name, d, d->info->options,
2913 *d->info->options_count, no_labels);
2914
2915 if (name) return rc;
2916 }
2917 if (!name) return TRUE;
2918
2919 printf("%s %s not found\n", type, name);
2920 return FALSE;
2921 }
2922
2923
2924
2925 /*************************************************
2926 * Read a named list item *
2927 *************************************************/
2928
2929 /* This function reads a name and a list (i.e. string). The name is used to
2930 save the list in a tree, sorted by its name. Each entry also has a number,
2931 which can be used for caching tests, but if the string contains any expansion
2932 items other than $key, the number is set negative to inhibit caching. This
2933 mechanism is used for domain, host, and address lists that are referenced by
2934 the "+name" syntax.
2935
2936 Arguments:
2937 anchorp points to the tree anchor
2938 numberp points to the current number for this tree
2939 max the maximum number permitted
2940 s the text of the option line, starting immediately after the name
2941 of the list type
2942 tname the name of the list type, for messages
2943
2944 Returns: nothing
2945 */
2946
2947 static void
2948 read_named_list(tree_node **anchorp, int *numberp, int max, uschar *s,
2949 uschar *tname)
2950 {
2951 BOOL forcecache = FALSE;
2952 uschar *ss;
2953 tree_node *t;
2954 namedlist_block *nb = store_get(sizeof(namedlist_block));
2955
2956 if (Ustrncmp(s, "_cache", 6) == 0)
2957 {
2958 forcecache = TRUE;
2959 s += 6;
2960 }
2961
2962 if (!isspace(*s))
2963 log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, "unrecognized configuration line");
2964
2965 if (*numberp >= max)
2966 log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, "too many named %ss (max is %d)\n",
2967 tname, max);
2968
2969 while (isspace(*s)) s++;
2970 ss = s;
2971 while (isalnum(*s) || *s == '_') s++;
2972 t = store_get(sizeof(tree_node) + s-ss);
2973 Ustrncpy(t->name, ss, s-ss);
2974 t->name[s-ss] = 0;
2975 while (isspace(*s)) s++;
2976
2977 if (!tree_insertnode(anchorp, t))
2978 log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN,
2979 "duplicate name \"%s\" for a named %s", t->name, tname);
2980
2981 t->data.ptr = nb;
2982 nb->number = *numberp;
2983 *numberp += 1;
2984
2985 if (*s++ != '=') log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN,
2986 "missing '=' after \"%s\"", t->name);
2987 while (isspace(*s)) s++;
2988 nb->string = read_string(s, t->name);
2989 nb->cache_data = NULL;
2990
2991 /* Check the string for any expansions; if any are found, mark this list
2992 uncacheable unless the user has explicited forced caching. */
2993
2994 if (!forcecache && Ustrchr(nb->string, '$') != NULL) nb->number = -1;
2995 }
2996
2997
2998
2999
3000 /*************************************************
3001 * Unpick data for a rate limit *
3002 *************************************************/
3003
3004 /* This function is called to unpick smtp_ratelimit_{mail,rcpt} into four
3005 separate values.
3006
3007 Arguments:
3008 s string, in the form t,b,f,l
3009 where t is the threshold (integer)
3010 b is the initial delay (time)
3011 f is the multiplicative factor (fixed point)
3012 k is the maximum time (time)
3013 threshold where to store threshold
3014 base where to store base in milliseconds
3015 factor where to store factor in milliseconds
3016 limit where to store limit
3017
3018 Returns: nothing (panics on error)
3019 */
3020
3021 static void
3022 unpick_ratelimit(uschar *s, int *threshold, int *base, double *factor,
3023 int *limit)
3024 {
3025 uschar bstring[16], lstring[16];
3026
3027 if (sscanf(CS s, "%d, %15[0123456789smhdw.], %lf, %15s", threshold, bstring,
3028 factor, lstring) == 4)
3029 {
3030 *base = readconf_readtime(bstring, 0, TRUE);
3031 *limit = readconf_readtime(lstring, 0, TRUE);
3032 if (*base >= 0 && *limit >= 0) return;
3033 }
3034 log_write(0, LOG_MAIN|LOG_PANIC_DIE, "malformed ratelimit data: %s", s);
3035 }
3036
3037
3038
3039
3040 /*************************************************
3041 * Drop privs for checking TLS config *
3042 *************************************************/
3043
3044 /* We want to validate TLS options during readconf, but do not want to be
3045 root when we call into the TLS library, in case of library linkage errors
3046 which cause segfaults; before this check, those were always done as the Exim
3047 runtime user and it makes sense to continue with that.
3048
3049 Assumes: tls_require_ciphers has been set, if it will be
3050 exim_user has been set, if it will be
3051 exim_group has been set, if it will be
3052
3053 Returns: bool for "okay"; false will cause caller to immediately exit.
3054 */
3055
3056 #ifdef SUPPORT_TLS
3057 static BOOL
3058 tls_dropprivs_validate_require_cipher(BOOL nowarn)
3059 {
3060 const uschar *errmsg;
3061 pid_t pid;
3062 int rc, status;
3063 void (*oldsignal)(int);
3064
3065 /* If TLS will never be used, no point checking ciphers */
3066
3067 if ( !tls_advertise_hosts
3068 || !*tls_advertise_hosts
3069 || Ustrcmp(tls_advertise_hosts, ":") == 0
3070 )
3071 return TRUE;
3072 else if (!nowarn && !tls_certificate)
3073 log_write(0, LOG_MAIN,
3074 "Warning: No server certificate defined; will use a selfsigned one.\n"
3075 " Suggested action: either install a certificate or change tls_advertise_hosts option");
3076
3077 oldsignal = signal(SIGCHLD, SIG_DFL);
3078
3079 fflush(NULL);
3080 if ((pid = fork()) < 0)
3081 log_write(0, LOG_MAIN|LOG_PANIC_DIE, "fork failed for TLS check");
3082
3083 if (pid == 0)
3084 {
3085 /* in some modes, will have dropped privilege already */
3086 if (!geteuid())
3087 exim_setugid(exim_uid, exim_gid, FALSE,
3088 US"calling tls_validate_require_cipher");
3089
3090 if ((errmsg = tls_validate_require_cipher()))
3091 log_write(0, LOG_PANIC_DIE|LOG_CONFIG,
3092 "tls_require_ciphers invalid: %s", errmsg);
3093 fflush(NULL);
3094 _exit(0);
3095 }
3096
3097 do {
3098 rc = waitpid(pid, &status, 0);
3099 } while (rc < 0 && errno == EINTR);
3100
3101 DEBUG(D_tls)
3102 debug_printf("tls_validate_require_cipher child %d ended: status=0x%x\n",
3103 (int)pid, status);
3104
3105 signal(SIGCHLD, oldsignal);
3106
3107 return status == 0;
3108 }
3109 #endif /* SUPPORT_TLS */
3110
3111
3112
3113
3114 /*************************************************
3115 * Read main configuration options *
3116 *************************************************/
3117
3118 /* This function is the first to be called for configuration reading. It
3119 opens the configuration file and reads general configuration settings until
3120 it reaches the end of the configuration section. The file is then left open so
3121 that the remaining configuration data can subsequently be read if needed for
3122 this run of Exim.
3123
3124 The configuration file must be owned either by root or exim, and be writeable
3125 only by root or uid/gid exim. The values for Exim's uid and gid can be changed
3126 in the config file, so the test is done on the compiled in values. A slight
3127 anomaly, to be carefully documented.
3128
3129 The name of the configuration file is taken from a list that is included in the
3130 binary of Exim. It can be altered from the command line, but if that is done,
3131 root privilege is immediately withdrawn unless the caller is root or exim.
3132 The first file on the list that exists is used.
3133
3134 For use on multiple systems that share file systems, first look for a
3135 configuration file whose name has the current node name on the end. If that is
3136 not found, try the generic name. For really contorted configurations, that run
3137 multiple Exims with different uid settings, first try adding the effective uid
3138 before the node name. These complications are going to waste resources on most
3139 systems. Therefore they are available only when requested by compile-time
3140 options. */
3141
3142 void
3143 readconf_main(BOOL nowarn)
3144 {
3145 int sep = 0;
3146 struct stat statbuf;
3147 uschar *s, *filename;
3148 const uschar *list = config_main_filelist;
3149
3150 /* Loop through the possible file names */
3151
3152 while((filename = string_nextinlist(&list, &sep, big_buffer, big_buffer_size)))
3153 {
3154
3155 /* Cut out all the fancy processing unless specifically wanted */
3156
3157 #if defined(CONFIGURE_FILE_USE_NODE) || defined(CONFIGURE_FILE_USE_EUID)
3158 uschar *suffix = filename + Ustrlen(filename);
3159
3160 /* Try for the node-specific file if a node name exists */
3161
3162 #ifdef CONFIGURE_FILE_USE_NODE
3163 struct utsname uts;
3164 if (uname(&uts) >= 0)
3165 {
3166 #ifdef CONFIGURE_FILE_USE_EUID
3167 sprintf(CS suffix, ".%ld.%.256s", (long int)original_euid, uts.nodename);
3168 config_file = Ufopen(filename, "rb");
3169 if (config_file == NULL)
3170 #endif /* CONFIGURE_FILE_USE_EUID */
3171 {
3172 sprintf(CS suffix, ".%.256s", uts.nodename);
3173 config_file = Ufopen(filename, "rb");
3174 }
3175 }
3176 #endif /* CONFIGURE_FILE_USE_NODE */
3177
3178 /* Otherwise, try the generic name, possibly with the euid added */
3179
3180 #ifdef CONFIGURE_FILE_USE_EUID
3181 if (config_file == NULL)
3182 {
3183 sprintf(CS suffix, ".%ld", (long int)original_euid);
3184 config_file = Ufopen(filename, "rb");
3185 }
3186 #endif /* CONFIGURE_FILE_USE_EUID */
3187
3188 /* Finally, try the unadorned name */
3189
3190 if (config_file == NULL)
3191 {
3192 *suffix = 0;
3193 config_file = Ufopen(filename, "rb");
3194 }
3195 #else /* if neither defined */
3196
3197 /* This is the common case when the fancy processing is not included. */
3198
3199 config_file = Ufopen(filename, "rb");
3200 #endif
3201
3202 /* If the file does not exist, continue to try any others. For any other
3203 error, break out (and die). */
3204
3205 if (config_file != NULL || errno != ENOENT) break;
3206 }
3207
3208 /* On success, save the name for verification; config_filename is used when
3209 logging configuration errors (it changes for .included files) whereas
3210 config_main_filename is the name shown by -bP. Failure to open a configuration
3211 file is a serious disaster. */
3212
3213 if (config_file)
3214 {
3215 uschar *last_slash = Ustrrchr(filename, '/');
3216 config_filename = config_main_filename = string_copy(filename);
3217
3218 /* The config_main_directory we need for the $config_dir expansion.
3219 config_main_filename we need for $config_file expansion.
3220 And config_dir is the directory of the current configuration, used for
3221 relative .includes. We do need to know it's name, as we change our working
3222 directory later. */
3223
3224 if (filename[0] == '/')
3225 config_main_directory = last_slash == filename ? US"/" : string_copyn(filename, last_slash - filename);
3226 else
3227 {
3228 /* relative configuration file name: working dir + / + basename(filename) */
3229
3230 uschar buf[PATH_MAX];
3231 gstring * g;
3232
3233 if (os_getcwd(buf, PATH_MAX) == NULL)
3234 {
3235 perror("exim: getcwd");
3236 exit(EXIT_FAILURE);
3237 }
3238 g = string_cat(NULL, buf);
3239
3240 /* If the dir does not end with a "/", append one */
3241 if (g->s[g->ptr-1] != '/')
3242 g = string_catn(g, US"/", 1);
3243
3244 /* If the config file contains a "/", extract the directory part */
3245 if (last_slash)
3246 g = string_catn(g, filename, last_slash - filename);
3247
3248 config_main_directory = string_from_gstring(g);
3249 }
3250 config_directory = config_main_directory;
3251 }
3252 else
3253 {
3254 if (filename == NULL)
3255 log_write(0, LOG_MAIN|LOG_PANIC_DIE, "non-existent configuration file(s): "
3256 "%s", config_main_filelist);
3257 else
3258 log_write(0, LOG_MAIN|LOG_PANIC_DIE, "%s", string_open_failed(errno,
3259 "configuration file %s", filename));
3260 }
3261
3262 /* Now, once we found and opened our configuration file, we change the directory
3263 to a safe place. Later we change to $spool_directory. */
3264
3265 if (Uchdir("/") < 0)
3266 {
3267 perror("exim: chdir `/': ");
3268 exit(EXIT_FAILURE);
3269 }
3270
3271 /* Check the status of the file we have opened, if we have retained root
3272 privileges and the file isn't /dev/null (which *should* be 0666). */
3273
3274 if (trusted_config && Ustrcmp(filename, US"/dev/null"))
3275 {
3276 if (fstat(fileno(config_file), &statbuf) != 0)
3277 log_write(0, LOG_MAIN|LOG_PANIC_DIE, "failed to stat configuration file %s",
3278 big_buffer);
3279<