Subject: Possible patch for wu-ftpd ?

From: Ian Jackson <[email-masked]>
Date: Mon, 1 Jul 96 04:44 BST

Would it be worth applying the patch below to our ftpd ?   I haven't
checked or tested it, but I have encountered the problem it purports
to solve.

Ian.

------- start of forwarded message (RFC 934 encapsulation) -------
Article: 645 of chiark.mail.linux-security
From: [email-masked] (Yury Shevchuk)
Sender: [email-masked]
To: [email-masked],
        Richard Jones <[email-masked]>
Subject: Re: [linux-security] wu.ftp, ftpaccess, and /bin/false shell
Date: Thu, 20 Jun 1996 00:52:06 GMT

Hello,

In message <[email-masked]>
    Richard Jones writes:

>  I'm trying to use the wu.ftp ftpaccess file to setup a guestgroup whereby
>users with listings in the /etc/passwd file can upload to certain 
>sections of a Linux-based web site.  However, I'd like to deny these 
>people telnet access.  In ftpaccess I use the line:
>
>guestgroup ftponly 
>
>ftponly is defined as a group in /etc/group and its users have 
>/etc/passwd entries that look like:
>
>ftponlyuser1:sladfkj:12:324:FTP ONLY:/usr/ftp/./user1s_ftp_dir/:bin/false
>
>This is straight out of O'Reilly's Managing Internet Info. Services.  
>This doesn't work for me, though.  With a shell set to /bin/false a user 
>is not allowed to ftp login.  Is this a Linux thing? The user can ftp 
>login with /bin/bash or some other viable shell, but this opens up telnet 
>ability to the user (I can't use /etc/hosts.deny because it's too coarse).

IMHO, this is an overlook in wu-ftpd: the daemon denies access to
users whose shells are not listed in /etc/shells.  Adding /etc/ftponly
(or /bin/false) to /etc/shells is not the right way to go, though,
since doing so would be against the definition of /etc/shells: that
file should list only true unrestricted command interpreters (note:
/usr/bin/chsh).

On our site, ftponly logins work with the following hack to wu-ftpd,
which skips the /etc/shells check for accounts that have /etc/ftponly
as the login shell.  BTW, /etc/ftponly is a link to /usr/bin/passwd on
this system, which lets ftponly users to telnet to the system only to
change their passwords (not my invention -- seen on one of linux
mailing lists).

- -- Yura

===================================================================
RCS file: ftpd.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
- --- 1.1	1995/02/14 21:32:14
+++ 1.2	1995/02/14 22:04:46
@@ -855,22 +855,31 @@
             shell = _PATH_BSHELL;
         while ((cp = getusershell()) != NULL)
             if (strcmp(cp, shell) == 0)
                 break;
         endusershell();
- -        if (cp == NULL || checkuser(name)) {
+        /* if user is a member of any of the guestgroups, cause a chroot() */
+        /* after they log in successfully                                  */
+        guest = acl_guestgroup(pw);
+        /* guestgroup users may have /etc/ftponly as a shell, even though  */
+        /* it is not in /etc/shells                                        */
+        if (cp == NULL && ! (guest && strcmp(shell, "/etc/ftponly") == 0)) {
             reply(530, "User %s access denied...", name);
- -            if (logging)
- -                syslog(LOG_NOTICE,
- -                       "FTP LOGIN REFUSED (bad shell) FROM %s [%s], %s",
- -                       remotehost, remoteaddr, name);
+            syslog(LOG_NOTICE,
+                   "FTP LOGIN REFUSED (bad shell) FROM %s [%s], %s",
+                   remotehost, remoteaddr, name);
             pw = (struct passwd *) NULL;
             return;
         }
- -        /* if user is a member of any of the guestgroups, cause a chroot() */
- -        /* after they log in successfully                                  */
- -        guest = acl_guestgroup(pw);
+        if (checkuser(name)) {
+            reply(530, "User %s access denied...", name);
+            syslog(LOG_NOTICE,
+                   "FTP LOGIN REFUSED (in ftpusers) FROM %s [%s], %s",
+                   remotehost, remoteaddr, name);
+            pw = (struct passwd *) NULL;
+            return;
+        }
     }
     if (access_ok(530) < 1) {
         reply(530, "User %s access denied....", name);
         syslog(LOG_NOTICE, "FTP LOGIN REFUSED (access denied) FROM %s [%s], %s",
                remotehost, remoteaddr, name);

------- end -------