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