diff options
author | imp <imp@FreeBSD.org> | 1996-09-22 04:19:27 +0000 |
---|---|---|
committer | imp <imp@FreeBSD.org> | 1996-09-22 04:19:27 +0000 |
commit | c04f619292e13248b5eac368266aee4d54699b51 (patch) | |
tree | 9c12365a107622c02dbcb4ffc7b4a1952873ff11 /libexec/tftpd | |
parent | a43b707795a51c0af5320d933cbf0d274a3661b4 (diff) | |
download | FreeBSD-src-c04f619292e13248b5eac368266aee4d54699b51.zip FreeBSD-src-c04f619292e13248b5eac368266aee4d54699b51.tar.gz |
Reviewed by: Bill Fenner <fennder@parc.xerox.com>
Reviewed by: Garrett Wollman <wollman@freebsd.org>
Submitted by: Warner Losh <imp@village.org>
Close PR bin/1145:
Add -s flag to tftpd. This enables the so-called secure mode
of tftpd where it chroots to a given directory before allowing access
to the files. In addition, it runs as nobody when in this mode.
Reviewed a long time ago by Bill and Garrett. Apply my patch from the
pr, and close the PR.
Diffstat (limited to 'libexec/tftpd')
-rw-r--r-- | libexec/tftpd/tftpd.8 | 15 | ||||
-rw-r--r-- | libexec/tftpd/tftpd.c | 33 |
2 files changed, 47 insertions, 1 deletions
diff --git a/libexec/tftpd/tftpd.8 b/libexec/tftpd/tftpd.8 index 430c1c4..4a9004d 100644 --- a/libexec/tftpd/tftpd.8 +++ b/libexec/tftpd/tftpd.8 @@ -42,6 +42,7 @@ Internet Trivial File Transfer Protocol server .Nm tftpd .Op Fl l .Op Fl n +.Op Fl s Ar directory .Op Ar directory ... .Sh DESCRIPTION .Nm Tftpd @@ -87,6 +88,15 @@ names are prefixed by the one of the given directories. 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 @@ Logs all requests using .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 , diff --git a/libexec/tftpd/tftpd.c b/libexec/tftpd/tftpd.c index 7500abf..9ab7778 100644 --- a/libexec/tftpd/tftpd.c +++ b/libexec/tftpd/tftpd.c @@ -52,6 +52,7 @@ static char sccsid[] = "@(#)tftpd.c 8.1 (Berkeley) 6/4/93"; #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 @@ static char sccsid[] = "@(#)tftpd.c 8.1 (Berkeley) 6/4/93"; #include <string.h> #include <syslog.h> #include <unistd.h> +#include <pwd.h> #include "tftpsubs.h" @@ -113,9 +115,11 @@ main(argc, argv) 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,6 +127,9 @@ main(argc, argv) case 'n': suppress_naks = 1; break; + case 's': + chroot_dir = optarg; + break; default: syslog(LOG_WARNING, "ignoring unknown option -%c", ch); } @@ -140,6 +147,10 @@ main(argc, argv) } } } + else if (chroot_dir) { + dirs->name = "/"; + dirs->len = 1; + } on = 1; if (ioctl(0, FIONBIO, &on) < 0) { @@ -203,6 +214,26 @@ main(argc, argv) 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); |