From acf458d957e73aaf32a0571513563743695d64d1 Mon Sep 17 00:00:00 2001 From: hpa Date: Tue, 10 Jul 2001 21:48:08 +0000 Subject: [PATCH] Add documentation for matching options; more verbose logging. --- tftpd/tftpd.8 | 85 +++++++++++++++++++++++++++++++++++++++++++++++++-- tftpd/tftpd.c | 35 +++++++++++++++++---- 2 files changed, 112 insertions(+), 8 deletions(-) diff --git a/tftpd/tftpd.8 b/tftpd/tftpd.8 index 086c760..491e94e 100644 --- a/tftpd/tftpd.8 +++ b/tftpd/tftpd.8 @@ -44,7 +44,9 @@ IPv4 Trivial File Transfer Protocol server .Sh SYNOPSIS .Nm in.tftpd +.Op Fl v .Op Fl c +.Op Fl m Ar mapfile .Op Fl u Ar userid .Op Fl r Ar option... .Op Fl s @@ -118,6 +120,16 @@ flag can be used to specify a user ID which .Nm will run as; the default is ``nobody''. .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 .Nm 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 flag can be used to disable options individually; this may allow 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 .Xr tftp 1 , +.Xr egrep 1 , +.Xr regex 7 , .Xr inetd 8 .Sh HISTORY 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. .Pp The -.Fl u -flag was added by H. Peter Anvin. +.Fl u , +.Fl v +and +.Fl m +flags were added by H. Peter Anvin. + diff --git a/tftpd/tftpd.c b/tftpd/tftpd.c index a2be3f9..e4d40e9 100644 --- a/tftpd/tftpd.c +++ b/tftpd/tftpd.c @@ -85,6 +85,8 @@ static const char *rcsid = "tftp-hpa $Id$"; int deny_severity = LOG_WARNING; int allow_severity = -1; /* Don't log at all */ +int verbosity = 0; + struct request_info wrap_request; #endif @@ -157,7 +159,7 @@ struct options { static 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); exit(1); } @@ -182,7 +184,7 @@ main(int argc, char **argv) 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) { case 'c': cancreate = 1; @@ -226,9 +228,12 @@ main(int argc, char **argv) } break; #endif + case 'v': + verbosity++; + break; default: - usage(); - break; + usage(); + break; } for (; optind != argc; optind++) { @@ -415,6 +420,7 @@ tftp(struct tftphdr *tp, int size) char *cp; int argn, ecode; struct formats *pf = NULL; + char *origfilename; char *filename, *mode = NULL; char *val = NULL, *opt = NULL; @@ -422,7 +428,7 @@ tftp(struct tftphdr *tp, int size) ((struct tftphdr *)ackbuf)->th_opcode = ntohs(OACK); - filename = cp = tp->th_stuff; + origfilename = cp = tp->th_stuff; argn = 0; while ( cp < buf + size && *cp ) { @@ -449,7 +455,7 @@ tftp(struct tftphdr *tp, int size) nak(EBADOP); 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 */ exit(0); } @@ -472,6 +478,17 @@ tftp(struct tftphdr *tp, int size) 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 ( tp->th_opcode == WRQ ) (*pf->f_recv)(pf, ackbuf, ap-ackbuf); @@ -966,6 +983,12 @@ nak(int error) length = strlen(pe->e_msg); tp->th_msg[length] = '\0'; 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) syslog(LOG_ERR, "nak: %m"); }