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