Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 20 Nov 1997 14:58:18 -0500 (EST)
From:      dchapes@golden.net
To:        FreeBSD-gnats-submit@FreeBSD.ORG
Subject:   bin/5109: patch to ftpd, new option to limit number of ftpd sessions
Message-ID:  <199711201958.OAA02139@squigy.ddm.on.ca>
Resent-Message-ID: <199711202000.MAA01996@hub.freebsd.org>

next in thread | raw e-mail | index | archive | help

>Number:         5109
>Category:       bin
>Synopsis:       patch to ftpd, new option to limit number of ftpd sessions
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    freebsd-bugs
>State:          open
>Class:          change-request
>Submitter-Id:   current-users
>Arrival-Date:   Thu Nov 20 12:00:04 PST 1997
>Last-Modified:
>Originator:     Dave Chapeskie
>Organization:
DDM Consulting
>Release:        FreeBSD 2.2-STABLE i386
>Environment:
>Description:

FreeBSD's ftpd(8) has no way to limit the number of ftp clients
allowed at one time so I spent a few minutes to add and test a new
"-C maxchildren" option to ftpd to do this (when used with the
existing -D option).

It would be nice if someone with commit privileges could commit this.

The following patch is relative to FreeBSD-2.2.5 (actually 2.2-STABLE
shortly after 2.2.5) but should apply to -current as well.

>How-To-Repeat:
>Fix:
	
Index: ftpd.8
===================================================================
RCS file: /cvs/FreeBSD/src/libexec/ftpd/ftpd.8,v
retrieving revision 1.9.2.8
diff -u -r1.9.2.8 ftpd.8
--- ftpd.8	1997/05/10 19:48:12	1.9.2.8
+++ ftpd.8	1997/11/20 19:18:13
@@ -50,6 +50,7 @@
 .Op Fl t Ar timeout
 .Op Fl a Ar address
 .Op Fl p Ar file
+.Op Fl C Ar maxchildren
 .Sh DESCRIPTION
 .Nm Ftpd
 is the
@@ -137,6 +138,16 @@
 .Ar file .
 .It Fl A
 Allow only anonymous ftp access
+.It Fl C
+When
+.Fl D
+is specified, limit the number of concurrent ftp sessions to
+.Ar maxchildren .
+If the file
+.Pa /etc/ftptoomany
+exists,
+.Nm
+displays it before exiting.
 .El
 .Pp
 The file
@@ -429,6 +440,8 @@
 Welcome notice.
 .It Pa /etc/ftpmotd
 Welcome notice after login.
+.It Pa /etc/ftptoomany
+Displayed when there are too many ftp sessions.
 .It Pa /etc/nologin
 Displayed and access refused.
 .It Pa /var/log/ftpd
Index: ftpd.c
===================================================================
RCS file: /cvs/FreeBSD/src/libexec/ftpd/ftpd.c,v
retrieving revision 1.25.2.11
diff -u -r1.25.2.11 ftpd.c
--- ftpd.c	1997/09/05 12:45:29	1.25.2.11
+++ ftpd.c	1997/11/20 19:28:59
@@ -128,6 +128,8 @@
 int	debug;
 int	timeout = 900;    /* timeout after 15 minutes of inactivity */
 int	maxtimeout = 7200;/* don't allow idle time to be set beyond 2 hours */
+int	maxchildren = 0;
+int	children = 0;
 int	logging;
 int	restricted_data_ports = 1;
 int	paranoid = 1;	  /* be extra careful about security */
@@ -287,7 +289,7 @@
 
 
 	bind_address.s_addr = htonl(INADDR_ANY);
-	while ((ch = getopt(argc, argv, "AdlDSURt:T:u:va:p:")) != -1) {
+	while ((ch = getopt(argc, argv, "AdlDSURt:T:u:va:p:C:")) != -1) {
 		switch (ch) {
 		case 'D':
 			daemon_mode++;
@@ -353,6 +355,10 @@
 			debug = 1;
 			break;
 
+		case 'C':
+			maxchildren = atoi(optarg);
+			break;
+
 		default:
 			warnx("unknown flag -%c ignored", optopt);
 			break;
@@ -441,6 +447,7 @@
 		while (1) {
 			addrlen = sizeof(his_addr);
 			fd = accept(ctl_sock, (struct sockaddr *)&his_addr, &addrlen);
+			children++;
 			if (fork() == 0) {
 				/* child */
 				(void) dup2(fd, 0);
@@ -518,6 +525,23 @@
 		reply(530, "System not available.");
 		exit(0);
 	}
+
+	/* If there are too many ftpd's */
+	if (maxchildren && children > maxchildren) {
+		if ((fd = fopen(_PATH_FTPTOOMANY,"r")) != NULL) {
+			while (fgets(line, sizeof(line), fd) != NULL) {
+				if ((cp = strchr(line, '\n')) != NULL)
+					*cp = '\0';
+				lreply(530, "%s", line);
+			}
+			(void) fflush(stdout);
+			(void) fclose(fd);
+		} else {
+			reply(530, "Too many ftp users, try again later.");
+		}
+		exit(0);
+	}
+
 #ifdef VIRTUAL_HOSTING
 	if ((fd = fopen(thishost->welcome, "r")) != NULL) {
 #else
@@ -537,6 +561,14 @@
 		fatal("Ran out of memory.");
 	(void) gethostname(hostname, MAXHOSTNAMELEN);
 #endif
+	if (daemon_mode) {
+		if (maxchildren) {
+			lreply(220, "There are currently %d users out of "
+				"%d possible.", children, maxchildren);
+		} else {
+			lreply(220, "There are currently %d users.", children);
+		}
+	}
 	reply(220, "%s FTP server (%s) ready.", hostname, version);
 	(void) setjmp(errcatch);
 	for (;;)
@@ -2222,7 +2254,9 @@
 reapchild(signo)
 	int signo;
 {
-	while (wait3(NULL, WNOHANG, NULL) > 0);
+	while (wait3(NULL, WNOHANG, NULL) > 0) {
+		children--;
+	}
 }
 
 #ifdef OLD_SETPROCTITLE
Index: pathnames.h
===================================================================
RCS file: /cvs/FreeBSD/src/libexec/ftpd/pathnames.h,v
retrieving revision 1.6.2.2
diff -u -r1.6.2.2 pathnames.h
--- pathnames.h	1997/04/29 12:55:33	1.6.2.2
+++ pathnames.h	1997/11/20 18:40:15
@@ -42,3 +42,4 @@
 #define	_PATH_FTPHOSTS		"/etc/ftphosts"
 #define	_PATH_FTPDSTATFILE	"/var/log/ftpd"
 #define	_PATH_LS		"/bin/ls"
+#define	_PATH_FTPTOOMANY	"/etc/ftptoomany"
>Audit-Trail:
>Unformatted:



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199711201958.OAA02139>