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 */