summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Downs <downsj@cvs.openbsd.org>1997-06-11 21:19:48 +0000
committerJason Downs <downsj@cvs.openbsd.org>1997-06-11 21:19:48 +0000
commitc4ea7a6273fe1a166ef86f0add1fe2256637b103 (patch)
treecbcff9ffbbcb0d9db197155143756473f22b5423
parentbf43c0c082cf7240e06c2a1cfac0231c6ba35c66 (diff)
Implement and document the -c flag.
-rw-r--r--libexec/tftpd/tftpd.827
-rw-r--r--libexec/tftpd/tftpd.c61
2 files changed, 67 insertions, 21 deletions
diff --git a/libexec/tftpd/tftpd.8 b/libexec/tftpd/tftpd.8
index 052872cde0f..7f9cb7d604d 100644
--- a/libexec/tftpd/tftpd.8
+++ b/libexec/tftpd/tftpd.8
@@ -1,4 +1,5 @@
-.\" $OpenBSD: tftpd.8,v 1.2 1996/10/08 01:20:21 michaels Exp $
+.\" $OpenBSD: tftpd.8,v 1.3 1997/06/11 21:19:46 downsj Exp $
+.\"
.\" Copyright (c) 1983, 1991 The Regents of the University of California.
.\" All rights reserved.
.\"
@@ -31,11 +32,11 @@
.\" SUCH DAMAGE.
.\"
.\" from: @(#)tftpd.8 6.7 (Berkeley) 5/13/91
-.\" $Id: tftpd.8,v 1.2 1996/10/08 01:20:21 michaels Exp $
+.\" $OpenBSD: tftpd.8,v 1.3 1997/06/11 21:19:46 downsj Exp $
.\"
-.Dd May 13, 1991
+.Dd June 11, 1997
.Dt TFTPD 8
-.Os BSD 4.2
+.Os
.Sh NAME
.Nm tftpd
.Nd
@@ -45,7 +46,7 @@ Trivial File Transfer Protocol server
.Nm tftpd
.Op Ar directory ...
.Nm tftpd
-.Fl s
+.Fl cs
.Op Ar directory
.Sh DESCRIPTION
.Nm Tftpd
@@ -88,9 +89,19 @@ as server program arguments in
In this case access is restricted to files whose
names are prefixed by the one of the given directories.
.Pp
+If the
+.Fl c
+flag is used,
+.Nm tftpd
+will allow new files to be created; otherwise uploaded files most already
+exist. Files are created with default permissions allowing anyone to read
+or write to them.
+.Pp
When using the
.Fl s
-flag with a directory name, tftpd will
+flag with a directory name,
+.Nm tftpd
+will
.Xr chroot 2
on startup; therefore the remote host is not expected to pass the directory
as part of the file name to transfer. This option is intended primarily for
@@ -107,3 +118,7 @@ command appeared in
The
.Fl s
flag appeared in NetBSD 0.9a.
+.Pp
+The
+.Fl c
+flag was added in OpenBSD 2.1.
diff --git a/libexec/tftpd/tftpd.c b/libexec/tftpd/tftpd.c
index a46938f6eb4..b0fbb78f621 100644
--- a/libexec/tftpd/tftpd.c
+++ b/libexec/tftpd/tftpd.c
@@ -1,3 +1,5 @@
+/* $OpenBSD: tftpd.c,v 1.7 1997/06/11 21:19:47 downsj Exp $ */
+
/*
* Copyright (c) 1983 Regents of the University of California.
* All rights reserved.
@@ -39,7 +41,7 @@ char copyright[] =
#ifndef lint
/*static char sccsid[] = "from: @(#)tftpd.c 5.13 (Berkeley) 2/26/91";*/
-static char rcsid[] = "$Id: tftpd.c,v 1.6 1997/02/16 23:49:21 deraadt Exp $";
+static char rcsid[] = "$OpenBSD: tftpd.c,v 1.7 1997/06/11 21:19:47 downsj Exp $: tftpd.c,v 1.6 1997/02/16 23:49:21 deraadt Exp $";
#endif /* not lint */
/*
@@ -87,11 +89,12 @@ int fromlen;
char *dirs[MAXARG+1];
int secure = 0;
+int cancreate = 0;
static void
usage()
{
- syslog(LOG_ERR, "Usage: %s [-s] [directory ...]\n", __progname);
+ syslog(LOG_ERR, "Usage: %s [-cs] [directory ...]\n", __progname);
exit(1);
}
@@ -111,8 +114,11 @@ main(argc, argv)
openlog("tftpd", LOG_PID, LOG_DAEMON);
- while ((c = getopt(argc, argv, "s")) != -1)
+ while ((c = getopt(argc, argv, "cs")) != -1)
switch (c) {
+ case 'c':
+ cancreate = 1;
+ break;
case 's':
secure = 1;
break;
@@ -319,7 +325,7 @@ validate_access(filename, mode)
int mode;
{
struct stat stbuf;
- int fd;
+ int fd, wmode;
char *cp, **dirp;
if (!secure) {
@@ -338,22 +344,47 @@ validate_access(filename, mode)
if (*dirp==0 && dirp!=dirs)
return (EACCESS);
}
- if (stat(filename, &stbuf) < 0)
- return (errno == ENOENT ? ENOTFOUND : EACCESS);
- if (mode == RRQ) {
- if ((stbuf.st_mode&(S_IREAD >> 6)) == 0)
- return (EACCESS);
+
+ /*
+ * We use different a different permissions scheme if `cancreate' is
+ * set.
+ */
+ wmode = O_TRUNC;
+ if (stat(filename, &stbuf) < 0) {
+ if (!cancreate)
+ return (errno == ENOENT ? ENOTFOUND : EACCESS);
+ else {
+ if ((errno == ENOENT) && (mode != RRQ))
+ wmode = O_CREAT;
+ else
+ return(EACCESS);
+ }
} else {
- if ((stbuf.st_mode&(S_IWRITE >> 6)) == 0)
- return (EACCESS);
+ if (mode == RRQ) {
+ if ((stbuf.st_mode&(S_IREAD >> 6)) == 0)
+ return (EACCESS);
+ } else {
+ if ((stbuf.st_mode&(S_IWRITE >> 6)) == 0)
+ return (EACCESS);
+ }
}
- fd = open(filename, mode == RRQ ? O_RDONLY : (O_WRONLY|O_TRUNC));
+ fd = open(filename, mode == RRQ ? O_RDONLY : (O_WRONLY|wmode));
if (fd < 0)
return (errno + 100);
- file = fdopen(fd, (mode == RRQ)? "r":"w");
- if (file == NULL) {
- return errno+100;
+ /*
+ * If the file was created, set default permissions.
+ */
+ if ((wmode == O_CREAT) && fchmod(fd, 0666) < 0) {
+ int serrno = errno;
+
+ close(fd);
+ unlink(filename);
+
+ return (serrno + 100);
}
+ file = fdopen(fd, (mode == RRQ)? "r":"w");
+ if (file == NULL)
+ return (errno + 100);
return (0);
}