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