1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
|
/* Copyright (c) 2002-2018 Dovecot authors, see the included COPYING file */
#include "auth-common.h"
#include "passdb.h"
#ifdef PASSDB_BSDAUTH
#include "safe-memset.h"
#include "auth-cache.h"
#include "ipwd.h"
#include "mycrypt.h"
#include <login_cap.h>
#include <bsd_auth.h>
static void
bsdauth_verify_plain(struct auth_request *request, const char *password,
verify_plain_callback_t *callback)
{
struct passwd pw;
const char *type;
int result;
e_debug(authdb_event(request), "lookup");
switch (i_getpwnam(request->fields.user, &pw)) {
case -1:
e_error(authdb_event(request),
"getpwnam() failed: %m");
callback(PASSDB_RESULT_INTERNAL_FAILURE, request);
return;
case 0:
auth_request_log_unknown_user(request, AUTH_SUBSYS_DB);
callback(PASSDB_RESULT_USER_UNKNOWN, request);
return;
}
/* check if the password is valid */
type = t_strdup_printf("auth-%s", request->fields.service);
result = auth_userokay(request->fields.user, NULL,
t_strdup_noconst(type),
t_strdup_noconst(password));
/* clear the passwords from memory */
safe_memset(pw.pw_passwd, 0, strlen(pw.pw_passwd));
if (result == 0) {
auth_request_log_password_mismatch(request, AUTH_SUBSYS_DB);
callback(PASSDB_RESULT_PASSWORD_MISMATCH, request);
return;
}
/* make sure we're using the username exactly as it's in the database */
auth_request_set_field(request, "user", pw.pw_name, NULL);
callback(PASSDB_RESULT_OK, request);
}
static struct passdb_module *
bsdauth_preinit(pool_t pool, const char *args)
{
struct passdb_module *module;
module = p_new(pool, struct passdb_module, 1);
module->default_pass_scheme = "PLAIN"; /* same reason as PAM */
module->blocking = TRUE;
if (strcmp(args, "blocking=no") == 0)
module->blocking = FALSE;
else if (str_begins(args, "cache_key="))
module->default_cache_key = auth_cache_parse_key(pool, args + 10);
else if (*args != '\0')
i_fatal("passdb bsdauth: Unknown setting: %s", args);
return module;
}
static void bsdauth_deinit(struct passdb_module *module ATTR_UNUSED)
{
endpwent();
}
struct passdb_module_interface passdb_bsdauth = {
"bsdauth",
bsdauth_preinit,
NULL,
bsdauth_deinit,
bsdauth_verify_plain,
NULL,
NULL
};
#else
struct passdb_module_interface passdb_bsdauth = {
.name = "bsdauth"
};
#endif
|