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