2 ** Copyright 1998 - 2007 Double Precision, Inc. See COPYING for
3 ** distribution information.
7 #include "courier_auth_config.h"
18 #include "authstaticlist.h"
19 #include "courierauthdebug.h"
20 #include "vpopmail_config.h"
24 static const char rcsid
[]="$Id: authvchkpw.c,v 1.29 2007/10/07 02:50:45 mrsam Exp $";
27 extern int auth_vchkpw_pre(const char *userid
, const char *service
,
28 int (*callback
)(struct authinfo
*, void *),
31 extern FILE *authvchkpw_file(const char *, const char *);
33 static int auth_vchkpw_login(const char *service
, char *authdata
,
34 int (*callback_func
)(struct authinfo
*, void *), void *callback_arg
);
36 struct callback_info
{
38 int (*callback_func
)(struct authinfo
*, void *);
42 static int callback_vchkpw(struct authinfo
*a
, void *p
)
44 struct callback_info
*i
=(struct callback_info
*)p
;
46 /* exit with perm failure if the supplied password is empty,
47 * or if the supplied password doesnt match the retrieved password */
50 DPRINTF("no password supplied");
54 if (authcheckpassword(i
->pass
, a
->passwd
))
57 a
->clearpasswd
=i
->pass
;
58 return (*i
->callback_func
)(a
, i
->callback_arg
);
63 #include "libhmac/hmac.h"
66 static int auth_vchkpw_login(const char *service
, char *authdata
,
67 int (*callback_func
)(struct authinfo
*, void *), void *callback_arg
);
69 static int auth_vchkpw_cram(const char *service
,
70 const char *authtype
, char *authdata
,
71 int (*callback_func
)(struct authinfo
*, void *),
74 struct cram_callback_info cci
;
76 if (auth_get_cram(authtype
, authdata
, &cci
))
79 cci
.callback_func
=callback_func
;
80 cci
.callback_arg
=callback_arg
;
82 return auth_vchkpw_pre(cci
.user
, service
, &auth_cram_callback
, &cci
);
86 int auth_vchkpw(const char *service
, const char *authtype
, char *authdata
,
87 int (*callback_func
)(struct authinfo
*, void *),
90 if (strcmp(authtype
, AUTHTYPE_LOGIN
) == 0)
91 return (auth_vchkpw_login(service
, authdata
,
92 callback_func
, callback_arg
));
95 return (auth_vchkpw_cram(service
, authtype
, authdata
,
96 callback_func
, callback_arg
));
106 static int auth_vchkpw_login(const char *service
, char *authdata
,
107 int (*callback_func
)(struct authinfo
*, void *), void *callback_arg
)
110 struct callback_info ci
;
112 /* Make sure that we have been supplied with the correct
113 * AUTHDATA format which is : userid<NEWLINE>password<NEWLINE>
115 if ( (user
=strtok(authdata
, "\n")) == 0 || (pass
=strtok(0, "\n")) == 0)
117 /* login syntax was invalid */
123 ci
.callback_func
=callback_func
;
124 ci
.callback_arg
=callback_arg
;
126 /* auth_vchkpw_pre() does this :
127 * - lookup the passwd entry for this user from the auth backend
128 * - check to see if this user is permitted to use this service type
129 * If successful it will populate the ci struct with the
130 * user's passwd entry. Return value of function will be 0.
131 * If unsuccessful (eg user doesnt exist, or is not permitted to
132 * use this auth method), it will return :
133 * <0 on a permanent failure (eg user doesnt exist)
134 * >0 on a temp failure
136 rc
=auth_vchkpw_pre(user
, service
, &callback_vchkpw
, &ci
);
141 /* user has been successfully auth'ed at this point */
145 ** sam - new courier-authlib never receives TCPREMOTEIP, at this
149 #ifdef HAVE_OPEN_SMTP_RELAY
150 if ( (strcmp("pop3", service
)==0) || (strcmp("imap", service
)==0) ) {
151 /* Michael Bowe 13th August 2003
153 * There is a problem here because open_smtp_relay needs
154 * to get the user's ip from getenv("TCPREMOTEIP").
155 * If we run --with-authvchkpw --without-authdaemon,
156 * then this var is available.
157 * But if we run --with-authvchkpw --with-authdaemon,
158 * then TCPREMOTEIP is null
160 * If TCPREMOTEIP isnt available, then open_smtp_relay()
161 * will just return() back immediately.
171 static void authvchkpwclose()
175 static int auth_vchkpw_changepass(const char *service
,
176 const char *username
,
180 struct vqpasswd
*vpw
;
184 /* Take the supplied userid, and split it out into the user and domain
185 * parts. (If a domain was not supplied, then set the domain to be
186 * the default domain)
188 /* WARNING: parse_email lowercases the username in place - not const!! */
189 if ( parse_email(username
, User
, Domain
, 256) != 0) {
190 /* Failed to successfully extract user and domain.
191 * So now exit with a permanent failure code
196 /* check to see if domain exists.
197 * If you pass an alias domain to vget_assign, it will change it
198 * to be the real domain on return from the function
200 if ( vget_assign(Domain
,NULL
,0,NULL
,NULL
) ==NULL
) {
201 /* domain doesnt exist */
205 if ( (vpw
=vauth_getpw(User
, Domain
)) == NULL
) {
206 /* That user doesnt exist in the auth backend */
211 /* Exit if any of the following :
212 * - user's password field in the passwd entry is empty
213 * - supplied current password doesnt match stored password
215 if (vpw
->pw_passwd
== 0 || authcheckpassword(pass
, vpw
->pw_passwd
)) {
220 /* save the new password into the auth backend */
221 if ( vpasswd(User
, Domain
, (char *)npass
, 0) != 0 ) {
222 /* password set failed */
229 struct authstaticinfo authvchkpw_info
={
234 auth_vchkpw_changepass
,
239 struct authstaticinfo
*courier_authvchkpw_init()
241 return &authvchkpw_info
;