ehrlich@psuvax1.psu.edu (Dan Ehrlich) (09/13/87)
Below are a set of patches to ftpd.c that result in most file operations being logged if logging is enabled. Modify the entry in /etc/inetd.conf to pass "-l" to ftpd when it gets cranked up. Here is the entry from our inetd.conf: ftp stream tcp nowait root /etc/ftpd ftpd -l RCS file: RCS/ftpd.c,v retrieving revision 1.1 retrieving revision 1.4 diff -c -r1.1 -r1.4 *** /tmp/,RCSt1028386 Sun Sep 13 09:23:58 1987 --- /tmp/,RCSt2028386 Sun Sep 13 09:24:01 1987 *************** *** 3,9 **** * All rights reserved. The Berkeley software License Agreement * specifies the terms and conditions for redistribution. */ ! #ifndef lint char copyright[] = "@(#) Copyright (c) 1985 Regents of the University of California.\n\ --- 3,23 ---- * All rights reserved. The Berkeley software License Agreement * specifies the terms and conditions for redistribution. */ ! /* ! * $Header: ftpd.c,v 1.4 87/09/11 11:13:47 ehrlich Exp $ ! * $Source: /usr/src/etc/ftpd/RCS/ftpd.c,v $ ! * $Log: ftpd.c,v $ ! * Revision 1.4 87/09/11 11:13:47 ehrlich ! * Clean up log messages a bit. --dre ! * ! * Revision 1.3 87/09/11 10:15:37 ehrlich ! * More extensive logging on file operations. --dre ! * ! * Revision 1.2 87/01/15 09:22:57 ehrlich ! * Log anonymous ftp logins with remote host name and remote user ident. ! * dre ! * ! */ #ifndef lint char copyright[] = "@(#) Copyright (c) 1985 Regents of the University of California.\n\ *************** *** 12,17 **** --- 26,33 ---- #ifndef lint static char sccsid[] = "@(#)ftpd.c 5.7 (Berkeley) 5/28/86"; + static char *RCShdr = "$Header: ftpd.c,v 1.4 87/09/11 11:13:47 ehrlich Exp $"; + static char *RCSsrc = "$Source: /usr/src/etc/ftpd/RCS/ftpd.c,v $"; #endif not lint /* *************** *** 54,59 **** --- 70,76 ---- extern FILE *popen(), *fopen(), *freopen(); extern int pclose(), fclose(); extern char *getline(); + extern char *ctime(); extern char cbuf[]; struct sockaddr_in ctrl_addr; *************** *** 81,86 **** --- 98,104 ---- char tmpline[7]; char hostname[32]; char remotehost[32]; + char password[32]; /* * Timeout intervals for retrying connections *************** *** 105,110 **** --- 123,129 ---- long pgid; char *cp; + openlog("ftpd", LOG_PID | LOG_CONS | LOG_NOWAIT, LOG_DAEMON); addrlen = sizeof (his_addr); if (getpeername(0, &his_addr, &addrlen) < 0) { syslog(LOG_ERR, "getpeername (%s): %m",argv[0]); *************** *** 117,123 **** } data_source.sin_port = htons(ntohs(ctrl_addr.sin_port) - 1); debug = 0; - openlog("ftpd", LOG_PID, LOG_DAEMON); argc--, argv++; while (argc > 0 && *argv[0] == '-') { for (cp = &argv[0][1]; *cp; cp++) switch (*cp) { --- 136,141 ---- *************** *** 177,182 **** --- 195,202 ---- (void) gethostname(hostname, sizeof (hostname)); reply(220, "%s FTP server (%s) ready.", hostname, version); + if (logging) + syslog(LOG_INFO, "%s FTP server (%s) ready.", hostname, version); for (;;) { (void) setjmp(errcatch); (void) yyparse(); *************** *** 187,193 **** { if (debug) ! syslog(LOG_DEBUG, "lost connection"); dologout(-1); } --- 207,213 ---- { if (debug) ! syslog(LOG_DEBUG, "lost connection with %s", remotehost); dologout(-1); } *************** *** 205,220 **** xpasswd = crypt(passwd, pw->pw_passwd); /* The strcmp does not catch null passwords! */ if (*pw->pw_passwd == '\0' || strcmp(xpasswd, pw->pw_passwd)) { reply(530, "Login incorrect."); pw = NULL; return; } ! } setegid(pw->pw_gid); initgroups(pw->pw_name, pw->pw_gid); if (chdir(pw->pw_dir)) { reply(530, "User %s: can't change directory to %s.", pw->pw_name, pw->pw_dir); goto bad; } --- 225,246 ---- xpasswd = crypt(passwd, pw->pw_passwd); /* The strcmp does not catch null passwords! */ if (*pw->pw_passwd == '\0' || strcmp(xpasswd, pw->pw_passwd)) { + if(logging) + syslog(LOG_INFO, "Login incorrect, user = %s.", pw->pw_name); reply(530, "Login incorrect."); pw = NULL; return; } ! } else /* If guest, password is ident of remote user. Tuck it away */ ! strncpy(password, passwd, sizeof(password)); setegid(pw->pw_gid); initgroups(pw->pw_name, pw->pw_gid); if (chdir(pw->pw_dir)) { reply(530, "User %s: can't change directory to %s.", pw->pw_name, pw->pw_dir); + if(logging) + syslog(LOG_INFO, "User %s: can't change directory to %s.", + pw->pw_name, pw->pw_dir); goto bad; } *************** *** 222,227 **** --- 248,255 ---- wtmp = open("/usr/adm/wtmp", O_WRONLY|O_APPEND); if (guest && chroot(pw->pw_dir) < 0) { reply(550, "Can't set guest privileges."); + if(logging) + syslog(LOG_INFO, "Can't set guest privileges: %m"); if (wtmp >= 0) { (void) close(wtmp); wtmp = -1; *************** *** 228,237 **** } goto bad; } ! if (!guest) reply(230, "User %s logged in.", pw->pw_name); ! else reply(230, "Guest login ok, access restrictions apply."); logged_in = 1; dologin(pw); seteuid(pw->pw_uid); --- 256,269 ---- } goto bad; } ! if (!guest) { reply(230, "User %s logged in.", pw->pw_name); ! if(logging) ! syslog(LOG_INFO, "User %s logged in from %s", pw->pw_name, ! remotehost); ! } else { reply(230, "Guest login ok, access restrictions apply."); + } logged_in = 1; dologin(pw); seteuid(pw->pw_uid); *************** *** 298,303 **** --- 330,338 ---- reply(550, "%s: not a plain file.", name); goto done; } + if (logging) + syslog(LOG_INFO, "%s at %s retrieving %s", + (guest ? password : pw->pw_name), remotehost, name); dout = dataconn(name, st.st_size, "w"); if (dout == NULL) goto done; *************** *** 346,351 **** --- 381,389 ---- reply(553, "%s: %s.", local, sys_errlist[errno]); return; } + if (logging) + syslog(LOG_INFO, "%s at %s storing %s", + (guest ? password : pw->pw_name), remotehost, name); din = dataconn(local, (off_t)-1, "r"); if (din == NULL) goto done; *************** *** 588,593 **** --- 626,633 ---- fatal(s) char *s; { + if (logging) + syslog(LOG_ERR, "Error in server: %s", s); reply(451, "Error in server: %s\n", s); reply(221, "Closing connection due to server error."); dologout(0); *************** *** 655,660 **** --- 695,703 ---- reply(550, "%s: %s.", name, sys_errlist[errno]); return; } + if (logging) + syslog(LOG_INFO, "%s at %s deleting %s", + (guest ? password : pw->pw_name), remotehost, name); if ((st.st_mode&S_IFMT) == S_IFDIR) { if (rmdir(name) < 0) { reply(550, "%s: %s.", name, sys_errlist[errno]); *************** *** 687,692 **** --- 730,738 ---- struct stat st; int dochown = stat(name, &st) < 0; + if (logging) + syslog(LOG_INFO, "%s at %s creating directory %s", + (guest ? password : pw->pw_name), remotehost, name); if (mkdir(name, 0777) < 0) { reply(550, "%s: %s.", name, sys_errlist[errno]); return; *************** *** 700,705 **** --- 746,754 ---- char *name; { + if (logging) + syslog(LOG_INFO, "%s at %s deleting directory %s", + (guest ? password : pw->pw_name), remotehost, name); if (rmdir(name) < 0) { reply(550, "%s: %s.", name, sys_errlist[errno]); return; *************** *** 736,741 **** --- 785,793 ---- char *from, *to; { + if (logging) + syslog(LOG_INFO, "%s at %s renaming %s to %s", + (guest ? password : pw->pw_name), remotehost, from, to); if (rename(from, to) < 0) { reply(550, "rename: %s.", sys_errlist[errno]); return; *************** *** 749,755 **** struct hostent *hp = gethostbyaddr(&sin->sin_addr, sizeof (struct in_addr), AF_INET); time_t t; - extern char *ctime(); if (hp) { (void) strncpy(remotehost, hp->h_name, sizeof (remotehost)); --- 801,806 ---- *************** *** 760,766 **** if (!logging) return; t = time((time_t *) 0); ! syslog(LOG_INFO,"FTPD: connection from %s at %s", remotehost, ctime(&t)); } #include <utmp.h> --- 811,817 ---- if (!logging) return; t = time((time_t *) 0); ! syslog(LOG_INFO,"connection from %s at %s", remotehost, ctime(&t)); } #include <utmp.h> *************** *** 789,794 **** --- 840,849 ---- wtmp = -1; } } + if (guest) { + syslog(LOG_INFO, "Anonymous login from \"%s\" by \"%s\"", + remotehost, password); + } } /* *************** *** 809,814 **** --- 864,877 ---- utmp.ut_time = (long) time((time_t *) 0); (void) write(wtmp, (char *)&utmp, sizeof (utmp)); (void) close(wtmp); + } + if(logging) { + if(guest) + syslog(LOG_INFO, "Guest %s at %s logged out", + password, remotehost); + else + syslog(LOG_INFO, "%s@%s logged out", pw->pw_name, + remotehost); } } /* beware of flushing buffers after a SIGPIPE */