Import Upstream version 0.69.0
[hcoop/debian/courier-authlib.git] / authmysql.cpp
CommitLineData
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
19extern "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
26static 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
70static 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
117static 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 142static 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
158int 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
170extern int auth_mysql_pre(const char *user, const char *service,
171 int (*callback)(struct authinfo *, void *),
172 void *arg);
173
174static 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
184extern "C" {
185 struct authstaticinfo *courier_authmysql_init()
186 {
187 return &authmysql_info;
188 }
d9898ee8 189}