summaryrefslogtreecommitdiff
path: root/libexec
diff options
context:
space:
mode:
authorKris Kennaway <kris@FreeBSD.org>2001-03-04 09:15:27 +0000
committerKris Kennaway <kris@FreeBSD.org>2001-03-04 09:15:27 +0000
commitb9aa3374f8951ff843a58465dbf661fcd661cab5 (patch)
treeadfd6169248865efe13a0a5e9461a3c1794ab6b8 /libexec
parent69601f9bd007fa6b49c413e6438a78a63607a47f (diff)
downloadsrc-test2-b9aa3374f8951ff843a58465dbf661fcd661cab5.tar.gz
src-test2-b9aa3374f8951ff843a58465dbf661fcd661cab5.zip
Notes
Diffstat (limited to 'libexec')
-rw-r--r--libexec/tftpd/tftpd.834
-rw-r--r--libexec/tftpd/tftpd.c29
2 files changed, 57 insertions, 6 deletions
diff --git a/libexec/tftpd/tftpd.8 b/libexec/tftpd/tftpd.8
index f53229ddd3ef..1c7382aa742b 100644
--- a/libexec/tftpd/tftpd.8
+++ b/libexec/tftpd/tftpd.8
@@ -41,7 +41,7 @@
Internet Trivial File Transfer Protocol server
.Sh SYNOPSIS
.Nm /usr/libexec/tftpd
-.Op Fl ln
+.Op Fl cCln
.Op Fl s Ar directory
.Op Fl u Ar user
.Op Ar directory ...
@@ -114,6 +114,25 @@ option is specified.
.Pp
The options are:
.Bl -tag -width Ds
+.It Fl c
+Changes the default root directory of a connecting host via chroot based on the
+connecting IP address.
+This prevents multiple clients from writing to the same file at the same time.
+If the directory does not exist, the client connection is refused.
+The
+.Fl s
+option is required for
+.Fl c
+and the specified
+.Ar directory
+is used as a base.
+.It Fl C
+Operates the same as
+.Fl c
+except it falls back to
+.Fl s Ns No 's
+.Ar directory
+if a directory does not exist for the client's IP.
.It Fl l
Log all requests using
.Xr syslog 3
@@ -165,7 +184,16 @@ the
.Fl s
option was introduced in
.Fx 2.2 ,
-and the
+the
.Fl u
option was introduced in
-.Fx 4.2 .
+.Fx 4.2 ,
+and the
+.Fl c
+option was introduced in
+.Fx 4.3 .
+.Sh BUGS
+Files larger than 33488896 octets (65535 blocks) cannot be transferred
+without client and server supporting blocksize negotiation (RFC1783).
+.Pp
+Many tftp clients will not transfer files over 16744448 octets (32767 blocks).
diff --git a/libexec/tftpd/tftpd.c b/libexec/tftpd/tftpd.c
index 56c6c028b19c..f219f081bf42 100644
--- a/libexec/tftpd/tftpd.c
+++ b/libexec/tftpd/tftpd.c
@@ -106,6 +106,7 @@ static struct dirlist {
} dirs[MAXDIRS+1];
static int suppress_naks;
static int logging;
+static int ipchroot;
static char *errtomsg __P((int));
static void nak __P((int));
@@ -124,8 +125,14 @@ main(argc, argv)
char *chuser = "nobody";
openlog("tftpd", LOG_PID | LOG_NDELAY, LOG_FTP);
- while ((ch = getopt(argc, argv, "lns:u:")) != -1) {
+ while ((ch = getopt(argc, argv, "cClns:u:")) != -1) {
switch (ch) {
+ case 'c':
+ ipchroot = 1;
+ break;
+ case 'C':
+ ipchroot = 2;
+ break;
case 'l':
logging = 1;
break;
@@ -159,6 +166,10 @@ main(argc, argv)
dirs->name = "/";
dirs->len = 1;
}
+ if (ipchroot && chroot_dir == NULL) {
+ syslog(LOG_ERR, "-c requires -s");
+ exit(1);
+ }
on = 1;
if (ioctl(0, FIONBIO, &on) < 0) {
@@ -229,6 +240,18 @@ main(argc, argv)
* be a problem. See the above comment about system clogging.
*/
if (chroot_dir) {
+ if (ipchroot) {
+ char *tempchroot;
+ struct stat sb;
+ int statret;
+
+ tempchroot = inet_ntoa(from.sin_addr);
+ asprintf(&tempchroot, "%s/%s", chroot_dir, tempchroot);
+ statret = stat(tempchroot, &sb);
+ if ((sb.st_mode & S_IFDIR) &&
+ (statret == 0 || (statret == -1 && ipchroot == 1)))
+ chroot_dir = tempchroot;
+ }
/* Must get this before chroot because /etc might go away */
if ((nobody = getpwnam(chuser)) == NULL) {
syslog(LOG_ERR, "%s: no such user", chuser);
@@ -478,7 +501,7 @@ xmitfile(pf)
struct tftphdr *dp, *r_init();
register struct tftphdr *ap; /* ack packet */
register int size, n;
- volatile int block;
+ volatile unsigned short block;
signal(SIGALRM, timer);
dp = r_init();
@@ -548,7 +571,7 @@ recvfile(pf)
struct tftphdr *dp, *w_init();
register struct tftphdr *ap; /* ack buffer */
register int n, size;
- volatile int block;
+ volatile unsigned short block;
signal(SIGALRM, timer);
dp = w_init();