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;

Reply via email to