Make environment.c more portable
[exim.git] / src / src / readconf.c
1 /*************************************************
2 * Exim - an Internet mail transport agent *
3 *************************************************/
4
5 /* Copyright (c) University of Cambridge 1995 - 2015 */
6 /* See the file NOTICE for conditions of use and distribution. */
7
8 /* Functions for reading the configuration file, and for displaying
9 overall configuration values. Thanks to Brian Candler for the original
10 implementation of the conditional .ifdef etc. */
11
12 #include "exim.h"
13
14 static void fn_smtp_receive_timeout(const uschar * name, const uschar * str);
15 static void save_config_line(const uschar* line);
16 static void save_config_position(const uschar *file, int line);
17 static void print_config(BOOL admin);
18 /* glibc seems to define environ as a macro, we can use this to check
19 it's existence. And, if we declare environ a 2nd time, it shouldn't
20 harm */
21 #ifndef environ
22 extern char **environ;
23 #endif
24
25
26 #define CSTATE_STACK_SIZE 10
27
28
29 /* Structure for chain (stack) of .included files */
30
31 typedef struct config_file_item {
32 struct config_file_item *next;
33 uschar *filename;
34 FILE *file;
35 int lineno;
36 } config_file_item;
37
38 /* Structure for chain of configuration lines (-bP config) */
39
40 typedef struct config_line_item {
41 struct config_line_item *next;
42 uschar *line;
43 } config_line_item;
44
45 static config_line_item* config_lines;
46
47 /* Structure of table of conditional words and their state transitions */
48
49 typedef 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
59 typedef struct syslog_fac_item {
60 uschar *name;
61 int value;
62 } syslog_fac_item;
63
64 /* constants */
65 static const char * const hidden = "<value not displayable>";
66
67 /* Static variables */
68
69 static config_file_item *config_file_stack = NULL; /* For includes */
70
71 static uschar *syslog_facility_str = NULL;
72 static uschar next_section[24];
73 static uschar time_buffer[24];
74
75 /* State variables for conditional loading (.ifdef / .else / .endif) */
76
77 static int cstate = 0;
78 static int cstate_stack_ptr = -1;
79 static int cstate_stack[CSTATE_STACK_SIZE];
80
81 /* Table of state transitions for handling conditional inclusions. There are
82 four 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
91 static 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
102 values: the length of the name (to save computing it each time), the state to
103 set if a macro was found in the line, the state to set if a macro was not found
104 in 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
111 static 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
120 static int cond_list_size = sizeof(cond_list)/sizeof(cond_item);
121
122 /* Table of syslog facility names and their values */
123
124 static 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
140 static 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
150 must be in alphabetic order because it is searched by binary chop. */
151
152 static 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 },
159 #ifdef WITH_CONTENT_SCAN
160 { "acl_not_smtp_mime", opt_stringptr, &acl_not_smtp_mime },
161 #endif
162 { "acl_not_smtp_start", opt_stringptr, &acl_not_smtp_start },
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 },
166 #ifndef DISABLE_PRDR
167 { "acl_smtp_data_prdr", opt_stringptr, &acl_smtp_data_prdr },
168 #endif
169 #ifndef DISABLE_DKIM
170 { "acl_smtp_dkim", opt_stringptr, &acl_smtp_dkim },
171 #endif
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 },
177 #ifdef WITH_CONTENT_SCAN
178 { "acl_smtp_mime", opt_stringptr, &acl_smtp_mime },
179 #endif
180 { "acl_smtp_notquit", opt_stringptr, &acl_smtp_notquit },
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 },
188 { "add_environment", opt_stringptr, &add_environment },
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 },
195 #ifdef WITH_CONTENT_SCAN
196 { "av_scanner", opt_stringptr, &av_scanner },
197 #endif
198 { "bi_command", opt_stringptr, &bi_command },
199 #ifdef EXPERIMENTAL_BRIGHTMAIL
200 { "bmi_config_file", opt_stringptr, &bmi_config_file },
201 #endif
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 },
205 { "bounce_return_linesize_limit", opt_mkint, &bounce_return_linesize_limit },
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 },
216 { "check_rfc2047_length", opt_bool, &check_rfc2047_length },
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 },
221 { "daemon_startup_retries", opt_int, &daemon_startup_retries },
222 { "daemon_startup_sleep", opt_time, &daemon_startup_sleep },
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
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 },
233 #ifdef ENABLE_DISABLE_FSYNC
234 { "disable_fsync", opt_bool, &disable_fsync },
235 #endif
236 { "disable_ipv6", opt_bool, &disable_ipv6 },
237 #ifndef DISABLE_DKIM
238 { "dkim_verify_signers", opt_stringptr, &dkim_verify_signers },
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 },
244 #endif
245 { "dns_again_means_nonexist", opt_stringptr, &dns_again_means_nonexist },
246 { "dns_check_names_pattern", opt_stringptr, &check_dns_names_pattern },
247 { "dns_csa_search_limit", opt_int, &dns_csa_search_limit },
248 { "dns_csa_use_reverse", opt_bool, &dns_csa_use_reverse },
249 { "dns_dnssec_ok", opt_int, &dns_dnssec_ok },
250 { "dns_ipv4_lookup", opt_stringptr, &dns_ipv4_lookup },
251 { "dns_retrans", opt_time, &dns_retrans },
252 { "dns_retry", opt_int, &dns_retry },
253 { "dns_trust_aa", opt_stringptr, &dns_trust_aa },
254 { "dns_use_edns0", opt_int, &dns_use_edns0 },
255 /* This option is now a no-op, retained for compability */
256 { "drop_cr", opt_bool, &drop_cr },
257 /*********************************************************/
258 { "dsn_advertise_hosts", opt_stringptr, &dsn_advertise_hosts },
259 { "dsn_from", opt_stringptr, &dsn_from },
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 },
263 #ifndef DISABLE_EVENT
264 { "event_action", opt_stringptr, &event_action },
265 #endif
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 },
275 #ifdef SUPPORT_TLS
276 { "gnutls_allow_auto_pkcs11", opt_bool, &gnutls_allow_auto_pkcs11 },
277 { "gnutls_compat_mode", opt_bool, &gnutls_compat_mode },
278 /* These three gnutls_require_* options stopped working in Exim 4.80 */
279 /* From 4.83 we log a warning; a future relase will remove them */
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
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 },
297 #ifdef SUPPORT_PROXY
298 { "hosts_proxy", opt_stringptr, &hosts_proxy },
299 #endif
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 },
307 { "keep_environment", opt_stringptr, &keep_environment },
308 { "keep_malformed", opt_time, &keep_malformed },
309 #ifdef LOOKUP_LDAP
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 },
315 { "ldap_default_servers", opt_stringptr, &eldap_default_servers },
316 { "ldap_require_cert", opt_stringptr, &eldap_require_cert },
317 { "ldap_start_tls", opt_bool, &eldap_start_tls },
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 },
332 { "message_body_newlines", opt_bool, &message_body_newlines },
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 },
346 #ifdef SUPPORT_TLS
347 { "openssl_options", opt_stringptr, &openssl_options },
348 #endif
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 },
362 #ifndef DISABLE_PRDR
363 { "prdr_enable", opt_bool, &prdr_enable },
364 #endif
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 },
377 { "queue_only_load_latch", opt_bool, &queue_only_load_latch },
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 },
388 #ifdef LOOKUP_REDIS
389 { "redis_servers", opt_stringptr, &redis_servers },
390 #endif
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 },
400 { "slow_lookup_log", opt_int, &slow_lookup_log },
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 },
423 { "smtp_receive_timeout", opt_func, &fn_smtp_receive_timeout },
424 { "smtp_reserve_hosts", opt_stringptr, &smtp_reserve_hosts },
425 { "smtp_return_error_details",opt_bool, &smtp_return_error_details },
426 #ifdef SUPPORT_I18N
427 { "smtputf8_advertise_hosts", opt_stringptr, &smtputf8_advertise_hosts },
428 #endif
429 #ifdef WITH_CONTENT_SCAN
430 { "spamd_address", opt_stringptr, &spamd_address },
431 #endif
432 #ifdef EXPERIMENTAL_SPF
433 { "spf_guess", opt_stringptr, &spf_guess },
434 #endif
435 { "split_spool_directory", opt_bool, &split_spool_directory },
436 { "spool_directory", opt_stringptr, &spool_directory },
437 #ifdef LOOKUP_SQLITE
438 { "sqlite_lock_timeout", opt_int, &sqlite_lock_timeout },
439 #endif
440 #ifdef EXPERIMENTAL_SRS
441 { "srs_config", opt_stringptr, &srs_config },
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 },
448 #endif
449 { "strict_acl_vars", opt_bool, &strict_acl_vars },
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 },
464 #ifdef USE_TCP_WRAPPERS
465 { "tcp_wrappers_daemon_name", opt_stringptr, &tcp_wrappers_daemon_name },
466 #endif
467 { "timeout_frozen_after", opt_time, &timeout_frozen_after },
468 { "timezone", opt_stringptr, &timezone_string },
469 { "tls_advertise_hosts", opt_stringptr, &tls_advertise_hosts },
470 #ifdef SUPPORT_TLS
471 { "tls_certificate", opt_stringptr, &tls_certificate },
472 { "tls_crl", opt_stringptr, &tls_crl },
473 { "tls_dh_max_bits", opt_int, &tls_dh_max_bits },
474 { "tls_dhparam", opt_stringptr, &tls_dhparam },
475 { "tls_eccurve", opt_stringptr, &tls_eccurve },
476 # ifndef DISABLE_OCSP
477 { "tls_ocsp_file", opt_stringptr, &tls_ocsp_file },
478 # endif
479 { "tls_on_connect_ports", opt_stringptr, &tls_in.on_connect_ports },
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
498 static 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
508 pointer variables in the options table or in option tables for various drivers.
509 For debugging output, it is useful to be able to find the name of the option
510 which is currently being processed. This function finds it, if it exists, by
511 searching the table(s).
512
513 Arguments: a value that is presumed to be in the table above
514 Returns: the option name, or an empty string
515 */
516
517 uschar *
518 readconf_find_option(void *p)
519 {
520 int i;
521 router_instance *r;
522 transport_instance *t;
523
524 for (i = 0; i < optionlist_config_size; i++)
525 if (p == optionlist_config[i].value) return US optionlist_config[i].name;
526
527 for (r = routers; r != NULL; r = r->next)
528 {
529 router_info *ri = r->info;
530 for (i = 0; i < *ri->options_count; i++)
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
538 for (t = transports; t != NULL; t = t->next)
539 {
540 transport_info *ti = t->info;
541 for (i = 0; i < *ti->options_count; i++)
542 {
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;
551 }
552 }
553
554 return US"";
555 }
556
557
558
559
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
565 encountered. The argument "line" should contain a complete logical line, and
566 start with the first letter of the macro name. The macro name and the
567 replacement text are extracted and stored. Redefinition of existing,
568 non-command line, macros is permitted using '==' instead of '='.
569
570 Arguments:
571 s points to the start of the logical line
572
573 Returns: nothing
574 */
575
576 static void
577 read_macro_assignment(uschar *s)
578 {
579 uschar name[64];
580 int namelen = 0;
581 BOOL redef = FALSE;
582 macro_item *m;
583 macro_item *mlast = NULL;
584
585 while (isalnum(*s) || *s == '_')
586 {
587 if (namelen >= sizeof(name) - 1)
588 log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN,
589 "macro name too long (maximum is " SIZE_T_FMT " characters)", sizeof(name) - 1);
590 name[namelen++] = *s++;
591 }
592 name[namelen] = 0;
593
594 while (isspace(*s)) s++;
595 if (*s++ != '=')
596 log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, "malformed macro definition");
597
598 if (*s == '=')
599 {
600 redef = TRUE;
601 s++;
602 }
603 while (isspace(*s)) s++;
604
605 /* If an existing macro of the same name was defined on the command line, we
606 just skip this definition. It's an error to attempt to redefine a macro without
607 redef set to TRUE, or to redefine a macro when it hasn't been defined earlier.
608 It is also an error to define a macro whose name begins with the name of a
609 previously defined macro. Note: it is documented that the other way round
610 works. */
611
612 for (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
643 if (m != NULL && m->command_line) return;
644
645 /* Redefinition must refer to an existing macro. */
646
647 if (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
655 called "name" which is one byte long. Thus, adding "namelen" gives us enough
656 room to store the "name" string. */
657
658 else
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
670 m->replacement = string_copy(s);
671 }
672
673
674
675
676
677 /*************************************************
678 * Read configuration line *
679 *************************************************/
680
681 /* A logical line of text is read from the configuration file into the big
682 buffer, taking account of macros, .includes, and continuations. The size of
683 big_buffer is increased if necessary. The count of configuration lines is
684 maintained. Physical input lines starting with # (ignoring leading white space,
685 and after macro replacement) and empty logical lines are always ignored.
686 Leading and trailing spaces are removed.
687
688 If we hit a line of the form "begin xxxx", the xxxx is placed in the
689 next_section vector, and the function returns NULL, indicating the end of a
690 configuration section. On end-of-file, NULL is returned with next_section
691 empty.
692
693 Arguments: none
694
695 Returns: a pointer to the first non-blank in the line,
696 or NULL if eof or end of section is reached
697 */
698
699 static uschar *
700 get_config_line(void)
701 {
702 int startoffset = 0; /* To first non-blank char in logical line */
703 int len = 0; /* Of logical line so far */
704 int newlen;
705 uschar *s, *ss;
706 macro_item *m;
707 BOOL macro_found;
708
709 /* Loop for handling continuation lines, skipping comments, and dealing with
710 .include files. */
711
712 for (;;)
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 {
718 (void)fclose(config_file);
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;
723 if (config_lines)
724 save_config_position(config_filename, config_lineno);
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
742 if (config_lines && config_lineno == 1)
743 save_config_position(config_filename, config_lineno);
744
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
927 if (*ss != '/')
928 log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, ".include specifies a non-"
929 "absolute path \"%s\"", ss);
930
931 if (include_if_exists != 0 && (Ustat(ss, &statbuf) != 0)) continue;
932
933 if (config_lines)
934 save_config_position(config_filename, config_lineno);
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,
985 more accurately, for the start of the next section). Place the name of the next
986 section in next_section, and return NULL. If the name given is longer than
987 next_section, truncate it. It will be unrecognized later, because all the known
988 section names do fit. Leave space for pluralizing. */
989
990 s = big_buffer + startoffset; /* First non-space character */
991
992 if (config_lines)
993 save_config_line(s);
994
995 if (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
1007 return 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
1017 output space are silently truncated. This function is also used from acl.c when
1018 parsing ACLs.
1019
1020 Arguments:
1021 name where to put the name
1022 len length of name
1023 s input pointer
1024
1025 Returns: new input pointer
1026 */
1027
1028 uschar *
1029 readconf_readname(uschar *name, int len, uschar *s)
1030 {
1031 int p = 0;
1032 while (isspace(*s)) s++;
1033 if (isalpha(*s))
1034 {
1035 while (isalnum(*s) || *s == '_')
1036 {
1037 if (p < len-1) name[p++] = *s;
1038 s++;
1039 }
1040 }
1041 name[p] = 0;
1042 while (isspace(*s)) s++;
1043 return 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
1054 time values. The format of a time value is:
1055
1056 [<n>w][<n>d][<n>h][<n>m][<n>s]
1057
1058 as long as at least one is present. If a format error is encountered,
1059 return a negative value. The value must be terminated by the given
1060 terminator.
1061
1062 Arguments:
1063 s input pointer
1064 terminator required terminating character
1065 return_msec if TRUE, allow fractional seconds and return milliseconds
1066
1067 Returns: 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
1072 int
1073 readconf_readtime(const uschar *s, int terminator, BOOL return_msec)
1074 {
1075 int yield = 0;
1076 for (;;)
1077 {
1078 int value, count;
1079 double fraction;
1080
1081 if (!isdigit(*s)) return -1;
1082 (void)sscanf(CCS s, "%d%n", &value, &count);
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;
1096 (void)sscanf(CCS s, "%lf%n", &fraction, &count);
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
1120 Arguments:
1121 s input pointer
1122 terminator required terminator
1123
1124 Returns: the value, or -1 on error
1125 */
1126
1127 static int
1128 readconf_readfixed(const uschar *s, int terminator)
1129 {
1130 int yield = 0;
1131 int value, count;
1132 if (!isdigit(*s)) return -1;
1133 (void)sscanf(CS s, "%d%n", &value, &count);
1134 s += count;
1135 yield = value * 1000;
1136 if (*s == '.')
1137 {
1138 int m = 100;
1139 while (isdigit((*(++s))))
1140 {
1141 yield += (*s - '0') * m;
1142 m /= 10;
1143 }
1144 }
1145
1146 return (*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
1157 Arguments:
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
1162 Returns: pointer to an option entry, or NULL if not found
1163 */
1164
1165 static optionlist *
1166 find_option(uschar *name, optionlist *ol, int last)
1167 {
1168 int first = 0;
1169 while (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 }
1177 return 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
1187 gids (even negative ones), we cannot represent "unset" by a special value.
1188 There is therefore a separate boolean variable for each one indicating whether
1189 a value is set or not. This function returns a pointer to the boolean, given
1190 the original option name. It is a major disaster if the flag cannot be found.
1191
1192 Arguments:
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
1200 Returns: a pointer to the boolean flag.
1201 */
1202
1203 static BOOL *
1204 get_set_flag(uschar *name, optionlist *oltop, int last, void *data_block)
1205 {
1206 optionlist *ol;
1207 uschar name2[64];
1208 sprintf(CS name2, "*set_%.50s", name);
1209 ol = find_option(name2, oltop, last);
1210 if (ol == NULL) log_write(0, LOG_MAIN|LOG_PANIC_DIE,
1211 "Exim internal error: missing set flag for %s", name);
1212 return (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
1224 the sysadmin thinks comments are permitted.
1225
1226 Arguments:
1227 s points to the extra characters
1228 t1..t3 strings to insert in the log message
1229
1230 Returns: doesn't return; dies
1231 */
1232
1233 static void
1234 extra_chars_error(const uschar *s, const uschar *t1, const uschar *t2, const uschar *t3)
1235 {
1236 uschar *comment = US"";
1237 if (*s == '#') comment = US" (# is comment only at line start)";
1238 log_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
1258 All this is decoded and placed into a control block. The OR of the flags is
1259 maintained in a common word.
1260
1261 Arguments:
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
1266 Returns: the control block for the parsed rule.
1267 */
1268
1269 static rewrite_rule *
1270 readconf_one_rewrite(const uschar *p, int *existflags, BOOL isglobal)
1271 {
1272 rewrite_rule *next = store_get(sizeof(rewrite_rule));
1273
1274 next->next = NULL;
1275 next->key = string_dequote(&p);
1276
1277 while (isspace(*p)) p++;
1278 if (*p == 0)
1279 log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN,
1280 "missing rewrite replacement string");
1281
1282 next->flags = 0;
1283 next->replacement = string_dequote(&p);
1284
1285 while (*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
1323 if ((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;
1329 return 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
1340 by readconf_one_rewrite(), and its flags are ORed into the global flag
1341 word rewrite_existflags. */
1342
1343 void
1344 readconf_rewrites(void)
1345 {
1346 rewrite_rule **chain = &global_rewrite_rules;
1347 uschar *p;
1348
1349 while ((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
1364 near the end of the current block, the string will just use what is necessary
1365 on the top of the stacking pool, because string_cat() uses the extension
1366 mechanism.
1367
1368 Argument:
1369 s the rest of the input line
1370 name the option name (for errors)
1371
1372 Returns: pointer to the string
1373 */
1374
1375 static uschar *
1376 read_string(const uschar *s, const uschar *name)
1377 {
1378 uschar *yield;
1379 const uschar *ss;
1380
1381 if (*s != '\"') return string_copy(s);
1382
1383 ss = s;
1384 yield = string_dequote(&s);
1385
1386 if (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
1390 if (*s != 0) extra_chars_error(s, US"string value for ", name, US"");
1391
1392 return yield;
1393 }
1394
1395
1396 /*************************************************
1397 * Custom-handler options *
1398 *************************************************/
1399 static void
1400 fn_smtp_receive_timeout(const uschar * name, const uschar * str)
1401 {
1402 if (*str == '$')
1403 smtp_receive_timeout_s = string_copy(str);
1404 else
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
1414 /*************************************************
1415 * Handle option line *
1416 *************************************************/
1417
1418 /* This function is called from several places to process a line containing the
1419 setting of an option. The first argument is the line to be decoded; it has been
1420 checked not to be empty and not to start with '#'. Trailing newlines and white
1421 space have been removed. The second argument is a pointer to the list of
1422 variable names that are to be recognized, together with their types and
1423 locations, and the third argument gives the number of entries in the list.
1424
1425 The fourth argument is a pointer to a data block. If it is NULL, then the data
1426 values in the options list are absolute addresses. Otherwise, they are byte
1427 offsets in the data block.
1428
1429 String option data may continue onto several lines; this function reads further
1430 data from config_file if necessary.
1431
1432 The yield of this function is normally zero. If a string continues onto
1433 multiple lines, then the data value is permitted to be followed by a comma
1434 or a semicolon (for use in drivers) and the yield is that character.
1435
1436 Arguments:
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
1448 Returns: 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
1453 static BOOL
1454 readconf_handle_option(uschar *buffer, optionlist *oltop, int last,
1455 void *data_block, uschar *unknown_txt)
1456 {
1457 int ptr = 0;
1458 int offset = 0;
1459 int n, count, type, value;
1460 int issecure = 0;
1461 uid_t uid;
1462 gid_t gid;
1463 BOOL boolvalue = TRUE;
1464 BOOL freesptr = TRUE;
1465 optionlist *ol, *ol2;
1466 struct passwd *pw;
1467 void *reset_point;
1468 int intbase = 0;
1469 uschar *inttype = US"";
1470 uschar *sptr;
1471 uschar *s = buffer;
1472 uschar *saved_condition, *strtemp;
1473 uschar **str_target;
1474 uschar name[64];
1475 uschar name2[64];
1476
1477 /* There may be leading spaces; thereafter, we expect an option name starting
1478 with a letter. */
1479
1480 while (isspace(*s)) s++;
1481 if (!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
1485 it turns out that what we read was "hide", set the flag indicating that
1486 this is a secure option, and loop to read the next word. */
1487
1488 for (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
1504 if (Ustrncmp(name, "no_", 3) == 0)
1505 {
1506 boolvalue = FALSE;
1507 offset = 3;
1508 }
1509
1510 if (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
1517 is set twice, is a disaster. */
1518
1519 ol = find_option(name + offset, oltop, last);
1520
1521 if (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
1527 if ((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);
1530
1531 ol->type |= opt_set | issecure;
1532 type = ol->type & opt_mask;
1533
1534 /* Types with data values must be followed by '='; the "no[t]_" prefix
1535 applies only to boolean values. */
1536
1537 if (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
1550 true/false/yes/no, or, in the case of opt_expand_bool, a general string that
1551 ultimately expands to one of those values. */
1552
1553 else if (*s != 0 && (offset != 0 || *s != '='))
1554 extra_chars_error(s, US"boolean option ", name, US"");
1555
1556 /* Skip white space after = */
1557
1558 if (*s == '=') while (isspace((*(++s))));
1559
1560 /* If there is a data block and the opt_public flag is not set, change
1561 the data block pointer to the private options block. */
1562
1563 if (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
1568 switch (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:
1609 if (data_block == NULL)
1610 str_target = (uschar **)(ol->value);
1611 else
1612 str_target = (uschar **)((uschar *)data_block + (long int)(ol->value));
1613 if (ol->type & opt_rep_con)
1614 {
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. */
1618 saved_condition = *str_target;
1619 strtemp = string_sprintf("${if and{{bool_lax{%s}}{bool_lax{%s}}}}",
1620 saved_condition, sptr);
1621 *str_target = string_copy_malloc(strtemp);
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.
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. */
1635 }
1636 else if (ol->type & opt_rep_str)
1637 {
1638 uschar sep_o = Ustrncmp(name, "headers_add", 11)==0 ? '\n' : ':';
1639 int sep_i = -(int)sep_o;
1640 const uschar * list = sptr;
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);
1648 }
1649 else
1650 {
1651 *str_target = sptr;
1652 freesptr = FALSE;
1653 }
1654 break;
1655
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
1690 while ((p = string_nextinlist(CUSS &sptr, &sep, big_buffer, BIG_BUFFER_SIZE)))
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;
1814 const uschar *p;
1815 const uschar *op = expand_string (sptr);
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);
1820
1821 p = op;
1822 if (*p != 0) count++;
1823 while (*p != 0) if (*p++ == ':' && *p != 0) count++;
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
1832 p = op;
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;
1855 const uschar *p;
1856 const uschar *op = expand_string (sptr);
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);
1861
1862 p = op;
1863 if (*p != 0) count++;
1864 while (*p != 0) if (*p++ == ':' && *p != 0) count++;
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
1873 p = op;
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;
2001 long int lvalue;
2002
2003 errno = 0;
2004 lvalue = strtol(CS s, CSS &endptr, intbase);
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 {
2014 if (lvalue > INT_MAX/1024 || lvalue < INT_MIN/1024) errno = ERANGE;
2015 else lvalue *= 1024;
2016 endptr++;
2017 }
2018 else if (tolower(*endptr) == 'm')
2019 {
2020 if (lvalue > INT_MAX/(1024*1024) || lvalue < INT_MIN/(1024*1024))
2021 errno = ERANGE;
2022 else lvalue *= 1024*1024;
2023 endptr++;
2024 }
2025 }
2026
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);
2030
2031 while (isspace(*endptr)) endptr++;
2032 if (*endptr != 0)
2033 extra_chars_error(endptr, inttype, US"integer value for ", name);
2034
2035 value = (int)lvalue;
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;
2177 break;
2178 }
2179
2180 case opt_func:
2181 {
2182 void (*fn)() = ol->value;
2183 fn(name, s);
2184 break;
2185 }
2186 }
2187
2188 return TRUE;
2189 }
2190
2191
2192
2193 /*************************************************
2194 * Print a time value *
2195 *************************************************/
2196
2197 /*
2198 Argument: a time value in seconds
2199 Returns: pointer to a fixed buffer containing the time as a string,
2200 in readconf_readtime() format
2201 */
2202
2203 uschar *
2204 readconf_printtime(int t)
2205 {
2206 int s, m, h, d, w;
2207 uschar *p = time_buffer;
2208
2209 if (t < 0)
2210 {
2211 *p++ = '-';
2212 t = -t;
2213 }
2214
2215 s = t % 60;
2216 t /= 60;
2217 m = t % 60;
2218 t /= 60;
2219 h = t % 24;
2220 t /= 24;
2221 d = t % 7;
2222 w = t/7;
2223
2224 if (w > 0) { sprintf(CS p, "%dw", w); while (*p) p++; }
2225 if (d > 0) { sprintf(CS p, "%dd", d); while (*p) p++; }
2226 if (h > 0) { sprintf(CS p, "%dh", h); while (*p) p++; }
2227 if (m > 0) { sprintf(CS p, "%dm", m); while (*p) p++; }
2228 if (s > 0 || p == time_buffer) sprintf(CS p, "%ds", s);
2229
2230 return 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.
2240 The entire options list is passed in as an argument, because some options come
2241 in pairs - typically uid/gid settings, which can either be explicit numerical
2242 values, or strings to be expanded later. If the numerical value is unset,
2243 search for "*expand_<name>" to see if there is a string equivalent.
2244
2245 Arguments:
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
2254 no_labels do not show "foo = " at the start.
2255
2256 Returns: nothing
2257 */
2258
2259 static void
2260 print_ol(optionlist *ol, uschar *name, void *options_block,
2261 optionlist *oltop, int last, BOOL no_labels)
2262 {
2263 struct passwd *pw;
2264 struct group *gr;
2265 optionlist *ol2;
2266 void *value;
2267 uid_t *uidlist;
2268 gid_t *gidlist;
2269 uschar *s;
2270 uschar name2[64];
2271
2272 if (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
2281 if (!admin_user && (ol->type & opt_secure) != 0)
2282 {
2283 if (no_labels)
2284 printf("%s\n", hidden);
2285 else
2286 printf("%s = %s\n", name, hidden);
2287 return;
2288 }
2289
2290 /* Else show the value of the option */
2291
2292 value = ol->value;
2293 if (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
2300 switch(ol->type & opt_mask)
2301 {
2302 case opt_stringptr:
2303 case opt_rewrite: /* Show the text value */
2304 s = *((uschar **)value);
2305 if (!no_labels) printf("%s = ", name);
2306 printf("%s\n", (s == NULL)? US"" : string_printing2(s, FALSE));
2307 break;
2308
2309 case opt_int:
2310 if (!no_labels) printf("%s = ", name);
2311 printf("%d\n", *((int *)value));
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 }
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);
2333 }
2334 }
2335 break;
2336
2337 case opt_Kint:
2338 {
2339 int x = *((int *)value);
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);
2344 }
2345 break;
2346
2347 case opt_octint:
2348 if (!no_labels) printf("%s = ", name);
2349 printf("%#o\n", *((int *)value));
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 {
2361 if (!no_labels) printf("%s = ", name);
2362 printf("%d.", x/1000);
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);
2388 if (!no_labels) printf("%s = ", name);
2389 printf("%s\n", (s == NULL)? US"" : string_printing(s));
2390 break;
2391 }
2392 }
2393
2394 /* Else fall through */
2395
2396 case opt_uid:
2397 if (!no_labels) printf("%s = ", name);
2398 if (! *get_set_flag(name, oltop, last, options_block))
2399 printf("\n");
2400 else
2401 {
2402 pw = getpwuid(*((uid_t *)value));
2403 if (pw == NULL)
2404 printf("%ld\n", (long int)(*((uid_t *)value)));
2405 else printf("%s\n", pw->pw_name);
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);
2422 if (!no_labels) printf("%s = ", name);
2423 printf("%s\n", (s == NULL)? US"" : string_printing(s));
2424 break;
2425 }
2426 }
2427
2428 /* Else fall through */
2429
2430 case opt_gid:
2431 if (!no_labels) printf("%s = ", name);
2432 if (! *get_set_flag(name, oltop, last, options_block))
2433 printf("\n");
2434 else
2435 {
2436 gr = getgrgid(*((int *)value));
2437 if (gr == NULL)
2438 printf("%ld\n", (long int)(*((int *)value)));
2439 else printf("%s\n", gr->gr_name);
2440 }
2441 break;
2442
2443 case opt_uidlist:
2444 uidlist = *((uid_t **)value);
2445 if (!no_labels) printf("%s =", name);
2446 if (uidlist != NULL)
2447 {
2448 int i;
2449 uschar sep = ' ';
2450 if (no_labels) sep = '\0';
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;
2456 if (sep != '\0') printf("%c", sep);
2457 if (name != NULL) printf("%s", name);
2458 else printf("%ld", (long int)(uidlist[i]));
2459 sep = ':';
2460 }
2461 }
2462 printf("\n");
2463 break;
2464
2465 case opt_gidlist:
2466 gidlist = *((gid_t **)value);
2467 if (!no_labels) printf("%s =", name);
2468 if (gidlist != NULL)
2469 {
2470 int i;
2471 uschar sep = ' ';
2472 if (no_labels) sep = '\0';
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;
2478 if (sep != '\0') printf("%c", sep);
2479 if (name != NULL) printf("%s", name);
2480 else printf("%ld", (long int)(gidlist[i]));
2481 sep = ':';
2482 }
2483 }
2484 printf("\n");
2485 break;
2486
2487 case opt_time:
2488 if (!no_labels) printf("%s = ", name);
2489 printf("%s\n", readconf_printtime(*((int *)value)));
2490 break;
2491
2492 case opt_timelist:
2493 {
2494 int i;
2495 int *list = (int *)value;
2496 if (!no_labels) printf("%s = ", name);
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 {
2519 if (!no_labels) printf("%s = ", name);
2520 printf("%s\n", string_printing(s));
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,
2543 causes the value of any main configuration variable to be output if the
2544 second argument is NULL. There are some special values:
2545
2546 all print all main configuration options
2547 config_file print the name of the configuration file
2548 (configure_file will still work, for backward
2549 compatibility)
2550 routers print the routers' configurations
2551 transports print the transports' configuration
2552 authenticators print the authenticators' configuration
2553 macros print the macros' configuration
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
2557 macro_list print a list of macro names
2558 +name print a named list item
2559 local_scan print the local_scan options
2560 config print the configuration as it is parsed
2561 environment print the used execution environment
2562
2563 If 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
2565 driver whose options are to be printed.
2566
2567 Arguments:
2568 name option name if type == NULL; else driver name
2569 type NULL or driver type name, as described above
2570 no_labels avoid the "foo = " at the start of an item
2571
2572 Returns: nothing
2573 */
2574
2575 void
2576 readconf_print(uschar *name, uschar *type, BOOL no_labels)
2577 {
2578 BOOL names_only = FALSE;
2579 optionlist *ol;
2580 optionlist *ol2 = NULL;
2581 driver_instance *d = NULL;
2582 macro_item *m;
2583 int size = 0;
2584
2585 if (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;
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);
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
2618 if ( Ustrcmp(name, "configure_file") == 0
2619 ||Ustrcmp(name, "config_file") == 0)
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)
2631 print_ol(ol, US ol->name, NULL,
2632 optionlist_config, optionlist_config_size,
2633 no_labels);
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,
2647 local_scan_options_count, no_labels);
2648 }
2649 #endif
2650 return;
2651 }
2652
2653 if (Ustrcmp(name, "config") == 0)
2654 {
2655 print_config(admin_user);
2656 return;
2657 }
2658
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
2676 else if (Ustrcmp(name, "macros") == 0)
2677 {
2678 type = US"macro";
2679 name = NULL;
2680 }
2681
2682 else if (Ustrcmp(name, "router_list") == 0)
2683 {
2684 type = US"router";
2685 name = NULL;
2686 names_only = TRUE;
2687 }
2688
2689 else if (Ustrcmp(name, "transport_list") == 0)
2690 {
2691 type = US"transport";
2692 name = NULL;
2693 names_only = TRUE;
2694 }
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
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
2729 else
2730 {
2731 print_ol(find_option(name, optionlist_config, optionlist_config_size),
2732 name, NULL, optionlist_config, optionlist_config_size, no_labels);
2733 return;
2734 }
2735 }
2736
2737 /* Handle the options for a router or transport. Skip options that are flagged
2738 as hidden. Some of these are options with names starting with '*', used for
2739 internal alternative representations of other options (which the printing
2740 function will sort out). Others are synonyms kept for backward compatibility.
2741 */
2742
2743 if (Ustrcmp(type, "router") == 0)
2744 {
2745 d = (driver_instance *)routers;
2746 ol2 = optionlist_routers;
2747 size = optionlist_routers_size;
2748 }
2749 else if (Ustrcmp(type, "transport") == 0)
2750 {
2751 d = (driver_instance *)transports;
2752 ol2 = optionlist_transports;
2753 size = optionlist_transports_size;
2754 }
2755 else if (Ustrcmp(type, "authenticator") == 0)
2756 {
2757 d = (driver_instance *)auths;
2758 ol2 = optionlist_auths;
2759 size = optionlist_auths_size;
2760 }
2761
2762 else 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
2788 if (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
2796 for (; 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)
2805 print_ol(ol, US ol->name, d, ol2, size, no_labels);
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)
2812 print_ol(ol, US ol->name, d, d->info->options, *(d->info->options_count), no_labels);
2813 }
2814 if (name != NULL) return;
2815 }
2816 if (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
2826 save the list in a tree, sorted by its name. Each entry also has a number,
2827 which can be used for caching tests, but if the string contains any expansion
2828 items other than $key, the number is set negative to inhibit caching. This
2829 mechanism is used for domain, host, and address lists that are referenced by
2830 the "+name" syntax.
2831
2832 Arguments:
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
2840 Returns: nothing
2841 */
2842
2843 static void
2844 read_named_list(tree_node **anchorp, int *numberp, int max, uschar *s,
2845 uschar *tname)
2846 {
2847 BOOL forcecache = FALSE;
2848 uschar *ss;
2849 tree_node *t;
2850 namedlist_block *nb = store_get(sizeof(namedlist_block));
2851
2852 if (Ustrncmp(s, "_cache", 6) == 0)
2853 {
2854 forcecache = TRUE;
2855 s += 6;
2856 }
2857
2858 if (!isspace(*s))
2859 log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, "unrecognized configuration line");
2860
2861 if (*numberp >= max)
2862 log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, "too many named %ss (max is %d)\n",
2863 tname, max);
2864
2865 while (isspace(*s)) s++;
2866 ss = s;
2867 while (isalnum(*s) || *s == '_') s++;
2868 t = store_get(sizeof(tree_node) + s-ss);
2869 Ustrncpy(t->name, ss, s-ss);
2870 t->name[s-ss] = 0;
2871 while (isspace(*s)) s++;
2872
2873 if (!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
2877 t->data.ptr = nb;
2878 nb->number = *numberp;
2879 *numberp += 1;
2880
2881 if (*s++ != '=') log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN,
2882 "missing '=' after \"%s\"", t->name);
2883 while (isspace(*s)) s++;
2884 nb->string = read_string(s, t->name);
2885 nb->cache_data = NULL;
2886
2887 /* Check the string for any expansions; if any are found, mark this list
2888 uncacheable unless the user has explicited forced caching. */
2889
2890 if (!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
2901 separate values.
2902
2903 Arguments:
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
2914 Returns: nothing (panics on error)
2915 */
2916
2917 static void
2918 unpick_ratelimit(uschar *s, int *threshold, int *base, double *factor,
2919 int *limit)
2920 {
2921 uschar bstring[16], lstring[16];
2922
2923 if (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 }
2930 log_write(0, LOG_MAIN|LOG_PANIC_DIE, "malformed ratelimit data: %s", s);
2931 }
2932
2933
2934
2935
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
2941 root when we call into the TLS library, in case of library linkage errors
2942 which cause segfaults; before this check, those were always done as the Exim
2943 runtime user and it makes sense to continue with that.
2944
2945 Assumes: 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
2949 Returns: bool for "okay"; false will cause caller to immediately exit.
2950 */
2951
2952 #ifdef SUPPORT_TLS
2953 static BOOL
2954 tls_dropprivs_validate_require_cipher(void)
2955 {
2956 const uschar *errmsg;
2957 pid_t pid;
2958 int rc, status;
2959 void (*oldsignal)(int);
2960
2961 /* If TLS will never be used, no point checking ciphers */
2962
2963 if ( !tls_advertise_hosts
2964 || !*tls_advertise_hosts
2965 || Ustrcmp(tls_advertise_hosts, ":") == 0
2966 )
2967 return TRUE;
2968 else 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
2973 oldsignal = signal(SIGCHLD, SIG_DFL);
2974
2975 fflush(NULL);
2976 if ((pid = fork()) < 0)
2977 log_write(0, LOG_MAIN|LOG_PANIC_DIE, "fork failed for TLS check");
2978
2979 if (pid == 0)
2980 {
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");
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
2996 do {
2997 rc = waitpid(pid, &status, 0);
2998 } while (rc < 0 && errno == EINTR);
2999
3000 DEBUG(D_tls)
3001 debug_printf("tls_validate_require_cipher child %d ended: status=0x%x\n",
3002 (int)pid, status);
3003
3004 signal(SIGCHLD, oldsignal);
3005
3006 return status == 0;
3007 }
3008 #endif /* SUPPORT_TLS */
3009
3010
3011
3012
3013 /*************************************************
3014 * Read main configuration options *
3015 *************************************************/
3016
3017 /* This function is the first to be called for configuration reading. It
3018 opens the configuration file and reads general configuration settings until
3019 it reaches the end of the configuration section. The file is then left open so
3020 that the remaining configuration data can subsequently be read if needed for
3021 this run of Exim.
3022
3023 The configuration file must be owned either by root or exim, and be writeable
3024 only by root or uid/gid exim. The values for Exim's uid and gid can be changed
3025 in the config file, so the test is done on the compiled in values. A slight
3026 anomaly, to be carefully documented.
3027
3028 The name of the configuration file is taken from a list that is included in the
3029 binary of Exim. It can be altered from the command line, but if that is done,
3030 root privilege is immediately withdrawn unless the caller is root or exim.
3031 The first file on the list that exists is used.
3032
3033 For use on multiple systems that share file systems, first look for a
3034 configuration file whose name has the current node name on the end. If that is
3035 not found, try the generic name. For really contorted configurations, that run
3036 multiple Exims with different uid settings, first try adding the effective uid
3037 before the node name. These complications are going to waste resources on most
3038 systems. Therefore they are available only when requested by compile-time
3039 options. */
3040
3041 void
3042 readconf_main(void)
3043 {
3044 int sep = 0;
3045 struct stat statbuf;
3046 uschar *s, *filename;
3047 const uschar *list = config_main_filelist;
3048
3049 /* Loop through the possible file names */
3050
3051 while((filename = string_nextinlist(&list, &sep, big_buffer, big_buffer_size))
3052 != NULL)
3053 {
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
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
3117 logging configuration errors (it changes for .included files) whereas
3118 config_main_filename is the name shown by -bP. Failure to open a configuration
3119 file is a serious disaster. */
3120
3121 if (config_file != NULL)
3122 {
3123 uschar *p;
3124 config_filename = config_main_filename = string_copy(filename);
3125
3126 p = Ustrrchr(filename, '/');
3127 config_main_directory = p ? string_copyn(filename, p - filename)
3128 : string_copy(US".");
3129 }
3130 else
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
3140 /* Check the status of the file we have opened, if we have retained root
3141 privileges and the file isn't /dev/null (which *should* be 0666). */
3142
3143 if (trusted_config && Ustrcmp(filename, US"/dev/null"))
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
3149 if ((statbuf.st_uid != root_uid /* owner not root */
3150 #ifdef CONFIGURE_OWNER
3151 && statbuf.st_uid != config_uid /* owner not the special one */
3152 #endif
3153 ) || /* or */
3154 (statbuf.st_gid != root_gid /* group not root & */
3155 #ifdef CONFIGURE_GROUP
3156 && statbuf.st_gid != config_gid /* group not the special one */
3157 #endif
3158 && (statbuf.st_mode & 020) != 0) || /* group writeable */
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
3167 letter. If we see something starting with an upper case letter, it is taken as
3168 a macro definition. */
3169
3170 while ((s = get_config_line()) != NULL)
3171 {
3172 if (isupper(s[0])) read_macro_assignment(s);
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
3198 if (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
3203 wanted. */
3204
3205 if (timezone_string != NULL && *timezone_string == 0) timezone_string = NULL;
3206
3207 /* The max retry interval must not be greater than 24 hours. */
3208
3209 if (retry_interval_max > 24*60*60) retry_interval_max = 24*60*60;
3210
3211 /* remote_max_parallel must be > 0 */
3212
3213 if (remote_max_parallel <= 0) remote_max_parallel = 1;
3214
3215 /* Save the configured setting of freeze_tell, so we can re-instate it at the
3216 start of a new SMTP message. */
3217
3218 freeze_tell_config = freeze_tell;
3219
3220 /* The primary host name may be required for expansion of spool_directory
3221 and log_file_path, so make sure it is set asap. It is obtained from uname(),
3222 but if that yields an unqualified value, make a FQDN by using gethostbyname to
3223 canonize it. Some people like upper case letters in their host names, so we
3224 don't force the case. */
3225
3226 if (primary_hostname == NULL)
3227 {
3228 const uschar *hostname;
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
3240 if (!disable_ipv6 && (dns_ipv4_lookup == NULL ||
3241 match_isinlist(hostname, CUSS &dns_ipv4_lookup, 0, NULL, NULL,
3242 MCL_DOMAIN, TRUE, NULL) != OK))
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
3277 smtp_active_hostname = primary_hostname;
3278
3279 /* If spool_directory wasn't set in the build-time configuration, it must have
3280 got set above. Of course, writing to the log may not work if log_file_path is
3281 not set, but it will at least get to syslog or somewhere, with any luck. */
3282
3283 if (*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
3288 host name. Same comment about failure. */
3289
3290 s = expand_string(spool_directory);
3291 if (s == NULL)
3292 log_write(0, LOG_MAIN|LOG_PANIC_DIE, "failed to expand spool_directory "
3293 "\"%s\": %s", spool_directory, expand_string_message);
3294 spool_directory = s;
3295
3296 /* Expand log_file_path, which must contain "%s" in any component that isn't
3297 the null string or "syslog". It is also allowed to contain one instance of %D
3298 or %M. However, it must NOT contain % followed by anything else. */
3299
3300 if (*log_file_path != 0)
3301 {
3302 const uschar *ss, *sss;
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 {
3322 if ((t[1] != 'D' && t[1] != 'M') || Ustrchr(t+2, '%') != NULL)
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
3332 openlog(). Default is LOG_MAIL set in globals.c. Allow the user to omit the
3333 leading "log_". */
3334
3335 if (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
3362 if (*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
3371 /* Set default value of process_log_path */
3372
3373 if (process_log_path == NULL || *process_log_path =='\0')
3374 process_log_path = string_sprintf("%s/exim-process.info", spool_directory);
3375
3376 /* Compile the regex for matching a UUCP-style "From_" line in an incoming
3377 message. */
3378
3379 regex_From = regex_must_compile(uucp_from_pattern, FALSE, TRUE);
3380
3381 /* Unpick the SMTP rate limiting options, if set */
3382
3383 if (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
3389 if (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
3397 if (qualify_domain_sender == NULL)
3398 qualify_domain_sender = primary_hostname;
3399 if (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
3403 name is given, but a numerical value does not. */
3404
3405 if (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
3416 and ensure it contains a domain. */
3417
3418 if (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
3435 smtp_accept_max must also be set. */
3436
3437 if (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
3444 so that it can be computed from the host name, for example. We do this last
3445 so as to ensure that everything else is set up before the expansion. */
3446
3447 if (host_number_string != NULL)
3448 {
3449 long int n;
3450 uschar *end;
3451 uschar *s = expand_string(host_number_string);
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);
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
3471 if ((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_");
3476
3477 /* This also checks that the library linkage is working and we can call
3478 routines in it, so call even if tls_require_ciphers is unset */
3479 if (!tls_dropprivs_validate_require_cipher())
3480 exit(1);
3481
3482 /* Magic number: at time of writing, 1024 has been the long-standing value
3483 used by so many clients, and what Exim used to use always, that it makes
3484 sense to just min-clamp this max-clamp at that. */
3485 if (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
3489 /* If openssl_options is set, validate it */
3490 if (openssl_options != NULL)
3491 {
3492 # ifdef USE_GNUTLS
3493 log_write(0, LOG_PANIC_DIE|LOG_CONFIG,
3494 "openssl_options is set but we're using GnuTLS");
3495 # else
3496 long dummy;
3497 if (!(tls_openssl_options_parse(openssl_options, &dummy)))
3498 log_write(0, LOG_PANIC_DIE|LOG_CONFIG,
3499 "openssl_options parse error: %s", openssl_options);
3500 # endif
3501 }
3502
3503 if (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");
3507 #endif /*SUPPORT_TLS*/
3508
3509 if ((!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");
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.
3522 We can now find the driver, set up defaults for the private options, and
3523 unset any "set" bits in the private options table (which might have been
3524 set by another incarnation of the same driver).
3525
3526 Arguments:
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
3533 Returns: pointer to the driver info block
3534 */
3535
3536 static driver_info *
3537 init_driver(driver_instance *d, driver_info *drivers_available,
3538 int size_of_info, uschar *class)
3539 {
3540 driver_info *dd;
3541
3542 for (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
3558 log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN,
3559 "%s %s: cannot find %s driver \"%s\"", class, d->name, class, d->driver_name);
3560
3561 return 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
3572 mechanisms. It reads the data from the current point in the configuration file
3573 up to the end of the section, and sets up a chain of instance blocks according
3574 to the file's contents. The file will already have been opened by a call to
3575 readconf_main, and must be left open for subsequent reading of further data.
3576
3577 Any errors cause a panic crash. Note that the blocks with names driver_info and
3578 driver_instance must map the first portions of all the _info and _instance
3579 blocks for this shared code to work.
3580
3581 Arguments:
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
3591 Returns: nothing
3592 */
3593
3594 void
3595 readconf_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 {
3605 driver_instance **p = anchor;
3606 driver_instance *d = NULL;
3607 uschar *buffer;
3608
3609 while ((buffer = get_config_line()) != NULL)
3610 {
3611 uschar name[64];
3612 uschar *s;
3613
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. */
3617
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 }
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
3683 /* Not the start of a new driver. Give an error if we have not set up a
3684 current driver yet. */
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
3718 if (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
3734 any of the string options for the driver contains the given string as an
3735 expansion variable.
3736
3737 Arguments:
3738 d points to a driver instance block
3739 s the string to search for
3740
3741 Returns: TRUE if a dependency is found
3742 */
3743
3744 BOOL
3745 readconf_depends(driver_instance *d, uschar *s)
3746 {
3747 int count = *(d->info->options_count);
3748 optionlist *ol;
3749 uschar *ss;
3750
3751 for (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
3769 DEBUG(D_transport) debug_printf("driver %s does not depend on %s\n", d->name, s);
3770 return 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
3781 program when testing retry information. It decodes strings such as "quota_7d"
3782 into numerical error codes.
3783
3784 Arguments:
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
3790 Returns: NULL if decoded correctly; else points to error text
3791 */
3792
3793 uschar *
3794 readconf_retry_error(const uschar *pp, const uschar *p,
3795 int *basic_errno, int *more_errno)
3796 {
3797 int len;
3798 const uschar *q = pp;
3799 while (q < p && *q != '_') q++;
3800 len = q - pp;
3801
3802 if (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
3809 else 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
3820 else 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;
3827 const uschar *x = q + 1;
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++)
3835 if (strncmpic(x, extras[i], xlen) == 0)
3836 {
3837 *more_errno = values[i];
3838 break;
3839 }
3840
3841 if (i >= sizeof(extras)/sizeof(uschar *))
3842 if (strncmpic(x, US"DNS", xlen) == 0)
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\"");
3846 else
3847 return US"\"A\", \"MX\", or \"connect\" expected after \"timeout\"";
3848 }
3849 }
3850
3851 else if (strncmpic(pp, US"mail_4", 6) == 0 ||
3852 strncmpic(pp, US"rcpt_4", 6) == 0 ||
3853 strncmpic(pp, US"data_4", 6) == 0)
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
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);
3873
3874 *basic_errno = *pp == 'm' ? ERRNO_MAIL4XX :
3875 *pp == 'r' ? ERRNO_RCPT4XX : ERRNO_DATA4XX;
3876 *more_errno = x << 8;
3877 }
3878
3879 else if (len == 4 && strncmpic(pp, US"auth", len) == 0 &&
3880 strncmpic(q+1, US"failed", p-q-1) == 0)
3881 *basic_errno = ERRNO_AUTHFAIL;
3882
3883 else if (strncmpic(pp, US"lost_connection", p - pp) == 0)
3884 *basic_errno = ERRNO_SMTPCLOSED;
3885
3886 else if (strncmpic(pp, US"tls_required", p - pp) == 0)
3887 *basic_errno = ERRNO_TLSREQUIRED;
3888
3889 else if (strncmpic(pp, US"lookup", p - pp) == 0)
3890 *basic_errno = ERRNO_UNKNOWNHOST;
3891
3892 else if (len != 1 || Ustrncmp(pp, "*", 1) != 0)
3893 return string_sprintf("unknown or malformed retry error \"%.*s\"", (int) (p-pp), pp);
3894
3895 return 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
3914 All this is decoded and placed into a control block. */
3915
3916
3917 /* Subroutine to read an argument, preceded by a comma and terminated
3918 by comma, semicolon, whitespace, or newline. The types are: 0 = time value,
3919 1 = fixed point number (returned *1000).
3920
3921 Arguments:
3922 paddr pointer to pointer to current character; updated
3923 type 0 => read a time; 1 => read a fixed point number
3924
3925 Returns: time in seconds or fixed point number * 1000
3926 */
3927
3928 static int
3929 retry_arg(const uschar **paddr, int type)
3930 {
3931 const uschar *p = *paddr;
3932 const uschar *pp;
3933
3934 if (*p++ != ',') log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, "comma expected");
3935
3936 while (isspace(*p)) p++;
3937 pp = p;
3938 while (isalnum(*p) || (type == 1 && *p == '.')) p++;
3939
3940 if (*p != 0 && !isspace(*p) && *p != ',' && *p != ';')
3941 log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, "comma or semicolon expected");
3942
3943 *paddr = p;
3944 switch (type)
3945 {
3946 case 0: return readconf_readtime(pp, *p, FALSE);
3947 case 1: return readconf_readfixed(pp, *p);
3948 }
3949 return 0; /* Keep picky compilers happy */
3950 }
3951
3952 /* The function proper */
3953
3954 void
3955 readconf_retries(void)
3956 {
3957 retry_config **chain = &retries;
3958 retry_config *next;
3959 const uschar *p;
3960
3961 while ((p = get_config_line()))
3962 {
3963 retry_rule **rchain;
3964 const uschar *pp;
3965 uschar *error;
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,
3981 "missing error type in retry rule");
3982
3983 /* Test error names for things we understand. */
3984
3985 if ((error = readconf_retry_error(pp, p, &next->basic_errno,
3986 &next->more_errno)))
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 */
4023 rule->p1 = retry_arg(&p, 0);
4024 break;
4025
4026 case 'G': /* Geometrically increasing intervals */
4027 case 'H': /* Ditto, but with randomness */
4028 rule->p1 = retry_arg(&p, 0);
4029 rule->p2 = retry_arg(&p, 1);
4030 break;
4031
4032 default:
4033 log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, "unknown retry rule letter");
4034 break;
4035 }
4036
4037 if (rule->timeout <= 0 || rule->p1 <= 0 ||
4038 (rule->rule != 'F' && rule->p2 < 1000))
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
4062 Arguments: none
4063 Returns: nothing
4064 */
4065
4066 static void
4067 auths_init(void)
4068 {
4069 auth_instance *au, *bu;
4070 readconf_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
4079 for (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
4106 message, we can just skip over the ACL information. No need to parse it.
4107
4108 First, we have a function for acl_read() to call back to get the next line. We
4109 need to remember the line we passed, because at the end it will contain the
4110 name of the next ACL. */
4111
4112 static uschar *acl_line;
4113
4114 static uschar *
4115 acl_callback(void)
4116 {
4117 acl_line = get_config_line();
4118 return acl_line;
4119 }
4120
4121
4122 /* Now the main function:
4123
4124 Arguments: none
4125 Returns: nothing
4126 */
4127
4128 static void
4129 readconf_acl(void)
4130 {
4131 uschar *p;
4132
4133 /* Read each ACL and add it into the tree. Macro (re)definitions are allowed
4134 between ACLs. */
4135
4136 acl_line = get_config_line();
4137
4138 while(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);
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");
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
4175 configuration file. If the local_scan() function allows for configuration
4176 options, we can process them. Otherwise, we expire in a panic.
4177
4178 Arguments: none
4179 Returns: nothing
4180 */
4181
4182 static void
4183 local_scan_init(void)
4184 {
4185 #ifndef LOCAL_SCAN_HAS_OPTIONS
4186 log_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
4190 uschar *p;
4191 while ((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
4206 configuration. It is called only when actually needed. Each subsequent section
4207 of the configuration starts with a line of the form
4208
4209 begin name
4210
4211 where the name is "routers", "transports", etc. A section is terminated by
4212 hitting the next "begin" line, and the next name is left in next_section.
4213 Because it may confuse people as to whether the names are singular or plural,
4214 we add "s" if it's missing. There is always enough room in next_section for
4215 this. This function is basically just a switch.
4216
4217 Arguments: none
4218 Returns: nothing
4219 */
4220
4221 static 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
4230 void
4231 readconf_rest(void)
4232 {
4233 int had = 0;
4234
4235 while(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 {
4264 case 0: readconf_acl(); break;
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
4274 (void)fclose(config_file);
4275 }
4276
4277 /* Init the storage for the pre-parsed config lines */
4278 void
4279 readconf_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
4285 static void
4286 save_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,
4292 this operates on a global (static) list that holds all the pre-parsed
4293 config lines, we do no further processing here, output formatting and
4294 honouring of <hide> or macros will be done during output */
4295 static void
4296 save_config_line(const uschar* line)
4297 {
4298 static config_line_item *current;
4299 config_line_item *next;
4300
4301 next = (config_line_item*) store_get(sizeof(config_line_item));
4302 next->line = string_copy(line);
4303 next->next = NULL;
4304
4305 if (!config_lines) config_lines = next;
4306 else current->next = next;
4307
4308 current = next;
4309 }
4310
4311 /* List the parsed config lines, care about nice formatting and
4312 hide the <hide> values unless we're the admin user */
4313 void
4314 print_config(BOOL admin)
4315 {
4316 config_line_item *i;
4317 const int TS = 2;
4318 int indent = 0;
4319
4320 for (i = config_lines; i; i = i->next)
4321 {
4322 uschar *current;
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
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)
4344 memmove(p+1, next, Ustrlen(next)+1);
4345
4346 if (*next == '"' || *next == '\'' || *next == '$')
4347 break;
4348 }
4349
4350 /* # lines */
4351 if (current[0] == '#')
4352 puts(CCS current);
4353
4354 /* begin lines are left aligned */
4355 else if (Ustrncmp(current, "begin", 5) == 0 && isspace(current[5]))
4356 {
4357 puts("");
4358 puts(CCS current);
4359 indent = TS;
4360 }
4361
4362 /* router/acl/transport block names */
4363 else if (current[Ustrlen(current)-1] == ':' && !Ustrchr(current, '='))
4364 {
4365 printf("\n%*s%s\n", TS, "", current);
4366 indent = 2 * TS;
4367 }
4368
4369 /* hidden lines (all MACROS or lines prefixed with "hide") */
4370 else if ( !admin
4371 && ( isupper(*current)
4372 || Ustrncmp(current, "hide", 4) == 0 && isspace(current[4])
4373 )
4374 )
4375 {
4376 if ((p = Ustrchr(current, '=')))
4377 {
4378 *p = '\0';
4379 printf("%*s%s= %s\n", indent, "", current, hidden);
4380 }
4381 /* e.g.: hide split_spool_directory */
4382 else
4383 printf("%*s\n", indent, hidden);
4384 }
4385
4386 else
4387 /* rest is public */
4388 printf("%*s%s\n", indent, "", current);
4389 }
4390 }
4391
4392 /* vi: aw ai sw=2
4393 */
4394 /* End of readconf.c */