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