Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src tftpd(8): Add -w so files can be uploaded without requiring ...



details:   https://anonhg.NetBSD.org/src/rev/28535238d4e7
branches:  trunk
changeset: 754365:28535238d4e7
user:      hubertf <hubertf%NetBSD.org@localhost>
date:      Wed Apr 28 22:21:51 2010 +0000

description:
tftpd(8): Add -w so files can be uploaded without requiring them
        to be created before the upload. See the section on security
        considerations before enabling. [hubertf 20100429]

Addresses PR bin/43164.

diffstat:

 doc/CHANGES           |   5 +++-
 libexec/tftpd/tftpd.8 |  19 +++++++++++++++--
 libexec/tftpd/tftpd.c |  52 +++++++++++++++++++++++++++++++++++++++++---------
 3 files changed, 62 insertions(+), 14 deletions(-)

diffs (191 lines):

diff -r 4503f671a4ce -r 28535238d4e7 doc/CHANGES
--- a/doc/CHANGES       Wed Apr 28 22:08:58 2010 +0000
+++ b/doc/CHANGES       Wed Apr 28 22:21:51 2010 +0000
@@ -1,4 +1,4 @@
-# LIST OF CHANGES FROM LAST RELEASE:                   <$Revision: 1.1383 $>
+# LIST OF CHANGES FROM LAST RELEASE:                   <$Revision: 1.1384 $>
 #
 #
 # [Note: This file does not mention every change made to the NetBSD source tree.
@@ -599,3 +599,6 @@
                The database cache for services(5) has been updated to use
                this. services_mkdb(8) can still be used to create the old
                format. [joerg 20100425]
+       tftpd(8): Add -w so files can be uploaded without requiring them
+               to be created before the upload. See the section on security 
+               considerations before enabling. [hubertf 20100429]
diff -r 4503f671a4ce -r 28535238d4e7 libexec/tftpd/tftpd.8
--- a/libexec/tftpd/tftpd.8     Wed Apr 28 22:08:58 2010 +0000
+++ b/libexec/tftpd/tftpd.8     Wed Apr 28 22:21:51 2010 +0000
@@ -1,4 +1,4 @@
-.\"    $NetBSD: tftpd.8,v 1.24 2010/01/08 23:27:08 wiz Exp $
+.\"    $NetBSD: tftpd.8,v 1.25 2010/04/28 22:21:51 hubertf Exp $
 .\"
 .\" Copyright (c) 1983, 1991, 1993
 .\"    The Regents of the University of California.  All rights reserved.
@@ -29,7 +29,7 @@
 .\"
 .\"    from: @(#)tftpd.8       8.1 (Berkeley) 6/4/93
 .\"
-.Dd January 8, 2010
+.Dd April 22, 2010
 .Dt TFTPD 8
 .Os
 .Sh NAME
@@ -44,6 +44,7 @@
 .Op Fl p Ar pathsep
 .Op Fl s Ar directory
 .Op Fl u Ar user
+.Op Fl w
 .Op Ar directory ...
 .Sh DESCRIPTION
 .Nm
@@ -70,7 +71,10 @@
 or containing
 .Dq Pa /../
 are not allowed.
-Files may be written to only if they already exist and are publicly writable.
+Unless option
+.Fl w
+is used,
+files may be written to only if they already exist and are publicly writable.
 .Pp
 Note that this extends the concept of
 .Qq public
@@ -148,6 +152,9 @@
 isn't also given, change the gid to that of
 .Ar user
 as well.
+.It Fl w
+Allow unrestricted writing of new files, with no need for
+a prior existance.
 .El
 .Sh SEE ALSO
 .Xr tftp 1 ,
@@ -232,3 +239,9 @@
 sort of file-access restrictions in place.
 The exact methods are specific to each site and therefore
 difficult to document here.
+.Pp
+If unrestricted file upload is enabled via the
+.Fl w
+option, care should be taken that this can be used
+to fill up disk space in an uncontrolled manner
+if this is used in an insecure environment.
diff -r 4503f671a4ce -r 28535238d4e7 libexec/tftpd/tftpd.c
--- a/libexec/tftpd/tftpd.c     Wed Apr 28 22:08:58 2010 +0000
+++ b/libexec/tftpd/tftpd.c     Wed Apr 28 22:21:51 2010 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: tftpd.c,v 1.36 2010/01/09 10:46:31 mbalmer Exp $       */
+/*     $NetBSD: tftpd.c,v 1.37 2010/04/28 22:21:51 hubertf Exp $       */
 
 /*
  * Copyright (c) 1983, 1993
@@ -36,7 +36,7 @@
 #if 0
 static char sccsid[] = "@(#)tftpd.c    8.1 (Berkeley) 6/4/93";
 #else
-__RCSID("$NetBSD: tftpd.c,v 1.36 2010/01/09 10:46:31 mbalmer Exp $");
+__RCSID("$NetBSD: tftpd.c,v 1.37 2010/04/28 22:21:51 hubertf Exp $");
 #endif
 #endif /* not lint */
 
@@ -109,6 +109,7 @@
 static int     secure;
 static char    pathsep = '\0';
 static char    *securedir;
+static int     unrestricted_writes;    /* uploaded files don't have to exist */
 
 struct formats;
 
@@ -171,7 +172,7 @@
        curuid = getuid();
        curgid = getgid();
 
-       while ((ch = getopt(argc, argv, "dg:lnp:s:u:w:")) != -1)
+       while ((ch = getopt(argc, argv, "dg:lnp:s:u:w")) != -1)
                switch (ch) {
                case 'd':
                        debug++;
@@ -204,6 +205,10 @@
                        tgtuser = optarg;
                        break;
 
+               case 'w':
+                       unrestricted_writes = 1;
+                       break;
+
                default:
                        usage();
                        break;
@@ -739,6 +744,8 @@
        static char      pathname[MAXPATHLEN];
        char            *filename;
        int              fd;
+       int              create = 0;
+       int              trunc = 0;
 
        filename = *filep;
 
@@ -804,21 +811,45 @@
                                return (EACCESS);
                        *filep = filename = pathname;
                } else {
+                       int stat_rc;
+
                        /*
                         * If there's no directory list, take our cue from the
                         * absolute file request check above (*filename == '/'),
                         * and allow access to anything.
                         */
-                       if (stat(filename, &stbuf) < 0)
-                               return (errno == ENOENT ? ENOTFOUND : EACCESS);
-                       if (!S_ISREG(stbuf.st_mode))
-                               return (ENOTFOUND);
+                       stat_rc = stat(filename, &stbuf);
                        if (mode == RRQ) {
+                               /* Read request */
+                               if (stat_rc < 0)
+                                      return (errno == ENOENT ? ENOTFOUND : EACCESS);
+                               if (!S_ISREG(stbuf.st_mode))
+                                      return (ENOTFOUND);
                                if ((stbuf.st_mode & S_IROTH) == 0)
                                        return (EACCESS);
                        } else {
-                               if ((stbuf.st_mode & S_IWOTH) == 0)
-                                       return (EACCESS);
+                               if (stat_rc < 0) {
+                                      /* Can't stat */
+                                      if (errno == EACCES) {
+                                              /* Permission denied */
+                                              return EACCESS;
+                                      } else {
+                                              /* Not there */
+                                              if (unrestricted_writes) {
+                                                      /* need to creat new file! */
+                                                      create = O_CREAT;
+                                              } else {
+                                                      /* Permission denied */
+                                                      return EACCESS;
+                                              }
+                                      }
+                               } else {
+                                      /* Can stat */
+                                      if ((stbuf.st_mode & S_IWOTH) == 0) {
+                                              return (EACCESS);
+                                      }
+                                      trunc = O_TRUNC;
+                               }
                        }
                        *filep = filename;
                }
@@ -827,7 +858,8 @@
        if (tftp_opt_tsize && mode == RRQ)
                tftp_tsize = (unsigned long) stbuf.st_size;
 
-       fd = open(filename, mode == RRQ ? O_RDONLY : O_WRONLY | O_TRUNC);
+       fd = open(filename, mode == RRQ ? O_RDONLY : O_WRONLY | trunc | create,
+                       0644); /* debatable */
        if (fd < 0)
                return (errno + 100);
        file = fdopen(fd, (mode == RRQ)? "r":"w");



Home | Main Index | Thread Index | Old Index