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