Add documentation for matching options; more verbose logging.

This commit is contained in:
hpa 2001-07-10 21:48:08 +00:00
parent baf8364f1a
commit acf458d957
2 changed files with 112 additions and 8 deletions

View file

@ -44,7 +44,9 @@
IPv4 Trivial File Transfer Protocol server IPv4 Trivial File Transfer Protocol server
.Sh SYNOPSIS .Sh SYNOPSIS
.Nm in.tftpd .Nm in.tftpd
.Op Fl v
.Op Fl c .Op Fl c
.Op Fl m Ar mapfile
.Op Fl u Ar userid .Op Fl u Ar userid
.Op Fl r Ar option... .Op Fl r Ar option...
.Op Fl s .Op Fl s
@ -118,6 +120,16 @@ flag can be used to specify a user ID which
.Nm .Nm
will run as; the default is ``nobody''. will run as; the default is ``nobody''.
.Pp .Pp
The
.Fl m
flag specifies a file which contains filename remapping rules.
.Pp
The
.Fl v
flag increases the logging verbosity of
.Nm tftpd ,
it can be specified multiple times.
.Pp
This version of This version of
.Nm .Nm
supports RFC 2347 option negotiation; the current version supports the supports RFC 2347 option negotiation; the current version supports the
@ -130,8 +142,73 @@ supports RFC 2347 option negotiation; the current version supports the
.Fl r .Fl r
flag can be used to disable options individually; this may allow flag can be used to disable options individually; this may allow
working around client bugs. working around client bugs.
.Sh FILENAME REMAPPING
The
.Fl m
option specifies a file which contains filename remapping rules. Each
non-comment line (comments begin with hash marks, #) contains an
.Ar operation ,
a
.Ar regex ,
a regular expression in the style of
.Xr egrep 1 ,
and optionally a
.Ar "replacement pattern" .
The operation indicated by
.Ar operation
is performed if the
.Ar regex
matches all or part of the filename. Rules are processed from the top
down, and by default, all rules are processed even if there is a
match.
.Pp
The
.Ar operation
can be any combination of the following letters:
.Pp
.Bl -tag -width verbose -compact
.It Ic r
Replace the substring matched by
.Ar regex
by the
.Ar "replacement pattern" .
The escape sequence
\\0
can be used to copy the entire matched string, and the sequences
\\1 to \\9
copies parenthesized subexpressions. To specify a backslash, white
space or hash mark, you need to \\-escape it.
.Pp
.It Ic g
Repeat this rule until it no longer matches. This is always used with
.Ic r .
.Pp
.It Ic i
Match the
.Ar regex
case-insensitively. By default it is case sensitive.
.Pp
.It Ic e
If this rule matches, end rule processing after executing the rule.
.Pp
.It Ic s
If this rule matches, start rule processing over from the very first
rule after executing this rule.
.Pp
.It Ic a
If this rule matches, refuse the request and send an access denied
error to the client.
.Pp
.It Ic G
This rule applies to GET (RRQ) requests only.
.Pp
.It Ic P
This rule applies to PUT (WRQ) requests only.
.El
.Sh SEE ALSO .Sh SEE ALSO
.Xr tftp 1 , .Xr tftp 1 ,
.Xr egrep 1 ,
.Xr regex 7 ,
.Xr inetd 8 .Xr inetd 8
.Sh HISTORY .Sh HISTORY
The The
@ -153,5 +230,9 @@ flag and RFC 2347 options were added by H. Peter Anvin based on
patches by Markus Gutschke and Gero Kulhman. patches by Markus Gutschke and Gero Kulhman.
.Pp .Pp
The The
.Fl u .Fl u ,
flag was added by H. Peter Anvin. .Fl v
and
.Fl m
flags were added by H. Peter Anvin.

View file

@ -85,6 +85,8 @@ static const char *rcsid = "tftp-hpa $Id$";
int deny_severity = LOG_WARNING; int deny_severity = LOG_WARNING;
int allow_severity = -1; /* Don't log at all */ int allow_severity = -1; /* Don't log at all */
int verbosity = 0;
struct request_info wrap_request; struct request_info wrap_request;
#endif #endif
@ -157,7 +159,7 @@ struct options {
static void static void
usage(void) usage(void)
{ {
syslog(LOG_ERR, "Usage: %s [-c] [-m mappings] [-u user] [-t timeout] [-r option...] [-s] [directory ...]", syslog(LOG_ERR, "Usage: %s [-vc][-m mappings][-u user][-t timeout][-r option...] [-s] [directory ...]",
__progname); __progname);
exit(1); exit(1);
} }
@ -182,7 +184,7 @@ main(int argc, char **argv)
openlog(__progname, LOG_PID | LOG_NDELAY, LOG_DAEMON); openlog(__progname, LOG_PID | LOG_NDELAY, LOG_DAEMON);
while ((c = getopt(argc, argv, "csu:r:t:m:")) != -1) while ((c = getopt(argc, argv, "csvu:r:t:m:")) != -1)
switch (c) { switch (c) {
case 'c': case 'c':
cancreate = 1; cancreate = 1;
@ -226,9 +228,12 @@ main(int argc, char **argv)
} }
break; break;
#endif #endif
case 'v':
verbosity++;
break;
default: default:
usage(); usage();
break; break;
} }
for (; optind != argc; optind++) { for (; optind != argc; optind++) {
@ -415,6 +420,7 @@ tftp(struct tftphdr *tp, int size)
char *cp; char *cp;
int argn, ecode; int argn, ecode;
struct formats *pf = NULL; struct formats *pf = NULL;
char *origfilename;
char *filename, *mode = NULL; char *filename, *mode = NULL;
char *val = NULL, *opt = NULL; char *val = NULL, *opt = NULL;
@ -422,7 +428,7 @@ tftp(struct tftphdr *tp, int size)
((struct tftphdr *)ackbuf)->th_opcode = ntohs(OACK); ((struct tftphdr *)ackbuf)->th_opcode = ntohs(OACK);
filename = cp = tp->th_stuff; origfilename = cp = tp->th_stuff;
argn = 0; argn = 0;
while ( cp < buf + size && *cp ) { while ( cp < buf + size && *cp ) {
@ -449,7 +455,7 @@ tftp(struct tftphdr *tp, int size)
nak(EBADOP); nak(EBADOP);
exit(0); exit(0);
} }
if ( !(filename = (*pf->f_rewrite)(filename, tp->th_opcode)) ) { if ( !(filename = (*pf->f_rewrite)(origfilename, tp->th_opcode)) ) {
nak(EACCES); /* File denied by mapping rule */ nak(EACCES); /* File denied by mapping rule */
exit(0); exit(0);
} }
@ -472,6 +478,17 @@ tftp(struct tftphdr *tp, int size)
exit(0); exit(0);
} }
if ( verbosity >= 1 ) {
if ( filename == origfilename || !strcmp(filename, origfilename) )
syslog(LOG_NOTICE, "%s from %s filename %s\n",
opcode[tp->th_opcode] == WRQ ? "WRQ" : "RRQ",
inet_ntoa(from.sin_addr), filename);
else
syslog(LOG_NOTICE, "%s from %s filename %s remapped to %s\n",
opcode[tp->th_opcode] == WRQ ? "WRQ" : "RRQ",
inet_ntoa(from.sin_addr), origfilename, filename);
}
if ( ap != (ackbuf+2) ) { if ( ap != (ackbuf+2) ) {
if ( tp->th_opcode == WRQ ) if ( tp->th_opcode == WRQ )
(*pf->f_recv)(pf, ackbuf, ap-ackbuf); (*pf->f_recv)(pf, ackbuf, ap-ackbuf);
@ -966,6 +983,12 @@ nak(int error)
length = strlen(pe->e_msg); length = strlen(pe->e_msg);
tp->th_msg[length] = '\0'; tp->th_msg[length] = '\0';
length += 5; length += 5;
if ( verbosity >= 2 ) {
syslog(LOG_INFO, "sending NAK (%d, %s) to %s",
error, tp->th_msg, inet_ntoa(from.sin_addr));
}
if (send(peer, buf, length, 0) != length) if (send(peer, buf, length, 0) != length)
syslog(LOG_ERR, "nak: %m"); syslog(LOG_ERR, "nak: %m");
} }