summaryrefslogtreecommitdiffstats
path: root/libexec/tftpd/tftpd.c
diff options
context:
space:
mode:
Diffstat (limited to 'libexec/tftpd/tftpd.c')
-rw-r--r--libexec/tftpd/tftpd.c33
1 files changed, 32 insertions, 1 deletions
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);
OpenPOWER on IntegriCloud