Import Debian changes 0.69.0-2
[hcoop/debian/courier-authlib.git] / authmysql.cpp
1 /*
2 ** Copyright 2000-2008 Double Precision, Inc. See COPYING for
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
16 #include <iostream>
17
18 #include "authmysql.h"
19 extern "C" {
20 #include "auth.h"
21 #include "courierauthstaticlist.h"
22 #include "courierauthdebug.h"
23 #include "courierauth.h"
24 }
25
26 static bool verify(const authmysqluserinfo &authinfo,
27 const char *user,
28 const char *pass)
29 {
30 if (authinfo.home.size() == 0) /* User not found */
31 {
32 errno=EPERM;
33 return false; /* Username not found */
34 }
35
36 if (authinfo.cryptpw.size())
37 {
38 if (authcheckpassword(pass,authinfo.cryptpw.c_str()))
39 {
40 errno=EPERM;
41 return false; /* User/Password not found. */
42 }
43 }
44 else if (authinfo.clearpw.size())
45 {
46 if (authinfo.clearpw != pass)
47 {
48 if (courier_authdebug_login_level >= 2)
49 {
50 DPRINTF("supplied password '%s' does not match clearpasswd '%s'",
51 pass, authinfo.clearpw.c_str());
52 }
53 else
54 {
55 DPRINTF("supplied password does not match clearpasswd");
56 }
57 errno=EPERM;
58 return false;
59 }
60 }
61 else
62 {
63 DPRINTF("no password available to compare for '%s'", user);
64 errno=EPERM;
65 return false; /* Username not found */
66 }
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;
95
96 memset(&aa, 0, sizeof(aa));
97
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);
109 aa.clearpasswd=pass;
110 aa.passwd=STR(cryptpw);
111 courier_authdebug_authinfo("DEBUG: authmysql: ", &aa,
112 aa.clearpasswd, aa.passwd);
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 {
121 authmysqluserinfo authinfo;
122
123 if (!auth_mysql_getuserinfo(user, service, authinfo))
124 {
125 errno=ENOENT;
126 return (-1);
127 }
128
129 if (!verify(authinfo, user, pass))
130 {
131 return (-1);
132 }
133
134 if (!auth_mysql_setpass(user, newpass, authinfo.cryptpw.c_str()))
135 {
136 errno=EPERM;
137 return (-1);
138 }
139 return (0);
140 }
141
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 }
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
166 return (auth_mysql_cram(service, authtype, authdata,
167 callback_func, callback_arg));
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
184 extern "C" {
185 struct authstaticinfo *courier_authmysql_init()
186 {
187 return &authmysql_info;
188 }
189 }