changeset 671:d2a574cbeccb HEAD

vpopmail's parse_email() is buggy, we need to zero fill the username buffer before calling it.
author Timo Sirainen <tss@iki.fi>
date Mon, 25 Nov 2002 15:35:53 +0200
parents e5f32324af3c
children 550eaf0fcb7a
files src/auth/userinfo-vpopmail.c
diffstat 1 files changed, 34 insertions(+), 5 deletions(-) [+]
line wrap: on
line diff
--- a/src/auth/userinfo-vpopmail.c	Mon Nov 25 15:19:55 2002 +0200
+++ b/src/auth/userinfo-vpopmail.c	Mon Nov 25 15:35:53 2002 +0200
@@ -13,6 +13,8 @@
 #include <vpopmail.h>
 #include <vauth.h>
 
+/* #define I_DEBUG(x) i_warning x */
+
 /* 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. */
@@ -26,28 +28,52 @@
 	char *passdup;
 	int result;
 
+	/* vpop_user must be zero-filled or parse_email() leaves an extra
+	   character after the user name. we'll fill vpop_domain as well
+	   just to be sure... */
+	memset(vpop_user, '\0', sizeof(vpop_user));
+	memset(vpop_domain, '\0', sizeof(vpop_domain));
+
 	if (parse_email(t_strdup_noconst(user), vpop_user, vpop_domain,
-			sizeof(vpop_user)-1) < 0)
+			sizeof(vpop_user)-1) < 0) {
+		I_DEBUG(("vpopmail: parse_email(%s) failed", user));
 		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)
+			&reply->uid, &reply->gid) == NULL) {
+		I_DEBUG(("vpopmail: vget_assign(%s) failed", vpop_domain));
 		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 */
+		I_DEBUG(("vpopmail: pw_dir isn't set, creating"));
+
 		if (make_user_dir(vpop_user, vpop_domain,
-				  reply->uid, reply->gid) == NULL)
+				  reply->uid, reply->gid) == NULL) {
+			i_error("vpopmail: make_user_dir(%s, %s) failed",
+				vpop_user, vpop_domain);
 			return FALSE;
+		}
 
 		vpw = vauth_getpw(vpop_user, vpop_domain);
 	}
 
-	if (vpw == NULL || (vpw->pw_gid & NO_IMAP))
+	if (vpw == NULL) {
+		I_DEBUG(("vpopmail: vauth_getpw(%s, %s) failed",
+		       vpop_user, vpop_domain));
 		return FALSE;
+	}
+
+	if (vpw->pw_gid & NO_IMAP) {
+		I_DEBUG(("vpopmail: IMAP disabled for %s@%s",
+		       vpop_user, vpop_domain));
+		return FALSE;
+	}
 
 	/* verify password */
         passdup = t_strdup_noconst(password);
@@ -56,8 +82,11 @@
 	memset(passdup, 0, strlen(passdup));
 	memset(vpw->pw_passwd, 0, strlen(vpw->pw_passwd));
 
-	if (!result)
+	if (!result) {
+		I_DEBUG(("vpopmail: password mismatch for user %s@%s",
+		       vpop_user, vpop_domain));
 		return FALSE;
+	}
 
 	/* make sure it's not giving too large values to us */
 	if (strlen(vpw->pw_dir) >= sizeof(reply->home)) {