~ubuntu-branches/ubuntu/trusty/dovecot/trusty-updates

1.13.12 by Jaldhar H. Vyas
Import upstream version 2.2.5
1
/* Copyright (c) 2009-2013 Dovecot authors, see the included COPYING file */
1.13.8 by Marco Nenciarini
Import upstream version 2.0.11
2
3
#include "lib.h"
4
#include "str.h"
5
#include "settings-parser.h"
6
#include "config-parser-private.h"
7
#include "old-set-parser.h"
8
1.13.12 by Jaldhar H. Vyas
Import upstream version 2.2.5
9
#define config_apply_line (void)config_apply_line
10
1.13.8 by Marco Nenciarini
Import upstream version 2.0.11
11
struct socket_set {
12
	const char *path, *mode, *user, *group;
13
	bool master;
14
};
15
16
struct old_set_parser {
17
	const char *base_dir;
18
	/* 1 when in auth {} section, >1 when inside auth { .. { .. } } */
19
	unsigned int auth_section;
20
	/* 1 when in socket listen {}, >1 when inside more of its sections */
21
	unsigned int socket_listen_section;
22
	bool seen_auth_section;
23
	struct socket_set socket_set;
24
};
25
26
static const struct config_filter any_filter = {
27
	.service = NULL
28
};
29
30
static const struct config_filter imap_filter = {
31
	.service = "imap"
32
};
33
static const struct config_filter pop3_filter = {
34
	.service = "pop3"
35
};
36
static const struct config_filter managesieve_filter = {
37
	.service = "sieve"
38
};
39
40
static void ATTR_FORMAT(2, 3)
41
obsolete(struct config_parser_context *ctx, const char *str, ...)
42
{
43
	static bool seen_obsoletes = FALSE;
44
	va_list args;
45
46
	if (!seen_obsoletes) {
47
		i_warning("NOTE: You can get a new clean config file with: "
48
			  "doveconf -n > dovecot-new.conf");
49
		seen_obsoletes = TRUE;
50
	}
51
52
	va_start(args, str);
53
	i_warning("Obsolete setting in %s:%u: %s",
54
		  ctx->cur_input->path, ctx->cur_input->linenum,
55
		  t_strdup_vprintf(str, args));
56
	va_end(args);
57
}
58
59
static void set_rename(struct config_parser_context *ctx,
60
		       const char *old_key, const char *key, const char *value)
61
{
62
	obsolete(ctx, "%s has been renamed to %s", old_key, key);
63
	config_parser_apply_line(ctx, CONFIG_LINE_TYPE_KEYVALUE, key, value);
64
}
65
66
static bool
67
old_settings_handle_root(struct config_parser_context *ctx,
68
			 const char *key, const char *value)
69
{
70
	const char *p;
71
	unsigned int len;
72
73
	if (strcmp(key, "base_dir") == 0) {
74
		len = strlen(value);
75
		if (len > 0 && value[len-1] == '/')
76
			value = t_strndup(value, len-1);
77
		ctx->old->base_dir = p_strdup(ctx->pool, value);
78
	}
79
	if (strcmp(key, "protocols") == 0) {
80
		char **protos, **s;
81
		bool have_imap = FALSE, have_imaps = FALSE;
82
		bool have_pop3 = FALSE, have_pop3s = FALSE;
83
84
		protos = p_strsplit_spaces(pool_datastack_create(), value, " ");
85
		for (s = protos; *s != NULL; s++) {
86
			if (strcmp(*s, "imap") == 0)
87
				have_imap = TRUE;
88
			else if (strcmp(*s, "imaps") == 0) {
89
				*s = "";
90
				have_imaps = TRUE;
91
			} else if (strcmp(*s, "pop3") == 0)
92
				have_pop3 = TRUE;
93
			else if (strcmp(*s, "pop3s") == 0) {
94
				*s = "";
95
				have_pop3s = TRUE;
96
			} else if (strcmp(*s, "managesieve") == 0) {
97
				*s = "sieve";
98
				obsolete(ctx, "protocols=managesieve has been renamed to protocols=sieve");
99
			}
100
		}
101
		value = t_strarray_join((const char *const *)protos, " ");
102
		/* ugly way to drop extra spaces.. */
103
		protos = p_strsplit_spaces(pool_datastack_create(), value, " ");
104
		value = t_strarray_join((const char *const *)protos, " ");
105
106
		if (have_imaps && !have_imap) {
1.13.12 by Jaldhar H. Vyas
Import upstream version 2.2.5
107
			obsolete(ctx, "'imaps' protocol can no longer be specified (use protocols=imap). to disable non-ssl imap, use service imap-login { inet_listener imap { port=0 } }");
1.13.8 by Marco Nenciarini
Import upstream version 2.0.11
108
			value = t_strconcat(value, " imap", NULL);
109
			config_apply_line(ctx, "port",
110
				"service/imap-login/inet_listener/imap/port=0", NULL);
111
		} else if (have_imaps)
1.14.2 by Marco Nenciarini
Import upstream version 2.0.13
112
			obsolete(ctx, "'imaps' protocol is no longer necessary, remove it");
1.13.8 by Marco Nenciarini
Import upstream version 2.0.11
113
		if (have_pop3s && !have_pop3) {
1.13.12 by Jaldhar H. Vyas
Import upstream version 2.2.5
114
			obsolete(ctx, "'pop3s' protocol can no longer be specified (use protocols=pop3). to disable non-ssl pop3, use service pop3-login { inet_listener pop3 { port=0 } }");
1.13.8 by Marco Nenciarini
Import upstream version 2.0.11
115
			value = t_strconcat(value, " pop3", NULL);
116
			config_apply_line(ctx, "port",
117
				"service/pop3-login/inet_listener/pop3/port=0", NULL);
118
		} else if (have_pop3s)
1.14.2 by Marco Nenciarini
Import upstream version 2.0.13
119
			obsolete(ctx, "'pop3s' protocol is no longer necessary, remove it");
1.13.8 by Marco Nenciarini
Import upstream version 2.0.11
120
121
		if (*value == ' ') value++;
122
		config_parser_apply_line(ctx, CONFIG_LINE_TYPE_KEYVALUE,
123
					 key, value);
124
		return TRUE;
125
	}
126
	if (strcmp(key, "ssl_cert_file") == 0 ||
127
	    strcmp(key, "ssl_key_file") == 0 ||
128
	    strcmp(key, "ssl_ca_file") == 0) {
129
		if (*value == '\0')
130
			return TRUE;
131
		p = t_strdup_until(key, strrchr(key, '_'));
132
		obsolete(ctx, "%s has been replaced by %s = <file", key, p);
133
		config_parser_apply_line(ctx, CONFIG_LINE_TYPE_KEYFILE,
134
					 p, value);
135
		return TRUE;
136
	}
137
	if (strcmp(key, "ssl_disable") == 0) {
138
		if (strcasecmp(value, "yes") == 0)
139
			value = "no";
140
		else if (strcasecmp(value, "no") == 0)
141
			value = "yes";
142
		set_rename(ctx, key, "ssl", value);
143
		return TRUE;
144
	}
1.13.9 by Micah Anderson
Import upstream version 2.1.3
145
	if (strcmp(key, "ssl_parameters_regenerate") == 0 &&
146
	    str_is_numeric(value, '\0') && strcmp(value, "0") != 0) {
147
		obsolete(ctx, "%s should have 'hours' suffix", key);
148
		config_apply_line(ctx, "", t_strconcat(key, "=", value, "h", NULL), NULL);
149
		return TRUE;
150
	}
1.13.8 by Marco Nenciarini
Import upstream version 2.0.11
151
	if (strcmp(key, "sieve") == 0 ||
152
	    strcmp(key, "sieve_storage") == 0) {
153
		if (strcmp(key, "sieve_storage") == 0)
154
			obsolete(ctx, "sieve_storage has been moved into plugin { sieve_dir }");
155
		else
156
			obsolete(ctx, "%s has been moved into plugin {} section", key);
157
158
		config_apply_line(ctx, "", "plugin=", NULL);
159
		config_apply_line(ctx, key,
160
			t_strdup_printf("plugin/%s=%s", key, value), NULL);
161
		return TRUE;
162
	}
163
	if (strcmp(key, "fsync_disable") == 0) {
164
		if (strcasecmp(value, "yes") == 0)
165
			value = "never";
166
		else if (strcasecmp(value, "no") == 0)
167
			value = "optimized";
168
		set_rename(ctx, key, "mail_fsync", value);
169
		return TRUE;
170
	}
171
	if (strcmp(key, "dbox_rotate_size") == 0) {
172
		set_rename(ctx, key, "mdbox_rotate_size", value);
173
		return TRUE;
174
	}
175
	if (strcmp(key, "imap_client_workarounds") == 0) {
176
		char **args, **arg;
177
178
		args = p_strsplit_spaces(pool_datastack_create(), value, " ,");
179
		for (arg = args; *arg != NULL; arg++) {
180
			if (strcmp(*arg, "outlook-idle") == 0) {
181
				*arg = "";
182
				obsolete(ctx, "imap_client_workarounds=outlook-idle is no longer necessary");
183
			} else if (strcmp(*arg, "netscape-eoh") == 0) {
184
				*arg = "";
185
				obsolete(ctx, "imap_client_workarounds=netscape-eoh is no longer supported");
186
			}
187
		}
188
		value = t_strarray_join((void *)args, " ");
189
		config_parser_apply_line(ctx, CONFIG_LINE_TYPE_KEYVALUE,
190
					 key, value);
191
		return TRUE;
192
	}
193
194
	if (strcmp(key, "login_dir") == 0 ||
195
	    strcmp(key, "dbox_rotate_min_size") == 0 ||
196
	    strcmp(key, "dbox_rotate_days") == 0 ||
197
	    strcmp(key, "mail_log_max_lines_per_sec") == 0 ||
198
	    strcmp(key, "maildir_copy_preserve_filename") == 0) {
199
		obsolete(ctx, "%s has been removed", key);
200
		return TRUE;
201
	}
202
	if (ctx->old->auth_section == 1) {
203
		if (strncmp(key, "auth_", 5) != 0)
204
			key = t_strconcat("auth_", key, NULL);
205
		config_parser_apply_line(ctx, CONFIG_LINE_TYPE_KEYVALUE,
206
					 key, value);
207
		return TRUE;
208
	}
209
	return FALSE;
210
}
211
212
static void
213
config_apply_login_set(struct config_parser_context *ctx,
214
		       struct config_section_stack *old_section,
215
		       const char *old_key, const char *key, const char *value)
216
{
217
	obsolete(ctx, "%s has been replaced by service { %s }", old_key, key);
218
219
	if (config_filter_match(&old_section->filter, &imap_filter)) {
220
		config_apply_line(ctx, key,
221
			t_strdup_printf("service/imap-login/%s=%s", key, value), NULL);
222
	}
223
	if (config_filter_match(&old_section->filter, &pop3_filter)) {
224
		config_apply_line(ctx, key,
225
			t_strdup_printf("service/pop3-login/%s=%s", key, value), NULL);
226
	}
227
	if (config_filter_match(&old_section->filter, &managesieve_filter)) {
228
		/* if pigeonhole isn't installed, this fails.
229
		   just ignore it then.. */
230
		config_apply_line(ctx, key,
231
			t_strdup_printf("service/managesieve-login/%s=%s", key, value), NULL);
232
		ctx->error = NULL;
233
	}
234
}
235
236
static void
237
config_apply_mail_set(struct config_parser_context *ctx,
238
		      struct config_section_stack *old_section,
239
		      const char *old_key, const char *key, const char *value)
240
{
241
	obsolete(ctx, "%s has been replaced by service { %s }", old_key, key);
242
243
	if (config_filter_match(&old_section->filter, &imap_filter)) {
244
		config_apply_line(ctx, key,
245
			t_strdup_printf("service/imap/%s=%s", key,value), NULL);
246
	}
247
	if (config_filter_match(&old_section->filter, &pop3_filter)) {
248
		config_apply_line(ctx, key,
249
			t_strdup_printf("service/pop3/%s=%s", key,value), NULL);
250
	}
251
	if (config_filter_match(&old_section->filter, &managesieve_filter)) {
252
		config_apply_line(ctx, key,
253
			t_strdup_printf("service/managesieve/%s=%s", key,value), NULL);
254
		ctx->error = NULL;
255
	}
256
}
257
258
static void
259
config_apply_auth_set(struct config_parser_context *ctx,
260
		      const char *old_key, const char *key, const char *value)
261
{
262
	obsolete(ctx, "%s has been replaced by service auth { %s }", old_key, key);
263
	config_apply_line(ctx, key,
264
		t_strdup_printf("service/auth/%s=%s", key,value), NULL);
265
}
266
267
static bool listen_has_port(const char *str)
268
{
269
	const char *const *addrs;
270
271
	if (strchr(str, ':') == NULL)
272
		return FALSE;
273
274
	addrs = t_strsplit_spaces(str, ", ");
275
	for (; *addrs != NULL; addrs++) {
276
		if (strcmp(*addrs, "*") != 0 &&
277
		    strcmp(*addrs, "::") != 0 &&
278
		    strcmp(*addrs, "[::]") != 0 &&
279
		    !is_ipv4_address(*addrs) &&
280
		    !is_ipv6_address(*addrs))
281
			return TRUE;
282
	}
283
	return FALSE;
284
}
285
286
static bool
287
old_settings_handle_proto(struct config_parser_context *ctx,
288
			  const char *key, const char *value)
289
{
290
	struct config_section_stack *old_section = ctx->cur_section;
291
	const char *p;
292
	uoff_t size;
293
	bool root;
294
295
	while (ctx->cur_section->prev != NULL)
296
		ctx->cur_section = ctx->cur_section->prev;
297
298
	root = config_filter_match(&old_section->filter, &any_filter);
299
300
	if (strcmp(key, "ssl_listen") == 0 ||
301
	    (strcmp(key, "listen") == 0 &&
302
	     (listen_has_port(value) || !root))) {
303
		const char *ssl = strcmp(key, "ssl_listen") == 0 ? "s" : "";
304
305
		if (*value == '\0') {
306
			/* default */
307
			return TRUE;
308
		}
309
		p = strrchr(value, ':');
1.13.11 by Jaldhar H. Vyas
Import upstream version 2.1.17
310
		if (p != NULL && listen_has_port(value)) {
1.13.8 by Marco Nenciarini
Import upstream version 2.0.11
311
			obsolete(ctx, "%s=..:port has been replaced by service { inet_listener { port } }", key);
312
			value = t_strdup_until(value, p++);
313
			if (config_filter_match(&old_section->filter, &imap_filter)) {
314
				config_apply_line(ctx, "port",
315
					t_strdup_printf("service/imap-login/inet_listener/imap%s/port=%s", ssl, p), NULL);
316
			}
317
			if (config_filter_match(&old_section->filter, &pop3_filter)) {
318
				config_apply_line(ctx, "port",
319
					t_strdup_printf("service/pop3-login/inet_listener/pop3%s/port=%s", ssl, p), NULL);
320
			}
321
			if (*ssl == '\0' &&
322
			    config_filter_match(&old_section->filter, &managesieve_filter)) {
323
				config_apply_line(ctx, "port",
324
					t_strdup_printf("service/managesieve-login/inet_listener/managesieve/port=%s", p), NULL);
325
				ctx->error = NULL;
326
			}
327
		}
328
		if (root && *ssl == '\0') {
329
			config_parser_apply_line(ctx, CONFIG_LINE_TYPE_KEYVALUE,
330
						 key, value);
331
		} else {
332
			obsolete(ctx, "protocol { %s } has been replaced by service { inet_listener { address } }", key);
333
			if (config_filter_match(&old_section->filter, &imap_filter)) {
334
				config_apply_line(ctx, "address",
335
					t_strdup_printf("service/imap-login/inet_listener/imap%s/address=%s", ssl, value), NULL);
336
			}
337
			if (config_filter_match(&old_section->filter, &pop3_filter)) {
338
				config_apply_line(ctx, "address",
339
					t_strdup_printf("service/pop3-login/inet_listener/pop3%s/address=%s", ssl, value), NULL);
340
			}
341
			if (*ssl == '\0' &&
342
			    config_filter_match(&old_section->filter, &managesieve_filter)) {
343
				config_apply_line(ctx, "address",
344
					t_strdup_printf("service/managesieve-login/inet_listener/managesieve/address=%s", value), NULL);
345
				ctx->error = NULL;
346
			}
347
		}
348
		return TRUE;
349
	}
350
	if (strcmp(key, "login_chroot") == 0) {
351
		if (strcmp(value, "no") == 0)
352
			value = "";
353
		else
354
			value = "login";
355
356
		config_apply_login_set(ctx, old_section, key, "chroot", value);
357
		return TRUE;
358
	}
359
	if (strcmp(key, "login_user") == 0) {
360
		config_apply_login_set(ctx, old_section, key, "user", value);
361
		return TRUE;
362
	}
363
	if (strcmp(key, "login_executable") == 0) {
364
		config_apply_login_set(ctx, old_section, key, "executable", value);
365
		return TRUE;
366
	}
367
	if (strcmp(key, "login_process_size") == 0) {
368
		config_apply_login_set(ctx, old_section, key, "vsz_limit",
369
				       t_strconcat(value, " M", NULL));
370
		return TRUE;
371
	}
372
	if (strcmp(key, "login_process_per_connection") == 0) {
373
		config_apply_login_set(ctx, old_section, key, "service_count",
374
				       strcmp(value, "no") == 0 ? "0" : "1");
375
		return TRUE;
376
	}
377
	if (strcmp(key, "login_processes_count") == 0) {
378
		config_apply_login_set(ctx, old_section, key, "process_min_avail", value);
379
		return TRUE;
380
	}
381
	if (strcmp(key, "login_max_processes_count") == 0) {
382
		config_apply_login_set(ctx, old_section, key, "process_limit", value);
383
		return TRUE;
384
	}
385
	if (strcmp(key, "login_max_connections") == 0) {
386
		config_apply_login_set(ctx, old_section, key, "client_limit", value);
387
		return TRUE;
388
	}
389
	if (strcmp(key, "login_process_size") == 0) {
390
		config_apply_login_set(ctx, old_section, key, "vsz_limit",
391
				       t_strconcat(value, " M", NULL));
392
		return TRUE;
393
	}
394
395
	if (strcmp(key, "max_mail_processes") == 0) {
396
		config_apply_mail_set(ctx, old_section, key, "process_limit", value);
397
		return TRUE;
398
	}
399
	if (strcmp(key, "mail_executable") == 0) {
400
		config_apply_mail_set(ctx, old_section, key, "executable", value);
401
		return TRUE;
402
	}
403
	if (strcmp(key, "mail_process_size") == 0) {
404
		config_apply_mail_set(ctx, old_section, key, "vsz_limit",
405
				      t_strconcat(value, " M", NULL));
406
		return TRUE;
407
	}
408
	if (strcmp(key, "mail_drop_priv_before_exec") == 0) {
409
		config_apply_mail_set(ctx, old_section, key, "drop_priv_before_exec", value);
410
		return TRUE;
411
	}
412
413
	if (ctx->old->auth_section == 1) {
414
		if (strncmp(key, "auth_", 5) != 0)
415
			key = t_strconcat("auth_", key, NULL);
416
	}
417
418
	if (strcmp(key, "auth_executable") == 0) {
419
		config_apply_auth_set(ctx, key, "executable", value);
420
		return TRUE;
421
	}
422
	if (strcmp(key, "auth_process_size") == 0) {
423
		config_apply_auth_set(ctx, key, "vsz_limit",
424
				      t_strconcat(value, " M", NULL));
425
		return TRUE;
426
	}
427
	if (strcmp(key, "auth_user") == 0) {
428
		config_apply_auth_set(ctx, key, "user", value);
429
		return TRUE;
430
	}
431
	if (strcmp(key, "auth_chroot") == 0) {
432
		config_apply_auth_set(ctx, key, "chroot", value);
433
		return TRUE;
434
	}
435
	if (strcmp(key, "auth_cache_size") == 0 &&
436
	    str_to_uoff(value, &size) == 0 && size > 0 && size < 1024) {
437
		obsolete(ctx, "auth_cache_size value no longer defaults to "
438
			 "megabytes. Use %sM", value);
439
		config_apply_line(ctx, key,
440
				  t_strdup_printf("%s=%sM", key, value), NULL);
441
		return TRUE;
442
	}
443
	if (strcmp(key, "auth_count") == 0) {
444
		if (strcmp(value, "count") == 0)
445
			obsolete(ctx, "auth_count has been removed");
446
		else
447
			obsolete(ctx, "auth_count has been removed, and its value must be 1");
448
		return TRUE;
449
	}
450
	if (ctx->old->socket_listen_section == 2) {
451
		const char **p = NULL;
452
453
		if (strcmp(key, "path") == 0)
454
			p = &ctx->old->socket_set.path;
455
		else if (strcmp(key, "mode") == 0)
456
			p = &ctx->old->socket_set.mode;
457
		else if (strcmp(key, "user") == 0)
458
			p = &ctx->old->socket_set.user;
459
		else if (strcmp(key, "group") == 0)
460
			p = &ctx->old->socket_set.group;
461
462
		if (p != NULL) {
463
			*p = p_strdup(ctx->pool, value);
464
			return TRUE;
465
		}
466
	}
467
	return FALSE;
468
}
469
470
static bool old_auth_section(struct config_parser_context *ctx,
471
			     const char *key, const char *value)
472
{
473
	if (ctx->old->auth_section == 0 && ctx->old->seen_auth_section) {
474
		obsolete(ctx, "Multiple auth sections are no longer supported");
475
		return FALSE;
476
	}
477
	ctx->old->seen_auth_section = TRUE;
478
	memset(&ctx->old->socket_set, 0, sizeof(ctx->old->socket_set));
479
480
	ctx->old->auth_section++;
481
	if ((strcmp(key, "passdb") == 0 || strcmp(key, "userdb") == 0) &&
482
	    ctx->old->auth_section == 2) {
483
		obsolete(ctx, "%s %s {} has been replaced by %s { driver=%s }",
484
			 key, value, key, value);
485
		config_parser_apply_line(ctx, CONFIG_LINE_TYPE_SECTION_BEGIN, key, "");
486
		config_parser_apply_line(ctx, CONFIG_LINE_TYPE_KEYVALUE,
487
					 "driver", value);
488
		return TRUE;
489
	}
490
	if (strcmp(key, "socket") == 0 && ctx->old->auth_section == 2) {
491
		if (strcmp(value, "connect") == 0) {
492
			obsolete(ctx, "socket connect {} is no longer supported, configure external auth server separately");
493
			return FALSE;
494
		}
495
		if (strcmp(value, "listen") != 0)
496
			return FALSE;
497
498
		/* socket listen { .. } */
499
		ctx->old->socket_listen_section++;
500
		return TRUE;
501
	}
502
503
	if (ctx->old->socket_listen_section > 0)
504
		ctx->old->socket_listen_section++;
505
	if ((strcmp(key, "master") == 0 || strcmp(key, "client") == 0) &&
506
	    ctx->old->socket_listen_section == 2) {
507
		ctx->old->socket_set.master = strcmp(key, "master") == 0;
508
		return TRUE;
509
	}
510
	return FALSE;
511
}
512
513
static bool old_namespace(struct config_parser_context *ctx,
514
			  const char *value)
515
{
516
	if (strcmp(value, "private") != 0 &&
517
	    strcmp(value, "shared") != 0 &&
518
	    strcmp(value, "public") != 0)
519
		return FALSE;
520
521
	obsolete(ctx, "namespace %s {} has been replaced by namespace { type=%s }", value, value);
522
	config_parser_apply_line(ctx, CONFIG_LINE_TYPE_SECTION_BEGIN, "namespace", "");
523
	config_parser_apply_line(ctx, CONFIG_LINE_TYPE_KEYVALUE,
524
				 "type", value);
525
	return TRUE;
526
}
527
528
static void socket_apply(struct config_parser_context *ctx)
529
{
530
	const struct socket_set *set = &ctx->old->socket_set;
531
	const char *path, *prefix;
532
	unsigned int len;
533
	bool master_suffix;
534
535
	if (set->path == NULL) {
536
		ctx->error = "socket listen {} is missing path";
537
		return;
538
	}
539
	path = set->path;
540
	len = strlen(ctx->old->base_dir);
541
	if (strncmp(path, ctx->old->base_dir, len) == 0 &&
542
	    path[len] == '/')
543
		path += len + 1;
544
545
	len = strlen(path);
546
	master_suffix = len >= 7 &&
547
		(strcmp(path + len - 7, "-master") == 0 ||
548
		 strcmp(path + len - 7, "-userdb") == 0);
549
550
	if (set->master && !master_suffix) {
551
		ctx->error = "socket listen { master { path=.. } } must end with -master (or -userdb) suffix";
552
		return;
553
	} else if (!set->master && master_suffix) {
554
		ctx->error = "socket listen { client { path=.. } } must end not with -master or -userdb suffix";
555
		return;
556
	}
557
558
	config_apply_line(ctx, "unix_listener",
559
		t_strdup_printf("service/auth/unix_listener=%s", settings_section_escape(path)), path);
560
	prefix = t_strdup_printf("service/auth/unix_listener/%s", settings_section_escape(path));
561
	if (set->mode != NULL) {
562
		config_apply_line(ctx, "mode",
563
			  t_strdup_printf("%s/mode=%s", prefix, set->mode), NULL);
564
	}
565
	if (set->user != NULL) {
566
		config_apply_line(ctx, "user",
567
			  t_strdup_printf("%s/user=%s", prefix, set->user), NULL);
568
	}
569
	if (set->group != NULL) {
570
		config_apply_line(ctx, "group",
571
			  t_strdup_printf("%s/group=%s", prefix, set->group), NULL);
572
	}
573
	memset(&ctx->old->socket_set, 0, sizeof(ctx->old->socket_set));
574
}
575
576
bool old_settings_handle(struct config_parser_context *ctx,
577
			 enum config_line_type type,
578
			 const char *key, const char *value)
579
{
580
	switch (type) {
581
	case CONFIG_LINE_TYPE_SKIP:
582
	case CONFIG_LINE_TYPE_ERROR:
583
	case CONFIG_LINE_TYPE_INCLUDE:
584
	case CONFIG_LINE_TYPE_INCLUDE_TRY:
585
	case CONFIG_LINE_TYPE_KEYFILE:
586
	case CONFIG_LINE_TYPE_KEYVARIABLE:
587
		break;
588
	case CONFIG_LINE_TYPE_KEYVALUE:
589
		if (ctx->pathlen == 0) {
590
			struct config_section_stack *old_section =
591
				ctx->cur_section;
592
			bool ret;
593
594
			ret = old_settings_handle_proto(ctx, key, value);
595
			ctx->cur_section = old_section;
596
			if (ret)
597
				return TRUE;
598
599
			return old_settings_handle_root(ctx, key, value);
600
		}
601
		break;
602
	case CONFIG_LINE_TYPE_SECTION_BEGIN:
603
		if (ctx->old->auth_section > 0)
604
			return old_auth_section(ctx, key, value);
605
		else if (ctx->pathlen == 0 && strcmp(key, "auth") == 0) {
606
			obsolete(ctx, "add auth_ prefix to all settings inside auth {} and remove the auth {} section completely");
607
			ctx->old->auth_section = 1;
608
			return TRUE;
609
		} else if (ctx->pathlen == 0 && strcmp(key, "namespace") == 0)
610
			return old_namespace(ctx, value);
611
		else if (ctx->pathlen == 0 && strcmp(key, "protocol") == 0 &&
612
			 strcmp(value, "managesieve") == 0) {
613
			obsolete(ctx, "protocol managesieve {} has been replaced by protocol sieve { }");
614
			config_parser_apply_line(ctx, CONFIG_LINE_TYPE_SECTION_BEGIN,
615
						 "protocol", "sieve");
616
			return TRUE;
617
		}
618
		break;
619
	case CONFIG_LINE_TYPE_SECTION_END:
620
		if (ctx->old->auth_section > 0) {
621
			if (--ctx->old->auth_section == 0)
622
				return TRUE;
623
		}
624
		if (ctx->old->socket_listen_section > 0) {
625
			if (ctx->old->socket_listen_section == 2)
626
				socket_apply(ctx);
627
			ctx->old->socket_listen_section--;
628
			return TRUE;
629
		}
630
		break;
631
	}
632
	return FALSE;
633
}
634
635
void old_settings_init(struct config_parser_context *ctx)
636
{
637
	ctx->old = p_new(ctx->pool, struct old_set_parser, 1);
638
	ctx->old->base_dir = PKG_RUNDIR;
639
}