cmd-inet/usr.sbin: remove -Wno-implicit-function-declaration
[unleashed.git] / usr / src / cmd / cmd-inet / usr.sbin / in.tftpd.c
blobfa79296469b9fd13939f70a8f53759acd24ef302
1 /*
2 * CDDL HEADER START
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
19 * CDDL HEADER END
21 * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
22 * Use is subject to license terms.
23 * Copyright (c) 2016 by Delphix. All rights reserved.
27 * Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T
28 * All Rights Reserved.
32 * University Copyright- Copyright (c) 1982, 1986, 1988
33 * The Regents of the University of California.
34 * All Rights Reserved.
36 * University Acknowledgment- Portions of this document are derived from
37 * software developed by the University of California, Berkeley, and its
38 * contributors.
42 * Trivial file transfer protocol server. A top level process runs in
43 * an infinite loop fielding new TFTP requests. A child process,
44 * communicating via a pipe with the top level process, sends delayed
45 * NAKs for those that we can't handle. A new child process is created
46 * to service each request that we can handle. The top level process
47 * exits after a period of time during which no new requests are
48 * received.
51 #include <sys/types.h>
52 #include <sys/socket.h>
53 #include <sys/wait.h>
54 #include <sys/stat.h>
55 #include <sys/time.h>
57 #include <netinet/in.h>
59 #include <arpa/inet.h>
60 #include <dirent.h>
61 #include <signal.h>
62 #include <stdio.h>
63 #include <stdlib.h>
64 #include <unistd.h>
65 #include <errno.h>
66 #include <ctype.h>
67 #include <netdb.h>
68 #include <setjmp.h>
69 #include <syslog.h>
70 #include <sys/param.h>
71 #include <fcntl.h>
72 #include <pwd.h>
73 #include <string.h>
74 #include <priv_utils.h>
75 #include "tftpcommon.h"
77 #define TIMEOUT 5
78 #define DELAY_SECS 3
79 #define DALLYSECS 60
81 #define SYSLOG_MSG(message) \
82 (syslog((((errno == ENETUNREACH) || (errno == EHOSTUNREACH) || \
83 (errno == ECONNREFUSED)) ? LOG_WARNING : LOG_ERR), message))
85 static int rexmtval = TIMEOUT;
86 static int maxtimeout = 5*TIMEOUT;
87 static int securetftp;
88 static int debug;
89 static int disable_pnp;
90 static int standalone;
91 static uid_t uid_nobody = UID_NOBODY;
92 static uid_t gid_nobody = GID_NOBODY;
93 static int reqsock = -1;
94 /* file descriptor of request socket */
95 static socklen_t fromlen;
96 static socklen_t fromplen;
97 static struct sockaddr_storage client;
98 static struct sockaddr_in6 *sin6_ptr;
99 static struct sockaddr_in *sin_ptr;
100 static struct sockaddr_in6 *from6_ptr;
101 static struct sockaddr_in *from_ptr;
102 static int addrfmly;
103 static int peer;
104 static off_t tsize;
105 static tftpbuf ackbuf;
106 static struct sockaddr_storage from;
107 static boolean_t tsize_set;
108 static pid_t child;
109 /* pid of child handling delayed replys */
110 static int delay_fd [2];
111 /* pipe for communicating with child */
112 static FILE *file;
113 static char *filename;
115 static union {
116 struct tftphdr hdr;
117 char data[SEGSIZE + 4];
118 } buf;
120 static union {
121 struct tftphdr hdr;
122 char data[SEGSIZE];
123 } oackbuf;
125 struct delay_info {
126 long timestamp; /* time request received */
127 int ecode; /* error code to return */
128 struct sockaddr_storage from; /* address of client */
131 int blocksize = SEGSIZE; /* Number of data bytes in a DATA packet */
134 * Default directory for unqualified names
135 * Used by TFTP boot procedures
137 static char *homedir = "/tftpboot";
139 struct formats {
140 char *f_mode;
141 int (*f_validate)(int);
142 void (*f_send)(struct formats *, int);
143 void (*f_recv)(struct formats *, int);
144 int f_convert;
147 static void delayed_responder(void);
148 static void tftp(struct tftphdr *, int);
149 static int validate_filename(int);
150 static void tftpd_sendfile(struct formats *, int);
151 static void tftpd_recvfile(struct formats *, int);
152 static void nak(int);
153 static char *blksize_handler(int, char *, int *);
154 static char *timeout_handler(int, char *, int *);
155 static char *tsize_handler(int, char *, int *);
157 static struct formats formats[] = {
158 { "netascii", validate_filename, tftpd_sendfile, tftpd_recvfile, 1 },
159 { "octet", validate_filename, tftpd_sendfile, tftpd_recvfile, 0 },
160 { NULL }
163 struct options {
164 char *opt_name;
165 char *(*opt_handler)(int, char *, int *);
168 static struct options options[] = {
169 { "blksize", blksize_handler },
170 { "timeout", timeout_handler },
171 { "tsize", tsize_handler },
172 { NULL }
175 static char optbuf[MAX_OPTVAL_LEN];
176 static int timeout;
177 static sigjmp_buf timeoutbuf;
180 main(int argc, char **argv)
182 struct tftphdr *tp;
183 int n;
184 int c;
185 struct passwd *pwd; /* for "nobody" entry */
186 struct in_addr ipv4addr;
187 char abuf[INET6_ADDRSTRLEN];
188 socklen_t addrlen;
190 openlog("tftpd", LOG_PID, LOG_DAEMON);
192 pwd = getpwnam("nobody");
193 if (pwd != NULL) {
194 uid_nobody = pwd->pw_uid;
195 gid_nobody = pwd->pw_gid;
198 /* Tftp will not start new executables; clear the limit set. */
199 (void) __init_daemon_priv(PU_CLEARLIMITSET, uid_nobody, gid_nobody,
200 PRIV_PROC_CHROOT, PRIV_NET_PRIVADDR, NULL);
202 /* Remove the unneeded basic privileges everywhere. */
203 (void) priv_set(PRIV_OFF, PRIV_ALLSETS, PRIV_PROC_EXEC,
204 PRIV_FILE_LINK_ANY, PRIV_PROC_INFO, PRIV_PROC_SESSION, NULL);
206 /* Remove the other privileges from E until we need them. */
207 (void) priv_set(PRIV_OFF, PRIV_EFFECTIVE, PRIV_PROC_CHROOT,
208 PRIV_NET_PRIVADDR, NULL);
210 while ((c = getopt(argc, argv, "dspST:")) != EOF)
211 switch (c) {
212 case 'd': /* enable debug */
213 debug++;
214 continue;
215 case 's': /* secure daemon */
216 securetftp = 1;
217 continue;
218 case 'p': /* disable name pnp mapping */
219 disable_pnp = 1;
220 continue;
221 case 'S':
222 standalone = 1;
223 continue;
224 case 'T':
225 rexmtval = atoi(optarg);
226 if (rexmtval <= 0 || rexmtval > MAX_TIMEOUT) {
227 (void) fprintf(stderr,
228 "%s: Invalid retransmission "
229 "timeout value: %s\n", argv[0], optarg);
230 exit(1);
232 maxtimeout = 5 * rexmtval;
233 continue;
234 case '?':
235 default:
236 usage:
237 (void) fprintf(stderr,
238 "usage: %s [-T rexmtval] [-spd] [home-directory]\n",
239 argv[0]);
240 for (; optind < argc; optind++)
241 syslog(LOG_ERR, "bad argument %s",
242 argv[optind]);
243 exit(1);
246 if (optind < argc)
247 if (optind == argc - 1 && *argv [optind] == '/')
248 homedir = argv [optind];
249 else
250 goto usage;
252 if (pipe(delay_fd) < 0) {
253 syslog(LOG_ERR, "pipe (main): %m");
254 exit(1);
257 (void) sigset(SIGCHLD, SIG_IGN); /* no zombies please */
259 if (standalone) {
260 socklen_t clientlen;
262 sin6_ptr = (struct sockaddr_in6 *)&client;
263 clientlen = sizeof (struct sockaddr_in6);
264 reqsock = socket(AF_INET6, SOCK_DGRAM, 0);
265 if (reqsock == -1) {
266 perror("socket");
267 exit(1);
269 (void) memset(&client, 0, clientlen);
270 sin6_ptr->sin6_family = AF_INET6;
271 sin6_ptr->sin6_port = htons(IPPORT_TFTP);
273 /* Enable privilege as tftp port is < 1024 */
274 (void) priv_set(PRIV_ON,
275 PRIV_EFFECTIVE, PRIV_NET_PRIVADDR, NULL);
276 if (bind(reqsock, (struct sockaddr *)&client,
277 clientlen) == -1) {
278 perror("bind");
279 exit(1);
281 (void) priv_set(PRIV_OFF, PRIV_EFFECTIVE, PRIV_NET_PRIVADDR,
282 NULL);
284 if (debug)
285 (void) puts("running in standalone mode...");
286 } else {
287 /* request socket passed on fd 0 by inetd */
288 reqsock = 0;
290 if (debug) {
291 int on = 1;
293 (void) setsockopt(reqsock, SOL_SOCKET, SO_DEBUG,
294 (char *)&on, sizeof (on));
297 (void) chdir(homedir);
299 (void) priv_set(PRIV_ON, PRIV_EFFECTIVE, PRIV_PROC_FORK, NULL);
300 if ((child = fork()) < 0) {
301 syslog(LOG_ERR, "fork (main): %m");
302 exit(1);
304 (void) priv_set(PRIV_OFF, PRIV_EFFECTIVE, PRIV_PROC_FORK, NULL);
306 if (child == 0) {
307 delayed_responder();
308 } /* child */
310 /* close read side of pipe */
311 (void) close(delay_fd[0]);
315 * Top level handling of incomming tftp requests. Read a request
316 * and pass it off to be handled. If request is valid, handling
317 * forks off and parent returns to this loop. If no new requests
318 * are received for DALLYSECS, exit and return to inetd.
321 for (;;) {
322 fd_set readfds;
323 struct timeval dally;
325 FD_ZERO(&readfds);
326 FD_SET(reqsock, &readfds);
327 dally.tv_sec = DALLYSECS;
328 dally.tv_usec = 0;
330 n = select(reqsock + 1, &readfds, NULL, NULL, &dally);
331 if (n < 0) {
332 if (errno == EINTR)
333 continue;
334 syslog(LOG_ERR, "select: %m");
335 (void) kill(child, SIGKILL);
336 exit(1);
338 if (n == 0) {
339 /* Select timed out. Its time to die. */
340 if (standalone)
341 continue;
342 else {
343 (void) kill(child, SIGKILL);
344 exit(0);
347 addrlen = sizeof (from);
348 if (getsockname(reqsock, (struct sockaddr *)&from,
349 &addrlen) < 0) {
350 syslog(LOG_ERR, "getsockname: %m");
351 exit(1);
354 switch (from.ss_family) {
355 case AF_INET:
356 fromlen = (socklen_t)sizeof (struct sockaddr_in);
357 break;
358 case AF_INET6:
359 fromlen = (socklen_t)sizeof (struct sockaddr_in6);
360 break;
361 default:
362 syslog(LOG_ERR,
363 "Unknown address Family on peer connection %d",
364 from.ss_family);
365 exit(1);
368 n = recvfrom(reqsock, &buf, sizeof (buf), 0,
369 (struct sockaddr *)&from, &fromlen);
370 if (n < 0) {
371 if (errno == EINTR)
372 continue;
373 if (standalone)
374 perror("recvfrom");
375 else
376 syslog(LOG_ERR, "recvfrom: %m");
377 (void) kill(child, SIGKILL);
378 exit(1);
381 (void) alarm(0);
383 switch (from.ss_family) {
384 case AF_INET:
385 addrfmly = AF_INET;
386 fromplen = sizeof (struct sockaddr_in);
387 sin_ptr = (struct sockaddr_in *)&client;
388 (void) memset(&client, 0, fromplen);
389 sin_ptr->sin_family = AF_INET;
390 break;
391 case AF_INET6:
392 addrfmly = AF_INET6;
393 fromplen = sizeof (struct sockaddr_in6);
394 sin6_ptr = (struct sockaddr_in6 *)&client;
395 (void) memset(&client, 0, fromplen);
396 sin6_ptr->sin6_family = AF_INET6;
397 break;
398 default:
399 syslog(LOG_ERR,
400 "Unknown address Family on peer connection");
401 exit(1);
403 peer = socket(addrfmly, SOCK_DGRAM, 0);
404 if (peer < 0) {
405 if (standalone)
406 perror("socket (main)");
407 else
408 syslog(LOG_ERR, "socket (main): %m");
409 (void) kill(child, SIGKILL);
410 exit(1);
412 if (debug) {
413 int on = 1;
415 (void) setsockopt(peer, SOL_SOCKET, SO_DEBUG,
416 (char *)&on, sizeof (on));
419 if (bind(peer, (struct sockaddr *)&client, fromplen) < 0) {
420 if (standalone)
421 perror("bind (main)");
422 else
423 syslog(LOG_ERR, "bind (main): %m");
424 (void) kill(child, SIGKILL);
425 exit(1);
427 if (standalone && debug) {
428 sin6_ptr = (struct sockaddr_in6 *)&client;
429 from6_ptr = (struct sockaddr_in6 *)&from;
430 if (IN6_IS_ADDR_V4MAPPED(&from6_ptr->sin6_addr)) {
431 IN6_V4MAPPED_TO_INADDR(&from6_ptr->sin6_addr,
432 &ipv4addr);
433 (void) inet_ntop(AF_INET, &ipv4addr, abuf,
434 sizeof (abuf));
435 } else {
436 (void) inet_ntop(AF_INET6,
437 &from6_ptr->sin6_addr, abuf,
438 sizeof (abuf));
440 /* get local port */
441 if (getsockname(peer, (struct sockaddr *)&client,
442 &fromplen) < 0)
443 perror("getsockname (main)");
444 (void) fprintf(stderr,
445 "request from %s port %d; local port %d\n",
446 abuf, from6_ptr->sin6_port, sin6_ptr->sin6_port);
448 tp = &buf.hdr;
449 tp->th_opcode = ntohs((ushort_t)tp->th_opcode);
450 if (tp->th_opcode == RRQ || tp->th_opcode == WRQ)
451 tftp(tp, n);
453 (void) close(peer);
454 (void) fclose(file);
457 /*NOTREACHED*/
458 return (0);
461 static void
462 delayed_responder(void)
464 struct delay_info dinfo;
465 long now;
467 /* we don't use the descriptors passed in to the parent */
468 (void) close(0);
469 (void) close(1);
470 if (standalone)
471 (void) close(reqsock);
473 /* close write side of pipe */
474 (void) close(delay_fd[1]);
476 for (;;) {
477 int n;
479 if ((n = read(delay_fd[0], &dinfo,
480 sizeof (dinfo))) != sizeof (dinfo)) {
481 if (n < 0) {
482 if (errno == EINTR)
483 continue;
484 if (standalone)
485 perror("read from pipe "
486 "(delayed responder)");
487 else
488 syslog(LOG_ERR, "read from pipe: %m");
490 exit(1);
492 switch (dinfo.from.ss_family) {
493 case AF_INET:
494 addrfmly = AF_INET;
495 fromplen = sizeof (struct sockaddr_in);
496 sin_ptr = (struct sockaddr_in *)&client;
497 (void) memset(&client, 0, fromplen);
498 sin_ptr->sin_family = AF_INET;
499 break;
500 case AF_INET6:
501 addrfmly = AF_INET6;
502 fromplen = sizeof (struct sockaddr_in6);
503 sin6_ptr = (struct sockaddr_in6 *)&client;
504 (void) memset(&client, 0, fromplen);
505 sin6_ptr->sin6_family = AF_INET6;
506 break;
508 peer = socket(addrfmly, SOCK_DGRAM, 0);
509 if (peer == -1) {
510 if (standalone)
511 perror("socket (delayed responder)");
512 else
513 syslog(LOG_ERR, "socket (delay): %m");
514 exit(1);
516 if (debug) {
517 int on = 1;
519 (void) setsockopt(peer, SOL_SOCKET, SO_DEBUG,
520 (char *)&on, sizeof (on));
523 if (bind(peer, (struct sockaddr *)&client, fromplen) < 0) {
524 if (standalone)
525 perror("bind (delayed responder)");
526 else
527 syslog(LOG_ERR, "bind (delay): %m");
528 exit(1);
530 if (client.ss_family == AF_INET) {
531 from_ptr = (struct sockaddr_in *)&dinfo.from;
532 from_ptr->sin_family = AF_INET;
533 } else {
534 from6_ptr = (struct sockaddr_in6 *)&dinfo.from;
535 from6_ptr->sin6_family = AF_INET6;
538 * Since a request hasn't been received from the client
539 * before the delayed responder process is forked, the
540 * from variable is uninitialized. So set it to contain
541 * the client address.
543 from = dinfo.from;
546 * only sleep if DELAY_SECS has not elapsed since
547 * original request was received. Ensure that `now'
548 * is not earlier than `dinfo.timestamp'
550 now = time(0);
551 if ((uint_t)(now - dinfo.timestamp) < DELAY_SECS)
552 (void) sleep(DELAY_SECS - (now - dinfo.timestamp));
553 nak(dinfo.ecode);
554 (void) close(peer);
555 } /* for */
557 /* NOTREACHED */
561 * Handle the Blocksize option.
562 * Return the blksize option value string to include in the OACK reply.
564 /*ARGSUSED*/
565 static char *
566 blksize_handler(int opcode, char *optval, int *errcode)
568 char *endp;
569 int value;
571 *errcode = -1;
572 errno = 0;
573 value = (int)strtol(optval, &endp, 10);
574 if (errno != 0 || value < MIN_BLKSIZE || *endp != '\0')
575 return (NULL);
577 * As the blksize value in the OACK reply can be less than the value
578 * requested, to support broken clients if the value requested is larger
579 * than allowed in the RFC, reply with the maximum value permitted.
581 if (value > MAX_BLKSIZE)
582 value = MAX_BLKSIZE;
584 blocksize = value;
585 (void) snprintf(optbuf, sizeof (optbuf), "%d", blocksize);
586 return (optbuf);
590 * Handle the Timeout Interval option.
591 * Return the timeout option value string to include in the OACK reply.
593 /*ARGSUSED*/
594 static char *
595 timeout_handler(int opcode, char *optval, int *errcode)
597 char *endp;
598 int value;
600 *errcode = -1;
601 errno = 0;
602 value = (int)strtol(optval, &endp, 10);
603 if (errno != 0 || *endp != '\0')
604 return (NULL);
606 * The timeout value in the OACK reply must match the value specified
607 * by the client, so if an invalid timeout is requested don't include
608 * the timeout option in the OACK reply.
610 if (value < MIN_TIMEOUT || value > MAX_TIMEOUT)
611 return (NULL);
613 rexmtval = value;
614 maxtimeout = 5 * rexmtval;
615 (void) snprintf(optbuf, sizeof (optbuf), "%d", rexmtval);
616 return (optbuf);
620 * Handle the Transfer Size option.
621 * Return the tsize option value string to include in the OACK reply.
623 static char *
624 tsize_handler(int opcode, char *optval, int *errcode)
626 char *endp;
627 longlong_t value;
629 *errcode = -1;
630 errno = 0;
631 value = strtoll(optval, &endp, 10);
632 if (errno != 0 || value < 0 || *endp != '\0')
633 return (NULL);
635 if (opcode == RRQ) {
636 if (tsize_set == B_FALSE)
637 return (NULL);
639 * The tsize value should be 0 for a read request, but to
640 * support broken clients we don't check that it is.
642 } else {
643 #if _FILE_OFFSET_BITS == 32
644 if (value > MAXOFF_T) {
645 *errcode = ENOSPACE;
646 return (NULL);
648 #endif
649 tsize = value;
650 tsize_set = B_TRUE;
652 (void) snprintf(optbuf, sizeof (optbuf), OFF_T_FMT, tsize);
653 return (optbuf);
657 * Process any options included by the client in the request packet.
658 * Return the size of the OACK reply packet built or 0 for no OACK reply.
660 static int
661 process_options(int opcode, char *opts, char *endopts)
663 char *cp, *optname, *optval, *ostr, *oackend;
664 struct tftphdr *oackp;
665 int i, errcode;
668 * To continue to interoperate with broken TFTP clients, ignore
669 * null padding appended to requests which don't include options.
671 cp = opts;
672 while ((cp < endopts) && (*cp == '\0'))
673 cp++;
674 if (cp == endopts)
675 return (0);
678 * Construct an Option ACKnowledgement packet if any requested option
679 * is recognized.
681 oackp = &oackbuf.hdr;
682 oackend = oackbuf.data + sizeof (oackbuf.data);
683 oackp->th_opcode = htons((ushort_t)OACK);
684 cp = (char *)&oackp->th_stuff;
685 while (opts < endopts) {
686 optname = opts;
687 if ((optval = next_field(optname, endopts)) == NULL) {
688 nak(EOPTNEG);
689 exit(1);
691 if ((opts = next_field(optval, endopts)) == NULL) {
692 nak(EOPTNEG);
693 exit(1);
695 for (i = 0; options[i].opt_name != NULL; i++) {
696 if (strcasecmp(optname, options[i].opt_name) == 0)
697 break;
699 if (options[i].opt_name != NULL) {
700 ostr = options[i].opt_handler(opcode, optval, &errcode);
701 if (ostr != NULL) {
702 cp += strlcpy(cp, options[i].opt_name,
703 oackend - cp) + 1;
704 if (cp <= oackend)
705 cp += strlcpy(cp, ostr, oackend - cp)
706 + 1;
708 if (cp > oackend) {
709 nak(EOPTNEG);
710 exit(1);
712 } else if (errcode >= 0) {
713 nak(errcode);
714 exit(1);
718 if (cp != (char *)&oackp->th_stuff)
719 return (cp - oackbuf.data);
720 return (0);
724 * Handle access errors caused by client requests.
727 static void
728 delay_exit(int ecode)
730 struct delay_info dinfo;
733 * The most likely cause of an error here is that
734 * something has broadcast an RRQ packet because it's
735 * trying to boot and doesn't know who the server is.
736 * Rather then sending an ERROR packet immediately, we
737 * wait a while so that the real server has a better chance
738 * of getting through (in case client has lousy Ethernet
739 * interface). We write to a child that handles delayed
740 * ERROR packets to avoid delaying service to new
741 * requests. Of course, we would rather just not answer
742 * RRQ packets that are broadcasted, but there's no way
743 * for a user process to determine this.
746 dinfo.timestamp = time(0);
749 * If running in secure mode, we map all errors to EACCESS
750 * so that the client gets no information about which files
751 * or directories exist.
753 if (securetftp)
754 dinfo.ecode = EACCESS;
755 else
756 dinfo.ecode = ecode;
758 dinfo.from = from;
759 if (write(delay_fd[1], &dinfo, sizeof (dinfo)) !=
760 sizeof (dinfo)) {
761 syslog(LOG_ERR, "delayed write failed.");
762 (void) kill(child, SIGKILL);
763 exit(1);
765 exit(0);
769 * Handle initial connection protocol.
771 static void
772 tftp(struct tftphdr *tp, int size)
774 char *cp;
775 int readmode, ecode;
776 struct formats *pf;
777 char *mode;
778 int fd;
779 static boolean_t firsttime = B_TRUE;
780 int oacklen;
781 struct stat statb;
783 readmode = (tp->th_opcode == RRQ);
784 filename = (char *)&tp->th_stuff;
785 mode = next_field(filename, &buf.data[size]);
786 cp = (mode != NULL) ? next_field(mode, &buf.data[size]) : NULL;
787 if (cp == NULL) {
788 nak(EBADOP);
789 exit(1);
791 if (debug && standalone) {
792 (void) fprintf(stderr, "%s for %s %s ",
793 readmode ? "RRQ" : "WRQ", filename, mode);
794 print_options(stderr, cp, size + buf.data - cp);
795 (void) putc('\n', stderr);
797 for (pf = formats; pf->f_mode != NULL; pf++)
798 if (strcasecmp(pf->f_mode, mode) == 0)
799 break;
800 if (pf->f_mode == NULL) {
801 nak(EBADOP);
802 exit(1);
806 * XXX fork a new process to handle this request before
807 * chroot(), otherwise the parent won't be able to create a
808 * new socket as that requires library access to system files
809 * and devices.
811 (void) priv_set(PRIV_ON, PRIV_EFFECTIVE, PRIV_PROC_FORK, NULL);
812 switch (fork()) {
813 case -1:
814 syslog(LOG_ERR, "fork (tftp): %m");
815 (void) priv_set(PRIV_OFF, PRIV_EFFECTIVE, PRIV_PROC_FORK, NULL);
816 return;
817 case 0:
818 (void) priv_set(PRIV_OFF, PRIV_EFFECTIVE, PRIV_PROC_FORK, NULL);
819 break;
820 default:
821 (void) priv_set(PRIV_OFF, PRIV_EFFECTIVE, PRIV_PROC_FORK, NULL);
822 return;
826 * Try to see if we can access the file. The access can still
827 * fail later if we are running in secure mode because of
828 * the chroot() call. We only want to execute the chroot() once.
830 if (securetftp && firsttime) {
831 (void) priv_set(PRIV_ON, PRIV_EFFECTIVE, PRIV_PROC_CHROOT,
832 NULL);
833 if (chroot(homedir) == -1) {
834 syslog(LOG_ERR,
835 "tftpd: cannot chroot to directory %s: %m\n",
836 homedir);
837 delay_exit(EACCESS);
839 else
841 firsttime = B_FALSE;
843 (void) priv_set(PRIV_OFF, PRIV_EFFECTIVE, PRIV_PROC_CHROOT,
844 NULL);
845 (void) chdir("/"); /* cd to new root */
847 (void) priv_set(PRIV_OFF, PRIV_ALLSETS, PRIV_PROC_CHROOT,
848 PRIV_NET_PRIVADDR, NULL);
850 ecode = (*pf->f_validate)(tp->th_opcode);
851 if (ecode != 0)
852 delay_exit(ecode);
854 /* we don't use the descriptors passed in to the parent */
855 (void) close(STDIN_FILENO);
856 (void) close(STDOUT_FILENO);
859 * Try to open file as low-priv setuid/setgid. Note that
860 * a chroot() has already been done.
862 fd = open(filename,
863 (readmode ? O_RDONLY : (O_WRONLY|O_TRUNC)) | O_NONBLOCK);
864 if ((fd < 0) || (fstat(fd, &statb) < 0))
865 delay_exit((errno == ENOENT) ? ENOTFOUND : EACCESS);
867 if (((statb.st_mode & ((readmode) ? S_IROTH : S_IWOTH)) == 0) ||
868 ((statb.st_mode & S_IFMT) != S_IFREG))
869 delay_exit(EACCESS);
871 file = fdopen(fd, readmode ? "r" : "w");
872 if (file == NULL)
873 delay_exit(errno + 100);
875 /* Don't know the size of transfers which involve conversion */
876 tsize_set = (readmode && (pf->f_convert == 0));
877 if (tsize_set)
878 tsize = statb.st_size;
880 /* Deal with any options sent by the client */
881 oacklen = process_options(tp->th_opcode, cp, buf.data + size);
883 if (tp->th_opcode == WRQ)
884 (*pf->f_recv)(pf, oacklen);
885 else
886 (*pf->f_send)(pf, oacklen);
888 exit(0);
892 * Maybe map filename into another one.
894 * For PNP, we get TFTP boot requests for filenames like
895 * <Unknown Hex IP Addr>.<Architecture Name>. We must
896 * map these to 'pnp.<Architecture Name>'. Note that
897 * uppercase is mapped to lowercase in the architecture names.
899 * For names <Hex IP Addr> there are two cases. First,
900 * it may be a buggy prom that omits the architecture code.
901 * So first check if <Hex IP Addr>.<arch> is on the filesystem.
902 * Second, this is how most Sun3s work; assume <arch> is sun3.
905 static char *
906 pnp_check(char *origname)
908 static char buf [MAXNAMLEN + 1];
909 char *arch, *s, *bufend;
910 in_addr_t ipaddr;
911 int len = (origname ? strlen(origname) : 0);
912 DIR *dir;
913 struct dirent *dp;
915 if (securetftp || disable_pnp || len < 8 || len > 14)
916 return (NULL);
919 * XXX see if this cable allows pnp; if not, return NULL
920 * Requires YP support for determining this!
923 ipaddr = htonl(strtol(origname, &arch, 16));
924 if ((arch == NULL) || (len > 8 && *arch != '.'))
925 return (NULL);
926 if (len == 8)
927 arch = "SUN3";
928 else
929 arch++;
932 * Allow <Hex IP Addr>* filename request to to be
933 * satisfied by <Hex IP Addr><Any Suffix> rather
934 * than enforcing this to be Sun3 systems. Also serves
935 * to make case of suffix a don't-care.
937 if ((dir = opendir(homedir)) == NULL)
938 return (NULL);
939 while ((dp = readdir(dir)) != NULL) {
940 if (strncmp(origname, dp->d_name, 8) == 0) {
941 (void) strlcpy(buf, dp->d_name, sizeof (buf));
942 (void) closedir(dir);
943 return (buf);
946 (void) closedir(dir);
949 * XXX maybe call YP master for most current data iff
950 * pnp is enabled.
954 * only do mapping PNP boot file name for machines that
955 * are not in the hosts database.
957 if (gethostbyaddr((char *)&ipaddr, sizeof (ipaddr), AF_INET) != NULL)
958 return (NULL);
960 s = buf + strlcpy(buf, "pnp.", sizeof (buf));
961 bufend = &buf[sizeof (buf) - 1];
962 while ((*arch != '\0') && (s < bufend))
963 *s++ = tolower (*arch++);
964 *s = '\0';
965 return (buf);
970 * Try to validate filename. If the filename doesn't exist try PNP mapping.
972 static int
973 validate_filename(int mode)
975 struct stat stbuf;
976 char *origfile;
978 if (stat(filename, &stbuf) < 0) {
979 if (errno != ENOENT)
980 return (EACCESS);
981 if (mode == WRQ)
982 return (ENOTFOUND);
984 /* try to map requested filename into a pnp filename */
985 origfile = filename;
986 filename = pnp_check(origfile);
987 if (filename == NULL)
988 return (ENOTFOUND);
990 if (stat(filename, &stbuf) < 0)
991 return (errno == ENOENT ? ENOTFOUND : EACCESS);
992 syslog(LOG_NOTICE, "%s -> %s\n", origfile, filename);
995 return (0);
998 /* ARGSUSED */
999 static void
1000 timer(int signum)
1002 timeout += rexmtval;
1003 if (timeout >= maxtimeout)
1004 exit(1);
1005 siglongjmp(timeoutbuf, 1);
1009 * Send the requested file.
1011 static void
1012 tftpd_sendfile(struct formats *pf, int oacklen)
1014 struct tftphdr *dp;
1015 volatile ushort_t block = 1;
1016 int size, n, serrno;
1018 if (oacklen != 0) {
1019 (void) sigset(SIGALRM, timer);
1020 timeout = 0;
1021 (void) sigsetjmp(timeoutbuf, 1);
1022 if (debug && standalone) {
1023 (void) fputs("Sending OACK ", stderr);
1024 print_options(stderr, (char *)&oackbuf.hdr.th_stuff,
1025 oacklen - 2);
1026 (void) putc('\n', stderr);
1028 if (sendto(peer, &oackbuf, oacklen, 0,
1029 (struct sockaddr *)&from, fromplen) != oacklen) {
1030 if (debug && standalone) {
1031 serrno = errno;
1032 perror("sendto (oack)");
1033 errno = serrno;
1035 SYSLOG_MSG("sendto (oack): %m");
1036 goto abort;
1038 (void) alarm(rexmtval); /* read the ack */
1039 for (;;) {
1040 (void) sigrelse(SIGALRM);
1041 n = recv(peer, &ackbuf, sizeof (ackbuf), 0);
1042 (void) sighold(SIGALRM);
1043 if (n < 0) {
1044 if (errno == EINTR)
1045 continue;
1046 serrno = errno;
1047 SYSLOG_MSG("recv (ack): %m");
1048 if (debug && standalone) {
1049 errno = serrno;
1050 perror("recv (ack)");
1052 goto abort;
1054 ackbuf.tb_hdr.th_opcode =
1055 ntohs((ushort_t)ackbuf.tb_hdr.th_opcode);
1056 ackbuf.tb_hdr.th_block =
1057 ntohs((ushort_t)ackbuf.tb_hdr.th_block);
1059 if (ackbuf.tb_hdr.th_opcode == ERROR) {
1060 if (debug && standalone) {
1061 (void) fprintf(stderr,
1062 "received ERROR %d",
1063 ackbuf.tb_hdr.th_code);
1064 if (n > 4)
1065 (void) fprintf(stderr,
1066 " %.*s", n - 4,
1067 ackbuf.tb_hdr.th_msg);
1068 (void) putc('\n', stderr);
1070 goto abort;
1073 if (ackbuf.tb_hdr.th_opcode == ACK) {
1074 if (debug && standalone)
1075 (void) fprintf(stderr,
1076 "received ACK for block %d\n",
1077 ackbuf.tb_hdr.th_block);
1078 if (ackbuf.tb_hdr.th_block == 0)
1079 break;
1081 * Don't resend the OACK, avoids getting stuck
1082 * in an OACK/ACK loop if the client keeps
1083 * replying with a bad ACK. Client will either
1084 * send a good ACK or timeout sending bad ones.
1088 cancel_alarm();
1090 dp = r_init();
1091 do {
1092 (void) sigset(SIGALRM, timer);
1093 size = readit(file, &dp, pf->f_convert);
1094 if (size < 0) {
1095 nak(errno + 100);
1096 goto abort;
1098 dp->th_opcode = htons((ushort_t)DATA);
1099 dp->th_block = htons((ushort_t)block);
1100 timeout = 0;
1101 (void) sigsetjmp(timeoutbuf, 1);
1102 if (debug && standalone)
1103 (void) fprintf(stderr, "Sending DATA block %d\n",
1104 block);
1105 if (sendto(peer, dp, size + 4, 0,
1106 (struct sockaddr *)&from, fromplen) != size + 4) {
1107 if (debug && standalone) {
1108 serrno = errno;
1109 perror("sendto (data)");
1110 errno = serrno;
1112 SYSLOG_MSG("sendto (data): %m");
1113 goto abort;
1115 read_ahead(file, pf->f_convert);
1116 (void) alarm(rexmtval); /* read the ack */
1117 for (;;) {
1118 (void) sigrelse(SIGALRM);
1119 n = recv(peer, &ackbuf, sizeof (ackbuf), 0);
1120 (void) sighold(SIGALRM);
1121 if (n < 0) {
1122 if (errno == EINTR)
1123 continue;
1124 serrno = errno;
1125 SYSLOG_MSG("recv (ack): %m");
1126 if (debug && standalone) {
1127 errno = serrno;
1128 perror("recv (ack)");
1130 goto abort;
1132 ackbuf.tb_hdr.th_opcode =
1133 ntohs((ushort_t)ackbuf.tb_hdr.th_opcode);
1134 ackbuf.tb_hdr.th_block =
1135 ntohs((ushort_t)ackbuf.tb_hdr.th_block);
1137 if (ackbuf.tb_hdr.th_opcode == ERROR) {
1138 if (debug && standalone) {
1139 (void) fprintf(stderr,
1140 "received ERROR %d",
1141 ackbuf.tb_hdr.th_code);
1142 if (n > 4)
1143 (void) fprintf(stderr,
1144 " %.*s", n - 4,
1145 ackbuf.tb_hdr.th_msg);
1146 (void) putc('\n', stderr);
1148 goto abort;
1151 if (ackbuf.tb_hdr.th_opcode == ACK) {
1152 if (debug && standalone)
1153 (void) fprintf(stderr,
1154 "received ACK for block %d\n",
1155 ackbuf.tb_hdr.th_block);
1156 if (ackbuf.tb_hdr.th_block == block) {
1157 break;
1160 * Never resend the current DATA packet on
1161 * receipt of a duplicate ACK, doing so would
1162 * cause the "Sorcerer's Apprentice Syndrome".
1166 cancel_alarm();
1167 block++;
1168 } while (size == blocksize);
1170 abort:
1171 cancel_alarm();
1172 (void) fclose(file);
1175 /* ARGSUSED */
1176 static void
1177 justquit(int signum)
1179 exit(0);
1183 * Receive a file.
1185 static void
1186 tftpd_recvfile(struct formats *pf, int oacklen)
1188 struct tftphdr *dp;
1189 struct tftphdr *ap; /* ack buffer */
1190 ushort_t block = 0;
1191 int n, size, acklen, serrno;
1193 dp = w_init();
1194 ap = &ackbuf.tb_hdr;
1195 do {
1196 (void) sigset(SIGALRM, timer);
1197 timeout = 0;
1198 if (oacklen == 0) {
1199 ap->th_opcode = htons((ushort_t)ACK);
1200 ap->th_block = htons((ushort_t)block);
1201 acklen = 4;
1202 } else {
1203 /* copy OACK packet to the ack buffer ready to send */
1204 (void) memcpy(&ackbuf, &oackbuf, oacklen);
1205 acklen = oacklen;
1206 oacklen = 0;
1208 block++;
1209 (void) sigsetjmp(timeoutbuf, 1);
1210 send_ack:
1211 if (debug && standalone) {
1212 if (ap->th_opcode == htons((ushort_t)ACK)) {
1213 (void) fprintf(stderr,
1214 "Sending ACK for block %d\n", block - 1);
1215 } else {
1216 (void) fprintf(stderr, "Sending OACK ");
1217 print_options(stderr, (char *)&ap->th_stuff,
1218 acklen - 2);
1219 (void) putc('\n', stderr);
1222 if (sendto(peer, &ackbuf, acklen, 0, (struct sockaddr *)&from,
1223 fromplen) != acklen) {
1224 if (ap->th_opcode == htons((ushort_t)ACK)) {
1225 if (debug && standalone) {
1226 serrno = errno;
1227 perror("sendto (ack)");
1228 errno = serrno;
1230 syslog(LOG_ERR, "sendto (ack): %m\n");
1231 } else {
1232 if (debug && standalone) {
1233 serrno = errno;
1234 perror("sendto (oack)");
1235 errno = serrno;
1237 syslog(LOG_ERR, "sendto (oack): %m\n");
1239 goto abort;
1241 if (write_behind(file, pf->f_convert) < 0) {
1242 nak(errno + 100);
1243 goto abort;
1245 (void) alarm(rexmtval);
1246 for (;;) {
1247 (void) sigrelse(SIGALRM);
1248 n = recv(peer, dp, blocksize + 4, 0);
1249 (void) sighold(SIGALRM);
1250 if (n < 0) { /* really? */
1251 if (errno == EINTR)
1252 continue;
1253 syslog(LOG_ERR, "recv (data): %m");
1254 goto abort;
1256 dp->th_opcode = ntohs((ushort_t)dp->th_opcode);
1257 dp->th_block = ntohs((ushort_t)dp->th_block);
1258 if (dp->th_opcode == ERROR) {
1259 cancel_alarm();
1260 if (debug && standalone) {
1261 (void) fprintf(stderr,
1262 "received ERROR %d", dp->th_code);
1263 if (n > 4)
1264 (void) fprintf(stderr,
1265 " %.*s", n - 4, dp->th_msg);
1266 (void) putc('\n', stderr);
1268 return;
1270 if (dp->th_opcode == DATA) {
1271 if (debug && standalone)
1272 (void) fprintf(stderr,
1273 "Received DATA block %d\n",
1274 dp->th_block);
1275 if (dp->th_block == block) {
1276 break; /* normal */
1278 /* Re-synchronize with the other side */
1279 if (synchnet(peer) < 0) {
1280 nak(errno + 100);
1281 goto abort;
1283 if (dp->th_block == (block-1))
1284 goto send_ack; /* rexmit */
1287 cancel_alarm();
1288 /* size = write(file, dp->th_data, n - 4); */
1289 size = writeit(file, &dp, n - 4, pf->f_convert);
1290 if (size != (n - 4)) {
1291 nak((size < 0) ? (errno + 100) : ENOSPACE);
1292 goto abort;
1294 } while (size == blocksize);
1295 if (write_behind(file, pf->f_convert) < 0) {
1296 nak(errno + 100);
1297 goto abort;
1299 n = fclose(file); /* close data file */
1300 file = NULL;
1301 if (n == EOF) {
1302 nak(errno + 100);
1303 goto abort;
1306 ap->th_opcode = htons((ushort_t)ACK); /* send the "final" ack */
1307 ap->th_block = htons((ushort_t)(block));
1308 if (debug && standalone)
1309 (void) fprintf(stderr, "Sending ACK for block %d\n", block);
1310 if (sendto(peer, &ackbuf, 4, 0, (struct sockaddr *)&from,
1311 fromplen) == -1) {
1312 if (debug && standalone)
1313 perror("sendto (ack)");
1315 (void) sigset(SIGALRM, justquit); /* just quit on timeout */
1316 (void) alarm(rexmtval);
1317 /* normally times out and quits */
1318 n = recv(peer, dp, blocksize + 4, 0);
1319 (void) alarm(0);
1320 dp->th_opcode = ntohs((ushort_t)dp->th_opcode);
1321 dp->th_block = ntohs((ushort_t)dp->th_block);
1322 if (n >= 4 && /* if read some data */
1323 dp->th_opcode == DATA && /* and got a data block */
1324 block == dp->th_block) { /* then my last ack was lost */
1325 if (debug && standalone) {
1326 (void) fprintf(stderr, "Sending ACK for block %d\n",
1327 block);
1329 /* resend final ack */
1330 if (sendto(peer, &ackbuf, 4, 0, (struct sockaddr *)&from,
1331 fromplen) == -1) {
1332 if (debug && standalone)
1333 perror("sendto (last ack)");
1337 abort:
1338 cancel_alarm();
1339 if (file != NULL)
1340 (void) fclose(file);
1344 * Send a nak packet (error message).
1345 * Error code passed in is one of the
1346 * standard TFTP codes, or a UNIX errno
1347 * offset by 100.
1348 * Handles connected as well as unconnected peer.
1350 static void
1351 nak(int error)
1353 struct tftphdr *tp;
1354 int length;
1355 struct errmsg *pe;
1356 int ret;
1358 tp = &buf.hdr;
1359 tp->th_opcode = htons((ushort_t)ERROR);
1360 tp->th_code = htons((ushort_t)error);
1361 for (pe = errmsgs; pe->e_code >= 0; pe++)
1362 if (pe->e_code == error)
1363 break;
1364 if (pe->e_code < 0) {
1365 pe->e_msg = strerror(error - 100);
1366 tp->th_code = EUNDEF; /* set 'undef' errorcode */
1368 (void) strlcpy(tp->th_msg, (pe->e_msg != NULL) ? pe->e_msg : "UNKNOWN",
1369 sizeof (buf) - sizeof (struct tftphdr));
1370 length = strlen(tp->th_msg);
1371 length += sizeof (struct tftphdr);
1372 if (debug && standalone)
1373 (void) fprintf(stderr, "Sending NAK: %s\n", tp->th_msg);
1375 ret = sendto(peer, &buf, length, 0, (struct sockaddr *)&from,
1376 fromplen);
1377 if (ret == -1 && errno == EISCONN) {
1378 /* Try without an address */
1379 ret = send(peer, &buf, length, 0);
1381 if (ret == -1) {
1382 if (standalone)
1383 perror("sendto (nak)");
1384 else
1385 syslog(LOG_ERR, "tftpd: nak: %m\n");
1386 } else if (ret != length) {
1387 if (standalone)
1388 perror("sendto (nak) lost data");
1389 else
1390 syslog(LOG_ERR, "tftpd: nak: %d lost\n", length - ret);