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