ftpd.c revision 325472
1/*
2 * Copyright (c) 1985, 1988, 1990, 1992, 1993, 1994
3 *	The Regents of the University of California.  All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 *    notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 *    notice, this list of conditions and the following disclaimer in the
12 *    documentation and/or other materials provided with the distribution.
13 * 3. Neither the name of the University nor the names of its contributors
14 *    may be used to endorse or promote products derived from this software
15 *    without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 */
29
30#if 0
31#ifndef lint
32static char copyright[] =
33"@(#) Copyright (c) 1985, 1988, 1990, 1992, 1993, 1994\n\
34	The Regents of the University of California.  All rights reserved.\n";
35#endif /* not lint */
36#endif
37
38#ifndef lint
39#if 0
40static char sccsid[] = "@(#)ftpd.c	8.4 (Berkeley) 4/16/94";
41#endif
42#endif /* not lint */
43
44#include <sys/cdefs.h>
45__FBSDID("$FreeBSD: stable/10/libexec/ftpd/ftpd.c 325472 2017-11-06 11:11:44Z eugen $");
46
47/*
48 * FTP server.
49 */
50#include <sys/param.h>
51#include <sys/ioctl.h>
52#include <sys/mman.h>
53#include <sys/socket.h>
54#include <sys/stat.h>
55#include <sys/time.h>
56#include <sys/wait.h>
57
58#include <netinet/in.h>
59#include <netinet/in_systm.h>
60#include <netinet/ip.h>
61#include <netinet/tcp.h>
62
63#define	FTP_NAMES
64#include <arpa/ftp.h>
65#include <arpa/inet.h>
66#include <arpa/telnet.h>
67
68#include <ctype.h>
69#include <dirent.h>
70#include <err.h>
71#include <errno.h>
72#include <fcntl.h>
73#include <glob.h>
74#include <limits.h>
75#include <netdb.h>
76#include <pwd.h>
77#include <grp.h>
78#include <opie.h>
79#include <signal.h>
80#include <stdint.h>
81#include <stdio.h>
82#include <stdlib.h>
83#include <string.h>
84#include <syslog.h>
85#include <time.h>
86#include <unistd.h>
87#include <libutil.h>
88#ifdef	LOGIN_CAP
89#include <login_cap.h>
90#endif
91
92#ifdef USE_PAM
93#include <security/pam_appl.h>
94#endif
95
96#include "pathnames.h"
97#include "extern.h"
98
99#include <stdarg.h>
100
101static char version[] = "Version 6.00LS";
102#undef main
103
104union sockunion ctrl_addr;
105union sockunion data_source;
106union sockunion data_dest;
107union sockunion his_addr;
108union sockunion pasv_addr;
109
110int	daemon_mode;
111int	data;
112int	dataport;
113int	hostinfo = 1;	/* print host-specific info in messages */
114int	logged_in;
115struct	passwd *pw;
116char	*homedir;
117int	ftpdebug;
118int	timeout = 900;    /* timeout after 15 minutes of inactivity */
119int	maxtimeout = 7200;/* don't allow idle time to be set beyond 2 hours */
120int	logging;
121int	restricted_data_ports = 1;
122int	paranoid = 1;	  /* be extra careful about security */
123int	anon_only = 0;    /* Only anonymous ftp allowed */
124int	assumeutf8 = 0;   /* Assume that server file names are in UTF-8 */
125int	guest;
126int	dochroot;
127char	*chrootdir;
128int	dowtmp = 1;
129int	stats;
130int	statfd = -1;
131int	type;
132int	form;
133int	stru;			/* avoid C keyword */
134int	mode;
135int	usedefault = 1;		/* for data transfers */
136int	pdata = -1;		/* for passive mode */
137int	readonly = 0;		/* Server is in readonly mode.	*/
138int	noepsv = 0;		/* EPSV command is disabled.	*/
139int	noretr = 0;		/* RETR command is disabled.	*/
140int	noguestretr = 0;	/* RETR command is disabled for anon users. */
141int	noguestmkd = 0;		/* MKD command is disabled for anon users. */
142int	noguestmod = 1;		/* anon users may not modify existing files. */
143
144off_t	file_size;
145off_t	byte_count;
146#if !defined(CMASK) || CMASK == 0
147#undef CMASK
148#define CMASK 027
149#endif
150int	defumask = CMASK;		/* default umask value */
151char	tmpline[7];
152char	*hostname;
153int	epsvall = 0;
154
155#ifdef VIRTUAL_HOSTING
156char	*ftpuser;
157
158static struct ftphost {
159	struct ftphost	*next;
160	struct addrinfo *hostinfo;
161	char		*hostname;
162	char		*anonuser;
163	char		*statfile;
164	char		*welcome;
165	char		*loginmsg;
166} *thishost, *firsthost;
167
168#endif
169char	remotehost[NI_MAXHOST];
170char	*ident = NULL;
171
172static char	wtmpid[20];
173
174#ifdef USE_PAM
175static int	auth_pam(struct passwd**, const char*);
176pam_handle_t	*pamh = NULL;
177#endif
178
179static struct opie	opiedata;
180static char		opieprompt[OPIE_CHALLENGE_MAX+1];
181static int		pwok;
182
183char	*pid_file = NULL; /* means default location to pidfile(3) */
184
185/*
186 * Limit number of pathnames that glob can return.
187 * A limit of 0 indicates the number of pathnames is unlimited.
188 */
189#define MAXGLOBARGS	16384
190#
191
192/*
193 * Timeout intervals for retrying connections
194 * to hosts that don't accept PORT cmds.  This
195 * is a kludge, but given the problems with TCP...
196 */
197#define	SWAITMAX	90	/* wait at most 90 seconds */
198#define	SWAITINT	5	/* interval between retries */
199
200int	swaitmax = SWAITMAX;
201int	swaitint = SWAITINT;
202
203#ifdef SETPROCTITLE
204#ifdef OLD_SETPROCTITLE
205char	**Argv = NULL;		/* pointer to argument vector */
206char	*LastArgv = NULL;	/* end of argv */
207#endif /* OLD_SETPROCTITLE */
208char	proctitle[LINE_MAX];	/* initial part of title */
209#endif /* SETPROCTITLE */
210
211#define LOGCMD(cmd, file)		logcmd((cmd), (file), NULL, -1)
212#define LOGCMD2(cmd, file1, file2)	logcmd((cmd), (file1), (file2), -1)
213#define LOGBYTES(cmd, file, cnt)	logcmd((cmd), (file), NULL, (cnt))
214
215static	volatile sig_atomic_t recvurg;
216static	int transflag;		/* NB: for debugging only */
217
218#define STARTXFER	flagxfer(1)
219#define ENDXFER		flagxfer(0)
220
221#define START_UNSAFE	maskurg(1)
222#define END_UNSAFE	maskurg(0)
223
224/* It's OK to put an `else' clause after this macro. */
225#define CHECKOOB(action)						\
226	if (recvurg) {							\
227		recvurg = 0;						\
228		if (myoob()) {						\
229			ENDXFER;					\
230			action;						\
231		}							\
232	}
233
234#ifdef VIRTUAL_HOSTING
235static void	 inithosts(int);
236static void	 selecthost(union sockunion *);
237#endif
238static void	 ack(char *);
239static void	 sigurg(int);
240static void	 maskurg(int);
241static void	 flagxfer(int);
242static int	 myoob(void);
243static int	 checkuser(char *, char *, int, char **, int *);
244static FILE	*dataconn(char *, off_t, char *);
245static void	 dolog(struct sockaddr *);
246static void	 end_login(void);
247static FILE	*getdatasock(char *);
248static int	 guniquefd(char *, char **);
249static void	 lostconn(int);
250static void	 sigquit(int);
251static int	 receive_data(FILE *, FILE *);
252static int	 send_data(FILE *, FILE *, size_t, off_t, int);
253static struct passwd *
254		 sgetpwnam(char *);
255static char	*sgetsave(char *);
256static void	 reapchild(int);
257static void	 appendf(char **, char *, ...) __printflike(2, 3);
258static void	 logcmd(char *, char *, char *, off_t);
259static void      logxfer(char *, off_t, time_t);
260static char	*doublequote(char *);
261static int	*socksetup(int, char *, const char *);
262
263int
264main(int argc, char *argv[], char **envp)
265{
266	socklen_t addrlen;
267	int ch, on = 1, tos;
268	char *cp, line[LINE_MAX];
269	FILE *fd;
270	char	*bindname = NULL;
271	const char *bindport = "ftp";
272	int	family = AF_UNSPEC;
273	struct sigaction sa;
274
275	tzset();		/* in case no timezone database in ~ftp */
276	sigemptyset(&sa.sa_mask);
277	sa.sa_flags = SA_RESTART;
278
279#ifdef OLD_SETPROCTITLE
280	/*
281	 *  Save start and extent of argv for setproctitle.
282	 */
283	Argv = argv;
284	while (*envp)
285		envp++;
286	LastArgv = envp[-1] + strlen(envp[-1]);
287#endif /* OLD_SETPROCTITLE */
288
289	/*
290	 * Prevent diagnostic messages from appearing on stderr.
291	 * We run as a daemon or from inetd; in both cases, there's
292	 * more reason in logging to syslog.
293	 */
294	(void) freopen(_PATH_DEVNULL, "w", stderr);
295	opterr = 0;
296
297	/*
298	 * LOG_NDELAY sets up the logging connection immediately,
299	 * necessary for anonymous ftp's that chroot and can't do it later.
300	 */
301	openlog("ftpd", LOG_PID | LOG_NDELAY, LOG_FTP);
302
303	while ((ch = getopt(argc, argv,
304	                    "468a:AdDEhlmMoOp:P:rRSt:T:u:UvW")) != -1) {
305		switch (ch) {
306		case '4':
307			family = (family == AF_INET6) ? AF_UNSPEC : AF_INET;
308			break;
309
310		case '6':
311			family = (family == AF_INET) ? AF_UNSPEC : AF_INET6;
312			break;
313
314		case '8':
315			assumeutf8 = 1;
316			break;
317
318		case 'a':
319			bindname = optarg;
320			break;
321
322		case 'A':
323			anon_only = 1;
324			break;
325
326		case 'd':
327			ftpdebug++;
328			break;
329
330		case 'D':
331			daemon_mode++;
332			break;
333
334		case 'E':
335			noepsv = 1;
336			break;
337
338		case 'h':
339			hostinfo = 0;
340			break;
341
342		case 'l':
343			logging++;	/* > 1 == extra logging */
344			break;
345
346		case 'm':
347			noguestmod = 0;
348			break;
349
350		case 'M':
351			noguestmkd = 1;
352			break;
353
354		case 'o':
355			noretr = 1;
356			break;
357
358		case 'O':
359			noguestretr = 1;
360			break;
361
362		case 'p':
363			pid_file = optarg;
364			break;
365
366		case 'P':
367			bindport = optarg;
368			break;
369
370		case 'r':
371			readonly = 1;
372			break;
373
374		case 'R':
375			paranoid = 0;
376			break;
377
378		case 'S':
379			stats++;
380			break;
381
382		case 't':
383			timeout = atoi(optarg);
384			if (maxtimeout < timeout)
385				maxtimeout = timeout;
386			break;
387
388		case 'T':
389			maxtimeout = atoi(optarg);
390			if (timeout > maxtimeout)
391				timeout = maxtimeout;
392			break;
393
394		case 'u':
395		    {
396			long val = 0;
397
398			val = strtol(optarg, &optarg, 8);
399			if (*optarg != '\0' || val < 0)
400				syslog(LOG_WARNING, "bad value for -u");
401			else
402				defumask = val;
403			break;
404		    }
405		case 'U':
406			restricted_data_ports = 0;
407			break;
408
409		case 'v':
410			ftpdebug++;
411			break;
412
413		case 'W':
414			dowtmp = 0;
415			break;
416
417		default:
418			syslog(LOG_WARNING, "unknown flag -%c ignored", optopt);
419			break;
420		}
421	}
422
423	/* handle filesize limit gracefully */
424	sa.sa_handler = SIG_IGN;
425	(void)sigaction(SIGXFSZ, &sa, NULL);
426
427	if (daemon_mode) {
428		int *ctl_sock, fd, maxfd = -1, nfds, i;
429		fd_set defreadfds, readfds;
430		pid_t pid;
431		struct pidfh *pfh;
432
433		if ((pfh = pidfile_open(pid_file, 0600, &pid)) == NULL) {
434			if (errno == EEXIST) {
435				syslog(LOG_ERR, "%s already running, pid %d",
436				       getprogname(), (int)pid);
437				exit(1);
438			}
439			syslog(LOG_WARNING, "pidfile_open: %m");
440		}
441
442		/*
443		 * Detach from parent.
444		 */
445		if (daemon(1, 1) < 0) {
446			syslog(LOG_ERR, "failed to become a daemon");
447			exit(1);
448		}
449
450		if (pfh != NULL && pidfile_write(pfh) == -1)
451			syslog(LOG_WARNING, "pidfile_write: %m");
452
453		sa.sa_handler = reapchild;
454		(void)sigaction(SIGCHLD, &sa, NULL);
455
456#ifdef VIRTUAL_HOSTING
457		inithosts(family);
458#endif
459
460		/*
461		 * Open a socket, bind it to the FTP port, and start
462		 * listening.
463		 */
464		ctl_sock = socksetup(family, bindname, bindport);
465		if (ctl_sock == NULL)
466			exit(1);
467
468		FD_ZERO(&defreadfds);
469		for (i = 1; i <= *ctl_sock; i++) {
470			FD_SET(ctl_sock[i], &defreadfds);
471			if (listen(ctl_sock[i], 32) < 0) {
472				syslog(LOG_ERR, "control listen: %m");
473				exit(1);
474			}
475			if (maxfd < ctl_sock[i])
476				maxfd = ctl_sock[i];
477		}
478
479		/*
480		 * Loop forever accepting connection requests and forking off
481		 * children to handle them.
482		 */
483		while (1) {
484			FD_COPY(&defreadfds, &readfds);
485			nfds = select(maxfd + 1, &readfds, NULL, NULL, 0);
486			if (nfds <= 0) {
487				if (nfds < 0 && errno != EINTR)
488					syslog(LOG_WARNING, "select: %m");
489				continue;
490			}
491
492			pid = -1;
493                        for (i = 1; i <= *ctl_sock; i++)
494				if (FD_ISSET(ctl_sock[i], &readfds)) {
495					addrlen = sizeof(his_addr);
496					fd = accept(ctl_sock[i],
497					    (struct sockaddr *)&his_addr,
498					    &addrlen);
499					if (fd == -1) {
500						syslog(LOG_WARNING,
501						       "accept: %m");
502						continue;
503					}
504					switch (pid = fork()) {
505					case 0:
506						/* child */
507						(void) dup2(fd, 0);
508						(void) dup2(fd, 1);
509						(void) close(fd);
510						for (i = 1; i <= *ctl_sock; i++)
511							close(ctl_sock[i]);
512						if (pfh != NULL)
513							pidfile_close(pfh);
514						goto gotchild;
515					case -1:
516						syslog(LOG_WARNING, "fork: %m");
517						/* FALLTHROUGH */
518					default:
519						close(fd);
520					}
521				}
522		}
523	} else {
524		addrlen = sizeof(his_addr);
525		if (getpeername(0, (struct sockaddr *)&his_addr, &addrlen) < 0) {
526			syslog(LOG_ERR, "getpeername (%s): %m",argv[0]);
527			exit(1);
528		}
529
530#ifdef VIRTUAL_HOSTING
531		if (his_addr.su_family == AF_INET6 &&
532		    IN6_IS_ADDR_V4MAPPED(&his_addr.su_sin6.sin6_addr))
533			family = AF_INET;
534		else
535			family = his_addr.su_family;
536		inithosts(family);
537#endif
538	}
539
540gotchild:
541	sa.sa_handler = SIG_DFL;
542	(void)sigaction(SIGCHLD, &sa, NULL);
543
544	sa.sa_handler = sigurg;
545	sa.sa_flags = 0;		/* don't restart syscalls for SIGURG */
546	(void)sigaction(SIGURG, &sa, NULL);
547
548	sigfillset(&sa.sa_mask);	/* block all signals in handler */
549	sa.sa_flags = SA_RESTART;
550	sa.sa_handler = sigquit;
551	(void)sigaction(SIGHUP, &sa, NULL);
552	(void)sigaction(SIGINT, &sa, NULL);
553	(void)sigaction(SIGQUIT, &sa, NULL);
554	(void)sigaction(SIGTERM, &sa, NULL);
555
556	sa.sa_handler = lostconn;
557	(void)sigaction(SIGPIPE, &sa, NULL);
558
559	addrlen = sizeof(ctrl_addr);
560	if (getsockname(0, (struct sockaddr *)&ctrl_addr, &addrlen) < 0) {
561		syslog(LOG_ERR, "getsockname (%s): %m",argv[0]);
562		exit(1);
563	}
564	dataport = ntohs(ctrl_addr.su_port) - 1; /* as per RFC 959 */
565#ifdef VIRTUAL_HOSTING
566	/* select our identity from virtual host table */
567	selecthost(&ctrl_addr);
568#endif
569#ifdef IP_TOS
570	if (ctrl_addr.su_family == AF_INET)
571      {
572	tos = IPTOS_LOWDELAY;
573	if (setsockopt(0, IPPROTO_IP, IP_TOS, &tos, sizeof(int)) < 0)
574		syslog(LOG_WARNING, "control setsockopt (IP_TOS): %m");
575      }
576#endif
577	/*
578	 * Disable Nagle on the control channel so that we don't have to wait
579	 * for peer's ACK before issuing our next reply.
580	 */
581	if (setsockopt(0, IPPROTO_TCP, TCP_NODELAY, &on, sizeof(on)) < 0)
582		syslog(LOG_WARNING, "control setsockopt (TCP_NODELAY): %m");
583
584	data_source.su_port = htons(ntohs(ctrl_addr.su_port) - 1);
585
586	(void)snprintf(wtmpid, sizeof(wtmpid), "%xftpd", getpid());
587
588	/* Try to handle urgent data inline */
589#ifdef SO_OOBINLINE
590	if (setsockopt(0, SOL_SOCKET, SO_OOBINLINE, &on, sizeof(on)) < 0)
591		syslog(LOG_WARNING, "control setsockopt (SO_OOBINLINE): %m");
592#endif
593
594#ifdef	F_SETOWN
595	if (fcntl(fileno(stdin), F_SETOWN, getpid()) == -1)
596		syslog(LOG_ERR, "fcntl F_SETOWN: %m");
597#endif
598	dolog((struct sockaddr *)&his_addr);
599	/*
600	 * Set up default state
601	 */
602	data = -1;
603	type = TYPE_A;
604	form = FORM_N;
605	stru = STRU_F;
606	mode = MODE_S;
607	tmpline[0] = '\0';
608
609	/* If logins are disabled, print out the message. */
610	if ((fd = fopen(_PATH_NOLOGIN,"r")) != NULL) {
611		while (fgets(line, sizeof(line), fd) != NULL) {
612			if ((cp = strchr(line, '\n')) != NULL)
613				*cp = '\0';
614			lreply(530, "%s", line);
615		}
616		(void) fflush(stdout);
617		(void) fclose(fd);
618		reply(530, "System not available.");
619		exit(0);
620	}
621#ifdef VIRTUAL_HOSTING
622	fd = fopen(thishost->welcome, "r");
623#else
624	fd = fopen(_PATH_FTPWELCOME, "r");
625#endif
626	if (fd != NULL) {
627		while (fgets(line, sizeof(line), fd) != NULL) {
628			if ((cp = strchr(line, '\n')) != NULL)
629				*cp = '\0';
630			lreply(220, "%s", line);
631		}
632		(void) fflush(stdout);
633		(void) fclose(fd);
634		/* reply(220,) must follow */
635	}
636#ifndef VIRTUAL_HOSTING
637	if ((hostname = malloc(MAXHOSTNAMELEN)) == NULL)
638		fatalerror("Ran out of memory.");
639	if (gethostname(hostname, MAXHOSTNAMELEN - 1) < 0)
640		hostname[0] = '\0';
641	hostname[MAXHOSTNAMELEN - 1] = '\0';
642#endif
643	if (hostinfo)
644		reply(220, "%s FTP server (%s) ready.", hostname, version);
645	else
646		reply(220, "FTP server ready.");
647	for (;;)
648		(void) yyparse();
649	/* NOTREACHED */
650}
651
652static void
653lostconn(int signo)
654{
655
656	if (ftpdebug)
657		syslog(LOG_DEBUG, "lost connection");
658	dologout(1);
659}
660
661static void
662sigquit(int signo)
663{
664
665	syslog(LOG_ERR, "got signal %d", signo);
666	dologout(1);
667}
668
669#ifdef VIRTUAL_HOSTING
670/*
671 * read in virtual host tables (if they exist)
672 */
673
674static void
675inithosts(int family)
676{
677	int insert;
678	size_t len;
679	FILE *fp;
680	char *cp, *mp, *line;
681	char *hostname;
682	char *vhost, *anonuser, *statfile, *welcome, *loginmsg;
683	struct ftphost *hrp, *lhrp;
684	struct addrinfo hints, *res, *ai;
685
686	/*
687	 * Fill in the default host information
688	 */
689	if ((hostname = malloc(MAXHOSTNAMELEN)) == NULL)
690		fatalerror("Ran out of memory.");
691	if (gethostname(hostname, MAXHOSTNAMELEN - 1) < 0)
692		hostname[0] = '\0';
693	hostname[MAXHOSTNAMELEN - 1] = '\0';
694	if ((hrp = malloc(sizeof(struct ftphost))) == NULL)
695		fatalerror("Ran out of memory.");
696	hrp->hostname = hostname;
697	hrp->hostinfo = NULL;
698
699	memset(&hints, 0, sizeof(hints));
700	hints.ai_flags = AI_PASSIVE;
701	hints.ai_family = family;
702	hints.ai_socktype = SOCK_STREAM;
703	if (getaddrinfo(hrp->hostname, NULL, &hints, &res) == 0)
704		hrp->hostinfo = res;
705	hrp->statfile = _PATH_FTPDSTATFILE;
706	hrp->welcome  = _PATH_FTPWELCOME;
707	hrp->loginmsg = _PATH_FTPLOGINMESG;
708	hrp->anonuser = "ftp";
709	hrp->next = NULL;
710	thishost = firsthost = lhrp = hrp;
711	if ((fp = fopen(_PATH_FTPHOSTS, "r")) != NULL) {
712		int addrsize, gothost;
713		void *addr;
714		struct hostent *hp;
715
716		while ((line = fgetln(fp, &len)) != NULL) {
717			int	i, hp_error;
718
719			/* skip comments */
720			if (line[0] == '#')
721				continue;
722			if (line[len - 1] == '\n') {
723				line[len - 1] = '\0';
724				mp = NULL;
725			} else {
726				if ((mp = malloc(len + 1)) == NULL)
727					fatalerror("Ran out of memory.");
728				memcpy(mp, line, len);
729				mp[len] = '\0';
730				line = mp;
731			}
732			cp = strtok(line, " \t");
733			/* skip empty lines */
734			if (cp == NULL)
735				goto nextline;
736			vhost = cp;
737
738			/* set defaults */
739			anonuser = "ftp";
740			statfile = _PATH_FTPDSTATFILE;
741			welcome  = _PATH_FTPWELCOME;
742			loginmsg = _PATH_FTPLOGINMESG;
743
744			/*
745			 * Preparse the line so we can use its info
746			 * for all the addresses associated with
747			 * the virtual host name.
748			 * Field 0, the virtual host name, is special:
749			 * it's already parsed off and will be strdup'ed
750			 * later, after we know its canonical form.
751			 */
752			for (i = 1; i < 5 && (cp = strtok(NULL, " \t")); i++)
753				if (*cp != '-' && (cp = strdup(cp)))
754					switch (i) {
755					case 1:	/* anon user permissions */
756						anonuser = cp;
757						break;
758					case 2: /* statistics file */
759						statfile = cp;
760						break;
761					case 3: /* welcome message */
762						welcome  = cp;
763						break;
764					case 4: /* login message */
765						loginmsg = cp;
766						break;
767					default: /* programming error */
768						abort();
769						/* NOTREACHED */
770					}
771
772			hints.ai_flags = AI_PASSIVE;
773			hints.ai_family = family;
774			hints.ai_socktype = SOCK_STREAM;
775			if (getaddrinfo(vhost, NULL, &hints, &res) != 0)
776				goto nextline;
777			for (ai = res; ai != NULL && ai->ai_addr != NULL;
778			     ai = ai->ai_next) {
779
780			gothost = 0;
781			for (hrp = firsthost; hrp != NULL; hrp = hrp->next) {
782				struct addrinfo *hi;
783
784				for (hi = hrp->hostinfo; hi != NULL;
785				     hi = hi->ai_next)
786					if (hi->ai_addrlen == ai->ai_addrlen &&
787					    memcmp(hi->ai_addr,
788						   ai->ai_addr,
789						   ai->ai_addr->sa_len) == 0) {
790						gothost++;
791						break;
792					}
793				if (gothost)
794					break;
795			}
796			if (hrp == NULL) {
797				if ((hrp = malloc(sizeof(struct ftphost))) == NULL)
798					goto nextline;
799				hrp->hostname = NULL;
800				insert = 1;
801			} else {
802				if (hrp->hostinfo && hrp->hostinfo != res)
803					freeaddrinfo(hrp->hostinfo);
804				insert = 0; /* host already in the chain */
805			}
806			hrp->hostinfo = res;
807
808			/*
809			 * determine hostname to use.
810			 * force defined name if there is a valid alias
811			 * otherwise fallback to primary hostname
812			 */
813			/* XXX: getaddrinfo() can't do alias check */
814			switch(hrp->hostinfo->ai_family) {
815			case AF_INET:
816				addr = &((struct sockaddr_in *)hrp->hostinfo->ai_addr)->sin_addr;
817				addrsize = sizeof(struct in_addr);
818				break;
819			case AF_INET6:
820				addr = &((struct sockaddr_in6 *)hrp->hostinfo->ai_addr)->sin6_addr;
821				addrsize = sizeof(struct in6_addr);
822				break;
823			default:
824				/* should not reach here */
825				freeaddrinfo(hrp->hostinfo);
826				if (insert)
827					free(hrp); /*not in chain, can free*/
828				else
829					hrp->hostinfo = NULL; /*mark as blank*/
830				goto nextline;
831				/* NOTREACHED */
832			}
833			if ((hp = getipnodebyaddr(addr, addrsize,
834						  hrp->hostinfo->ai_family,
835						  &hp_error)) != NULL) {
836				if (strcmp(vhost, hp->h_name) != 0) {
837					if (hp->h_aliases == NULL)
838						vhost = hp->h_name;
839					else {
840						i = 0;
841						while (hp->h_aliases[i] &&
842						       strcmp(vhost, hp->h_aliases[i]) != 0)
843							++i;
844						if (hp->h_aliases[i] == NULL)
845							vhost = hp->h_name;
846					}
847				}
848			}
849			if (hrp->hostname &&
850			    strcmp(hrp->hostname, vhost) != 0) {
851				free(hrp->hostname);
852				hrp->hostname = NULL;
853			}
854			if (hrp->hostname == NULL &&
855			    (hrp->hostname = strdup(vhost)) == NULL) {
856				freeaddrinfo(hrp->hostinfo);
857				hrp->hostinfo = NULL; /* mark as blank */
858				if (hp)
859					freehostent(hp);
860				goto nextline;
861			}
862			hrp->anonuser = anonuser;
863			hrp->statfile = statfile;
864			hrp->welcome  = welcome;
865			hrp->loginmsg = loginmsg;
866			if (insert) {
867				hrp->next  = NULL;
868				lhrp->next = hrp;
869				lhrp = hrp;
870			}
871			if (hp)
872				freehostent(hp);
873		      }
874nextline:
875			if (mp)
876				free(mp);
877		}
878		(void) fclose(fp);
879	}
880}
881
882static void
883selecthost(union sockunion *su)
884{
885	struct ftphost	*hrp;
886	u_int16_t port;
887#ifdef INET6
888	struct in6_addr *mapped_in6 = NULL;
889#endif
890	struct addrinfo *hi;
891
892#ifdef INET6
893	/*
894	 * XXX IPv4 mapped IPv6 addr consideraton,
895	 * specified in rfc2373.
896	 */
897	if (su->su_family == AF_INET6 &&
898	    IN6_IS_ADDR_V4MAPPED(&su->su_sin6.sin6_addr))
899		mapped_in6 = &su->su_sin6.sin6_addr;
900#endif
901
902	hrp = thishost = firsthost;	/* default */
903	port = su->su_port;
904	su->su_port = 0;
905	while (hrp != NULL) {
906	    for (hi = hrp->hostinfo; hi != NULL; hi = hi->ai_next) {
907		if (memcmp(su, hi->ai_addr, hi->ai_addrlen) == 0) {
908			thishost = hrp;
909			goto found;
910		}
911#ifdef INET6
912		/* XXX IPv4 mapped IPv6 addr consideraton */
913		if (hi->ai_addr->sa_family == AF_INET && mapped_in6 != NULL &&
914		    (memcmp(&mapped_in6->s6_addr[12],
915			    &((struct sockaddr_in *)hi->ai_addr)->sin_addr,
916			    sizeof(struct in_addr)) == 0)) {
917			thishost = hrp;
918			goto found;
919		}
920#endif
921	    }
922	    hrp = hrp->next;
923	}
924found:
925	su->su_port = port;
926	/* setup static variables as appropriate */
927	hostname = thishost->hostname;
928	ftpuser = thishost->anonuser;
929}
930#endif
931
932/*
933 * Helper function for sgetpwnam().
934 */
935static char *
936sgetsave(char *s)
937{
938	char *new = malloc(strlen(s) + 1);
939
940	if (new == NULL) {
941		reply(421, "Ran out of memory.");
942		dologout(1);
943		/* NOTREACHED */
944	}
945	(void) strcpy(new, s);
946	return (new);
947}
948
949/*
950 * Save the result of a getpwnam.  Used for USER command, since
951 * the data returned must not be clobbered by any other command
952 * (e.g., globbing).
953 * NB: The data returned by sgetpwnam() will remain valid until
954 * the next call to this function.  Its difference from getpwnam()
955 * is that sgetpwnam() is known to be called from ftpd code only.
956 */
957static struct passwd *
958sgetpwnam(char *name)
959{
960	static struct passwd save;
961	struct passwd *p;
962
963	if ((p = getpwnam(name)) == NULL)
964		return (p);
965	if (save.pw_name) {
966		free(save.pw_name);
967		free(save.pw_passwd);
968		free(save.pw_class);
969		free(save.pw_gecos);
970		free(save.pw_dir);
971		free(save.pw_shell);
972	}
973	save = *p;
974	save.pw_name = sgetsave(p->pw_name);
975	save.pw_passwd = sgetsave(p->pw_passwd);
976	save.pw_class = sgetsave(p->pw_class);
977	save.pw_gecos = sgetsave(p->pw_gecos);
978	save.pw_dir = sgetsave(p->pw_dir);
979	save.pw_shell = sgetsave(p->pw_shell);
980	return (&save);
981}
982
983static int login_attempts;	/* number of failed login attempts */
984static int askpasswd;		/* had user command, ask for passwd */
985static char curname[MAXLOGNAME];	/* current USER name */
986
987/*
988 * USER command.
989 * Sets global passwd pointer pw if named account exists and is acceptable;
990 * sets askpasswd if a PASS command is expected.  If logged in previously,
991 * need to reset state.  If name is "ftp" or "anonymous", the name is not in
992 * _PATH_FTPUSERS, and ftp account exists, set guest and pw, then just return.
993 * If account doesn't exist, ask for passwd anyway.  Otherwise, check user
994 * requesting login privileges.  Disallow anyone who does not have a standard
995 * shell as returned by getusershell().  Disallow anyone mentioned in the file
996 * _PATH_FTPUSERS to allow people such as root and uucp to be avoided.
997 */
998void
999user(char *name)
1000{
1001	int ecode;
1002	char *cp, *shell;
1003
1004	if (logged_in) {
1005		if (guest) {
1006			reply(530, "Can't change user from guest login.");
1007			return;
1008		} else if (dochroot) {
1009			reply(530, "Can't change user from chroot user.");
1010			return;
1011		}
1012		end_login();
1013	}
1014
1015	guest = 0;
1016#ifdef VIRTUAL_HOSTING
1017	pw = sgetpwnam(thishost->anonuser);
1018#else
1019	pw = sgetpwnam("ftp");
1020#endif
1021	if (strcmp(name, "ftp") == 0 || strcmp(name, "anonymous") == 0) {
1022		if (checkuser(_PATH_FTPUSERS, "ftp", 0, NULL, &ecode) ||
1023		    (ecode != 0 && ecode != ENOENT))
1024			reply(530, "User %s access denied.", name);
1025		else if (checkuser(_PATH_FTPUSERS, "anonymous", 0, NULL, &ecode) ||
1026		    (ecode != 0 && ecode != ENOENT))
1027			reply(530, "User %s access denied.", name);
1028		else if (pw != NULL) {
1029			guest = 1;
1030			askpasswd = 1;
1031			reply(331,
1032			"Guest login ok, send your email address as password.");
1033		} else
1034			reply(530, "User %s unknown.", name);
1035		if (!askpasswd && logging)
1036			syslog(LOG_NOTICE,
1037			    "ANONYMOUS FTP LOGIN REFUSED FROM %s", remotehost);
1038		return;
1039	}
1040	if (anon_only != 0) {
1041		reply(530, "Sorry, only anonymous ftp allowed.");
1042		return;
1043	}
1044
1045	if ((pw = sgetpwnam(name))) {
1046		if ((shell = pw->pw_shell) == NULL || *shell == 0)
1047			shell = _PATH_BSHELL;
1048		setusershell();
1049		while ((cp = getusershell()) != NULL)
1050			if (strcmp(cp, shell) == 0)
1051				break;
1052		endusershell();
1053
1054		if (cp == NULL ||
1055		    (checkuser(_PATH_FTPUSERS, name, 1, NULL, &ecode) ||
1056		    (ecode != 0 && ecode != ENOENT))) {
1057			reply(530, "User %s access denied.", name);
1058			if (logging)
1059				syslog(LOG_NOTICE,
1060				    "FTP LOGIN REFUSED FROM %s, %s",
1061				    remotehost, name);
1062			pw = NULL;
1063			return;
1064		}
1065	}
1066	if (logging)
1067		strncpy(curname, name, sizeof(curname)-1);
1068
1069	pwok = 0;
1070#ifdef USE_PAM
1071	/* XXX Kluge! The conversation mechanism needs to be fixed. */
1072#endif
1073	if (opiechallenge(&opiedata, name, opieprompt) == 0) {
1074		pwok = (pw != NULL) &&
1075		       opieaccessfile(remotehost) &&
1076		       opiealways(pw->pw_dir);
1077		reply(331, "Response to %s %s for %s.",
1078		      opieprompt, pwok ? "requested" : "required", name);
1079	} else {
1080		pwok = 1;
1081		reply(331, "Password required for %s.", name);
1082	}
1083	askpasswd = 1;
1084	/*
1085	 * Delay before reading passwd after first failed
1086	 * attempt to slow down passwd-guessing programs.
1087	 */
1088	if (login_attempts)
1089		sleep(login_attempts);
1090}
1091
1092/*
1093 * Check if a user is in the file "fname",
1094 * return a pointer to a malloc'd string with the rest
1095 * of the matching line in "residue" if not NULL.
1096 */
1097static int
1098checkuser(char *fname, char *name, int pwset, char **residue, int *ecode)
1099{
1100	FILE *fd;
1101	int found = 0;
1102	size_t len;
1103	char *line, *mp, *p;
1104
1105	if (ecode != NULL)
1106		*ecode = 0;
1107	if ((fd = fopen(fname, "r")) != NULL) {
1108		while (!found && (line = fgetln(fd, &len)) != NULL) {
1109			/* skip comments */
1110			if (line[0] == '#')
1111				continue;
1112			if (line[len - 1] == '\n') {
1113				line[len - 1] = '\0';
1114				mp = NULL;
1115			} else {
1116				if ((mp = malloc(len + 1)) == NULL)
1117					fatalerror("Ran out of memory.");
1118				memcpy(mp, line, len);
1119				mp[len] = '\0';
1120				line = mp;
1121			}
1122			/* avoid possible leading and trailing whitespace */
1123			p = strtok(line, " \t");
1124			/* skip empty lines */
1125			if (p == NULL)
1126				goto nextline;
1127			/*
1128			 * if first chr is '@', check group membership
1129			 */
1130			if (p[0] == '@') {
1131				int i = 0;
1132				struct group *grp;
1133
1134				if (p[1] == '\0') /* single @ matches anyone */
1135					found = 1;
1136				else {
1137					if ((grp = getgrnam(p+1)) == NULL)
1138						goto nextline;
1139					/*
1140					 * Check user's default group
1141					 */
1142					if (pwset && grp->gr_gid == pw->pw_gid)
1143						found = 1;
1144					/*
1145					 * Check supplementary groups
1146					 */
1147					while (!found && grp->gr_mem[i])
1148						found = strcmp(name,
1149							grp->gr_mem[i++])
1150							== 0;
1151				}
1152			}
1153			/*
1154			 * Otherwise, just check for username match
1155			 */
1156			else
1157				found = strcmp(p, name) == 0;
1158			/*
1159			 * Save the rest of line to "residue" if matched
1160			 */
1161			if (found && residue) {
1162				if ((p = strtok(NULL, "")) != NULL)
1163					p += strspn(p, " \t");
1164				if (p && *p) {
1165				 	if ((*residue = strdup(p)) == NULL)
1166						fatalerror("Ran out of memory.");
1167				} else
1168					*residue = NULL;
1169			}
1170nextline:
1171			if (mp)
1172				free(mp);
1173		}
1174		(void) fclose(fd);
1175	} else if (ecode != NULL)
1176		*ecode = errno;
1177	return (found);
1178}
1179
1180/*
1181 * Terminate login as previous user, if any, resetting state;
1182 * used when USER command is given or login fails.
1183 */
1184static void
1185end_login(void)
1186{
1187#ifdef USE_PAM
1188	int e;
1189#endif
1190
1191	(void) seteuid(0);
1192#ifdef	LOGIN_CAP
1193	setusercontext(NULL, getpwuid(0), 0, LOGIN_SETALL & ~(LOGIN_SETLOGIN |
1194		       LOGIN_SETUSER | LOGIN_SETGROUP | LOGIN_SETPATH |
1195		       LOGIN_SETENV));
1196#endif
1197	if (logged_in && dowtmp)
1198		ftpd_logwtmp(wtmpid, NULL, NULL);
1199	pw = NULL;
1200#ifdef USE_PAM
1201	if (pamh) {
1202		if ((e = pam_setcred(pamh, PAM_DELETE_CRED)) != PAM_SUCCESS)
1203			syslog(LOG_ERR, "pam_setcred: %s", pam_strerror(pamh, e));
1204		if ((e = pam_close_session(pamh,0)) != PAM_SUCCESS)
1205			syslog(LOG_ERR, "pam_close_session: %s", pam_strerror(pamh, e));
1206		if ((e = pam_end(pamh, e)) != PAM_SUCCESS)
1207			syslog(LOG_ERR, "pam_end: %s", pam_strerror(pamh, e));
1208		pamh = NULL;
1209	}
1210#endif
1211	logged_in = 0;
1212	guest = 0;
1213	dochroot = 0;
1214}
1215
1216#ifdef USE_PAM
1217
1218/*
1219 * the following code is stolen from imap-uw PAM authentication module and
1220 * login.c
1221 */
1222#define COPY_STRING(s) (s ? strdup(s) : NULL)
1223
1224struct cred_t {
1225	const char *uname;		/* user name */
1226	const char *pass;		/* password */
1227};
1228typedef struct cred_t cred_t;
1229
1230static int
1231auth_conv(int num_msg, const struct pam_message **msg,
1232	  struct pam_response **resp, void *appdata)
1233{
1234	int i;
1235	cred_t *cred = (cred_t *) appdata;
1236	struct pam_response *reply;
1237
1238	reply = calloc(num_msg, sizeof *reply);
1239	if (reply == NULL)
1240		return PAM_BUF_ERR;
1241
1242	for (i = 0; i < num_msg; i++) {
1243		switch (msg[i]->msg_style) {
1244		case PAM_PROMPT_ECHO_ON:	/* assume want user name */
1245			reply[i].resp_retcode = PAM_SUCCESS;
1246			reply[i].resp = COPY_STRING(cred->uname);
1247			/* PAM frees resp. */
1248			break;
1249		case PAM_PROMPT_ECHO_OFF:	/* assume want password */
1250			reply[i].resp_retcode = PAM_SUCCESS;
1251			reply[i].resp = COPY_STRING(cred->pass);
1252			/* PAM frees resp. */
1253			break;
1254		case PAM_TEXT_INFO:
1255		case PAM_ERROR_MSG:
1256			reply[i].resp_retcode = PAM_SUCCESS;
1257			reply[i].resp = NULL;
1258			break;
1259		default:			/* unknown message style */
1260			free(reply);
1261			return PAM_CONV_ERR;
1262		}
1263	}
1264
1265	*resp = reply;
1266	return PAM_SUCCESS;
1267}
1268
1269/*
1270 * Attempt to authenticate the user using PAM.  Returns 0 if the user is
1271 * authenticated, or 1 if not authenticated.  If some sort of PAM system
1272 * error occurs (e.g., the "/etc/pam.conf" file is missing) then this
1273 * function returns -1.  This can be used as an indication that we should
1274 * fall back to a different authentication mechanism.
1275 */
1276static int
1277auth_pam(struct passwd **ppw, const char *pass)
1278{
1279	const char *tmpl_user;
1280	const void *item;
1281	int rval;
1282	int e;
1283	cred_t auth_cred = { (*ppw)->pw_name, pass };
1284	struct pam_conv conv = { &auth_conv, &auth_cred };
1285
1286	e = pam_start("ftpd", (*ppw)->pw_name, &conv, &pamh);
1287	if (e != PAM_SUCCESS) {
1288		/*
1289		 * In OpenPAM, it's OK to pass NULL to pam_strerror()
1290		 * if context creation has failed in the first place.
1291		 */
1292		syslog(LOG_ERR, "pam_start: %s", pam_strerror(NULL, e));
1293		return -1;
1294	}
1295
1296	e = pam_set_item(pamh, PAM_RHOST, remotehost);
1297	if (e != PAM_SUCCESS) {
1298		syslog(LOG_ERR, "pam_set_item(PAM_RHOST): %s",
1299			pam_strerror(pamh, e));
1300		if ((e = pam_end(pamh, e)) != PAM_SUCCESS) {
1301			syslog(LOG_ERR, "pam_end: %s", pam_strerror(pamh, e));
1302		}
1303		pamh = NULL;
1304		return -1;
1305	}
1306
1307	e = pam_authenticate(pamh, 0);
1308	switch (e) {
1309	case PAM_SUCCESS:
1310		/*
1311		 * With PAM we support the concept of a "template"
1312		 * user.  The user enters a login name which is
1313		 * authenticated by PAM, usually via a remote service
1314		 * such as RADIUS or TACACS+.  If authentication
1315		 * succeeds, a different but related "template" name
1316		 * is used for setting the credentials, shell, and
1317		 * home directory.  The name the user enters need only
1318		 * exist on the remote authentication server, but the
1319		 * template name must be present in the local password
1320		 * database.
1321		 *
1322		 * This is supported by two various mechanisms in the
1323		 * individual modules.  However, from the application's
1324		 * point of view, the template user is always passed
1325		 * back as a changed value of the PAM_USER item.
1326		 */
1327		if ((e = pam_get_item(pamh, PAM_USER, &item)) ==
1328		    PAM_SUCCESS) {
1329			tmpl_user = (const char *) item;
1330			if (strcmp((*ppw)->pw_name, tmpl_user) != 0)
1331				*ppw = getpwnam(tmpl_user);
1332		} else
1333			syslog(LOG_ERR, "Couldn't get PAM_USER: %s",
1334			    pam_strerror(pamh, e));
1335		rval = 0;
1336		break;
1337
1338	case PAM_AUTH_ERR:
1339	case PAM_USER_UNKNOWN:
1340	case PAM_MAXTRIES:
1341		rval = 1;
1342		break;
1343
1344	default:
1345		syslog(LOG_ERR, "pam_authenticate: %s", pam_strerror(pamh, e));
1346		rval = -1;
1347		break;
1348	}
1349
1350	if (rval == 0) {
1351		e = pam_acct_mgmt(pamh, 0);
1352		if (e != PAM_SUCCESS) {
1353			syslog(LOG_ERR, "pam_acct_mgmt: %s",
1354						pam_strerror(pamh, e));
1355			rval = 1;
1356		}
1357	}
1358
1359	if (rval != 0) {
1360		if ((e = pam_end(pamh, e)) != PAM_SUCCESS) {
1361			syslog(LOG_ERR, "pam_end: %s", pam_strerror(pamh, e));
1362		}
1363		pamh = NULL;
1364	}
1365	return rval;
1366}
1367
1368#endif /* USE_PAM */
1369
1370void
1371pass(char *passwd)
1372{
1373	int rval, ecode;
1374	FILE *fd;
1375#ifdef	LOGIN_CAP
1376	login_cap_t *lc = NULL;
1377#endif
1378#ifdef USE_PAM
1379	int e;
1380#endif
1381	char *residue = NULL;
1382	char *xpasswd;
1383
1384	if (logged_in || askpasswd == 0) {
1385		reply(503, "Login with USER first.");
1386		return;
1387	}
1388	askpasswd = 0;
1389	if (!guest) {		/* "ftp" is only account allowed no password */
1390		if (pw == NULL) {
1391			rval = 1;	/* failure below */
1392			goto skip;
1393		}
1394#ifdef USE_PAM
1395		rval = auth_pam(&pw, passwd);
1396		if (rval >= 0) {
1397			opieunlock();
1398			goto skip;
1399		}
1400#endif
1401		if (opieverify(&opiedata, passwd) == 0)
1402			xpasswd = pw->pw_passwd;
1403		else if (pwok) {
1404			xpasswd = crypt(passwd, pw->pw_passwd);
1405			if (passwd[0] == '\0' && pw->pw_passwd[0] != '\0')
1406				xpasswd = ":";
1407		} else {
1408			rval = 1;
1409			goto skip;
1410		}
1411		rval = strcmp(pw->pw_passwd, xpasswd);
1412		if (pw->pw_expire && time(NULL) >= pw->pw_expire)
1413			rval = 1;	/* failure */
1414skip:
1415		/*
1416		 * If rval == 1, the user failed the authentication check
1417		 * above.  If rval == 0, either PAM or local authentication
1418		 * succeeded.
1419		 */
1420		if (rval) {
1421			reply(530, "Login incorrect.");
1422			if (logging) {
1423				syslog(LOG_NOTICE,
1424				    "FTP LOGIN FAILED FROM %s",
1425				    remotehost);
1426				syslog(LOG_AUTHPRIV | LOG_NOTICE,
1427				    "FTP LOGIN FAILED FROM %s, %s",
1428				    remotehost, curname);
1429			}
1430			pw = NULL;
1431			if (login_attempts++ >= 5) {
1432				syslog(LOG_NOTICE,
1433				    "repeated login failures from %s",
1434				    remotehost);
1435				exit(0);
1436			}
1437			return;
1438		}
1439	}
1440	login_attempts = 0;		/* this time successful */
1441	if (setegid(pw->pw_gid) < 0) {
1442		reply(550, "Can't set gid.");
1443		return;
1444	}
1445	/* May be overridden by login.conf */
1446	(void) umask(defumask);
1447#ifdef	LOGIN_CAP
1448	if ((lc = login_getpwclass(pw)) != NULL) {
1449		char	remote_ip[NI_MAXHOST];
1450
1451		if (getnameinfo((struct sockaddr *)&his_addr, his_addr.su_len,
1452			remote_ip, sizeof(remote_ip) - 1, NULL, 0,
1453			NI_NUMERICHOST))
1454				*remote_ip = 0;
1455		remote_ip[sizeof(remote_ip) - 1] = 0;
1456		if (!auth_hostok(lc, remotehost, remote_ip)) {
1457			syslog(LOG_INFO|LOG_AUTH,
1458			    "FTP LOGIN FAILED (HOST) as %s: permission denied.",
1459			    pw->pw_name);
1460			reply(530, "Permission denied.");
1461			pw = NULL;
1462			return;
1463		}
1464		if (!auth_timeok(lc, time(NULL))) {
1465			reply(530, "Login not available right now.");
1466			pw = NULL;
1467			return;
1468		}
1469	}
1470	setusercontext(lc, pw, 0, LOGIN_SETALL &
1471		       ~(LOGIN_SETRESOURCES | LOGIN_SETUSER | LOGIN_SETPATH | LOGIN_SETENV));
1472#else
1473	setlogin(pw->pw_name);
1474	(void) initgroups(pw->pw_name, pw->pw_gid);
1475#endif
1476
1477#ifdef USE_PAM
1478	if (pamh) {
1479		if ((e = pam_open_session(pamh, 0)) != PAM_SUCCESS) {
1480			syslog(LOG_ERR, "pam_open_session: %s", pam_strerror(pamh, e));
1481		} else if ((e = pam_setcred(pamh, PAM_ESTABLISH_CRED)) != PAM_SUCCESS) {
1482			syslog(LOG_ERR, "pam_setcred: %s", pam_strerror(pamh, e));
1483		}
1484	}
1485#endif
1486
1487	dochroot =
1488		checkuser(_PATH_FTPCHROOT, pw->pw_name, 1, &residue, &ecode)
1489#ifdef	LOGIN_CAP	/* Allow login.conf configuration as well */
1490		|| login_getcapbool(lc, "ftp-chroot", 0)
1491#endif
1492	;
1493	/*
1494	 * It is possible that checkuser() failed to open the chroot file.
1495	 * If this is the case, report that logins are un-available, since we
1496	 * have no way of checking whether or not the user should be chrooted.
1497	 * We ignore ENOENT since it is not required that this file be present.
1498	 */
1499	if (ecode != 0 && ecode != ENOENT) {
1500		reply(530, "Login not available right now.");
1501		return;
1502	}
1503	chrootdir = NULL;
1504
1505	/* Disable wtmp logging when chrooting. */
1506	if (dochroot || guest)
1507		dowtmp = 0;
1508	if (dowtmp)
1509		ftpd_logwtmp(wtmpid, pw->pw_name,
1510		    (struct sockaddr *)&his_addr);
1511	logged_in = 1;
1512
1513#ifdef	LOGIN_CAP
1514	setusercontext(lc, pw, 0, LOGIN_SETRESOURCES);
1515#endif
1516
1517	if (guest && stats && statfd < 0)
1518#ifdef VIRTUAL_HOSTING
1519		statfd = open(thishost->statfile, O_WRONLY|O_APPEND);
1520#else
1521		statfd = open(_PATH_FTPDSTATFILE, O_WRONLY|O_APPEND);
1522#endif
1523		if (statfd < 0)
1524			stats = 0;
1525
1526	/*
1527	 * For a chrooted local user,
1528	 * a) see whether ftpchroot(5) specifies a chroot directory,
1529	 * b) extract the directory pathname from the line,
1530	 * c) expand it to the absolute pathname if necessary.
1531	 */
1532	if (dochroot && residue &&
1533	    (chrootdir = strtok(residue, " \t")) != NULL) {
1534		if (chrootdir[0] != '/')
1535			asprintf(&chrootdir, "%s/%s", pw->pw_dir, chrootdir);
1536		else
1537			chrootdir = strdup(chrootdir); /* make it permanent */
1538		if (chrootdir == NULL)
1539			fatalerror("Ran out of memory.");
1540	}
1541	if (guest || dochroot) {
1542		/*
1543		 * If no chroot directory set yet, use the login directory.
1544		 * Copy it so it can be modified while pw->pw_dir stays intact.
1545		 */
1546		if (chrootdir == NULL &&
1547		    (chrootdir = strdup(pw->pw_dir)) == NULL)
1548			fatalerror("Ran out of memory.");
1549		/*
1550		 * Check for the "/chroot/./home" syntax,
1551		 * separate the chroot and home directory pathnames.
1552		 */
1553		if ((homedir = strstr(chrootdir, "/./")) != NULL) {
1554			*(homedir++) = '\0';	/* wipe '/' */
1555			homedir++;		/* skip '.' */
1556		} else {
1557			/*
1558			 * We MUST do a chdir() after the chroot. Otherwise
1559			 * the old current directory will be accessible as "."
1560			 * outside the new root!
1561			 */
1562			homedir = "/";
1563		}
1564		/*
1565		 * Finally, do chroot()
1566		 */
1567		if (chroot(chrootdir) < 0) {
1568			reply(550, "Can't change root.");
1569			goto bad;
1570		}
1571		__FreeBSD_libc_enter_restricted_mode();
1572	} else	/* real user w/o chroot */
1573		homedir = pw->pw_dir;
1574	/*
1575	 * Set euid *before* doing chdir() so
1576	 * a) the user won't be carried to a directory that he couldn't reach
1577	 *    on his own due to no permission to upper path components,
1578	 * b) NFS mounted homedirs w/restrictive permissions will be accessible
1579	 *    (uid 0 has no root power over NFS if not mapped explicitly.)
1580	 */
1581	if (seteuid(pw->pw_uid) < 0) {
1582		reply(550, "Can't set uid.");
1583		goto bad;
1584	}
1585	if (chdir(homedir) < 0) {
1586		if (guest || dochroot) {
1587			reply(550, "Can't change to base directory.");
1588			goto bad;
1589		} else {
1590			if (chdir("/") < 0) {
1591				reply(550, "Root is inaccessible.");
1592				goto bad;
1593			}
1594			lreply(230, "No directory! Logging in with home=/.");
1595		}
1596	}
1597
1598	/*
1599	 * Display a login message, if it exists.
1600	 * N.B. reply(230,) must follow the message.
1601	 */
1602#ifdef VIRTUAL_HOSTING
1603	fd = fopen(thishost->loginmsg, "r");
1604#else
1605	fd = fopen(_PATH_FTPLOGINMESG, "r");
1606#endif
1607	if (fd != NULL) {
1608		char *cp, line[LINE_MAX];
1609
1610		while (fgets(line, sizeof(line), fd) != NULL) {
1611			if ((cp = strchr(line, '\n')) != NULL)
1612				*cp = '\0';
1613			lreply(230, "%s", line);
1614		}
1615		(void) fflush(stdout);
1616		(void) fclose(fd);
1617	}
1618	if (guest) {
1619		if (ident != NULL)
1620			free(ident);
1621		ident = strdup(passwd);
1622		if (ident == NULL)
1623			fatalerror("Ran out of memory.");
1624
1625		reply(230, "Guest login ok, access restrictions apply.");
1626#ifdef SETPROCTITLE
1627#ifdef VIRTUAL_HOSTING
1628		if (thishost != firsthost)
1629			snprintf(proctitle, sizeof(proctitle),
1630				 "%s: anonymous(%s)/%s", remotehost, hostname,
1631				 passwd);
1632		else
1633#endif
1634			snprintf(proctitle, sizeof(proctitle),
1635				 "%s: anonymous/%s", remotehost, passwd);
1636		setproctitle("%s", proctitle);
1637#endif /* SETPROCTITLE */
1638		if (logging)
1639			syslog(LOG_INFO, "ANONYMOUS FTP LOGIN FROM %s, %s",
1640			    remotehost, passwd);
1641	} else {
1642		if (dochroot)
1643			reply(230, "User %s logged in, "
1644				   "access restrictions apply.", pw->pw_name);
1645		else
1646			reply(230, "User %s logged in.", pw->pw_name);
1647
1648#ifdef SETPROCTITLE
1649		snprintf(proctitle, sizeof(proctitle),
1650			 "%s: user/%s", remotehost, pw->pw_name);
1651		setproctitle("%s", proctitle);
1652#endif /* SETPROCTITLE */
1653		if (logging)
1654			syslog(LOG_INFO, "FTP LOGIN FROM %s as %s",
1655			    remotehost, pw->pw_name);
1656	}
1657	if (logging && (guest || dochroot))
1658		syslog(LOG_INFO, "session root changed to %s", chrootdir);
1659#ifdef	LOGIN_CAP
1660	login_close(lc);
1661#endif
1662	if (residue)
1663		free(residue);
1664	return;
1665bad:
1666	/* Forget all about it... */
1667#ifdef	LOGIN_CAP
1668	login_close(lc);
1669#endif
1670	if (residue)
1671		free(residue);
1672	end_login();
1673}
1674
1675void
1676retrieve(char *cmd, char *name)
1677{
1678	FILE *fin, *dout;
1679	struct stat st;
1680	int (*closefunc)(FILE *);
1681	time_t start;
1682	char line[BUFSIZ];
1683
1684	if (cmd == 0) {
1685		fin = fopen(name, "r"), closefunc = fclose;
1686		st.st_size = 0;
1687	} else {
1688		(void) snprintf(line, sizeof(line), cmd, name);
1689		name = line;
1690		fin = ftpd_popen(line, "r"), closefunc = ftpd_pclose;
1691		st.st_size = -1;
1692		st.st_blksize = BUFSIZ;
1693	}
1694	if (fin == NULL) {
1695		if (errno != 0) {
1696			perror_reply(550, name);
1697			if (cmd == 0) {
1698				LOGCMD("get", name);
1699			}
1700		}
1701		return;
1702	}
1703	byte_count = -1;
1704	if (cmd == 0) {
1705		if (fstat(fileno(fin), &st) < 0) {
1706			perror_reply(550, name);
1707			goto done;
1708		}
1709		if (!S_ISREG(st.st_mode)) {
1710			/*
1711			 * Never sending a raw directory is a workaround
1712			 * for buggy clients that will attempt to RETR
1713			 * a directory before listing it, e.g., Mozilla.
1714			 * Preventing a guest from getting irregular files
1715			 * is a simple security measure.
1716			 */
1717			if (S_ISDIR(st.st_mode) || guest) {
1718				reply(550, "%s: not a plain file.", name);
1719				goto done;
1720			}
1721			st.st_size = -1;
1722			/* st.st_blksize is set for all descriptor types */
1723		}
1724	}
1725	if (restart_point) {
1726		if (type == TYPE_A) {
1727			off_t i, n;
1728			int c;
1729
1730			n = restart_point;
1731			i = 0;
1732			while (i++ < n) {
1733				if ((c=getc(fin)) == EOF) {
1734					perror_reply(550, name);
1735					goto done;
1736				}
1737				if (c == '\n')
1738					i++;
1739			}
1740		} else if (lseek(fileno(fin), restart_point, L_SET) < 0) {
1741			perror_reply(550, name);
1742			goto done;
1743		}
1744	}
1745	dout = dataconn(name, st.st_size, "w");
1746	if (dout == NULL)
1747		goto done;
1748	time(&start);
1749	send_data(fin, dout, st.st_blksize, st.st_size,
1750		  restart_point == 0 && cmd == 0 && S_ISREG(st.st_mode));
1751	if (cmd == 0 && guest && stats && byte_count > 0)
1752		logxfer(name, byte_count, start);
1753	(void) fclose(dout);
1754	data = -1;
1755	pdata = -1;
1756done:
1757	if (cmd == 0)
1758		LOGBYTES("get", name, byte_count);
1759	(*closefunc)(fin);
1760}
1761
1762void
1763store(char *name, char *mode, int unique)
1764{
1765	int fd;
1766	FILE *fout, *din;
1767	int (*closefunc)(FILE *);
1768
1769	if (*mode == 'a') {		/* APPE */
1770		if (unique) {
1771			/* Programming error */
1772			syslog(LOG_ERR, "Internal: unique flag to APPE");
1773			unique = 0;
1774		}
1775		if (guest && noguestmod) {
1776			reply(550, "Appending to existing file denied.");
1777			goto err;
1778		}
1779		restart_point = 0;	/* not affected by preceding REST */
1780	}
1781	if (unique)			/* STOU overrides REST */
1782		restart_point = 0;
1783	if (guest && noguestmod) {
1784		if (restart_point) {	/* guest STOR w/REST */
1785			reply(550, "Modifying existing file denied.");
1786			goto err;
1787		} else			/* treat guest STOR as STOU */
1788			unique = 1;
1789	}
1790
1791	if (restart_point)
1792		mode = "r+";	/* so ASCII manual seek can work */
1793	if (unique) {
1794		if ((fd = guniquefd(name, &name)) < 0)
1795			goto err;
1796		fout = fdopen(fd, mode);
1797	} else
1798		fout = fopen(name, mode);
1799	closefunc = fclose;
1800	if (fout == NULL) {
1801		perror_reply(553, name);
1802		goto err;
1803	}
1804	byte_count = -1;
1805	if (restart_point) {
1806		if (type == TYPE_A) {
1807			off_t i, n;
1808			int c;
1809
1810			n = restart_point;
1811			i = 0;
1812			while (i++ < n) {
1813				if ((c=getc(fout)) == EOF) {
1814					perror_reply(550, name);
1815					goto done;
1816				}
1817				if (c == '\n')
1818					i++;
1819			}
1820			/*
1821			 * We must do this seek to "current" position
1822			 * because we are changing from reading to
1823			 * writing.
1824			 */
1825			if (fseeko(fout, 0, SEEK_CUR) < 0) {
1826				perror_reply(550, name);
1827				goto done;
1828			}
1829		} else if (lseek(fileno(fout), restart_point, L_SET) < 0) {
1830			perror_reply(550, name);
1831			goto done;
1832		}
1833	}
1834	din = dataconn(name, -1, "r");
1835	if (din == NULL)
1836		goto done;
1837	if (receive_data(din, fout) == 0) {
1838		if (unique)
1839			reply(226, "Transfer complete (unique file name:%s).",
1840			    name);
1841		else
1842			reply(226, "Transfer complete.");
1843	}
1844	(void) fclose(din);
1845	data = -1;
1846	pdata = -1;
1847done:
1848	LOGBYTES(*mode == 'a' ? "append" : "put", name, byte_count);
1849	(*closefunc)(fout);
1850	return;
1851err:
1852	LOGCMD(*mode == 'a' ? "append" : "put" , name);
1853	return;
1854}
1855
1856static FILE *
1857getdatasock(char *mode)
1858{
1859	int on = 1, s, t, tries;
1860
1861	if (data >= 0)
1862		return (fdopen(data, mode));
1863
1864	s = socket(data_dest.su_family, SOCK_STREAM, 0);
1865	if (s < 0)
1866		goto bad;
1867	if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0)
1868		syslog(LOG_WARNING, "data setsockopt (SO_REUSEADDR): %m");
1869	/* anchor socket to avoid multi-homing problems */
1870	data_source = ctrl_addr;
1871	data_source.su_port = htons(dataport);
1872	(void) seteuid(0);
1873	for (tries = 1; ; tries++) {
1874		/*
1875		 * We should loop here since it's possible that
1876		 * another ftpd instance has passed this point and is
1877		 * trying to open a data connection in active mode now.
1878		 * Until the other connection is opened, we'll be getting
1879		 * EADDRINUSE because no SOCK_STREAM sockets in the system
1880		 * can share both local and remote addresses, localIP:20
1881		 * and *:* in this case.
1882		 */
1883		if (bind(s, (struct sockaddr *)&data_source,
1884		    data_source.su_len) >= 0)
1885			break;
1886		if (errno != EADDRINUSE || tries > 10)
1887			goto bad;
1888		sleep(tries);
1889	}
1890	(void) seteuid(pw->pw_uid);
1891#ifdef IP_TOS
1892	if (data_source.su_family == AF_INET)
1893      {
1894	on = IPTOS_THROUGHPUT;
1895	if (setsockopt(s, IPPROTO_IP, IP_TOS, &on, sizeof(int)) < 0)
1896		syslog(LOG_WARNING, "data setsockopt (IP_TOS): %m");
1897      }
1898#endif
1899#ifdef TCP_NOPUSH
1900	/*
1901	 * Turn off push flag to keep sender TCP from sending short packets
1902	 * at the boundaries of each write().
1903	 */
1904	on = 1;
1905	if (setsockopt(s, IPPROTO_TCP, TCP_NOPUSH, &on, sizeof on) < 0)
1906		syslog(LOG_WARNING, "data setsockopt (TCP_NOPUSH): %m");
1907#endif
1908	return (fdopen(s, mode));
1909bad:
1910	/* Return the real value of errno (close may change it) */
1911	t = errno;
1912	(void) seteuid(pw->pw_uid);
1913	(void) close(s);
1914	errno = t;
1915	return (NULL);
1916}
1917
1918static FILE *
1919dataconn(char *name, off_t size, char *mode)
1920{
1921	char sizebuf[32];
1922	FILE *file;
1923	int retry = 0, tos, conerrno;
1924
1925	file_size = size;
1926	byte_count = 0;
1927	if (size != -1)
1928		(void) snprintf(sizebuf, sizeof(sizebuf),
1929				" (%jd bytes)", (intmax_t)size);
1930	else
1931		*sizebuf = '\0';
1932	if (pdata >= 0) {
1933		union sockunion from;
1934		socklen_t fromlen = ctrl_addr.su_len;
1935		int flags, s;
1936		struct timeval timeout;
1937		fd_set set;
1938
1939		FD_ZERO(&set);
1940		FD_SET(pdata, &set);
1941
1942		timeout.tv_usec = 0;
1943		timeout.tv_sec = 120;
1944
1945		/*
1946		 * Granted a socket is in the blocking I/O mode,
1947		 * accept() will block after a successful select()
1948		 * if the selected connection dies in between.
1949		 * Therefore set the non-blocking I/O flag here.
1950		 */
1951		if ((flags = fcntl(pdata, F_GETFL, 0)) == -1 ||
1952		    fcntl(pdata, F_SETFL, flags | O_NONBLOCK) == -1)
1953			goto pdata_err;
1954		if (select(pdata+1, &set, NULL, NULL, &timeout) <= 0 ||
1955		    (s = accept(pdata, (struct sockaddr *) &from, &fromlen)) < 0)
1956			goto pdata_err;
1957		(void) close(pdata);
1958		pdata = s;
1959		/*
1960		 * Unset the inherited non-blocking I/O flag
1961		 * on the child socket so stdio can work on it.
1962		 */
1963		if ((flags = fcntl(pdata, F_GETFL, 0)) == -1 ||
1964		    fcntl(pdata, F_SETFL, flags & ~O_NONBLOCK) == -1)
1965			goto pdata_err;
1966#ifdef IP_TOS
1967		if (from.su_family == AF_INET)
1968	      {
1969		tos = IPTOS_THROUGHPUT;
1970		if (setsockopt(s, IPPROTO_IP, IP_TOS, &tos, sizeof(int)) < 0)
1971			syslog(LOG_WARNING, "pdata setsockopt (IP_TOS): %m");
1972	      }
1973#endif
1974		reply(150, "Opening %s mode data connection for '%s'%s.",
1975		     type == TYPE_A ? "ASCII" : "BINARY", name, sizebuf);
1976		return (fdopen(pdata, mode));
1977pdata_err:
1978		reply(425, "Can't open data connection.");
1979		(void) close(pdata);
1980		pdata = -1;
1981		return (NULL);
1982	}
1983	if (data >= 0) {
1984		reply(125, "Using existing data connection for '%s'%s.",
1985		    name, sizebuf);
1986		usedefault = 1;
1987		return (fdopen(data, mode));
1988	}
1989	if (usedefault)
1990		data_dest = his_addr;
1991	usedefault = 1;
1992	do {
1993		file = getdatasock(mode);
1994		if (file == NULL) {
1995			char hostbuf[NI_MAXHOST], portbuf[NI_MAXSERV];
1996
1997			if (getnameinfo((struct sockaddr *)&data_source,
1998				data_source.su_len,
1999				hostbuf, sizeof(hostbuf) - 1,
2000				portbuf, sizeof(portbuf) - 1,
2001				NI_NUMERICHOST|NI_NUMERICSERV))
2002					*hostbuf = *portbuf = 0;
2003			hostbuf[sizeof(hostbuf) - 1] = 0;
2004			portbuf[sizeof(portbuf) - 1] = 0;
2005			reply(425, "Can't create data socket (%s,%s): %s.",
2006				hostbuf, portbuf, strerror(errno));
2007			return (NULL);
2008		}
2009		data = fileno(file);
2010		conerrno = 0;
2011		if (connect(data, (struct sockaddr *)&data_dest,
2012		    data_dest.su_len) == 0)
2013			break;
2014		conerrno = errno;
2015		(void) fclose(file);
2016		data = -1;
2017		if (conerrno == EADDRINUSE) {
2018			sleep(swaitint);
2019			retry += swaitint;
2020		} else {
2021			break;
2022		}
2023	} while (retry <= swaitmax);
2024	if (conerrno != 0) {
2025		reply(425, "Can't build data connection: %s.",
2026			   strerror(conerrno));
2027		return (NULL);
2028	}
2029	reply(150, "Opening %s mode data connection for '%s'%s.",
2030	     type == TYPE_A ? "ASCII" : "BINARY", name, sizebuf);
2031	return (file);
2032}
2033
2034/*
2035 * A helper macro to avoid code duplication
2036 * in send_data() and receive_data().
2037 *
2038 * XXX We have to block SIGURG during putc() because BSD stdio
2039 * is unable to restart interrupted write operations and hence
2040 * the entire buffer contents will be lost as soon as a write()
2041 * call indicates EINTR to stdio.
2042 */
2043#define FTPD_PUTC(ch, file, label)					\
2044	do {								\
2045		int ret;						\
2046									\
2047		do {							\
2048			START_UNSAFE;					\
2049			ret = putc((ch), (file));			\
2050			END_UNSAFE;					\
2051			CHECKOOB(return (-1))				\
2052			else if (ferror(file))				\
2053				goto label;				\
2054			clearerr(file);					\
2055		} while (ret == EOF);					\
2056	} while (0)
2057
2058/*
2059 * Tranfer the contents of "instr" to "outstr" peer using the appropriate
2060 * encapsulation of the data subject to Mode, Structure, and Type.
2061 *
2062 * NB: Form isn't handled.
2063 */
2064static int
2065send_data(FILE *instr, FILE *outstr, size_t blksize, off_t filesize, int isreg)
2066{
2067	int c, cp, filefd, netfd;
2068	char *buf;
2069
2070	STARTXFER;
2071
2072	switch (type) {
2073
2074	case TYPE_A:
2075		cp = EOF;
2076		for (;;) {
2077			c = getc(instr);
2078			CHECKOOB(return (-1))
2079			else if (c == EOF && ferror(instr))
2080				goto file_err;
2081			if (c == EOF) {
2082				if (ferror(instr)) {	/* resume after OOB */
2083					clearerr(instr);
2084					continue;
2085				}
2086				if (feof(instr))	/* EOF */
2087					break;
2088				syslog(LOG_ERR, "Internal: impossible condition"
2089						" on file after getc()");
2090				goto file_err;
2091			}
2092			if (c == '\n' && cp != '\r') {
2093				FTPD_PUTC('\r', outstr, data_err);
2094				byte_count++;
2095			}
2096			FTPD_PUTC(c, outstr, data_err);
2097			byte_count++;
2098			cp = c;
2099		}
2100#ifdef notyet	/* BSD stdio isn't ready for that */
2101		while (fflush(outstr) == EOF) {
2102			CHECKOOB(return (-1))
2103			else
2104				goto data_err;
2105			clearerr(outstr);
2106		}
2107		ENDXFER;
2108#else
2109		ENDXFER;
2110		if (fflush(outstr) == EOF)
2111			goto data_err;
2112#endif
2113		reply(226, "Transfer complete.");
2114		return (0);
2115
2116	case TYPE_I:
2117	case TYPE_L:
2118		/*
2119		 * isreg is only set if we are not doing restart and we
2120		 * are sending a regular file
2121		 */
2122		netfd = fileno(outstr);
2123		filefd = fileno(instr);
2124
2125		if (isreg) {
2126			char *msg = "Transfer complete.";
2127			off_t cnt, offset;
2128			int err;
2129
2130			cnt = offset = 0;
2131
2132			while (filesize > 0) {
2133				err = sendfile(filefd, netfd, offset, 0,
2134					       NULL, &cnt, 0);
2135				/*
2136				 * Calculate byte_count before OOB processing.
2137				 * It can be used in myoob() later.
2138				 */
2139				byte_count += cnt;
2140				offset += cnt;
2141				filesize -= cnt;
2142				CHECKOOB(return (-1))
2143				else if (err == -1) {
2144					if (errno != EINTR &&
2145					    cnt == 0 && offset == 0)
2146						goto oldway;
2147					goto data_err;
2148				}
2149				if (err == -1)	/* resume after OOB */
2150					continue;
2151				/*
2152				 * We hit the EOF prematurely.
2153				 * Perhaps the file was externally truncated.
2154				 */
2155				if (cnt == 0) {
2156					msg = "Transfer finished due to "
2157					      "premature end of file.";
2158					break;
2159				}
2160			}
2161			ENDXFER;
2162			reply(226, "%s", msg);
2163			return (0);
2164		}
2165
2166oldway:
2167		if ((buf = malloc(blksize)) == NULL) {
2168			ENDXFER;
2169			reply(451, "Ran out of memory.");
2170			return (-1);
2171		}
2172
2173		for (;;) {
2174			int cnt, len;
2175			char *bp;
2176
2177			cnt = read(filefd, buf, blksize);
2178			CHECKOOB(free(buf); return (-1))
2179			else if (cnt < 0) {
2180				free(buf);
2181				goto file_err;
2182			}
2183			if (cnt < 0)	/* resume after OOB */
2184				continue;
2185			if (cnt == 0)	/* EOF */
2186				break;
2187			for (len = cnt, bp = buf; len > 0;) {
2188				cnt = write(netfd, bp, len);
2189				CHECKOOB(free(buf); return (-1))
2190				else if (cnt < 0) {
2191					free(buf);
2192					goto data_err;
2193				}
2194				if (cnt <= 0)
2195					continue;
2196				len -= cnt;
2197				bp += cnt;
2198				byte_count += cnt;
2199			}
2200		}
2201		ENDXFER;
2202		free(buf);
2203		reply(226, "Transfer complete.");
2204		return (0);
2205	default:
2206		ENDXFER;
2207		reply(550, "Unimplemented TYPE %d in send_data.", type);
2208		return (-1);
2209	}
2210
2211data_err:
2212	ENDXFER;
2213	perror_reply(426, "Data connection");
2214	return (-1);
2215
2216file_err:
2217	ENDXFER;
2218	perror_reply(551, "Error on input file");
2219	return (-1);
2220}
2221
2222/*
2223 * Transfer data from peer to "outstr" using the appropriate encapulation of
2224 * the data subject to Mode, Structure, and Type.
2225 *
2226 * N.B.: Form isn't handled.
2227 */
2228static int
2229receive_data(FILE *instr, FILE *outstr)
2230{
2231	int c, cp;
2232	int bare_lfs = 0;
2233
2234	STARTXFER;
2235
2236	switch (type) {
2237
2238	case TYPE_I:
2239	case TYPE_L:
2240		for (;;) {
2241			int cnt, len;
2242			char *bp;
2243			char buf[BUFSIZ];
2244
2245			cnt = read(fileno(instr), buf, sizeof(buf));
2246			CHECKOOB(return (-1))
2247			else if (cnt < 0)
2248				goto data_err;
2249			if (cnt < 0)	/* resume after OOB */
2250				continue;
2251			if (cnt == 0)	/* EOF */
2252				break;
2253			for (len = cnt, bp = buf; len > 0;) {
2254				cnt = write(fileno(outstr), bp, len);
2255				CHECKOOB(return (-1))
2256				else if (cnt < 0)
2257					goto file_err;
2258				if (cnt <= 0)
2259					continue;
2260				len -= cnt;
2261				bp += cnt;
2262				byte_count += cnt;
2263			}
2264		}
2265		ENDXFER;
2266		return (0);
2267
2268	case TYPE_E:
2269		ENDXFER;
2270		reply(553, "TYPE E not implemented.");
2271		return (-1);
2272
2273	case TYPE_A:
2274		cp = EOF;
2275		for (;;) {
2276			c = getc(instr);
2277			CHECKOOB(return (-1))
2278			else if (c == EOF && ferror(instr))
2279				goto data_err;
2280			if (c == EOF && ferror(instr)) { /* resume after OOB */
2281				clearerr(instr);
2282				continue;
2283			}
2284
2285			if (cp == '\r') {
2286				if (c != '\n')
2287					FTPD_PUTC('\r', outstr, file_err);
2288			} else
2289				if (c == '\n')
2290					bare_lfs++;
2291			if (c == '\r') {
2292				byte_count++;
2293				cp = c;
2294				continue;
2295			}
2296
2297			/* Check for EOF here in order not to lose last \r. */
2298			if (c == EOF) {
2299				if (feof(instr))	/* EOF */
2300					break;
2301				syslog(LOG_ERR, "Internal: impossible condition"
2302						" on data stream after getc()");
2303				goto data_err;
2304			}
2305
2306			byte_count++;
2307			FTPD_PUTC(c, outstr, file_err);
2308			cp = c;
2309		}
2310#ifdef notyet	/* BSD stdio isn't ready for that */
2311		while (fflush(outstr) == EOF) {
2312			CHECKOOB(return (-1))
2313			else
2314				goto file_err;
2315			clearerr(outstr);
2316		}
2317		ENDXFER;
2318#else
2319		ENDXFER;
2320		if (fflush(outstr) == EOF)
2321			goto file_err;
2322#endif
2323		if (bare_lfs) {
2324			lreply(226,
2325		"WARNING! %d bare linefeeds received in ASCII mode.",
2326			    bare_lfs);
2327		(void)printf("   File may not have transferred correctly.\r\n");
2328		}
2329		return (0);
2330	default:
2331		ENDXFER;
2332		reply(550, "Unimplemented TYPE %d in receive_data.", type);
2333		return (-1);
2334	}
2335
2336data_err:
2337	ENDXFER;
2338	perror_reply(426, "Data connection");
2339	return (-1);
2340
2341file_err:
2342	ENDXFER;
2343	perror_reply(452, "Error writing to file");
2344	return (-1);
2345}
2346
2347void
2348statfilecmd(char *filename)
2349{
2350	FILE *fin;
2351	int atstart;
2352	int c, code;
2353	char line[LINE_MAX];
2354	struct stat st;
2355
2356	code = lstat(filename, &st) == 0 && S_ISDIR(st.st_mode) ? 212 : 213;
2357	(void)snprintf(line, sizeof(line), _PATH_LS " -lgA %s", filename);
2358	fin = ftpd_popen(line, "r");
2359	if (fin == NULL) {
2360		perror_reply(551, filename);
2361		return;
2362	}
2363	lreply(code, "Status of %s:", filename);
2364	atstart = 1;
2365	while ((c = getc(fin)) != EOF) {
2366		if (c == '\n') {
2367			if (ferror(stdout)){
2368				perror_reply(421, "Control connection");
2369				(void) ftpd_pclose(fin);
2370				dologout(1);
2371				/* NOTREACHED */
2372			}
2373			if (ferror(fin)) {
2374				perror_reply(551, filename);
2375				(void) ftpd_pclose(fin);
2376				return;
2377			}
2378			(void) putc('\r', stdout);
2379		}
2380		/*
2381		 * RFC 959 says neutral text should be prepended before
2382		 * a leading 3-digit number followed by whitespace, but
2383		 * many ftp clients can be confused by any leading digits,
2384		 * as a matter of fact.
2385		 */
2386		if (atstart && isdigit(c))
2387			(void) putc(' ', stdout);
2388		(void) putc(c, stdout);
2389		atstart = (c == '\n');
2390	}
2391	(void) ftpd_pclose(fin);
2392	reply(code, "End of status.");
2393}
2394
2395void
2396statcmd(void)
2397{
2398	union sockunion *su;
2399	u_char *a, *p;
2400	char hname[NI_MAXHOST];
2401	int ispassive;
2402
2403	if (hostinfo) {
2404		lreply(211, "%s FTP server status:", hostname);
2405		printf("     %s\r\n", version);
2406	} else
2407		lreply(211, "FTP server status:");
2408	printf("     Connected to %s", remotehost);
2409	if (!getnameinfo((struct sockaddr *)&his_addr, his_addr.su_len,
2410			 hname, sizeof(hname) - 1, NULL, 0, NI_NUMERICHOST)) {
2411		hname[sizeof(hname) - 1] = 0;
2412		if (strcmp(hname, remotehost) != 0)
2413			printf(" (%s)", hname);
2414	}
2415	printf("\r\n");
2416	if (logged_in) {
2417		if (guest)
2418			printf("     Logged in anonymously\r\n");
2419		else
2420			printf("     Logged in as %s\r\n", pw->pw_name);
2421	} else if (askpasswd)
2422		printf("     Waiting for password\r\n");
2423	else
2424		printf("     Waiting for user name\r\n");
2425	printf("     TYPE: %s", typenames[type]);
2426	if (type == TYPE_A || type == TYPE_E)
2427		printf(", FORM: %s", formnames[form]);
2428	if (type == TYPE_L)
2429#if CHAR_BIT == 8
2430		printf(" %d", CHAR_BIT);
2431#else
2432		printf(" %d", bytesize);	/* need definition! */
2433#endif
2434	printf("; STRUcture: %s; transfer MODE: %s\r\n",
2435	    strunames[stru], modenames[mode]);
2436	if (data != -1)
2437		printf("     Data connection open\r\n");
2438	else if (pdata != -1) {
2439		ispassive = 1;
2440		su = &pasv_addr;
2441		goto printaddr;
2442	} else if (usedefault == 0) {
2443		ispassive = 0;
2444		su = &data_dest;
2445printaddr:
2446#define UC(b) (((int) b) & 0xff)
2447		if (epsvall) {
2448			printf("     EPSV only mode (EPSV ALL)\r\n");
2449			goto epsvonly;
2450		}
2451
2452		/* PORT/PASV */
2453		if (su->su_family == AF_INET) {
2454			a = (u_char *) &su->su_sin.sin_addr;
2455			p = (u_char *) &su->su_sin.sin_port;
2456			printf("     %s (%d,%d,%d,%d,%d,%d)\r\n",
2457				ispassive ? "PASV" : "PORT",
2458				UC(a[0]), UC(a[1]), UC(a[2]), UC(a[3]),
2459				UC(p[0]), UC(p[1]));
2460		}
2461
2462		/* LPRT/LPSV */
2463	    {
2464		int alen, af, i;
2465
2466		switch (su->su_family) {
2467		case AF_INET:
2468			a = (u_char *) &su->su_sin.sin_addr;
2469			p = (u_char *) &su->su_sin.sin_port;
2470			alen = sizeof(su->su_sin.sin_addr);
2471			af = 4;
2472			break;
2473		case AF_INET6:
2474			a = (u_char *) &su->su_sin6.sin6_addr;
2475			p = (u_char *) &su->su_sin6.sin6_port;
2476			alen = sizeof(su->su_sin6.sin6_addr);
2477			af = 6;
2478			break;
2479		default:
2480			af = 0;
2481			break;
2482		}
2483		if (af) {
2484			printf("     %s (%d,%d,", ispassive ? "LPSV" : "LPRT",
2485				af, alen);
2486			for (i = 0; i < alen; i++)
2487				printf("%d,", UC(a[i]));
2488			printf("%d,%d,%d)\r\n", 2, UC(p[0]), UC(p[1]));
2489		}
2490	    }
2491
2492epsvonly:;
2493		/* EPRT/EPSV */
2494	    {
2495		int af;
2496
2497		switch (su->su_family) {
2498		case AF_INET:
2499			af = 1;
2500			break;
2501		case AF_INET6:
2502			af = 2;
2503			break;
2504		default:
2505			af = 0;
2506			break;
2507		}
2508		if (af) {
2509			union sockunion tmp;
2510
2511			tmp = *su;
2512			if (tmp.su_family == AF_INET6)
2513				tmp.su_sin6.sin6_scope_id = 0;
2514			if (!getnameinfo((struct sockaddr *)&tmp, tmp.su_len,
2515					hname, sizeof(hname) - 1, NULL, 0,
2516					NI_NUMERICHOST)) {
2517				hname[sizeof(hname) - 1] = 0;
2518				printf("     %s |%d|%s|%d|\r\n",
2519					ispassive ? "EPSV" : "EPRT",
2520					af, hname, htons(tmp.su_port));
2521			}
2522		}
2523	    }
2524#undef UC
2525	} else
2526		printf("     No data connection\r\n");
2527	reply(211, "End of status.");
2528}
2529
2530void
2531fatalerror(char *s)
2532{
2533
2534	reply(451, "Error in server: %s", s);
2535	reply(221, "Closing connection due to server error.");
2536	dologout(0);
2537	/* NOTREACHED */
2538}
2539
2540void
2541reply(int n, const char *fmt, ...)
2542{
2543	va_list ap;
2544
2545	(void)printf("%d ", n);
2546	va_start(ap, fmt);
2547	(void)vprintf(fmt, ap);
2548	va_end(ap);
2549	(void)printf("\r\n");
2550	(void)fflush(stdout);
2551	if (ftpdebug) {
2552		syslog(LOG_DEBUG, "<--- %d ", n);
2553		va_start(ap, fmt);
2554		vsyslog(LOG_DEBUG, fmt, ap);
2555		va_end(ap);
2556	}
2557}
2558
2559void
2560lreply(int n, const char *fmt, ...)
2561{
2562	va_list ap;
2563
2564	(void)printf("%d- ", n);
2565	va_start(ap, fmt);
2566	(void)vprintf(fmt, ap);
2567	va_end(ap);
2568	(void)printf("\r\n");
2569	(void)fflush(stdout);
2570	if (ftpdebug) {
2571		syslog(LOG_DEBUG, "<--- %d- ", n);
2572		va_start(ap, fmt);
2573		vsyslog(LOG_DEBUG, fmt, ap);
2574		va_end(ap);
2575	}
2576}
2577
2578static void
2579ack(char *s)
2580{
2581
2582	reply(250, "%s command successful.", s);
2583}
2584
2585void
2586nack(char *s)
2587{
2588
2589	reply(502, "%s command not implemented.", s);
2590}
2591
2592/* ARGSUSED */
2593void
2594yyerror(char *s)
2595{
2596	char *cp;
2597
2598	if ((cp = strchr(cbuf,'\n')))
2599		*cp = '\0';
2600	reply(500, "%s: command not understood.", cbuf);
2601}
2602
2603void
2604delete(char *name)
2605{
2606	struct stat st;
2607
2608	LOGCMD("delete", name);
2609	if (lstat(name, &st) < 0) {
2610		perror_reply(550, name);
2611		return;
2612	}
2613	if (S_ISDIR(st.st_mode)) {
2614		if (rmdir(name) < 0) {
2615			perror_reply(550, name);
2616			return;
2617		}
2618		goto done;
2619	}
2620	if (guest && noguestmod) {
2621		reply(550, "Operation not permitted.");
2622		return;
2623	}
2624	if (unlink(name) < 0) {
2625		perror_reply(550, name);
2626		return;
2627	}
2628done:
2629	ack("DELE");
2630}
2631
2632void
2633cwd(char *path)
2634{
2635
2636	if (chdir(path) < 0)
2637		perror_reply(550, path);
2638	else
2639		ack("CWD");
2640}
2641
2642void
2643makedir(char *name)
2644{
2645	char *s;
2646
2647	LOGCMD("mkdir", name);
2648	if (guest && noguestmkd)
2649		reply(550, "Operation not permitted.");
2650	else if (mkdir(name, 0777) < 0)
2651		perror_reply(550, name);
2652	else {
2653		if ((s = doublequote(name)) == NULL)
2654			fatalerror("Ran out of memory.");
2655		reply(257, "\"%s\" directory created.", s);
2656		free(s);
2657	}
2658}
2659
2660void
2661removedir(char *name)
2662{
2663
2664	LOGCMD("rmdir", name);
2665	if (rmdir(name) < 0)
2666		perror_reply(550, name);
2667	else
2668		ack("RMD");
2669}
2670
2671void
2672pwd(void)
2673{
2674	char *s, path[MAXPATHLEN + 1];
2675
2676	if (getcwd(path, sizeof(path)) == NULL)
2677		perror_reply(550, "Get current directory");
2678	else {
2679		if ((s = doublequote(path)) == NULL)
2680			fatalerror("Ran out of memory.");
2681		reply(257, "\"%s\" is current directory.", s);
2682		free(s);
2683	}
2684}
2685
2686char *
2687renamefrom(char *name)
2688{
2689	struct stat st;
2690
2691	if (guest && noguestmod) {
2692		reply(550, "Operation not permitted.");
2693		return (NULL);
2694	}
2695	if (lstat(name, &st) < 0) {
2696		perror_reply(550, name);
2697		return (NULL);
2698	}
2699	reply(350, "File exists, ready for destination name.");
2700	return (name);
2701}
2702
2703void
2704renamecmd(char *from, char *to)
2705{
2706	struct stat st;
2707
2708	LOGCMD2("rename", from, to);
2709
2710	if (guest && (stat(to, &st) == 0)) {
2711		reply(550, "%s: permission denied.", to);
2712		return;
2713	}
2714
2715	if (rename(from, to) < 0)
2716		perror_reply(550, "rename");
2717	else
2718		ack("RNTO");
2719}
2720
2721static void
2722dolog(struct sockaddr *who)
2723{
2724	char who_name[NI_MAXHOST];
2725
2726	realhostname_sa(remotehost, sizeof(remotehost) - 1, who, who->sa_len);
2727	remotehost[sizeof(remotehost) - 1] = 0;
2728	if (getnameinfo(who, who->sa_len,
2729		who_name, sizeof(who_name) - 1, NULL, 0, NI_NUMERICHOST))
2730			*who_name = 0;
2731	who_name[sizeof(who_name) - 1] = 0;
2732
2733#ifdef SETPROCTITLE
2734#ifdef VIRTUAL_HOSTING
2735	if (thishost != firsthost)
2736		snprintf(proctitle, sizeof(proctitle), "%s: connected (to %s)",
2737			 remotehost, hostname);
2738	else
2739#endif
2740		snprintf(proctitle, sizeof(proctitle), "%s: connected",
2741			 remotehost);
2742	setproctitle("%s", proctitle);
2743#endif /* SETPROCTITLE */
2744
2745	if (logging) {
2746#ifdef VIRTUAL_HOSTING
2747		if (thishost != firsthost)
2748			syslog(LOG_INFO, "connection from %s (%s) to %s",
2749			       remotehost, who_name, hostname);
2750		else
2751#endif
2752			syslog(LOG_INFO, "connection from %s (%s)",
2753			       remotehost, who_name);
2754	}
2755}
2756
2757/*
2758 * Record logout in wtmp file
2759 * and exit with supplied status.
2760 */
2761void
2762dologout(int status)
2763{
2764
2765	if (logged_in && dowtmp) {
2766		(void) seteuid(0);
2767#ifdef		LOGIN_CAP
2768 	        setusercontext(NULL, getpwuid(0), 0, LOGIN_SETALL & ~(LOGIN_SETLOGIN |
2769		       LOGIN_SETUSER | LOGIN_SETGROUP | LOGIN_SETPATH |
2770		       LOGIN_SETENV));
2771#endif
2772		ftpd_logwtmp(wtmpid, NULL, NULL);
2773	}
2774	/* beware of flushing buffers after a SIGPIPE */
2775	_exit(status);
2776}
2777
2778static void
2779sigurg(int signo)
2780{
2781
2782	recvurg = 1;
2783}
2784
2785static void
2786maskurg(int flag)
2787{
2788	int oerrno;
2789	sigset_t sset;
2790
2791	if (!transflag) {
2792		syslog(LOG_ERR, "Internal: maskurg() while no transfer");
2793		return;
2794	}
2795	oerrno = errno;
2796	sigemptyset(&sset);
2797	sigaddset(&sset, SIGURG);
2798	sigprocmask(flag ? SIG_BLOCK : SIG_UNBLOCK, &sset, NULL);
2799	errno = oerrno;
2800}
2801
2802static void
2803flagxfer(int flag)
2804{
2805
2806	if (flag) {
2807		if (transflag)
2808			syslog(LOG_ERR, "Internal: flagxfer(1): "
2809					"transfer already under way");
2810		transflag = 1;
2811		maskurg(0);
2812		recvurg = 0;
2813	} else {
2814		if (!transflag)
2815			syslog(LOG_ERR, "Internal: flagxfer(0): "
2816					"no active transfer");
2817		maskurg(1);
2818		transflag = 0;
2819	}
2820}
2821
2822/*
2823 * Returns 0 if OK to resume or -1 if abort requested.
2824 */
2825static int
2826myoob(void)
2827{
2828	char *cp;
2829	int ret;
2830
2831	if (!transflag) {
2832		syslog(LOG_ERR, "Internal: myoob() while no transfer");
2833		return (0);
2834	}
2835	cp = tmpline;
2836	ret = getline(cp, 7, stdin);
2837	if (ret == -1) {
2838		reply(221, "You could at least say goodbye.");
2839		dologout(0);
2840	} else if (ret == -2) {
2841		/* Ignore truncated command. */
2842		return (0);
2843	}
2844	upper(cp);
2845	if (strcmp(cp, "ABOR\r\n") == 0) {
2846		tmpline[0] = '\0';
2847		reply(426, "Transfer aborted. Data connection closed.");
2848		reply(226, "Abort successful.");
2849		return (-1);
2850	}
2851	if (strcmp(cp, "STAT\r\n") == 0) {
2852		tmpline[0] = '\0';
2853		if (file_size != -1)
2854			reply(213, "Status: %jd of %jd bytes transferred.",
2855				   (intmax_t)byte_count, (intmax_t)file_size);
2856		else
2857			reply(213, "Status: %jd bytes transferred.",
2858				   (intmax_t)byte_count);
2859	}
2860	return (0);
2861}
2862
2863/*
2864 * Note: a response of 425 is not mentioned as a possible response to
2865 *	the PASV command in RFC959. However, it has been blessed as
2866 *	a legitimate response by Jon Postel in a telephone conversation
2867 *	with Rick Adams on 25 Jan 89.
2868 */
2869void
2870passive(void)
2871{
2872	socklen_t len;
2873	int on;
2874	char *p, *a;
2875
2876	if (pdata >= 0)		/* close old port if one set */
2877		close(pdata);
2878
2879	pdata = socket(ctrl_addr.su_family, SOCK_STREAM, 0);
2880	if (pdata < 0) {
2881		perror_reply(425, "Can't open passive connection");
2882		return;
2883	}
2884	on = 1;
2885	if (setsockopt(pdata, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0)
2886		syslog(LOG_WARNING, "pdata setsockopt (SO_REUSEADDR): %m");
2887
2888	(void) seteuid(0);
2889
2890#ifdef IP_PORTRANGE
2891	if (ctrl_addr.su_family == AF_INET) {
2892	    on = restricted_data_ports ? IP_PORTRANGE_HIGH
2893				       : IP_PORTRANGE_DEFAULT;
2894
2895	    if (setsockopt(pdata, IPPROTO_IP, IP_PORTRANGE,
2896			    &on, sizeof(on)) < 0)
2897		    goto pasv_error;
2898	}
2899#endif
2900#ifdef IPV6_PORTRANGE
2901	if (ctrl_addr.su_family == AF_INET6) {
2902	    on = restricted_data_ports ? IPV6_PORTRANGE_HIGH
2903				       : IPV6_PORTRANGE_DEFAULT;
2904
2905	    if (setsockopt(pdata, IPPROTO_IPV6, IPV6_PORTRANGE,
2906			    &on, sizeof(on)) < 0)
2907		    goto pasv_error;
2908	}
2909#endif
2910
2911	pasv_addr = ctrl_addr;
2912	pasv_addr.su_port = 0;
2913	if (bind(pdata, (struct sockaddr *)&pasv_addr, pasv_addr.su_len) < 0)
2914		goto pasv_error;
2915
2916	(void) seteuid(pw->pw_uid);
2917
2918	len = sizeof(pasv_addr);
2919	if (getsockname(pdata, (struct sockaddr *) &pasv_addr, &len) < 0)
2920		goto pasv_error;
2921	if (listen(pdata, 1) < 0)
2922		goto pasv_error;
2923	if (pasv_addr.su_family == AF_INET)
2924		a = (char *) &pasv_addr.su_sin.sin_addr;
2925	else if (pasv_addr.su_family == AF_INET6 &&
2926		 IN6_IS_ADDR_V4MAPPED(&pasv_addr.su_sin6.sin6_addr))
2927		a = (char *) &pasv_addr.su_sin6.sin6_addr.s6_addr[12];
2928	else
2929		goto pasv_error;
2930
2931	p = (char *) &pasv_addr.su_port;
2932
2933#define UC(b) (((int) b) & 0xff)
2934
2935	reply(227, "Entering Passive Mode (%d,%d,%d,%d,%d,%d)", UC(a[0]),
2936		UC(a[1]), UC(a[2]), UC(a[3]), UC(p[0]), UC(p[1]));
2937	return;
2938
2939pasv_error:
2940	(void) seteuid(pw->pw_uid);
2941	(void) close(pdata);
2942	pdata = -1;
2943	perror_reply(425, "Can't open passive connection");
2944	return;
2945}
2946
2947/*
2948 * Long Passive defined in RFC 1639.
2949 *     228 Entering Long Passive Mode
2950 *         (af, hal, h1, h2, h3,..., pal, p1, p2...)
2951 */
2952
2953void
2954long_passive(char *cmd, int pf)
2955{
2956	socklen_t len;
2957	int on;
2958	char *p, *a;
2959
2960	if (pdata >= 0)		/* close old port if one set */
2961		close(pdata);
2962
2963	if (pf != PF_UNSPEC) {
2964		if (ctrl_addr.su_family != pf) {
2965			switch (ctrl_addr.su_family) {
2966			case AF_INET:
2967				pf = 1;
2968				break;
2969			case AF_INET6:
2970				pf = 2;
2971				break;
2972			default:
2973				pf = 0;
2974				break;
2975			}
2976			/*
2977			 * XXX
2978			 * only EPRT/EPSV ready clients will understand this
2979			 */
2980			if (strcmp(cmd, "EPSV") == 0 && pf) {
2981				reply(522, "Network protocol mismatch, "
2982					"use (%d)", pf);
2983			} else
2984				reply(501, "Network protocol mismatch."); /*XXX*/
2985
2986			return;
2987		}
2988	}
2989
2990	pdata = socket(ctrl_addr.su_family, SOCK_STREAM, 0);
2991	if (pdata < 0) {
2992		perror_reply(425, "Can't open passive connection");
2993		return;
2994	}
2995	on = 1;
2996	if (setsockopt(pdata, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0)
2997		syslog(LOG_WARNING, "pdata setsockopt (SO_REUSEADDR): %m");
2998
2999	(void) seteuid(0);
3000
3001	pasv_addr = ctrl_addr;
3002	pasv_addr.su_port = 0;
3003	len = pasv_addr.su_len;
3004
3005#ifdef IP_PORTRANGE
3006	if (ctrl_addr.su_family == AF_INET) {
3007	    on = restricted_data_ports ? IP_PORTRANGE_HIGH
3008				       : IP_PORTRANGE_DEFAULT;
3009
3010	    if (setsockopt(pdata, IPPROTO_IP, IP_PORTRANGE,
3011			    &on, sizeof(on)) < 0)
3012		    goto pasv_error;
3013	}
3014#endif
3015#ifdef IPV6_PORTRANGE
3016	if (ctrl_addr.su_family == AF_INET6) {
3017	    on = restricted_data_ports ? IPV6_PORTRANGE_HIGH
3018				       : IPV6_PORTRANGE_DEFAULT;
3019
3020	    if (setsockopt(pdata, IPPROTO_IPV6, IPV6_PORTRANGE,
3021			    &on, sizeof(on)) < 0)
3022		    goto pasv_error;
3023	}
3024#endif
3025
3026	if (bind(pdata, (struct sockaddr *)&pasv_addr, len) < 0)
3027		goto pasv_error;
3028
3029	(void) seteuid(pw->pw_uid);
3030
3031	if (getsockname(pdata, (struct sockaddr *) &pasv_addr, &len) < 0)
3032		goto pasv_error;
3033	if (listen(pdata, 1) < 0)
3034		goto pasv_error;
3035
3036#define UC(b) (((int) b) & 0xff)
3037
3038	if (strcmp(cmd, "LPSV") == 0) {
3039		p = (char *)&pasv_addr.su_port;
3040		switch (pasv_addr.su_family) {
3041		case AF_INET:
3042			a = (char *) &pasv_addr.su_sin.sin_addr;
3043		v4_reply:
3044			reply(228,
3045"Entering Long Passive Mode (%d,%d,%d,%d,%d,%d,%d,%d,%d)",
3046			      4, 4, UC(a[0]), UC(a[1]), UC(a[2]), UC(a[3]),
3047			      2, UC(p[0]), UC(p[1]));
3048			return;
3049		case AF_INET6:
3050			if (IN6_IS_ADDR_V4MAPPED(&pasv_addr.su_sin6.sin6_addr)) {
3051				a = (char *) &pasv_addr.su_sin6.sin6_addr.s6_addr[12];
3052				goto v4_reply;
3053			}
3054			a = (char *) &pasv_addr.su_sin6.sin6_addr;
3055			reply(228,
3056"Entering Long Passive Mode "
3057"(%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d)",
3058			      6, 16, UC(a[0]), UC(a[1]), UC(a[2]), UC(a[3]),
3059			      UC(a[4]), UC(a[5]), UC(a[6]), UC(a[7]),
3060			      UC(a[8]), UC(a[9]), UC(a[10]), UC(a[11]),
3061			      UC(a[12]), UC(a[13]), UC(a[14]), UC(a[15]),
3062			      2, UC(p[0]), UC(p[1]));
3063			return;
3064		}
3065	} else if (strcmp(cmd, "EPSV") == 0) {
3066		switch (pasv_addr.su_family) {
3067		case AF_INET:
3068		case AF_INET6:
3069			reply(229, "Entering Extended Passive Mode (|||%d|)",
3070				ntohs(pasv_addr.su_port));
3071			return;
3072		}
3073	} else {
3074		/* more proper error code? */
3075	}
3076
3077pasv_error:
3078	(void) seteuid(pw->pw_uid);
3079	(void) close(pdata);
3080	pdata = -1;
3081	perror_reply(425, "Can't open passive connection");
3082	return;
3083}
3084
3085/*
3086 * Generate unique name for file with basename "local"
3087 * and open the file in order to avoid possible races.
3088 * Try "local" first, then "local.1", "local.2" etc, up to "local.99".
3089 * Return descriptor to the file, set "name" to its name.
3090 *
3091 * Generates failure reply on error.
3092 */
3093static int
3094guniquefd(char *local, char **name)
3095{
3096	static char new[MAXPATHLEN];
3097	struct stat st;
3098	char *cp;
3099	int count;
3100	int fd;
3101
3102	cp = strrchr(local, '/');
3103	if (cp)
3104		*cp = '\0';
3105	if (stat(cp ? local : ".", &st) < 0) {
3106		perror_reply(553, cp ? local : ".");
3107		return (-1);
3108	}
3109	if (cp) {
3110		/*
3111		 * Let not overwrite dirname with counter suffix.
3112		 * -4 is for /nn\0
3113		 * In this extreme case dot won't be put in front of suffix.
3114		 */
3115		if (strlen(local) > sizeof(new) - 4) {
3116			reply(553, "Pathname too long.");
3117			return (-1);
3118		}
3119		*cp = '/';
3120	}
3121	/* -4 is for the .nn<null> we put on the end below */
3122	(void) snprintf(new, sizeof(new) - 4, "%s", local);
3123	cp = new + strlen(new);
3124	/*
3125	 * Don't generate dotfile unless requested explicitly.
3126	 * This covers the case when basename gets truncated off
3127	 * by buffer size.
3128	 */
3129	if (cp > new && cp[-1] != '/')
3130		*cp++ = '.';
3131	for (count = 0; count < 100; count++) {
3132		/* At count 0 try unmodified name */
3133		if (count)
3134			(void)sprintf(cp, "%d", count);
3135		if ((fd = open(count ? new : local,
3136		    O_RDWR | O_CREAT | O_EXCL, 0666)) >= 0) {
3137			*name = count ? new : local;
3138			return (fd);
3139		}
3140		if (errno != EEXIST) {
3141			perror_reply(553, count ? new : local);
3142			return (-1);
3143		}
3144	}
3145	reply(452, "Unique file name cannot be created.");
3146	return (-1);
3147}
3148
3149/*
3150 * Format and send reply containing system error number.
3151 */
3152void
3153perror_reply(int code, char *string)
3154{
3155
3156	reply(code, "%s: %s.", string, strerror(errno));
3157}
3158
3159static char *onefile[] = {
3160	"",
3161	0
3162};
3163
3164void
3165send_file_list(char *whichf)
3166{
3167	struct stat st;
3168	DIR *dirp = NULL;
3169	struct dirent *dir;
3170	FILE *dout = NULL;
3171	char **dirlist, *dirname;
3172	int simple = 0;
3173	int freeglob = 0;
3174	glob_t gl;
3175
3176	if (strpbrk(whichf, "~{[*?") != NULL) {
3177		int flags = GLOB_BRACE|GLOB_NOCHECK|GLOB_TILDE;
3178
3179		memset(&gl, 0, sizeof(gl));
3180		gl.gl_matchc = MAXGLOBARGS;
3181		flags |= GLOB_LIMIT;
3182		freeglob = 1;
3183		if (glob(whichf, flags, 0, &gl)) {
3184			reply(550, "No matching files found.");
3185			goto out;
3186		} else if (gl.gl_pathc == 0) {
3187			errno = ENOENT;
3188			perror_reply(550, whichf);
3189			goto out;
3190		}
3191		dirlist = gl.gl_pathv;
3192	} else {
3193		onefile[0] = whichf;
3194		dirlist = onefile;
3195		simple = 1;
3196	}
3197
3198	while ((dirname = *dirlist++)) {
3199		if (stat(dirname, &st) < 0) {
3200			/*
3201			 * If user typed "ls -l", etc, and the client
3202			 * used NLST, do what the user meant.
3203			 */
3204			if (dirname[0] == '-' && *dirlist == NULL &&
3205			    dout == NULL)
3206				retrieve(_PATH_LS " %s", dirname);
3207			else
3208				perror_reply(550, whichf);
3209			goto out;
3210		}
3211
3212		if (S_ISREG(st.st_mode)) {
3213			if (dout == NULL) {
3214				dout = dataconn("file list", -1, "w");
3215				if (dout == NULL)
3216					goto out;
3217				STARTXFER;
3218			}
3219			START_UNSAFE;
3220			fprintf(dout, "%s%s\n", dirname,
3221				type == TYPE_A ? "\r" : "");
3222			END_UNSAFE;
3223			if (ferror(dout))
3224				goto data_err;
3225			byte_count += strlen(dirname) +
3226				      (type == TYPE_A ? 2 : 1);
3227			CHECKOOB(goto abrt);
3228			continue;
3229		} else if (!S_ISDIR(st.st_mode))
3230			continue;
3231
3232		if ((dirp = opendir(dirname)) == NULL)
3233			continue;
3234
3235		while ((dir = readdir(dirp)) != NULL) {
3236			char nbuf[MAXPATHLEN];
3237
3238			CHECKOOB(goto abrt);
3239
3240			if (dir->d_name[0] == '.' && dir->d_namlen == 1)
3241				continue;
3242			if (dir->d_name[0] == '.' && dir->d_name[1] == '.' &&
3243			    dir->d_namlen == 2)
3244				continue;
3245
3246			snprintf(nbuf, sizeof(nbuf),
3247				"%s/%s", dirname, dir->d_name);
3248
3249			/*
3250			 * We have to do a stat to insure it's
3251			 * not a directory or special file.
3252			 */
3253			if (simple || (stat(nbuf, &st) == 0 &&
3254			    S_ISREG(st.st_mode))) {
3255				if (dout == NULL) {
3256					dout = dataconn("file list", -1, "w");
3257					if (dout == NULL)
3258						goto out;
3259					STARTXFER;
3260				}
3261				START_UNSAFE;
3262				if (nbuf[0] == '.' && nbuf[1] == '/')
3263					fprintf(dout, "%s%s\n", &nbuf[2],
3264						type == TYPE_A ? "\r" : "");
3265				else
3266					fprintf(dout, "%s%s\n", nbuf,
3267						type == TYPE_A ? "\r" : "");
3268				END_UNSAFE;
3269				if (ferror(dout))
3270					goto data_err;
3271				byte_count += strlen(nbuf) +
3272					      (type == TYPE_A ? 2 : 1);
3273				CHECKOOB(goto abrt);
3274			}
3275		}
3276		(void) closedir(dirp);
3277		dirp = NULL;
3278	}
3279
3280	if (dout == NULL)
3281		reply(550, "No files found.");
3282	else if (ferror(dout))
3283data_err:	perror_reply(550, "Data connection");
3284	else
3285		reply(226, "Transfer complete.");
3286out:
3287	if (dout) {
3288		ENDXFER;
3289abrt:
3290		(void) fclose(dout);
3291		data = -1;
3292		pdata = -1;
3293	}
3294	if (dirp)
3295		(void) closedir(dirp);
3296	if (freeglob) {
3297		freeglob = 0;
3298		globfree(&gl);
3299	}
3300}
3301
3302void
3303reapchild(int signo)
3304{
3305	while (waitpid(-1, NULL, WNOHANG) > 0);
3306}
3307
3308#ifdef OLD_SETPROCTITLE
3309/*
3310 * Clobber argv so ps will show what we're doing.  (Stolen from sendmail.)
3311 * Warning, since this is usually started from inetd.conf, it often doesn't
3312 * have much of an environment or arglist to overwrite.
3313 */
3314void
3315setproctitle(const char *fmt, ...)
3316{
3317	int i;
3318	va_list ap;
3319	char *p, *bp, ch;
3320	char buf[LINE_MAX];
3321
3322	va_start(ap, fmt);
3323	(void)vsnprintf(buf, sizeof(buf), fmt, ap);
3324
3325	/* make ps print our process name */
3326	p = Argv[0];
3327	*p++ = '-';
3328
3329	i = strlen(buf);
3330	if (i > LastArgv - p - 2) {
3331		i = LastArgv - p - 2;
3332		buf[i] = '\0';
3333	}
3334	bp = buf;
3335	while (ch = *bp++)
3336		if (ch != '\n' && ch != '\r')
3337			*p++ = ch;
3338	while (p < LastArgv)
3339		*p++ = ' ';
3340}
3341#endif /* OLD_SETPROCTITLE */
3342
3343static void
3344appendf(char **strp, char *fmt, ...)
3345{
3346	va_list ap;
3347	char *ostr, *p;
3348
3349	va_start(ap, fmt);
3350	vasprintf(&p, fmt, ap);
3351	va_end(ap);
3352	if (p == NULL)
3353		fatalerror("Ran out of memory.");
3354	if (*strp == NULL)
3355		*strp = p;
3356	else {
3357		ostr = *strp;
3358		asprintf(strp, "%s%s", ostr, p);
3359		if (*strp == NULL)
3360			fatalerror("Ran out of memory.");
3361		free(ostr);
3362	}
3363}
3364
3365static void
3366logcmd(char *cmd, char *file1, char *file2, off_t cnt)
3367{
3368	char *msg = NULL;
3369	char wd[MAXPATHLEN + 1];
3370
3371	if (logging <= 1)
3372		return;
3373
3374	if (getcwd(wd, sizeof(wd) - 1) == NULL)
3375		strcpy(wd, strerror(errno));
3376
3377	appendf(&msg, "%s", cmd);
3378	if (file1)
3379		appendf(&msg, " %s", file1);
3380	if (file2)
3381		appendf(&msg, " %s", file2);
3382	if (cnt >= 0)
3383		appendf(&msg, " = %jd bytes", (intmax_t)cnt);
3384	appendf(&msg, " (wd: %s", wd);
3385	if (guest || dochroot)
3386		appendf(&msg, "; chrooted");
3387	appendf(&msg, ")");
3388	syslog(LOG_INFO, "%s", msg);
3389	free(msg);
3390}
3391
3392static void
3393logxfer(char *name, off_t size, time_t start)
3394{
3395	char buf[MAXPATHLEN + 1024];
3396	char path[MAXPATHLEN + 1];
3397	time_t now;
3398
3399	if (statfd >= 0) {
3400		time(&now);
3401		if (realpath(name, path) == NULL) {
3402			syslog(LOG_NOTICE, "realpath failed on %s: %m", path);
3403			return;
3404		}
3405		snprintf(buf, sizeof(buf), "%.20s!%s!%s!%s!%jd!%ld\n",
3406			ctime(&now)+4, ident, remotehost,
3407			path, (intmax_t)size,
3408			(long)(now - start + (now == start)));
3409		write(statfd, buf, strlen(buf));
3410	}
3411}
3412
3413static char *
3414doublequote(char *s)
3415{
3416	int n;
3417	char *p, *s2;
3418
3419	for (p = s, n = 0; *p; p++)
3420		if (*p == '"')
3421			n++;
3422
3423	if ((s2 = malloc(p - s + n + 1)) == NULL)
3424		return (NULL);
3425
3426	for (p = s2; *s; s++, p++) {
3427		if ((*p = *s) == '"')
3428			*(++p) = '"';
3429	}
3430	*p = '\0';
3431
3432	return (s2);
3433}
3434
3435/* setup server socket for specified address family */
3436/* if af is PF_UNSPEC more than one socket may be returned */
3437/* the returned list is dynamically allocated, so caller needs to free it */
3438static int *
3439socksetup(int af, char *bindname, const char *bindport)
3440{
3441	struct addrinfo hints, *res, *r;
3442	int error, maxs, *s, *socks;
3443	const int on = 1;
3444
3445	memset(&hints, 0, sizeof(hints));
3446	hints.ai_flags = AI_PASSIVE;
3447	hints.ai_family = af;
3448	hints.ai_socktype = SOCK_STREAM;
3449	error = getaddrinfo(bindname, bindport, &hints, &res);
3450	if (error) {
3451		syslog(LOG_ERR, "%s", gai_strerror(error));
3452		if (error == EAI_SYSTEM)
3453			syslog(LOG_ERR, "%s", strerror(errno));
3454		return NULL;
3455	}
3456
3457	/* Count max number of sockets we may open */
3458	for (maxs = 0, r = res; r; r = r->ai_next, maxs++)
3459		;
3460	socks = malloc((maxs + 1) * sizeof(int));
3461	if (!socks) {
3462		freeaddrinfo(res);
3463		syslog(LOG_ERR, "couldn't allocate memory for sockets");
3464		return NULL;
3465	}
3466
3467	*socks = 0;   /* num of sockets counter at start of array */
3468	s = socks + 1;
3469	for (r = res; r; r = r->ai_next) {
3470		*s = socket(r->ai_family, r->ai_socktype, r->ai_protocol);
3471		if (*s < 0) {
3472			syslog(LOG_DEBUG, "control socket: %m");
3473			continue;
3474		}
3475		if (setsockopt(*s, SOL_SOCKET, SO_REUSEADDR,
3476		    &on, sizeof(on)) < 0)
3477			syslog(LOG_WARNING,
3478			    "control setsockopt (SO_REUSEADDR): %m");
3479		if (r->ai_family == AF_INET6) {
3480			if (setsockopt(*s, IPPROTO_IPV6, IPV6_V6ONLY,
3481			    &on, sizeof(on)) < 0)
3482				syslog(LOG_WARNING,
3483				    "control setsockopt (IPV6_V6ONLY): %m");
3484		}
3485		if (bind(*s, r->ai_addr, r->ai_addrlen) < 0) {
3486			syslog(LOG_DEBUG, "control bind: %m");
3487			close(*s);
3488			continue;
3489		}
3490		(*socks)++;
3491		s++;
3492	}
3493
3494	if (res)
3495		freeaddrinfo(res);
3496
3497	if (*socks == 0) {
3498		syslog(LOG_ERR, "control socket: Couldn't bind to any socket");
3499		free(socks);
3500		return NULL;
3501	}
3502	return(socks);
3503}
3504