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>
