Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 20 Jul 2023 20:23:39 GMT
From:      Eugene Grosbein <eugen@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org
Subject:   git: 273a307d0b80 - main - tftpd: introduce new option -S
Message-ID:  <202307202023.36KKNdNp002721@gitrepo.freebsd.org>

next in thread | raw e-mail | index | archive | help
The branch main has been updated by eugen:

URL: https://cgit.FreeBSD.org/src/commit/?id=273a307d0b80743fb08e23237b3f74dc94a8fa2a

commit 273a307d0b80743fb08e23237b3f74dc94a8fa2a
Author:     Eugene Grosbein <eugen@FreeBSD.org>
AuthorDate: 2023-07-20 20:11:33 +0000
Commit:     Eugene Grosbein <eugen@FreeBSD.org>
CommitDate: 2023-07-20 20:23:35 +0000

    tftpd: introduce new option -S
    
    Historically, tftpd disallowed write requests to existing files
    that are not publicly writable. Such requirement is questionable at least.
    Let us make it possible to run tftpd in chrooted environment
    keeping files non-world writable.
    
    New option -S enables write requests to existing files
    for chrooted run according to generic file permissions.
    It is ignored unless tftpd runs chrooted.
    
    MFC after:      1 month
    Requested by:   marck
    Differential:   https://reviews.freebsd.org/D41090 (based on)
---
 libexec/tftpd/tftpd.8 | 22 ++++++++++++++++++----
 libexec/tftpd/tftpd.c | 14 +++++++++++---
 2 files changed, 29 insertions(+), 7 deletions(-)

diff --git a/libexec/tftpd/tftpd.8 b/libexec/tftpd/tftpd.8
index e4f5ab94a2fe..a984cdc32c94 100644
--- a/libexec/tftpd/tftpd.8
+++ b/libexec/tftpd/tftpd.8
@@ -28,7 +28,7 @@
 .\"	@(#)tftpd.8	8.1 (Berkeley) 6/4/93
 .\" $FreeBSD$
 .\"
-.Dd March 2, 2020
+.Dd July 20, 2023
 .Dt TFTPD 8
 .Os
 .Sh NAME
@@ -72,7 +72,11 @@ Files containing the string
 or starting with
 .Dq Li "../"
 are not allowed.
-Files may be written only if they already exist and are publicly writable.
+Files may be written only if they already exist (unless the
+.Fl w
+option is used) and are publicly writable (unless chrooted and the
+.Fl S
+option is used).
 Note that this extends the concept of
 .Dq public
 to include
@@ -191,6 +195,12 @@ to change its root directory to
 After doing that but before accepting commands,
 .Nm
 will switch credentials to an unprivileged user.
+.It Fl S
+If
+.Nm
+runs chrooted, the option allows write requests according to generic
+file permissions, skipping requirement for files to be publicly writable.
+The option is ignored for non-chrooted run.
 .It Fl u Ar user
 Switch credentials to
 .Ar user
@@ -275,12 +285,16 @@ the
 .Fl c
 option was introduced in
 .Fx 4.3 ,
-and the
+the
 .Fl F
 and
 .Fl W
 options were introduced in
-.Fx 7.4 .
+.Fx 7.4 ,
+and the
+.Fl S
+option was introduced in
+.Fx 13.3 .
 .Pp
 Support for Timeout Interval and Transfer Size Options (RFC2349)
 was introduced in
diff --git a/libexec/tftpd/tftpd.c b/libexec/tftpd/tftpd.c
index b25e8b0c762f..9ae7575f3d23 100644
--- a/libexec/tftpd/tftpd.c
+++ b/libexec/tftpd/tftpd.c
@@ -100,6 +100,7 @@ static struct dirlist {
 static int	suppress_naks;
 static int	logging;
 static int	ipchroot;
+static int	check_woth = 1;
 static int	create_new = 0;
 static const char *newfile_format = "%Y%m%d";
 static int	increase_name = 0;
@@ -141,7 +142,7 @@ main(int argc, char *argv[])
 	acting_as_client = 0;
 
 	tftp_openlog("tftpd", LOG_PID | LOG_NDELAY, LOG_FTP);
-	while ((ch = getopt(argc, argv, "cCd::F:lnoOp:s:u:U:wW")) != -1) {
+	while ((ch = getopt(argc, argv, "cCd::F:lnoOp:sS:u:U:wW")) != -1) {
 		switch (ch) {
 		case 'c':
 			ipchroot = 1;
@@ -181,6 +182,9 @@ main(int argc, char *argv[])
 		case 's':
 			chroot_dir = optarg;
 			break;
+		case 'S':
+			check_woth = -1;
+			break;
 		case 'u':
 			chuser = optarg;
 			break;
@@ -361,7 +365,11 @@ main(int argc, char *argv[])
 			tftp_log(LOG_ERR, "setuid failed");
 			exit(1);
 		}
+		if (check_woth == -1)
+			check_woth = 0;
 	}
+	if (check_woth == -1)
+		check_woth = 1;
 
 	len = sizeof(me_sock);
 	if (getsockname(0, (struct sockaddr *)&me_sock, &len) == 0) {
@@ -704,7 +712,7 @@ validate_access(int peer, char **filep, int mode)
 			if ((stbuf.st_mode & S_IROTH) == 0)
 				return (EACCESS);
 		} else {
-			if ((stbuf.st_mode & S_IWOTH) == 0)
+			if (check_woth && ((stbuf.st_mode & S_IWOTH) == 0))
 				return (EACCESS);
 		}
 	} else {
@@ -734,7 +742,7 @@ validate_access(int peer, char **filep, int mode)
 					if ((stbuf.st_mode & S_IROTH) != 0)
 						break;
 				} else {
-					if ((stbuf.st_mode & S_IWOTH) != 0)
+					if (!check_woth || ((stbuf.st_mode & S_IWOTH) != 0))
 						break;
 				}
 				err = EACCESS;



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