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);