Subject: bin/4133: ftpd should be able to use alternate configuration files
To: None <gnats-bugs@gnats.netbsd.org>
From: Matthias Scheler <tron@lyssa.owl.de>
List: netbsd-bugs
Date: 09/21/1997 23:31:30
>Number:         4133
>Category:       bin
>Synopsis:       ftpd should be able to use alternate configuration files
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    bin-bug-people (Utility Bug People)
>State:          open
>Class:          change-request
>Submitter-Id:   net
>Arrival-Date:   Sun Sep 21 14:35:01 1997
>Last-Modified:
>Originator:     Matthias Scheler
>Organization:
Matthias Scheler                                http://home.owl.de/~tron/
>Release:        970905
>Environment:
System: NetBSD lyssa 1.2G NetBSD 1.2G (LYSSA) #1: Sun Sep 7 15:04:37 MEST 1997 tron@lyssa:/usr/src/sys/arch/i386/compile/LYSSA i386

>Description:
[This PR supersedes bin/4131.]
To make "ftpd" behave differently depending on e.g. entries in "hosts.allow"
or different IP addresses (aka virtual ftp servers) it should have an option
to read its configuration files from a different directory. Unfortunately
there's no option for this purpose.

>How-To-Repeat:
man 8 ftpd

>Fix:
*** src/libexec/ftpd/conf.c.orig	Thu Aug 14 13:26:26 1997
--- src/libexec/ftpd/conf.c	Sun Sep 21 22:43:45 1997
*************** parse_conf(findclass)
*** 106,112 ****
  		curclass.modify = 0;
  	}
  
! 	infile = _PATH_FTPDCONF;
  	if ((f = fopen(infile, "r")) == NULL)
  		return;
  
--- 106,112 ----
  		curclass.modify = 0;
  	}
  
! 	infile = conffilename(_PATH_FTPDCONF);
  	if ((f = fopen(infile, "r")) == NULL)
  		return;
  
*** src/libexec/ftpd/extern.h.orig	Thu Jun 19 13:15:23 1997
--- src/libexec/ftpd/extern.h	Sun Sep 21 22:25:24 1997
***************
*** 36,41 ****
--- 36,42 ----
   */
  
  void	blkfree __P((char **));
+ char   *conffilename __P((char *));
  char  **copyblk __P((char **));
  void	cwd __P((char *));
  void	delete __P((char *));
*************** void	store __P((char *, char *, int));
*** 67,73 ****
  void	upper __P((char *));
  void	user __P((char *));
  void	yyerror __P((char *));
- 
  
  #define CLASS_CHROOT	"chroot"
  #define CLASS_GUEST	"guest"
--- 68,73 ----
*** src/libexec/ftpd/ftpd.8.orig	Sat Jun 14 13:20:30 1997
--- src/libexec/ftpd/ftpd.8	Sun Sep 21 21:58:40 1997
*************** Internet File Transfer Protocol server
*** 44,49 ****
--- 44,50 ----
  .Nm
  .Op Fl dl
  .Op Fl a Ar anondir
+ .Op Fl c Ar confdir
  .Sh DESCRIPTION
  .Nm
  is the
*************** Define the directory to
*** 63,68 ****
--- 64,74 ----
  .Xr chroot 2
  into for anonymous logins.
  Default is the home directory for the ftp user.
+ .It Fl c
+ Change the root directory of the configuration files from
+ .Dq Pa /etc
+ to
+ .Ar directory .
  .It Fl d
  Debugging information is written to the syslog using LOG_FTP.
  .It Fl l
*** src/libexec/ftpd/ftpd.c.orig	Wed Aug 27 13:18:37 1997
--- src/libexec/ftpd/ftpd.c	Sun Sep 21 22:49:57 1997
*************** char	remotehost[MAXHOSTNAMELEN];
*** 132,137 ****
--- 132,138 ----
  static char ttyline[20];
  char	*tty = ttyline;		/* for klogin */
  static char *anondir = NULL;
+ static char confdir[MAXPATHLEN];
  
  extern struct ftpclass curclass;
  
*************** static void	 send_data __P((FILE *, FILE
*** 191,196 ****
--- 192,198 ----
  static struct passwd *
  		 sgetpwnam __P((char *));
  static char	*sgetsave __P((char *));
+ char	        *conffilename __P((char *));
  
  int main __P((int, char *[], char **));
  
*************** main(argc, argv, envp)
*** 243,258 ****
  #endif
  	data_source.sin_port = htons(ntohs(ctrl_addr.sin_port) - 1);
  	debug = 0;
  
  	/* set this here so klogin can use it... */
  	(void)snprintf(ttyline, sizeof(ttyline), "ftp%d", getpid());
  
! 	while ((ch = getopt(argc, argv, "a:dlt:T:u:v")) != EOF) {
  		switch (ch) {
  		case 'a':
  			anondir = optarg;
  			break;
  
  		case 'd':
  		case 'v':		/* deprecated */
  			debug = 1;
--- 245,266 ----
  #endif
  	data_source.sin_port = htons(ntohs(ctrl_addr.sin_port) - 1);
  	debug = 0;
+ 	(void)strcpy (confdir, _DEFAULT_CONFDIR);
  
  	/* set this here so klogin can use it... */
  	(void)snprintf(ttyline, sizeof(ttyline), "ftp%d", getpid());
  
! 	while ((ch = getopt(argc, argv, "a:c:dlt:T:u:v")) != EOF) {
  		switch (ch) {
  		case 'a':
  			anondir = optarg;
  			break;
  
+ 		case 'c':
+ 			(void)strncpy(confdir, optarg, sizeof(confdir));
+ 			confdir[sizeof(confdir)-1] = '\0';
+                         break;
+ 
  		case 'd':
  		case 'v':		/* deprecated */
  			debug = 1;
*************** main(argc, argv, envp)
*** 313,319 ****
  		reply(530, "System not available.");
  		exit(0);
  	}
! 	if ((fd = fopen(_PATH_FTPWELCOME, "r")) != NULL) {
  		while (fgets(line, sizeof(line), fd) != NULL) {
  			if ((cp = strchr(line, '\n')) != NULL)
  				*cp = '\0';
--- 321,327 ----
  		reply(530, "System not available.");
  		exit(0);
  	}
! 	if ((fd = fopen(conffilename(_PATH_FTPWELCOME), "r")) != NULL) {
  		while (fgets(line, sizeof(line), fd) != NULL) {
  			if ((cp = strchr(line, '\n')) != NULL)
  				*cp = '\0';
*************** user(name)
*** 435,440 ****
--- 443,449 ----
  			    "ANONYMOUS FTP LOGIN REFUSED FROM %s", remotehost);
  		return;
  	}
+ 
  	pw = sgetpwnam(name);
  	if (logging)
  		strncpy(curname, name, sizeof(curname)-1);
*************** checkaccess(name)
*** 516,522 ****
  	int retval = ALLOWED;
  	char *glob, *perm, line[BUFSIZ];
  
! 	if ((fd = fopen(_PATH_FTPUSERS, "r")) == NULL)
  		return NOT_ALLOWED;
  
  	while (fgets(line, sizeof(line), fd) != NULL)  {
--- 525,531 ----
  	int retval = ALLOWED;
  	char *glob, *perm, line[BUFSIZ];
  
! 	if ((fd = fopen(conffilename(_PATH_FTPUSERS), "r")) == NULL)
  		return NOT_ALLOWED;
  
  	while (fgets(line, sizeof(line), fd) != NULL)  {
*************** skip:
*** 657,663 ****
  	logwtmp(ttyline, pw->pw_name, remotehost);
  	logged_in = 1;
  
! 	dochroot = checkuser(_PATH_FTPCHROOT, pw->pw_name);
  
  	/* parse ftpd.conf, setting up various parameters */
  	if (guest)
--- 666,672 ----
  	logwtmp(ttyline, pw->pw_name, remotehost);
  	logged_in = 1;
  
! 	dochroot = checkuser(conffilename(_PATH_FTPCHROOT), pw->pw_name);
  
  	/* parse ftpd.conf, setting up various parameters */
  	if (guest)
*************** skip:
*** 699,705 ****
  	 * Display a login message, if it exists.
  	 * N.B. reply(230,) must follow the message.
  	 */
! 	if ((fd = fopen(_PATH_FTPLOGINMESG, "r")) != NULL) {
  		char *cp, line[LINE_MAX];
  
  		while (fgets(line, sizeof(line), fd) != NULL) {
--- 708,714 ----
  	 * Display a login message, if it exists.
  	 * N.B. reply(230,) must follow the message.
  	 */
! 	if ((fd = fopen(conffilename(_PATH_FTPLOGINMESG), "r")) != NULL) {
  		char *cp, line[LINE_MAX];
  
  		while (fgets(line, sizeof(line), fd) != NULL) {
*************** out:
*** 1782,1785 ****
--- 1791,1804 ----
  		freeglob = 0;
  		globfree(&gl);
  	}
+ }
+ 
+ char *
+ conffilename(s)
+ 	char *s;
+ {
+ 	static char filename[MAXPATHLEN];
+ 
+ 	(void)snprintf(filename, sizeof(filename), "%s/%s", confdir ,s);
+ 	return filename;
  }
*** src/libexec/ftpd/pathnames.h.orig	Sat Jun 14 13:20:32 1997
--- src/libexec/ftpd/pathnames.h	Sun Sep 21 22:38:37 1997
***************
*** 37,44 ****
  
  #include <paths.h>
  
! #define	_PATH_FTPCHROOT		"/etc/ftpchroot"
! #define	_PATH_FTPDCONF		"/etc/ftpd.conf"
! #define	_PATH_FTPLOGINMESG	"/etc/motd"
! #define	_PATH_FTPUSERS		"/etc/ftpusers"
! #define	_PATH_FTPWELCOME	"/etc/ftpwelcome"
--- 37,46 ----
  
  #include <paths.h>
  
! #define _DEFAULT_CONFDIR	"/etc"
! 
! #define	_PATH_FTPCHROOT		"ftpchroot"
! #define	_PATH_FTPDCONF		"ftpd.conf"
! #define	_PATH_FTPLOGINMESG	"motd"
! #define	_PATH_FTPUSERS		"ftpusers"
! #define	_PATH_FTPWELCOME	"ftpwelcome"

>Audit-Trail:
>Unformatted: