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