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