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