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