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