SCCS-vsn: libexec/tftpd/tftpd.c 5.9
SCCS-vsn: libexec/tftpd/tftpd.8 6.4
.\" IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
.\" WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
.\"
.\" IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
.\" WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
.\"
-.\" @(#)tftpd.8 6.3 (Berkeley) %G%
+.\" @(#)tftpd.8 6.4 (Berkeley) %G%
tftpd \- DARPA Trivial File Transfer Protocol server
.SH SYNOPSIS
.B /etc/tftpd
tftpd \- DARPA Trivial File Transfer Protocol server
.SH SYNOPSIS
.B /etc/tftpd
.SH DESCRIPTION
.I Tftpd
is a server which supports the DARPA Trivial File Transfer
.SH DESCRIPTION
.I Tftpd
is a server which supports the DARPA Trivial File Transfer
this may not be appropriate on all systems, and its implications
should be considered before enabling tftp service.
The server should have the user ID with the lowest possible privilege.
this may not be appropriate on all systems, and its implications
should be considered before enabling tftp service.
The server should have the user ID with the lowest possible privilege.
+.PP
+Access to files may be restricted by invoking
+.I tftpd
+with a list of directories by including pathnames
+as server program arguments in
+.IR /etc/inetd.conf .
+In this case access is restricted to files whose
+names are prefixed by the one of the given directories.
.SH "SEE ALSO"
tftp(1), inetd(8)
.SH "SEE ALSO"
tftp(1), inetd(8)
#endif /* not lint */
#ifndef lint
#endif /* not lint */
#ifndef lint
-static char sccsid[] = "@(#)tftpd.c 5.8 (Berkeley) %G%";
+static char sccsid[] = "@(#)tftpd.c 5.9 (Berkeley) %G%";
struct sockaddr_in from;
int fromlen;
struct sockaddr_in from;
int fromlen;
+#define MAXARG 4
+char *dirs[MAXARG+1];
+
+main(ac, av)
+ char **av;
{
register struct tftphdr *tp;
{
register struct tftphdr *tp;
+ ac--; av++;
+ while (ac-- > 0 && n < MAXARG)
+ dirs[n++] = *av++;
openlog("tftpd", LOG_PID, LOG_DAEMON);
if (ioctl(0, FIONBIO, &on) < 0) {
syslog(LOG_ERR, "ioctl(FIONBIO): %m\n");
openlog("tftpd", LOG_PID, LOG_DAEMON);
if (ioctl(0, FIONBIO, &on) < 0) {
syslog(LOG_ERR, "ioctl(FIONBIO): %m\n");
* have no uid or gid, for now require
* file to exist and be publicly
* readable/writable.
* have no uid or gid, for now require
* file to exist and be publicly
* readable/writable.
+ * If we were invoked with arguments
+ * from inetd then the file must also be
+ * in one of the given directory prefixes.
* Note also, full path name must be
* given as we have no login directory.
*/
* Note also, full path name must be
* given as we have no login directory.
*/
{
struct stat stbuf;
int fd;
{
struct stat stbuf;
int fd;
if (*filename != '/')
return (EACCESS);
if (*filename != '/')
return (EACCESS);
+ for (; *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) {
if (stat(filename, &stbuf) < 0)
return (errno == ENOENT ? ENOTFOUND : EACCESS);
if (mode == RRQ) {