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 |
}
|