Add -s flag, per Roland McGrath, with changes and a manual page addition by me.
This commit is contained in:
parent
324dc53797
commit
45fe1558b2
@ -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.
|
||||
|
@ -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) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user