diff --git a/libexec/tftpd/tftpd.8 b/libexec/tftpd/tftpd.8 --- a/libexec/tftpd/tftpd.8 +++ b/libexec/tftpd/tftpd.8 @@ -36,7 +36,7 @@ .Nd Internet Trivial File Transfer Protocol server .Sh SYNOPSIS .Nm tftpd -.Op Fl cdClnow +.Op Fl cdClnoSw .Op Fl F Ar strftime-format .Op Fl s Ar directory .Op Fl u Ar user @@ -191,6 +191,8 @@ After doing that but before accepting commands, .Nm will switch credentials to an unprivileged user. +.It Fl S +Skip requirements for world-writable permissions to write to file. .It Fl u Ar user Switch credentials to .Ar user diff --git a/libexec/tftpd/tftpd.c b/libexec/tftpd/tftpd.c --- a/libexec/tftpd/tftpd.c +++ b/libexec/tftpd/tftpd.c @@ -104,6 +104,7 @@ static const char *newfile_format = "%Y%m%d"; static int increase_name = 0; static mode_t mask = S_IWGRP | S_IWOTH; +static int secwrt = 0; struct formats; static void tftp_recvfile(int peer, const char *mode); @@ -141,7 +142,7 @@ 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:s:Su:U:wW")) != -1) { switch (ch) { case 'c': ipchroot = 1; @@ -181,6 +182,9 @@ case 's': chroot_dir = optarg; break; + case 'S': + secwrt = 1; + break; case 'u': chuser = optarg; break; @@ -734,7 +738,7 @@ if ((stbuf.st_mode & S_IROTH) != 0) break; } else { - if ((stbuf.st_mode & S_IWOTH) != 0) + if (secwrt || (stbuf.st_mode & S_IWOTH) != 0) break; } err = EACCESS;