1 /* WARNING: THIS FILE IS GENERATED - DO NOT PATCH!
2    It's not enough alone in any case, because the defaults may be
3    coming from the individual *-settings.c in some situations. If you
4    wish to modify defaults, change the other *-settings.c files and
5    just delete this file. This file will be automatically regenerated
6    by make. (This file is distributed in the tarball only because some
7    systems might not have Perl installed.) */
8 #include "lib.h"
9 #include "array.h"
10 #include "str.h"
11 #include "ipwd.h"
12 #include "var-expand.h"
13 #include "file-lock.h"
14 #include "fsync-mode.h"
15 #include "hash-format.h"
16 #include "net.h"
17 #include "unichar.h"
18 #include "hash-method.h"
19 #include "settings-parser.h"
20 #include "message-header-parser.h"
21 #include "all-settings.h"
22 #include <stddef.h>
23 #include <unistd.h>
24 #define CONFIG_BINARY
25 extern buffer_t config_all_services_buf;/* ../../src/lib-storage/mail-storage-settings.h */
26 extern const struct setting_parser_info mail_user_setting_parser_info;
27 extern const struct setting_parser_info mail_namespace_setting_parser_info;
28 extern const struct setting_parser_info mail_storage_setting_parser_info;
29 /* <settings checks> */
30 #define MAILBOX_SET_AUTO_NO "no"
31 #define MAILBOX_SET_AUTO_CREATE "create"
32 #define MAILBOX_SET_AUTO_SUBSCRIBE "subscribe"
33 /* </settings checks> */
34 struct mail_storage_settings {
35 	const char *mail_location;
36 	const char *mail_attachment_fs;
37 	const char *mail_attachment_dir;
38 	const char *mail_attachment_hash;
39 	uoff_t mail_attachment_min_size;
40 	const char *mail_attribute_dict;
41 	unsigned int mail_prefetch_count;
42 	const char *mail_cache_fields;
43 	const char *mail_always_cache_fields;
44 	const char *mail_never_cache_fields;
45 	const char *mail_server_comment;
46 	const char *mail_server_admin;
47 	unsigned int mail_cache_min_mail_count;
48 	unsigned int mail_cache_unaccessed_field_drop;
49 	uoff_t mail_cache_record_max_size;
50 	uoff_t mail_cache_max_size;
51 	uoff_t mail_cache_purge_min_size;
52 	unsigned int mail_cache_purge_delete_percentage;
53 	unsigned int mail_cache_purge_continued_percentage;
54 	unsigned int mail_cache_purge_header_continue_count;
55 	uoff_t mail_index_rewrite_min_log_bytes;
56 	uoff_t mail_index_rewrite_max_log_bytes;
57 	uoff_t mail_index_log_rotate_min_size;
58 	uoff_t mail_index_log_rotate_max_size;
59 	unsigned int mail_index_log_rotate_min_age;
60 	unsigned int mail_index_log2_max_age;
61 	unsigned int mailbox_idle_check_interval;
62 	unsigned int mail_max_keyword_length;
63 	unsigned int mail_max_lock_timeout;
64 	unsigned int mail_temp_scan_interval;
65 	unsigned int mail_vsize_bg_after_count;
66 	unsigned int mail_sort_max_read_count;
67 	bool mail_save_crlf;
68 	const char *mail_fsync;
69 	bool mmap_disable;
70 	bool dotlock_use_excl;
71 	bool mail_nfs_storage;
72 	bool mail_nfs_index;
73 	bool mailbox_list_index;
74 	bool mailbox_list_index_very_dirty_syncs;
75 	bool mailbox_list_index_include_inbox;
76 	bool mail_debug;
77 	bool mail_full_filesystem_access;
78 	bool maildir_stat_dirs;
79 	bool mail_shared_explicit_inbox;
80 	const char *lock_method;
81 	const char *pop3_uidl_format;
82 
83 	const char *hostname;
84 	const char *recipient_delimiter;
85 
86 	const char *mail_attachment_detection_options;
87 
88 	enum file_lock_method parsed_lock_method;
89 	enum fsync_mode parsed_fsync_mode;
90 
91 	const char *const *parsed_mail_attachment_content_type_filter;
92 	bool parsed_mail_attachment_exclude_inlined;
93 	bool parsed_mail_attachment_detection_add_flags;
94 	bool parsed_mail_attachment_detection_no_flags_on_fetch;
95 };
96 struct mail_namespace_settings {
97 	const char *name;
98 	const char *type;
99 	const char *separator;
100 	const char *prefix;
101 	const char *location;
102 	const char *alias_for;
103 
104 	bool inbox;
105 	bool hidden;
106 	const char *list;
107 	bool subscriptions;
108 	bool ignore_on_failure;
109 	bool disabled;
110 	unsigned int order;
111 
112 	ARRAY(struct mailbox_settings *) mailboxes;
113 	struct mail_user_settings *user_set;
114 };
115 struct mailbox_settings {
116 	const char *name;
117 	const char *autocreate;
118 	const char *special_use;
119 	const char *driver;
120 	const char *comment;
121 	unsigned int autoexpunge;
122 	unsigned int autoexpunge_max_mails;
123 };
124 struct mail_user_settings {
125 	const char *base_dir;
126 	const char *auth_socket_path;
127 	const char *mail_temp_dir;
128 
129 	const char *mail_uid;
130 	const char *mail_gid;
131 	const char *mail_home;
132 	const char *mail_chroot;
133 	const char *mail_access_groups;
134 	const char *mail_privileged_group;
135 	const char *valid_chroot_dirs;
136 
137 	unsigned int first_valid_uid, last_valid_uid;
138 	unsigned int first_valid_gid, last_valid_gid;
139 
140 	const char *mail_plugins;
141 	const char *mail_plugin_dir;
142 
143 	const char *mail_log_prefix;
144 
145 	const char *hostname;
146 	const char *postmaster_address;
147 
148 	ARRAY(struct mail_namespace_settings *) namespaces;
149 	ARRAY(const char *) plugin_envs;
150 
151 	/* May be NULL - use mail_storage_get_postmaster_address() instead of
152 	   directly accessing this. */
153 	const struct message_address *_parsed_postmaster_address;
154 	const struct smtp_address *_parsed_postmaster_address_smtp;
155 };
156 /* ../../src/lib-storage/index/pop3c/pop3c-settings.h */
157 /* <settings checks> */
158 enum pop3c_features {
159         POP3C_FEATURE_NO_PIPELINING = 0x1,
160 };
161 /* </settings checks> */
162 struct pop3c_settings {
163 	const char *pop3c_host;
164 	in_port_t pop3c_port;
165 
166 	const char *pop3c_user;
167 	const char *pop3c_master_user;
168 	const char *pop3c_password;
169 
170 	const char *pop3c_ssl;
171 	bool pop3c_ssl_verify;
172 
173 	const char *pop3c_rawlog_dir;
174 	bool pop3c_quick_received_date;
175 
176 	const char *pop3c_features;
177 	enum pop3c_features parsed_features;
178 };
179 /* ../../src/lib-storage/index/mbox/mbox-settings.h */
180 struct mbox_settings {
181 	const char *mbox_read_locks;
182 	const char *mbox_write_locks;
183 	unsigned int mbox_lock_timeout;
184 	unsigned int mbox_dotlock_change_timeout;
185 	uoff_t mbox_min_index_size;
186 	bool mbox_dirty_syncs;
187 	bool mbox_very_dirty_syncs;
188 	bool mbox_lazy_writes;
189 	const char *mbox_md5;
190 };
191 /* ../../src/lib-storage/index/maildir/maildir-settings.h */
192 struct maildir_settings {
193 	bool maildir_copy_with_hardlinks;
194 	bool maildir_very_dirty_syncs;
195 	bool maildir_broken_filename_sizes;
196 	bool maildir_empty_new;
197 };
198 /* ../../src/lib-storage/index/imapc/imapc-settings.h */
199 /* <settings checks> */
200 enum imapc_features {
201 	IMAPC_FEATURE_RFC822_SIZE		= 0x01,
202 	IMAPC_FEATURE_GUID_FORCED		= 0x02,
203 	IMAPC_FEATURE_FETCH_HEADERS		= 0x04,
204 	IMAPC_FEATURE_GMAIL_MIGRATION		= 0x08,
205 	IMAPC_FEATURE_SEARCH			= 0x10,
206 	IMAPC_FEATURE_ZIMBRA_WORKAROUNDS	= 0x20,
207 	IMAPC_FEATURE_NO_EXAMINE		= 0x40,
208 	IMAPC_FEATURE_PROXYAUTH			= 0x80,
209 	IMAPC_FEATURE_FETCH_MSN_WORKAROUNDS	= 0x100,
210 	IMAPC_FEATURE_FETCH_FIX_BROKEN_MAILS	= 0x200,
211 	IMAPC_FEATURE_MODSEQ			= 0x400,
212 	IMAPC_FEATURE_DELAY_LOGIN		= 0x800,
213 	IMAPC_FEATURE_FETCH_BODYSTRUCTURE	= 0x1000,
214 	IMAPC_FEATURE_SEND_ID			= 0x2000,
215 	IMAPC_FEATURE_FETCH_EMPTY_IS_EXPUNGED	= 0x4000,
216 	IMAPC_FEATURE_NO_MSN_UPDATES		= 0x8000,
217 	IMAPC_FEATURE_ACL 			= 0x10000,
218 };
219 /* </settings checks> */
220 struct imapc_settings {
221 	const char *imapc_host;
222 	in_port_t imapc_port;
223 
224 	const char *imapc_user;
225 	const char *imapc_master_user;
226 	const char *imapc_password;
227 	const char *imapc_sasl_mechanisms;
228 
229 	const char *imapc_ssl;
230 	bool imapc_ssl_verify;
231 
232 	const char *imapc_features;
233 	const char *imapc_rawlog_dir;
234 	const char *imapc_list_prefix;
235 	unsigned int imapc_cmd_timeout;
236 	unsigned int imapc_max_idle_time;
237 	unsigned int imapc_connection_retry_count;
238 	unsigned int imapc_connection_retry_interval;
239 	uoff_t imapc_max_line_length;
240 
241 	const char *pop3_deleted_flag;
242 
243 	enum imapc_features parsed_features;
244 	unsigned int throttle_init_msecs;
245 	unsigned int throttle_max_msecs;
246 	unsigned int throttle_shrink_min_msecs;
247 };
248 /* ../../src/lib-storage/index/dbox-multi/mdbox-settings.h */
249 struct mdbox_settings {
250 	bool mdbox_preallocate_space;
251 	uoff_t mdbox_rotate_size;
252 	unsigned int mdbox_rotate_interval;
253 };
254 /* ../../src/lib-smtp/smtp-submit-settings.h */
255 extern const struct setting_parser_info smtp_submit_setting_parser_info;
256 struct smtp_submit_settings {
257 	const char *hostname;
258 	bool mail_debug;
259 
260 	const char *submission_host;
261 	const char *sendmail_path;
262 	unsigned int submission_timeout;
263 
264 	const char *submission_ssl;
265 };
266 /* ../../src/lib-settings/settings.h */
267 #define DEF_STRUCT_STR(name, struct_name) \
268 	{ SET_STR + COMPILE_ERROR_IF_TYPES_NOT_COMPATIBLE( \
269 		((struct struct_name *)0)->name, const char *), \
270 	  #name, offsetof(struct struct_name, name) }
271 #define DEF_STRUCT_INT(name, struct_name) \
272 	{ SET_INT + COMPILE_ERROR_IF_TYPES_NOT_COMPATIBLE( \
273 		((struct struct_name *)0)->name, unsigned int), \
274 	  #name, offsetof(struct struct_name, name) }
275 #define DEF_STRUCT_BOOL(name, struct_name) \
276 	{ SET_BOOL + COMPILE_ERROR_IF_TYPES_NOT_COMPATIBLE( \
277 		((struct struct_name *)0)->name, bool), \
278 	  #name, offsetof(struct struct_name, name) }
279 /* ../../src/lib-master/service-settings.h */
280 /* <settings checks> */
281 enum service_user_default {
282 	SERVICE_USER_DEFAULT_NONE = 0,
283 	SERVICE_USER_DEFAULT_INTERNAL,
284 	SERVICE_USER_DEFAULT_LOGIN
285 };
286 
287 enum service_type {
288 	SERVICE_TYPE_UNKNOWN,
289 	SERVICE_TYPE_LOG,
290 	SERVICE_TYPE_ANVIL,
291 	SERVICE_TYPE_CONFIG,
292 	SERVICE_TYPE_LOGIN,
293 	SERVICE_TYPE_STARTUP,
294 	/* Worker processes are intentionally limited to their process_limit,
295 	   and they can regularly reach it. There shouldn't be unnecessary
296 	   warnings about temporarily reaching the limit. */
297 	SERVICE_TYPE_WORKER,
298 };
299 /* </settings checks> */
300 struct file_listener_settings {
301 	const char *path;
302 	unsigned int mode;
303 	const char *user;
304 	const char *group;
305 };
306 ARRAY_DEFINE_TYPE(file_listener_settings, struct file_listener_settings *);
307 struct inet_listener_settings {
308 	const char *name;
309 	const char *address;
310 	in_port_t port;
311 	bool ssl;
312 	bool reuse_port;
313 	bool haproxy;
314 };
315 ARRAY_DEFINE_TYPE(inet_listener_settings, struct inet_listener_settings *);
316 struct service_settings {
317 	const char *name;
318 	const char *protocol;
319 	const char *type;
320 	const char *executable;
321 	const char *user;
322 	const char *group;
323 	const char *privileged_group;
324 	const char *extra_groups;
325 	const char *chroot;
326 
327 	bool drop_priv_before_exec;
328 
329 	unsigned int process_min_avail;
330 	unsigned int process_limit;
331 	unsigned int client_limit;
332 	unsigned int service_count;
333 	unsigned int idle_kill;
334 	uoff_t vsz_limit;
335 
336 	ARRAY_TYPE(file_listener_settings) unix_listeners;
337 	ARRAY_TYPE(file_listener_settings) fifo_listeners;
338 	ARRAY_TYPE(inet_listener_settings) inet_listeners;
339 
340 	/* internal to master: */
341 	struct master_settings *master_set;
342 	enum service_type parsed_type;
343 	enum service_user_default user_default;
344 	bool login_dump_core:1;
345 
346 	/* -- flags that can be set internally -- */
347 
348 	/* process_limit must not be higher than 1 */
349 	bool process_limit_1:1;
350 };
351 ARRAY_DEFINE_TYPE(service_settings, struct service_settings *);
352 /* ../../src/lib-master/master-service-ssl-settings.h */
353 extern const struct setting_parser_info master_service_ssl_setting_parser_info;
354 extern const struct setting_parser_info master_service_ssl_server_setting_parser_info;
355 struct master_service_ssl_settings {
356 	const char *ssl;
357 	const char *ssl_ca;
358 	const char *ssl_client_ca_file;
359 	const char *ssl_client_ca_dir;
360 	const char *ssl_client_cert;
361 	const char *ssl_client_key;
362 	const char *ssl_cipher_list;
363 	const char *ssl_cipher_suites;
364 	const char *ssl_curve_list;
365 	const char *ssl_min_protocol;
366 	const char *ssl_cert_username_field;
367 	const char *ssl_crypto_device;
368 	const char *ssl_options;
369 
370 	bool ssl_verify_client_cert;
371 	bool ssl_client_require_valid_cert;
372 	bool ssl_require_crl;
373 	bool verbose_ssl;
374 	bool ssl_prefer_server_ciphers;
375 
376 	/* These are derived from ssl_options, not set directly */
377 	struct {
378 		bool compression;
379 		bool tickets;
380 	} parsed_opts;
381 };
382 struct master_service_ssl_server_settings {
383 	const char *ssl_cert;
384 	const char *ssl_alt_cert;
385 	const char *ssl_key;
386 	const char *ssl_alt_key;
387 	const char *ssl_key_password;
388 	const char *ssl_dh;
389 };
390 /* ../../src/lib-master/master-service-settings.h */
391 extern const struct setting_parser_info master_service_setting_parser_info;
392 struct master_service_settings {
393 	/* NOTE: log process won't see any new settings unless they're
394 	   explicitly sent via environment variables by master process. */
395 	const char *base_dir;
396 	const char *state_dir;
397 	const char *instance_name;
398 	const char *log_path;
399 	const char *info_log_path;
400 	const char *debug_log_path;
401 	const char *log_timestamp;
402 	const char *log_debug;
403 	const char *log_core_filter;
404 	const char *syslog_facility;
405 	const char *import_environment;
406 	const char *stats_writer_socket_path;
407 	uoff_t config_cache_size;
408 	bool version_ignore;
409 	bool shutdown_clients;
410 	bool verbose_proctitle;
411 
412 	const char *haproxy_trusted_networks;
413 	unsigned int haproxy_timeout;
414 };
415 /* ../../src/lib-lda/lda-settings.h */
416 extern const struct setting_parser_info lda_setting_parser_info;
417 struct lda_settings {
418 	const char *hostname;
419 	const char *rejection_subject;
420 	const char *rejection_reason;
421 	const char *deliver_log_format;
422 	const char *recipient_delimiter;
423 	const char *lda_original_recipient_header;
424 
425 	bool quota_full_tempfail;
426 	bool lda_mailbox_autocreate;
427 	bool lda_mailbox_autosubscribe;
428 };
429 /* ../../src/lib-dict-backend/dict-sql-settings.h */
430 struct dict_sql_settings {
431 	const char *connect;
432 
433 	unsigned int max_pattern_fields_count;
434 	ARRAY(struct dict_sql_map) maps;
435 };
436 /* ../../src/lib-dict-backend/dict-ldap-settings.h */
437 struct dict_ldap_settings {
438 	const char *uri;
439 	const char *bind_dn;
440 	const char *password;
441 	unsigned int timeout;
442 	unsigned int max_idle_time;
443 	unsigned int debug;
444 	unsigned int max_attribute_count;
445 	bool require_ssl;
446 	bool start_tls;
447 	ARRAY(struct dict_ldap_map) maps;
448 };
449 /* ../../src/lib-storage/mail-storage-settings.c */
450 extern const struct setting_parser_info mailbox_setting_parser_info;
451 extern const struct setting_parser_info mail_namespace_setting_parser_info;
452 /* <settings checks> */
mail_cache_fields_parse(const char * key,const char * value,const char ** error_r)453 static bool mail_cache_fields_parse(const char *key, const char *value,
454 				    const char **error_r)
455 {
456 	const char *const *arr;
457 
458 	for (arr = t_strsplit_spaces(value, " ,"); *arr != NULL; arr++) {
459 		const char *name = *arr;
460 
461 		if (strncasecmp(name, "hdr.", 4) == 0 &&
462 		    !message_header_name_is_valid(name+4)) {
463 			*error_r = t_strdup_printf(
464 				"Invalid %s: %s is not a valid header name",
465 				key, name);
466 			return FALSE;
467 		}
468 	}
469 	return TRUE;
470 }
471 
mail_storage_settings_check(void * _set,pool_t pool,const char ** error_r)472 static bool mail_storage_settings_check(void *_set, pool_t pool,
473 					const char **error_r)
474 {
475 	struct mail_storage_settings *set = _set;
476 	struct hash_format *format;
477 	const char *p, *error;
478 	bool uidl_format_ok;
479 	char c;
480 
481 	if (set->mailbox_idle_check_interval == 0) {
482 		*error_r = "mailbox_idle_check_interval must not be 0";
483 		return FALSE;
484 	}
485 
486 	if (strcmp(set->mail_fsync, "optimized") == 0)
487 		set->parsed_fsync_mode = FSYNC_MODE_OPTIMIZED;
488 	else if (strcmp(set->mail_fsync, "never") == 0)
489 		set->parsed_fsync_mode = FSYNC_MODE_NEVER;
490 	else if (strcmp(set->mail_fsync, "always") == 0)
491 		set->parsed_fsync_mode = FSYNC_MODE_ALWAYS;
492 	else {
493 		*error_r = t_strdup_printf("Unknown mail_fsync: %s",
494 					   set->mail_fsync);
495 		return FALSE;
496 	}
497 
498 	if (set->mail_nfs_index && !set->mmap_disable) {
499 		*error_r = "mail_nfs_index=yes requires mmap_disable=yes";
500 		return FALSE;
501 	}
502 	if (set->mail_nfs_index &&
503 	    set->parsed_fsync_mode != FSYNC_MODE_ALWAYS) {
504 		*error_r = "mail_nfs_index=yes requires mail_fsync=always";
505 		return FALSE;
506 	}
507 
508 	if (!file_lock_method_parse(set->lock_method,
509 				    &set->parsed_lock_method)) {
510 		*error_r = t_strdup_printf("Unknown lock_method: %s",
511 					   set->lock_method);
512 		return FALSE;
513 	}
514 
515 	if (set->mail_cache_max_size > 1024 * 1024 * 1024) {
516 		*error_r = "mail_cache_max_size can't be over 1 GB";
517 		return FALSE;
518 	}
519 	if (set->mail_cache_purge_delete_percentage > 100) {
520 		*error_r = "mail_cache_purge_delete_percentage can't be over 100";
521 		return FALSE;
522 	}
523 
524 	uidl_format_ok = FALSE;
525 	for (p = set->pop3_uidl_format; *p != '\0'; p++) {
526 		if (p[0] != '%' || p[1] == '\0')
527 			continue;
528 
529 		c = var_get_key(++p);
530 		switch (c) {
531 		case 'v':
532 		case 'u':
533 		case 'm':
534 		case 'f':
535 		case 'g':
536 			uidl_format_ok = TRUE;
537 			break;
538 		case '%':
539 			break;
540 		default:
541 			*error_r = t_strdup_printf(
542 				"Unknown pop3_uidl_format variable: %%%c", c);
543 			return FALSE;
544 		}
545 	}
546 	if (!uidl_format_ok) {
547 		*error_r = "pop3_uidl_format setting doesn't contain any "
548 			"%% variables.";
549 		return FALSE;
550 	}
551 
552 	if (strchr(set->mail_attachment_hash, '/') != NULL) {
553 		*error_r = "mail_attachment_hash setting "
554 			"must not contain '/' characters";
555 		return FALSE;
556 	}
557 	if (hash_format_init(set->mail_attachment_hash, &format, &error) < 0) {
558 		*error_r = t_strconcat("Invalid mail_attachment_hash setting: ",
559 				       error, NULL);
560 		return FALSE;
561 	}
562 	if (strchr(set->mail_attachment_hash, '-') != NULL) {
563 		*error_r = "mail_attachment_hash setting "
564 			"must not contain '-' characters";
565 		return FALSE;
566 	}
567 	hash_format_deinit_free(&format);
568 
569 	// FIXME: check set->mail_server_admin syntax (RFC 5464, Section 6.2.2)
570 
571 #ifndef CONFIG_BINARY
572 	if (*set->hostname == '\0')
573 		set->hostname = p_strdup(pool, my_hostdomain());
574 #endif
575 
576 	/* parse mail_attachment_indicator_options */
577 	if (*set->mail_attachment_detection_options != '\0') {
578 		ARRAY_TYPE(const_string) content_types;
579 		p_array_init(&content_types, pool, 2);
580 
581 		const char *const *options =
582 			t_strsplit_spaces(set->mail_attachment_detection_options, " ");
583 
584 		while(*options != NULL) {
585 			const char *opt = *options;
586 
587 			if (strcmp(opt, "add-flags") == 0 ||
588 			    strcmp(opt, "add-flags-on-save") == 0) {
589 				set->parsed_mail_attachment_detection_add_flags = TRUE;
590 			} else if (strcmp(opt, "no-flags-on-fetch") == 0) {
591 				set->parsed_mail_attachment_detection_no_flags_on_fetch = TRUE;
592 			} else if (strcmp(opt, "exclude-inlined") == 0) {
593 				set->parsed_mail_attachment_exclude_inlined = TRUE;
594 			} else if (str_begins(opt, "content-type=")) {
595 				const char *value = p_strdup(pool, opt+13);
596 				array_push_back(&content_types, &value);
597 			} else {
598 				*error_r = t_strdup_printf("mail_attachment_detection_options: "
599 					"Unknown option: %s", opt);
600 				return FALSE;
601 			}
602 			options++;
603 		}
604 
605 		array_append_zero(&content_types);
606 		set->parsed_mail_attachment_content_type_filter = array_front(&content_types);
607 	}
608 
609 	if (!mail_cache_fields_parse("mail_cache_fields",
610 				     set->mail_cache_fields, error_r))
611 		return FALSE;
612 	if (!mail_cache_fields_parse("mail_always_cache_fields",
613 				     set->mail_always_cache_fields, error_r))
614 		return FALSE;
615 	if (!mail_cache_fields_parse("mail_never_cache_fields",
616 				     set->mail_never_cache_fields, error_r))
617 		return FALSE;
618 	return TRUE;
619 }
620 
namespace_settings_check(void * _set,pool_t pool ATTR_UNUSED,const char ** error_r)621 static bool namespace_settings_check(void *_set, pool_t pool ATTR_UNUSED,
622 				     const char **error_r)
623 {
624 	struct mail_namespace_settings *ns = _set;
625 	struct mail_namespace_settings *const *namespaces;
626 	const char *name;
627 	unsigned int i, count;
628 
629 	name = ns->prefix != NULL ? ns->prefix : "";
630 
631 	if (ns->separator[0] != '\0' && ns->separator[1] != '\0') {
632 		*error_r = t_strdup_printf("Namespace '%s': "
633 			"Hierarchy separator must be only one character long",
634 			name);
635 		return FALSE;
636 	}
637 	if (!uni_utf8_str_is_valid(name)) {
638 		*error_r = t_strdup_printf("Namespace prefix not valid UTF8: %s",
639 					   name);
640 		return FALSE;
641 	}
642 
643 	if (ns->alias_for != NULL && !ns->disabled) {
644 		if (array_is_created(&ns->user_set->namespaces)) {
645 			namespaces = array_get(&ns->user_set->namespaces,
646 					       &count);
647 		} else {
648 			namespaces = NULL;
649 			count = 0;
650 		}
651 		for (i = 0; i < count; i++) {
652 			if (strcmp(namespaces[i]->prefix, ns->alias_for) == 0)
653 				break;
654 		}
655 		if (i == count) {
656 			*error_r = t_strdup_printf(
657 				"Namespace '%s': alias_for points to "
658 				"unknown namespace: %s", name, ns->alias_for);
659 			return FALSE;
660 		}
661 		if (namespaces[i]->alias_for != NULL) {
662 			*error_r = t_strdup_printf(
663 				"Namespace '%s': alias_for chaining isn't "
664 				"allowed: %s -> %s", name, ns->alias_for,
665 				namespaces[i]->alias_for);
666 			return FALSE;
667 		}
668 	}
669 	return TRUE;
670 }
671 
mailbox_special_use_exists(const char * name)672 static bool mailbox_special_use_exists(const char *name)
673 {
674 	if (name[0] != '\\')
675 		return FALSE;
676 	name++;
677 
678 	if (strcasecmp(name, "All") == 0)
679 		return TRUE;
680 	if (strcasecmp(name, "Archive") == 0)
681 		return TRUE;
682 	if (strcasecmp(name, "Drafts") == 0)
683 		return TRUE;
684 	if (strcasecmp(name, "Flagged") == 0)
685 		return TRUE;
686 	if (strcasecmp(name, "Important") == 0)
687 		return TRUE;
688 	if (strcasecmp(name, "Junk") == 0)
689 		return TRUE;
690 	if (strcasecmp(name, "Sent") == 0)
691 		return TRUE;
692 	if (strcasecmp(name, "Trash") == 0)
693 		return TRUE;
694 	return FALSE;
695 }
696 
697 static bool
mailbox_special_use_check(struct mailbox_settings * set,pool_t pool,const char ** error_r)698 mailbox_special_use_check(struct mailbox_settings *set, pool_t pool,
699 			  const char **error_r)
700 {
701 	const char *const *uses, *str;
702 	unsigned int i;
703 
704 	uses = t_strsplit_spaces(set->special_use, " ");
705 	for (i = 0; uses[i] != NULL; i++) {
706 		if (!mailbox_special_use_exists(uses[i])) {
707 			*error_r = t_strdup_printf(
708 				"mailbox %s: unknown special_use: %s",
709 				set->name, uses[i]);
710 			return FALSE;
711 		}
712 	}
713 	/* make sure there are no extra spaces */
714 	str = t_strarray_join(uses, " ");
715 	if (strcmp(str, set->special_use) != 0)
716 		set->special_use = p_strdup(pool, str);
717 	return TRUE;
718 }
719 
mailbox_settings_check(void * _set,pool_t pool,const char ** error_r)720 static bool mailbox_settings_check(void *_set, pool_t pool,
721 				   const char **error_r)
722 {
723 	struct mailbox_settings *set = _set;
724 
725 	if (!uni_utf8_str_is_valid(set->name)) {
726 		*error_r = t_strdup_printf("mailbox %s: name isn't valid UTF-8",
727 					   set->name);
728 		return FALSE;
729 	}
730 	if (*set->special_use != '\0') {
731 		if (!mailbox_special_use_check(set, pool, error_r))
732 			return FALSE;
733 	}
734 	return TRUE;
735 }
736 
mail_user_settings_check(void * _set,pool_t pool ATTR_UNUSED,const char ** error_r ATTR_UNUSED)737 static bool mail_user_settings_check(void *_set, pool_t pool ATTR_UNUSED,
738 				     const char **error_r ATTR_UNUSED)
739 {
740 	struct mail_user_settings *set = _set;
741 
742 #ifndef CONFIG_BINARY
743 	fix_base_path(set, pool, &set->auth_socket_path);
744 
745 	if (*set->hostname == '\0')
746 		set->hostname = p_strdup(pool, my_hostdomain());
747 	if (set->postmaster_address[0] == SETTING_STRVAR_UNEXPANDED[0] &&
748 	    set->postmaster_address[1] == '\0') {
749 		/* check for valid looking fqdn in hostname */
750 		if (strchr(set->hostname, '.') == NULL) {
751 			*error_r = "postmaster_address setting not given";
752 			return FALSE;
753 		}
754 		set->postmaster_address =
755 			p_strconcat(pool, SETTING_STRVAR_UNEXPANDED,
756 				    "postmaster@", set->hostname, NULL);
757 	}
758 #else
759 	if (*set->mail_plugins != '\0' &&
760 	    access(set->mail_plugin_dir, R_OK | X_OK) < 0) {
761 		*error_r = t_strdup_printf(
762 			"mail_plugin_dir: access(%s) failed: %m",
763 			set->mail_plugin_dir);
764 		return FALSE;
765 	}
766 #endif
767 	return TRUE;
768 }
769 
770 #ifndef CONFIG_BINARY
parse_postmaster_address(const char * address,pool_t pool,struct mail_user_settings * set,const char ** error_r)771 static bool parse_postmaster_address(const char *address, pool_t pool,
772 				     struct mail_user_settings *set,
773 				     const char **error_r) ATTR_NULL(3)
774 {
775 	struct message_address *addr;
776 	struct smtp_address *smtp_addr;
777 
778 	addr = message_address_parse(pool,
779 		(const unsigned char *)address,
780 		strlen(address), 2, 0);
781 	if (addr == NULL || addr->domain == NULL || addr->invalid_syntax ||
782 	    smtp_address_create_from_msg(pool, addr, &smtp_addr) < 0) {
783 		*error_r = t_strdup_printf(
784 			"invalid address `%s' specified for the "
785 			"postmaster_address setting", address);
786 		return FALSE;
787 	}
788 	if (addr->next != NULL) {
789 		*error_r = "more than one address specified for the "
790 			"postmaster_address setting";
791 		return FALSE;
792 	}
793 	if (addr->name == NULL || *addr->name == '\0')
794 		addr->name = "Postmaster";
795 	if (set != NULL) {
796 		set->_parsed_postmaster_address = addr;
797 		set->_parsed_postmaster_address_smtp = smtp_addr;
798 	}
799 	return TRUE;
800 }
801 
802 static bool
mail_user_settings_expand_check(void * _set,pool_t pool,const char ** error_r ATTR_UNUSED)803 mail_user_settings_expand_check(void *_set, pool_t pool,
804 				const char **error_r ATTR_UNUSED)
805 {
806 	struct mail_user_settings *set = _set;
807 	const char *error;
808 
809 	/* Parse if possible. Perform error handling later. */
810 	(void)parse_postmaster_address(set->postmaster_address, pool,
811 				       set, &error);
812 	return TRUE;
813 }
814 #endif
815 
816 /* </settings checks> */
817 #undef DEF
818 #define DEF(type, name) \
819 	SETTING_DEFINE_STRUCT_##type(#name, name, struct mail_storage_settings)
820 static const struct setting_define mail_storage_setting_defines[] = {
821 	DEF(STR_VARS, mail_location),
822 	{ .type = SET_ALIAS, .key = "mail" },
823 	DEF(STR_VARS, mail_attachment_fs),
824 	DEF(STR_VARS, mail_attachment_dir),
825 	DEF(STR, mail_attachment_hash),
826 	DEF(SIZE, mail_attachment_min_size),
827 	DEF(STR, mail_attachment_detection_options),
828 	DEF(STR_VARS, mail_attribute_dict),
829 	DEF(UINT, mail_prefetch_count),
830 	DEF(STR, mail_cache_fields),
831 	DEF(STR, mail_always_cache_fields),
832 	DEF(STR, mail_never_cache_fields),
833 	DEF(STR, mail_server_comment),
834 	DEF(STR, mail_server_admin),
835 	DEF(UINT, mail_cache_min_mail_count),
836 	DEF(TIME_HIDDEN, mail_cache_unaccessed_field_drop),
837 	DEF(SIZE_HIDDEN, mail_cache_record_max_size),
838 	DEF(SIZE_HIDDEN, mail_cache_max_size),
839 	DEF(SIZE_HIDDEN, mail_cache_purge_min_size),
840 	DEF(UINT_HIDDEN, mail_cache_purge_delete_percentage),
841 	DEF(UINT_HIDDEN, mail_cache_purge_continued_percentage),
842 	DEF(UINT_HIDDEN, mail_cache_purge_header_continue_count),
843 	DEF(SIZE_HIDDEN, mail_index_rewrite_min_log_bytes),
844 	DEF(SIZE_HIDDEN, mail_index_rewrite_max_log_bytes),
845 	DEF(SIZE_HIDDEN, mail_index_log_rotate_min_size),
846 	DEF(SIZE_HIDDEN, mail_index_log_rotate_max_size),
847 	DEF(TIME_HIDDEN, mail_index_log_rotate_min_age),
848 	DEF(TIME_HIDDEN, mail_index_log2_max_age),
849 	DEF(TIME, mailbox_idle_check_interval),
850 	DEF(UINT, mail_max_keyword_length),
851 	DEF(TIME, mail_max_lock_timeout),
852 	DEF(TIME, mail_temp_scan_interval),
853 	DEF(UINT, mail_vsize_bg_after_count),
854 	DEF(UINT, mail_sort_max_read_count),
855 	DEF(BOOL, mail_save_crlf),
856 	DEF(ENUM, mail_fsync),
857 	DEF(BOOL, mmap_disable),
858 	DEF(BOOL, dotlock_use_excl),
859 	DEF(BOOL, mail_nfs_storage),
860 	DEF(BOOL, mail_nfs_index),
861 	DEF(BOOL, mailbox_list_index),
862 	DEF(BOOL, mailbox_list_index_very_dirty_syncs),
863 	DEF(BOOL, mailbox_list_index_include_inbox),
864 	DEF(BOOL, mail_debug),
865 	DEF(BOOL, mail_full_filesystem_access),
866 	DEF(BOOL, maildir_stat_dirs),
867 	DEF(BOOL, mail_shared_explicit_inbox),
868 	DEF(ENUM, lock_method),
869 	DEF(STR, pop3_uidl_format),
870 
871 	DEF(STR, hostname),
872 	DEF(STR, recipient_delimiter),
873 
874 	SETTING_DEFINE_LIST_END
875 };
876 const struct mail_storage_settings mail_storage_default_settings = {
877 	.mail_location = "",
878 	.mail_attachment_fs = "sis posix",
879 	.mail_attachment_dir = "",
880 	.mail_attachment_hash = "%{sha1}",
881 	.mail_attachment_min_size = 1024*128,
882 	.mail_attachment_detection_options = "",
883 	.mail_attribute_dict = "",
884 	.mail_prefetch_count = 0,
885 	.mail_cache_fields = "flags",
886 	.mail_always_cache_fields = "",
887 	.mail_never_cache_fields = "imap.envelope",
888 	.mail_server_comment = "",
889 	.mail_server_admin = "",
890 	.mail_cache_min_mail_count = 0,
891 	.mail_cache_unaccessed_field_drop = 60*60*24*30,
892 	.mail_cache_record_max_size = 64 * 1024,
893 	.mail_cache_max_size = 1024 * 1024 * 1024,
894 	.mail_cache_purge_min_size = 32 * 1024,
895 	.mail_cache_purge_delete_percentage = 20,
896 	.mail_cache_purge_continued_percentage = 200,
897 	.mail_cache_purge_header_continue_count = 4,
898 	.mail_index_rewrite_min_log_bytes = 8 * 1024,
899 	.mail_index_rewrite_max_log_bytes = 128 * 1024,
900 	.mail_index_log_rotate_min_size = 32 * 1024,
901 	.mail_index_log_rotate_max_size = 1024 * 1024,
902 	.mail_index_log_rotate_min_age = 5 * 60,
903 	.mail_index_log2_max_age = 3600 * 24 * 2,
904 	.mailbox_idle_check_interval = 30,
905 	.mail_max_keyword_length = 50,
906 	.mail_max_lock_timeout = 0,
907 	.mail_temp_scan_interval = 7*24*60*60,
908 	.mail_vsize_bg_after_count = 0,
909 	.mail_sort_max_read_count = 0,
910 	.mail_save_crlf = FALSE,
911 	.mail_fsync = "optimized:never:always",
912 	.mmap_disable = FALSE,
913 	.dotlock_use_excl = TRUE,
914 	.mail_nfs_storage = FALSE,
915 	.mail_nfs_index = FALSE,
916 	.mailbox_list_index = TRUE,
917 	.mailbox_list_index_very_dirty_syncs = FALSE,
918 	.mailbox_list_index_include_inbox = FALSE,
919 	.mail_debug = FALSE,
920 	.mail_full_filesystem_access = FALSE,
921 	.maildir_stat_dirs = FALSE,
922 	.mail_shared_explicit_inbox = FALSE,
923 	.lock_method = "fcntl:flock:dotlock",
924 	.pop3_uidl_format = "%08Xu%08Xv",
925 
926 	.hostname = "",
927 	.recipient_delimiter = "+",
928 };
929 const struct setting_parser_info mail_storage_setting_parser_info = {
930 	.module_name = "mail",
931 	.defines = mail_storage_setting_defines,
932 	.defaults = &mail_storage_default_settings,
933 
934 	.type_offset = SIZE_MAX,
935 	.struct_size = sizeof(struct mail_storage_settings),
936 
937 	.parent_offset = SIZE_MAX,
938 	.parent = &mail_user_setting_parser_info,
939 
940 	.check_func = mail_storage_settings_check,
941 };
942 #undef DEF
943 #define DEF(type, name) \
944 	SETTING_DEFINE_STRUCT_##type(#name, name, struct mailbox_settings)
945 static const struct setting_define mailbox_setting_defines[] = {
946 	DEF(STR, name),
947 	{ .type = SET_ENUM, .key = "auto",
948 	  .offset = offsetof(struct mailbox_settings, autocreate) } ,
949 	DEF(STR, special_use),
950 	DEF(STR, driver),
951 	DEF(STR, comment),
952 	DEF(TIME, autoexpunge),
953 	DEF(UINT, autoexpunge_max_mails),
954 
955 	SETTING_DEFINE_LIST_END
956 };
957 const struct mailbox_settings mailbox_default_settings = {
958 	.name = "",
959 	.autocreate = MAILBOX_SET_AUTO_NO":"
960 		MAILBOX_SET_AUTO_CREATE":"
961 		MAILBOX_SET_AUTO_SUBSCRIBE,
962 	.special_use = "",
963 	.driver = "",
964 	.comment = "",
965 	.autoexpunge = 0,
966 	.autoexpunge_max_mails = 0
967 };
968 const struct setting_parser_info mailbox_setting_parser_info = {
969 	.defines = mailbox_setting_defines,
970 	.defaults = &mailbox_default_settings,
971 
972 	.type_offset = offsetof(struct mailbox_settings, name),
973 	.struct_size = sizeof(struct mailbox_settings),
974 
975 	.parent_offset = SIZE_MAX,
976 	.parent = &mail_user_setting_parser_info,
977 
978 	.check_func = mailbox_settings_check
979 };
980 #undef DEF
981 #undef DEFLIST_UNIQUE
982 #define DEF(type, name) \
983 	SETTING_DEFINE_STRUCT_##type(#name, name, struct mail_namespace_settings)
984 #define DEFLIST_UNIQUE(field, name, defines) \
985 	{ .type = SET_DEFLIST_UNIQUE, .key = name, \
986 	  .offset = offsetof(struct mail_namespace_settings, field), \
987 	  .list_info = defines }
988 static const struct setting_define mail_namespace_setting_defines[] = {
989 	DEF(STR, name),
990 	DEF(ENUM, type),
991 	DEF(STR, separator),
992 	DEF(STR_VARS, prefix),
993 	DEF(STR_VARS, location),
994 	{ .type = SET_ALIAS, .key = "mail" },
995 	{ .type = SET_ALIAS, .key = "mail_location" },
996 	DEF(STR_VARS, alias_for),
997 
998 	DEF(BOOL, inbox),
999 	DEF(BOOL, hidden),
1000 	DEF(ENUM, list),
1001 	DEF(BOOL, subscriptions),
1002 	DEF(BOOL, ignore_on_failure),
1003 	DEF(BOOL, disabled),
1004 	DEF(UINT, order),
1005 
1006 	DEFLIST_UNIQUE(mailboxes, "mailbox", &mailbox_setting_parser_info),
1007 
1008 	SETTING_DEFINE_LIST_END
1009 };
1010 const struct mail_namespace_settings mail_namespace_default_settings = {
1011 	.name = "",
1012 	.type = "private:shared:public",
1013 	.separator = "",
1014 	.prefix = "",
1015 	.location = "",
1016 	.alias_for = NULL,
1017 
1018 	.inbox = FALSE,
1019 	.hidden = FALSE,
1020 	.list = "yes:no:children",
1021 	.subscriptions = TRUE,
1022 	.ignore_on_failure = FALSE,
1023 	.disabled = FALSE,
1024 	.order = 0,
1025 
1026 	.mailboxes = ARRAY_INIT
1027 };
1028 const struct setting_parser_info mail_namespace_setting_parser_info = {
1029 	.defines = mail_namespace_setting_defines,
1030 	.defaults = &mail_namespace_default_settings,
1031 
1032 	.type_offset = offsetof(struct mail_namespace_settings, name),
1033 	.struct_size = sizeof(struct mail_namespace_settings),
1034 
1035 	.parent_offset = offsetof(struct mail_namespace_settings, user_set),
1036 	.parent = &mail_user_setting_parser_info,
1037 
1038 	.check_func = namespace_settings_check
1039 };
1040 #undef DEF
1041 #undef DEFLIST_UNIQUE
1042 #define DEF(type, name) \
1043 	SETTING_DEFINE_STRUCT_##type(#name, name, struct mail_user_settings)
1044 #define DEFLIST_UNIQUE(field, name, defines) \
1045 	{ .type = SET_DEFLIST_UNIQUE, .key = name, \
1046 	  .offset = offsetof(struct mail_user_settings, field), \
1047 	  .list_info = defines }
1048 static const struct setting_define mail_user_setting_defines[] = {
1049 	DEF(STR, base_dir),
1050 	DEF(STR, auth_socket_path),
1051 	DEF(STR_VARS, mail_temp_dir),
1052 
1053 	DEF(STR, mail_uid),
1054 	DEF(STR, mail_gid),
1055 	DEF(STR_VARS, mail_home),
1056 	DEF(STR_VARS, mail_chroot),
1057 	DEF(STR, mail_access_groups),
1058 	DEF(STR, mail_privileged_group),
1059 	DEF(STR, valid_chroot_dirs),
1060 
1061 	DEF(UINT, first_valid_uid),
1062 	DEF(UINT, last_valid_uid),
1063 	DEF(UINT, first_valid_gid),
1064 	DEF(UINT, last_valid_gid),
1065 
1066 	DEF(STR, mail_plugins),
1067 	DEF(STR, mail_plugin_dir),
1068 
1069 	DEF(STR, mail_log_prefix),
1070 
1071 	DEF(STR, hostname),
1072 	DEF(STR_VARS, postmaster_address),
1073 
1074 	DEFLIST_UNIQUE(namespaces, "namespace", &mail_namespace_setting_parser_info),
1075 	{ .type = SET_STRLIST, .key = "plugin",
1076 	  .offset = offsetof(struct mail_user_settings, plugin_envs) },
1077 
1078 	SETTING_DEFINE_LIST_END
1079 };
1080 static const struct mail_user_settings mail_user_default_settings = {
1081 	.base_dir = PKG_RUNDIR,
1082 	.auth_socket_path = "auth-userdb",
1083 	.mail_temp_dir = "/tmp",
1084 
1085 	.mail_uid = "",
1086 	.mail_gid = "",
1087 	.mail_home = "",
1088 	.mail_chroot = "",
1089 	.mail_access_groups = "",
1090 	.mail_privileged_group = "",
1091 	.valid_chroot_dirs = "",
1092 
1093 	.first_valid_uid = 500,
1094 	.last_valid_uid = 0,
1095 	.first_valid_gid = 1,
1096 	.last_valid_gid = 0,
1097 
1098 	.mail_plugins = "",
1099 	.mail_plugin_dir = MODULEDIR,
1100 
1101 	.mail_log_prefix = "%s(%u)<%{pid}><%{session}>: ",
1102 
1103 	.hostname = "",
1104 	.postmaster_address = "postmaster@%{if;%d;ne;;%d;%{hostname}}",
1105 
1106 	.namespaces = ARRAY_INIT,
1107 	.plugin_envs = ARRAY_INIT
1108 };
1109 const struct setting_parser_info mail_user_setting_parser_info = {
1110 	.module_name = "mail",
1111 	.defines = mail_user_setting_defines,
1112 	.defaults = &mail_user_default_settings,
1113 
1114 	.type_offset = SIZE_MAX,
1115 	.struct_size = sizeof(struct mail_user_settings),
1116 
1117 	.parent_offset = SIZE_MAX,
1118 
1119 	.check_func = mail_user_settings_check,
1120 #ifndef CONFIG_BINARY
1121 	.expand_check_func = mail_user_settings_expand_check,
1122 #endif
1123 };
1124 /* ../../src/lib-storage/index/pop3c/pop3c-settings.c */
1125 /* <settings checks> */
1126 struct pop3c_feature_list {
1127 	const char *name;
1128 	enum pop3c_features num;
1129 };
1130 
1131 static const struct pop3c_feature_list pop3c_feature_list[] = {
1132 	{ "no-pipelining", POP3C_FEATURE_NO_PIPELINING },
1133 	{ NULL, 0 }
1134 };
1135 
1136 static int
pop3c_settings_parse_features(struct pop3c_settings * set,const char ** error_r)1137 pop3c_settings_parse_features(struct pop3c_settings *set,
1138 			      const char **error_r)
1139 {
1140 	enum pop3c_features features = 0;
1141 	const struct pop3c_feature_list *list;
1142 	const char *const *str;
1143 
1144 	str = t_strsplit_spaces(set->pop3c_features, " ,");
1145 	for (; *str != NULL; str++) {
1146 		list = pop3c_feature_list;
1147 		for (; list->name != NULL; list++) {
1148 			if (strcasecmp(*str, list->name) == 0) {
1149 				features |= list->num;
1150 				break;
1151 			}
1152 		}
1153 		if (list->name == NULL) {
1154 			*error_r = t_strdup_printf("pop3c_features: "
1155 				"Unknown feature: %s", *str);
1156 			return -1;
1157 		}
1158 	}
1159 	set->parsed_features = features;
1160 	return 0;
1161 }
1162 
pop3c_settings_check(void * _set,pool_t pool ATTR_UNUSED,const char ** error_r)1163 static bool pop3c_settings_check(void *_set, pool_t pool ATTR_UNUSED,
1164 				 const char **error_r)
1165 {
1166 	struct pop3c_settings *set = _set;
1167 
1168 	if (pop3c_settings_parse_features(set, error_r) < 0)
1169 		return FALSE;
1170 	return TRUE;
1171 }
1172 /* </settings checks> */
1173 #undef DEF
1174 #define DEF(type, name) \
1175 	SETTING_DEFINE_STRUCT_##type(#name, name, struct pop3c_settings)
1176 static const struct setting_define pop3c_setting_defines[] = {
1177 	DEF(STR, pop3c_host),
1178 	DEF(IN_PORT, pop3c_port),
1179 
1180 	DEF(STR_VARS, pop3c_user),
1181 	DEF(STR_VARS, pop3c_master_user),
1182 	DEF(STR, pop3c_password),
1183 
1184 	DEF(ENUM, pop3c_ssl),
1185 	DEF(BOOL, pop3c_ssl_verify),
1186 
1187 	DEF(STR, pop3c_rawlog_dir),
1188 	DEF(BOOL, pop3c_quick_received_date),
1189 
1190 	DEF(STR, pop3c_features),
1191 
1192 	SETTING_DEFINE_LIST_END
1193 };
1194 static const struct pop3c_settings pop3c_default_settings = {
1195 	.pop3c_host = "",
1196 	.pop3c_port = 110,
1197 
1198 	.pop3c_user = "%u",
1199 	.pop3c_master_user = "",
1200 	.pop3c_password = "",
1201 
1202 	.pop3c_ssl = "no:pop3s:starttls",
1203 	.pop3c_ssl_verify = TRUE,
1204 
1205 	.pop3c_rawlog_dir = "",
1206 	.pop3c_quick_received_date = FALSE,
1207 
1208 	.pop3c_features = ""
1209 };
1210 static const struct setting_parser_info pop3c_setting_parser_info = {
1211 	.module_name = "pop3c",
1212 	.defines = pop3c_setting_defines,
1213 	.defaults = &pop3c_default_settings,
1214 
1215 	.type_offset = SIZE_MAX,
1216 	.struct_size = sizeof(struct pop3c_settings),
1217 
1218 	.parent_offset = SIZE_MAX,
1219 	.parent = &mail_user_setting_parser_info,
1220 
1221         .check_func = pop3c_settings_check
1222 };
1223 /* ../../src/lib-storage/index/mbox/mbox-settings.c */
1224 #undef DEF
1225 #define DEF(type, name) \
1226 	SETTING_DEFINE_STRUCT_##type(#name, name, struct mbox_settings)
1227 static const struct setting_define mbox_setting_defines[] = {
1228 	DEF(STR, mbox_read_locks),
1229 	DEF(STR, mbox_write_locks),
1230 	DEF(TIME, mbox_lock_timeout),
1231 	DEF(TIME, mbox_dotlock_change_timeout),
1232 	DEF(SIZE, mbox_min_index_size),
1233 	DEF(BOOL, mbox_dirty_syncs),
1234 	DEF(BOOL, mbox_very_dirty_syncs),
1235 	DEF(BOOL, mbox_lazy_writes),
1236 	DEF(ENUM, mbox_md5),
1237 
1238 	SETTING_DEFINE_LIST_END
1239 };
1240 static const struct mbox_settings mbox_default_settings = {
1241 	.mbox_read_locks = "fcntl",
1242 	.mbox_write_locks = "dotlock fcntl",
1243 	.mbox_lock_timeout = 5*60,
1244 	.mbox_dotlock_change_timeout = 2*60,
1245 	.mbox_min_index_size = 0,
1246 	.mbox_dirty_syncs = TRUE,
1247 	.mbox_very_dirty_syncs = FALSE,
1248 	.mbox_lazy_writes = TRUE,
1249 	.mbox_md5 = "apop3d:all"
1250 };
1251 static const struct setting_parser_info mbox_setting_parser_info = {
1252 	.module_name = "mbox",
1253 	.defines = mbox_setting_defines,
1254 	.defaults = &mbox_default_settings,
1255 
1256 	.type_offset = SIZE_MAX,
1257 	.struct_size = sizeof(struct mbox_settings),
1258 
1259 	.parent_offset = SIZE_MAX,
1260 	.parent = &mail_user_setting_parser_info
1261 };
1262 /* ../../src/lib-storage/index/maildir/maildir-settings.c */
1263 #undef DEF
1264 #define DEF(type, name) \
1265 	SETTING_DEFINE_STRUCT_##type(#name, name, struct maildir_settings)
1266 static const struct setting_define maildir_setting_defines[] = {
1267 	DEF(BOOL, maildir_copy_with_hardlinks),
1268 	DEF(BOOL, maildir_very_dirty_syncs),
1269 	DEF(BOOL, maildir_broken_filename_sizes),
1270 	DEF(BOOL, maildir_empty_new),
1271 
1272 	SETTING_DEFINE_LIST_END
1273 };
1274 static const struct maildir_settings maildir_default_settings = {
1275 	.maildir_copy_with_hardlinks = TRUE,
1276 	.maildir_very_dirty_syncs = FALSE,
1277 	.maildir_broken_filename_sizes = FALSE,
1278 	.maildir_empty_new = FALSE
1279 };
1280 static const struct setting_parser_info maildir_setting_parser_info = {
1281 	.module_name = "maildir",
1282 	.defines = maildir_setting_defines,
1283 	.defaults = &maildir_default_settings,
1284 
1285 	.type_offset = SIZE_MAX,
1286 	.struct_size = sizeof(struct maildir_settings),
1287 
1288 	.parent_offset = SIZE_MAX,
1289 	.parent = &mail_user_setting_parser_info
1290 };
1291 /* ../../src/lib-storage/index/imapc/imapc-settings.c */
1292 /* <settings checks> */
1293 struct imapc_feature_list {
1294 	const char *name;
1295 	enum imapc_features num;
1296 };
1297 
1298 static const struct imapc_feature_list imapc_feature_list[] = {
1299 	{ "rfc822.size", IMAPC_FEATURE_RFC822_SIZE },
1300 	{ "guid-forced", IMAPC_FEATURE_GUID_FORCED },
1301 	{ "fetch-headers", IMAPC_FEATURE_FETCH_HEADERS },
1302 	{ "gmail-migration", IMAPC_FEATURE_GMAIL_MIGRATION },
1303 	{ "search", IMAPC_FEATURE_SEARCH },
1304 	{ "zimbra-workarounds", IMAPC_FEATURE_ZIMBRA_WORKAROUNDS },
1305 	{ "no-examine", IMAPC_FEATURE_NO_EXAMINE },
1306 	{ "proxyauth", IMAPC_FEATURE_PROXYAUTH },
1307 	{ "fetch-msn-workarounds", IMAPC_FEATURE_FETCH_MSN_WORKAROUNDS },
1308 	{ "fetch-fix-broken-mails", IMAPC_FEATURE_FETCH_FIX_BROKEN_MAILS },
1309 	{ "modseq", IMAPC_FEATURE_MODSEQ },
1310 	{ "delay-login", IMAPC_FEATURE_DELAY_LOGIN },
1311 	{ "fetch-bodystructure", IMAPC_FEATURE_FETCH_BODYSTRUCTURE },
1312 	{ "send-id", IMAPC_FEATURE_SEND_ID },
1313 	{ "fetch-empty-is-expunged", IMAPC_FEATURE_FETCH_EMPTY_IS_EXPUNGED },
1314 	{ "no-msn-updates", IMAPC_FEATURE_NO_MSN_UPDATES },
1315 	{ "acl", IMAPC_FEATURE_ACL },
1316 	{ NULL, 0 }
1317 };
1318 
1319 static int
imapc_settings_parse_throttle(struct imapc_settings * set,const char * throttle_str,const char ** error_r)1320 imapc_settings_parse_throttle(struct imapc_settings *set,
1321 			      const char *throttle_str, const char **error_r)
1322 {
1323 	const char *const *tmp;
1324 
1325 	tmp = t_strsplit(throttle_str, ":");
1326 	if (str_array_length(tmp) != 3 ||
1327 	    str_to_uint(tmp[0], &set->throttle_init_msecs) < 0 ||
1328 	    str_to_uint(tmp[1], &set->throttle_max_msecs) < 0 ||
1329 	    str_to_uint(tmp[2], &set->throttle_shrink_min_msecs) < 0) {
1330 		*error_r = "imapc_features: Invalid throttle settings";
1331 		return -1;
1332 	}
1333 	return 0;
1334 }
1335 
1336 static int
imapc_settings_parse_features(struct imapc_settings * set,const char ** error_r)1337 imapc_settings_parse_features(struct imapc_settings *set,
1338 			      const char **error_r)
1339 {
1340         enum imapc_features features = 0;
1341         const struct imapc_feature_list *list;
1342 	const char *const *str;
1343 
1344         str = t_strsplit_spaces(set->imapc_features, " ,");
1345 	for (; *str != NULL; str++) {
1346 		list = imapc_feature_list;
1347 		for (; list->name != NULL; list++) {
1348 			if (strcasecmp(*str, list->name) == 0) {
1349 				features |= list->num;
1350 				break;
1351 			}
1352 		}
1353 		if (strncasecmp(*str, "throttle:", 9) == 0) {
1354 			if (imapc_settings_parse_throttle(set, *str + 9, error_r) < 0)
1355 				return -1;
1356 			continue;
1357 		}
1358 		if (list->name == NULL) {
1359 			*error_r = t_strdup_printf("imapc_features: "
1360 				"Unknown feature: %s", *str);
1361 			return -1;
1362 		}
1363 	}
1364 	set->parsed_features = features;
1365 	return 0;
1366 }
1367 
imapc_settings_check(void * _set,pool_t pool ATTR_UNUSED,const char ** error_r)1368 static bool imapc_settings_check(void *_set, pool_t pool ATTR_UNUSED,
1369 				 const char **error_r)
1370 {
1371 	struct imapc_settings *set = _set;
1372 
1373 	if (set->imapc_max_idle_time == 0) {
1374 		*error_r = "imapc_max_idle_time must not be 0";
1375 		return FALSE;
1376 	}
1377 	if (imapc_settings_parse_features(set, error_r) < 0)
1378 		return FALSE;
1379 	return TRUE;
1380 }
1381 #undef DEF
1382 #define DEF(type, name) \
1383 	SETTING_DEFINE_STRUCT_##type(#name, name, struct imapc_settings)
1384 static const struct setting_define imapc_setting_defines[] = {
1385 	DEF(STR, imapc_host),
1386 	DEF(IN_PORT, imapc_port),
1387 
1388 	DEF(STR_VARS, imapc_user),
1389 	DEF(STR_VARS, imapc_master_user),
1390 	DEF(STR, imapc_password),
1391 	DEF(STR, imapc_sasl_mechanisms),
1392 
1393 	DEF(ENUM, imapc_ssl),
1394 	DEF(BOOL, imapc_ssl_verify),
1395 
1396 	DEF(STR, imapc_features),
1397 	DEF(STR, imapc_rawlog_dir),
1398 	DEF(STR, imapc_list_prefix),
1399 	DEF(TIME, imapc_cmd_timeout),
1400 	DEF(TIME, imapc_max_idle_time),
1401 	DEF(UINT, imapc_connection_retry_count),
1402 	DEF(TIME_MSECS, imapc_connection_retry_interval),
1403 	DEF(SIZE, imapc_max_line_length),
1404 
1405 	DEF(STR, pop3_deleted_flag),
1406 
1407 	SETTING_DEFINE_LIST_END
1408 };
1409 static const struct imapc_settings imapc_default_settings = {
1410 	.imapc_host = "",
1411 	.imapc_port = 143,
1412 
1413 	.imapc_user = "",
1414 	.imapc_master_user = "",
1415 	.imapc_password = "",
1416 	.imapc_sasl_mechanisms = "",
1417 
1418 	.imapc_ssl = "no:imaps:starttls",
1419 	.imapc_ssl_verify = TRUE,
1420 
1421 	.imapc_features = "",
1422 	.imapc_rawlog_dir = "",
1423 	.imapc_list_prefix = "",
1424 	.imapc_cmd_timeout = 5*60,
1425 	.imapc_max_idle_time = 60*29,
1426 	.imapc_connection_retry_count = 1,
1427 	.imapc_connection_retry_interval = 1000,
1428 	.imapc_max_line_length = 0,
1429 
1430 	.pop3_deleted_flag = ""
1431 };
1432 static const struct setting_parser_info imapc_setting_parser_info = {
1433 	.module_name = "imapc",
1434 	.defines = imapc_setting_defines,
1435 	.defaults = &imapc_default_settings,
1436 
1437 	.type_offset = SIZE_MAX,
1438 	.struct_size = sizeof(struct imapc_settings),
1439 
1440 	.parent_offset = SIZE_MAX,
1441 	.parent = &mail_user_setting_parser_info,
1442 
1443 	.check_func = imapc_settings_check
1444 };
1445 /* ../../src/lib-storage/index/dbox-multi/mdbox-settings.c */
1446 #undef DEF
1447 #define DEF(type, name) \
1448 	SETTING_DEFINE_STRUCT_##type(#name, name, struct mdbox_settings)
1449 static const struct setting_define mdbox_setting_defines[] = {
1450 	DEF(BOOL, mdbox_preallocate_space),
1451 	DEF(SIZE, mdbox_rotate_size),
1452 	DEF(TIME, mdbox_rotate_interval),
1453 
1454 	SETTING_DEFINE_LIST_END
1455 };
1456 static const struct mdbox_settings mdbox_default_settings = {
1457 	.mdbox_preallocate_space = FALSE,
1458 	.mdbox_rotate_size = 10*1024*1024,
1459 	.mdbox_rotate_interval = 0
1460 };
1461 static const struct setting_parser_info mdbox_setting_parser_info = {
1462 	.module_name = "mdbox",
1463 	.defines = mdbox_setting_defines,
1464 	.defaults = &mdbox_default_settings,
1465 
1466 	.type_offset = SIZE_MAX,
1467 	.struct_size = sizeof(struct mdbox_settings),
1468 
1469 	.parent_offset = SIZE_MAX,
1470 	.parent = &mail_user_setting_parser_info
1471 };
1472 /* ../../src/lib-lda/lda-settings.c */
1473 #undef DEF
1474 #undef DEFLIST
1475 #define DEF(type, name) \
1476 	SETTING_DEFINE_STRUCT_##type(#name, name, struct lda_settings)
1477 #define DEFLIST(field, name, defines) \
1478 	{ .type = SET_DEFLIST, .key = name, \
1479 	  .offset = offsetof(struct lda_settings, field), \
1480 	  .list_info = defines }
1481 static const struct setting_define lda_setting_defines[] = {
1482 	DEF(STR, hostname),
1483 	DEF(STR, rejection_subject),
1484 	DEF(STR, rejection_reason),
1485 	DEF(STR, deliver_log_format),
1486 	DEF(STR, recipient_delimiter),
1487 	DEF(STR, lda_original_recipient_header),
1488 	DEF(BOOL, quota_full_tempfail),
1489 	DEF(BOOL, lda_mailbox_autocreate),
1490 	DEF(BOOL, lda_mailbox_autosubscribe),
1491 
1492 	SETTING_DEFINE_LIST_END
1493 };
1494 static const struct lda_settings lda_default_settings = {
1495 	.hostname = "",
1496 	.rejection_subject = "Rejected: %s",
1497 	.rejection_reason =
1498 		"Your message to <%t> was automatically rejected:%n%r",
1499 	.deliver_log_format = "msgid=%m: %$",
1500 	.recipient_delimiter = "+",
1501 	.lda_original_recipient_header = "",
1502 	.quota_full_tempfail = FALSE,
1503 	.lda_mailbox_autocreate = FALSE,
1504 	.lda_mailbox_autosubscribe = FALSE
1505 };
1506 static const struct setting_parser_info *lda_setting_dependencies[] = {
1507 	&mail_user_setting_parser_info,
1508 	&smtp_submit_setting_parser_info,
1509 	NULL
1510 };
1511 const struct setting_parser_info lda_setting_parser_info = {
1512 	.module_name = "lda",
1513 	.defines = lda_setting_defines,
1514 	.defaults = &lda_default_settings,
1515 
1516 	.type_offset = SIZE_MAX,
1517 	.struct_size = sizeof(struct lda_settings),
1518 
1519 	.parent_offset = SIZE_MAX,
1520 
1521 #ifndef CONFIG_BINARY
1522 	.check_func = lda_settings_check,
1523 #endif
1524 	.dependencies = lda_setting_dependencies
1525 };
1526 /* ../../src/lib-dict-backend/dict-sql-settings.c */
1527 #define DEF_STR(name) DEF_STRUCT_STR(name, dict_sql_map)
1528 #define DEF_BOOL(name) DEF_STRUCT_BOOL(name, dict_sql_map)
1529 /* ../../src/lib-dict-backend/dict-ldap-settings.c */
1530 #undef DEF_STR
1531 #undef DEF_BOOL
1532 #undef DEF_UINT
1533 #define DEF_STR(name) DEF_STRUCT_STR(name, dict_ldap_map)
1534 #define DEF_BOOL(name) DEF_STRUCT_BOOL(name, dict_ldap_map)
1535 #define DEF_UINT(name) DEF_STRUCT_UINT(name ,dict_ldap_map)
1536 /* ../../src/submission/submission-settings.h */
1537 extern const struct setting_parser_info submission_setting_parser_info;
1538 /* <settings checks> */
1539 enum submission_client_workarounds {
1540 	SUBMISSION_WORKAROUND_WHITESPACE_BEFORE_PATH	= BIT(0),
1541 	SUBMISSION_WORKAROUND_MAILBOX_FOR_PATH		= BIT(1),
1542 };
1543 /* </settings checks> */
1544 struct submission_settings {
1545 	bool verbose_proctitle;
1546 	const char *rawlog_dir;
1547 
1548 	const char *hostname;
1549 
1550 	const char *login_greeting;
1551 	const char *login_trusted_networks;
1552 
1553 	const char *recipient_delimiter;
1554 
1555 	/* submission: */
1556 	uoff_t submission_max_mail_size;
1557 	unsigned int submission_max_recipients;
1558 	const char *submission_client_workarounds;
1559 	const char *submission_logout_format;
1560 
1561 	/* submission backend: */
1562 	const char *submission_backend_capabilities;
1563 
1564 	/* submission relay: */
1565 	const char *submission_relay_host;
1566 	in_port_t submission_relay_port;
1567 	bool submission_relay_trusted;
1568 
1569 	const char *submission_relay_user;
1570 	const char *submission_relay_master_user;
1571 	const char *submission_relay_password;
1572 
1573 	const char *submission_relay_ssl;
1574 	bool submission_relay_ssl_verify;
1575 
1576 	const char *submission_relay_rawlog_dir;
1577 	unsigned int submission_relay_max_idle_time;
1578 
1579 	unsigned int submission_relay_connect_timeout;
1580 	unsigned int submission_relay_command_timeout;
1581 
1582 	/* imap urlauth: */
1583 	const char *imap_urlauth_host;
1584 	in_port_t imap_urlauth_port;
1585 
1586 	enum submission_client_workarounds parsed_workarounds;
1587 };
1588 /* ../../src/submission-login/submission-login-settings.h */
1589 extern const struct setting_parser_info *submission_login_setting_roots[];
1590 struct submission_login_settings {
1591 	const char *hostname;
1592 
1593 	/* submission: */
1594 	uoff_t submission_max_mail_size;
1595 	const char *submission_backend_capabilities;
1596 };
1597 /* ../../src/stats/stats-settings.h */
1598 extern const struct setting_parser_info stats_setting_parser_info;
1599 extern const struct setting_parser_info stats_metric_setting_parser_info;
1600 /* <settings checks> */
1601 /*
1602  * We allow a selection of a timestamp format.
1603  *
1604  * The 'time-unix' format generates a number with the number of seconds
1605  * since 1970-01-01 00:00 UTC.
1606  *
1607  * The 'time-rfc3339' format uses the YYYY-MM-DDTHH:MM:SS.uuuuuuZ format as
1608  * defined by RFC 3339.
1609  *
1610  * The special native format (not explicitly selectable in the config, but
1611  * default if no time-* token is used) uses the format's native timestamp
1612  * format.  Note that not all formats have a timestamp data format.
1613  *
1614  * The native format and the rules below try to address the question: can a
1615  * parser that doesn't have any knowledge of fields' values' types losslessly
1616  * reconstruct the fields?
1617  *
1618  * For example, JSON only has strings and numbers, so it cannot represent a
1619  * timestamp in a "context-free lossless" way.  Therefore, when making a
1620  * JSON blob, we need to decide which way to serialize timestamps.  No
1621  * matter how we do it, we incur some loss.  If a decoder sees 1557232304 in
1622  * a field, it cannot be certain if the field is an integer that just
1623  * happens to be a reasonable timestamp, or if it actually is a timestamp.
1624  * Same goes with RFC3339 - it could just be that the user supplied a string
1625  * that looks like a timestamp, and that string made it into an event field.
1626  *
1627  * Other common serialization formats, such as CBOR, have a lossless way of
1628  * encoding timestamps.
1629  *
1630  * Note that there are two concepts at play: native and default.
1631  *
1632  * The rules for how the format's timestamp formats are used:
1633  *
1634  * 1. The default time format is the native format.
1635  * 2. The native time format may or may not exist for a given format (e.g.,
1636  *    in JSON)
1637  * 3. If the native format doesn't exist and no time format was specified in
1638  *    the config, it is a config error.
1639  *
1640  * We went with these rules because:
1641  *
1642  * 1. It prevents type information loss by default.
1643  * 2. It completely isolates the policy from the algorithm.
1644  * 3. It defers the decision whether each format without a native timestamp
1645  *    type should have a default acting as native until after we've had some
1646  *    operational experience.
1647  * 4. A future decision to add a default (via 3. point) will be 100% compatible.
1648  */
1649 enum event_exporter_time_fmt {
1650 	EVENT_EXPORTER_TIME_FMT_NATIVE = 0,
1651 	EVENT_EXPORTER_TIME_FMT_UNIX,
1652 	EVENT_EXPORTER_TIME_FMT_RFC3339,
1653 };
1654 /* </settings checks> */
1655 /* <settings checks> */
1656 enum stats_metric_group_by_func {
1657 	STATS_METRIC_GROUPBY_DISCRETE = 0,
1658 	STATS_METRIC_GROUPBY_QUANTIZED,
1659 };
1660 
1661 /*
1662  * A range covering a stats bucket.  The the interval is half closed - the
1663  * minimum is excluded and the maximum is included.  In other words: (min, max].
1664  * Because we don't have a +Inf and -Inf, we use INTMAX_MIN and INTMAX_MAX
1665  * respectively.
1666  */
1667 struct stats_metric_settings_bucket_range {
1668 	intmax_t min;
1669 	intmax_t max;
1670 };
1671 
1672 struct stats_metric_settings_group_by {
1673 	const char *field;
1674 	enum stats_metric_group_by_func func;
1675 	unsigned int num_ranges;
1676 	struct stats_metric_settings_bucket_range *ranges;
1677 };
1678 /* </settings checks> */
1679 #define STATS_METRIC_SETTINGS_DEFAULT_EXPORTER_INCLUDE \
1680 	"name hostname timestamps categories fields"
1681 struct stats_exporter_settings {
1682 	const char *name;
1683 	const char *transport;
1684 	const char *transport_args;
1685 	unsigned int transport_timeout;
1686 	const char *format;
1687 	const char *format_args;
1688 
1689 	/* parsed values */
1690 	enum event_exporter_time_fmt parsed_time_format;
1691 };
1692 struct stats_metric_settings {
1693 	const char *metric_name;
1694 	const char *description;
1695 	const char *fields;
1696 	const char *group_by;
1697 	const char *filter;
1698 
1699 	ARRAY(struct stats_metric_settings_group_by) parsed_group_by;
1700 	struct event_filter *parsed_filter;
1701 
1702 	/* exporter related fields */
1703 	const char *exporter;
1704 	const char *exporter_include;
1705 };
1706 struct stats_settings {
1707 	const char *stats_http_rawlog_dir;
1708 
1709 	ARRAY(struct stats_exporter_settings *) exporters;
1710 	ARRAY(struct stats_metric_settings *) metrics;
1711 };
1712 /* ../../src/replication/replicator/replicator-settings.h */
1713 extern const struct setting_parser_info replicator_setting_parser_info;
1714 struct replicator_settings {
1715 	const char *auth_socket_path;
1716 	const char *doveadm_socket_path;
1717 	const char *replication_dsync_parameters;
1718 
1719 	unsigned int replication_full_sync_interval;
1720 	unsigned int replication_max_conns;
1721 };
1722 /* ../../src/replication/aggregator/aggregator-settings.h */
1723 extern const struct setting_parser_info aggregator_setting_parser_info;
1724 struct aggregator_settings {
1725 	const char *replicator_host;
1726 	in_port_t replicator_port;
1727 };
1728 /* ../../src/pop3/pop3-settings.h */
1729 extern const struct setting_parser_info pop3_setting_parser_info;
1730 /* <settings checks> */
1731 enum pop3_client_workarounds {
1732 	WORKAROUND_OUTLOOK_NO_NULS		= 0x01,
1733 	WORKAROUND_OE_NS_EOH			= 0x02
1734 };
1735 enum pop3_delete_type {
1736 	POP3_DELETE_TYPE_EXPUNGE = 0,
1737 	POP3_DELETE_TYPE_FLAG,
1738 };
1739 /* </settings checks> */
1740 struct pop3_settings {
1741 	bool verbose_proctitle;
1742 	const char *rawlog_dir;
1743 
1744 	/* pop3: */
1745 	bool pop3_no_flag_updates;
1746 	bool pop3_enable_last;
1747 	bool pop3_reuse_xuidl;
1748 	bool pop3_save_uidl;
1749 	bool pop3_lock_session;
1750 	bool pop3_fast_size_lookups;
1751 	const char *pop3_client_workarounds;
1752 	const char *pop3_logout_format;
1753 	const char *pop3_uidl_duplicates;
1754 	const char *pop3_deleted_flag;
1755 	const char *pop3_delete_type;
1756 
1757 	enum pop3_client_workarounds parsed_workarounds;
1758 	enum pop3_delete_type parsed_delete_type;
1759 };
1760 /* ../../src/pop3-login/pop3-login-settings.h */
1761 extern const struct setting_parser_info *pop3_login_setting_roots[];
1762 /* ../../src/plugins/quota/quota-status-settings.h */
1763 extern const struct setting_parser_info quota_status_setting_parser_info;
1764 struct quota_status_settings {
1765 	const char *recipient_delimiter;
1766 };
1767 /* ../../src/plugins/mail-crypt/fs-crypt-settings.h */
1768 extern const struct setting_parser_info fs_crypt_setting_parser_info;
1769 struct fs_crypt_settings {
1770 	ARRAY(const char *) plugin_envs;
1771 };
1772 /* ../../src/old-stats/stats-settings.h */
1773 extern const struct setting_parser_info old_stats_setting_parser_info;
1774 struct old_stats_settings {
1775 	uoff_t memory_limit;
1776 
1777 	unsigned int command_min_time;
1778 	unsigned int session_min_time;
1779 	unsigned int user_min_time;
1780 	unsigned int domain_min_time;
1781 	unsigned int ip_min_time;
1782 
1783 	unsigned int carbon_interval;
1784 	const char *carbon_server;
1785 	const char *carbon_name;
1786 };
1787 /* ../../src/master/master-settings.h */
1788 extern const struct setting_parser_info master_setting_parser_info;
1789 struct master_settings {
1790 	const char *base_dir;
1791 	const char *state_dir;
1792 	const char *libexec_dir;
1793 	const char *instance_name;
1794 	const char *protocols;
1795 	const char *listen;
1796 	const char *ssl;
1797 	const char *default_internal_user;
1798 	const char *default_internal_group;
1799 	const char *default_login_user;
1800 	unsigned int default_process_limit;
1801 	unsigned int default_client_limit;
1802 	unsigned int default_idle_kill;
1803 	uoff_t default_vsz_limit;
1804 
1805 	bool version_ignore;
1806 
1807 	unsigned int first_valid_uid, last_valid_uid;
1808 	unsigned int first_valid_gid, last_valid_gid;
1809 
1810 	ARRAY_TYPE(service_settings) services;
1811 	char **protocols_split;
1812 };
1813 /* ../../src/login-common/login-settings.h */
1814 extern const struct setting_parser_info **login_set_roots;
1815 extern const struct setting_parser_info login_setting_parser_info;
1816 struct login_settings {
1817 	const char *login_trusted_networks;
1818 	const char *login_source_ips;
1819 	const char *login_greeting;
1820 	const char *login_log_format_elements, *login_log_format;
1821 	const char *login_access_sockets;
1822 	const char *login_proxy_notify_path;
1823 	const char *login_plugin_dir;
1824 	const char *login_plugins;
1825 	unsigned int login_proxy_timeout;
1826 	unsigned int login_proxy_max_reconnects;
1827 	unsigned int login_proxy_max_disconnect_delay;
1828 	const char *login_proxy_rawlog_dir;
1829 	const char *director_username_hash;
1830 
1831 	bool auth_ssl_require_client_cert;
1832 	bool auth_ssl_username_from_cert;
1833 
1834 	bool disable_plaintext_auth;
1835 	bool auth_verbose;
1836 	bool auth_debug;
1837 	bool auth_debug_passwords;
1838 	bool verbose_proctitle;
1839 
1840 	unsigned int mail_max_userip_connections;
1841 
1842 	/* generated: */
1843 	char *const *log_format_elements_split;
1844 };
1845 /* ../../src/lmtp/lmtp-settings.h */
1846 extern const struct setting_parser_info lmtp_setting_parser_info;
1847 /* <settings checks> */
1848 enum lmtp_hdr_delivery_address {
1849 	LMTP_HDR_DELIVERY_ADDRESS_NONE,
1850 	LMTP_HDR_DELIVERY_ADDRESS_FINAL,
1851 	LMTP_HDR_DELIVERY_ADDRESS_ORIGINAL
1852 };
1853 
1854 enum lmtp_client_workarounds {
1855 	LMTP_WORKAROUND_WHITESPACE_BEFORE_PATH	= BIT(0),
1856 	LMTP_WORKAROUND_MAILBOX_FOR_PATH	= BIT(1),
1857 };
1858 /* </settings checks> */
1859 struct lmtp_settings {
1860 	bool lmtp_proxy;
1861 	bool lmtp_save_to_detail_mailbox;
1862 	bool lmtp_rcpt_check_quota;
1863 	bool lmtp_add_received_header;
1864 	unsigned int lmtp_user_concurrency_limit;
1865 	const char *lmtp_hdr_delivery_address;
1866 	const char *lmtp_rawlog_dir;
1867 	const char *lmtp_proxy_rawlog_dir;
1868 
1869 	const char *lmtp_client_workarounds;
1870 
1871 	const char *login_greeting;
1872 	const char *login_trusted_networks;
1873 
1874 	const char *mail_plugins;
1875 	const char *mail_plugin_dir;
1876 
1877 	enum lmtp_hdr_delivery_address parsed_lmtp_hdr_delivery_address;
1878 
1879 	enum lmtp_client_workarounds parsed_workarounds;
1880 };
1881 /* ../../src/imap/imap-settings.h */
1882 extern const struct setting_parser_info imap_setting_parser_info;
1883 /* <settings checks> */
1884 enum imap_client_workarounds {
1885 	WORKAROUND_DELAY_NEWMAIL		= 0x01,
1886 	WORKAROUND_TB_EXTRA_MAILBOX_SEP		= 0x08,
1887 	WORKAROUND_TB_LSUB_FLAGS		= 0x10
1888 };
1889 
1890 enum imap_client_fetch_failure {
1891 	IMAP_CLIENT_FETCH_FAILURE_DISCONNECT_IMMEDIATELY,
1892 	IMAP_CLIENT_FETCH_FAILURE_DISCONNECT_AFTER,
1893 	IMAP_CLIENT_FETCH_FAILURE_NO_AFTER,
1894 };
1895 /* </settings checks> */
1896 struct imap_settings {
1897 	bool verbose_proctitle;
1898 	const char *rawlog_dir;
1899 
1900 	/* imap: */
1901 	uoff_t imap_max_line_length;
1902 	unsigned int imap_idle_notify_interval;
1903 	const char *imap_capability;
1904 	const char *imap_client_workarounds;
1905 	const char *imap_logout_format;
1906 	const char *imap_id_send;
1907 	const char *imap_id_log;
1908 	const char *imap_fetch_failure;
1909 	bool imap_metadata;
1910 	bool imap_literal_minus;
1911 	unsigned int imap_hibernate_timeout;
1912 
1913 	/* imap urlauth: */
1914 	const char *imap_urlauth_host;
1915 	in_port_t imap_urlauth_port;
1916 
1917 	enum imap_client_workarounds parsed_workarounds;
1918 	enum imap_client_fetch_failure parsed_fetch_failure;
1919 };
1920 /* ../../src/imap-urlauth/imap-urlauth-worker-settings.h */
1921 extern const struct setting_parser_info imap_urlauth_worker_setting_parser_info;
1922 struct imap_urlauth_worker_settings {
1923 	bool verbose_proctitle;
1924 
1925 	/* imap_urlauth: */
1926 	const char *imap_urlauth_host;
1927 	in_port_t imap_urlauth_port;
1928 };
1929 /* ../../src/imap-urlauth/imap-urlauth-settings.h */
1930 extern const struct setting_parser_info imap_urlauth_setting_parser_info;
1931 struct imap_urlauth_settings {
1932 	const char *base_dir;
1933 
1934 	bool mail_debug;
1935 
1936 	bool verbose_proctitle;
1937 
1938 	/* imap_urlauth: */
1939 	const char *imap_urlauth_logout_format;
1940 
1941 	const char *imap_urlauth_submit_user;
1942 	const char *imap_urlauth_stream_user;
1943 };
1944 /* ../../src/imap-urlauth/imap-urlauth-login-settings.h */
1945 extern const struct setting_parser_info *imap_urlauth_login_setting_roots[];
1946 /* ../../src/imap-login/imap-login-settings.h */
1947 extern const struct setting_parser_info *imap_login_setting_roots[];
1948 struct imap_login_settings {
1949 	const char *imap_capability;
1950 	const char *imap_id_send;
1951 	const char *imap_id_log;
1952 	bool imap_literal_minus;
1953 	bool imap_id_retain;
1954 };
1955 /* ../../src/doveadm/doveadm-settings.h */
1956 extern const struct setting_parser_info doveadm_setting_parser_info;
1957 /* <settings checks> */
1958 enum dsync_features {
1959 	DSYNC_FEATURE_EMPTY_HDR_WORKAROUND = 0x1,
1960 };
1961 /* </settings checks> */
1962 struct doveadm_settings {
1963 	const char *base_dir;
1964 	const char *libexec_dir;
1965 	const char *mail_plugins;
1966 	const char *mail_plugin_dir;
1967 	const char *mail_temp_dir;
1968 	bool auth_debug;
1969 	const char *auth_socket_path;
1970 	const char *doveadm_socket_path;
1971 	unsigned int doveadm_worker_count;
1972 	in_port_t doveadm_port;
1973 	const char *doveadm_ssl;
1974 	const char *doveadm_username;
1975 	const char *doveadm_password;
1976 	const char *doveadm_allowed_commands;
1977 	const char *dsync_alt_char;
1978 	const char *dsync_remote_cmd;
1979 	const char *director_username_hash;
1980 	const char *doveadm_api_key;
1981 	const char *dsync_features;
1982 	const char *dsync_hashed_headers;
1983 	unsigned int dsync_commit_msgs_interval;
1984 	const char *doveadm_http_rawlog_dir;
1985 	enum dsync_features parsed_features;
1986 	ARRAY(const char *) plugin_envs;
1987 };
1988 /* ../../src/director/director-settings.h */
1989 extern const struct setting_parser_info director_setting_parser_info;
1990 struct director_settings {
1991 	const char *master_user_separator;
1992 
1993 	const char *director_servers;
1994 	const char *director_mail_servers;
1995 	const char *director_username_hash;
1996 	const char *director_flush_socket;
1997 
1998 	unsigned int director_ping_idle_timeout;
1999 	unsigned int director_ping_max_timeout;
2000 	unsigned int director_user_expire;
2001 	unsigned int director_user_kick_delay;
2002 	unsigned int director_max_parallel_moves;
2003 	unsigned int director_max_parallel_kicks;
2004 	uoff_t director_output_buffer_size;
2005 };
2006 /* ../../src/dict/dict-settings.h */
2007 extern const struct setting_parser_info dict_setting_parser_info;
2008 struct dict_server_settings {
2009 	const char *base_dir;
2010 	bool verbose_proctitle;
2011 
2012 	const char *dict_db_config;
2013 	ARRAY(const char *) dicts;
2014 };
2015 /* ../../src/auth/auth-settings.h */
2016 extern const struct setting_parser_info auth_setting_parser_info;
2017 struct auth_passdb_settings {
2018 	const char *name;
2019 	const char *driver;
2020 	const char *args;
2021 	const char *default_fields;
2022 	const char *override_fields;
2023 	const char *mechanisms;
2024 	const char *username_filter;
2025 
2026 	const char *skip;
2027 	const char *result_success;
2028 	const char *result_failure;
2029 	const char *result_internalfail;
2030 	bool deny;
2031 	bool pass; /* deprecated, use result_success=continue instead */
2032 	bool master;
2033 	const char *auth_verbose;
2034 };
2035 struct auth_userdb_settings {
2036 	const char *name;
2037 	const char *driver;
2038 	const char *args;
2039 	const char *default_fields;
2040 	const char *override_fields;
2041 
2042 	const char *skip;
2043 	const char *result_success;
2044 	const char *result_failure;
2045 	const char *result_internalfail;
2046 	const char *auth_verbose;
2047 };
2048 struct auth_settings {
2049 	const char *mechanisms;
2050 	const char *realms;
2051 	const char *default_realm;
2052 	uoff_t cache_size;
2053 	unsigned int cache_ttl;
2054 	unsigned int cache_negative_ttl;
2055 	bool cache_verify_password_with_worker;
2056 	const char *username_chars;
2057 	const char *username_translation;
2058 	const char *username_format;
2059 	const char *master_user_separator;
2060 	const char *anonymous_username;
2061 	const char *krb5_keytab;
2062 	const char *gssapi_hostname;
2063 	const char *winbind_helper_path;
2064 	const char *proxy_self;
2065 	unsigned int failure_delay;
2066 
2067 	const char *policy_server_url;
2068 	const char *policy_server_api_header;
2069 	unsigned int policy_server_timeout_msecs;
2070 	const char *policy_hash_mech;
2071 	const char *policy_hash_nonce;
2072 	const char *policy_request_attributes;
2073 	bool policy_reject_on_fail;
2074 	bool policy_check_before_auth;
2075 	bool policy_check_after_auth;
2076 	bool policy_report_after_auth;
2077 	bool policy_log_only;
2078 	unsigned int policy_hash_truncate;
2079 
2080 	bool stats;
2081 	bool verbose, debug, debug_passwords;
2082 	const char *verbose_passwords;
2083 	bool ssl_require_client_cert;
2084 	bool ssl_username_from_cert;
2085 	bool use_winbind;
2086 
2087 	unsigned int worker_max_count;
2088 
2089 	/* settings that don't have auth_ prefix: */
2090 	ARRAY(struct auth_passdb_settings *) passdbs;
2091 	ARRAY(struct auth_userdb_settings *) userdbs;
2092 
2093 	const char *base_dir;
2094 	const char *ssl_client_ca_dir;
2095 	const char *ssl_client_ca_file;
2096 
2097 	bool verbose_proctitle;
2098 	unsigned int first_valid_uid;
2099 	unsigned int last_valid_uid;
2100 	unsigned int first_valid_gid;
2101 	unsigned int last_valid_gid;
2102 
2103 	/* generated: */
2104 	char username_chars_map[256];
2105 	char username_translation_map[256];
2106 	const char *const *realms_arr;
2107 	const struct ip_addr *proxy_self_ips;
2108 };
2109 /* ../../src/util/tcpwrap-settings.c */
2110 #ifdef HAVE_LIBWRAP
2111 struct service_settings tcpwrap_service_settings = {
2112 	.name = "tcpwrap",
2113 	.protocol = "",
2114 	.type = "",
2115 	.executable = "tcpwrap",
2116 	.user = "$default_internal_user",
2117 	.group = "",
2118 	.privileged_group = "",
2119 	.extra_groups = "",
2120 	.chroot = "",
2121 
2122 	.drop_priv_before_exec = FALSE,
2123 
2124 	.process_min_avail = 0,
2125 	.process_limit = 0,
2126 	.client_limit = 1,
2127 	.service_count = 0,
2128 	.idle_kill = 0,
2129 	.vsz_limit = UOFF_T_MAX,
2130 
2131 	.unix_listeners = ARRAY_INIT,
2132 	.fifo_listeners = ARRAY_INIT,
2133 	.inet_listeners = ARRAY_INIT
2134 };
2135 #endif
2136 /* ../../src/util/health-check-settings.c */
2137 struct service_settings health_check_service_settings = {
2138 	.name = "health-check",
2139 	.protocol = "",
2140 	.type = "",
2141 	.executable = "script -p health-check.sh",
2142 	.user = "$default_internal_user",
2143 	.group = "",
2144 	.privileged_group = "",
2145 	.extra_groups = "",
2146 	.chroot = "",
2147 
2148 	.drop_priv_before_exec = TRUE,
2149 
2150 	.process_min_avail = 0,
2151 	.process_limit = 0,
2152 	.client_limit = 1,
2153 	.service_count = 0,
2154 	.idle_kill = 0,
2155 	.vsz_limit = UOFF_T_MAX,
2156 
2157 	.unix_listeners = ARRAY_INIT,
2158 	.fifo_listeners = ARRAY_INIT,
2159 	.inet_listeners = ARRAY_INIT
2160 };
2161 /* ../../src/submission/submission-settings.c */
2162 /* <settings checks> */
2163 static struct file_listener_settings submission_unix_listeners_array[] = {
2164 	{ "login/submission", 0666, "", "" }
2165 };
2166 static struct file_listener_settings *submission_unix_listeners[] = {
2167 	&submission_unix_listeners_array[0]
2168 };
2169 static buffer_t submission_unix_listeners_buf = {
2170 	{ { submission_unix_listeners, sizeof(submission_unix_listeners) } }
2171 };
2172 /* </settings checks> */
2173 /* <settings checks> */
2174 struct submission_client_workaround_list {
2175 	const char *name;
2176 	enum submission_client_workarounds num;
2177 };
2178 
2179 static const struct submission_client_workaround_list
2180 submission_client_workaround_list[] = {
2181 	{ "whitespace-before-path",
2182 	  SUBMISSION_WORKAROUND_WHITESPACE_BEFORE_PATH },
2183 	{ "mailbox-for-path",
2184 	  SUBMISSION_WORKAROUND_MAILBOX_FOR_PATH },
2185 	{ NULL, 0 }
2186 };
2187 
2188 static int
submission_settings_parse_workarounds(struct submission_settings * set,const char ** error_r)2189 submission_settings_parse_workarounds(struct submission_settings *set,
2190 				const char **error_r)
2191 {
2192 	enum submission_client_workarounds client_workarounds = 0;
2193         const struct submission_client_workaround_list *list;
2194 	const char *const *str;
2195 
2196         str = t_strsplit_spaces(set->submission_client_workarounds, " ,");
2197 	for (; *str != NULL; str++) {
2198 		list = submission_client_workaround_list;
2199 		for (; list->name != NULL; list++) {
2200 			if (strcasecmp(*str, list->name) == 0) {
2201 				client_workarounds |= list->num;
2202 				break;
2203 			}
2204 		}
2205 		if (list->name == NULL) {
2206 			*error_r = t_strdup_printf(
2207 				"submission_client_workarounds: "
2208 				"Unknown workaround: %s", *str);
2209 			return -1;
2210 		}
2211 	}
2212 	set->parsed_workarounds = client_workarounds;
2213 	return 0;
2214 }
2215 
2216 static bool
submission_settings_verify(void * _set,pool_t pool ATTR_UNUSED,const char ** error_r)2217 submission_settings_verify(void *_set, pool_t pool ATTR_UNUSED, const char **error_r)
2218 {
2219 	struct submission_settings *set = _set;
2220 
2221 	if (submission_settings_parse_workarounds(set, error_r) < 0)
2222 		return FALSE;
2223 
2224 #ifndef CONFIG_BINARY
2225 	if (set->submission_relay_max_idle_time == 0) {
2226 		*error_r = "submission_relay_max_idle_time must not be 0";
2227 		return FALSE;
2228 	}
2229 	if (*set->hostname == '\0')
2230 		set->hostname = p_strdup(pool, my_hostdomain());
2231 #endif
2232 	return TRUE;
2233 }
2234 /* </settings checks> */
2235 struct service_settings submission_service_settings = {
2236 	.name = "submission",
2237 	.protocol = "submission",
2238 	.type = "",
2239 	.executable = "submission",
2240 	.user = "",
2241 	.group = "",
2242 	.privileged_group = "",
2243 	.extra_groups = "$default_internal_group",
2244 	.chroot = "",
2245 
2246 	.drop_priv_before_exec = FALSE,
2247 
2248 	.process_min_avail = 0,
2249 	.process_limit = 1024,
2250 	.client_limit = 1,
2251 	.service_count = 1,
2252 	.idle_kill = 0,
2253 	.vsz_limit = UOFF_T_MAX,
2254 
2255 	.unix_listeners = { { &submission_unix_listeners_buf,
2256 			      sizeof(submission_unix_listeners[0]) } },
2257 	.fifo_listeners = ARRAY_INIT,
2258 	.inet_listeners = ARRAY_INIT
2259 };
2260 #undef DEF
2261 #define DEF(type, name) \
2262 	SETTING_DEFINE_STRUCT_##type(#name, name, struct submission_settings)
2263 static const struct setting_define submission_setting_defines[] = {
2264 	DEF(BOOL, verbose_proctitle),
2265 	DEF(STR_VARS, rawlog_dir),
2266 
2267 	DEF(STR, hostname),
2268 
2269 	DEF(STR, login_greeting),
2270 	DEF(STR, login_trusted_networks),
2271 
2272 	DEF(STR, recipient_delimiter),
2273 
2274 	DEF(SIZE, submission_max_mail_size),
2275 	DEF(UINT, submission_max_recipients),
2276 	DEF(STR, submission_client_workarounds),
2277 	DEF(STR, submission_logout_format),
2278 
2279 	DEF(STR, submission_backend_capabilities),
2280 
2281 	DEF(STR, submission_relay_host),
2282 	DEF(IN_PORT, submission_relay_port),
2283 	DEF(BOOL, submission_relay_trusted),
2284 
2285 	DEF(STR, submission_relay_user),
2286 	DEF(STR, submission_relay_master_user),
2287 	DEF(STR, submission_relay_password),
2288 
2289 	DEF(ENUM, submission_relay_ssl),
2290 	DEF(BOOL, submission_relay_ssl_verify),
2291 
2292 	DEF(STR_VARS, submission_relay_rawlog_dir),
2293 	DEF(TIME, submission_relay_max_idle_time),
2294 
2295 	DEF(TIME_MSECS, submission_relay_connect_timeout),
2296 	DEF(TIME_MSECS, submission_relay_command_timeout),
2297 
2298 	DEF(STR, imap_urlauth_host),
2299 	DEF(IN_PORT, imap_urlauth_port),
2300 
2301 	SETTING_DEFINE_LIST_END
2302 };
2303 static const struct submission_settings submission_default_settings = {
2304 	.verbose_proctitle = FALSE,
2305 	.rawlog_dir = "",
2306 
2307 	.hostname = "",
2308 
2309 	.login_greeting = PACKAGE_NAME" ready.",
2310 	.login_trusted_networks = "",
2311 
2312 	.recipient_delimiter = "+",
2313 
2314 	.submission_max_mail_size = 40*1024*1024,
2315 	.submission_max_recipients = 0,
2316 	.submission_client_workarounds = "",
2317 	.submission_logout_format = "in=%i out=%o",
2318 
2319 	.submission_backend_capabilities = NULL,
2320 
2321 	.submission_relay_host = "",
2322 	.submission_relay_port = 25,
2323 	.submission_relay_trusted = FALSE,
2324 
2325 	.submission_relay_user = "",
2326 	.submission_relay_master_user = "",
2327 	.submission_relay_password = "",
2328 
2329 	.submission_relay_ssl = "no:smtps:starttls",
2330 	.submission_relay_ssl_verify = TRUE,
2331 
2332 	.submission_relay_rawlog_dir = "",
2333 	.submission_relay_max_idle_time = 60*29,
2334 
2335 	.submission_relay_connect_timeout = 30*1000,
2336 	.submission_relay_command_timeout = 60*5*1000,
2337 
2338 	.imap_urlauth_host = "",
2339 	.imap_urlauth_port = 143,
2340 };
2341 static const struct setting_parser_info *submission_setting_dependencies[] = {
2342 	&mail_user_setting_parser_info,
2343 	NULL
2344 };
2345 const struct setting_parser_info submission_setting_parser_info = {
2346 	.module_name = "submission",
2347 	.defines = submission_setting_defines,
2348 	.defaults = &submission_default_settings,
2349 
2350 	.type_offset = SIZE_MAX,
2351 	.struct_size = sizeof(struct submission_settings),
2352 
2353 	.parent_offset = SIZE_MAX,
2354 
2355 	.check_func = submission_settings_verify,
2356 	.dependencies = submission_setting_dependencies
2357 };
2358 /* ../../src/submission-login/submission-login-settings.c */
2359 /* <settings checks> */
2360 static struct inet_listener_settings submission_login_inet_listeners_array[] = {
2361 	{ .name = "submission", .address = "", .port = 587  },
2362 	{ .name = "submissions", .address = "", .port = 465, .ssl = TRUE }
2363 };
2364 static struct inet_listener_settings *submission_login_inet_listeners[] = {
2365 	&submission_login_inet_listeners_array[0]
2366 };
2367 static buffer_t submission_login_inet_listeners_buf = {
2368 	{ { submission_login_inet_listeners,
2369 	    sizeof(submission_login_inet_listeners) } }
2370 };
2371 
2372 /* </settings checks> */
2373 struct service_settings submission_login_service_settings = {
2374 	.name = "submission-login",
2375 	.protocol = "submission",
2376 	.type = "login",
2377 	.executable = "submission-login",
2378 	.user = "$default_login_user",
2379 	.group = "",
2380 	.privileged_group = "",
2381 	.extra_groups = "",
2382 	.chroot = "login",
2383 
2384 	.drop_priv_before_exec = FALSE,
2385 
2386 	.process_min_avail = 0,
2387 	.process_limit = 0,
2388 	.client_limit = 0,
2389 	.service_count = 1,
2390 	.idle_kill = 0,
2391 	.vsz_limit = UOFF_T_MAX,
2392 
2393 	.unix_listeners = ARRAY_INIT,
2394 	.fifo_listeners = ARRAY_INIT,
2395 	.inet_listeners = { { &submission_login_inet_listeners_buf,
2396 			      sizeof(submission_login_inet_listeners[0]) } }
2397 };
2398 #undef DEF
2399 #define DEF(type, name) \
2400 	SETTING_DEFINE_STRUCT_##type(#name, name, struct submission_login_settings)
2401 static const struct setting_define submission_login_setting_defines[] = {
2402 	DEF(STR, hostname),
2403 
2404 	DEF(SIZE, submission_max_mail_size),
2405 	DEF(STR, submission_backend_capabilities),
2406 
2407 	SETTING_DEFINE_LIST_END
2408 };
2409 static const struct submission_login_settings submission_login_default_settings = {
2410 	.hostname = "",
2411 
2412 	.submission_max_mail_size = 0,
2413 	.submission_backend_capabilities = NULL
2414 };
2415 static const struct setting_parser_info *submission_login_setting_dependencies[] = {
2416 	&login_setting_parser_info,
2417 	NULL
2418 };
2419 const struct setting_parser_info submission_login_setting_parser_info = {
2420 	.module_name = "submission-login",
2421 	.defines = submission_login_setting_defines,
2422 	.defaults = &submission_login_default_settings,
2423 
2424 	.type_offset = SIZE_MAX,
2425 	.struct_size = sizeof(struct submission_login_settings),
2426 	.parent_offset = SIZE_MAX,
2427 
2428 #ifndef CONFIG_BINARY
2429 	.check_func = submission_login_settings_check,
2430 #endif
2431 	.dependencies = submission_login_setting_dependencies
2432 };
2433 const struct setting_parser_info *submission_login_setting_roots[] = {
2434 	&login_setting_parser_info,
2435 	&submission_login_setting_parser_info,
2436 	NULL
2437 };
2438 /* ../../src/stats/stats-settings.c */
2439 extern const struct setting_parser_info stats_metric_setting_parser_info;
2440 extern const struct setting_parser_info stats_exporter_setting_parser_info;
2441 /* <settings checks> */
2442 #include "event-filter.h"
2443 #include <math.h>
2444 /* </settings checks> */
2445 /* <settings checks> */
2446 static struct file_listener_settings stats_unix_listeners_array[] = {
2447 	{ "stats-reader", 0600, "", "" },
2448 	{ "stats-writer", 0660, "", "$default_internal_group" },
2449 };
2450 static struct file_listener_settings *stats_unix_listeners[] = {
2451 	&stats_unix_listeners_array[0],
2452 	&stats_unix_listeners_array[1],
2453 };
2454 static buffer_t stats_unix_listeners_buf = {
2455 	{ { stats_unix_listeners, sizeof(stats_unix_listeners) } }
2456 };
2457 /* </settings checks> */
2458 /* <settings checks> */
parse_format_args_set_time(struct stats_exporter_settings * set,enum event_exporter_time_fmt fmt,const char ** error_r)2459 static bool parse_format_args_set_time(struct stats_exporter_settings *set,
2460 				       enum event_exporter_time_fmt fmt,
2461 				       const char **error_r)
2462 {
2463 	if ((set->parsed_time_format != EVENT_EXPORTER_TIME_FMT_NATIVE) &&
2464 	    (set->parsed_time_format != fmt)) {
2465 		*error_r = t_strdup_printf("Exporter '%s' specifies multiple "
2466 					   "time format args", set->name);
2467 		return FALSE;
2468 	}
2469 
2470 	set->parsed_time_format = fmt;
2471 
2472 	return TRUE;
2473 }
2474 
parse_format_args(struct stats_exporter_settings * set,const char ** error_r)2475 static bool parse_format_args(struct stats_exporter_settings *set,
2476 			      const char **error_r)
2477 {
2478 	const char *const *tmp;
2479 
2480 	/* Defaults */
2481 	set->parsed_time_format = EVENT_EXPORTER_TIME_FMT_NATIVE;
2482 
2483 	tmp = t_strsplit_spaces(set->format_args, " ");
2484 
2485 	/*
2486 	 * If the config contains multiple types of the same type (e.g.,
2487 	 * both time-rfc3339 and time-unix) we fail the config check.
2488 	 *
2489 	 * Note: At the moment, we have only time-* tokens.  In the future
2490 	 * when we have other tokens, they should be parsed here.
2491 	 */
2492 	for (; *tmp != NULL; tmp++) {
2493 		enum event_exporter_time_fmt fmt;
2494 
2495 		if (strcmp(*tmp, "time-rfc3339") == 0) {
2496 			fmt = EVENT_EXPORTER_TIME_FMT_RFC3339;
2497 		} else if (strcmp(*tmp, "time-unix") == 0) {
2498 			fmt = EVENT_EXPORTER_TIME_FMT_UNIX;
2499 		} else {
2500 			*error_r = t_strdup_printf("Unknown exporter format "
2501 						   "arg: %s", *tmp);
2502 			return FALSE;
2503 		}
2504 
2505 		if (!parse_format_args_set_time(set, fmt, error_r))
2506 			return FALSE;
2507 	}
2508 
2509 	return TRUE;
2510 }
2511 
stats_exporter_settings_check(void * _set,pool_t pool ATTR_UNUSED,const char ** error_r)2512 static bool stats_exporter_settings_check(void *_set, pool_t pool ATTR_UNUSED,
2513 					  const char **error_r)
2514 {
2515 	struct stats_exporter_settings *set = _set;
2516 	bool time_fmt_required;
2517 
2518 	if (set->name[0] == '\0') {
2519 		*error_r = "Exporter name can't be empty";
2520 		return FALSE;
2521 	}
2522 
2523 	/* TODO: The following should be plugable.
2524 	 *
2525 	 * Note: Make sure to mirror any changes to the below code in
2526 	 * stats_exporters_add_set().
2527 	 */
2528 	if (set->format[0] == '\0') {
2529 		*error_r = "Exporter format name can't be empty";
2530 		return FALSE;
2531 	} else if (strcmp(set->format, "none") == 0) {
2532 		time_fmt_required = FALSE;
2533 	} else if (strcmp(set->format, "json") == 0) {
2534 		time_fmt_required = TRUE;
2535 	} else if (strcmp(set->format, "tab-text") == 0) {
2536 		time_fmt_required = TRUE;
2537 	} else {
2538 		*error_r = t_strdup_printf("Unknown exporter format '%s'",
2539 					   set->format);
2540 		return FALSE;
2541 	}
2542 
2543 	/* TODO: The following should be plugable.
2544 	 *
2545 	 * Note: Make sure to mirror any changes to the below code in
2546 	 * stats_exporters_add_set().
2547 	 */
2548 	if (set->transport[0] == '\0') {
2549 		*error_r = "Exporter transport name can't be empty";
2550 		return FALSE;
2551 	} else if (strcmp(set->transport, "drop") == 0 ||
2552 		   strcmp(set->transport, "http-post") == 0 ||
2553 		   strcmp(set->transport, "log") == 0) {
2554 		/* no-op */
2555 	} else {
2556 		*error_r = t_strdup_printf("Unknown transport type '%s'",
2557 					   set->transport);
2558 		return FALSE;
2559 	}
2560 
2561 	if (!parse_format_args(set, error_r))
2562 		return FALSE;
2563 
2564 	/* Some formats don't have a native way of serializing time stamps */
2565 	if (time_fmt_required &&
2566 	    set->parsed_time_format == EVENT_EXPORTER_TIME_FMT_NATIVE) {
2567 		*error_r = t_strdup_printf("%s exporter format requires a "
2568 					   "time-* argument", set->format);
2569 		return FALSE;
2570 	}
2571 
2572 	return TRUE;
2573 }
2574 
parse_metric_group_by_common(const char * func,const char * const * params,intmax_t * min_r,intmax_t * max_r,intmax_t * other_r,const char ** error_r)2575 static bool parse_metric_group_by_common(const char *func,
2576 					 const char *const *params,
2577 					 intmax_t *min_r,
2578 					 intmax_t *max_r,
2579 					 intmax_t *other_r,
2580 					 const char **error_r)
2581 {
2582 	intmax_t min, max, other;
2583 
2584 	if ((str_array_length(params) != 3) ||
2585 	    (str_to_intmax(params[0], &min) < 0) ||
2586 	    (str_to_intmax(params[1], &max) < 0) ||
2587 	    (str_to_intmax(params[2], &other) < 0)) {
2588 		*error_r = t_strdup_printf("group_by '%s' aggregate function takes "
2589 					   "3 int args", func);
2590 		return FALSE;
2591 	}
2592 
2593 	if ((min < 0) || (max < 0) || (other < 0)) {
2594 		*error_r = t_strdup_printf("group_by '%s' aggregate function "
2595 					   "arguments must be >= 0", func);
2596 		return FALSE;
2597 	}
2598 
2599 	if (min >= max) {
2600 		*error_r = t_strdup_printf("group_by '%s' aggregate function "
2601 					   "min must be < max (%ju must be < %ju)",
2602 					   func, min, max);
2603 		return FALSE;
2604 	}
2605 
2606 	*min_r = min;
2607 	*max_r = max;
2608 	*other_r = other;
2609 
2610 	return TRUE;
2611 }
2612 
parse_metric_group_by_exp(pool_t pool,struct stats_metric_settings_group_by * group_by,const char * const * params,const char ** error_r)2613 static bool parse_metric_group_by_exp(pool_t pool, struct stats_metric_settings_group_by *group_by,
2614 				      const char *const *params, const char **error_r)
2615 {
2616 	intmax_t min, max, base;
2617 
2618 	if (!parse_metric_group_by_common("exponential", params, &min, &max, &base, error_r))
2619 		return FALSE;
2620 
2621 	if ((base != 2) && (base != 10)) {
2622 		*error_r = t_strdup_printf("group_by 'exponential' aggregate function "
2623 					   "base must be one of: 2, 10 (base=%ju)",
2624 					   base);
2625 		return FALSE;
2626 	}
2627 
2628 	group_by->func = STATS_METRIC_GROUPBY_QUANTIZED;
2629 
2630 	/*
2631 	 * Allocate the bucket range array and fill it in
2632 	 *
2633 	 * The first bucket is special - it contains everything less than or
2634 	 * equal to 'base^min'.  The last bucket is also special - it
2635 	 * contains everything greater than 'base^max'.
2636 	 *
2637 	 * The second bucket begins at 'base^min + 1', the third bucket
2638 	 * begins at 'base^(min + 1) + 1', and so on.
2639 	 */
2640 	group_by->num_ranges = max - min + 2;
2641 	group_by->ranges = p_new(pool, struct stats_metric_settings_bucket_range,
2642 				 group_by->num_ranges);
2643 
2644 	/* set up min & max buckets */
2645 	group_by->ranges[0].min = INTMAX_MIN;
2646 	group_by->ranges[0].max = pow(base, min);
2647 	group_by->ranges[group_by->num_ranges - 1].min = pow(base, max);
2648 	group_by->ranges[group_by->num_ranges - 1].max = INTMAX_MAX;
2649 
2650 	/* remaining buckets */
2651 	for (unsigned int i = 1; i < group_by->num_ranges - 1; i++) {
2652 		group_by->ranges[i].min = pow(base, min + (i - 1));
2653 		group_by->ranges[i].max = pow(base, min + i);
2654 	}
2655 
2656 	return TRUE;
2657 }
2658 
parse_metric_group_by_lin(pool_t pool,struct stats_metric_settings_group_by * group_by,const char * const * params,const char ** error_r)2659 static bool parse_metric_group_by_lin(pool_t pool, struct stats_metric_settings_group_by *group_by,
2660 				      const char *const *params, const char **error_r)
2661 {
2662 	intmax_t min, max, step;
2663 
2664 	if (!parse_metric_group_by_common("linear", params, &min, &max, &step, error_r))
2665 		return FALSE;
2666 
2667 	if ((min + step) > max) {
2668 		*error_r = t_strdup_printf("group_by 'linear' aggregate function "
2669 					   "min+step must be <= max (%ju must be <= %ju)",
2670 					   min + step, max);
2671 		return FALSE;
2672 	}
2673 
2674 	group_by->func = STATS_METRIC_GROUPBY_QUANTIZED;
2675 
2676 	/*
2677 	 * Allocate the bucket range array and fill it in
2678 	 *
2679 	 * The first bucket is special - it contains everything less than or
2680 	 * equal to 'min'.  The last bucket is also special - it contains
2681 	 * everything greater than 'max'.
2682 	 *
2683 	 * The second bucket begins at 'min + 1', the third bucket begins at
2684 	 * 'min + 1 * step + 1', the fourth at 'min + 2 * step + 1', and so on.
2685 	 */
2686 	group_by->num_ranges = (max - min) / step + 2;
2687 	group_by->ranges = p_new(pool, struct stats_metric_settings_bucket_range,
2688 				 group_by->num_ranges);
2689 
2690 	/* set up min & max buckets */
2691 	group_by->ranges[0].min = INTMAX_MIN;
2692 	group_by->ranges[0].max = min;
2693 	group_by->ranges[group_by->num_ranges - 1].min = max;
2694 	group_by->ranges[group_by->num_ranges - 1].max = INTMAX_MAX;
2695 
2696 	/* remaining buckets */
2697 	for (unsigned int i = 1; i < group_by->num_ranges - 1; i++) {
2698 		group_by->ranges[i].min = min + (i - 1) * step;
2699 		group_by->ranges[i].max = min + i * step;
2700 	}
2701 
2702 	return TRUE;
2703 }
2704 
parse_metric_group_by(struct stats_metric_settings * set,pool_t pool,const char ** error_r)2705 static bool parse_metric_group_by(struct stats_metric_settings *set,
2706 				  pool_t pool, const char **error_r)
2707 {
2708 	const char *const *tmp = t_strsplit_spaces(set->group_by, " ");
2709 
2710 	if (tmp[0] == NULL)
2711 		return TRUE;
2712 
2713 	p_array_init(&set->parsed_group_by, pool, str_array_length(tmp));
2714 
2715 	/* For each group_by field */
2716 	for (; *tmp != NULL; tmp++) {
2717 		struct stats_metric_settings_group_by group_by;
2718 		const char *const *params;
2719 
2720 		i_zero(&group_by);
2721 
2722 		/* <field name>:<aggregation func>... */
2723 		params = t_strsplit(*tmp, ":");
2724 
2725 		if (params[1] == NULL) {
2726 			/* <field name> - alias for <field>:discrete */
2727 			group_by.func = STATS_METRIC_GROUPBY_DISCRETE;
2728 		} else if (strcmp(params[1], "discrete") == 0) {
2729 			/* <field>:discrete */
2730 			group_by.func = STATS_METRIC_GROUPBY_DISCRETE;
2731 			if (params[2] != NULL) {
2732 				*error_r = "group_by 'discrete' aggregate function "
2733 					   "does not take any args";
2734 				return FALSE;
2735 			}
2736 		} else if (strcmp(params[1], "exponential") == 0) {
2737 			/* <field>:exponential:<min mag>:<max mag>:<base> */
2738 			if (!parse_metric_group_by_exp(pool, &group_by, &params[2], error_r))
2739 				return FALSE;
2740 		} else if (strcmp(params[1], "linear") == 0) {
2741 			/* <field>:linear:<min val>:<max val>:<step> */
2742 			if (!parse_metric_group_by_lin(pool, &group_by, &params[2], error_r))
2743 				return FALSE;
2744 		} else {
2745 			*error_r = t_strdup_printf("unknown aggregation function "
2746 						   "'%s' on field '%s'", params[1], params[0]);
2747 			return FALSE;
2748 		}
2749 
2750 		group_by.field = p_strdup(pool, params[0]);
2751 
2752 		array_push_back(&set->parsed_group_by, &group_by);
2753 	}
2754 
2755 	return TRUE;
2756 }
2757 
stats_metric_settings_check(void * _set,pool_t pool,const char ** error_r)2758 static bool stats_metric_settings_check(void *_set, pool_t pool, const char **error_r)
2759 {
2760 	struct stats_metric_settings *set = _set;
2761 
2762 	if (set->metric_name[0] == '\0') {
2763 		*error_r = "Metric name can't be empty";
2764 		return FALSE;
2765 	}
2766 
2767 	if (set->filter[0] == '\0') {
2768 		*error_r = t_strdup_printf("metric %s { filter } is empty - "
2769 					   "will not match anything", set->metric_name);
2770 		return FALSE;
2771 	}
2772 
2773 	set->parsed_filter = event_filter_create_fragment(pool);
2774 	if (event_filter_parse(set->filter, set->parsed_filter, error_r) < 0)
2775 		return FALSE;
2776 
2777 	if (!parse_metric_group_by(set, pool, error_r))
2778 		return FALSE;
2779 
2780 	return TRUE;
2781 }
2782 
stats_settings_check(void * _set,pool_t pool ATTR_UNUSED,const char ** error_r)2783 static bool stats_settings_check(void *_set, pool_t pool ATTR_UNUSED,
2784 				 const char **error_r)
2785 {
2786 	struct stats_settings *set = _set;
2787 	struct stats_exporter_settings *exporter;
2788 	struct stats_metric_settings *metric;
2789 
2790 	if (!array_is_created(&set->metrics) || !array_is_created(&set->exporters))
2791 		return TRUE;
2792 
2793 	/* check that all metrics refer to exporters that exist */
2794 	array_foreach_elem(&set->metrics, metric) {
2795 		bool found = FALSE;
2796 
2797 		if (metric->exporter[0] == '\0')
2798 			continue; /* metric not exported */
2799 
2800 		array_foreach_elem(&set->exporters, exporter) {
2801 			if (strcmp(metric->exporter, exporter->name) == 0) {
2802 				found = TRUE;
2803 				break;
2804 			}
2805 		}
2806 
2807 		if (!found) {
2808 			*error_r = t_strdup_printf("metric %s refers to "
2809 						   "non-existent exporter '%s'",
2810 						   metric->metric_name,
2811 						   metric->exporter);
2812 			return FALSE;
2813 		}
2814 	}
2815 
2816 	return TRUE;
2817 }
2818 /* </settings checks> */
2819 struct service_settings stats_service_settings = {
2820 	.name = "stats",
2821 	.protocol = "",
2822 	.type = "",
2823 	.executable = "stats",
2824 	.user = "$default_internal_user",
2825 	.group = "",
2826 	.privileged_group = "",
2827 	.extra_groups = "",
2828 	.chroot = "",
2829 
2830 	.drop_priv_before_exec = FALSE,
2831 
2832 	.process_min_avail = 0,
2833 	.process_limit = 1,
2834 	.client_limit = 0,
2835 	.service_count = 0,
2836 	.idle_kill = UINT_MAX,
2837 	.vsz_limit = UOFF_T_MAX,
2838 
2839 	.unix_listeners = { { &stats_unix_listeners_buf,
2840 			      sizeof(stats_unix_listeners[0]) } },
2841 	.inet_listeners = ARRAY_INIT,
2842 };
2843 #undef DEF
2844 #define DEF(type, name) \
2845 	SETTING_DEFINE_STRUCT_##type(#name, name, struct stats_exporter_settings)
2846 static const struct setting_define stats_exporter_setting_defines[] = {
2847 	DEF(STR, name),
2848 	DEF(STR, transport),
2849 	DEF(STR, transport_args),
2850 	DEF(TIME_MSECS, transport_timeout),
2851 	DEF(STR, format),
2852 	DEF(STR, format_args),
2853 	SETTING_DEFINE_LIST_END
2854 };
2855 static const struct stats_exporter_settings stats_exporter_default_settings = {
2856 	.name = "",
2857 	.transport = "",
2858 	.transport_args = "",
2859 	.transport_timeout = 250, /* ms */
2860 	.format = "",
2861 	.format_args = "",
2862 };
2863 const struct setting_parser_info stats_exporter_setting_parser_info = {
2864 	.defines = stats_exporter_setting_defines,
2865 	.defaults = &stats_exporter_default_settings,
2866 
2867 	.type_offset = offsetof(struct stats_exporter_settings, name),
2868 	.struct_size = sizeof(struct stats_exporter_settings),
2869 
2870 	.parent_offset = SIZE_MAX,
2871 	.check_func = stats_exporter_settings_check,
2872 };
2873 #undef DEF
2874 #define DEF(type, name) \
2875 	SETTING_DEFINE_STRUCT_##type(#name, name, struct stats_metric_settings)
2876 static const struct setting_define stats_metric_setting_defines[] = {
2877 	DEF(STR, metric_name),
2878 	DEF(STR, fields),
2879 	DEF(STR, group_by),
2880 	DEF(STR, filter),
2881 	DEF(STR, exporter),
2882 	DEF(STR, exporter_include),
2883 	DEF(STR, description),
2884 	SETTING_DEFINE_LIST_END
2885 };
2886 static const struct stats_metric_settings stats_metric_default_settings = {
2887 	.metric_name = "",
2888 	.fields = "",
2889 	.filter = "",
2890 	.exporter = "",
2891 	.group_by = "",
2892 	.exporter_include = STATS_METRIC_SETTINGS_DEFAULT_EXPORTER_INCLUDE,
2893 	.description = "",
2894 };
2895 const struct setting_parser_info stats_metric_setting_parser_info = {
2896 	.defines = stats_metric_setting_defines,
2897 	.defaults = &stats_metric_default_settings,
2898 
2899 	.type_offset = offsetof(struct stats_metric_settings, metric_name),
2900 	.struct_size = sizeof(struct stats_metric_settings),
2901 
2902 	.parent_offset = SIZE_MAX,
2903 	.check_func = stats_metric_settings_check,
2904 };
2905 #undef DEF
2906 #define DEF(type, name) \
2907 	SETTING_DEFINE_STRUCT_##type(#name, name, struct stats_settings)
2908 #undef DEFLIST_UNIQUE
2909 #define DEFLIST_UNIQUE(field, name, defines) \
2910 	{ .type = SET_DEFLIST_UNIQUE, .key = name, \
2911 	  .offset = offsetof(struct stats_settings, field), \
2912 	  .list_info = defines }
2913 static const struct setting_define stats_setting_defines[] = {
2914 	DEF(STR, stats_http_rawlog_dir),
2915 
2916 	DEFLIST_UNIQUE(metrics, "metric", &stats_metric_setting_parser_info),
2917 	DEFLIST_UNIQUE(exporters, "event_exporter", &stats_exporter_setting_parser_info),
2918 	SETTING_DEFINE_LIST_END
2919 };
2920 const struct stats_settings stats_default_settings = {
2921 	.stats_http_rawlog_dir = "",
2922 
2923 	.metrics = ARRAY_INIT,
2924 	.exporters = ARRAY_INIT,
2925 };
2926 const struct setting_parser_info stats_setting_parser_info = {
2927 	.module_name = "stats",
2928 	.defines = stats_setting_defines,
2929 	.defaults = &stats_default_settings,
2930 
2931 	.type_offset = SIZE_MAX,
2932 	.struct_size = sizeof(struct stats_settings),
2933 
2934 	.parent_offset = SIZE_MAX,
2935 	.check_func = stats_settings_check,
2936 };
2937 /* ../../src/replication/replicator/replicator-settings.c */
2938 /* <settings checks> */
2939 static struct file_listener_settings replicator_unix_listeners_array[] = {
2940 	{ "replicator", 0600, "$default_internal_user", "" },
2941 	{ "replicator-doveadm", 0, "$default_internal_user", "" }
2942 };
2943 static struct file_listener_settings *replicator_unix_listeners[] = {
2944 	&replicator_unix_listeners_array[0],
2945 	&replicator_unix_listeners_array[1]
2946 };
2947 static buffer_t replicator_unix_listeners_buf = {
2948 	{ { replicator_unix_listeners, sizeof(replicator_unix_listeners) } }
2949 };
2950 /* </settings checks> */
2951 struct service_settings replicator_service_settings = {
2952 	.name = "replicator",
2953 	.protocol = "",
2954 	.type = "",
2955 	.executable = "replicator",
2956 	.user = "",
2957 	.group = "",
2958 	.privileged_group = "",
2959 	.extra_groups = "",
2960 	.chroot = "",
2961 
2962 	.drop_priv_before_exec = FALSE,
2963 
2964 	.process_min_avail = 0,
2965 	.process_limit = 1,
2966 	.client_limit = 0,
2967 	.service_count = 0,
2968 	.idle_kill = UINT_MAX,
2969 	.vsz_limit = UOFF_T_MAX,
2970 
2971 	.unix_listeners = { { &replicator_unix_listeners_buf,
2972 			      sizeof(replicator_unix_listeners[0]) } },
2973 	.fifo_listeners = ARRAY_INIT,
2974 	.inet_listeners = ARRAY_INIT,
2975 
2976 	.process_limit_1 = TRUE
2977 };
2978 #undef DEF
2979 #define DEF(type, name) \
2980 	SETTING_DEFINE_STRUCT_##type(#name, name, struct replicator_settings)
2981 static const struct setting_define replicator_setting_defines[] = {
2982 	DEF(STR, auth_socket_path),
2983 	DEF(STR, doveadm_socket_path),
2984 	DEF(STR, replication_dsync_parameters),
2985 
2986 	DEF(TIME, replication_full_sync_interval),
2987 	DEF(UINT, replication_max_conns),
2988 
2989 	SETTING_DEFINE_LIST_END
2990 };
2991 const struct replicator_settings replicator_default_settings = {
2992 	.auth_socket_path = "auth-userdb",
2993 	.doveadm_socket_path = "doveadm-server",
2994 	.replication_dsync_parameters = "-d -N -l 30 -U",
2995 
2996 	.replication_full_sync_interval = 60*60*24,
2997 	.replication_max_conns = 10
2998 };
2999 const struct setting_parser_info replicator_setting_parser_info = {
3000 	.module_name = "replicator",
3001 	.defines = replicator_setting_defines,
3002 	.defaults = &replicator_default_settings,
3003 
3004 	.type_offset = SIZE_MAX,
3005 	.struct_size = sizeof(struct replicator_settings),
3006 
3007 	.parent_offset = SIZE_MAX
3008 };
3009 /* ../../src/replication/aggregator/aggregator-settings.c */
3010 /* <settings checks> */
3011 static struct file_listener_settings aggregator_unix_listeners_array[] = {
3012 	{ "replication-notify", 0600, "", "" }
3013 };
3014 static struct file_listener_settings *aggregator_unix_listeners[] = {
3015 	&aggregator_unix_listeners_array[0]
3016 };
3017 static buffer_t aggregator_unix_listeners_buf = {
3018 	{ { aggregator_unix_listeners, sizeof(aggregator_unix_listeners) } }
3019 };
3020 
3021 static struct file_listener_settings aggregator_fifo_listeners_array[] = {
3022 	{ "replication-notify-fifo", 0600, "", "" }
3023 };
3024 static struct file_listener_settings *aggregator_fifo_listeners[] = {
3025 	&aggregator_fifo_listeners_array[0]
3026 };
3027 static buffer_t aggregator_fifo_listeners_buf = {
3028 	{ { aggregator_fifo_listeners, sizeof(aggregator_fifo_listeners) } }
3029 };
3030 /* </settings checks> */
3031 struct service_settings aggregator_service_settings = {
3032 	.name = "aggregator",
3033 	.protocol = "",
3034 	.type = "",
3035 	.executable = "aggregator",
3036 	.user = "$default_internal_user",
3037 	.group = "",
3038 	.privileged_group = "",
3039 	.extra_groups = "",
3040 	.chroot = ".",
3041 
3042 	.drop_priv_before_exec = FALSE,
3043 
3044 	.process_min_avail = 0,
3045 	.process_limit = 0,
3046 	.client_limit = 0,
3047 	.service_count = 0,
3048 	.idle_kill = 0,
3049 	.vsz_limit = UOFF_T_MAX,
3050 
3051 	.unix_listeners = { { &aggregator_unix_listeners_buf,
3052 			      sizeof(aggregator_unix_listeners[0]) } },
3053 	.fifo_listeners = { { &aggregator_fifo_listeners_buf,
3054 			      sizeof(aggregator_fifo_listeners[0]) } },
3055 	.inet_listeners = ARRAY_INIT
3056 };
3057 #undef DEF
3058 #define DEF(type, name) \
3059 	SETTING_DEFINE_STRUCT_##type(#name, name, struct aggregator_settings)
3060 static const struct setting_define aggregator_setting_defines[] = {
3061 	DEF(STR, replicator_host),
3062 	DEF(IN_PORT, replicator_port),
3063 
3064 	SETTING_DEFINE_LIST_END
3065 };
3066 const struct aggregator_settings aggregator_default_settings = {
3067 	.replicator_host = "replicator",
3068 	.replicator_port = 0
3069 };
3070 const struct setting_parser_info aggregator_setting_parser_info = {
3071 	.module_name = "aggregator",
3072 	.defines = aggregator_setting_defines,
3073 	.defaults = &aggregator_default_settings,
3074 
3075 	.type_offset = SIZE_MAX,
3076 	.struct_size = sizeof(struct aggregator_settings),
3077 
3078 	.parent_offset = SIZE_MAX
3079 };
3080 /* ../../src/pop3/pop3-settings.c */
3081 /* <settings checks> */
3082 static struct file_listener_settings pop3_unix_listeners_array[] = {
3083 	{ "login/pop3", 0666, "", "" }
3084 };
3085 static struct file_listener_settings *pop3_unix_listeners[] = {
3086 	&pop3_unix_listeners_array[0]
3087 };
3088 static buffer_t pop3_unix_listeners_buf = {
3089 	{ { pop3_unix_listeners, sizeof(pop3_unix_listeners) } }
3090 };
3091 /* </settings checks> */
3092 /* <settings checks> */
3093 struct pop3_client_workaround_list {
3094 	const char *name;
3095 	enum pop3_client_workarounds num;
3096 };
3097 
3098 static const struct pop3_client_workaround_list pop3_client_workaround_list[] = {
3099 	{ "outlook-no-nuls", WORKAROUND_OUTLOOK_NO_NULS },
3100 	{ "oe-ns-eoh", WORKAROUND_OE_NS_EOH },
3101 	{ NULL, 0 }
3102 };
3103 
3104 static int
pop3_settings_parse_workarounds(struct pop3_settings * set,const char ** error_r)3105 pop3_settings_parse_workarounds(struct pop3_settings *set,
3106 				const char **error_r)
3107 {
3108         enum pop3_client_workarounds client_workarounds = 0;
3109 	const struct pop3_client_workaround_list *list;
3110 	const char *const *str;
3111 
3112         str = t_strsplit_spaces(set->pop3_client_workarounds, " ,");
3113 	for (; *str != NULL; str++) {
3114 		list = pop3_client_workaround_list;
3115 		for (; list->name != NULL; list++) {
3116 			if (strcasecmp(*str, list->name) == 0) {
3117 				client_workarounds |= list->num;
3118 				break;
3119 			}
3120 		}
3121 		if (list->name == NULL) {
3122 			*error_r = t_strdup_printf("pop3_client_workarounds: "
3123 				"Unknown workaround: %s", *str);
3124 			return -1;
3125 		}
3126 	}
3127 	set->parsed_workarounds = client_workarounds;
3128 	return 0;
3129 }
3130 
3131 static bool
pop3_settings_verify(void * _set,pool_t pool ATTR_UNUSED,const char ** error_r)3132 pop3_settings_verify(void *_set, pool_t pool ATTR_UNUSED, const char **error_r)
3133 {
3134 	struct pop3_settings *set = _set;
3135 
3136 	if (pop3_settings_parse_workarounds(set, error_r) < 0)
3137 		return FALSE;
3138 	if (strcmp(set->pop3_delete_type, "default") == 0) {
3139 		if (set->pop3_deleted_flag[0] == '\0')
3140 			set->parsed_delete_type = POP3_DELETE_TYPE_EXPUNGE;
3141 		else
3142 			set->parsed_delete_type = POP3_DELETE_TYPE_FLAG;
3143 	} else if (strcmp(set->pop3_delete_type, "expunge") == 0) {
3144 		set->parsed_delete_type = POP3_DELETE_TYPE_EXPUNGE;
3145 	} else if (strcmp(set->pop3_delete_type, "flag") == 0) {
3146 		if (set->pop3_deleted_flag[0] == '\0') {
3147 			*error_r = "pop3_delete_type=flag, but pop3_deleted_flag not set";
3148 			return FALSE;
3149 		}
3150 		set->parsed_delete_type = POP3_DELETE_TYPE_FLAG;
3151 	} else {
3152 		*error_r = t_strdup_printf("pop3_delete_type: Unknown value '%s'",
3153 					   set->pop3_delete_type);
3154 		return FALSE;
3155 	}
3156 	return TRUE;
3157 }
3158 /* </settings checks> */
3159 struct service_settings pop3_service_settings = {
3160 	.name = "pop3",
3161 	.protocol = "pop3",
3162 	.type = "",
3163 	.executable = "pop3",
3164 	.user = "",
3165 	.group = "",
3166 	.privileged_group = "",
3167 	.extra_groups = "$default_internal_group",
3168 	.chroot = "",
3169 
3170 	.drop_priv_before_exec = FALSE,
3171 
3172 	.process_min_avail = 0,
3173 	.process_limit = 1024,
3174 	.client_limit = 1,
3175 	.service_count = 1,
3176 	.idle_kill = 0,
3177 	.vsz_limit = UOFF_T_MAX,
3178 
3179 	.unix_listeners = { { &pop3_unix_listeners_buf,
3180 			      sizeof(pop3_unix_listeners[0]) } },
3181 	.fifo_listeners = ARRAY_INIT,
3182 	.inet_listeners = ARRAY_INIT
3183 };
3184 #undef DEF
3185 #undef DEFLIST
3186 #define DEF(type, name) \
3187 	SETTING_DEFINE_STRUCT_##type(#name, name, struct pop3_settings)
3188 #define DEFLIST(field, name, defines) \
3189 	{ .type = SET_DEFLIST, .key = name, \
3190 	  .offset = offsetof(struct pop3_settings, field), \
3191 	  .list_info = defines }
3192 static const struct setting_define pop3_setting_defines[] = {
3193 	DEF(BOOL, verbose_proctitle),
3194 	DEF(STR_VARS, rawlog_dir),
3195 
3196 	DEF(BOOL, pop3_no_flag_updates),
3197 	DEF(BOOL, pop3_enable_last),
3198 	DEF(BOOL, pop3_reuse_xuidl),
3199 	DEF(BOOL, pop3_save_uidl),
3200 	DEF(BOOL, pop3_lock_session),
3201 	DEF(BOOL, pop3_fast_size_lookups),
3202 	DEF(STR, pop3_client_workarounds),
3203 	DEF(STR, pop3_logout_format),
3204 	DEF(ENUM, pop3_uidl_duplicates),
3205 	DEF(STR, pop3_deleted_flag),
3206 	DEF(ENUM, pop3_delete_type),
3207 
3208 	SETTING_DEFINE_LIST_END
3209 };
3210 static const struct pop3_settings pop3_default_settings = {
3211 	.verbose_proctitle = FALSE,
3212 	.rawlog_dir = "",
3213 
3214 	.pop3_no_flag_updates = FALSE,
3215 	.pop3_enable_last = FALSE,
3216 	.pop3_reuse_xuidl = FALSE,
3217 	.pop3_save_uidl = FALSE,
3218 	.pop3_lock_session = FALSE,
3219 	.pop3_fast_size_lookups = FALSE,
3220 	.pop3_client_workarounds = "",
3221 	.pop3_logout_format = "top=%t/%p, retr=%r/%b, del=%d/%m, size=%s",
3222 	.pop3_uidl_duplicates = "allow:rename",
3223 	.pop3_deleted_flag = "",
3224 	.pop3_delete_type = "default:expunge:flag"
3225 };
3226 static const struct setting_parser_info *pop3_setting_dependencies[] = {
3227 	&mail_user_setting_parser_info,
3228 	NULL
3229 };
3230 const struct setting_parser_info pop3_setting_parser_info = {
3231 	.module_name = "pop3",
3232 	.defines = pop3_setting_defines,
3233 	.defaults = &pop3_default_settings,
3234 
3235 	.type_offset = SIZE_MAX,
3236 	.struct_size = sizeof(struct pop3_settings),
3237 
3238 	.parent_offset = SIZE_MAX,
3239 
3240 	.check_func = pop3_settings_verify,
3241 	.dependencies = pop3_setting_dependencies
3242 };
3243 /* ../../src/pop3-login/pop3-login-settings.c */
3244 /* <settings checks> */
3245 static struct inet_listener_settings pop3_login_inet_listeners_array[] = {
3246 	{ .name = "pop3", .address = "", .port = 110 },
3247 	{ .name = "pop3s", .address = "", .port = 995, .ssl = TRUE }
3248 };
3249 static struct inet_listener_settings *pop3_login_inet_listeners[] = {
3250 	&pop3_login_inet_listeners_array[0],
3251 	&pop3_login_inet_listeners_array[1]
3252 };
3253 static buffer_t pop3_login_inet_listeners_buf = {
3254 	{ { pop3_login_inet_listeners, sizeof(pop3_login_inet_listeners) } }
3255 };
3256 
3257 /* </settings checks> */
3258 struct service_settings pop3_login_service_settings = {
3259 	.name = "pop3-login",
3260 	.protocol = "pop3",
3261 	.type = "login",
3262 	.executable = "pop3-login",
3263 	.user = "$default_login_user",
3264 	.group = "",
3265 	.privileged_group = "",
3266 	.extra_groups = "",
3267 	.chroot = "login",
3268 
3269 	.drop_priv_before_exec = FALSE,
3270 
3271 	.process_min_avail = 0,
3272 	.process_limit = 0,
3273 	.client_limit = 0,
3274 	.service_count = 1,
3275 	.idle_kill = 0,
3276 	.vsz_limit = UOFF_T_MAX,
3277 
3278 	.unix_listeners = ARRAY_INIT,
3279 	.fifo_listeners = ARRAY_INIT,
3280 	.inet_listeners = { { &pop3_login_inet_listeners_buf,
3281 			      sizeof(pop3_login_inet_listeners[0]) } }
3282 };
3283 static const struct setting_define pop3_login_setting_defines[] = {
3284 	SETTING_DEFINE_LIST_END
3285 };
3286 static const struct setting_parser_info *pop3_login_setting_dependencies[] = {
3287 	&login_setting_parser_info,
3288 	NULL
3289 };
3290 const struct setting_parser_info pop3_login_setting_parser_info = {
3291 	.module_name = "pop3-login",
3292 	.defines = pop3_login_setting_defines,
3293 
3294 	.type_offset = SIZE_MAX,
3295 	.parent_offset = SIZE_MAX,
3296 
3297 	.dependencies = pop3_login_setting_dependencies
3298 };
3299 const struct setting_parser_info *pop3_login_setting_roots[] = {
3300 	&login_setting_parser_info,
3301 	&pop3_login_setting_parser_info,
3302 	NULL
3303 };
3304 /* ../../src/plugins/quota/quota-status-settings.c */
3305 #undef DEF
3306 #define DEF(type, name) \
3307 	SETTING_DEFINE_STRUCT_##type(#name, name, struct quota_status_settings)
3308 static const struct setting_define quota_status_setting_defines[] = {
3309 	DEF(STR, recipient_delimiter),
3310 
3311 	SETTING_DEFINE_LIST_END
3312 };
3313 static const struct quota_status_settings quota_status_default_settings = {
3314 	.recipient_delimiter = "+",
3315 };
3316 static const struct setting_parser_info *quota_status_setting_dependencies[] = {
3317 	NULL
3318 };
3319 const struct setting_parser_info quota_status_setting_parser_info = {
3320 	.module_name = "mail",
3321 	.defines = quota_status_setting_defines,
3322 	.defaults = &quota_status_default_settings,
3323 
3324 	.type_offset = SIZE_MAX,
3325 	.struct_size = sizeof(struct quota_status_settings),
3326 
3327 	.parent_offset = SIZE_MAX,
3328 	.dependencies = quota_status_setting_dependencies
3329 };
3330 /* ../../src/plugins/mail-crypt/fs-crypt-settings.c */
3331 static const struct setting_define fs_crypt_setting_defines[] = {
3332 	{ .type = SET_STRLIST, .key = "plugin",
3333 	  .offset = offsetof(struct fs_crypt_settings, plugin_envs) },
3334 
3335 	SETTING_DEFINE_LIST_END
3336 };
3337 const struct fs_crypt_settings fs_crypt_default_settings = {
3338 	.plugin_envs = ARRAY_INIT
3339 };
3340 static const struct setting_parser_info *fs_crypt_setting_dependencies[] = {
3341 	NULL
3342 };
3343 const struct setting_parser_info fs_crypt_setting_parser_info = {
3344 	.module_name = "fs-crypt",
3345 	.defines = fs_crypt_setting_defines,
3346 	.defaults = &fs_crypt_default_settings,
3347 
3348 	.type_offset = SIZE_MAX,
3349 	.struct_size = sizeof(struct fs_crypt_settings),
3350 
3351 	.parent_offset = SIZE_MAX,
3352 	.dependencies = fs_crypt_setting_dependencies
3353 };
3354 /* ../../src/old-stats/stats-settings.c */
3355 /* <settings checks> */
3356 static struct file_listener_settings old_stats_unix_listeners_array[] = {
3357 	{ "old-stats", 0600, "", "" }
3358 };
3359 static struct file_listener_settings *old_stats_unix_listeners[] = {
3360 	&old_stats_unix_listeners_array[0]
3361 };
3362 static buffer_t old_stats_unix_listeners_buf = {
3363 	{ { old_stats_unix_listeners, sizeof(old_stats_unix_listeners) } }
3364 };
3365 static struct file_listener_settings old_stats_fifo_listeners_array[] = {
3366 	{ "old-stats-mail", 0600, "", "" },
3367 	{ "old-stats-user", 0600, "", "" }
3368 };
3369 static struct file_listener_settings *old_stats_fifo_listeners[] = {
3370 	&old_stats_fifo_listeners_array[0],
3371 	&old_stats_fifo_listeners_array[1]
3372 };
3373 static buffer_t old_stats_fifo_listeners_buf = {
3374 	{ { old_stats_fifo_listeners, sizeof(old_stats_fifo_listeners) } }
3375 };
3376 /* </settings checks> */
3377 struct service_settings old_stats_service_settings = {
3378 	.name = "old-stats",
3379 	.protocol = "",
3380 	.type = "",
3381 	.executable = "old-stats",
3382 	.user = "$default_internal_user",
3383 	.group = "",
3384 	.privileged_group = "",
3385 	.extra_groups = "",
3386 	.chroot = "empty",
3387 
3388 	.drop_priv_before_exec = FALSE,
3389 
3390 	.process_min_avail = 0,
3391 	.process_limit = 1,
3392 	.client_limit = 0,
3393 	.service_count = 0,
3394 	.idle_kill = UINT_MAX,
3395 	.vsz_limit = UOFF_T_MAX,
3396 
3397 	.unix_listeners = { { &old_stats_unix_listeners_buf,
3398 			      sizeof(old_stats_unix_listeners[0]) } },
3399 	.fifo_listeners = { { &old_stats_fifo_listeners_buf,
3400 			      sizeof(old_stats_fifo_listeners[0]) } },
3401 	.inet_listeners = ARRAY_INIT,
3402 
3403 	.process_limit_1 = TRUE
3404 };
3405 #undef DEF
3406 #define DEF(type, name) \
3407 	SETTING_DEFINE_STRUCT_##type("old_stats_"#name, name, struct old_stats_settings)
3408 static const struct setting_define old_stats_setting_defines[] = {
3409 	DEF(SIZE, memory_limit),
3410 	DEF(TIME, command_min_time),
3411 	DEF(TIME, session_min_time),
3412 	DEF(TIME, user_min_time),
3413 	DEF(TIME, domain_min_time),
3414 	DEF(TIME, ip_min_time),
3415 	DEF(STR, carbon_server),
3416 	DEF(TIME, carbon_interval),
3417 	DEF(STR, carbon_name),
3418 	SETTING_DEFINE_LIST_END
3419 };
3420 const struct old_stats_settings old_stats_default_settings = {
3421 	.memory_limit = 1024*1024*16,
3422 
3423 	.command_min_time = 60,
3424 	.session_min_time = 60*15,
3425 	.user_min_time = 60*60,
3426 	.domain_min_time = 60*60*12,
3427 	.ip_min_time = 60*60*12,
3428 
3429 	.carbon_interval = 30,
3430 	.carbon_server = "",
3431 	.carbon_name = ""
3432 };
3433 const struct setting_parser_info old_stats_setting_parser_info = {
3434 	.module_name = "stats",
3435 	.defines = old_stats_setting_defines,
3436 	.defaults = &old_stats_default_settings,
3437 
3438 	.type_offset = SIZE_MAX,
3439 	.struct_size = sizeof(struct old_stats_settings),
3440 
3441 	.parent_offset = SIZE_MAX
3442 };
3443 /* ../../src/master/master-settings.c */
3444 extern const struct setting_parser_info service_setting_parser_info;
3445 extern const struct setting_parser_info service_setting_parser_info;
3446 /* <settings checks> */
3447 static void
expand_user(const char ** user,enum service_user_default * default_r,const struct master_settings * set)3448 expand_user(const char **user, enum service_user_default *default_r,
3449 	    const struct master_settings *set)
3450 {
3451 	/* $variable expansion is typically done by doveconf, but these
3452 	   variables can come from built-in settings, so we need to expand
3453 	   them here */
3454 	if (strcmp(*user, "$default_internal_user") == 0) {
3455 		*user = set->default_internal_user;
3456 		*default_r = SERVICE_USER_DEFAULT_INTERNAL;
3457 	} else if (strcmp(*user, "$default_login_user") == 0) {
3458 		*user = set->default_login_user;
3459 		*default_r = SERVICE_USER_DEFAULT_LOGIN;
3460 	} else {
3461 		*default_r = SERVICE_USER_DEFAULT_NONE;
3462 	}
3463 }
3464 
3465 static void
expand_group(const char ** group,const struct master_settings * set)3466 expand_group(const char **group, const struct master_settings *set)
3467 {
3468 	/* $variable expansion is typically done by doveconf, but these
3469 	   variables can come from built-in settings, so we need to expand
3470 	   them here */
3471 	if (strcmp(*group, "$default_internal_group") == 0)
3472 		*group = set->default_internal_group;
3473 }
3474 
3475 static bool
fix_file_listener_paths(ARRAY_TYPE (file_listener_settings)* l,pool_t pool,const struct master_settings * master_set,ARRAY_TYPE (const_string)* all_listeners,const char ** error_r)3476 fix_file_listener_paths(ARRAY_TYPE(file_listener_settings) *l,
3477 			pool_t pool, const struct master_settings *master_set,
3478 			ARRAY_TYPE(const_string) *all_listeners,
3479 			const char **error_r)
3480 {
3481 	struct file_listener_settings *set;
3482 	size_t base_dir_len = strlen(master_set->base_dir);
3483 	enum service_user_default user_default;
3484 
3485 	if (!array_is_created(l))
3486 		return TRUE;
3487 
3488 	array_foreach_elem(l, set) {
3489 		if (set->path[0] == '\0') {
3490 			*error_r = "path must not be empty";
3491 			return FALSE;
3492 		}
3493 
3494 		expand_user(&set->user, &user_default, master_set);
3495 		expand_group(&set->group, master_set);
3496 		if (*set->path != '/') {
3497 			set->path = p_strconcat(pool, master_set->base_dir, "/",
3498 						set->path, NULL);
3499 		} else if (strncmp(set->path, master_set->base_dir,
3500 				   base_dir_len) == 0 &&
3501 			   set->path[base_dir_len] == '/') {
3502 			i_warning("You should remove base_dir prefix from "
3503 				  "unix_listener: %s", set->path);
3504 		}
3505 		if (set->mode != 0)
3506 			array_push_back(all_listeners, &set->path);
3507 	}
3508 	return TRUE;
3509 }
3510 
add_inet_listeners(ARRAY_TYPE (inet_listener_settings)* l,ARRAY_TYPE (const_string)* all_listeners)3511 static void add_inet_listeners(ARRAY_TYPE(inet_listener_settings) *l,
3512 			       ARRAY_TYPE(const_string) *all_listeners)
3513 {
3514 	struct inet_listener_settings *set;
3515 	const char *str;
3516 
3517 	if (!array_is_created(l))
3518 		return;
3519 
3520 	array_foreach_elem(l, set) {
3521 		if (set->port != 0) {
3522 			str = t_strdup_printf("%u:%s", set->port, set->address);
3523 			array_push_back(all_listeners, &str);
3524 		}
3525 	}
3526 }
3527 
master_settings_parse_type(struct service_settings * set,const char ** error_r)3528 static bool master_settings_parse_type(struct service_settings *set,
3529 				       const char **error_r)
3530 {
3531 	if (*set->type == '\0')
3532 		set->parsed_type = SERVICE_TYPE_UNKNOWN;
3533 	else if (strcmp(set->type, "log") == 0)
3534 		set->parsed_type = SERVICE_TYPE_LOG;
3535 	else if (strcmp(set->type, "config") == 0)
3536 		set->parsed_type = SERVICE_TYPE_CONFIG;
3537 	else if (strcmp(set->type, "anvil") == 0)
3538 		set->parsed_type = SERVICE_TYPE_ANVIL;
3539 	else if (strcmp(set->type, "login") == 0)
3540 		set->parsed_type = SERVICE_TYPE_LOGIN;
3541 	else if (strcmp(set->type, "startup") == 0)
3542 		set->parsed_type = SERVICE_TYPE_STARTUP;
3543 	else if (strcmp(set->type, "worker") == 0)
3544 		set->parsed_type = SERVICE_TYPE_WORKER;
3545 	else {
3546 		*error_r = t_strconcat("Unknown service type: ",
3547 				       set->type, NULL);
3548 		return FALSE;
3549 	}
3550 	return TRUE;
3551 }
3552 
service_set_login_dump_core(struct service_settings * set)3553 static void service_set_login_dump_core(struct service_settings *set)
3554 {
3555 	const char *p;
3556 
3557 	if (set->parsed_type != SERVICE_TYPE_LOGIN)
3558 		return;
3559 
3560 	p = strstr(set->executable, " -D");
3561 	if (p != NULL && (p[3] == '\0' || p[3] == ' '))
3562 		set->login_dump_core = TRUE;
3563 }
3564 
3565 static bool
services_have_protocol(struct master_settings * set,const char * name)3566 services_have_protocol(struct master_settings *set, const char *name)
3567 {
3568 	struct service_settings *service;
3569 
3570 	array_foreach_elem(&set->services, service) {
3571 		if (strcmp(service->protocol, name) == 0)
3572 			return TRUE;
3573 	}
3574 	return FALSE;
3575 }
3576 
3577 #ifdef CONFIG_BINARY
3578 static const struct service_settings *
master_default_settings_get_service(const char * name)3579 master_default_settings_get_service(const char *name)
3580 {
3581 	extern struct master_settings master_default_settings;
3582 	struct service_settings *set;
3583 
3584 	array_foreach_elem(&master_default_settings.services, set) {
3585 		if (strcmp(set->name, name) == 0)
3586 			return set;
3587 	}
3588 	return NULL;
3589 }
3590 #endif
3591 
3592 static unsigned int
service_get_client_limit(struct master_settings * set,const char * name)3593 service_get_client_limit(struct master_settings *set, const char *name)
3594 {
3595 	struct service_settings *service;
3596 
3597 	array_foreach_elem(&set->services, service) {
3598 		if (strcmp(service->name, name) == 0) {
3599 			if (service->client_limit != 0)
3600 				return service->client_limit;
3601 			else
3602 				return set->default_client_limit;
3603 		}
3604 	}
3605 	return set->default_client_limit;
3606 }
3607 
3608 static bool
master_settings_verify(void * _set,pool_t pool,const char ** error_r)3609 master_settings_verify(void *_set, pool_t pool, const char **error_r)
3610 {
3611 	static bool warned_auth = FALSE, warned_anvil = FALSE;
3612 	struct master_settings *set = _set;
3613 	struct service_settings *const *services;
3614 	const char *const *strings;
3615 	ARRAY_TYPE(const_string) all_listeners;
3616 	struct passwd pw;
3617 	unsigned int i, j, count, client_limit, process_limit;
3618 	unsigned int max_auth_client_processes, max_anvil_client_processes;
3619 	string_t *max_auth_client_processes_reason = t_str_new(64);
3620 	string_t *max_anvil_client_processes_reason = t_str_new(64);
3621 	size_t len;
3622 #ifdef CONFIG_BINARY
3623 	const struct service_settings *default_service;
3624 #else
3625 	rlim_t fd_limit;
3626 	const char *max_client_limit_source = "default_client_limit";
3627 	unsigned int max_client_limit = set->default_client_limit;
3628 #endif
3629 
3630 	if (*set->listen == '\0') {
3631 		*error_r = "listen can't be set empty";
3632 		return FALSE;
3633 	}
3634 
3635 	len = strlen(set->base_dir);
3636 	if (len > 0 && set->base_dir[len-1] == '/') {
3637 		/* drop trailing '/' */
3638 		set->base_dir = p_strndup(pool, set->base_dir, len - 1);
3639 	}
3640 
3641 	if (set->last_valid_uid != 0 &&
3642 	    set->first_valid_uid > set->last_valid_uid) {
3643 		*error_r = "first_valid_uid can't be larger than last_valid_uid";
3644 		return FALSE;
3645 	}
3646 	if (set->last_valid_gid != 0 &&
3647 	    set->first_valid_gid > set->last_valid_gid) {
3648 		*error_r = "first_valid_gid can't be larger than last_valid_gid";
3649 		return FALSE;
3650 	}
3651 
3652 	if (i_getpwnam(set->default_login_user, &pw) == 0) {
3653 		*error_r = t_strdup_printf("default_login_user doesn't exist: %s",
3654 					   set->default_login_user);
3655 		return FALSE;
3656 	}
3657 	if (i_getpwnam(set->default_internal_user, &pw) == 0) {
3658 		*error_r = t_strdup_printf("default_internal_user doesn't exist: %s",
3659 					   set->default_internal_user);
3660 		return FALSE;
3661 	}
3662 
3663 	/* check that we have at least one service. the actual service
3664 	   structure validity is checked later while creating them. */
3665 	if (!array_is_created(&set->services) ||
3666 	    array_count(&set->services) == 0) {
3667 		*error_r = "No services defined";
3668 		return FALSE;
3669 	}
3670 	services = array_get(&set->services, &count);
3671 	for (i = 0; i < count; i++) {
3672 		struct service_settings *service = services[i];
3673 
3674 		if (*service->name == '\0') {
3675 			*error_r = t_strdup_printf(
3676 				"Service #%d is missing name", i);
3677 			return FALSE;
3678 		}
3679 		if (!master_settings_parse_type(service, error_r))
3680 			return FALSE;
3681 		for (j = 0; j < i; j++) {
3682 			if (strcmp(service->name, services[j]->name) == 0) {
3683 				*error_r = t_strdup_printf(
3684 					"Duplicate service name: %s",
3685 					service->name);
3686 				return FALSE;
3687 			}
3688 		}
3689 		expand_user(&service->user, &service->user_default, set);
3690 		expand_group(&service->extra_groups, set);
3691 		service_set_login_dump_core(service);
3692 	}
3693 	set->protocols_split = p_strsplit_spaces(pool, set->protocols, " ");
3694 	if (set->protocols_split[0] != NULL &&
3695 	    strcmp(set->protocols_split[0], "none") == 0 &&
3696 	    set->protocols_split[1] == NULL)
3697 		set->protocols_split[0] = NULL;
3698 
3699 	for (i = 0; set->protocols_split[i] != NULL; i++) {
3700 		if (!services_have_protocol(set, set->protocols_split[i])) {
3701 			*error_r = t_strdup_printf("protocols: "
3702 						   "Unknown protocol: %s",
3703 						   set->protocols_split[i]);
3704 			return FALSE;
3705 		}
3706 	}
3707 	t_array_init(&all_listeners, 64);
3708 	max_auth_client_processes = 0;
3709 	max_anvil_client_processes = 2; /* blocking, nonblocking pipes */
3710 	for (i = 0; i < count; i++) {
3711 		struct service_settings *service = services[i];
3712 
3713 		if (*service->protocol != '\0' &&
3714 		    !str_array_find((const char **)set->protocols_split,
3715 				    service->protocol)) {
3716 			/* protocol not enabled, ignore its settings */
3717 			continue;
3718 		}
3719 
3720 		if (*service->executable != '/' &&
3721 		    *service->executable != '\0') {
3722 			service->executable =
3723 				p_strconcat(pool, set->libexec_dir, "/",
3724 					    service->executable, NULL);
3725 		}
3726 		if (*service->chroot != '/' && *service->chroot != '\0') {
3727 			service->chroot =
3728 				p_strconcat(pool, set->base_dir, "/",
3729 					    service->chroot, NULL);
3730 		}
3731 		if (service->drop_priv_before_exec &&
3732 		    *service->chroot != '\0') {
3733 			*error_r = t_strdup_printf("service(%s): "
3734 				"drop_priv_before_exec=yes can't be "
3735 				"used with chroot", service->name);
3736 			return FALSE;
3737 		}
3738 		process_limit = service->process_limit;
3739 		if (process_limit == 0)
3740 			process_limit = set->default_process_limit;
3741 		if (service->process_min_avail > process_limit) {
3742 			*error_r = t_strdup_printf("service(%s): "
3743 				"process_min_avail is higher than process_limit",
3744 				service->name);
3745 			return FALSE;
3746 		}
3747 		if (service->vsz_limit < 1024*1024 && service->vsz_limit != 0) {
3748 			*error_r = t_strdup_printf("service(%s): "
3749 				"vsz_limit is too low", service->name);
3750 			return FALSE;
3751 		}
3752 
3753 #ifdef CONFIG_BINARY
3754 		default_service =
3755 			master_default_settings_get_service(service->name);
3756 		if (default_service != NULL &&
3757 		    default_service->process_limit_1 && process_limit > 1) {
3758 			*error_r = t_strdup_printf("service(%s): "
3759 				"process_limit must be 1", service->name);
3760 			return FALSE;
3761 		}
3762 #else
3763 		if (max_client_limit < service->client_limit) {
3764 			max_client_limit = service->client_limit;
3765 			max_client_limit_source = t_strdup_printf(
3766 				"service %s { client_limit }", service->name);
3767 		}
3768 #endif
3769 
3770 		if (*service->protocol != '\0') {
3771 			/* each imap/pop3/lmtp process can use up a connection,
3772 			   although if service_count=1 it's only temporary.
3773 			   imap-hibernate doesn't do any auth lookups. */
3774 			if ((service->service_count != 1 ||
3775 			     strcmp(service->type, "login") == 0) &&
3776 			    strcmp(service->name, "imap-hibernate") != 0) {
3777 				str_printfa(max_auth_client_processes_reason,
3778 					    " + service %s { process_limit=%u }",
3779 					    service->name, process_limit);
3780 				max_auth_client_processes += process_limit;
3781 			}
3782 		}
3783 		if (strcmp(service->type, "login") == 0 ||
3784 		    strcmp(service->name, "auth") == 0) {
3785 			max_anvil_client_processes += process_limit;
3786 			str_printfa(max_anvil_client_processes_reason,
3787 				    " + service %s { process_limit=%u }",
3788 				    service->name, process_limit);
3789 		}
3790 
3791 		if (!fix_file_listener_paths(&service->unix_listeners, pool,
3792 					     set, &all_listeners, error_r)) {
3793 			*error_r = t_strdup_printf("service(%s): unix_listener: %s",
3794 						   service->name, *error_r);
3795 			return FALSE;
3796 		}
3797 		if (!fix_file_listener_paths(&service->fifo_listeners, pool,
3798 					     set, &all_listeners, error_r)) {
3799 			*error_r = t_strdup_printf("service(%s): fifo_listener: %s",
3800 						   service->name, *error_r);
3801 			return FALSE;
3802 		}
3803 		add_inet_listeners(&service->inet_listeners, &all_listeners);
3804 	}
3805 
3806 	client_limit = service_get_client_limit(set, "auth");
3807 	if (client_limit < max_auth_client_processes && !warned_auth) {
3808 		warned_auth = TRUE;
3809 		str_delete(max_auth_client_processes_reason, 0, 3);
3810 		i_warning("service auth { client_limit=%u } is lower than "
3811 			  "required under max. load (%u). "
3812 			  "Counted for protocol services with service_count != 1: %s",
3813 			  client_limit, max_auth_client_processes,
3814 			  str_c(max_auth_client_processes_reason));
3815 	}
3816 
3817 	client_limit = service_get_client_limit(set, "anvil");
3818 	if (client_limit < max_anvil_client_processes && !warned_anvil) {
3819 		warned_anvil = TRUE;
3820 		str_delete(max_anvil_client_processes_reason, 0, 3);
3821 		i_warning("service anvil { client_limit=%u } is lower than "
3822 			  "required under max. load (%u). Counted with: %s",
3823 			  client_limit, max_anvil_client_processes,
3824 			  str_c(max_anvil_client_processes_reason));
3825 	}
3826 #ifndef CONFIG_BINARY
3827 	if (restrict_get_fd_limit(&fd_limit) == 0 &&
3828 	    fd_limit < (rlim_t)max_client_limit) {
3829 		i_warning("fd limit (ulimit -n) is lower than required "
3830 			  "under max. load (%u < %u), because of %s",
3831 			  (unsigned int)fd_limit, max_client_limit,
3832 			  max_client_limit_source);
3833 	}
3834 #endif
3835 
3836 	/* check for duplicate listeners */
3837 	array_sort(&all_listeners, i_strcmp_p);
3838 	strings = array_get(&all_listeners, &count);
3839 	for (i = 1; i < count; i++) {
3840 		if (strcmp(strings[i-1], strings[i]) == 0) {
3841 			*error_r = t_strdup_printf("duplicate listener: %s",
3842 						   strings[i]);
3843 			return FALSE;
3844 		}
3845 	}
3846 	return TRUE;
3847 }
3848 /* </settings checks> */
3849 #undef DEF
3850 #define DEF(type, name) \
3851 	SETTING_DEFINE_STRUCT_##type(#name, name, struct file_listener_settings)
3852 static const struct setting_define file_listener_setting_defines[] = {
3853 	DEF(STR, path),
3854 	DEF(UINT_OCT, mode),
3855 	DEF(STR, user),
3856 	DEF(STR, group),
3857 
3858 	SETTING_DEFINE_LIST_END
3859 };
3860 static const struct file_listener_settings file_listener_default_settings = {
3861 	.path = "",
3862 	.mode = 0600,
3863 	.user = "",
3864 	.group = "",
3865 };
3866 static const struct setting_parser_info file_listener_setting_parser_info = {
3867 	.defines = file_listener_setting_defines,
3868 	.defaults = &file_listener_default_settings,
3869 
3870 	.type_offset = offsetof(struct file_listener_settings, path),
3871 	.struct_size = sizeof(struct file_listener_settings),
3872 
3873 	.parent_offset = SIZE_MAX,
3874 	.parent = &service_setting_parser_info
3875 };
3876 #undef DEF
3877 #define DEF(type, name) \
3878 	SETTING_DEFINE_STRUCT_##type(#name, name, struct inet_listener_settings)
3879 static const struct setting_define inet_listener_setting_defines[] = {
3880 	DEF(STR, name),
3881 	DEF(STR, address),
3882 	DEF(IN_PORT, port),
3883 	DEF(BOOL, ssl),
3884 	DEF(BOOL, reuse_port),
3885 	DEF(BOOL, haproxy),
3886 
3887 	SETTING_DEFINE_LIST_END
3888 };
3889 static const struct inet_listener_settings inet_listener_default_settings = {
3890 	.name = "",
3891 	.address = "",
3892 	.port = 0,
3893 	.ssl = FALSE,
3894 	.reuse_port = FALSE,
3895 	.haproxy = FALSE
3896 };
3897 static const struct setting_parser_info inet_listener_setting_parser_info = {
3898 	.defines = inet_listener_setting_defines,
3899 	.defaults = &inet_listener_default_settings,
3900 
3901 	.type_offset = offsetof(struct inet_listener_settings, name),
3902 	.struct_size = sizeof(struct inet_listener_settings),
3903 
3904 	.parent_offset = SIZE_MAX,
3905 	.parent = &service_setting_parser_info
3906 };
3907 #undef DEF
3908 #undef DEFLIST_UNIQUE
3909 #define DEF(type, name) \
3910 	SETTING_DEFINE_STRUCT_##type(#name, name, struct service_settings)
3911 #define DEFLIST_UNIQUE(field, name, defines) \
3912 	{ .type = SET_DEFLIST_UNIQUE, .key = name, \
3913 	  .offset = offsetof(struct service_settings, field), \
3914 	  .list_info = defines }
3915 static const struct setting_define service_setting_defines[] = {
3916 	DEF(STR, name),
3917 	DEF(STR, protocol),
3918 	DEF(STR, type),
3919 	DEF(STR, executable),
3920 	DEF(STR, user),
3921 	DEF(STR, group),
3922 	DEF(STR, privileged_group),
3923 	DEF(STR, extra_groups),
3924 	DEF(STR, chroot),
3925 
3926 	DEF(BOOL, drop_priv_before_exec),
3927 
3928 	DEF(UINT, process_min_avail),
3929 	DEF(UINT, process_limit),
3930 	DEF(UINT, client_limit),
3931 	DEF(UINT, service_count),
3932 	DEF(TIME, idle_kill),
3933 	DEF(SIZE, vsz_limit),
3934 
3935 	DEFLIST_UNIQUE(unix_listeners, "unix_listener",
3936 		       &file_listener_setting_parser_info),
3937 	DEFLIST_UNIQUE(fifo_listeners, "fifo_listener",
3938 		       &file_listener_setting_parser_info),
3939 	DEFLIST_UNIQUE(inet_listeners, "inet_listener",
3940 		       &inet_listener_setting_parser_info),
3941 
3942 	SETTING_DEFINE_LIST_END
3943 };
3944 static const struct service_settings service_default_settings = {
3945 	.name = "",
3946 	.protocol = "",
3947 	.type = "",
3948 	.executable = "",
3949 	.user = "",
3950 	.group = "",
3951 	.privileged_group = "",
3952 	.extra_groups = "",
3953 	.chroot = "",
3954 
3955 	.drop_priv_before_exec = FALSE,
3956 
3957 	.process_min_avail = 0,
3958 	.process_limit = 0,
3959 	.client_limit = 0,
3960 	.service_count = 0,
3961 	.idle_kill = 0,
3962 	.vsz_limit = UOFF_T_MAX,
3963 
3964 	.unix_listeners = ARRAY_INIT,
3965 	.fifo_listeners = ARRAY_INIT,
3966 	.inet_listeners = ARRAY_INIT
3967 };
3968 const struct setting_parser_info service_setting_parser_info = {
3969 	.defines = service_setting_defines,
3970 	.defaults = &service_default_settings,
3971 
3972 	.type_offset = offsetof(struct service_settings, name),
3973 	.struct_size = sizeof(struct service_settings),
3974 
3975 	.parent_offset = offsetof(struct service_settings, master_set),
3976 	.parent = &master_setting_parser_info
3977 };
3978 #undef DEF
3979 #undef DEFLIST_UNIQUE
3980 #define DEF(type, name) \
3981 	SETTING_DEFINE_STRUCT_##type(#name, name, struct master_settings)
3982 #define DEFLIST_UNIQUE(field, name, defines) \
3983 	{ .type = SET_DEFLIST_UNIQUE, .key = name, \
3984 	  .offset = offsetof(struct master_settings, field), \
3985 	  .list_info = defines }
3986 static const struct setting_define master_setting_defines[] = {
3987 	DEF(STR, base_dir),
3988 	DEF(STR, state_dir),
3989 	DEF(STR, libexec_dir),
3990 	DEF(STR, instance_name),
3991 	DEF(STR, protocols),
3992 	DEF(STR, listen),
3993 	DEF(ENUM, ssl),
3994 	DEF(STR, default_internal_user),
3995 	DEF(STR, default_internal_group),
3996 	DEF(STR, default_login_user),
3997 	DEF(UINT, default_process_limit),
3998 	DEF(UINT, default_client_limit),
3999 	DEF(TIME, default_idle_kill),
4000 	DEF(SIZE, default_vsz_limit),
4001 
4002 	DEF(BOOL, version_ignore),
4003 
4004 	DEF(UINT, first_valid_uid),
4005 	DEF(UINT, last_valid_uid),
4006 	DEF(UINT, first_valid_gid),
4007 	DEF(UINT, last_valid_gid),
4008 
4009 	DEFLIST_UNIQUE(services, "service", &service_setting_parser_info),
4010 
4011 	SETTING_DEFINE_LIST_END
4012 };
4013 struct master_settings master_default_settings = {
4014 	.base_dir = PKG_RUNDIR,
4015 	.state_dir = PKG_STATEDIR,
4016 	.libexec_dir = PKG_LIBEXECDIR,
4017 	.instance_name = PACKAGE,
4018 	.protocols = "imap pop3 lmtp",
4019 	.listen = "*, ::",
4020 	.ssl = "yes:no:required",
4021 	.default_internal_user = "dovecot",
4022 	.default_internal_group = "dovecot",
4023 	.default_login_user = "dovenull",
4024 	.default_process_limit = 100,
4025 	.default_client_limit = 1000,
4026 	.default_idle_kill = 60,
4027 	.default_vsz_limit = 256*1024*1024,
4028 
4029 	.version_ignore = FALSE,
4030 
4031 	.first_valid_uid = 500,
4032 	.last_valid_uid = 0,
4033 	.first_valid_gid = 1,
4034 	.last_valid_gid = 0,
4035 
4036 #ifndef CONFIG_BINARY
4037 	.services = ARRAY_INIT
4038 #else
4039 	.services = { { &config_all_services_buf,
4040 			     sizeof(struct service_settings *) } },
4041 #endif
4042 };
4043 const struct setting_parser_info master_setting_parser_info = {
4044 	.module_name = "master",
4045 	.defines = master_setting_defines,
4046 	.defaults = &master_default_settings,
4047 
4048 	.type_offset = SIZE_MAX,
4049 	.struct_size = sizeof(struct master_settings),
4050 
4051 	.parent_offset = SIZE_MAX,
4052 
4053 	.check_func = master_settings_verify
4054 };
4055 /* ../../src/login-common/login-settings.c */
4056 /* <settings checks> */
login_settings_check(void * _set,pool_t pool,const char ** error_r ATTR_UNUSED)4057 static bool login_settings_check(void *_set, pool_t pool,
4058 				 const char **error_r ATTR_UNUSED)
4059 {
4060 	struct login_settings *set = _set;
4061 
4062 	set->log_format_elements_split =
4063 		p_strsplit(pool, set->login_log_format_elements, " ");
4064 
4065 	if (set->auth_debug_passwords)
4066 		set->auth_debug = TRUE;
4067 	if (set->auth_debug)
4068 		set->auth_verbose = TRUE;
4069 	return TRUE;
4070 }
4071 /* </settings checks> */
4072 #undef DEF
4073 #define DEF(type, name) \
4074 	SETTING_DEFINE_STRUCT_##type(#name, name, struct login_settings)
4075 static const struct setting_define login_setting_defines[] = {
4076 	DEF(STR, login_trusted_networks),
4077 	DEF(STR, login_source_ips),
4078 	DEF(STR_VARS, login_greeting),
4079 	DEF(STR, login_log_format_elements),
4080 	DEF(STR, login_log_format),
4081 	DEF(STR, login_access_sockets),
4082 	DEF(STR_VARS, login_proxy_notify_path),
4083 	DEF(STR, login_plugin_dir),
4084 	DEF(STR, login_plugins),
4085 	DEF(TIME_MSECS, login_proxy_timeout),
4086 	DEF(UINT, login_proxy_max_reconnects),
4087 	DEF(TIME, login_proxy_max_disconnect_delay),
4088 	DEF(STR, login_proxy_rawlog_dir),
4089 	DEF(STR, director_username_hash),
4090 
4091 	DEF(BOOL, auth_ssl_require_client_cert),
4092 	DEF(BOOL, auth_ssl_username_from_cert),
4093 
4094 	DEF(BOOL, disable_plaintext_auth),
4095 	DEF(BOOL, auth_verbose),
4096 	DEF(BOOL, auth_debug),
4097 	DEF(BOOL, verbose_proctitle),
4098 
4099 	DEF(UINT, mail_max_userip_connections),
4100 
4101 	SETTING_DEFINE_LIST_END
4102 };
4103 static const struct login_settings login_default_settings = {
4104 	.login_trusted_networks = "",
4105 	.login_source_ips = "",
4106 	.login_greeting = PACKAGE_NAME" ready.",
4107 	.login_log_format_elements = "user=<%u> method=%m rip=%r lip=%l mpid=%e %c session=<%{session}>",
4108 	.login_log_format = "%$: %s",
4109 	.login_access_sockets = "",
4110 	.login_proxy_notify_path = "proxy-notify",
4111 	.login_plugin_dir = MODULEDIR"/login",
4112 	.login_plugins = "",
4113 	.login_proxy_timeout = 30*1000,
4114 	.login_proxy_max_reconnects = 3,
4115 	.login_proxy_max_disconnect_delay = 0,
4116 	.login_proxy_rawlog_dir = "",
4117 	.director_username_hash = "%u",
4118 
4119 	.auth_ssl_require_client_cert = FALSE,
4120 	.auth_ssl_username_from_cert = FALSE,
4121 
4122 	.disable_plaintext_auth = TRUE,
4123 	.auth_verbose = FALSE,
4124 	.auth_debug = FALSE,
4125 	.verbose_proctitle = FALSE,
4126 
4127 	.mail_max_userip_connections = 10
4128 };
4129 const struct setting_parser_info login_setting_parser_info = {
4130 	.module_name = "login",
4131 	.defines = login_setting_defines,
4132 	.defaults = &login_default_settings,
4133 
4134 	.type_offset = SIZE_MAX,
4135 	.struct_size = sizeof(struct login_settings),
4136 
4137 	.parent_offset = SIZE_MAX,
4138 
4139 	.check_func = login_settings_check
4140 };
4141 /* ../../src/log/log-settings.c */
4142 /* <settings checks> */
4143 static struct file_listener_settings log_unix_listeners_array[] = {
4144 	{ "log-errors", 0600, "", "" }
4145 };
4146 static struct file_listener_settings *log_unix_listeners[] = {
4147 	&log_unix_listeners_array[0]
4148 };
4149 static buffer_t log_unix_listeners_buf = {
4150 	{ { log_unix_listeners, sizeof(log_unix_listeners) } }
4151 };
4152 /* </settings checks> */
4153 struct service_settings log_service_settings = {
4154 	.name = "log",
4155 	.protocol = "",
4156 	.type = "log",
4157 	.executable = "log",
4158 	.user = "",
4159 	.group = "",
4160 	.privileged_group = "",
4161 	.extra_groups = "",
4162 	.chroot = "",
4163 
4164 	.drop_priv_before_exec = FALSE,
4165 
4166 	.process_min_avail = 0,
4167 	.process_limit = 1,
4168 	.client_limit = 0,
4169 	.service_count = 0,
4170 	.idle_kill = UINT_MAX,
4171 	.vsz_limit = UOFF_T_MAX,
4172 
4173 	.unix_listeners = { { &log_unix_listeners_buf,
4174 			      sizeof(log_unix_listeners[0]) } },
4175 	.fifo_listeners = ARRAY_INIT,
4176 	.inet_listeners = ARRAY_INIT,
4177 
4178 	.process_limit_1 = TRUE
4179 };
4180 /* ../../src/lmtp/lmtp-settings.c */
4181 /* <settings checks> */
4182 static struct file_listener_settings lmtp_unix_listeners_array[] = {
4183 	{ "lmtp", 0666, "", "" }
4184 };
4185 static struct file_listener_settings *lmtp_unix_listeners[] = {
4186 	&lmtp_unix_listeners_array[0]
4187 };
4188 static buffer_t lmtp_unix_listeners_buf = {
4189 	{ { lmtp_unix_listeners, sizeof(lmtp_unix_listeners) } }
4190 };
4191 /* </settings checks> */
4192 /* <settings checks> */
4193 struct lmtp_client_workaround_list {
4194 	const char *name;
4195 	enum lmtp_client_workarounds num;
4196 };
4197 
4198 static const struct lmtp_client_workaround_list
4199 lmtp_client_workaround_list[] = {
4200 	{ "whitespace-before-path", LMTP_WORKAROUND_WHITESPACE_BEFORE_PATH },
4201 	{ "mailbox-for-path", LMTP_WORKAROUND_MAILBOX_FOR_PATH },
4202 	{ NULL, 0 }
4203 };
4204 
4205 static int
lmtp_settings_parse_workarounds(struct lmtp_settings * set,const char ** error_r)4206 lmtp_settings_parse_workarounds(struct lmtp_settings *set,
4207 				const char **error_r)
4208 {
4209 	enum lmtp_client_workarounds client_workarounds = 0;
4210         const struct lmtp_client_workaround_list *list;
4211 	const char *const *str;
4212 
4213         str = t_strsplit_spaces(set->lmtp_client_workarounds, " ,");
4214 	for (; *str != NULL; str++) {
4215 		list = lmtp_client_workaround_list;
4216 		for (; list->name != NULL; list++) {
4217 			if (strcasecmp(*str, list->name) == 0) {
4218 				client_workarounds |= list->num;
4219 				break;
4220 			}
4221 		}
4222 		if (list->name == NULL) {
4223 			*error_r = t_strdup_printf(
4224 				"lmtp_client_workarounds: "
4225 				"Unknown workaround: %s", *str);
4226 			return -1;
4227 		}
4228 	}
4229 	set->parsed_workarounds = client_workarounds;
4230 	return 0;
4231 }
4232 
lmtp_settings_check(void * _set,pool_t pool ATTR_UNUSED,const char ** error_r)4233 static bool lmtp_settings_check(void *_set, pool_t pool ATTR_UNUSED,
4234 				const char **error_r)
4235 {
4236 	struct lmtp_settings *set = _set;
4237 
4238 	if (lmtp_settings_parse_workarounds(set, error_r) < 0)
4239 		return FALSE;
4240 
4241 	if (strcmp(set->lmtp_hdr_delivery_address, "none") == 0) {
4242 		set->parsed_lmtp_hdr_delivery_address =
4243 			LMTP_HDR_DELIVERY_ADDRESS_NONE;
4244 	} else if (strcmp(set->lmtp_hdr_delivery_address, "final") == 0) {
4245 		set->parsed_lmtp_hdr_delivery_address =
4246 			LMTP_HDR_DELIVERY_ADDRESS_FINAL;
4247 	} else if (strcmp(set->lmtp_hdr_delivery_address, "original") == 0) {
4248 		set->parsed_lmtp_hdr_delivery_address =
4249 			LMTP_HDR_DELIVERY_ADDRESS_ORIGINAL;
4250 	} else {
4251 		*error_r = t_strdup_printf("Unknown lmtp_hdr_delivery_address: %s",
4252 					   set->lmtp_hdr_delivery_address);
4253 		return FALSE;
4254 	}
4255 	return TRUE;
4256 }
4257 /* </settings checks> */
4258 struct service_settings lmtp_service_settings = {
4259 	.name = "lmtp",
4260 	.protocol = "lmtp",
4261 	.type = "",
4262 	.executable = "lmtp",
4263 	.user = "",
4264 	.group = "",
4265 	.privileged_group = "",
4266 	.extra_groups = "$default_internal_group",
4267 	.chroot = "",
4268 
4269 	.drop_priv_before_exec = FALSE,
4270 
4271 	.process_min_avail = 0,
4272 	.process_limit = 0,
4273 	.client_limit = 1,
4274 	.service_count = 0,
4275 	.idle_kill = 0,
4276 	.vsz_limit = UOFF_T_MAX,
4277 
4278 	.unix_listeners = { { &lmtp_unix_listeners_buf,
4279 			      sizeof(lmtp_unix_listeners[0]) } },
4280 	.fifo_listeners = ARRAY_INIT,
4281 	.inet_listeners = ARRAY_INIT
4282 };
4283 #undef DEF
4284 #define DEF(type, name) \
4285 	SETTING_DEFINE_STRUCT_##type(#name, name, struct lmtp_settings)
4286 static const struct setting_define lmtp_setting_defines[] = {
4287 	DEF(BOOL, lmtp_proxy),
4288 	DEF(BOOL, lmtp_save_to_detail_mailbox),
4289 	DEF(BOOL, lmtp_rcpt_check_quota),
4290 	DEF(BOOL, lmtp_add_received_header),
4291 	DEF(UINT, lmtp_user_concurrency_limit),
4292 	DEF(ENUM, lmtp_hdr_delivery_address),
4293 	DEF(STR_VARS, lmtp_rawlog_dir),
4294 	DEF(STR_VARS, lmtp_proxy_rawlog_dir),
4295 
4296 	DEF(STR, lmtp_client_workarounds),
4297 
4298 	DEF(STR_VARS, login_greeting),
4299 	DEF(STR, login_trusted_networks),
4300 
4301 	DEF(STR, mail_plugins),
4302 	DEF(STR, mail_plugin_dir),
4303 
4304 	SETTING_DEFINE_LIST_END
4305 };
4306 static const struct lmtp_settings lmtp_default_settings = {
4307 	.lmtp_proxy = FALSE,
4308 	.lmtp_save_to_detail_mailbox = FALSE,
4309 	.lmtp_rcpt_check_quota = FALSE,
4310 	.lmtp_add_received_header = TRUE,
4311 	.lmtp_user_concurrency_limit = 0,
4312 	.lmtp_hdr_delivery_address = "final:none:original",
4313 	.lmtp_rawlog_dir = "",
4314 	.lmtp_proxy_rawlog_dir = "",
4315 
4316 	.lmtp_client_workarounds = "",
4317 
4318 	.login_greeting = PACKAGE_NAME" ready.",
4319 	.login_trusted_networks = "",
4320 
4321 	.mail_plugins = "",
4322 	.mail_plugin_dir = MODULEDIR,
4323 };
4324 static const struct setting_parser_info *lmtp_setting_dependencies[] = {
4325 	&lda_setting_parser_info,
4326 	NULL
4327 };
4328 const struct setting_parser_info lmtp_setting_parser_info = {
4329 	.module_name = "lmtp",
4330 	.defines = lmtp_setting_defines,
4331 	.defaults = &lmtp_default_settings,
4332 
4333 	.type_offset = SIZE_MAX,
4334 	.struct_size = sizeof(struct lmtp_settings),
4335 
4336 	.parent_offset = SIZE_MAX,
4337 
4338 	.check_func = lmtp_settings_check,
4339 	.dependencies = lmtp_setting_dependencies
4340 };
4341 /* ../../src/ipc/ipc-settings.c */
4342 /* <settings checks> */
4343 static struct file_listener_settings ipc_unix_listeners_array[] = {
4344 	{ "ipc", 0600, "$default_internal_user", "" },
4345 	{ "login/ipc-proxy", 0600, "$default_login_user", "" }
4346 };
4347 static struct file_listener_settings *ipc_unix_listeners[] = {
4348 	&ipc_unix_listeners_array[0],
4349 	&ipc_unix_listeners_array[1]
4350 };
4351 static buffer_t ipc_unix_listeners_buf = {
4352 	{ { ipc_unix_listeners, sizeof(ipc_unix_listeners) } }
4353 };
4354 /* </settings checks> */
4355 struct service_settings ipc_service_settings = {
4356 	.name = "ipc",
4357 	.protocol = "",
4358 	.type = "",
4359 	.executable = "ipc",
4360 	.user = "$default_internal_user",
4361 	.group = "",
4362 	.privileged_group = "",
4363 	.extra_groups = "",
4364 	.chroot = "empty",
4365 
4366 	.drop_priv_before_exec = FALSE,
4367 
4368 	.process_min_avail = 0,
4369 	.process_limit = 1,
4370 	.client_limit = 0,
4371 	.service_count = 0,
4372 	.idle_kill = 0,
4373 	.vsz_limit = UOFF_T_MAX,
4374 
4375 	.unix_listeners = { { &ipc_unix_listeners_buf,
4376 			      sizeof(ipc_unix_listeners[0]) } },
4377 	.fifo_listeners = ARRAY_INIT,
4378 	.inet_listeners = ARRAY_INIT,
4379 
4380 	.process_limit_1 = TRUE
4381 };
4382 /* ../../src/indexer/indexer-worker-settings.c */
4383 /* <settings checks> */
4384 static struct file_listener_settings indexer_worker_unix_listeners_array[] = {
4385 	{ "indexer-worker", 0600, "$default_internal_user", "" }
4386 };
4387 static struct file_listener_settings *indexer_worker_unix_listeners[] = {
4388 	&indexer_worker_unix_listeners_array[0]
4389 };
4390 static buffer_t indexer_worker_unix_listeners_buf = {
4391 	{ { indexer_worker_unix_listeners, sizeof(indexer_worker_unix_listeners) } }
4392 };
4393 /* </settings checks> */
4394 struct service_settings indexer_worker_service_settings = {
4395 	.name = "indexer-worker",
4396 	.protocol = "",
4397 	.type = "worker",
4398 	.executable = "indexer-worker",
4399 	.user = "",
4400 	.group = "",
4401 	.privileged_group = "",
4402 	.extra_groups = "$default_internal_group",
4403 	.chroot = "",
4404 
4405 	.drop_priv_before_exec = FALSE,
4406 
4407 	.process_min_avail = 0,
4408 	.process_limit = 10,
4409 	.client_limit = 1,
4410 	.service_count = 0,
4411 	.idle_kill = 0,
4412 	.vsz_limit = UOFF_T_MAX,
4413 
4414 	.unix_listeners = { { &indexer_worker_unix_listeners_buf,
4415 			      sizeof(indexer_worker_unix_listeners[0]) } },
4416 	.fifo_listeners = ARRAY_INIT,
4417 	.inet_listeners = ARRAY_INIT
4418 };
4419 /* ../../src/indexer/indexer-settings.c */
4420 extern const struct setting_parser_info service_setting_parser_info;
4421 /* <settings checks> */
4422 static struct file_listener_settings indexer_unix_listeners_array[] = {
4423 	{ "indexer", 0666, "", "" }
4424 };
4425 static struct file_listener_settings *indexer_unix_listeners[] = {
4426 	&indexer_unix_listeners_array[0]
4427 };
4428 static buffer_t indexer_unix_listeners_buf = {
4429 	{ { indexer_unix_listeners, sizeof(indexer_unix_listeners) } }
4430 };
4431 /* </settings checks> */
4432 struct service_settings indexer_service_settings = {
4433 	.name = "indexer",
4434 	.protocol = "",
4435 	.type = "",
4436 	.executable = "indexer",
4437 	.user = "$default_internal_user",
4438 	.group = "",
4439 	.privileged_group = "",
4440 	.extra_groups = "",
4441 	.chroot = "",
4442 
4443 	.drop_priv_before_exec = FALSE,
4444 
4445 	.process_min_avail = 0,
4446 	.process_limit = 1,
4447 	.client_limit = 0,
4448 	.service_count = 0,
4449 	.idle_kill = 0,
4450 	.vsz_limit = UOFF_T_MAX,
4451 
4452 	.unix_listeners = { { &indexer_unix_listeners_buf,
4453 			      sizeof(indexer_unix_listeners[0]) } },
4454 	.fifo_listeners = ARRAY_INIT,
4455 	.inet_listeners = ARRAY_INIT,
4456 
4457 	.process_limit_1 = TRUE
4458 };
4459 /* ../../src/imap/imap-settings.c */
4460 /* <settings checks> */
4461 static struct file_listener_settings imap_unix_listeners_array[] = {
4462 	{ "login/imap", 0666, "", "" },
4463 	{ "imap-master", 0600, "", "" }
4464 };
4465 static struct file_listener_settings *imap_unix_listeners[] = {
4466 	&imap_unix_listeners_array[0],
4467 	&imap_unix_listeners_array[1]
4468 };
4469 static buffer_t imap_unix_listeners_buf = {
4470 	{ { imap_unix_listeners, sizeof(imap_unix_listeners) } }
4471 };
4472 /* </settings checks> */
4473 /* <settings checks> */
4474 struct imap_client_workaround_list {
4475 	const char *name;
4476 	enum imap_client_workarounds num;
4477 };
4478 
4479 static const struct imap_client_workaround_list imap_client_workaround_list[] = {
4480 	{ "delay-newmail", WORKAROUND_DELAY_NEWMAIL },
4481 	{ "tb-extra-mailbox-sep", WORKAROUND_TB_EXTRA_MAILBOX_SEP },
4482 	{ "tb-lsub-flags", WORKAROUND_TB_LSUB_FLAGS },
4483 	{ NULL, 0 }
4484 };
4485 
4486 static int
imap_settings_parse_workarounds(struct imap_settings * set,const char ** error_r)4487 imap_settings_parse_workarounds(struct imap_settings *set,
4488 				const char **error_r)
4489 {
4490         enum imap_client_workarounds client_workarounds = 0;
4491         const struct imap_client_workaround_list *list;
4492 	const char *const *str;
4493 
4494         str = t_strsplit_spaces(set->imap_client_workarounds, " ,");
4495 	for (; *str != NULL; str++) {
4496 		list = imap_client_workaround_list;
4497 		for (; list->name != NULL; list++) {
4498 			if (strcasecmp(*str, list->name) == 0) {
4499 				client_workarounds |= list->num;
4500 				break;
4501 			}
4502 		}
4503 		if (list->name == NULL) {
4504 			*error_r = t_strdup_printf("imap_client_workarounds: "
4505 				"Unknown workaround: %s", *str);
4506 			return -1;
4507 		}
4508 	}
4509 	set->parsed_workarounds = client_workarounds;
4510 	return 0;
4511 }
4512 
4513 
4514 static bool
imap_settings_verify(void * _set,pool_t pool ATTR_UNUSED,const char ** error_r)4515 imap_settings_verify(void *_set, pool_t pool ATTR_UNUSED, const char **error_r)
4516 {
4517 	struct imap_settings *set = _set;
4518 
4519 	if (imap_settings_parse_workarounds(set, error_r) < 0)
4520 		return FALSE;
4521 
4522 	if (strcmp(set->imap_fetch_failure, "disconnect-immediately") == 0)
4523 		set->parsed_fetch_failure = IMAP_CLIENT_FETCH_FAILURE_DISCONNECT_IMMEDIATELY;
4524 	else if (strcmp(set->imap_fetch_failure, "disconnect-after") == 0)
4525 		set->parsed_fetch_failure = IMAP_CLIENT_FETCH_FAILURE_DISCONNECT_AFTER;
4526 	else if (strcmp(set->imap_fetch_failure, "no-after") == 0)
4527 		set->parsed_fetch_failure = IMAP_CLIENT_FETCH_FAILURE_NO_AFTER;
4528 	else {
4529 		*error_r = t_strdup_printf("Unknown imap_fetch_failure: %s",
4530 					   set->imap_fetch_failure);
4531 		return FALSE;
4532 	}
4533 	return TRUE;
4534 }
4535 /* </settings checks> */
4536 struct service_settings imap_service_settings = {
4537 	.name = "imap",
4538 	.protocol = "imap",
4539 	.type = "",
4540 	.executable = "imap",
4541 	.user = "",
4542 	.group = "",
4543 	.privileged_group = "",
4544 	.extra_groups = "$default_internal_group",
4545 	.chroot = "",
4546 
4547 	.drop_priv_before_exec = FALSE,
4548 
4549 	.process_min_avail = 0,
4550 	.process_limit = 1024,
4551 	.client_limit = 1,
4552 	.service_count = 1,
4553 	.idle_kill = 0,
4554 	.vsz_limit = UOFF_T_MAX,
4555 
4556 	.unix_listeners = { { &imap_unix_listeners_buf,
4557 			      sizeof(imap_unix_listeners[0]) } },
4558 	.fifo_listeners = ARRAY_INIT,
4559 	.inet_listeners = ARRAY_INIT
4560 };
4561 #undef DEF
4562 #undef DEFLIST
4563 #define DEF(type, name) \
4564 	SETTING_DEFINE_STRUCT_##type(#name, name, struct imap_settings)
4565 #define DEFLIST(field, name, defines) \
4566 	{ .type = SET_DEFLIST, .key = name, \
4567 	  .offset = offsetof(struct imap_settings, field), \
4568 	  .list_info = defines }
4569 static const struct setting_define imap_setting_defines[] = {
4570 	DEF(BOOL, verbose_proctitle),
4571 	DEF(STR_VARS, rawlog_dir),
4572 
4573 	DEF(SIZE, imap_max_line_length),
4574 	DEF(TIME, imap_idle_notify_interval),
4575 	DEF(STR, imap_capability),
4576 	DEF(STR, imap_client_workarounds),
4577 	DEF(STR, imap_logout_format),
4578 	DEF(STR, imap_id_send),
4579 	DEF(STR, imap_id_log),
4580 	DEF(ENUM, imap_fetch_failure),
4581 	DEF(BOOL, imap_metadata),
4582 	DEF(BOOL, imap_literal_minus),
4583 	DEF(TIME, imap_hibernate_timeout),
4584 
4585 	DEF(STR, imap_urlauth_host),
4586 	DEF(IN_PORT, imap_urlauth_port),
4587 
4588 	SETTING_DEFINE_LIST_END
4589 };
4590 static const struct imap_settings imap_default_settings = {
4591 	.verbose_proctitle = FALSE,
4592 	.rawlog_dir = "",
4593 
4594 	/* RFC-2683 recommends at least 8000 bytes. Some clients however don't
4595 	   break large message sets to multiple commands, so we're pretty
4596 	   liberal by default. */
4597 	.imap_max_line_length = 64*1024,
4598 	.imap_idle_notify_interval = 2*60,
4599 	.imap_capability = "",
4600 	.imap_client_workarounds = "",
4601 	.imap_logout_format = "in=%i out=%o deleted=%{deleted} "
4602 		"expunged=%{expunged} trashed=%{trashed} "
4603 		"hdr_count=%{fetch_hdr_count} hdr_bytes=%{fetch_hdr_bytes} "
4604 		"body_count=%{fetch_body_count} body_bytes=%{fetch_body_bytes}",
4605 	.imap_id_send = "name *",
4606 	.imap_id_log = "",
4607 	.imap_fetch_failure = "disconnect-immediately:disconnect-after:no-after",
4608 	.imap_metadata = FALSE,
4609 	.imap_literal_minus = FALSE,
4610 	.imap_hibernate_timeout = 0,
4611 
4612 	.imap_urlauth_host = "",
4613 	.imap_urlauth_port = 143
4614 };
4615 static const struct setting_parser_info *imap_setting_dependencies[] = {
4616 	&mail_user_setting_parser_info,
4617 	&smtp_submit_setting_parser_info,
4618 	NULL
4619 };
4620 const struct setting_parser_info imap_setting_parser_info = {
4621 	.module_name = "imap",
4622 	.defines = imap_setting_defines,
4623 	.defaults = &imap_default_settings,
4624 
4625 	.type_offset = SIZE_MAX,
4626 	.struct_size = sizeof(struct imap_settings),
4627 
4628 	.parent_offset = SIZE_MAX,
4629 
4630 	.check_func = imap_settings_verify,
4631 	.dependencies = imap_setting_dependencies
4632 };
4633 /* ../../src/imap-urlauth/imap-urlauth-worker-settings.c */
4634 /* <settings checks> */
4635 static struct file_listener_settings imap_urlauth_worker_unix_listeners_array[] = {
4636 	{ "imap-urlauth-worker", 0600, "$default_internal_user", "" }
4637 };
4638 static struct file_listener_settings *imap_urlauth_worker_unix_listeners[] = {
4639 	&imap_urlauth_worker_unix_listeners_array[0]
4640 };
4641 static buffer_t imap_urlauth_worker_unix_listeners_buf = {
4642 	{ { imap_urlauth_worker_unix_listeners,
4643 	    sizeof(imap_urlauth_worker_unix_listeners) } }
4644 };
4645 /* </settings checks> */
4646 struct service_settings imap_urlauth_worker_service_settings = {
4647 	.name = "imap-urlauth-worker",
4648 	.protocol = "imap",
4649 	.type = "",
4650 	.executable = "imap-urlauth-worker",
4651 	.user = "",
4652 	.group = "",
4653 	.privileged_group = "",
4654 	.extra_groups = "$default_internal_group",
4655 	.chroot = "",
4656 
4657 	.drop_priv_before_exec = FALSE,
4658 
4659 	.process_min_avail = 0,
4660 	.process_limit = 1024,
4661 	.client_limit = 1,
4662 	.service_count = 1,
4663 	.idle_kill = 0,
4664 	.vsz_limit = UOFF_T_MAX,
4665 
4666 	.unix_listeners = { { &imap_urlauth_worker_unix_listeners_buf,
4667 			      sizeof(imap_urlauth_worker_unix_listeners[0]) } },
4668 	.fifo_listeners = ARRAY_INIT,
4669 	.inet_listeners = ARRAY_INIT
4670 };
4671 #undef DEF
4672 #define DEF(type, name) \
4673 	SETTING_DEFINE_STRUCT_##type(#name, name, struct imap_urlauth_worker_settings)
4674 static const struct setting_define imap_urlauth_worker_setting_defines[] = {
4675 	DEF(BOOL, verbose_proctitle),
4676 
4677 	DEF(STR, imap_urlauth_host),
4678 	DEF(IN_PORT, imap_urlauth_port),
4679 
4680 	SETTING_DEFINE_LIST_END
4681 };
4682 const struct imap_urlauth_worker_settings imap_urlauth_worker_default_settings = {
4683 	.verbose_proctitle = FALSE,
4684 
4685 	.imap_urlauth_host = "",
4686 	.imap_urlauth_port = 143
4687 };
4688 static const struct setting_parser_info *imap_urlauth_worker_setting_dependencies[] = {
4689 	&mail_user_setting_parser_info,
4690 	NULL
4691 };
4692 const struct setting_parser_info imap_urlauth_worker_setting_parser_info = {
4693 	.module_name = "imap-urlauth-worker",
4694 	.defines = imap_urlauth_worker_setting_defines,
4695 	.defaults = &imap_urlauth_worker_default_settings,
4696 
4697 	.type_offset = SIZE_MAX,
4698 	.struct_size = sizeof(struct imap_urlauth_worker_settings),
4699 
4700 	.parent_offset = SIZE_MAX,
4701 
4702 	.dependencies = imap_urlauth_worker_setting_dependencies
4703 };
4704 /* ../../src/imap-urlauth/imap-urlauth-settings.c */
4705 /* <settings checks> */
4706 static struct file_listener_settings imap_urlauth_unix_listeners_array[] = {
4707 	{ "token-login/imap-urlauth", 0666, "", "" }
4708 };
4709 static struct file_listener_settings *imap_urlauth_unix_listeners[] = {
4710 	&imap_urlauth_unix_listeners_array[0]
4711 };
4712 static buffer_t imap_urlauth_unix_listeners_buf = {
4713 	{ { imap_urlauth_unix_listeners, sizeof(imap_urlauth_unix_listeners) } }
4714 };
4715 /* </settings checks> */
4716 struct service_settings imap_urlauth_service_settings = {
4717 	.name = "imap-urlauth",
4718 	.protocol = "imap",
4719 	.type = "",
4720 	.executable = "imap-urlauth",
4721 	.user = "$default_internal_user",
4722 	.group = "",
4723 	.privileged_group = "",
4724 	.extra_groups = "",
4725 	.chroot = "",
4726 
4727 	.drop_priv_before_exec = FALSE,
4728 
4729 	.process_min_avail = 0,
4730 	.process_limit = 1024,
4731 	.client_limit = 1,
4732 	.service_count = 1,
4733 	.idle_kill = 0,
4734 	.vsz_limit = UOFF_T_MAX,
4735 
4736 	.unix_listeners = { { &imap_urlauth_unix_listeners_buf,
4737 			      sizeof(imap_urlauth_unix_listeners[0]) } },
4738 	.fifo_listeners = ARRAY_INIT,
4739 	.inet_listeners = ARRAY_INIT
4740 };
4741 #undef DEF
4742 #define DEF(type, name) \
4743 	SETTING_DEFINE_STRUCT_##type(#name, name, struct imap_urlauth_settings)
4744 static const struct setting_define imap_urlauth_setting_defines[] = {
4745 	DEF(STR, base_dir),
4746 
4747 	DEF(BOOL, mail_debug),
4748 
4749 	DEF(BOOL, verbose_proctitle),
4750 
4751 	DEF(STR, imap_urlauth_logout_format),
4752 	DEF(STR, imap_urlauth_submit_user),
4753 	DEF(STR, imap_urlauth_stream_user),
4754 
4755 	SETTING_DEFINE_LIST_END
4756 };
4757 const struct imap_urlauth_settings imap_urlauth_default_settings = {
4758 	.base_dir = PKG_RUNDIR,
4759   .mail_debug = FALSE,
4760 
4761 	.verbose_proctitle = FALSE,
4762 
4763 	.imap_urlauth_logout_format = "in=%i out=%o",
4764 	.imap_urlauth_submit_user = NULL,
4765 	.imap_urlauth_stream_user = NULL
4766 };
4767 static const struct setting_parser_info *imap_urlauth_setting_dependencies[] = {
4768 	NULL
4769 };
4770 const struct setting_parser_info imap_urlauth_setting_parser_info = {
4771 	.module_name = "imap-urlauth",
4772 	.defines = imap_urlauth_setting_defines,
4773 	.defaults = &imap_urlauth_default_settings,
4774 
4775 	.type_offset = SIZE_MAX,
4776 	.struct_size = sizeof(struct imap_urlauth_settings),
4777 
4778 	.parent_offset = SIZE_MAX,
4779 
4780 	.dependencies = imap_urlauth_setting_dependencies
4781 };
4782 /* ../../src/imap-urlauth/imap-urlauth-login-settings.c */
4783 /* <settings checks> */
4784 static struct file_listener_settings
4785 imap_urlauth_login_unix_listeners_array[] = {
4786 	{ "imap-urlauth", 0666, "", "" }
4787 };
4788 static struct file_listener_settings *imap_urlauth_login_unix_listeners[] = {
4789 	&imap_urlauth_login_unix_listeners_array[0]
4790 };
4791 static buffer_t imap_urlauth_login_unix_listeners_buf = {
4792 	{ { imap_urlauth_login_unix_listeners,
4793 	    sizeof(imap_urlauth_login_unix_listeners) } }
4794 };
4795 /* </settings checks> */
4796 struct service_settings imap_urlauth_login_service_settings = {
4797 	.name = "imap-urlauth-login",
4798 	.protocol = "imap",
4799 	.type = "login",
4800 	.executable = "imap-urlauth-login",
4801 	.user = "$default_login_user",
4802 	.group = "",
4803 	.privileged_group = "",
4804 	.extra_groups = "",
4805 	.chroot = "token-login",
4806 
4807 	.drop_priv_before_exec = FALSE,
4808 
4809 	.process_min_avail = 0,
4810 	.process_limit = 0,
4811 	.client_limit = 0,
4812 	.service_count = 1,
4813 	.idle_kill = 0,
4814 	.vsz_limit = UOFF_T_MAX,
4815 
4816 	.unix_listeners = { { &imap_urlauth_login_unix_listeners_buf,
4817 			      sizeof(imap_urlauth_login_unix_listeners[0]) } },
4818 	.fifo_listeners = ARRAY_INIT,
4819 	.inet_listeners = ARRAY_INIT
4820 };
4821 static const struct setting_define imap_urlauth_login_setting_defines[] = {
4822 	SETTING_DEFINE_LIST_END
4823 };
4824 static const struct setting_parser_info *imap_urlauth_login_setting_dependencies[] = {
4825 	&login_setting_parser_info,
4826 	NULL
4827 };
4828 const struct setting_parser_info imap_urlauth_login_setting_parser_info = {
4829 	.module_name = "imap-urlauth-login",
4830 	.defines = imap_urlauth_login_setting_defines,
4831 
4832 	.type_offset = SIZE_MAX,
4833 	.parent_offset = SIZE_MAX,
4834 
4835 	.dependencies = imap_urlauth_login_setting_dependencies
4836 };
4837 const struct setting_parser_info *imap_urlauth_login_setting_roots[] = {
4838 	&login_setting_parser_info,
4839 	&imap_urlauth_login_setting_parser_info,
4840 	NULL
4841 };
4842 /* ../../src/imap-login/imap-login-settings.c */
4843 /* <settings checks> */
4844 static struct inet_listener_settings imap_login_inet_listeners_array[] = {
4845 	{ .name = "imap", .address = "", .port = 143 },
4846 	{ .name = "imaps", .address = "", .port = 993, .ssl = TRUE }
4847 };
4848 static struct inet_listener_settings *imap_login_inet_listeners[] = {
4849 	&imap_login_inet_listeners_array[0],
4850 	&imap_login_inet_listeners_array[1]
4851 };
4852 static buffer_t imap_login_inet_listeners_buf = {
4853 	{ { imap_login_inet_listeners, sizeof(imap_login_inet_listeners) } }
4854 };
4855 /* </settings checks> */
4856 struct service_settings imap_login_service_settings = {
4857 	.name = "imap-login",
4858 	.protocol = "imap",
4859 	.type = "login",
4860 	.executable = "imap-login",
4861 	.user = "$default_login_user",
4862 	.group = "",
4863 	.privileged_group = "",
4864 	.extra_groups = "",
4865 	.chroot = "login",
4866 
4867 	.drop_priv_before_exec = FALSE,
4868 
4869 	.process_min_avail = 0,
4870 	.process_limit = 0,
4871 	.client_limit = 0,
4872 	.service_count = 1,
4873 	.idle_kill = 0,
4874 	.vsz_limit = UOFF_T_MAX,
4875 
4876 	.unix_listeners = ARRAY_INIT,
4877 	.fifo_listeners = ARRAY_INIT,
4878 	.inet_listeners = { { &imap_login_inet_listeners_buf,
4879 			      sizeof(imap_login_inet_listeners[0]) } }
4880 };
4881 #undef DEF
4882 #define DEF(type, name) \
4883 	SETTING_DEFINE_STRUCT_##type(#name, name, struct imap_login_settings)
4884 static const struct setting_define imap_login_setting_defines[] = {
4885 	DEF(STR, imap_capability),
4886 	DEF(STR, imap_id_send),
4887 	DEF(STR, imap_id_log),
4888 	DEF(BOOL, imap_literal_minus),
4889 	DEF(BOOL, imap_id_retain),
4890 
4891 	SETTING_DEFINE_LIST_END
4892 };
4893 static const struct imap_login_settings imap_login_default_settings = {
4894 	.imap_capability = "",
4895 	.imap_id_send = "name *",
4896 	.imap_id_log = "",
4897 	.imap_literal_minus = FALSE,
4898 	.imap_id_retain = FALSE,
4899 };
4900 static const struct setting_parser_info *imap_login_setting_dependencies[] = {
4901 	&login_setting_parser_info,
4902 	NULL
4903 };
4904 static const struct setting_parser_info imap_login_setting_parser_info = {
4905 	.module_name = "imap-login",
4906 	.defines = imap_login_setting_defines,
4907 	.defaults = &imap_login_default_settings,
4908 
4909 	.type_offset = SIZE_MAX,
4910 	.struct_size = sizeof(struct imap_login_settings),
4911 
4912 	.parent_offset = SIZE_MAX,
4913 	.dependencies = imap_login_setting_dependencies
4914 };
4915 const struct setting_parser_info *imap_login_setting_roots[] = {
4916 	&login_setting_parser_info,
4917 	&imap_login_setting_parser_info,
4918 	NULL
4919 };
4920 /* ../../src/imap-hibernate/imap-hibernate-settings.c */
4921 /* <settings checks> */
4922 static struct file_listener_settings imap_hibernate_unix_listeners_array[] = {
4923 	{ "imap-hibernate", 0660, "", "$default_internal_group" }
4924 };
4925 static struct file_listener_settings *imap_hibernate_unix_listeners[] = {
4926 	&imap_hibernate_unix_listeners_array[0]
4927 };
4928 static buffer_t imap_hibernate_unix_listeners_buf = {
4929 	{ { imap_hibernate_unix_listeners, sizeof(imap_hibernate_unix_listeners) } }
4930 };
4931 /* </settings checks> */
4932 struct service_settings imap_hibernate_service_settings = {
4933 	.name = "imap-hibernate",
4934 	.protocol = "imap",
4935 	.type = "",
4936 	.executable = "imap-hibernate",
4937 	.user = "$default_internal_user",
4938 	.group = "",
4939 	.privileged_group = "",
4940 	.extra_groups = "",
4941 	.chroot = "",
4942 
4943 	.drop_priv_before_exec = FALSE,
4944 
4945 	.process_min_avail = 0,
4946 	.process_limit = 0,
4947 	.client_limit = 0,
4948 	.service_count = 0,
4949 	.idle_kill = 0,
4950 	.vsz_limit = UOFF_T_MAX,
4951 
4952 	.unix_listeners = { { &imap_hibernate_unix_listeners_buf,
4953 			      sizeof(imap_hibernate_unix_listeners[0]) } },
4954 	.fifo_listeners = ARRAY_INIT,
4955 	.inet_listeners = ARRAY_INIT
4956 };
4957 /* ../../src/doveadm/doveadm-settings.c */
4958 /* <settings checks> */
4959 static struct file_listener_settings doveadm_unix_listeners_array[] = {
4960 	{ "doveadm-server", 0600, "", "" }
4961 };
4962 static struct file_listener_settings *doveadm_unix_listeners[] = {
4963 	&doveadm_unix_listeners_array[0]
4964 };
4965 static buffer_t doveadm_unix_listeners_buf = {
4966 	{ { doveadm_unix_listeners, sizeof(doveadm_unix_listeners) } }
4967 };
4968 /* </settings checks> */
4969 /* <settings checks> */
4970 struct dsync_feature_list {
4971 	const char *name;
4972 	enum dsync_features num;
4973 };
4974 
4975 static const struct dsync_feature_list dsync_feature_list[] = {
4976 	{ "empty-header-workaround", DSYNC_FEATURE_EMPTY_HDR_WORKAROUND },
4977 	{ NULL, 0 }
4978 };
4979 
4980 static int
dsync_settings_parse_features(struct doveadm_settings * set,const char ** error_r)4981 dsync_settings_parse_features(struct doveadm_settings *set,
4982 			      const char **error_r)
4983 {
4984 	enum dsync_features features = 0;
4985 	const struct dsync_feature_list *list;
4986 	const char *const *str;
4987 
4988 	str = t_strsplit_spaces(set->dsync_features, " ,");
4989 	for (; *str != NULL; str++) {
4990 		list = dsync_feature_list;
4991 		for (; list->name != NULL; list++) {
4992 			if (strcasecmp(*str, list->name) == 0) {
4993 				features |= list->num;
4994 				break;
4995 			}
4996 		}
4997 		if (list->name == NULL) {
4998 			*error_r = t_strdup_printf("dsync_features: "
4999 				"Unknown feature: %s", *str);
5000 			return -1;
5001 		}
5002 	}
5003 	set->parsed_features = features;
5004 	return 0;
5005 }
5006 
doveadm_settings_check(void * _set,pool_t pool ATTR_UNUSED,const char ** error_r)5007 static bool doveadm_settings_check(void *_set, pool_t pool ATTR_UNUSED,
5008 				   const char **error_r)
5009 {
5010 	struct doveadm_settings *set = _set;
5011 
5012 #ifndef CONFIG_BINARY
5013 	fix_base_path(set, pool, &set->auth_socket_path);
5014 	fix_base_path(set, pool, &set->doveadm_socket_path);
5015 #endif
5016 	if (*set->dsync_hashed_headers == '\0') {
5017 		*error_r = "dsync_hashed_headers must not be empty";
5018 		return FALSE;
5019 	}
5020 	if (*set->dsync_alt_char == '\0') {
5021 		*error_r = "dsync_alt_char must not be empty";
5022 		return FALSE;
5023 	}
5024 	if (dsync_settings_parse_features(set, error_r) != 0)
5025 		return FALSE;
5026 	return TRUE;
5027 }
5028 /* </settings checks> */
5029 struct service_settings doveadm_service_settings = {
5030 	.name = "doveadm",
5031 	.protocol = "",
5032 	.type = "",
5033 	.executable = "doveadm-server",
5034 	.user = "",
5035 	.group = "",
5036 	.privileged_group = "",
5037 	.extra_groups = "$default_internal_group",
5038 	.chroot = "",
5039 
5040 	.drop_priv_before_exec = FALSE,
5041 
5042 	.process_min_avail = 0,
5043 	.process_limit = 0,
5044 	.client_limit = 1,
5045 	.service_count = 1,
5046 	.idle_kill = 0,
5047 	.vsz_limit = UOFF_T_MAX,
5048 
5049 	.unix_listeners = { { &doveadm_unix_listeners_buf,
5050 			      sizeof(doveadm_unix_listeners[0]) } },
5051 	.fifo_listeners = ARRAY_INIT,
5052 	.inet_listeners = ARRAY_INIT
5053 };
5054 #undef DEF
5055 #define DEF(type, name) \
5056 	SETTING_DEFINE_STRUCT_##type(#name, name, struct doveadm_settings)
5057 static const struct setting_define doveadm_setting_defines[] = {
5058 	DEF(STR, base_dir),
5059 	DEF(STR, libexec_dir),
5060 	DEF(STR, mail_plugins),
5061 	DEF(STR, mail_plugin_dir),
5062 	DEF(STR_VARS, mail_temp_dir),
5063 	DEF(BOOL, auth_debug),
5064 	DEF(STR, auth_socket_path),
5065 	DEF(STR, doveadm_socket_path),
5066 	DEF(UINT, doveadm_worker_count),
5067 	DEF(IN_PORT, doveadm_port),
5068 	{ .type = SET_ALIAS, .key = "doveadm_proxy_port" },
5069 	DEF(ENUM, doveadm_ssl),
5070 	DEF(STR, doveadm_username),
5071 	DEF(STR, doveadm_password),
5072 	DEF(STR, doveadm_allowed_commands),
5073 	DEF(STR, dsync_alt_char),
5074 	DEF(STR, dsync_remote_cmd),
5075 	DEF(STR, director_username_hash),
5076 	DEF(STR, doveadm_api_key),
5077 	DEF(STR, dsync_features),
5078 	DEF(UINT, dsync_commit_msgs_interval),
5079 	DEF(STR, doveadm_http_rawlog_dir),
5080 	DEF(STR, dsync_hashed_headers),
5081 
5082 	{ .type = SET_STRLIST, .key = "plugin",
5083 	  .offset = offsetof(struct doveadm_settings, plugin_envs) },
5084 
5085 	SETTING_DEFINE_LIST_END
5086 };
5087 const struct doveadm_settings doveadm_default_settings = {
5088 	.base_dir = PKG_RUNDIR,
5089 	.libexec_dir = PKG_LIBEXECDIR,
5090 	.mail_plugins = "",
5091 	.mail_plugin_dir = MODULEDIR,
5092 	.mail_temp_dir = "/tmp",
5093 	.auth_debug = FALSE,
5094 	.auth_socket_path = "auth-userdb",
5095 	.doveadm_socket_path = "doveadm-server",
5096 	.doveadm_worker_count = 0,
5097 	.doveadm_port = 0,
5098 	.doveadm_ssl = "no:ssl:starttls",
5099 	.doveadm_username = "doveadm",
5100 	.doveadm_password = "",
5101 	.doveadm_allowed_commands = "",
5102 	.dsync_alt_char = "_",
5103 	.dsync_remote_cmd = "ssh -l%{login} %{host} doveadm dsync-server -u%u -U",
5104 	.dsync_features = "",
5105 	.dsync_hashed_headers = "Date Message-ID",
5106 	.dsync_commit_msgs_interval = 100,
5107 	.director_username_hash = "%Lu",
5108 	.doveadm_api_key = "",
5109 	.doveadm_http_rawlog_dir = "",
5110 
5111 	.plugin_envs = ARRAY_INIT
5112 };
5113 static const struct setting_parser_info *doveadm_setting_dependencies[] = {
5114 	&mail_user_setting_parser_info,
5115 	NULL
5116 };
5117 const struct setting_parser_info doveadm_setting_parser_info = {
5118 	.module_name = "doveadm",
5119 	.defines = doveadm_setting_defines,
5120 	.defaults = &doveadm_default_settings,
5121 
5122 	.type_offset = SIZE_MAX,
5123 	.struct_size = sizeof(struct doveadm_settings),
5124 
5125 	.parent_offset = SIZE_MAX,
5126 	.check_func = doveadm_settings_check,
5127 	.dependencies = doveadm_setting_dependencies
5128 };
5129 /* ../../src/dns/dns-client-settings.c */
5130 /* <settings checks> */
5131 static struct file_listener_settings dns_client_unix_listeners_array[] = {
5132 	{ "dns-client", 0666, "", "" },
5133 	{ "login/dns-client", 0666, "", "" },
5134 };
5135 static struct file_listener_settings *dns_client_unix_listeners[] = {
5136 	&dns_client_unix_listeners_array[0],
5137         &dns_client_unix_listeners_array[1],
5138 };
5139 static buffer_t dns_client_unix_listeners_buf = {
5140 	{ { dns_client_unix_listeners, sizeof(dns_client_unix_listeners) } }
5141 };
5142 /* </settings checks> */
5143 struct service_settings dns_client_service_settings = {
5144 	.name = "dns-client",
5145 	.protocol = "",
5146 	.type = "",
5147 	.executable = "dns-client",
5148 	.user = "$default_internal_user",
5149 	.group = "",
5150 	.privileged_group = "",
5151 	.extra_groups = "",
5152 	.chroot = "",
5153 
5154 	.drop_priv_before_exec = FALSE,
5155 
5156 	.process_min_avail = 0,
5157 	.process_limit = 0,
5158 	.client_limit = 1,
5159 	.service_count = 0,
5160 	.idle_kill = 0,
5161 	.vsz_limit = UOFF_T_MAX,
5162 
5163 	.unix_listeners = { { &dns_client_unix_listeners_buf,
5164 			      sizeof(dns_client_unix_listeners[0]) } },
5165 	.fifo_listeners = ARRAY_INIT,
5166 	.inet_listeners = ARRAY_INIT
5167 };
5168 /* ../../src/director/director-settings.c */
5169 /* <settings checks> */
5170 static bool director_settings_verify(void *_set, pool_t pool, const char **error_r);
5171 
5172 static struct file_listener_settings director_unix_listeners_array[] = {
5173 	{ "login/director", 0, "", "" },
5174 	{ "director-admin", 0600, "", "" }
5175 };
5176 static struct file_listener_settings *director_unix_listeners[] = {
5177 	&director_unix_listeners_array[0],
5178 	&director_unix_listeners_array[1]
5179 };
5180 static buffer_t director_unix_listeners_buf = {
5181 	{ { director_unix_listeners, sizeof(director_unix_listeners) } }
5182 };
5183 static struct file_listener_settings director_fifo_listeners_array[] = {
5184 	{ "login/proxy-notify", 0, "", "" }
5185 };
5186 static struct file_listener_settings *director_fifo_listeners[] = {
5187 	&director_fifo_listeners_array[0]
5188 };
5189 static buffer_t director_fifo_listeners_buf = {
5190 	{ { director_fifo_listeners, sizeof(director_fifo_listeners) } }
5191 };
5192 /* </settings checks> */
5193 /* <settings checks> */
5194 static bool
director_settings_verify(void * _set,pool_t pool ATTR_UNUSED,const char ** error_r)5195 director_settings_verify(void *_set, pool_t pool ATTR_UNUSED, const char **error_r)
5196 {
5197 	struct director_settings *set = _set;
5198 
5199 	if (set->director_user_expire < 10) {
5200 		*error_r = "director_user_expire is too low";
5201 		return FALSE;
5202 	}
5203 	return TRUE;
5204 }
5205 /* </settings checks> */
5206 struct service_settings director_service_settings = {
5207 	.name = "director",
5208 	.protocol = "",
5209 	.type = "",
5210 	.executable = "director",
5211 	.user = "$default_internal_user",
5212 	.group = "",
5213 	.privileged_group = "",
5214 	.extra_groups = "",
5215 	.chroot = ".",
5216 
5217 	.drop_priv_before_exec = FALSE,
5218 
5219 	.process_min_avail = 0,
5220 	.process_limit = 1,
5221 	.client_limit = 0,
5222 	.service_count = 0,
5223 	.idle_kill = UINT_MAX,
5224 	.vsz_limit = UOFF_T_MAX,
5225 
5226 	.unix_listeners = { { &director_unix_listeners_buf,
5227 			      sizeof(director_unix_listeners[0]) } },
5228 	.fifo_listeners = { { &director_fifo_listeners_buf,
5229 			      sizeof(director_fifo_listeners[0]) } },
5230 	.inet_listeners = ARRAY_INIT,
5231 
5232 	.process_limit_1 = TRUE
5233 };
5234 #undef DEF
5235 #define DEF(type, name) \
5236 	SETTING_DEFINE_STRUCT_##type(#name, name, struct director_settings)
5237 static const struct setting_define director_setting_defines[] = {
5238 	DEF(STR, master_user_separator),
5239 
5240 	DEF(STR, director_servers),
5241 	DEF(STR, director_mail_servers),
5242 	DEF(STR, director_username_hash),
5243 	DEF(STR, director_flush_socket),
5244 	DEF(TIME, director_ping_idle_timeout),
5245 	DEF(TIME, director_ping_max_timeout),
5246 	DEF(TIME, director_user_expire),
5247 	DEF(TIME, director_user_kick_delay),
5248 	DEF(UINT, director_max_parallel_moves),
5249 	DEF(UINT, director_max_parallel_kicks),
5250 	DEF(SIZE, director_output_buffer_size),
5251 
5252 	SETTING_DEFINE_LIST_END
5253 };
5254 const struct director_settings director_default_settings = {
5255 	.master_user_separator = "",
5256 
5257 	.director_servers = "",
5258 	.director_mail_servers = "",
5259 	.director_username_hash = "%Lu",
5260 	.director_flush_socket = "",
5261 	.director_ping_idle_timeout = 30,
5262 	.director_ping_max_timeout = 60,
5263 	.director_user_expire = 60*15,
5264 	.director_user_kick_delay = 2,
5265 	.director_max_parallel_moves = 100,
5266 	.director_max_parallel_kicks = 100,
5267 	.director_output_buffer_size = 10 * 1024 * 1024,
5268 };
5269 const struct setting_parser_info director_setting_parser_info = {
5270 	.module_name = "director",
5271 	.defines = director_setting_defines,
5272 	.defaults = &director_default_settings,
5273 
5274 	.type_offset = SIZE_MAX,
5275 	.struct_size = sizeof(struct director_settings),
5276 
5277 	.parent_offset = SIZE_MAX,
5278 
5279 	.check_func = director_settings_verify
5280 };
5281 /* ../../src/dict/dict-settings.c */
5282 /* <settings checks> */
5283 static struct file_listener_settings dict_unix_listeners_array[] = {
5284 	{ "dict", 0660, "", "$default_internal_group" }
5285 };
5286 static struct file_listener_settings *dict_unix_listeners[] = {
5287 	&dict_unix_listeners_array[0]
5288 };
5289 static buffer_t dict_unix_listeners_buf = {
5290 	{ { dict_unix_listeners, sizeof(dict_unix_listeners) } }
5291 };
5292 
5293 static struct file_listener_settings dict_async_unix_listeners_array[] = {
5294 	{ "dict-async", 0660, "", "$default_internal_group" }
5295 };
5296 static struct file_listener_settings *dict_async_unix_listeners[] = {
5297 	&dict_async_unix_listeners_array[0]
5298 };
5299 static buffer_t dict_async_unix_listeners_buf = {
5300 	{ { dict_async_unix_listeners, sizeof(dict_async_unix_listeners) } }
5301 };
5302 /* </settings checks> */
5303 struct service_settings dict_service_settings = {
5304 	.name = "dict",
5305 	.protocol = "",
5306 	.type = "",
5307 	.executable = "dict",
5308 	.user = "$default_internal_user",
5309 	.group = "",
5310 	.privileged_group = "",
5311 	.extra_groups = "",
5312 	.chroot = "",
5313 
5314 	.drop_priv_before_exec = FALSE,
5315 
5316 	.process_min_avail = 0,
5317 	.process_limit = 0,
5318 	.client_limit = 1,
5319 	.service_count = 0,
5320 	.idle_kill = 0,
5321 	.vsz_limit = UOFF_T_MAX,
5322 
5323 	.unix_listeners = { { &dict_unix_listeners_buf,
5324 			      sizeof(dict_unix_listeners[0]) } },
5325 	.fifo_listeners = ARRAY_INIT,
5326 	.inet_listeners = ARRAY_INIT
5327 };
5328 struct service_settings dict_async_service_settings = {
5329 	.name = "dict-async",
5330 	.protocol = "",
5331 	.type = "",
5332 	.executable = "dict",
5333 	.user = "$default_internal_user",
5334 	.group = "",
5335 	.privileged_group = "",
5336 	.extra_groups = "",
5337 	.chroot = "",
5338 
5339 	.drop_priv_before_exec = FALSE,
5340 
5341 	.process_min_avail = 0,
5342 	.process_limit = 0,
5343 	.client_limit = 0,
5344 	.service_count = 0,
5345 	.idle_kill = 0,
5346 	.vsz_limit = UOFF_T_MAX,
5347 
5348 	.unix_listeners = { { &dict_async_unix_listeners_buf,
5349 			      sizeof(dict_async_unix_listeners[0]) } },
5350 	.fifo_listeners = ARRAY_INIT,
5351 	.inet_listeners = ARRAY_INIT
5352 };
5353 #undef DEF
5354 #define DEF(type, name) \
5355 	SETTING_DEFINE_STRUCT_##type(#name, name, struct dict_server_settings)
5356 static const struct setting_define dict_setting_defines[] = {
5357 	DEF(STR, base_dir),
5358 	DEF(BOOL, verbose_proctitle),
5359 
5360 	DEF(STR, dict_db_config),
5361 	{ .type = SET_STRLIST, .key = "dict",
5362 	  .offset = offsetof(struct dict_server_settings, dicts) },
5363 
5364 	SETTING_DEFINE_LIST_END
5365 };
5366 const struct dict_server_settings dict_default_settings = {
5367 	.base_dir = PKG_RUNDIR,
5368 	.verbose_proctitle = FALSE,
5369 
5370 	.dict_db_config = "",
5371 	.dicts = ARRAY_INIT
5372 };
5373 const struct setting_parser_info dict_setting_parser_info = {
5374 	.module_name = "dict",
5375 	.defines = dict_setting_defines,
5376 	.defaults = &dict_default_settings,
5377 
5378 	.type_offset = SIZE_MAX,
5379 	.struct_size = sizeof(struct dict_server_settings),
5380 
5381 	.parent_offset = SIZE_MAX
5382 };
5383 /* ../../src/config/config-settings.c */
5384 /* <settings checks> */
5385 static struct file_listener_settings config_unix_listeners_array[] = {
5386 	{ "config", 0600, "", "" }
5387 };
5388 static struct file_listener_settings *config_unix_listeners[] = {
5389 	&config_unix_listeners_array[0]
5390 };
5391 static buffer_t config_unix_listeners_buf = {
5392 	{ { config_unix_listeners, sizeof(config_unix_listeners) } }
5393 };
5394 /* </settings checks> */
5395 struct service_settings config_service_settings = {
5396 	.name = "config",
5397 	.protocol = "",
5398 	.type = "config",
5399 	.executable = "config",
5400 	.user = "",
5401 	.group = "",
5402 	.privileged_group = "",
5403 	.extra_groups = "",
5404 	.chroot = "",
5405 
5406 	.drop_priv_before_exec = FALSE,
5407 
5408 	.process_min_avail = 0,
5409 	.process_limit = 0,
5410 	.client_limit = 0,
5411 	.service_count = 0,
5412 	.idle_kill = UINT_MAX,
5413 	.vsz_limit = UOFF_T_MAX,
5414 
5415 	.unix_listeners = { { &config_unix_listeners_buf,
5416 			      sizeof(config_unix_listeners[0]) } },
5417 	.fifo_listeners = ARRAY_INIT,
5418 	.inet_listeners = ARRAY_INIT
5419 };
5420 /* ../../src/auth/auth-settings.c */
5421 extern const struct setting_parser_info auth_passdb_setting_parser_info;
5422 extern const struct setting_parser_info auth_userdb_setting_parser_info;
5423 /* <settings checks> */
5424 static struct file_listener_settings auth_unix_listeners_array[] = {
5425 	{ "login/login", 0666, "", "" },
5426 	{ "token-login/tokenlogin", 0666, "", "" },
5427 	{ "auth-login", 0600, "$default_internal_user", "" },
5428 	{ "auth-client", 0600, "$default_internal_user", "" },
5429 	{ "auth-userdb", 0666, "$default_internal_user", "" },
5430 	{ "auth-master", 0600, "", "" }
5431 };
5432 static struct file_listener_settings *auth_unix_listeners[] = {
5433 	&auth_unix_listeners_array[0],
5434 	&auth_unix_listeners_array[1],
5435 	&auth_unix_listeners_array[2],
5436 	&auth_unix_listeners_array[3],
5437 	&auth_unix_listeners_array[4],
5438 	&auth_unix_listeners_array[5]
5439 };
5440 static buffer_t auth_unix_listeners_buf = {
5441 	{ { auth_unix_listeners, sizeof(auth_unix_listeners) } }
5442 };
5443 /* </settings checks> */
5444 /* <settings checks> */
5445 static struct file_listener_settings auth_worker_unix_listeners_array[] = {
5446 	{ "auth-worker", 0600, "$default_internal_user", "" }
5447 };
5448 static struct file_listener_settings *auth_worker_unix_listeners[] = {
5449 	&auth_worker_unix_listeners_array[0]
5450 };
5451 static buffer_t auth_worker_unix_listeners_buf = {
5452 	{ { auth_worker_unix_listeners, sizeof(auth_worker_unix_listeners) } }
5453 };
5454 /* </settings checks> */
5455 /* <settings checks> */
5456 static bool
auth_settings_set_self_ips(struct auth_settings * set,pool_t pool,const char ** error_r)5457 auth_settings_set_self_ips(struct auth_settings *set, pool_t pool,
5458 			   const char **error_r)
5459 {
5460 	const char *const *tmp;
5461 	ARRAY(struct ip_addr) ips_array;
5462 	struct ip_addr *ips;
5463 	unsigned int ips_count;
5464 	int ret;
5465 
5466 	if (*set->proxy_self == '\0') {
5467 		set->proxy_self_ips = p_new(pool, struct ip_addr, 1);
5468 		return TRUE;
5469 	}
5470 
5471 	p_array_init(&ips_array, pool, 4);
5472 	tmp = t_strsplit_spaces(set->proxy_self, " ");
5473 	for (; *tmp != NULL; tmp++) {
5474 		ret = net_gethostbyname(*tmp, &ips, &ips_count);
5475 		if (ret != 0) {
5476 			*error_r = t_strdup_printf("auth_proxy_self_ips: "
5477 				"gethostbyname(%s) failed: %s",
5478 				*tmp, net_gethosterror(ret));
5479 		}
5480 		array_append(&ips_array, ips, ips_count);
5481 	}
5482 	array_append_zero(&ips_array);
5483 	set->proxy_self_ips = array_front(&ips_array);
5484 	return TRUE;
5485 }
5486 
5487 static bool
auth_verify_verbose_password(struct auth_settings * set,const char ** error_r)5488 auth_verify_verbose_password(struct auth_settings *set,
5489 			     const char **error_r)
5490 {
5491 	const char *p, *value = set->verbose_passwords;
5492 	unsigned int num;
5493 
5494 	p = strchr(value, ':');
5495 	if (p != NULL) {
5496 		if (str_to_uint(p+1, &num) < 0 || num == 0) {
5497 			*error_r = t_strdup_printf("auth_verbose_passwords: "
5498 				"Invalid truncation number: '%s'", p+1);
5499 			return FALSE;
5500 		}
5501 		value = t_strdup_until(value, p);
5502 	}
5503 	if (strcmp(value, "no") == 0)
5504 		return TRUE;
5505 	else if (strcmp(value, "plain") == 0)
5506 		return TRUE;
5507 	else if (strcmp(value, "sha1") == 0)
5508 		return TRUE;
5509 	else if (strcmp(value, "yes") == 0) {
5510 		/* just use it as alias for "plain" */
5511 		set->verbose_passwords = "plain";
5512 		return TRUE;
5513 	} else {
5514 		*error_r = "auth_verbose_passwords: Invalid value";
5515 		return FALSE;
5516 	}
5517 }
5518 
auth_settings_check(void * _set,pool_t pool,const char ** error_r)5519 static bool auth_settings_check(void *_set, pool_t pool,
5520 				const char **error_r)
5521 {
5522 	struct auth_settings *set = _set;
5523 	const char *p;
5524 
5525 	if (set->debug_passwords)
5526 		set->debug = TRUE;
5527 	if (set->debug)
5528 		set->verbose = TRUE;
5529 
5530 	if (set->worker_max_count == 0) {
5531 		*error_r = "auth_worker_max_count must be above zero";
5532 		return FALSE;
5533 	}
5534 
5535 	if (set->cache_size > 0 && set->cache_size < 1024) {
5536 		/* probably a configuration error.
5537 		   older versions used megabyte numbers */
5538 		*error_r = t_strdup_printf("auth_cache_size value is too small "
5539 					   "(%"PRIuUOFF_T" bytes)",
5540 					   set->cache_size);
5541 		return FALSE;
5542 	}
5543 
5544 	if (!auth_verify_verbose_password(set, error_r))
5545 		return FALSE;
5546 
5547 	if (*set->username_chars == '\0') {
5548 		/* all chars are allowed */
5549 		memset(set->username_chars_map, 1,
5550 		       sizeof(set->username_chars_map));
5551 	} else {
5552 		for (p = set->username_chars; *p != '\0'; p++)
5553 			set->username_chars_map[(int)(uint8_t)*p] = 1;
5554 	}
5555 
5556 	if (*set->username_translation != '\0') {
5557 		p = set->username_translation;
5558 		for (; *p != '\0' && p[1] != '\0'; p += 2)
5559 			set->username_translation_map[(int)(uint8_t)*p] = p[1];
5560 	}
5561 	set->realms_arr =
5562 		(const char *const *)p_strsplit_spaces(pool, set->realms, " ");
5563 
5564 	if (*set->policy_server_url != '\0') {
5565 		if (*set->policy_hash_nonce == '\0') {
5566 
5567 			*error_r = "auth_policy_hash_nonce must be set when policy server is used";
5568 			return FALSE;
5569 		}
5570 		const struct hash_method *digest = hash_method_lookup(set->policy_hash_mech);
5571 		if (digest == NULL) {
5572 			*error_r = "invalid auth_policy_hash_mech given";
5573 			return FALSE;
5574 		}
5575 		if (set->policy_hash_truncate > 0 && set->policy_hash_truncate >= digest->digest_size*8) {
5576 			*error_r = t_strdup_printf("policy_hash_truncate is not smaller than digest size (%u >= %u)",
5577 				set->policy_hash_truncate,
5578 				digest->digest_size*8);
5579 			return FALSE;
5580 		}
5581 	}
5582 
5583 	if (!auth_settings_set_self_ips(set, pool, error_r))
5584 		return FALSE;
5585 	return TRUE;
5586 }
5587 
5588 static bool
auth_passdb_settings_check(void * _set,pool_t pool ATTR_UNUSED,const char ** error_r)5589 auth_passdb_settings_check(void *_set, pool_t pool ATTR_UNUSED,
5590 			   const char **error_r)
5591 {
5592 	struct auth_passdb_settings *set = _set;
5593 
5594 	if (set->driver == NULL || *set->driver == '\0') {
5595 		*error_r = "passdb is missing driver";
5596 		return FALSE;
5597 	}
5598 	if (set->pass && strcmp(set->result_success, "return-ok") != 0) {
5599 		*error_r = "Obsolete pass=yes setting mixed with non-default result_success";
5600 		return FALSE;
5601 	}
5602 	return TRUE;
5603 }
5604 
5605 static bool
auth_userdb_settings_check(void * _set,pool_t pool ATTR_UNUSED,const char ** error_r)5606 auth_userdb_settings_check(void *_set, pool_t pool ATTR_UNUSED,
5607 			   const char **error_r)
5608 {
5609 	struct auth_userdb_settings *set = _set;
5610 
5611 	if (set->driver == NULL || *set->driver == '\0') {
5612 		*error_r = "userdb is missing driver";
5613 		return FALSE;
5614 	}
5615 	return TRUE;
5616 }
5617 /* </settings checks> */
5618 struct service_settings auth_service_settings = {
5619 	.name = "auth",
5620 	.protocol = "",
5621 	.type = "",
5622 	.executable = "auth",
5623 	.user = "$default_internal_user",
5624 	.group = "",
5625 	.privileged_group = "",
5626 	.extra_groups = "",
5627 	.chroot = "",
5628 
5629 	.drop_priv_before_exec = FALSE,
5630 
5631 	.process_min_avail = 0,
5632 	.process_limit = 1,
5633 	.client_limit = 0,
5634 	.service_count = 0,
5635 	.idle_kill = 0,
5636 	.vsz_limit = UOFF_T_MAX,
5637 
5638 	.unix_listeners = { { &auth_unix_listeners_buf,
5639 			      sizeof(auth_unix_listeners[0]) } },
5640 	.fifo_listeners = ARRAY_INIT,
5641 	.inet_listeners = ARRAY_INIT,
5642 
5643 	.process_limit_1 = TRUE
5644 };
5645 struct service_settings auth_worker_service_settings = {
5646 	.name = "auth-worker",
5647 	.protocol = "",
5648 	.type = "worker",
5649 	.executable = "auth -w",
5650 	.user = "",
5651 	.group = "",
5652 	.privileged_group = "",
5653 	.extra_groups = "",
5654 	.chroot = "",
5655 
5656 	.drop_priv_before_exec = FALSE,
5657 
5658 	.process_min_avail = 0,
5659 	.process_limit = 0,
5660 	.client_limit = 1,
5661 	.service_count = 0,
5662 	.idle_kill = 0,
5663 	.vsz_limit = UOFF_T_MAX,
5664 
5665 	.unix_listeners = { { &auth_worker_unix_listeners_buf,
5666 			      sizeof(auth_worker_unix_listeners[0]) } },
5667 	.fifo_listeners = ARRAY_INIT,
5668 	.inet_listeners = ARRAY_INIT
5669 };
5670 #undef DEF
5671 #define DEF(type, name) \
5672 	SETTING_DEFINE_STRUCT_##type(#name, name, struct auth_passdb_settings)
5673 static const struct setting_define auth_passdb_setting_defines[] = {
5674 	DEF(STR, name),
5675 	DEF(STR, driver),
5676 	DEF(STR, args),
5677 	DEF(STR, default_fields),
5678 	DEF(STR, override_fields),
5679 	DEF(STR, mechanisms),
5680 	DEF(STR, username_filter),
5681 
5682 	DEF(ENUM, skip),
5683 	DEF(ENUM, result_success),
5684 	DEF(ENUM, result_failure),
5685 	DEF(ENUM, result_internalfail),
5686 
5687 	DEF(BOOL, deny),
5688 	DEF(BOOL, pass),
5689 	DEF(BOOL, master),
5690 	DEF(ENUM, auth_verbose),
5691 
5692 	SETTING_DEFINE_LIST_END
5693 };
5694 static const struct auth_passdb_settings auth_passdb_default_settings = {
5695 	.name = "",
5696 	.driver = "",
5697 	.args = "",
5698 	.default_fields = "",
5699 	.override_fields = "",
5700 	.mechanisms = "",
5701 	.username_filter = "",
5702 
5703 	.skip = "never:authenticated:unauthenticated",
5704 	.result_success = "return-ok:return:return-fail:continue:continue-ok:continue-fail",
5705 	.result_failure = "continue:return:return-ok:return-fail:continue-ok:continue-fail",
5706 	.result_internalfail = "continue:return:return-ok:return-fail:continue-ok:continue-fail",
5707 
5708 	.deny = FALSE,
5709 	.pass = FALSE,
5710 	.master = FALSE,
5711 	.auth_verbose = "default:yes:no"
5712 };
5713 const struct setting_parser_info auth_passdb_setting_parser_info = {
5714 	.defines = auth_passdb_setting_defines,
5715 	.defaults = &auth_passdb_default_settings,
5716 
5717 	.type_offset = offsetof(struct auth_passdb_settings, name),
5718 	.struct_size = sizeof(struct auth_passdb_settings),
5719 
5720 	.parent_offset = SIZE_MAX,
5721 	.parent = &auth_setting_parser_info,
5722 
5723 	.check_func = auth_passdb_settings_check
5724 };
5725 #undef DEF
5726 #define DEF(type, name) \
5727 	SETTING_DEFINE_STRUCT_##type(#name, name, struct auth_userdb_settings)
5728 static const struct setting_define auth_userdb_setting_defines[] = {
5729 	DEF(STR, name),
5730 	DEF(STR, driver),
5731 	DEF(STR, args),
5732 	DEF(STR, default_fields),
5733 	DEF(STR, override_fields),
5734 
5735 	DEF(ENUM, skip),
5736 	DEF(ENUM, result_success),
5737 	DEF(ENUM, result_failure),
5738 	DEF(ENUM, result_internalfail),
5739 
5740 	DEF(ENUM, auth_verbose),
5741 
5742 	SETTING_DEFINE_LIST_END
5743 };
5744 static const struct auth_userdb_settings auth_userdb_default_settings = {
5745 	/* NOTE: when adding fields, update also auth.c:userdb_dummy_set */
5746 	.name = "",
5747 	.driver = "",
5748 	.args = "",
5749 	.default_fields = "",
5750 	.override_fields = "",
5751 
5752 	.skip = "never:found:notfound",
5753 	.result_success = "return-ok:return:return-fail:continue:continue-ok:continue-fail",
5754 	.result_failure = "continue:return:return-ok:return-fail:continue-ok:continue-fail",
5755 	.result_internalfail = "continue:return:return-ok:return-fail:continue-ok:continue-fail",
5756 
5757 	.auth_verbose = "default:yes:no"
5758 };
5759 const struct setting_parser_info auth_userdb_setting_parser_info = {
5760 	.defines = auth_userdb_setting_defines,
5761 	.defaults = &auth_userdb_default_settings,
5762 
5763 	.type_offset = offsetof(struct auth_userdb_settings, name),
5764 	.struct_size = sizeof(struct auth_userdb_settings),
5765 
5766 	.parent_offset = SIZE_MAX,
5767 	.parent = &auth_setting_parser_info,
5768 
5769 	.check_func = auth_userdb_settings_check
5770 };
5771 #undef DEF
5772 #undef DEF_NOPREFIX
5773 #undef DEFLIST
5774 #define DEF(type, name) \
5775 	SETTING_DEFINE_STRUCT_##type("auth_"#name, name, struct auth_settings)
5776 #define DEF_NOPREFIX(type, name) \
5777 	SETTING_DEFINE_STRUCT_##type(#name, name, struct auth_settings)
5778 #define DEFLIST(field, name, defines) \
5779 	{ .type = SET_DEFLIST, .key = name, \
5780 	  .offset = offsetof(struct auth_settings, field), \
5781 	  .list_info = defines }
5782 static const struct setting_define auth_setting_defines[] = {
5783 	DEF(STR, mechanisms),
5784 	DEF(STR, realms),
5785 	DEF(STR, default_realm),
5786 	DEF(SIZE, cache_size),
5787 	DEF(TIME, cache_ttl),
5788 	DEF(TIME, cache_negative_ttl),
5789 	DEF(BOOL, cache_verify_password_with_worker),
5790 	DEF(STR, username_chars),
5791 	DEF(STR, username_translation),
5792 	DEF(STR, username_format),
5793 	DEF(STR, master_user_separator),
5794 	DEF(STR, anonymous_username),
5795 	DEF(STR, krb5_keytab),
5796 	DEF(STR, gssapi_hostname),
5797 	DEF(STR, winbind_helper_path),
5798 	DEF(STR, proxy_self),
5799 	DEF(TIME, failure_delay),
5800 
5801 	DEF(STR, policy_server_url),
5802 	DEF(STR, policy_server_api_header),
5803 	DEF(UINT, policy_server_timeout_msecs),
5804 	DEF(STR, policy_hash_mech),
5805 	DEF(STR, policy_hash_nonce),
5806 	DEF(STR, policy_request_attributes),
5807 	DEF(BOOL, policy_reject_on_fail),
5808 	DEF(BOOL, policy_check_before_auth),
5809 	DEF(BOOL, policy_check_after_auth),
5810 	DEF(BOOL, policy_report_after_auth),
5811 	DEF(BOOL, policy_log_only),
5812 	DEF(UINT, policy_hash_truncate),
5813 
5814 	DEF(BOOL, stats),
5815 	DEF(BOOL, verbose),
5816 	DEF(BOOL, debug),
5817 	DEF(BOOL, debug_passwords),
5818 	DEF(STR, verbose_passwords),
5819 	DEF(BOOL, ssl_require_client_cert),
5820 	DEF(BOOL, ssl_username_from_cert),
5821 	DEF(BOOL, use_winbind),
5822 
5823 	DEF(UINT, worker_max_count),
5824 
5825 	DEFLIST(passdbs, "passdb", &auth_passdb_setting_parser_info),
5826 	DEFLIST(userdbs, "userdb", &auth_userdb_setting_parser_info),
5827 
5828 	DEF_NOPREFIX(STR, base_dir),
5829 	DEF_NOPREFIX(BOOL, verbose_proctitle),
5830 	DEF_NOPREFIX(UINT, first_valid_uid),
5831 	DEF_NOPREFIX(UINT, last_valid_uid),
5832 	DEF_NOPREFIX(UINT, first_valid_gid),
5833 	DEF_NOPREFIX(UINT, last_valid_gid),
5834 
5835 	DEF_NOPREFIX(STR, ssl_client_ca_dir),
5836 	DEF_NOPREFIX(STR, ssl_client_ca_file),
5837 
5838 	SETTING_DEFINE_LIST_END
5839 };
5840 static const struct auth_settings auth_default_settings = {
5841 	.mechanisms = "plain",
5842 	.realms = "",
5843 	.default_realm = "",
5844 	.cache_size = 0,
5845 	.cache_ttl = 60*60,
5846 	.cache_negative_ttl = 60*60,
5847 	.cache_verify_password_with_worker = FALSE,
5848 	.username_chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890.-_@",
5849 	.username_translation = "",
5850 	.username_format = "%Lu",
5851 	.master_user_separator = "",
5852 	.anonymous_username = "anonymous",
5853 	.krb5_keytab = "",
5854 	.gssapi_hostname = "",
5855 	.winbind_helper_path = "/usr/bin/ntlm_auth",
5856 	.proxy_self = "",
5857 	.failure_delay = 2,
5858 
5859 	.policy_server_url = "",
5860 	.policy_server_api_header = "",
5861 	.policy_server_timeout_msecs = 2000,
5862 	.policy_hash_mech = "sha256",
5863 	.policy_hash_nonce = "",
5864 	.policy_request_attributes = "login=%{requested_username} pwhash=%{hashed_password} remote=%{rip} device_id=%{client_id} protocol=%s session_id=%{session}",
5865 	.policy_reject_on_fail = FALSE,
5866 	.policy_check_before_auth = TRUE,
5867 	.policy_check_after_auth = TRUE,
5868 	.policy_report_after_auth = TRUE,
5869 	.policy_log_only = FALSE,
5870 	.policy_hash_truncate = 12,
5871 
5872 	.stats = FALSE,
5873 	.verbose = FALSE,
5874 	.debug = FALSE,
5875 	.debug_passwords = FALSE,
5876 	.verbose_passwords = "no",
5877 	.ssl_require_client_cert = FALSE,
5878 	.ssl_username_from_cert = FALSE,
5879 	.ssl_client_ca_dir = "",
5880 	.ssl_client_ca_file = "",
5881 
5882 	.use_winbind = FALSE,
5883 
5884 	.worker_max_count = 30,
5885 
5886 	.passdbs = ARRAY_INIT,
5887 	.userdbs = ARRAY_INIT,
5888 
5889 	.base_dir = PKG_RUNDIR,
5890 	.verbose_proctitle = FALSE,
5891 	.first_valid_uid = 500,
5892 	.last_valid_uid = 0,
5893 	.first_valid_gid = 1,
5894 	.last_valid_gid = 0,
5895 };
5896 const struct setting_parser_info auth_setting_parser_info = {
5897 	.module_name = "auth",
5898 	.defines = auth_setting_defines,
5899 	.defaults = &auth_default_settings,
5900 
5901 	.type_offset = SIZE_MAX,
5902 	.struct_size = sizeof(struct auth_settings),
5903 
5904 	.parent_offset = SIZE_MAX,
5905 
5906 	.check_func = auth_settings_check
5907 };
5908 /* ../../src/anvil/anvil-settings.c */
5909 /* <settings checks> */
5910 static struct file_listener_settings anvil_unix_listeners_array[] = {
5911 	{ "anvil", 0600, "", "" },
5912 	{ "anvil-auth-penalty", 0600, "", "" }
5913 };
5914 static struct file_listener_settings *anvil_unix_listeners[] = {
5915 	&anvil_unix_listeners_array[0],
5916 	&anvil_unix_listeners_array[1]
5917 };
5918 static buffer_t anvil_unix_listeners_buf = {
5919 	{ { anvil_unix_listeners, sizeof(anvil_unix_listeners) } }
5920 };
5921 /* </settings checks> */
5922 struct service_settings anvil_service_settings = {
5923 	.name = "anvil",
5924 	.protocol = "",
5925 	.type = "anvil",
5926 	.executable = "anvil",
5927 	.user = "$default_internal_user",
5928 	.group = "",
5929 	.privileged_group = "",
5930 	.extra_groups = "",
5931 	.chroot = "empty",
5932 
5933 	.drop_priv_before_exec = FALSE,
5934 
5935 	.process_min_avail = 1,
5936 	.process_limit = 1,
5937 	.client_limit = 0,
5938 	.service_count = 0,
5939 	.idle_kill = UINT_MAX,
5940 	.vsz_limit = UOFF_T_MAX,
5941 
5942 	.unix_listeners = { { &anvil_unix_listeners_buf,
5943 			      sizeof(anvil_unix_listeners[0]) } },
5944 	.fifo_listeners = ARRAY_INIT,
5945 	.inet_listeners = ARRAY_INIT,
5946 
5947 	.process_limit_1 = TRUE
5948 };
5949 static struct service_settings *config_all_services[] = {
5950 #ifdef HAVE_LIBWRAP
5951 	&tcpwrap_service_settings,
5952 #endif
5953 	&health_check_service_settings,
5954 	&submission_service_settings,
5955 	&submission_login_service_settings,
5956 	&stats_service_settings,
5957 	&replicator_service_settings,
5958 	&aggregator_service_settings,
5959 	&pop3_service_settings,
5960 	&pop3_login_service_settings,
5961 	&old_stats_service_settings,
5962 	&log_service_settings,
5963 	&lmtp_service_settings,
5964 	&ipc_service_settings,
5965 	&indexer_worker_service_settings,
5966 	&indexer_service_settings,
5967 	&imap_service_settings,
5968 	&imap_urlauth_worker_service_settings,
5969 	&imap_urlauth_service_settings,
5970 	&imap_urlauth_login_service_settings,
5971 	&imap_login_service_settings,
5972 	&imap_hibernate_service_settings,
5973 	&doveadm_service_settings,
5974 	&dns_client_service_settings,
5975 	&director_service_settings,
5976 	&dict_service_settings,
5977 	&dict_async_service_settings,
5978 	&config_service_settings,
5979 	&auth_service_settings,
5980 	&auth_worker_service_settings,
5981 	&anvil_service_settings,
5982 };
5983 buffer_t config_all_services_buf = {
5984 	{ { config_all_services, sizeof(config_all_services) } }
5985 };
5986 const struct setting_parser_info *all_default_roots[] = {
5987 	&master_service_setting_parser_info,
5988 	&master_service_ssl_setting_parser_info,
5989 	&master_service_ssl_server_setting_parser_info,
5990 	&smtp_submit_setting_parser_info,
5991 	&aggregator_setting_parser_info,
5992 	&auth_setting_parser_info,
5993 	&dict_setting_parser_info,
5994 	&director_setting_parser_info,
5995 	&doveadm_setting_parser_info,
5996 	&fs_crypt_setting_parser_info,
5997 	&imap_login_setting_parser_info,
5998 	&imap_setting_parser_info,
5999 	&imap_urlauth_login_setting_parser_info,
6000 	&imap_urlauth_setting_parser_info,
6001 	&imap_urlauth_worker_setting_parser_info,
6002 	&imapc_setting_parser_info,
6003 	&lda_setting_parser_info,
6004 	&lmtp_setting_parser_info,
6005 	&login_setting_parser_info,
6006 	&mail_storage_setting_parser_info,
6007 	&mail_user_setting_parser_info,
6008 	&maildir_setting_parser_info,
6009 	&master_setting_parser_info,
6010 	&mbox_setting_parser_info,
6011 	&mdbox_setting_parser_info,
6012 	&old_stats_setting_parser_info,
6013 	&pop3_login_setting_parser_info,
6014 	&pop3_setting_parser_info,
6015 	&pop3c_setting_parser_info,
6016 	&quota_status_setting_parser_info,
6017 	&replicator_setting_parser_info,
6018 	&stats_setting_parser_info,
6019 	&submission_login_setting_parser_info,
6020 	&submission_setting_parser_info,
6021 	NULL
6022 };
6023 const struct setting_parser_info *const *all_roots = all_default_roots;
6024 ARRAY_TYPE(service_settings) *default_services = &master_default_settings.services;
6025