Commit | Line | Data |
---|---|---|
d9898ee8 | 1 | /* |
ac40fd9e | 2 | ** Copyright 2000-2008 Double Precision, Inc. See COPYING for |
d9898ee8 | 3 | ** distribution information. |
4 | */ | |
5 | #if HAVE_CONFIG_H | |
6 | #include "courier_auth_config.h" | |
7 | #endif | |
8 | #include <stdio.h> | |
9 | #include <stdlib.h> | |
10 | #include <string.h> | |
11 | #include <errno.h> | |
12 | #include <pwd.h> | |
13 | #if HAVE_UNISTD_H | |
14 | #include <unistd.h> | |
15 | #endif | |
0e333c05 | 16 | #include <iostream> |
d9898ee8 | 17 | |
d9898ee8 | 18 | #include "authmysql.h" |
0e333c05 CE |
19 | extern "C" { |
20 | #include "auth.h" | |
b0322a85 | 21 | #include "courierauthstaticlist.h" |
d9898ee8 | 22 | #include "courierauthdebug.h" |
0e333c05 CE |
23 | #include "courierauth.h" |
24 | } | |
d9898ee8 | 25 | |
0e333c05 CE |
26 | static bool verify(const authmysqluserinfo &authinfo, |
27 | const char *user, | |
28 | const char *pass) | |
d9898ee8 | 29 | { |
0e333c05 | 30 | if (authinfo.home.size() == 0) /* User not found */ |
d9898ee8 | 31 | { |
32 | errno=EPERM; | |
0e333c05 | 33 | return false; /* Username not found */ |
d9898ee8 | 34 | } |
35 | ||
0e333c05 | 36 | if (authinfo.cryptpw.size()) |
d9898ee8 | 37 | { |
0e333c05 | 38 | if (authcheckpassword(pass,authinfo.cryptpw.c_str())) |
d9898ee8 | 39 | { |
40 | errno=EPERM; | |
0e333c05 | 41 | return false; /* User/Password not found. */ |
d9898ee8 | 42 | } |
43 | } | |
0e333c05 | 44 | else if (authinfo.clearpw.size()) |
d9898ee8 | 45 | { |
0e333c05 | 46 | if (authinfo.clearpw != pass) |
d9898ee8 | 47 | { |
48 | if (courier_authdebug_login_level >= 2) | |
49 | { | |
50 | DPRINTF("supplied password '%s' does not match clearpasswd '%s'", | |
0e333c05 | 51 | pass, authinfo.clearpw.c_str()); |
d9898ee8 | 52 | } |
53 | else | |
54 | { | |
55 | DPRINTF("supplied password does not match clearpasswd"); | |
56 | } | |
57 | errno=EPERM; | |
0e333c05 | 58 | return false; |
d9898ee8 | 59 | } |
60 | } | |
61 | else | |
62 | { | |
0e333c05 | 63 | DPRINTF("no password available to compare for '%s'", user); |
d9898ee8 | 64 | errno=EPERM; |
0e333c05 | 65 | return false; /* Username not found */ |
d9898ee8 | 66 | } |
0e333c05 CE |
67 | return true; |
68 | } | |
69 | ||
70 | static int auth_mysql_login(const char *service, char *authdata, | |
71 | int (*callback_func)(struct authinfo *, void *), | |
72 | void *callback_arg) | |
73 | { | |
74 | char *user, *pass; | |
75 | struct authinfo aa; | |
76 | ||
77 | if ((user=strtok(authdata, "\n")) == 0 || | |
78 | (pass=strtok(0, "\n")) == 0) | |
79 | { | |
80 | errno=EPERM; | |
81 | return (-1); | |
82 | } | |
83 | ||
84 | authmysqluserinfo authinfo; | |
85 | ||
86 | if (!auth_mysql_getuserinfo(user, service, authinfo)) | |
87 | /* Fatal error - such as MySQL being down */ | |
88 | { | |
89 | errno=EACCES; | |
90 | return (-1); | |
91 | } | |
92 | ||
93 | if (!verify(authinfo, user, pass)) | |
94 | return -1; | |
d9898ee8 | 95 | |
96 | memset(&aa, 0, sizeof(aa)); | |
97 | ||
0e333c05 CE |
98 | aa.sysuserid= &authinfo.uid; |
99 | aa.sysgroupid= authinfo.gid; | |
100 | aa.homedir=authinfo.home.c_str(); | |
101 | ||
102 | #define STR(z) (authinfo.z.size() ? authinfo.z.c_str():0) | |
103 | ||
104 | aa.maildir=STR(maildir); | |
105 | aa.address=STR(username); | |
106 | aa.quota=STR(quota); | |
107 | aa.fullname=STR(fullname); | |
108 | aa.options=STR(options); | |
d9898ee8 | 109 | aa.clearpasswd=pass; |
0e333c05 | 110 | aa.passwd=STR(cryptpw); |
d9898ee8 | 111 | courier_authdebug_authinfo("DEBUG: authmysql: ", &aa, |
0e333c05 | 112 | aa.clearpasswd, aa.passwd); |
d9898ee8 | 113 | |
114 | return (*callback_func)(&aa, callback_arg); | |
115 | } | |
116 | ||
117 | static int auth_mysql_changepw(const char *service, const char *user, | |
118 | const char *pass, | |
119 | const char *newpass) | |
120 | { | |
0e333c05 | 121 | authmysqluserinfo authinfo; |
d9898ee8 | 122 | |
0e333c05 | 123 | if (!auth_mysql_getuserinfo(user, service, authinfo)) |
d9898ee8 | 124 | { |
125 | errno=ENOENT; | |
126 | return (-1); | |
127 | } | |
128 | ||
0e333c05 | 129 | if (!verify(authinfo, user, pass)) |
d9898ee8 | 130 | { |
d9898ee8 | 131 | return (-1); |
132 | } | |
133 | ||
0e333c05 | 134 | if (!auth_mysql_setpass(user, newpass, authinfo.cryptpw.c_str())) |
d9898ee8 | 135 | { |
136 | errno=EPERM; | |
137 | return (-1); | |
138 | } | |
139 | return (0); | |
140 | } | |
141 | ||
d9898ee8 | 142 | static int auth_mysql_cram(const char *service, |
143 | const char *authtype, char *authdata, | |
144 | int (*callback_func)(struct authinfo *, void *), | |
145 | void *callback_arg) | |
146 | { | |
147 | struct cram_callback_info cci; | |
148 | ||
149 | if (auth_get_cram(authtype, authdata, &cci)) | |
150 | return (-1); | |
151 | ||
152 | cci.callback_func=callback_func; | |
153 | cci.callback_arg=callback_arg; | |
154 | ||
155 | return auth_mysql_pre(cci.user, service, &auth_cram_callback, &cci); | |
156 | } | |
d9898ee8 | 157 | |
158 | int auth_mysql(const char *service, const char *authtype, char *authdata, | |
159 | int (*callback_func)(struct authinfo *, void *), | |
160 | void *callback_arg) | |
161 | { | |
162 | if (strcmp(authtype, AUTHTYPE_LOGIN) == 0) | |
163 | return (auth_mysql_login(service, authdata, | |
164 | callback_func, callback_arg)); | |
165 | ||
d9898ee8 | 166 | return (auth_mysql_cram(service, authtype, authdata, |
167 | callback_func, callback_arg)); | |
d9898ee8 | 168 | } |
169 | ||
170 | extern int auth_mysql_pre(const char *user, const char *service, | |
171 | int (*callback)(struct authinfo *, void *), | |
172 | void *arg); | |
173 | ||
174 | static struct authstaticinfo authmysql_info={ | |
175 | "authmysql", | |
176 | auth_mysql, | |
177 | auth_mysql_pre, | |
178 | auth_mysql_cleanup, | |
179 | auth_mysql_changepw, | |
180 | auth_mysql_cleanup, | |
181 | auth_mysql_enumerate}; | |
182 | ||
183 | ||
0e333c05 CE |
184 | extern "C" { |
185 | struct authstaticinfo *courier_authmysql_init() | |
186 | { | |
187 | return &authmysql_info; | |
188 | } | |
d9898ee8 | 189 | } |