Hi,
This diff adds an option for client IP address path prefixes to the
tftpd(8). First, I used the -r rewrite socket for this, but...
If you use the rewrite socket feature, the tftpd(8) will exit with an
error when the rewrite socket is closed. A reopen of the socket is not
possible, if its outside of the chroot directory. And a privilege
separated tftpd(8) is a bit overkill for a stable per client path
rewrite feature. This story led me to this change here.
Any suggestions or objections are welcome. :-)
Bye,
Jan
Index: tftpd.8
===================================================================
RCS file: /mount/openbsd/cvs/src/usr.sbin/tftpd/tftpd.8,v
retrieving revision 1.5
diff -u -p -r1.5 tftpd.8
--- tftpd.8 18 Jul 2015 05:32:56 -0000 1.5
+++ tftpd.8 18 Oct 2017 19:58:40 -0000
@@ -40,7 +40,7 @@
.Op Fl 46cdv
.Op Fl l Ar address
.Op Fl p Ar port
-.Op Fl r Ar socket
+.Op Fl i | Fl r Ar socket
.Ar directory
.Sh DESCRIPTION
.Nm
@@ -113,6 +113,12 @@ listens on the port indicated in the
.Ql tftp
service description; see
.Xr services 5 .
+.It Fl i
+.Nm
+will use the clients IP address as subdirectory prefix for all requested
+filenames.
+This option can not be combined with
+.Fl r .
.It Fl r Ar socket
Issue filename rewrite requests to the specified UNIX domain socket.
.Nm
@@ -126,6 +132,8 @@ before the TFTP request will continue.
By default
.Nm
does not use filename rewriting.
+This option can not be combined with
+.Fl i .
.It Fl v
Log the client IP, type of request, and filename.
.It Ar directory
Index: tftpd.c
===================================================================
RCS file: /mount/openbsd/cvs/src/usr.sbin/tftpd/tftpd.c,v
retrieving revision 1.39
diff -u -p -r1.39 tftpd.c
--- tftpd.c 26 May 2017 17:38:46 -0000 1.39
+++ tftpd.c 18 Oct 2017 19:59:40 -0000
@@ -282,14 +282,15 @@ __dead void
usage(void)
{
extern char *__progname;
- fprintf(stderr, "usage: %s [-46cdv] [-l address] [-p port] [-r socket]"
- " directory\n", __progname);
+ fprintf(stderr, "usage: %s [-46cdv] [-l address] [-p port]"
+ " [-i | -r socket] directory\n", __progname);
exit(1);
}
int cancreate = 0;
int verbose = 0;
int debug = 0;
+int iflag = 0;
int
main(int argc, char *argv[])
@@ -307,7 +308,7 @@ main(int argc, char *argv[])
int family = AF_UNSPEC;
int devnull = -1;
- while ((c = getopt(argc, argv, "46cdl:p:r:v")) != -1) {
+ while ((c = getopt(argc, argv, "46cdil:p:r:v")) != -1) {
switch (c) {
case '4':
family = AF_INET;
@@ -321,6 +322,11 @@ main(int argc, char *argv[])
case 'd':
verbose = debug = 1;
break;
+ case 'i':
+ if (rewrite != NULL)
+ usage();
+ iflag = 1;
+ break;
case 'l':
addr = optarg;
break;
@@ -328,6 +334,8 @@ main(int argc, char *argv[])
port = optarg;
break;
case 'r':
+ if (iflag)
+ usage();
rewrite = optarg;
break;
case 'v':
@@ -903,7 +911,13 @@ again:
if (rwmap != NULL)
rewrite_map(client, filename);
- else
+ else if (iflag) {
+ char nfilename[PATH_MAX];
+
+ snprintf(nfilename, sizeof nfilename, "%s/%s",
+ getip(&client->ss), filename);
+ tftp_open(client, nfilename);
+ } else
tftp_open(client, filename);
return;