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