Add changelog entry.
[hcoop/debian/courier-authlib.git] / authpgsql.c
CommitLineData
d9898ee8 1/*
2** Copyright 2000-2005 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
17#include "auth.h"
18#include "authpgsql.h"
19#include "authstaticlist.h"
20#include "courierauthdebug.h"
21
22static const char rcsid[]="$Id: authpgsql.c,v 1.13 2006/10/28 19:22:52 mrsam Exp $";
23
24extern void auth_pgsql_enumerate( void(*cb_func)(const char *name,
25 uid_t uid,
26 gid_t gid,
27 const char *homedir,
28 const char *maildir,
29 const char *options,
30 void *void_arg),
31 void *void_arg);
32
33static int auth_pgsql_login(const char *service, char *authdata,
34 int (*callback_func)(struct authinfo *, void *),
35 void *callback_arg)
36{
37 char *user, *pass;
38 struct authpgsqluserinfo *authinfo;
39 struct authinfo aa;
40
41 if ((user=strtok(authdata, "\n")) == 0 ||
42 (pass=strtok(0, "\n")) == 0)
43 {
44 errno=EPERM;
45 return (-1);
46 }
47
48 authinfo=auth_pgsql_getuserinfo(user, service);
49
50 if (!authinfo) /* Fatal error - such as PgSQL being down */
51 {
52 errno=EACCES;
53 return (1);
54 }
55
56 if (authinfo->cryptpw)
57 {
58 if (authcheckpassword(pass,authinfo->cryptpw))
59 {
60 errno=EPERM;
61 return (-1); /* User/Password not found. */
62 }
63 }
64 else if (authinfo->clearpw)
65 {
66 if (strcmp(pass, authinfo->clearpw))
67 {
68 if (courier_authdebug_login_level >= 2)
69 {
70 DPRINTF("supplied password '%s' does not match clearpasswd '%s'",
71 pass, authinfo->clearpw);
72 }
73 else
74 {
75 DPRINTF("supplied password does not match clearpasswd");
76 }
77 errno=EPERM;
78 return (-1);
79 }
80 }
81 else
82 {
83 DPRINTF("no password available to compare");
84 errno=EPERM;
85 return (-1); /* Username not found */
86 }
87
88
89 memset(&aa, 0, sizeof(aa));
90
91 /*aa.sysusername=user;*/
92 aa.sysuserid= &authinfo->uid;
93 aa.sysgroupid= authinfo->gid;
94 aa.homedir=authinfo->home;
95 aa.maildir=authinfo->maildir && authinfo->maildir[0] ?
96 authinfo->maildir:0;
97 aa.address=authinfo->username;
98 aa.quota=authinfo->quota && authinfo->quota[0] ?
99 authinfo->quota:0;
100 aa.fullname=authinfo->fullname;
101 aa.options=authinfo->options;
102 aa.passwd=authinfo->cryptpw;
103 aa.clearpasswd=pass;
104 courier_authdebug_authinfo("DEBUG: authpgsql: ", &aa,
105 authinfo->clearpw, authinfo->cryptpw);
106 return (*callback_func)(&aa, callback_arg);
107}
108
109static int auth_pgsql_changepw(const char *service, const char *user,
110 const char *pass,
111 const char *newpass)
112{
113 struct authpgsqluserinfo *authinfo;
114
115 authinfo=auth_pgsql_getuserinfo(user, service);
116
117 if (!authinfo)
118 {
119 errno=ENOENT;
120 return (-1);
121 }
122
123 if (authinfo->cryptpw)
124 {
125 if (authcheckpassword(pass,authinfo->cryptpw))
126 {
127 errno=EPERM;
128 return (-1); /* User/Password not found. */
129 }
130 }
131 else if (authinfo->clearpw)
132 {
133 if (strcmp(pass, authinfo->clearpw))
134 {
135 errno=EPERM;
136 return (-1);
137 }
138 }
139 else
140 {
141 errno=EPERM;
142 return (-1);
143 }
144
145 if (auth_pgsql_setpass(user, newpass, authinfo->cryptpw))
146 {
147 errno=EPERM;
148 return (-1);
149 }
150 return (0);
151}
152
153#if HAVE_HMACLIB
154
155#include "libhmac/hmac.h"
156#include "cramlib.h"
157
158static int auth_pgsql_cram(const char *service,
159 const char *authtype, char *authdata,
160 int (*callback_func)(struct authinfo *, void *),
161 void *callback_arg)
162{
163 struct cram_callback_info cci;
164
165 if (auth_get_cram(authtype, authdata, &cci))
166 return (-1);
167
168 cci.callback_func=callback_func;
169 cci.callback_arg=callback_arg;
170
171 return auth_pgsql_pre(cci.user, service, &auth_cram_callback, &cci);
172}
173#endif
174
175int auth_pgsql(const char *service, const char *authtype, char *authdata,
176 int (*callback_func)(struct authinfo *, void *),
177 void *callback_arg)
178{
179 if (strcmp(authtype, AUTHTYPE_LOGIN) == 0)
180 return (auth_pgsql_login(service, authdata,
181 callback_func, callback_arg));
182
183#if HAVE_HMACLIB
184 return (auth_pgsql_cram(service, authtype, authdata,
185 callback_func, callback_arg));
186#else
187 errno=EPERM;
188 return (-1);
189#endif
190}
191
192extern int auth_pgsql_pre(const char *user, const char *service,
193 int (*callback)(struct authinfo *, void *),
194 void *arg);
195
196static struct authstaticinfo authpgsql_info={
197 "authpgsql",
198 auth_pgsql,
199 auth_pgsql_pre,
200 auth_pgsql_cleanup,
201 auth_pgsql_changepw,
202 auth_pgsql_cleanup,
203 auth_pgsql_enumerate};
204
205struct authstaticinfo *courier_authpgsql_init()
206{
207 return &authpgsql_info;
208}