cak@Purdue.ARPA (01/13/84)
From: Christopher A Kent <cak@Purdue.ARPA> Description: The FTP daemon doesn't properly log anonymous logins in /usr/adm/wtmp because the chroot to /usr/ftp is done before wtmp is opened; thus the open always fails. My previous fix to this was not wonderful, because while it correctly record logins, it never recorded logouts. This version does both. I also changed logging to be done via syslog(3), and now log the ident supplied by anonymous users as well as all connections. Repeat-By: ftp to localhost, log in as ftp, quit, and do a last. No record. Fix: Apply the following diffs to ftpd.c; note that logging must be explicitly enabled with -l in /etc/rc.local. RCS file: RCS/ftpd.c,v retrieving revision 1.1 retrieving revision 1.2 diff -c -r1.1 -r1.2 *** /tmp/,RCSt1006490 Fri Jan 13 12:21:37 1984 --- /tmp/,RCSt2006490 Fri Jan 13 12:21:43 1984 *************** *** 1,5 #ifndef lint ! static char rcsid[] = "$Header: /usr/src/etc/ftpd/RCS/ftpd.c,v 1.1 84/01/11 19:46:08 cak Rel $"; static char sccsid[] = "@(#)ftpd.c 4.28 (Berkeley) 9/22/83"; #endif --- 1,5 ----- #ifndef lint ! static char rcsid[] = "$Header: /usr/src/etc/ftpd/RCS/ftpd.c,v 1.2 84/01/13 11:55:30 cak Exp $"; static char sccsid[] = "@(#)ftpd.c 4.28 (Berkeley) 9/22/83"; #endif *************** *** 55,60 int timeout; int logging; int guest; int type; int form; int stru; /* avoid C keyword */ --- 55,61 ----- int timeout; int logging; int guest; + int wtmp; int type; int form; int stru; /* avoid C keyword */ *************** *** 235,240 pw->pw_name, pw->pw_dir); goto bad; } if (guest && chroot(pw->pw_dir) < 0) { reply(550, "Can't set guest privileges."); goto bad; --- 236,245 ----- pw->pw_name, pw->pw_dir); goto bad; } + + if (guest) /* grab wtmp before chroot */ + wtmp = open("/usr/adm/wtmp", O_WRONLY|O_APPEND); + if (guest && chroot(pw->pw_dir) < 0) { reply(550, "Can't set guest privileges."); goto bad; *************** *** 724,730 dologin(pw) struct passwd *pw; { - int wtmp; char line[32]; wtmp = open("/usr/adm/wtmp", O_WRONLY|O_APPEND); --- 729,734 ----- dologin(pw) struct passwd *pw; { char line[32]; if (guest && (wtmp >= 0)) *************** *** 727,733 int wtmp; char line[32]; ! wtmp = open("/usr/adm/wtmp", O_WRONLY|O_APPEND); if (wtmp >= 0) { /* hack, but must be unique and no tty line */ sprintf(line, "ftp%d", getpid()); --- 731,740 ----- { char line[32]; ! if (guest && (wtmp >= 0)) ! lseek(wtmp, 0, L_XTND); ! else ! wtmp = open("/usr/adm/wtmp", O_WRONLY|O_APPEND); if (wtmp >= 0) { /* hack, but must be unique and no tty line */ sprintf(line, "ftp%d", getpid()); *************** *** 736,742 SCPYN(utmp.ut_host, remotehost); utmp.ut_time = time(0); (void) write(wtmp, (char *)&utmp, sizeof (utmp)); ! (void) close(wtmp); } } --- 743,750 ----- SCPYN(utmp.ut_host, remotehost); utmp.ut_time = time(0); (void) write(wtmp, (char *)&utmp, sizeof (utmp)); ! if (!guest) ! (void) close(wtmp); } } *************** *** 747,754 dologout(status) int status; { - int wtmp; - if (!logged_in) _exit(status); seteuid(0); --- 755,760 ----- dologout(status) int status; { if (!logged_in) _exit(status); seteuid(0); *************** *** 752,758 if (!logged_in) _exit(status); seteuid(0); ! wtmp = open("/usr/adm/wtmp", O_WRONLY|O_APPEND); if (wtmp >= 0) { SCPYN(utmp.ut_name, ""); SCPYN(utmp.ut_host, ""); --- 758,767 ----- if (!logged_in) _exit(status); seteuid(0); ! if (guest && (wtmp >= 0)) ! lseek(wtmp, 0, L_XTND); ! else ! wtmp = open("/usr/adm/wtmp", O_WRONLY|O_APPEND); if (wtmp >= 0) { SCPYN(utmp.ut_name, ""); SCPYN(utmp.ut_host, ""); ----------
jsq@ut-sally.UUCP (01/17/84)
Cak@Purdue's fix to logging of anonymous logins by ftpd in wtmp had several problems. The following is another fix for the same but, which has been run by cak for criticism. I will submit it to Berkeley shortly. *** ftpd.c.dist Tue Jan 17 12:33:52 1984 --- ftpd.c Tue Jan 17 12:41:11 1984 *************** *** 234,242 pw->pw_name, pw->pw_dir); goto bad; } ! if (guest && chroot(pw->pw_dir) < 0) { ! reply(550, "Can't set guest privileges."); ! goto bad; } if (!guest) reply(230, "User %s logged in.", pw->pw_name); --- 234,246 ----- pw->pw_name, pw->pw_dir); goto bad; } ! if (guest) { ! dologset(1); ! if (chroot(pw->pw_dir) < 0) { ! dologset(0); ! reply(550, "Can't set guest privileges."); ! goto bad; ! } } if (!guest) reply(230, "User %s logged in.", pw->pw_name); *************** *** 716,721 #define SCPYN(a, b) strncpy(a, b, sizeof (a)) struct utmp utmp; /* * Record login in wtmp file. --- 720,726 ----- #define SCPYN(a, b) strncpy(a, b, sizeof (a)) struct utmp utmp; + int wtmp = -1; /* * Open or close wtmp. *************** *** 718,723 struct utmp utmp; /* * Record login in wtmp file. */ dologin(pw) --- 723,745 ----- int wtmp = -1; /* + * Open or close wtmp. + */ + dologset(flag) + int flag; + { + if (flag) { + if (wtmp < 0) + wtmp = open("/usr/adm/wtmp", O_WRONLY|O_APPEND); + return; + } + if (wtmp < 0) + return; + (void) close (wtmp); + wtmp = -1; + } + + /* * Record login in wtmp file. */ dologin(pw) *************** *** 723,729 dologin(pw) struct passwd *pw; { - int wtmp; char line[32]; wtmp = open("/usr/adm/wtmp", O_WRONLY|O_APPEND); --- 745,750 ----- dologin(pw) struct passwd *pw; { char line[32]; dologset(1); *************** *** 726,732 int wtmp; char line[32]; ! wtmp = open("/usr/adm/wtmp", O_WRONLY|O_APPEND); if (wtmp >= 0) { /* hack, but must be unique and no tty line */ sprintf(line, "ftp%d", getpid()); --- 747,753 ----- { char line[32]; ! dologset(1); if (wtmp >= 0) { /* hack, but must be unique and no tty line */ sprintf(line, "ftp%d", getpid()); *************** *** 735,741 SCPYN(utmp.ut_host, remotehost); utmp.ut_time = time(0); (void) write(wtmp, (char *)&utmp, sizeof (utmp)); ! (void) close(wtmp); } } --- 756,763 ----- SCPYN(utmp.ut_host, remotehost); utmp.ut_time = time(0); (void) write(wtmp, (char *)&utmp, sizeof (utmp)); ! if (!guest) ! dologset(0); } } *************** *** 746,753 dologout(status) int status; { - int wtmp; - if (!logged_in) _exit(status); seteuid(0); --- 768,773 ----- dologout(status) int status; { if (!logged_in) _exit(status); seteuid(0); *************** *** 751,757 if (!logged_in) _exit(status); seteuid(0); ! wtmp = open("/usr/adm/wtmp", O_WRONLY|O_APPEND); if (wtmp >= 0) { SCPYN(utmp.ut_name, ""); SCPYN(utmp.ut_host, ""); --- 771,778 ----- if (!logged_in) _exit(status); seteuid(0); ! if (!guest) ! dologset(1); if (wtmp >= 0) { SCPYN(utmp.ut_name, ""); SCPYN(utmp.ut_host, ""); *************** *** 757,763 SCPYN(utmp.ut_host, ""); utmp.ut_time = time(0); (void) write(wtmp, (char *)&utmp, sizeof (utmp)); ! (void) close(wtmp); } /* beware of flushing buffers after a SIGPIPE */ _exit(status); --- 778,784 ----- SCPYN(utmp.ut_host, ""); utmp.ut_time = time(0); (void) write(wtmp, (char *)&utmp, sizeof (utmp)); ! dologset(0); } /* beware of flushing buffers after a SIGPIPE */ _exit(status); -- John Quarterman, CS Dept., University of Texas, Austin, Texas {ihnp4,seismo,ctvax}!ut-sally!jsq, jsq@ut-sally.{ARPA,UUCP}