Mercurial > dovecot > core-2.2
changeset 280:fa2d1a1d025e HEAD
vpopmail authentication. compiles, not tested if it really works.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Fri, 20 Sep 2002 14:27:18 +0300 |
parents | 49f4b0be0d87 |
children | b7fe6867e549 |
files | acconfig.h configure.in dovecot-example.conf src/auth/Makefile.am src/auth/userinfo-vpopmail.c src/auth/userinfo.c src/auth/userinfo.h |
diffstat | 7 files changed, 130 insertions(+), 5 deletions(-) [+] |
line wrap: on
line diff
--- a/acconfig.h Fri Sep 20 14:25:05 2002 +0300 +++ b/acconfig.h Fri Sep 20 14:27:18 2002 +0300 @@ -11,6 +11,7 @@ #undef USERINFO_PASSWD_FILE #undef USERINFO_SHADOW #undef USERINFO_PAM +#undef USERINFO_VPOPMAIL #undef AUTH_PAM_USERPASS /* IMAP capabilities */
--- a/configure.in Fri Sep 20 14:25:05 2002 +0300 +++ b/configure.in Fri Sep 20 14:27:18 2002 +0300 @@ -64,8 +64,17 @@ fi, want_pam=yes) +AC_ARG_WITH(vpopmail, +[ --with-vpopmail Build with vpopmail support (default)], + if test x$withval = xno; then + want_vpopmail=no + else + want_vpopmail=yes + fi, + want_vpopmail=yes) + AC_ARG_WITH(gnutls, -[ --without-gnutls Don't try to use GNUTLS], +[ --with-gnutls Build with GNUTLS (default)], if test x$withval = xno; then want_gnutls=no else @@ -306,6 +315,20 @@ ]) fi +if test $want_vpopmail = yes; then + vpopmail_home="`echo ~vpopmail`" + if test -f $vpopmail_home/etc/lib_deps; then + VPOPMAIL_CFLAGS="`cat $vpopmail_home/etc/inc_deps` $CFLAGS" + VPOPMAIL_LIBS="`cat $vpopmail_home/etc/lib_deps`" + AC_DEFINE(USERINFO_VPOPMAIL) + else + want_vpopmail=no + fi +fi + +AC_SUBST(VPOPMAIL_CFLAGS) +AC_SUBST(VPOPMAIL_LIBS) + if test $need_crypt = yes; then AC_CHECK_LIB(crypt, crypt, [ USERINFO_LIBS="$USERINFO_LIBS -lcrypt"
--- a/dovecot-example.conf Fri Sep 20 14:25:05 2002 +0300 +++ b/dovecot-example.conf Fri Sep 20 14:27:18 2002 +0300 @@ -142,6 +142,7 @@ # pam: PAM authentication # passwd-file /etc/passwd.imap: /etc/passwd-like file. Supports digest-md5 # style passwords +# vpopmail: vpopmail authentication auth_userinfo = pam # Executable location
--- a/src/auth/Makefile.am Fri Sep 20 14:25:05 2002 +0300 +++ b/src/auth/Makefile.am Fri Sep 20 14:27:18 2002 +0300 @@ -1,11 +1,13 @@ pkglib_PROGRAMS = imap-auth INCLUDES = \ - -I$(top_srcdir)/src/lib + -I$(top_srcdir)/src/lib \ + $(VPOPMAIL_CFLAGS) imap_auth_LDADD = \ ../lib/liblib.a \ - $(USERINFO_LIBS) + $(USERINFO_LIBS) \ + $(VPOPMAIL_LIBS) imap_auth_SOURCES = \ auth.c \ @@ -19,7 +21,8 @@ userinfo-passwd.c \ userinfo-shadow.c \ userinfo-pam.c \ - userinfo-passwd-file.c + userinfo-passwd-file.c \ + userinfo-vpopmail.c noinst_HEADERS = \ auth.h \
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/auth/userinfo-vpopmail.c Fri Sep 20 14:27:18 2002 +0300 @@ -0,0 +1,92 @@ +/* Copyright (C) 2002 Timo Sirainen */ + +/* Thanks to Courier-IMAP for showing how the vpopmail API should be used */ + +#include "common.h" + +#ifdef USERINFO_VPOPMAIL + +#include "userinfo.h" +#include "userinfo-passwd.h" + +#include <unistd.h> +#include <vpopmail.h> +#include <vauth.h> + +/* Limit user and domain to 80 chars each (+1 for \0). I wouldn't recommend + raising this limit at least much, vpopmail is full of potential buffer + overflows. */ +#define VPOPMAIL_LIMIT 81 + +static int vpopmail_verify_plain(const char *user, const char *password, + AuthCookieReplyData *reply) +{ + char vpop_user[VPOPMAIL_LIMIT], vpop_domain[VPOPMAIL_LIMIT]; + struct vqpasswd *vpw; + char *passdup; + int result; + + if (parse_email(t_strdup_noconst(user), vpop_user, vpop_domain, + sizeof(vpop_user)-1) < 0) + return FALSE; + + /* we have to get uid/gid separately, because the gid field in + struct vqpasswd isn't really gid at all but just some flags... */ + if (vget_assign(vpop_domain, NULL, 0, + &reply->uid, &reply->gid) == NULL) + return FALSE; + + vpw = vauth_getpw(vpop_user, vpop_domain); + if (vpw != NULL && (vpw->pw_dir == NULL || vpw->pw_dir[0] == '\0')) { + /* user's homedir doesn't exist yet, create it */ + if (make_user_dir(vpop_user, vpop_domain, + reply->uid, reply->gid) == NULL) + return FALSE; + + vpw = vauth_getpw(vpop_user, vpop_domain); + } + + if (vpw == NULL || (vpw->pw_gid & NO_IMAP)) + return FALSE; + + /* verify password */ + passdup = t_strdup_noconst(password); + result = strcmp(crypt(passdup, vpw->pw_passwd), vpw->pw_passwd) == 0; + + memset(passdup, 0, strlen(passdup)); + memset(vpw->pw_passwd, 0, strlen(vpw->pw_passwd)); + + if (!result) + return FALSE; + + /* make sure it's not giving too large values to us */ + if (strlen(vpw->pw_dir) >= sizeof(reply->home)) { + i_panic("Home directory too large (%u > %u)", + strlen(vpw->pw_dir), sizeof(reply->home)-1); + } + + if (strlen(vpw->pw_name) >= sizeof(reply->user)) { + i_panic("Username too large (%u > %u)", + strlen(vpw->pw_name), sizeof(reply->user)-1); + } + + strcpy(reply->user, vpw->pw_name); + strcpy(reply->home, vpw->pw_dir); + + return TRUE; +} + +static void vpopmail_deinit(void) +{ + vclose(); +} + +UserInfoModule userinfo_vpopmail = { + NULL, + vpopmail_deinit, + + vpopmail_verify_plain, + NULL +}; + +#endif
--- a/src/auth/userinfo.c Fri Sep 20 14:25:05 2002 +0300 +++ b/src/auth/userinfo.c Fri Sep 20 14:27:18 2002 +0300 @@ -33,6 +33,10 @@ if (strcasecmp(name, "passwd-file") == 0) userinfo = &userinfo_passwd_file; #endif +#ifdef USERINFO_VPOPMAIL + if (strcasecmp(name, "vpopmail") == 0) + userinfo = &userinfo_vpopmail; +#endif if (userinfo == NULL) i_fatal("Unknown userinfo type '%s'", name);
--- a/src/auth/userinfo.h Fri Sep 20 14:25:05 2002 +0300 +++ b/src/auth/userinfo.h Fri Sep 20 14:27:18 2002 +0300 @@ -11,7 +11,7 @@ information. reply should have been initialized (zeroed) before calling this function. */ int (*verify_plain)(const char *user, const char *password, - AuthCookieReplyData *reply); + AuthCookieReplyData *reply); /* Digest-MD5 specific password lookup. The digest is filled with the MD5 password which consists of a MD5 sum of @@ -28,6 +28,7 @@ extern UserInfoModule userinfo_shadow; extern UserInfoModule userinfo_pam; extern UserInfoModule userinfo_passwd_file; +extern UserInfoModule userinfo_vpopmail; void userinfo_init(void); void userinfo_deinit(void);