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>