1 /* Copyright (c) 2005-2018 Dovecot authors, see the included COPYING file */
2
3 #include "lib.h"
4 #include "array.h"
5 #include "hash-method.h"
6 #include "settings-parser.h"
7 #include "master-service-private.h"
8 #include "master-service-settings.h"
9 #include "service-settings.h"
10 #include "auth-settings.h"
11
12 #include <stddef.h>
13
14 static bool auth_settings_check(void *_set, pool_t pool, const char **error_r);
15 static bool auth_passdb_settings_check(void *_set, pool_t pool, const char **error_r);
16 static bool auth_userdb_settings_check(void *_set, pool_t pool, const char **error_r);
17
18 /* <settings checks> */
19 static struct file_listener_settings auth_unix_listeners_array[] = {
20 { "login/login", 0666, "", "" },
21 { "token-login/tokenlogin", 0666, "", "" },
22 { "auth-login", 0600, "$default_internal_user", "" },
23 { "auth-client", 0600, "$default_internal_user", "" },
24 { "auth-userdb", 0666, "$default_internal_user", "" },
25 { "auth-master", 0600, "", "" }
26 };
27 static struct file_listener_settings *auth_unix_listeners[] = {
28 &auth_unix_listeners_array[0],
29 &auth_unix_listeners_array[1],
30 &auth_unix_listeners_array[2],
31 &auth_unix_listeners_array[3],
32 &auth_unix_listeners_array[4],
33 &auth_unix_listeners_array[5]
34 };
35 static buffer_t auth_unix_listeners_buf = {
36 { { auth_unix_listeners, sizeof(auth_unix_listeners) } }
37 };
38 /* </settings checks> */
39
40 struct service_settings auth_service_settings = {
41 .name = "auth",
42 .protocol = "",
43 .type = "",
44 .executable = "auth",
45 .user = "$default_internal_user",
46 .group = "",
47 .privileged_group = "",
48 .extra_groups = "",
49 .chroot = "",
50
51 .drop_priv_before_exec = FALSE,
52
53 .process_min_avail = 0,
54 .process_limit = 1,
55 .client_limit = 0,
56 .service_count = 0,
57 .idle_kill = 0,
58 .vsz_limit = UOFF_T_MAX,
59
60 .unix_listeners = { { &auth_unix_listeners_buf,
61 sizeof(auth_unix_listeners[0]) } },
62 .fifo_listeners = ARRAY_INIT,
63 .inet_listeners = ARRAY_INIT,
64
65 .process_limit_1 = TRUE
66 };
67
68 /* <settings checks> */
69 static struct file_listener_settings auth_worker_unix_listeners_array[] = {
70 { "auth-worker", 0600, "$default_internal_user", "" }
71 };
72 static struct file_listener_settings *auth_worker_unix_listeners[] = {
73 &auth_worker_unix_listeners_array[0]
74 };
75 static buffer_t auth_worker_unix_listeners_buf = {
76 { { auth_worker_unix_listeners, sizeof(auth_worker_unix_listeners) } }
77 };
78 /* </settings checks> */
79
80 struct service_settings auth_worker_service_settings = {
81 .name = "auth-worker",
82 .protocol = "",
83 .type = "worker",
84 .executable = "auth -w",
85 .user = "",
86 .group = "",
87 .privileged_group = "",
88 .extra_groups = "",
89 .chroot = "",
90
91 .drop_priv_before_exec = FALSE,
92
93 .process_min_avail = 0,
94 .process_limit = 0,
95 .client_limit = 1,
96 .service_count = 0,
97 .idle_kill = 0,
98 .vsz_limit = UOFF_T_MAX,
99
100 .unix_listeners = { { &auth_worker_unix_listeners_buf,
101 sizeof(auth_worker_unix_listeners[0]) } },
102 .fifo_listeners = ARRAY_INIT,
103 .inet_listeners = ARRAY_INIT
104 };
105
106 #undef DEF
107 #define DEF(type, name) \
108 SETTING_DEFINE_STRUCT_##type(#name, name, struct auth_passdb_settings)
109
110 static const struct setting_define auth_passdb_setting_defines[] = {
111 DEF(STR, name),
112 DEF(STR, driver),
113 DEF(STR, args),
114 DEF(STR, default_fields),
115 DEF(STR, override_fields),
116 DEF(STR, mechanisms),
117 DEF(STR, username_filter),
118
119 DEF(ENUM, skip),
120 DEF(ENUM, result_success),
121 DEF(ENUM, result_failure),
122 DEF(ENUM, result_internalfail),
123
124 DEF(BOOL, deny),
125 DEF(BOOL, pass),
126 DEF(BOOL, master),
127 DEF(ENUM, auth_verbose),
128
129 SETTING_DEFINE_LIST_END
130 };
131
132 static const struct auth_passdb_settings auth_passdb_default_settings = {
133 .name = "",
134 .driver = "",
135 .args = "",
136 .default_fields = "",
137 .override_fields = "",
138 .mechanisms = "",
139 .username_filter = "",
140
141 .skip = "never:authenticated:unauthenticated",
142 .result_success = "return-ok:return:return-fail:continue:continue-ok:continue-fail",
143 .result_failure = "continue:return:return-ok:return-fail:continue-ok:continue-fail",
144 .result_internalfail = "continue:return:return-ok:return-fail:continue-ok:continue-fail",
145
146 .deny = FALSE,
147 .pass = FALSE,
148 .master = FALSE,
149 .auth_verbose = "default:yes:no"
150 };
151
152 const struct setting_parser_info auth_passdb_setting_parser_info = {
153 .defines = auth_passdb_setting_defines,
154 .defaults = &auth_passdb_default_settings,
155
156 .type_offset = offsetof(struct auth_passdb_settings, name),
157 .struct_size = sizeof(struct auth_passdb_settings),
158
159 .parent_offset = SIZE_MAX,
160 .parent = &auth_setting_parser_info,
161
162 .check_func = auth_passdb_settings_check
163 };
164
165 #undef DEF
166 #define DEF(type, name) \
167 SETTING_DEFINE_STRUCT_##type(#name, name, struct auth_userdb_settings)
168
169 static const struct setting_define auth_userdb_setting_defines[] = {
170 DEF(STR, name),
171 DEF(STR, driver),
172 DEF(STR, args),
173 DEF(STR, default_fields),
174 DEF(STR, override_fields),
175
176 DEF(ENUM, skip),
177 DEF(ENUM, result_success),
178 DEF(ENUM, result_failure),
179 DEF(ENUM, result_internalfail),
180
181 DEF(ENUM, auth_verbose),
182
183 SETTING_DEFINE_LIST_END
184 };
185
186 static const struct auth_userdb_settings auth_userdb_default_settings = {
187 /* NOTE: when adding fields, update also auth.c:userdb_dummy_set */
188 .name = "",
189 .driver = "",
190 .args = "",
191 .default_fields = "",
192 .override_fields = "",
193
194 .skip = "never:found:notfound",
195 .result_success = "return-ok:return:return-fail:continue:continue-ok:continue-fail",
196 .result_failure = "continue:return:return-ok:return-fail:continue-ok:continue-fail",
197 .result_internalfail = "continue:return:return-ok:return-fail:continue-ok:continue-fail",
198
199 .auth_verbose = "default:yes:no"
200 };
201
202 const struct setting_parser_info auth_userdb_setting_parser_info = {
203 .defines = auth_userdb_setting_defines,
204 .defaults = &auth_userdb_default_settings,
205
206 .type_offset = offsetof(struct auth_userdb_settings, name),
207 .struct_size = sizeof(struct auth_userdb_settings),
208
209 .parent_offset = SIZE_MAX,
210 .parent = &auth_setting_parser_info,
211
212 .check_func = auth_userdb_settings_check
213 };
214
215 /* we're kind of kludging here to avoid "auth_" prefix in the struct fields */
216 #undef DEF
217 #undef DEF_NOPREFIX
218 #undef DEFLIST
219 #define DEF(type, name) \
220 SETTING_DEFINE_STRUCT_##type("auth_"#name, name, struct auth_settings)
221 #define DEF_NOPREFIX(type, name) \
222 SETTING_DEFINE_STRUCT_##type(#name, name, struct auth_settings)
223 #define DEFLIST(field, name, defines) \
224 { .type = SET_DEFLIST, .key = name, \
225 .offset = offsetof(struct auth_settings, field), \
226 .list_info = defines }
227
228 static const struct setting_define auth_setting_defines[] = {
229 DEF(STR, mechanisms),
230 DEF(STR, realms),
231 DEF(STR, default_realm),
232 DEF(SIZE, cache_size),
233 DEF(TIME, cache_ttl),
234 DEF(TIME, cache_negative_ttl),
235 DEF(BOOL, cache_verify_password_with_worker),
236 DEF(STR, username_chars),
237 DEF(STR, username_translation),
238 DEF(STR, username_format),
239 DEF(STR, master_user_separator),
240 DEF(STR, anonymous_username),
241 DEF(STR, krb5_keytab),
242 DEF(STR, gssapi_hostname),
243 DEF(STR, winbind_helper_path),
244 DEF(STR, proxy_self),
245 DEF(TIME, failure_delay),
246
247 DEF(STR, policy_server_url),
248 DEF(STR, policy_server_api_header),
249 DEF(UINT, policy_server_timeout_msecs),
250 DEF(STR, policy_hash_mech),
251 DEF(STR, policy_hash_nonce),
252 DEF(STR, policy_request_attributes),
253 DEF(BOOL, policy_reject_on_fail),
254 DEF(BOOL, policy_check_before_auth),
255 DEF(BOOL, policy_check_after_auth),
256 DEF(BOOL, policy_report_after_auth),
257 DEF(BOOL, policy_log_only),
258 DEF(UINT, policy_hash_truncate),
259
260 DEF(BOOL, stats),
261 DEF(BOOL, verbose),
262 DEF(BOOL, debug),
263 DEF(BOOL, debug_passwords),
264 DEF(STR, verbose_passwords),
265 DEF(BOOL, ssl_require_client_cert),
266 DEF(BOOL, ssl_username_from_cert),
267 DEF(BOOL, use_winbind),
268
269 DEF(UINT, worker_max_count),
270
271 DEFLIST(passdbs, "passdb", &auth_passdb_setting_parser_info),
272 DEFLIST(userdbs, "userdb", &auth_userdb_setting_parser_info),
273
274 DEF_NOPREFIX(STR, base_dir),
275 DEF_NOPREFIX(BOOL, verbose_proctitle),
276 DEF_NOPREFIX(UINT, first_valid_uid),
277 DEF_NOPREFIX(UINT, last_valid_uid),
278 DEF_NOPREFIX(UINT, first_valid_gid),
279 DEF_NOPREFIX(UINT, last_valid_gid),
280
281 DEF_NOPREFIX(STR, ssl_client_ca_dir),
282 DEF_NOPREFIX(STR, ssl_client_ca_file),
283
284 SETTING_DEFINE_LIST_END
285 };
286
287 static const struct auth_settings auth_default_settings = {
288 .mechanisms = "plain",
289 .realms = "",
290 .default_realm = "",
291 .cache_size = 0,
292 .cache_ttl = 60*60,
293 .cache_negative_ttl = 60*60,
294 .cache_verify_password_with_worker = FALSE,
295 .username_chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890.-_@",
296 .username_translation = "",
297 .username_format = "%Lu",
298 .master_user_separator = "",
299 .anonymous_username = "anonymous",
300 .krb5_keytab = "",
301 .gssapi_hostname = "",
302 .winbind_helper_path = "/usr/bin/ntlm_auth",
303 .proxy_self = "",
304 .failure_delay = 2,
305
306 .policy_server_url = "",
307 .policy_server_api_header = "",
308 .policy_server_timeout_msecs = 2000,
309 .policy_hash_mech = "sha256",
310 .policy_hash_nonce = "",
311 .policy_request_attributes = "login=%{requested_username} pwhash=%{hashed_password} remote=%{rip} device_id=%{client_id} protocol=%s session_id=%{session}",
312 .policy_reject_on_fail = FALSE,
313 .policy_check_before_auth = TRUE,
314 .policy_check_after_auth = TRUE,
315 .policy_report_after_auth = TRUE,
316 .policy_log_only = FALSE,
317 .policy_hash_truncate = 12,
318
319 .stats = FALSE,
320 .verbose = FALSE,
321 .debug = FALSE,
322 .debug_passwords = FALSE,
323 .verbose_passwords = "no",
324 .ssl_require_client_cert = FALSE,
325 .ssl_username_from_cert = FALSE,
326 .ssl_client_ca_dir = "",
327 .ssl_client_ca_file = "",
328
329 .use_winbind = FALSE,
330
331 .worker_max_count = 30,
332
333 .passdbs = ARRAY_INIT,
334 .userdbs = ARRAY_INIT,
335
336 .base_dir = PKG_RUNDIR,
337 .verbose_proctitle = FALSE,
338 .first_valid_uid = 500,
339 .last_valid_uid = 0,
340 .first_valid_gid = 1,
341 .last_valid_gid = 0,
342 };
343
344 const struct setting_parser_info auth_setting_parser_info = {
345 .module_name = "auth",
346 .defines = auth_setting_defines,
347 .defaults = &auth_default_settings,
348
349 .type_offset = SIZE_MAX,
350 .struct_size = sizeof(struct auth_settings),
351
352 .parent_offset = SIZE_MAX,
353
354 .check_func = auth_settings_check
355 };
356
357 /* <settings checks> */
358 static bool
auth_settings_set_self_ips(struct auth_settings * set,pool_t pool,const char ** error_r)359 auth_settings_set_self_ips(struct auth_settings *set, pool_t pool,
360 const char **error_r)
361 {
362 const char *const *tmp;
363 ARRAY(struct ip_addr) ips_array;
364 struct ip_addr *ips;
365 unsigned int ips_count;
366 int ret;
367
368 if (*set->proxy_self == '\0') {
369 set->proxy_self_ips = p_new(pool, struct ip_addr, 1);
370 return TRUE;
371 }
372
373 p_array_init(&ips_array, pool, 4);
374 tmp = t_strsplit_spaces(set->proxy_self, " ");
375 for (; *tmp != NULL; tmp++) {
376 ret = net_gethostbyname(*tmp, &ips, &ips_count);
377 if (ret != 0) {
378 *error_r = t_strdup_printf("auth_proxy_self_ips: "
379 "gethostbyname(%s) failed: %s",
380 *tmp, net_gethosterror(ret));
381 }
382 array_append(&ips_array, ips, ips_count);
383 }
384 array_append_zero(&ips_array);
385 set->proxy_self_ips = array_front(&ips_array);
386 return TRUE;
387 }
388
389 static bool
auth_verify_verbose_password(struct auth_settings * set,const char ** error_r)390 auth_verify_verbose_password(struct auth_settings *set,
391 const char **error_r)
392 {
393 const char *p, *value = set->verbose_passwords;
394 unsigned int num;
395
396 p = strchr(value, ':');
397 if (p != NULL) {
398 if (str_to_uint(p+1, &num) < 0 || num == 0) {
399 *error_r = t_strdup_printf("auth_verbose_passwords: "
400 "Invalid truncation number: '%s'", p+1);
401 return FALSE;
402 }
403 value = t_strdup_until(value, p);
404 }
405 if (strcmp(value, "no") == 0)
406 return TRUE;
407 else if (strcmp(value, "plain") == 0)
408 return TRUE;
409 else if (strcmp(value, "sha1") == 0)
410 return TRUE;
411 else if (strcmp(value, "yes") == 0) {
412 /* just use it as alias for "plain" */
413 set->verbose_passwords = "plain";
414 return TRUE;
415 } else {
416 *error_r = "auth_verbose_passwords: Invalid value";
417 return FALSE;
418 }
419 }
420
auth_settings_check(void * _set,pool_t pool,const char ** error_r)421 static bool auth_settings_check(void *_set, pool_t pool,
422 const char **error_r)
423 {
424 struct auth_settings *set = _set;
425 const char *p;
426
427 if (set->debug_passwords)
428 set->debug = TRUE;
429 if (set->debug)
430 set->verbose = TRUE;
431
432 if (set->worker_max_count == 0) {
433 *error_r = "auth_worker_max_count must be above zero";
434 return FALSE;
435 }
436
437 if (set->cache_size > 0 && set->cache_size < 1024) {
438 /* probably a configuration error.
439 older versions used megabyte numbers */
440 *error_r = t_strdup_printf("auth_cache_size value is too small "
441 "(%"PRIuUOFF_T" bytes)",
442 set->cache_size);
443 return FALSE;
444 }
445
446 if (!auth_verify_verbose_password(set, error_r))
447 return FALSE;
448
449 if (*set->username_chars == '\0') {
450 /* all chars are allowed */
451 memset(set->username_chars_map, 1,
452 sizeof(set->username_chars_map));
453 } else {
454 for (p = set->username_chars; *p != '\0'; p++)
455 set->username_chars_map[(int)(uint8_t)*p] = 1;
456 }
457
458 if (*set->username_translation != '\0') {
459 p = set->username_translation;
460 for (; *p != '\0' && p[1] != '\0'; p += 2)
461 set->username_translation_map[(int)(uint8_t)*p] = p[1];
462 }
463 set->realms_arr =
464 (const char *const *)p_strsplit_spaces(pool, set->realms, " ");
465
466 if (*set->policy_server_url != '\0') {
467 if (*set->policy_hash_nonce == '\0') {
468
469 *error_r = "auth_policy_hash_nonce must be set when policy server is used";
470 return FALSE;
471 }
472 const struct hash_method *digest = hash_method_lookup(set->policy_hash_mech);
473 if (digest == NULL) {
474 *error_r = "invalid auth_policy_hash_mech given";
475 return FALSE;
476 }
477 if (set->policy_hash_truncate > 0 && set->policy_hash_truncate >= digest->digest_size*8) {
478 *error_r = t_strdup_printf("policy_hash_truncate is not smaller than digest size (%u >= %u)",
479 set->policy_hash_truncate,
480 digest->digest_size*8);
481 return FALSE;
482 }
483 }
484
485 if (!auth_settings_set_self_ips(set, pool, error_r))
486 return FALSE;
487 return TRUE;
488 }
489
490 static bool
auth_passdb_settings_check(void * _set,pool_t pool ATTR_UNUSED,const char ** error_r)491 auth_passdb_settings_check(void *_set, pool_t pool ATTR_UNUSED,
492 const char **error_r)
493 {
494 struct auth_passdb_settings *set = _set;
495
496 if (set->driver == NULL || *set->driver == '\0') {
497 *error_r = "passdb is missing driver";
498 return FALSE;
499 }
500 if (set->pass && strcmp(set->result_success, "return-ok") != 0) {
501 *error_r = "Obsolete pass=yes setting mixed with non-default result_success";
502 return FALSE;
503 }
504 return TRUE;
505 }
506
507 static bool
auth_userdb_settings_check(void * _set,pool_t pool ATTR_UNUSED,const char ** error_r)508 auth_userdb_settings_check(void *_set, pool_t pool ATTR_UNUSED,
509 const char **error_r)
510 {
511 struct auth_userdb_settings *set = _set;
512
513 if (set->driver == NULL || *set->driver == '\0') {
514 *error_r = "userdb is missing driver";
515 return FALSE;
516 }
517 return TRUE;
518 }
519 /* </settings checks> */
520
521 struct auth_settings *global_auth_settings;
522
523 struct auth_settings *
auth_settings_read(const char * service,pool_t pool,struct master_service_settings_output * output_r)524 auth_settings_read(const char *service, pool_t pool,
525 struct master_service_settings_output *output_r)
526 {
527 static const struct setting_parser_info *set_roots[] = {
528 &auth_setting_parser_info,
529 NULL
530 };
531 struct master_service_settings_input input;
532 struct setting_parser_context *set_parser;
533 const char *error;
534 void **sets;
535
536 i_zero(&input);
537 input.roots = set_roots;
538 input.module = "auth";
539 input.service = service;
540 if (master_service_settings_read(master_service, &input,
541 output_r, &error) < 0)
542 i_fatal("Error reading configuration: %s", error);
543
544 pool_ref(pool);
545 set_parser = settings_parser_dup(master_service->set_parser, pool);
546 if (!settings_parser_check(set_parser, pool, &error))
547 i_unreached();
548
549 sets = master_service_settings_parser_get_others(master_service,
550 set_parser);
551 settings_parser_deinit(&set_parser);
552 return sets[0];
553 }
554