Add -s flag, per Roland McGrath, with changes and a manual page addition by me.

This commit is contained in:
mycroft 1994-01-10 16:29:46 +00:00
parent 324dc53797
commit 45fe1558b2
2 changed files with 56 additions and 17 deletions

View File

@ -30,7 +30,7 @@
.\" SUCH DAMAGE.
.\"
.\" from: @(#)tftpd.8 6.7 (Berkeley) 5/13/91
.\" $Id: tftpd.8,v 1.2 1993/08/01 07:39:46 mycroft Exp $
.\" $Id: tftpd.8,v 1.3 1994/01/10 16:29:46 mycroft Exp $
.\"
.Dd May 13, 1991
.Dt TFTPD 8
@ -43,6 +43,9 @@ Trivial File Transfer Protocol server
.Sh SYNOPSIS
.Nm tftpd
.Op Ar directory ...
.Nm tftpd
.Fl s
.Op Ar directory
.Sh DESCRIPTION
.Nm Tftpd
is a server which supports the
@ -83,6 +86,14 @@ as server program arguments in
.Pa /etc/inetd.conf .
In this case access is restricted to files whose
names are prefixed by the one of the given directories.
.Pp
When using the
.Fl s
flag with a directory name, 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
compatibility with SunOS boot ROMs which do not include a directory name.
.Sh SEE ALSO
.Xr tftp 1 ,
.Xr inetd 8
@ -91,3 +102,7 @@ The
.Nm
command appeared in
.Bx 4.2 .
.Pp
The
.Fl s
flag appeared in NetBSD 0.9a.

View File

@ -39,7 +39,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.3 1993/08/01 18:28:53 mycroft Exp $";
static char rcsid[] = "$Id: tftpd.c,v 1.4 1994/01/10 16:29:48 mycroft Exp $";
#endif /* not lint */
/*
@ -84,6 +84,8 @@ int fromlen;
#define MAXARG 4
char *dirs[MAXARG+1];
int secure = 0;
main(ac, av)
char **av;
{
@ -92,9 +94,28 @@ main(ac, av)
int on = 1;
ac--; av++;
while (ac-- > 0 && n < MAXARG)
dirs[n++] = *av++;
if (!strcmp(*av, "-s")) {
ac--; av++;
secure = 1;
}
openlog("tftpd", LOG_PID, LOG_DAEMON);
while (ac-- > 0) {
if (!secure) {
if (n >= MAXARG) {
syslog(LOG_ERR, "too many directories\n");
exit(1);
} else
dirs[n++] = *av;
}
if (chdir(*av++)) {
syslog(LOG_ERR, "%s: %m\n", av[-1]);
exit(1);
}
}
if (secure && chroot(".")) {
syslog(LOG_ERR, "chroot: %m\n");
exit(1);
}
if (ioctl(0, FIONBIO, &on) < 0) {
syslog(LOG_ERR, "ioctl(FIONBIO): %m\n");
exit(1);
@ -270,19 +291,22 @@ validate_access(filename, mode)
int fd;
char *cp, **dirp;
if (*filename != '/')
return (EACCESS);
/*
* prevent tricksters from getting around the directory restrictions
*/
for (cp = filename + 1; *cp; cp++)
if(*cp == '.' && strncmp(cp-1, "/../", 4) == 0)
return(EACCESS);
for (dirp = dirs; *dirp; dirp++)
if (strncmp(filename, *dirp, strlen(*dirp)) == 0)
break;
if (*dirp==0 && dirp!=dirs)
return (EACCESS);
if (!secure) {
if (*filename != '/')
return (EACCESS);
/*
* prevent tricksters from getting around the directory
* restrictions
*/
for (cp = filename + 1; *cp; cp++)
if(*cp == '.' && strncmp(cp-1, "/../", 4) == 0)
return(EACCESS);
for (dirp = dirs; *dirp; dirp++)
if (strncmp(filename, *dirp, strlen(*dirp)) == 0)
break;
if (*dirp==0 && dirp!=dirs)
return (EACCESS);
}
if (stat(filename, &stbuf) < 0)
return (errno == ENOENT ? ENOTFOUND : EACCESS);
if (mode == RRQ) {