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