remap: *actually* build, and fix masked logic errors
[tftp-hpa.git] / tftpd / tftpd.c
blobe0041dc65926f13525f9adfad3f474d2e79bb7aa
1 /*
2 * Copyright (c) 1983 Regents of the University of California.
3 * Copyright (c) 1999-2009 H. Peter Anvin
4 * Copyright (c) 2011-2014 Intel Corporation; author: H. Peter Anvin
5 * All rights reserved.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. All advertising materials mentioning features or use of this software
16 * must display the following acknowledgement:
17 * This product includes software developed by the University of
18 * California, Berkeley and its contributors.
19 * 4. Neither the name of the University nor the names of its contributors
20 * may be used to endorse or promote products derived from this software
21 * without specific prior written permission.
23 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 * SUCH DAMAGE.
36 #include "config.h" /* Must be included first */
37 #include "tftpd.h"
40 * Trivial file transfer protocol server.
42 * This version includes many modifications by Jim Guyton <guyton@rand-unix>
45 #include <sys/ioctl.h>
46 #include <signal.h>
47 #include <ctype.h>
48 #include <pwd.h>
49 #include <limits.h>
50 #include <syslog.h>
52 #include "common/tftpsubs.h"
53 #include "recvfrom.h"
54 #include "remap.h"
56 #ifdef HAVE_SYS_FILIO_H
57 #include <sys/filio.h> /* Necessary for FIONBIO on Solaris */
58 #endif
60 #ifdef HAVE_TCPWRAPPERS
61 #include <tcpd.h>
63 int deny_severity = LOG_WARNING;
64 int allow_severity = -1; /* Don't log at all */
66 static struct request_info wrap_request;
67 #endif
69 #ifdef HAVE_IPV6
70 static int ai_fam = AF_UNSPEC;
71 #else
72 static int ai_fam = AF_INET;
73 #endif
75 #define TIMEOUT 1000000 /* Default timeout (us) */
76 #define TRIES 6 /* Number of attempts to send each packet */
77 #define TIMEOUT_LIMIT ((1 << TRIES)-1)
79 const char *tftpd_progname;
80 static int peer;
81 static unsigned long timeout = TIMEOUT; /* Current timeout value */
82 static unsigned long rexmtval = TIMEOUT; /* Basic timeout value */
83 static unsigned long maxtimeout = TIMEOUT_LIMIT * TIMEOUT;
84 static int timeout_quit = 0;
85 static sigjmp_buf timeoutbuf;
86 static uint16_t rollover_val = 0;
88 #define PKTSIZE MAX_SEGSIZE+4
89 static char buf[PKTSIZE];
90 static char ackbuf[PKTSIZE];
91 static unsigned int max_blksize = MAX_SEGSIZE;
93 static char tmpbuf[INET6_ADDRSTRLEN], *tmp_p;
95 static union sock_addr from;
96 static off_t tsize;
97 static int tsize_ok;
99 static int ndirs;
100 static const char **dirs;
102 static int secure = 0;
103 int cancreate = 0;
104 int unixperms = 0;
105 int portrange = 0;
106 unsigned int portrange_from, portrange_to;
107 int verbosity = 0;
109 #ifdef WITH_REGEX
110 static struct rule *rewrite_rules = NULL;
111 #endif
113 static FILE *file;
115 int tftp(struct tftphdr *, int);
116 static void nak(int, const char *);
117 static void timer(int);
118 static void do_opt(const char *, const char *, char **);
120 static int set_blksize(uintmax_t *);
121 static int set_blksize2(uintmax_t *);
122 static int set_tsize(uintmax_t *);
123 static int set_timeout(uintmax_t *);
124 static int set_utimeout(uintmax_t *);
125 static int set_rollover(uintmax_t *);
127 struct options {
128 const char *o_opt;
129 int (*o_fnc)(uintmax_t *);
130 } options[] = {
131 {"blksize", set_blksize},
132 {"blksize2", set_blksize2},
133 {"tsize", set_tsize},
134 {"timeout", set_timeout},
135 {"utimeout", set_utimeout},
136 {"rollover", set_rollover},
137 {NULL, NULL}
140 /* Simple handler for SIGHUP */
141 static volatile sig_atomic_t caught_sighup = 0;
142 static void handle_sighup(int sig)
144 (void)sig; /* Suppress unused warning */
145 caught_sighup = 1;
148 /* Handle exit requests by SIGTERM and SIGINT */
149 static volatile sig_atomic_t exit_signal = 0;
150 static void handle_exit(int sig)
152 exit_signal = sig;
155 /* Handle timeout signal or timeout event */
156 static void timer(int sig)
158 (void)sig; /* Suppress unused warning */
159 timeout <<= 1;
160 if (timeout >= maxtimeout || timeout_quit)
161 exit(0);
162 siglongjmp(timeoutbuf, 1);
165 #ifdef WITH_REGEX
166 static struct rule *read_remap_rules(const char *rulefile)
168 FILE *f;
169 struct rule *rulep;
171 f = fopen(rulefile, "rt");
172 if (!f) {
173 syslog(LOG_ERR, "Cannot open map file: %s: %m", rulefile);
174 exit(EX_NOINPUT);
176 rulep = parserulefile(f);
177 fclose(f);
179 return rulep;
181 #endif
184 * Rules for locking files; return 0 on success, -1 on failure
186 static int lock_file(int fd, int lock_write)
188 (void)lock_write;
189 #if defined(HAVE_FCNTL) && HAVE_DECL_F_SETLK
190 struct flock fl;
192 fl.l_type = lock_write ? F_WRLCK : F_RDLCK;
193 fl.l_whence = SEEK_SET;
194 fl.l_start = 0;
195 fl.l_len = 0; /* Whole file */
196 return fcntl(fd, F_SETLK, &fl);
197 #elif defined(HAVE_FLOCK) && HAVE_DECL_LOCK_SH && HAVE_DECL_LOCK_EX
198 return flock(fd, lock_write ? LOCK_EX|LOCK_NB : LOCK_SH|LOCK_NB);
199 #else
200 return 0; /* Hope & pray... */
201 #endif
204 static void set_socket_nonblock(int fd, int flag)
206 int err;
207 int flags;
208 #if defined(HAVE_FCNTL) && defined(HAVE_O_NONBLOCK_DEFINITION)
209 /* Posixly correct */
210 err = ((flags = fcntl(fd, F_GETFL, 0)) < 0) ||
211 (fcntl
212 (fd, F_SETFL,
213 flag ? flags | O_NONBLOCK : flags & ~O_NONBLOCK) < 0);
214 #else
215 flags = flag ? 1 : 0;
216 err = (ioctl(fd, FIONBIO, &flags) < 0);
217 #endif
218 if (err) {
219 syslog(LOG_ERR, "Cannot set nonblock flag on socket: %m");
220 exit(EX_OSERR);
224 static void pmtu_discovery_off(int fd)
226 #if defined(IP_MTU_DISCOVER) && defined(IP_PMTUDISC_DONT)
227 int pmtu = IP_PMTUDISC_DONT;
229 setsockopt(fd, IPPROTO_IP, IP_MTU_DISCOVER, &pmtu, sizeof(pmtu));
230 #endif
234 * Receive packet with synchronous timeout; timeout is adjusted
235 * to account for time spent waiting.
237 static int recv_time(int s, void *rbuf, int len, unsigned int flags,
238 unsigned long *timeout_us_p)
240 fd_set fdset;
241 struct timeval tmv, t0, t1;
242 int rv, err;
243 unsigned long timeout_us = *timeout_us_p;
244 unsigned long timeout_left, dt;
246 gettimeofday(&t0, NULL);
247 timeout_left = timeout_us;
249 for (;;) {
250 FD_ZERO(&fdset);
251 FD_SET(s, &fdset);
253 do {
254 tmv.tv_sec = timeout_left / 1000000;
255 tmv.tv_usec = timeout_left % 1000000;
257 rv = select(s + 1, &fdset, NULL, NULL, &tmv);
258 err = errno;
260 gettimeofday(&t1, NULL);
262 dt = (t1.tv_sec - t0.tv_sec) * 1000000 +
263 (t1.tv_usec - t0.tv_usec);
264 *timeout_us_p = timeout_left =
265 (dt >= timeout_us) ? 1 : (timeout_us - dt);
266 } while (rv == -1 && err == EINTR);
268 if (rv == 0) {
269 timer(0); /* Should not return */
270 return -1;
273 set_socket_nonblock(s, 1);
274 rv = recv(s, rbuf, len, flags);
275 err = errno;
276 set_socket_nonblock(s, 0);
278 if (rv < 0) {
279 if (E_WOULD_BLOCK(err) || err == EINTR) {
280 continue; /* Once again, with feeling... */
281 } else {
282 errno = err;
283 return rv;
285 } else {
286 return rv;
291 static int split_port(char **ap, char **pp)
293 char *a, *p;
294 int ret = AF_UNSPEC;
296 a = *ap;
297 #ifdef HAVE_IPV6
298 if (is_numeric_ipv6(a)) {
299 if (*a++ != '[')
300 return -1;
301 *ap = a;
302 p = strrchr(a, ']');
303 if (!p)
304 return -1;
305 *p++ = 0;
306 a = p;
307 ret = AF_INET6;
308 p = strrchr(a, ':');
309 if (p)
310 *p++ = 0;
311 } else
312 #endif
314 struct in_addr in;
316 p = strrchr(a, ':');
317 if (p)
318 *p++ = 0;
319 if (inet_aton(a, &in))
320 ret = AF_INET;
322 *pp = p;
323 return ret;
326 enum long_only_options {
327 OPT_VERBOSITY = 256,
328 OPT_MAP_STEPS
331 static struct option long_options[] = {
332 { "ipv4", 0, NULL, '4' },
333 { "ipv6", 0, NULL, '6' },
334 { "create", 0, NULL, 'c' },
335 { "secure", 0, NULL, 's' },
336 { "permissive", 0, NULL, 'p' },
337 { "verbose", 0, NULL, 'v' },
338 { "verbosity", 1, NULL, OPT_VERBOSITY },
339 { "version", 0, NULL, 'V' },
340 { "listen", 0, NULL, 'l' },
341 { "foreground", 0, NULL, 'L' },
342 { "address", 1, NULL, 'a' },
343 { "blocksize", 1, NULL, 'B' },
344 { "user", 1, NULL, 'u' },
345 { "umask", 1, NULL, 'U' },
346 { "refuse", 1, NULL, 'r' },
347 { "timeout", 1, NULL, 't' },
348 { "retransmit", 1, NULL, 'T' },
349 { "port-range", 1, NULL, 'R' },
350 { "map-file", 1, NULL, 'm' },
351 { "map-steps", 1, NULL, OPT_MAP_STEPS },
352 { "pidfile", 1, NULL, 'P' },
353 { NULL, 0, NULL, 0 }
355 static const char short_options[] = "46cspvVlLa:B:u:U:r:t:T:R:m:P:";
357 int main(int argc, char **argv)
359 struct tftphdr *tp;
360 struct passwd *pw;
361 struct options *opt;
362 union sock_addr myaddr;
363 struct sockaddr_in bindaddr4;
364 #ifdef HAVE_IPV6
365 struct sockaddr_in6 bindaddr6;
366 int force_ipv6 = 0;
367 #endif
368 int n;
369 int fd = -1;
370 int fd4 = -1;
371 int fd6 = -1;
372 int fdmax = 0;
373 int standalone = 0; /* Standalone (listen) mode */
374 int nodaemon = 0; /* Do not detach process */
375 char *address = NULL; /* Address to listen to */
376 pid_t pid;
377 mode_t my_umask = 0;
378 int spec_umask = 0;
379 int c;
380 int setrv;
381 int die;
382 int waittime = 900; /* Default time to wait for a connect */
383 const char *user = "nobody"; /* Default user */
384 char *p, *ep;
385 #ifdef WITH_REGEX
386 char *rewrite_file = NULL;
387 #endif
388 const char *pidfile = NULL;
389 u_short tp_opcode;
391 /* basename() is way too much of a pain from a portability standpoint */
393 p = strrchr(argv[0], '/');
394 tftpd_progname = (p && p[1]) ? p + 1 : argv[0];
396 openlog(tftpd_progname, LOG_PID | LOG_NDELAY, LOG_DAEMON);
398 srand(time(NULL) ^ getpid());
400 while ((c = getopt_long(argc, argv, short_options, long_options, NULL))
401 != -1)
402 switch (c) {
403 case '4':
404 ai_fam = AF_INET;
405 break;
406 #ifdef HAVE_IPV6
407 case '6':
408 ai_fam = AF_INET6;
409 force_ipv6 = 1;
410 break;
411 #endif
412 case 'c':
413 cancreate = 1;
414 break;
415 case 's':
416 secure = 1;
417 break;
418 case 'p':
419 unixperms = 1;
420 break;
421 case 'l':
422 standalone = 1;
423 break;
424 case 'L':
425 standalone = 1;
426 nodaemon = 1;
427 break;
428 case 'a':
429 address = optarg;
430 break;
431 case 't':
432 waittime = atoi(optarg);
433 break;
434 case 'B':
436 char *vp;
437 max_blksize = (unsigned int)strtoul(optarg, &vp, 10);
438 if (max_blksize < 512 || max_blksize > MAX_SEGSIZE || *vp) {
439 syslog(LOG_ERR,
440 "Bad maximum blocksize value (range 512-%d): %s",
441 MAX_SEGSIZE, optarg);
442 exit(EX_USAGE);
445 break;
446 case 'T':
448 char *vp;
449 unsigned long tov = strtoul(optarg, &vp, 10);
450 if (tov < 10000UL || tov > 255000000UL || *vp) {
451 syslog(LOG_ERR, "Bad timeout value: %s", optarg);
452 exit(EX_USAGE);
454 rexmtval = timeout = tov;
455 maxtimeout = rexmtval * TIMEOUT_LIMIT;
457 break;
458 case 'R':
460 if (sscanf(optarg, "%u:%u", &portrange_from, &portrange_to)
461 != 2 || portrange_from > portrange_to
462 || portrange_to >= 65535) {
463 syslog(LOG_ERR, "Bad port range: %s", optarg);
464 exit(EX_USAGE);
466 portrange = 1;
468 break;
469 case 'u':
470 user = optarg;
471 break;
472 case 'U':
473 my_umask = strtoul(optarg, &ep, 8);
474 if (*ep) {
475 syslog(LOG_ERR, "Invalid umask: %s", optarg);
476 exit(EX_USAGE);
478 spec_umask = 1;
479 break;
480 case 'r':
481 for (opt = options; opt->o_opt; opt++) {
482 if (!strcasecmp(optarg, opt->o_opt)) {
483 opt->o_opt = ""; /* Don't support this option */
484 break;
487 if (!opt->o_opt) {
488 syslog(LOG_ERR, "Unknown option: %s", optarg);
489 exit(EX_USAGE);
491 break;
492 #ifdef WITH_REGEX
493 case 'm':
494 if (rewrite_file) {
495 syslog(LOG_ERR, "Multiple -m options");
496 exit(EX_USAGE);
498 rewrite_file = optarg;
499 break;
500 case OPT_MAP_STEPS:
502 unsigned long steps = strtoul(optarg, &ep, 0);
503 if (*optarg && *ep && steps > 0 && steps <= INT_MAX) {
504 deadman_max_steps = steps;
505 } else {
506 syslog(LOG_ERR, "Bad --map-steps option: %s", optarg);
507 exit(EX_USAGE);
509 break;
511 #endif
512 case 'v':
513 verbosity++;
514 break;
515 case OPT_VERBOSITY:
516 verbosity = atoi(optarg);
517 break;
518 case 'V':
519 /* Print configuration to stdout and exit */
520 printf("%s\n", TFTPD_CONFIG_STR);
521 exit(0);
522 break;
523 case 'P':
524 pidfile = optarg;
525 break;
526 default:
527 syslog(LOG_ERR, "Unknown option: '%c'", optopt);
528 break;
531 dirs = xmalloc((argc - optind + 1) * sizeof(char *));
532 for (ndirs = 0; optind != argc; optind++)
533 dirs[ndirs++] = argv[optind];
535 dirs[ndirs] = NULL;
537 if (secure) {
538 if (ndirs == 0) {
539 syslog(LOG_ERR, "no -s directory");
540 exit(EX_USAGE);
542 if (ndirs > 1) {
543 syslog(LOG_ERR, "too many -s directories");
544 exit(EX_USAGE);
546 if (chdir(dirs[0])) {
547 syslog(LOG_ERR, "%s: %m", dirs[0]);
548 exit(EX_NOINPUT);
552 pw = getpwnam(user);
553 if (!pw) {
554 syslog(LOG_ERR, "no user %s: %m", user);
555 exit(EX_NOUSER);
558 #ifdef WITH_REGEX
559 if (rewrite_file)
560 rewrite_rules = read_remap_rules(rewrite_file);
561 #endif
563 if (pidfile && !standalone) {
564 syslog(LOG_WARNING, "not in standalone mode, ignoring pid file");
565 pidfile = NULL;
568 /* If we're running standalone, set up the input port */
569 if (standalone) {
570 FILE *pf;
571 #ifdef HAVE_IPV6
572 if (ai_fam != AF_INET6) {
573 #endif
574 fd4 = socket(AF_INET, SOCK_DGRAM, 0);
575 if (fd4 < 0) {
576 syslog(LOG_ERR, "cannot open IPv4 socket: %m");
577 exit(EX_OSERR);
579 #ifndef __CYGWIN__
580 set_socket_nonblock(fd4, 1);
581 #endif
582 memset(&bindaddr4, 0, sizeof bindaddr4);
583 bindaddr4.sin_family = AF_INET;
584 bindaddr4.sin_addr.s_addr = INADDR_ANY;
585 bindaddr4.sin_port = htons(IPPORT_TFTP);
586 #ifdef HAVE_IPV6
588 if (ai_fam != AF_INET) {
589 fd6 = socket(AF_INET6, SOCK_DGRAM, 0);
590 if (fd6 < 0) {
591 if (fd4 < 0) {
592 syslog(LOG_ERR, "cannot open IPv6 socket: %m");
593 exit(EX_OSERR);
594 } else {
595 syslog(LOG_ERR,
596 "cannot open IPv6 socket, disable IPv6: %m");
599 #ifndef __CYGWIN__
600 set_socket_nonblock(fd6, 1);
601 #endif
602 memset(&bindaddr6, 0, sizeof bindaddr6);
603 bindaddr6.sin6_family = AF_INET6;
604 bindaddr6.sin6_port = htons(IPPORT_TFTP);
606 #endif
607 if (address) {
608 char *portptr = NULL, *eportptr;
609 int err;
610 struct servent *servent;
611 unsigned long port;
613 address = tfstrdup(address);
614 err = split_port(&address, &portptr);
615 switch (err) {
616 case AF_INET:
617 #ifdef HAVE_IPV6
618 if (fd6 >= 0) {
619 close(fd6);
620 fd6 = -1;
621 if (ai_fam == AF_INET6) {
622 syslog(LOG_ERR,
623 "Address %s is not in address family AF_INET6",
624 address);
625 exit(EX_USAGE);
627 ai_fam = AF_INET;
629 break;
630 case AF_INET6:
631 if (fd4 >= 0) {
632 close(fd4);
633 fd4 = -1;
634 if (ai_fam == AF_INET) {
635 syslog(LOG_ERR,
636 "Address %s is not in address family AF_INET",
637 address);
638 exit(EX_USAGE);
640 ai_fam = AF_INET6;
642 break;
643 #endif
644 case AF_UNSPEC:
645 break;
646 default:
647 syslog(LOG_ERR,
648 "Numeric IPv6 addresses need to be enclosed in []");
649 exit(EX_USAGE);
651 if (!portptr)
652 portptr = (char *)"tftp";
653 if (*address) {
654 if (fd4 >= 0) {
655 bindaddr4.sin_family = AF_INET;
656 err = set_sock_addr(address,
657 (union sock_addr *)&bindaddr4, NULL);
658 if (err) {
659 syslog(LOG_ERR,
660 "cannot resolve local IPv4 bind address: %s, %s",
661 address, gai_strerror(err));
662 exit(EX_NOINPUT);
665 #ifdef HAVE_IPV6
666 if (fd6 >= 0) {
667 bindaddr6.sin6_family = AF_INET6;
668 err = set_sock_addr(address,
669 (union sock_addr *)&bindaddr6, NULL);
670 if (err) {
671 if (fd4 >= 0) {
672 syslog(LOG_ERR,
673 "cannot resolve local IPv6 bind address: %s"
674 "(%s); using IPv4 only",
675 address, gai_strerror(err));
676 close(fd6);
677 fd6 = -1;
678 } else {
679 syslog(LOG_ERR,
680 "cannot resolve local IPv6 bind address: %s"
681 "(%s)", address, gai_strerror(err));
682 exit(EX_NOINPUT);
686 #endif
687 } else {
688 /* Default to using INADDR_ANY */
691 if (portptr && *portptr) {
692 servent = getservbyname(portptr, "udp");
693 if (servent) {
694 if (fd4 >= 0)
695 bindaddr4.sin_port = servent->s_port;
696 #ifdef HAVE_IPV6
697 if (fd6 >= 0)
698 bindaddr6.sin6_port = servent->s_port;
699 #endif
700 } else if ((port = strtoul(portptr, &eportptr, 0))
701 && !*eportptr) {
702 if (fd4 >= 0)
703 bindaddr4.sin_port = htons(port);
704 #ifdef HAVE_IPV6
705 if (fd6 >= 0)
706 bindaddr6.sin6_port = htons(port);
707 #endif
708 } else if (!strcmp(portptr, "tftp")) {
709 /* It's TFTP, we're OK */
710 } else {
711 syslog(LOG_ERR, "cannot resolve local bind port: %s",
712 portptr);
713 exit(EX_NOINPUT);
718 if (fd4 >= 0) {
719 if (bind(fd4, (struct sockaddr *)&bindaddr4,
720 sizeof(bindaddr4)) < 0) {
721 syslog(LOG_ERR, "cannot bind to local IPv4 socket: %m");
722 exit(EX_OSERR);
725 #ifdef HAVE_IPV6
726 if (fd6 >= 0) {
727 #if defined(IPV6_V6ONLY)
728 int on = 1;
729 if (fd4 >= 0 || force_ipv6)
730 if (setsockopt(fd6, IPPROTO_IPV6, IPV6_V6ONLY, (char*)&on,
731 sizeof(on)))
732 syslog(LOG_ERR, "cannot setsockopt IPV6_V6ONLY %m");
733 #endif
734 if (bind(fd6, (struct sockaddr *)&bindaddr6,
735 sizeof(bindaddr6)) < 0) {
736 if (fd4 >= 0) {
737 syslog(LOG_ERR,
738 "cannot bind to local IPv6 socket,"
739 "IPv6 disabled: %m");
740 close(fd6);
741 fd6 = -1;
742 } else {
743 syslog(LOG_ERR, "cannot bind to local IPv6 socket: %m");
744 exit(EX_OSERR);
748 #endif
749 /* Daemonize this process */
750 /* Note: when running in secure mode (-s), we must not chdir, since
751 we are already in the proper directory. */
752 if (!nodaemon && daemon(secure, 0) < 0) {
753 syslog(LOG_ERR, "cannot daemonize: %m");
754 exit(EX_OSERR);
756 set_signal(SIGTERM, handle_exit, 0);
757 set_signal(SIGINT, handle_exit, 0);
758 if (pidfile) {
759 pf = fopen (pidfile, "w");
760 if (!pf) {
761 syslog(LOG_ERR, "cannot open pid file '%s' for writing: %m", pidfile);
762 pidfile = NULL;
763 } else {
764 if (fprintf(pf, "%d\n", getpid()) < 0)
765 syslog(LOG_ERR, "error writing pid file '%s': %m", pidfile);
766 if (fclose(pf))
767 syslog(LOG_ERR, "error closing pid file '%s': %m", pidfile);
770 if (fd6 > fd4)
771 fdmax = fd6;
772 else
773 fdmax = fd4;
774 } else {
775 /* 0 is our socket descriptor */
776 close(1);
777 close(2);
778 fd = 0;
779 fdmax = 0;
780 /* Note: on Cygwin, select() on a nonblocking socket becomes
781 a nonblocking select. */
782 #ifndef __CYGWIN__
783 set_socket_nonblock(fd, 1);
784 #endif
787 /* Disable path MTU discovery */
788 pmtu_discovery_off(fd);
790 /* This means we don't want to wait() for children */
791 #ifdef SA_NOCLDWAIT
792 set_signal(SIGCHLD, SIG_IGN, SA_NOCLDSTOP | SA_NOCLDWAIT);
793 #else
794 set_signal(SIGCHLD, SIG_IGN, SA_NOCLDSTOP);
795 #endif
797 /* Take SIGHUP and use it to set a variable. This
798 is polled synchronously to make sure we don't
799 lose packets as a result. */
800 set_signal(SIGHUP, handle_sighup, 0);
802 if (spec_umask || !unixperms)
803 umask(my_umask);
805 while (1) {
806 fd_set readset;
807 struct timeval tv_waittime;
808 int rv;
810 if (exit_signal) { /* happens in standalone mode only */
811 if (pidfile && unlink(pidfile)) {
812 syslog(LOG_WARNING, "error removing pid file '%s': %m", pidfile);
813 exit(EX_OSERR);
814 } else {
815 exit(0);
819 if (caught_sighup) {
820 caught_sighup = 0;
821 if (standalone) {
822 #ifdef WITH_REGEX
823 if (rewrite_file) {
824 freerules(rewrite_rules);
825 rewrite_rules = read_remap_rules(rewrite_file);
827 #endif
828 } else {
829 /* Return to inetd for respawn */
830 exit(0);
834 FD_ZERO(&readset);
835 if (standalone) {
836 if (fd4 >= 0) {
837 FD_SET(fd4, &readset);
838 #ifdef __CYGWIN__
839 /* On Cygwin, select() on a nonblocking socket returns
840 immediately, with a rv of 0! */
841 set_socket_nonblock(fd4, 0);
842 #endif
844 if (fd6 >= 0) {
845 FD_SET(fd6, &readset);
846 #ifdef __CYGWIN__
847 /* On Cygwin, select() on a nonblocking socket returns
848 immediately, with a rv of 0! */
849 set_socket_nonblock(fd6, 0);
850 #endif
852 } else { /* fd always 0 */
853 fd = 0;
854 #ifdef __CYGWIN__
855 /* On Cygwin, select() on a nonblocking socket returns
856 immediately, with a rv of 0! */
857 set_socket_nonblock(fd, 0);
858 #endif
859 FD_SET(fd, &readset);
861 tv_waittime.tv_sec = waittime;
862 tv_waittime.tv_usec = 0;
865 /* Never time out if we're in standalone mode */
866 rv = select(fdmax + 1, &readset, NULL, NULL,
867 standalone ? NULL : &tv_waittime);
868 if (rv == -1 && errno == EINTR)
869 continue; /* Signal caught, reloop */
871 if (rv == -1) {
872 syslog(LOG_ERR, "select loop: %m");
873 exit(EX_IOERR);
874 } else if (rv == 0) {
875 exit(0); /* Timeout, return to inetd */
878 if (standalone) {
879 if ((fd4 >= 0) && FD_ISSET(fd4, &readset))
880 fd = fd4;
881 else if ((fd6 >= 0) && FD_ISSET(fd6, &readset))
882 fd = fd6;
883 else /* not in set ??? */
884 continue;
886 #ifdef __CYGWIN__
887 /* On Cygwin, select() on a nonblocking socket returns
888 immediately, with a rv of 0! */
889 set_socket_nonblock(fd, 0);
890 #endif
892 n = myrecvfrom(fd, buf, sizeof(buf), 0, &from, &myaddr);
894 if (n < 0) {
895 if (E_WOULD_BLOCK(errno) || errno == EINTR) {
896 continue; /* Again, from the top */
897 } else {
898 syslog(LOG_ERR, "recvfrom: %m");
899 exit(EX_IOERR);
902 #ifdef HAVE_IPV6
903 if ((from.sa.sa_family != AF_INET) && (from.sa.sa_family != AF_INET6)) {
904 syslog(LOG_ERR, "received address was not AF_INET/AF_INET6,"
905 " please check your inetd config");
906 #else
907 if (from.sa.sa_family != AF_INET) {
908 syslog(LOG_ERR, "received address was not AF_INET,"
909 " please check your inetd config");
910 #endif
911 exit(EX_PROTOCOL);
914 if (standalone) {
915 if ((from.sa.sa_family == AF_INET) &&
916 (myaddr.si.sin_addr.s_addr == INADDR_ANY)) {
917 /* myrecvfrom() didn't capture the source address; but we might
918 have bound to a specific address, if so we should use it */
919 memcpy(SOCKADDR_P(&myaddr), &bindaddr4.sin_addr,
920 sizeof(bindaddr4.sin_addr));
921 #ifdef HAVE_IPV6
922 } else if ((from.sa.sa_family == AF_INET6) &&
923 IN6_IS_ADDR_UNSPECIFIED((struct in6_addr *)
924 SOCKADDR_P(&myaddr))) {
925 memcpy(SOCKADDR_P(&myaddr), &bindaddr6.sin6_addr,
926 sizeof(bindaddr6.sin6_addr));
927 #endif
932 * Now that we have read the request packet from the UDP
933 * socket, we fork and go back to listening to the socket.
935 pid = fork();
936 if (pid < 0) {
937 syslog(LOG_ERR, "fork: %m");
938 exit(EX_OSERR); /* Return to inetd, just in case */
939 } else if (pid == 0)
940 break; /* Child exit, parent loop */
943 /* Child process: handle the actual request here */
945 /* Ignore SIGHUP */
946 set_signal(SIGHUP, SIG_IGN, 0);
948 /* Make sure the log socket is still connected. This has to be
949 done before the chroot, while /dev/log is still accessible.
950 When not running standalone, there is little chance that the
951 syslog daemon gets restarted by the time we get here. */
952 if (secure && standalone) {
953 closelog();
954 openlog(tftpd_progname, LOG_PID | LOG_NDELAY, LOG_DAEMON);
957 #ifdef HAVE_TCPWRAPPERS
958 /* Verify if this was a legal request for us. This has to be
959 done before the chroot, while /etc is still accessible. */
960 request_init(&wrap_request,
961 RQ_DAEMON, tftpd_progname,
962 RQ_FILE, fd,
963 RQ_CLIENT_SIN, &from, RQ_SERVER_SIN, &myaddr, 0);
964 sock_methods(&wrap_request);
966 tmp_p = (char *)inet_ntop(myaddr.sa.sa_family, SOCKADDR_P(&myaddr),
967 tmpbuf, INET6_ADDRSTRLEN);
968 if (!tmp_p) {
969 tmp_p = tmpbuf;
970 strcpy(tmpbuf, "???");
972 if (hosts_access(&wrap_request) == 0) {
973 if (deny_severity != -1)
974 syslog(deny_severity, "connection refused from %s", tmp_p);
975 exit(EX_NOPERM); /* Access denied */
976 } else if (allow_severity != -1) {
977 syslog(allow_severity, "connect from %s", tmp_p);
979 #endif
981 /* Close file descriptors we don't need */
982 close(fd);
984 /* Get a socket. This has to be done before the chroot(), since
985 some systems require access to /dev to create a socket. */
987 peer = socket(myaddr.sa.sa_family, SOCK_DGRAM, 0);
988 if (peer < 0) {
989 syslog(LOG_ERR, "socket: %m");
990 exit(EX_IOERR);
993 /* Set up the supplementary group access list if possible
994 /etc/group still need to be accessible at this point.
995 If we get EPERM, this is already a restricted process, e.g.
996 using user namespaces on Linux. */
997 die = 0;
998 #ifdef HAVE_SETGROUPS
999 setrv = setgroups(0, NULL);
1000 if (setrv && errno != EPERM) {
1001 syslog(LOG_ERR, "cannot clear group list");
1002 die = EX_OSERR;
1004 #endif
1005 #ifdef HAVE_INITGROUPS
1006 setrv = initgroups(user, pw->pw_gid);
1007 if (!setrv) {
1008 die = 0;
1009 } else if (errno != EPERM) {
1010 syslog(LOG_ERR, "cannot set groups for user %s", user);
1011 die = EX_OSERR;
1013 #endif
1014 if (die)
1015 exit(die);
1017 /* Chroot and drop privileges */
1018 if (secure) {
1019 if (chroot(".")) {
1020 syslog(LOG_ERR, "chroot: %m");
1021 exit(EX_OSERR);
1023 #ifdef __CYGWIN__
1024 chdir("/"); /* Cygwin chroot() bug workaround */
1025 #endif
1028 #ifdef HAVE_SETRESGID
1029 setrv = setresgid(pw->pw_gid, pw->pw_gid, pw->pw_gid);
1030 #elif defined(HAVE_SETREGID)
1031 setrv = setregid(pw->pw_gid, pw->pw_gid);
1032 #else
1033 setrv = setegid(pw->pw_gid) || setgid(pw->pw_gid);
1034 #endif
1035 if (setrv && errno == EPERM) {
1036 setrv = 0; /* Assume already restricted by system policy */
1039 #ifdef HAVE_SETRESUID
1040 setrv = setrv || setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid);
1041 #elif defined(HAVE_SETREUID)
1042 setrv = setrv || setreuid(pw->pw_uid, pw->pw_uid);
1043 #else
1044 /* Important: setuid() must come first */
1045 setrv = setrv || setuid(pw->pw_uid) ||
1046 (geteuid() != pw->pw_uid && seteuid(pw->pw_uid));
1047 #endif
1048 if (setrv && errno == EPERM) {
1049 setrv = 0; /* Assume already restricted by system policy */
1052 if (setrv) {
1053 syslog(LOG_ERR, "cannot drop privileges: %m");
1054 exit(EX_OSERR);
1057 /* Process the request... */
1058 if (pick_port_bind(peer, &myaddr, portrange_from, portrange_to) < 0) {
1059 syslog(LOG_ERR, "bind: %m");
1060 exit(EX_IOERR);
1063 if (connect(peer, &from.sa, SOCKLEN(&from)) < 0) {
1064 syslog(LOG_ERR, "connect: %m");
1065 exit(EX_IOERR);
1068 /* Disable path MTU discovery */
1069 pmtu_discovery_off(peer);
1071 tp = (struct tftphdr *)buf;
1072 tp_opcode = ntohs(tp->th_opcode);
1073 if (tp_opcode == RRQ || tp_opcode == WRQ)
1074 tftp(tp, n);
1075 exit(0);
1078 static char *rewrite_access(const struct formats *,
1079 char *, int, int, const char **);
1080 static int validate_access(char *, int, const struct formats *, const char **);
1081 static void tftp_sendfile(const struct formats *, struct tftphdr *, int);
1082 static void tftp_recvfile(const struct formats *, struct tftphdr *, int);
1084 static const struct formats formats[] = {
1086 "netascii", rewrite_access, validate_access, tftp_sendfile,
1087 tftp_recvfile, 1}, {
1088 "octet", rewrite_access, validate_access, tftp_sendfile,
1089 tftp_recvfile, 0}, {
1090 NULL, NULL, NULL, NULL, NULL, 0}
1094 * Handle initial connection protocol.
1096 int tftp(struct tftphdr *tp, int size)
1098 char *cp, *end;
1099 int argn, ecode;
1100 const struct formats *pf = NULL;
1101 char *origfilename;
1102 char *filename, *mode = NULL;
1103 const char *errmsgptr;
1104 u_short tp_opcode = ntohs(tp->th_opcode);
1106 char *val = NULL, *opt = NULL;
1107 char *ap = ackbuf + 2;
1109 ((struct tftphdr *)ackbuf)->th_opcode = htons(OACK);
1111 origfilename = cp = (char *)&(tp->th_stuff);
1112 argn = 0;
1114 end = (char *)tp + size;
1116 while (cp < end && *cp) {
1117 do {
1118 cp++;
1119 } while (cp < end && *cp);
1121 if (*cp) {
1122 nak(EBADOP, "Request not null-terminated");
1123 exit(0);
1126 argn++;
1127 if (argn == 1) {
1128 mode = ++cp;
1129 } else if (argn == 2) {
1130 for (cp = mode; *cp; cp++)
1131 *cp = tolower(*cp);
1132 for (pf = formats; pf->f_mode; pf++) {
1133 if (!strcmp(pf->f_mode, mode))
1134 break;
1136 if (!pf->f_mode) {
1137 nak(EBADOP, "Unknown mode");
1138 exit(0);
1140 file = NULL;
1141 if (!(filename = (*pf->f_rewrite)
1142 (pf, origfilename, tp_opcode, from.sa.sa_family, &errmsgptr))) {
1143 nak(EACCESS, errmsgptr); /* File denied by mapping rule */
1144 exit(0);
1146 if (verbosity >= 1) {
1147 tmp_p = (char *)inet_ntop(from.sa.sa_family, SOCKADDR_P(&from),
1148 tmpbuf, INET6_ADDRSTRLEN);
1149 if (!tmp_p) {
1150 tmp_p = tmpbuf;
1151 strcpy(tmpbuf, "???");
1153 if (filename == origfilename
1154 || !strcmp(filename, origfilename))
1155 syslog(LOG_NOTICE, "%s from %s filename %s\n",
1156 tp_opcode == WRQ ? "WRQ" : "RRQ",
1157 tmp_p, filename);
1158 else
1159 syslog(LOG_NOTICE,
1160 "%s from %s filename %s remapped to %s\n",
1161 tp_opcode == WRQ ? "WRQ" : "RRQ",
1162 tmp_p, origfilename,
1163 filename);
1166 * If "file" is already set, then a file was already validated
1167 * and opened during remap processing.
1169 if (!file) {
1170 ecode =
1171 (*pf->f_validate) (filename, tp_opcode, pf, &errmsgptr);
1172 if (ecode) {
1173 nak(ecode, errmsgptr);
1174 exit(0);
1177 opt = ++cp;
1178 } else if (argn & 1) {
1179 val = ++cp;
1180 } else {
1181 do_opt(opt, val, &ap);
1182 opt = ++cp;
1186 if (!pf) {
1187 nak(EBADOP, "Missing mode");
1188 exit(0);
1191 if (ap != (ackbuf + 2)) {
1192 if (tp_opcode == WRQ)
1193 (*pf->f_recv) (pf, (struct tftphdr *)ackbuf, ap - ackbuf);
1194 else
1195 (*pf->f_send) (pf, (struct tftphdr *)ackbuf, ap - ackbuf);
1196 } else {
1197 if (tp_opcode == WRQ)
1198 (*pf->f_recv) (pf, NULL, 0);
1199 else
1200 (*pf->f_send) (pf, NULL, 0);
1202 exit(0); /* Request completed */
1205 static int blksize_set;
1208 * Set a non-standard block size (c.f. RFC2348)
1210 static int set_blksize(uintmax_t *vp)
1212 uintmax_t sz = *vp;
1214 if (blksize_set)
1215 return 0;
1217 if (sz < 8)
1218 return 0;
1219 else if (sz > max_blksize)
1220 sz = max_blksize;
1222 *vp = segsize = sz;
1223 blksize_set = 1;
1224 return 1;
1228 * Set a power-of-two block size (nonstandard)
1230 static int set_blksize2(uintmax_t *vp)
1232 uintmax_t sz = *vp;
1234 if (blksize_set)
1235 return 0;
1237 if (sz < 8)
1238 return (0);
1239 else if (sz > max_blksize)
1240 sz = max_blksize;
1241 else
1243 /* Convert to a power of two */
1244 if (sz & (sz - 1)) {
1245 unsigned int sz1 = 1;
1246 /* Not a power of two - need to convert */
1247 while (sz >>= 1)
1248 sz1 <<= 1;
1249 sz = sz1;
1252 *vp = segsize = sz;
1253 blksize_set = 1;
1254 return 1;
1258 * Set the block number rollover value
1260 static int set_rollover(uintmax_t *vp)
1262 uintmax_t ro = *vp;
1264 if (ro > 65535)
1265 return 0;
1267 rollover_val = (uint16_t)ro;
1268 return 1;
1272 * Return a file size (c.f. RFC2349)
1273 * For netascii mode, we don't know the size ahead of time;
1274 * so reject the option.
1276 static int set_tsize(uintmax_t *vp)
1278 uintmax_t sz = *vp;
1280 if (!tsize_ok)
1281 return 0;
1283 if (sz == 0)
1284 sz = tsize;
1286 *vp = sz;
1287 return 1;
1291 * Set the timeout (c.f. RFC2349). This is supposed
1292 * to be the (default) retransmission timeout, but being an
1293 * integer in seconds it seems a bit limited.
1295 static int set_timeout(uintmax_t *vp)
1297 uintmax_t to = *vp;
1299 if (to < 1 || to > 255)
1300 return 0;
1302 rexmtval = timeout = to * 1000000UL;
1303 maxtimeout = rexmtval * TIMEOUT_LIMIT;
1305 return 1;
1308 /* Similar, but in microseconds. We allow down to 10 ms. */
1309 static int set_utimeout(uintmax_t *vp)
1311 uintmax_t to = *vp;
1313 if (to < 10000UL || to > 255000000UL)
1314 return 0;
1316 rexmtval = timeout = to;
1317 maxtimeout = rexmtval * TIMEOUT_LIMIT;
1319 return 1;
1323 * Conservative calculation for the size of a buffer which can hold an
1324 * arbitrary integer
1326 #define OPTBUFSIZE (sizeof(uintmax_t) * CHAR_BIT / 3 + 3)
1329 * Parse RFC2347 style options; we limit the arguments to positive
1330 * integers which matches all our current options.
1332 static void do_opt(const char *opt, const char *val, char **ap)
1334 struct options *po;
1335 char retbuf[OPTBUFSIZE];
1336 char *p = *ap;
1337 size_t optlen, retlen;
1338 char *vend;
1339 uintmax_t v;
1341 /* Global option-parsing variables initialization */
1342 blksize_set = 0;
1344 if (!*opt || !*val)
1345 return;
1347 errno = 0;
1348 v = strtoumax(val, &vend, 10);
1349 if (*vend || errno == ERANGE)
1350 return;
1352 for (po = options; po->o_opt; po++)
1353 if (!strcasecmp(po->o_opt, opt)) {
1354 if (po->o_fnc(&v)) {
1355 optlen = strlen(opt);
1356 retlen = sprintf(retbuf, "%"PRIuMAX, v);
1358 if (p + optlen + retlen + 2 >= ackbuf + sizeof(ackbuf)) {
1359 nak(EOPTNEG, "Insufficient space for options");
1360 exit(0);
1363 memcpy(p, opt, optlen+1);
1364 p += optlen+1;
1365 memcpy(p, retbuf, retlen+1);
1366 p += retlen+1;
1367 } else {
1368 nak(EOPTNEG, "Unsupported option(s) requested");
1369 exit(0);
1371 break;
1374 *ap = p;
1377 #ifdef WITH_REGEX
1380 * This is called by the remap engine when it encounters macros such
1381 * as \i. It should write the output in "output" if non-NULL, and
1382 * return the length of the output (generated or not).
1384 * Return -1 on failure.
1386 static int rewrite_macros(char macro, char *output)
1388 char *p, tb[INET6_ADDRSTRLEN];
1389 int l=0;
1391 switch (macro) {
1392 case 'i':
1393 p = (char *)inet_ntop(from.sa.sa_family, SOCKADDR_P(&from),
1394 tb, INET6_ADDRSTRLEN);
1395 if (output && p)
1396 strcpy(output, p);
1397 if (!p)
1398 return 0;
1399 else
1400 return strlen(p);
1402 case 'x':
1403 if (output) {
1404 if (from.sa.sa_family == AF_INET) {
1405 sprintf(output, "%08lX",
1406 (unsigned long)ntohl(from.si.sin_addr.s_addr));
1407 l = 8;
1408 #ifdef HAVE_IPV6
1409 } else {
1410 unsigned char *c = (unsigned char *)SOCKADDR_P(&from);
1411 p = tb;
1412 for (l = 0; l < 16; l++) {
1413 sprintf(p, "%02X", *c);
1414 c++;
1415 p += 2;
1417 strcpy(output, tb);
1418 l = strlen(tb);
1419 #endif
1422 return l;
1424 default:
1425 return -1;
1430 * Modify the filename, if applicable. If it returns NULL, deny the access.
1432 static char *rewrite_access(const struct formats *pf, char *filename,
1433 int mode, int af, const char **msg)
1435 if (rewrite_rules) {
1436 char *newname =
1437 rewrite_string(pf, filename, rewrite_rules, mode, af,
1438 rewrite_macros, msg);
1439 filename = newname;
1441 return filename;
1444 #else
1445 static char *rewrite_access(const struct formats *pf, char *filename,
1446 int mode, int af, const char **msg)
1448 (void)pf;
1449 (void)mode; /* Avoid warning */
1450 (void)msg;
1451 (void)af;
1452 return filename;
1454 #endif
1457 * Validate file access. Since we
1458 * have no uid or gid, for now require
1459 * file to exist and be publicly
1460 * readable/writable, unless -p specified.
1461 * If we were invoked with arguments
1462 * from inetd then the file must also be
1463 * in one of the given directory prefixes.
1464 * Note also, full path name must be
1465 * given as we have no login directory.
1467 static int validate_access(char *filename, int mode,
1468 const struct formats *pf, const char **errmsg)
1470 struct stat stbuf;
1471 int i, len;
1472 int fd, wmode, rmode;
1473 char *cp;
1474 const char **dirp;
1475 char stdio_mode[3];
1477 tsize_ok = 0;
1478 *errmsg = NULL;
1480 if (!secure) {
1481 if (*filename != '/') {
1482 *errmsg = "Only absolute filenames allowed";
1483 return (EACCESS);
1487 * prevent tricksters from getting around the directory
1488 * restrictions
1490 len = strlen(filename);
1491 for (i = 1; i < len - 3; i++) {
1492 cp = filename + i;
1493 if (*cp == '.' && memcmp(cp - 1, "/../", 4) == 0) {
1494 *errmsg = "Reverse path not allowed";
1495 return (EACCESS);
1499 for (dirp = dirs; *dirp; dirp++)
1500 if (strncmp(filename, *dirp, strlen(*dirp)) == 0)
1501 break;
1502 if (*dirp == 0 && dirp != dirs) {
1503 *errmsg = "Forbidden directory";
1504 return (EACCESS);
1509 * We use different a different permissions scheme if `cancreate' is
1510 * set.
1512 wmode = O_WRONLY | (cancreate ? O_CREAT : 0) | (pf->f_convert ? O_TEXT : O_BINARY);
1513 rmode = O_RDONLY | (pf->f_convert ? O_TEXT : O_BINARY);
1515 #ifndef HAVE_FTRUNCATE
1516 wmode |= O_TRUNC; /* This really sucks on a dupe */
1517 #endif
1519 fd = open(filename, mode == RRQ ? rmode : wmode, 0666);
1520 if (fd < 0) {
1521 switch (errno) {
1522 case ENOENT:
1523 case ENOTDIR:
1524 return ENOTFOUND;
1525 case ENOSPC:
1526 return ENOSPACE;
1527 case EEXIST:
1528 return EEXISTS;
1529 default:
1530 return errno + 100;
1534 if (fstat(fd, &stbuf) < 0)
1535 exit(EX_OSERR); /* This shouldn't happen */
1537 /* A duplicate RRQ or (worse!) WRQ packet could really cause havoc... */
1538 if (lock_file(fd, mode != RRQ))
1539 exit(0);
1541 if (mode == RRQ) {
1542 if (!unixperms && (stbuf.st_mode & (S_IREAD >> 6)) == 0) {
1543 *errmsg = "File must have global read permissions";
1544 return (EACCESS);
1546 tsize = stbuf.st_size;
1547 /* We don't know the tsize if conversion is needed */
1548 tsize_ok = !pf->f_convert;
1549 } else {
1550 if (!unixperms) {
1551 if ((stbuf.st_mode & (S_IWRITE >> 6)) == 0) {
1552 *errmsg = "File must have global write permissions";
1553 return (EACCESS);
1557 #ifdef HAVE_FTRUNCATE
1558 /* We didn't get to truncate the file at open() time */
1559 if (ftruncate(fd, (off_t) 0)) {
1560 *errmsg = "Cannot reset file size";
1561 return (EACCESS);
1563 #endif
1564 tsize = 0;
1565 tsize_ok = 1;
1568 stdio_mode[0] = (mode == RRQ) ? 'r' : 'w';
1569 stdio_mode[1] = (pf->f_convert) ? 't' : 'b';
1570 stdio_mode[2] = '\0';
1572 file = fdopen(fd, stdio_mode);
1573 if (file == NULL)
1574 exit(EX_OSERR); /* Internal error */
1576 return (0);
1580 * Send the requested file.
1582 static void tftp_sendfile(const struct formats *pf, struct tftphdr *oap, int oacklen)
1584 struct tftphdr *dp;
1585 struct tftphdr *ap; /* ack packet */
1586 static u_short block = 1; /* Static to avoid longjmp funnies */
1587 u_short ap_opcode, ap_block;
1588 unsigned long r_timeout;
1589 int size, n;
1591 if (oap) {
1592 timeout = rexmtval;
1593 (void)sigsetjmp(timeoutbuf, 1);
1594 oack:
1595 r_timeout = timeout;
1596 if (send(peer, oap, oacklen, 0) != oacklen) {
1597 syslog(LOG_WARNING, "tftpd: oack: %m\n");
1598 goto abort;
1600 for (;;) {
1601 n = recv_time(peer, ackbuf, sizeof(ackbuf), 0, &r_timeout);
1602 if (n < 0) {
1603 syslog(LOG_WARNING, "tftpd: read: %m\n");
1604 goto abort;
1606 ap = (struct tftphdr *)ackbuf;
1607 ap_opcode = ntohs((u_short) ap->th_opcode);
1608 ap_block = ntohs((u_short) ap->th_block);
1610 if (ap_opcode == ERROR) {
1611 syslog(LOG_WARNING,
1612 "tftp: client does not accept options\n");
1613 goto abort;
1615 if (ap_opcode == ACK) {
1616 if (ap_block == 0)
1617 break;
1618 /* Resynchronize with the other side */
1619 (void)synchnet(peer);
1620 goto oack;
1625 dp = r_init();
1626 do {
1627 size = readit(file, &dp, pf->f_convert);
1628 if (size < 0) {
1629 nak(errno + 100, NULL);
1630 goto abort;
1632 dp->th_opcode = htons((u_short) DATA);
1633 dp->th_block = htons((u_short) block);
1634 timeout = rexmtval;
1635 (void)sigsetjmp(timeoutbuf, 1);
1637 r_timeout = timeout;
1638 if (send(peer, dp, size + 4, 0) != size + 4) {
1639 syslog(LOG_WARNING, "tftpd: write: %m");
1640 goto abort;
1642 read_ahead(file, pf->f_convert);
1643 for (;;) {
1644 n = recv_time(peer, ackbuf, sizeof(ackbuf), 0, &r_timeout);
1645 if (n < 0) {
1646 syslog(LOG_WARNING, "tftpd: read(ack): %m");
1647 goto abort;
1649 ap = (struct tftphdr *)ackbuf;
1650 ap_opcode = ntohs((u_short) ap->th_opcode);
1651 ap_block = ntohs((u_short) ap->th_block);
1653 if (ap_opcode == ERROR)
1654 goto abort;
1656 if (ap_opcode == ACK) {
1657 if (ap_block == block) {
1658 break;
1660 /* Re-synchronize with the other side */
1661 (void)synchnet(peer);
1663 * RFC1129/RFC1350: We MUST NOT re-send the DATA
1664 * packet in response to an invalid ACK. Doing so
1665 * would cause the Sorcerer's Apprentice bug.
1670 if (!++block)
1671 block = rollover_val;
1672 } while (size == segsize);
1673 abort:
1674 (void)fclose(file);
1678 * Receive a file.
1680 static void tftp_recvfile(const struct formats *pf,
1681 struct tftphdr *oack, int oacklen)
1683 struct tftphdr *dp;
1684 int n, size;
1685 /* These are "static" to avoid longjmp funnies */
1686 static struct tftphdr *oap;
1687 static struct tftphdr *ap; /* ack buffer */
1688 static u_short block = 0;
1689 static int acksize;
1690 u_short dp_opcode, dp_block;
1691 unsigned long r_timeout;
1693 oap = oack;
1695 dp = w_init();
1696 do {
1697 timeout = rexmtval;
1699 if (!block && oap) {
1700 ap = (struct tftphdr *)ackbuf;
1701 acksize = oacklen;
1702 } else {
1703 ap = (struct tftphdr *)ackbuf;
1704 ap->th_opcode = htons((u_short) ACK);
1705 ap->th_block = htons((u_short) block);
1706 acksize = 4;
1707 /* If we're sending a regular ACK, that means we have successfully
1708 * sent the OACK. Clear oap so that we won't try to send another
1709 * OACK when the block number wraps back to 0. */
1710 oap = NULL;
1712 if (!++block)
1713 block = rollover_val;
1714 (void)sigsetjmp(timeoutbuf, 1);
1715 send_ack:
1716 r_timeout = timeout;
1717 if (send(peer, ackbuf, acksize, 0) != acksize) {
1718 syslog(LOG_WARNING, "tftpd: write(ack): %m");
1719 goto abort;
1721 write_behind(file, pf->f_convert);
1722 for (;;) {
1723 n = recv_time(peer, dp, PKTSIZE, 0, &r_timeout);
1724 if (n < 0) { /* really? */
1725 syslog(LOG_WARNING, "tftpd: read: %m");
1726 goto abort;
1728 dp_opcode = ntohs((u_short) dp->th_opcode);
1729 dp_block = ntohs((u_short) dp->th_block);
1730 if (dp_opcode == ERROR)
1731 goto abort;
1732 if (dp_opcode == DATA) {
1733 if (dp_block == block) {
1734 break; /* normal */
1736 /* Re-synchronize with the other side */
1737 (void)synchnet(peer);
1738 if (dp_block == (block - 1))
1739 goto send_ack; /* rexmit */
1742 /* size = write(file, dp->th_data, n - 4); */
1743 size = writeit(file, &dp, n - 4, pf->f_convert);
1744 if (size != (n - 4)) { /* ahem */
1745 if (size < 0)
1746 nak(errno + 100, NULL);
1747 else
1748 nak(ENOSPACE, NULL);
1749 goto abort;
1751 } while (size == segsize);
1752 write_behind(file, pf->f_convert);
1753 (void)fclose(file); /* close data file */
1755 ap->th_opcode = htons((u_short) ACK); /* send the "final" ack */
1756 ap->th_block = htons((u_short) (block));
1757 (void)send(peer, ackbuf, 4, 0);
1759 timeout_quit = 1; /* just quit on timeout */
1760 n = recv_time(peer, buf, sizeof(buf), 0, &timeout); /* normally times out and quits */
1761 timeout_quit = 0;
1763 if (n >= 4 && /* if read some data */
1764 dp_opcode == DATA && /* and got a data block */
1765 block == dp_block) { /* then my last ack was lost */
1766 (void)send(peer, ackbuf, 4, 0); /* resend final ack */
1768 abort:
1769 return;
1772 static const char *const errmsgs[] = {
1773 "Undefined error code", /* 0 - EUNDEF */
1774 "File not found", /* 1 - ENOTFOUND */
1775 "Access denied", /* 2 - EACCESS */
1776 "Disk full or allocation exceeded", /* 3 - ENOSPACE */
1777 "Illegal TFTP operation", /* 4 - EBADOP */
1778 "Unknown transfer ID", /* 5 - EBADID */
1779 "File already exists", /* 6 - EEXISTS */
1780 "No such user", /* 7 - ENOUSER */
1781 "Failure to negotiate RFC2347 options" /* 8 - EOPTNEG */
1784 #define ERR_CNT (sizeof(errmsgs)/sizeof(const char *))
1787 * Send a nak packet (error message).
1788 * Error code passed in is one of the
1789 * standard TFTP codes, or a UNIX errno
1790 * offset by 100.
1792 static void nak(int error, const char *msg)
1794 struct tftphdr *tp;
1795 int length;
1797 tp = (struct tftphdr *)buf;
1798 tp->th_opcode = htons((u_short) ERROR);
1800 if (error >= 100) {
1801 /* This is a Unix errno+100 */
1802 if (!msg)
1803 msg = strerror(error - 100);
1804 error = EUNDEF;
1805 } else {
1806 if ((unsigned)error >= ERR_CNT)
1807 error = EUNDEF;
1809 if (!msg)
1810 msg = errmsgs[error];
1813 tp->th_code = htons((u_short) error);
1815 length = strlen(msg) + 1;
1816 memcpy(tp->th_msg, msg, length);
1817 length += 4; /* Add space for header */
1819 if (verbosity >= 2) {
1820 tmp_p = (char *)inet_ntop(from.sa.sa_family, SOCKADDR_P(&from),
1821 tmpbuf, INET6_ADDRSTRLEN);
1822 if (!tmp_p) {
1823 tmp_p = tmpbuf;
1824 strcpy(tmpbuf, "???");
1826 syslog(LOG_INFO, "sending NAK (%d, %s) to %s",
1827 error, tp->th_msg, tmp_p);
1830 if (send(peer, buf, length, 0) != length)
1831 syslog(LOG_WARNING, "nak: %m");