/*
** Copyright 2000-2004 Double Precision, Inc. See COPYING for
** distribution information.
*/
#if HAVE_CONFIG_H
#include "courier_auth_config.h"
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <pwd.h>
#if HAVE_UNISTD_H
#include <unistd.h>
#endif
#include "auth.h"
#include "authmysql.h"
#include "authstaticlist.h"
#include "courierauthdebug.h"
static const char rcsid[]="$Id: authmysql.c,v 1.23 2006/10/28 19:22:52 mrsam Exp $";
extern void auth_mysql_enumerate( void(*cb_func)(const char *name,
uid_t uid,
gid_t gid,
const char *homedir,
const char *maildir,
const char *options,
void *void_arg),
void *void_arg);
static int auth_mysql_login(const char *service, char *authdata,
int (*callback_func)(struct authinfo *, void *),
void *callback_arg)
{
char *user, *pass;
struct authmysqluserinfo *authinfo;
struct authinfo aa;
if ((user=strtok(authdata, "\n")) == 0 ||
(pass=strtok(0, "\n")) == 0)
{
errno=EPERM;
return (-1);
}
authinfo=auth_mysql_getuserinfo(user, service);
if (!authinfo) /* Fatal error - such as MySQL being down */
{
errno=EACCES;
return (1);
}
if (authinfo->cryptpw)
{
if (authcheckpassword(pass,authinfo->cryptpw))
{
errno=EPERM;
return (-1); /* User/Password not found. */
}
}
else if (authinfo->clearpw)
{
if (strcmp(pass, authinfo->clearpw))
{
if (courier_authdebug_login_level >= 2)
{
DPRINTF("supplied password '%s' does not match clearpasswd '%s'",
pass, authinfo->clearpw);
}
else
{
DPRINTF("supplied password does not match clearpasswd");
}
errno=EPERM;
return (-1);
}
}
else
{
DPRINTF("no password available to compare");
errno=EPERM;
return (-1); /* Username not found */
}
memset(&aa, 0, sizeof(aa));
aa.sysuserid= &authinfo->uid;
aa.sysgroupid= authinfo->gid;
aa.homedir=authinfo->home;
aa.maildir=authinfo->maildir && authinfo->maildir[0] ?
authinfo->maildir:0;
aa.address=authinfo->username;
aa.quota=authinfo->quota && authinfo->quota[0] ?
authinfo->quota:0;
aa.fullname=authinfo->fullname;
aa.options=authinfo->options;
aa.clearpasswd=pass;
aa.passwd=authinfo->cryptpw;
courier_authdebug_authinfo("DEBUG: authmysql: ", &aa,
authinfo->clearpw, authinfo->cryptpw);
return (*callback_func)(&aa, callback_arg);
}
static int auth_mysql_changepw(const char *service, const char *user,
const char *pass,
const char *newpass)
{
struct authmysqluserinfo *authinfo;
authinfo=auth_mysql_getuserinfo(user, service);
if (!authinfo)
{
errno=ENOENT;
return (-1);
}
if (authinfo->cryptpw)
{
if (authcheckpassword(pass,authinfo->cryptpw))
{
errno=EPERM;
return (-1); /* User/Password not found. */
}
}
else if (authinfo->clearpw)
{
if (strcmp(pass, authinfo->clearpw))
{
errno=EPERM;
return (-1);
}
}
else
{
errno=EPERM;
return (-1);
}
if (auth_mysql_setpass(user, newpass, authinfo->cryptpw))
{
errno=EPERM;
return (-1);
}
return (0);
}
#if HAVE_HMACLIB
#include "libhmac/hmac.h"
#include "cramlib.h"
static int auth_mysql_cram(const char *service,
const char *authtype, char *authdata,
int (*callback_func)(struct authinfo *, void *),
void *callback_arg)
{
struct cram_callback_info cci;
if (auth_get_cram(authtype, authdata, &cci))
return (-1);
cci.callback_func=callback_func;
cci.callback_arg=callback_arg;
return auth_mysql_pre(cci.user, service, &auth_cram_callback, &cci);
}
#endif
int auth_mysql(const char *service, const char *authtype, char *authdata,
int (*callback_func)(struct authinfo *, void *),
void *callback_arg)
{
if (strcmp(authtype, AUTHTYPE_LOGIN) == 0)
return (auth_mysql_login(service, authdata,
callback_func, callback_arg));
#if HAVE_HMACLIB
return (auth_mysql_cram(service, authtype, authdata,
callback_func, callback_arg));
#else
errno=EPERM;
return (-1);
#endif
}
extern int auth_mysql_pre(const char *user, const char *service,
int (*callback)(struct authinfo *, void *),
void *arg);
static struct authstaticinfo authmysql_info={
"authmysql",
auth_mysql,
auth_mysql_pre,
auth_mysql_cleanup,
auth_mysql_changepw,
auth_mysql_cleanup,
auth_mysql_enumerate};
struct authstaticinfo *courier_authmysql_init()
{
return &authmysql_info;
}
syntax highlighted by Code2HTML, v. 0.9.1