Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 16 Apr 1996 14:00:02 -0700 (PDT)
From:      Warner Losh <imp@village.org>
To:        freebsd-bugs
Subject:   Re: bin/1145: tftpd should support -s 
Message-ID:  <199604162100.OAA08733@freefall.freebsd.org>

next in thread | raw e-mail | index | archive | help
The following reply was made to PR bin/1145; it has been noted by GNATS.

From: Warner Losh <imp@village.org>
To: Bill Fenner <fenner@parc.xerox.com>
Cc: FreeBSD-gnats-submit@freebsd.org
Subject: Re: bin/1145: tftpd should support -s 
Date: Tue, 16 Apr 1996 14:53:20 -0600

 I've taken Bill's and Garrett's suggestions and made those changes.
 I've also moved the chroot to *AFTER* the recvfrom because if it is
 before and there is a problem with the chroot then inetd would loop
 very quickly...  Here's the whole patch, please ignore the first patch
 I submitted.  Comments?
 
 Warner
 
 Index: tftpd.8
 ===================================================================
 RCS file: /home/imp/FreeBSD/CVS/src/libexec/tftpd/tftpd.8,v
 retrieving revision 1.1.1.1
 diff -u -r1.1.1.1 tftpd.8
 --- tftpd.8	1994/05/27 12:39:25	1.1.1.1
 +++ tftpd.8	1996/04/15 23:56:55
 @@ -42,6 +42,7 @@
  .Nm tftpd
  .Op Fl l
  .Op Fl n
 +.Op Fl s Ar directory
  .Op Ar directory ...
  .Sh DESCRIPTION
  .Nm Tftpd
 @@ -87,6 +88,15 @@
  The given directories are also treated as a search path for 
  relative filename requests.
  .Pp
 +The chroot option provides additional security by restricting access
 +of tftpd to only a chroot'd file system.  This is useful when moving
 +from an OS that supported 
 +.Nm -s
 +as a boot server.  Because chroot is restricted to root, you must run
 +tftpd as root.  However, if you chroot, then
 +.Nm tftpd
 +will set its user id to nobody.
 +.Pp
  The options are:
  .Bl -tag -width Ds
  .It Fl l
 @@ -95,6 +105,11 @@
  .It Fl n
  Suppresses negative acknowledgement of requests for nonexistent
  relative filenames.
 +.It Fl s Ar directory
 +Causes tftpd to chroot to
 +.Pa directory
 +before accepting commands.  In addition, the user id is set to
 +nobody.
  .El
  .Sh SEE ALSO
  .Xr tftp 1 ,
 Index: tftpd.c
 ===================================================================
 RCS file: /home/imp/FreeBSD/CVS/src/libexec/tftpd/tftpd.c,v
 retrieving revision 1.2
 diff -u -r1.2 tftpd.c
 --- tftpd.c	1995/02/26 23:28:00	1.2
 +++ tftpd.c	1996/04/16 20:47:27
 @@ -52,6 +52,7 @@
  #include <sys/ioctl.h>
  #include <sys/stat.h>
  #include <sys/socket.h>
 +#include <sys/types.h>
  
  #include <netinet/in.h>
  #include <arpa/tftp.h>
 @@ -68,6 +69,7 @@
  #include <string.h>
  #include <syslog.h>
  #include <unistd.h>
 +#include <pwd.h>
  
  #include "tftpsubs.h"
  
 @@ -113,9 +115,11 @@
  	register int n;
  	int ch, on;
  	struct sockaddr_in sin;
 +	char *chroot_dir = NULL;
 +	struct passwd *nobody;
  
  	openlog("tftpd", LOG_PID, LOG_FTP);
 -	while ((ch = getopt(argc, argv, "ln")) != EOF) {
 +	while ((ch = getopt(argc, argv, "lns:")) != EOF) {
  		switch (ch) {
  		case 'l':
  			logging = 1;
 @@ -123,10 +127,14 @@
  		case 'n':
  			suppress_naks = 1;
  			break;
 +		case 's':
 +			chroot_dir = optarg;
 +			break;
  		default:
  			syslog(LOG_WARNING, "ignoring unknown option -%c", ch);
  		}
  	}
 +
  	if (optind < argc) {
  		struct dirlist *dirp;
  
 @@ -140,6 +148,10 @@
  			}
  		}
  	}
 +	else if (chroot_dir) {
 +		dirs->name = "/";
 +		dirs->len = 1;
 +	}
  
  	on = 1;
  	if (ioctl(0, FIONBIO, &on) < 0) {
 @@ -203,6 +215,27 @@
  			exit(0);
  		}
  	}
 +
 +	/*
 +	 * Since we exit here, we should do that only after the above
 +	 * recvfrom to keep inetd from constantly forking should there
 +	 * be a problem.  See the above comment about system clogging.
 +	 */
 +	if (chroot_dir) {
 +		/* Must get this before chroot because /etc might go away */
 +		if ((nobody = getpwnam("nobody")) == NULL) {
 +			syslog(LOG_ERR, "nobody: no such user");
 +			exit(1);
 +		}
 +		if (chroot(chroot_dir)) {
 +			syslog(LOG_ERR, "chroot: %s: %m", chroot_dir);
 +			exit(1);
 +		}
 +		chdir( "/" );
 +		setuid(nobody->pw_uid);
 +	}
 +
 +
  	from.sin_family = AF_INET;
  	alarm(0);
  	close(0);



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