Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

ports/28810: qpopper 4.0.3 + PAM modification; HAVE_SHADOW stupidity

0 views
Skip to first unread message

Seva Gluschenko

unread,
Jul 8, 2001, 9:20:18 AM7/8/01
to

>Number: 28810
>Category: ports
>Synopsis: qpopper 4.0.3 + PAM modification; HAVE_SHADOW stupidity
>Confidential: no
>Severity: non-critical
>Priority: low
>Responsible: freebsd-ports
>State: open
>Quarter:
>Keywords:
>Date-Required:
>Class: sw-bug
>Submitter-Id: current-users
>Arrival-Date: Sun Jul 08 06:20:01 PDT 2001
>Closed-Date:
>Last-Modified:
>Originator: Seva Gluschenko
>Release: FreeBSD 4.3-STABLE i386
>Organization:
Cronyx Plus LLC
>Environment:
CONFIGURE_ARGS= --enable-specialauth \
--enable-log-login \
--enable-shy \
--enable-log-facility=LOG_LOCAL0 \
--enable-uw-kludge \
--with-openssl \
--enable-server-mode \
--with-pam=pop

System: FreeBSD home.rinet.ru 4.3-STABLE

>Description:

Problem 1.

Without --with-pam argument given, the auth_user
function used in pop_pass.c produce error like:

pop_pass.c: In function `auth_user':
pop_pass.c:1174: warning: assignment makes pointer from integer without a cast
pop_pass.c:1181: dereferencing pointer to incomplete type
*** Error code 1

The quick look into code shows up the shadow access attempt:

pwd = getspnam ( p->user );

and previously defined shadow password structure:

register struct spwd *pwd;

which weren't properly framed with #ifdef HAVE_SHADOW_H macro check.
The patch supplied addresses this problem.


Problem 2.

As you may know, FreeBSD up to 4-STABLE has no default NSS
implementation. Thus, when you try to make use of PAM for
"non-existent" users, e.g. for POP users which have maildrops
but have no passwd entries for them, you're receiving the
message

ERR [AUTH] Password supplied for "xxxxxx" is incorrect.

The patch supplied changes the qpopper's behaviour, so that it
can receive the template user (say, "mailkeeper") from PAM and
use its credentials for further processing while keeping the
original username as the maildrop name.

>How-To-Repeat:

Problem 1:

# ./configure \
--enable-specialauth \
--enable-log-login \
--enable-shy \
--enable-log-facility=LOG_LOCAL0 \
--enable-uw-kludge \
--with-openssl \
--enable-server-mode

after configure finishes, run 'make' and have fun. Vendor has been
notified, but no response appeared.

Problem 2:

Start ./configure with CONFIGURE_ARGS specified in environment (the
same as above and --with-pam=pop). Be sure to replace "pop" PAM
service name with that one listed in your /etc/pam.conf. Type "make"
and then "make install". Make any additional steps required as it
specified in QPopper documentation.

Run QPopper and watch that nice "ERR [AUTH]" messages for PAM-known
users.

Greetings to fellow popa3d patchers who gave me a cute piece of code
which I've modified to satisfy QPopper needs, of course.

>Fix:

diff -u -r dist/qpopper4.0.3/popper/genpath.c qpopper4.0.3/popper/genpath.c
--- dist/qpopper4.0.3/popper/genpath.c Mon May 7 05:00:49 2001
+++ qpopper4.0.3/popper/genpath.c Sun Jul 8 16:03:14 2001
@@ -115,7 +115,11 @@
return -1; /*bogus login name*/
}

+#if !PAM_NOUTMPL
+ pszUser = p->user;
+#else
pszUser = pw->pw_name;
+#endif

/*
* First, the parent directory
diff -u -r dist/qpopper4.0.3/popper/pop_pass.c qpopper4.0.3/popper/pop_pass.c
--- dist/qpopper4.0.3/popper/pop_pass.c Sat Jun 2 06:24:35 2001
+++ qpopper4.0.3/popper/pop_pass.c Sun Jul 8 16:39:04 2001
@@ -436,6 +436,10 @@
POP * p;
struct passwd *pw;
{
+#if !PAM_NOUTMPL
+ static char buf[MAXLOGNAME];
+ const void *item;
+#endif
pam_handle_t *pamh = NULL;
int pamerror = 0;
int erc = 0;
@@ -488,6 +492,46 @@
return ( pop_msg ( p, POP_FAILURE, HERE, GP_ERRSTRING,
p->user, errmsg, pamerror ) );
}
+
+#if !PAM_NOUTMPL
+ /*
+ * With PAM we support the concept of a "template"
+ * user. The user enters a login name which is
+ * authenticated by PAM, usually via a remote service
+ * such as RADIUS or TACACS+. If authentication
+ * succeeds, a different but related "template" name
+ * is used for setting the credentials, shell, and
+ * home directory. The name the user enters need only
+ * exist on the remote authentication server, but the
+ * template name must be present in the local password
+ * database.
+ *
+ * This is supported by two various mechanisms in the
+ * individual modules. However, from the application's
+ * point of view, the template user is always passed
+ * back as a changed value of the PAM_USER item.
+ */
+
+ pamerror = pam_get_item(pamh, PAM_USER, &item);
+ DEBUG_LOG1 ( p, "pam_get_item returned %i", pamerror );
+ if (pamerror != PAM_SUCCESS) {
+ errmsg = pam_strerror ( pamh, pamerror );
+ pam_end(pamh, 0);
+ return ( pop_msg ( p, POP_FAILURE, HERE, GP_ERRSTRING,
+ p->user, errmsg, pamerror ) );
+ }
+ strlcpy( buf, item, sizeof(buf) );
+ if ((pw = getpwnam(buf)) == NULL) {
+ pam_end(pamh, 0);
+ return ( pop_msg ( p, POP_FAILURE, HERE,
+ "Error accessing user %s (no such template: %s)",
+ p->user, buf ) );
+ }
+ DEBUG_LOG2 ( p, "User will be %s, mailbox %s",
+ pw->pw_name, p->user);
+ memcpy(&p->pw, pw, sizeof(struct passwd));
+#endif
+
pamerror = pam_setcred ( pamh, PAM_ESTABLISH_CRED );
DEBUG_LOG1 ( p, "pam_setcred returned %i", pamerror );
if ( pamerror != PAM_SUCCESS ) {
@@ -1165,8 +1209,9 @@
POP * p;
struct passwd *pw;
{
- register struct spwd *pwd;
long today;
+# ifdef HAVE_SHADOW_H
+ register struct spwd *pwd;

/*
* Look for the user in the shadow password file
@@ -1180,6 +1225,7 @@
} else {
pw->pw_passwd = (char *)strdup(pwd->sp_pwdp);
}
+# endif /* HAVE_SHADOW_H */

/*
* We don't accept connections from users with null passwords
@@ -1280,6 +1326,7 @@
return ( pop_msg ( p, POP_FAILURE, HERE, ERRMSG_AUTH, p->user ) );
}

+# if defined (__FreeBSD__) && !defined (USE_PAM)
/*
* Verify user known by system.
*/
@@ -1290,6 +1337,7 @@
sleep ( SLEEP_SECONDS );
return ( pop_msg ( p, POP_FAILURE, HERE, ERRMSG_PW, p->user ) );
}
+# endif

#ifdef SECURENISPLUS
/*
@@ -1382,6 +1430,19 @@
sleep ( SLEEP_SECONDS );
return ( POP_FAILURE );
}
+
+#if defined (__FreeBSD__) && defined (USE_PAM)
+ /*
+ * Verify user known by system.
+ */
+ pwp = &p->pw;
+ if ( pwp->pw_name == NULL ) {
+ DEBUG_LOG1 ( p, "User %.128s not known by system",
+ p->user );
+ sleep ( SLEEP_SECONDS );
+ return ( pop_msg ( p, POP_FAILURE, HERE, ERRMSG_PW, p->user ) );
+ }
+#endif

#ifdef SECURENISPLUS
seteuid ( uid_save );
>Release-Note:
>Audit-Trail:
>Unformatted:

To Unsubscribe: send mail to majo...@FreeBSD.org
with "unsubscribe freebsd-ports" in the body of the message

0 new messages