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 malloc(sizeof(struct pam_response) * num_msg); 1116 1117 for (i = 0; i < num_msg; i++) { 1118 switch (msg[i]->msg_style) { 1119 case PAM_PROMPT_ECHO_ON: /* assume want user name */ 1120 reply[i].resp_retcode = PAM_SUCCESS; 1121 reply[i].resp = COPY_STRING(cred->uname); 1122 /* PAM frees resp. */ 1123 break; 1124 case PAM_PROMPT_ECHO_OFF: /* assume want password */ 1125 reply[i].resp_retcode = PAM_SUCCESS; 1126 reply[i].resp = COPY_STRING(cred->pass); 1127 /* PAM frees resp. */ 1128 break; 1129 case PAM_TEXT_INFO: 1130 case PAM_ERROR_MSG: 1131 reply[i].resp_retcode = PAM_SUCCESS; 1132 reply[i].resp = NULL; 1133 break; 1134 default: /* unknown message style */ 1135 free(reply); 1136 return PAM_CONV_ERR; 1137 } 1138 } 1139 1140 *resp = reply; 1141 return PAM_SUCCESS; 1142 } 1143 1144 /* 1145 * Attempt to authenticate the user using PAM. Returns 0 if the user is 1146 * authenticated, or 1 if not authenticated. If some sort of PAM system 1147 * error occurs (e.g., the "/etc/pam.conf" file is missing) then this 1148 * function returns -1. This can be used as an indication that we should 1149 * fall back to a different authentication mechanism. 1150 */ 1151 static int 1152 auth_pam(struct passwd **ppw, const char *pass) 1153 { 1154 pam_handle_t *pamh = NULL; 1155 const char *tmpl_user; 1156 const void *item; 1157 int rval; 1158 int e; 1159 cred_t auth_cred = { (*ppw)->pw_name, pass }; 1160 struct pam_conv conv = { &auth_conv, &auth_cred }; 1161 1162 e = pam_start("ftpd", (*ppw)->pw_name, &conv, &pamh); 1163 if (e != PAM_SUCCESS) { 1164 syslog(LOG_ERR, "pam_start: %s", pam_strerror(pamh, e)); 1165 return -1; 1166 } 1167 1168 e = pam_set_item(pamh, PAM_RHOST, remotehost); 1169 if (e != PAM_SUCCESS) { 1170 syslog(LOG_ERR, "pam_set_item(PAM_RHOST): %s", 1171 pam_strerror(pamh, e)); 1172 return -1; 1173 } 1174 1175 e = pam_authenticate(pamh, 0); 1176 switch (e) { 1177 case PAM_SUCCESS: 1178 /* 1179 * With PAM we support the concept of a "template" 1180 * user. The user enters a login name which is 1181 * authenticated by PAM, usually via a remote service 1182 * such as RADIUS or TACACS+. If authentication 1183 * succeeds, a different but related "template" name 1184 * is used for setting the credentials, shell, and 1185 * home directory. The name the user enters need only 1186 * exist on the remote authentication server, but the 1187 * template name must be present in the local password 1188 * database. 1189 * 1190 * This is supported by two various mechanisms in the 1191 * individual modules. However, from the application's 1192 * point of view, the template user is always passed 1193 * back as a changed value of the PAM_USER item. 1194 */ 1195 if ((e = pam_get_item(pamh, PAM_USER, &item)) == 1196 PAM_SUCCESS) { 1197 tmpl_user = (const char *) item; 1198 if (strcmp((*ppw)->pw_name, tmpl_user) != 0) 1199 *ppw = getpwnam(tmpl_user); 1200 } else 1201 syslog(LOG_ERR, "Couldn't get PAM_USER: %s", 1202 pam_strerror(pamh, e)); 1203 rval = 0; 1204 break; 1205 1206 case PAM_AUTH_ERR: 1207 case PAM_USER_UNKNOWN: 1208 case PAM_MAXTRIES: 1209 rval = 1; 1210 break; 1211 1212 default: 1213 syslog(LOG_ERR, "pam_authenticate: %s", pam_strerror(pamh, e)); 1214 rval = -1; 1215 break; 1216 } 1217 1218 if (rval == 0) { 1219 e = pam_acct_mgmt(pamh, 0); 1220 if (e == PAM_NEW_AUTHTOK_REQD) { 1221 e = pam_chauthtok(pamh, PAM_CHANGE_EXPIRED_AUTHTOK); 1222 if (e != PAM_SUCCESS) { 1223 syslog(LOG_ERR, "pam_chauthtok: %s", pam_strerror(pamh, e)); 1224 rval = 1; 1225 } 1226 } else if (e != PAM_SUCCESS) { 1227 rval = 1; 1228 } 1229 } 1230 1231 if (rval != 0) { 1232 if ((e = pam_end(pamh, e)) != PAM_SUCCESS) { 1233 syslog(LOG_ERR, "pam_end: %s", pam_strerror(pamh, e)); 1234 } 1235 pamh = NULL; 1236 } 1237 return rval; 1238 } 1239 1240 #endif /* USE_PAM */ 1241 1242 void 1243 pass(char *passwd) 1244 { 1245 int rval; 1246 FILE *fd; 1247 #ifdef LOGIN_CAP 1248 login_cap_t *lc = NULL; 1249 #endif 1250 #ifdef USE_PAM 1251 int e; 1252 #endif 1253 char *xpasswd; 1254 1255 if (logged_in || askpasswd == 0) { 1256 reply(503, "Login with USER first."); 1257 return; 1258 } 1259 askpasswd = 0; 1260 if (!guest) { /* "ftp" is only account allowed no password */ 1261 if (pw == NULL) { 1262 rval = 1; /* failure below */ 1263 goto skip; 1264 } 1265 #ifdef USE_PAM 1266 rval = auth_pam(&pw, passwd); 1267 if (rval >= 0) { 1268 opieunlock(); 1269 goto skip; 1270 } 1271 #endif 1272 if (opieverify(&opiedata, passwd) == 0) 1273 xpasswd = pw->pw_passwd; 1274 else if (pwok) { 1275 xpasswd = crypt(passwd, pw->pw_passwd); 1276 if (passwd[0] == '\0' && pw->pw_passwd[0] != '\0') 1277 xpasswd = ":"; 1278 } else { 1279 rval = 1; 1280 goto skip; 1281 } 1282 rval = strcmp(pw->pw_passwd, xpasswd); 1283 if (pw->pw_expire && time(NULL) >= pw->pw_expire) 1284 rval = 1; /* failure */ 1285 skip: 1286 /* 1287 * If rval == 1, the user failed the authentication check 1288 * above. If rval == 0, either PAM or local authentication 1289 * succeeded. 1290 */ 1291 if (rval) { 1292 reply(530, "Login incorrect."); 1293 if (logging) 1294 syslog(LOG_NOTICE, 1295 "FTP LOGIN FAILED FROM %s, %s", 1296 remotehost, curname); 1297 pw = NULL; 1298 if (login_attempts++ >= 5) { 1299 syslog(LOG_NOTICE, 1300 "repeated login failures from %s", 1301 remotehost); 1302 exit(0); 1303 } 1304 return; 1305 } 1306 } 1307 login_attempts = 0; /* this time successful */ 1308 if (setegid((gid_t)pw->pw_gid) < 0) { 1309 reply(550, "Can't set gid."); 1310 return; 1311 } 1312 /* May be overridden by login.conf */ 1313 (void) umask(defumask); 1314 #ifdef LOGIN_CAP 1315 if ((lc = login_getpwclass(pw)) != NULL) { 1316 char remote_ip[MAXHOSTNAMELEN]; 1317 1318 getnameinfo((struct sockaddr *)&his_addr, his_addr.su_len, 1319 remote_ip, sizeof(remote_ip) - 1, NULL, 0, 1320 NI_NUMERICHOST|NI_WITHSCOPEID); 1321 remote_ip[sizeof(remote_ip) - 1] = 0; 1322 if (!auth_hostok(lc, remotehost, remote_ip)) { 1323 syslog(LOG_INFO|LOG_AUTH, 1324 "FTP LOGIN FAILED (HOST) as %s: permission denied.", 1325 pw->pw_name); 1326 reply(530, "Permission denied.\n"); 1327 pw = NULL; 1328 return; 1329 } 1330 if (!auth_timeok(lc, time(NULL))) { 1331 reply(530, "Login not available right now.\n"); 1332 pw = NULL; 1333 return; 1334 } 1335 } 1336 setusercontext(lc, pw, (uid_t)0, 1337 LOGIN_SETLOGIN|LOGIN_SETGROUP|LOGIN_SETPRIORITY| 1338 LOGIN_SETRESOURCES|LOGIN_SETUMASK); 1339 #else 1340 setlogin(pw->pw_name); 1341 (void) initgroups(pw->pw_name, pw->pw_gid); 1342 #endif 1343 1344 #ifdef USE_PAM 1345 if (pamh) { 1346 if ((e = pam_open_session(pamh, 0)) != PAM_SUCCESS) { 1347 syslog(LOG_ERR, "pam_open_session: %s", pam_strerror(pamh, e)); 1348 } else if ((e = pam_setcred(pamh, PAM_ESTABLISH_CRED)) != PAM_SUCCESS) { 1349 syslog(LOG_ERR, "pam_setcred: %s", pam_strerror(pamh, e)); 1350 } 1351 } 1352 #endif 1353 1354 /* open wtmp before chroot */ 1355 ftpd_logwtmp(ttyline, pw->pw_name, (struct sockaddr *)&his_addr); 1356 logged_in = 1; 1357 1358 if (guest && stats && statfd < 0) 1359 #ifdef VIRTUAL_HOSTING 1360 if ((statfd = open(thishost->statfile, O_WRONLY|O_APPEND)) < 0) 1361 #else 1362 if ((statfd = open(_PATH_FTPDSTATFILE, O_WRONLY|O_APPEND)) < 0) 1363 #endif 1364 stats = 0; 1365 1366 dochroot = 1367 #ifdef LOGIN_CAP /* Allow login.conf configuration as well */ 1368 login_getcapbool(lc, "ftp-chroot", 0) || 1369 #endif 1370 checkuser(_PATH_FTPCHROOT, pw->pw_name, 1); 1371 if (guest) { 1372 /* 1373 * We MUST do a chdir() after the chroot. Otherwise 1374 * the old current directory will be accessible as "." 1375 * outside the new root! 1376 */ 1377 if (chroot(pw->pw_dir) < 0 || chdir("/") < 0) { 1378 reply(550, "Can't set guest privileges."); 1379 goto bad; 1380 } 1381 } else if (dochroot) { 1382 if (chroot(pw->pw_dir) < 0 || chdir("/") < 0) { 1383 reply(550, "Can't change root."); 1384 goto bad; 1385 } 1386 } else if (chdir(pw->pw_dir) < 0) { 1387 if (chdir("/") < 0) { 1388 reply(530, "User %s: can't change directory to %s.", 1389 pw->pw_name, pw->pw_dir); 1390 goto bad; 1391 } else 1392 lreply(230, "No directory! Logging in with home=/"); 1393 } 1394 if (seteuid((uid_t)pw->pw_uid) < 0) { 1395 reply(550, "Can't set uid."); 1396 goto bad; 1397 } 1398 1399 /* 1400 * Display a login message, if it exists. 1401 * N.B. reply(230,) must follow the message. 1402 */ 1403 #ifdef VIRTUAL_HOSTING 1404 if ((fd = fopen(thishost->loginmsg, "r")) != NULL) { 1405 #else 1406 if ((fd = fopen(_PATH_FTPLOGINMESG, "r")) != NULL) { 1407 #endif 1408 char *cp, line[LINE_MAX]; 1409 1410 while (fgets(line, sizeof(line), fd) != NULL) { 1411 if ((cp = strchr(line, '\n')) != NULL) 1412 *cp = '\0'; 1413 lreply(230, "%s", line); 1414 } 1415 (void) fflush(stdout); 1416 (void) fclose(fd); 1417 } 1418 if (guest) { 1419 if (ident != NULL) 1420 free(ident); 1421 ident = strdup(passwd); 1422 if (ident == NULL) 1423 fatalerror("Ran out of memory."); 1424 1425 reply(230, "Guest login ok, access restrictions apply."); 1426 #ifdef SETPROCTITLE 1427 #ifdef VIRTUAL_HOSTING 1428 if (thishost != firsthost) 1429 snprintf(proctitle, sizeof(proctitle), 1430 "%s: anonymous(%s)/%s", remotehost, hostname, 1431 passwd); 1432 else 1433 #endif 1434 snprintf(proctitle, sizeof(proctitle), 1435 "%s: anonymous/%s", remotehost, passwd); 1436 setproctitle("%s", proctitle); 1437 #endif /* SETPROCTITLE */ 1438 if (logging) 1439 syslog(LOG_INFO, "ANONYMOUS FTP LOGIN FROM %s, %s", 1440 remotehost, passwd); 1441 } else { 1442 if (dochroot) 1443 reply(230, "User %s logged in, " 1444 "access restrictions apply.", pw->pw_name); 1445 else 1446 reply(230, "User %s logged in.", pw->pw_name); 1447 1448 #ifdef SETPROCTITLE 1449 snprintf(proctitle, sizeof(proctitle), 1450 "%s: user/%s", remotehost, pw->pw_name); 1451 setproctitle("%s", proctitle); 1452 #endif /* SETPROCTITLE */ 1453 if (logging) 1454 syslog(LOG_INFO, "FTP LOGIN FROM %s as %s", 1455 remotehost, pw->pw_name); 1456 } 1457 #ifdef LOGIN_CAP 1458 login_close(lc); 1459 #endif 1460 return; 1461 bad: 1462 /* Forget all about it... */ 1463 #ifdef LOGIN_CAP 1464 login_close(lc); 1465 #endif 1466 end_login(); 1467 } 1468 1469 void 1470 retrieve(char *cmd, char *name) 1471 { 1472 FILE *fin, *dout; 1473 struct stat st; 1474 int (*closefunc)(FILE *); 1475 time_t start; 1476 1477 if (cmd == 0) { 1478 fin = fopen(name, "r"), closefunc = fclose; 1479 st.st_size = 0; 1480 } else { 1481 char line[BUFSIZ]; 1482 1483 (void) snprintf(line, sizeof(line), cmd, name), name = line; 1484 fin = ftpd_popen(line, "r"), closefunc = ftpd_pclose; 1485 st.st_size = -1; 1486 st.st_blksize = BUFSIZ; 1487 } 1488 if (fin == NULL) { 1489 if (errno != 0) { 1490 perror_reply(550, name); 1491 if (cmd == 0) { 1492 LOGCMD("get", name); 1493 } 1494 } 1495 return; 1496 } 1497 byte_count = -1; 1498 if (cmd == 0 && (fstat(fileno(fin), &st) < 0 || !S_ISREG(st.st_mode))) { 1499 reply(550, "%s: not a plain file.", name); 1500 goto done; 1501 } 1502 if (restart_point) { 1503 if (type == TYPE_A) { 1504 off_t i, n; 1505 int c; 1506 1507 n = restart_point; 1508 i = 0; 1509 while (i++ < n) { 1510 if ((c=getc(fin)) == EOF) { 1511 perror_reply(550, name); 1512 goto done; 1513 } 1514 if (c == '\n') 1515 i++; 1516 } 1517 } else if (lseek(fileno(fin), restart_point, L_SET) < 0) { 1518 perror_reply(550, name); 1519 goto done; 1520 } 1521 } 1522 dout = dataconn(name, st.st_size, "w"); 1523 if (dout == NULL) 1524 goto done; 1525 time(&start); 1526 send_data(fin, dout, st.st_blksize, st.st_size, 1527 restart_point == 0 && cmd == 0 && S_ISREG(st.st_mode)); 1528 if (cmd == 0 && guest && stats) 1529 logxfer(name, st.st_size, start); 1530 (void) fclose(dout); 1531 data = -1; 1532 pdata = -1; 1533 done: 1534 if (cmd == 0) 1535 LOGBYTES("get", name, byte_count); 1536 (*closefunc)(fin); 1537 } 1538 1539 void 1540 store(char *name, char *mode, int unique) 1541 { 1542 FILE *fout, *din; 1543 struct stat st; 1544 int (*closefunc)(FILE *); 1545 1546 if ((unique || guest) && stat(name, &st) == 0 && 1547 (name = gunique(name)) == NULL) { 1548 LOGCMD(*mode == 'w' ? "put" : "append", name); 1549 return; 1550 } 1551 1552 if (restart_point) 1553 mode = "r+"; 1554 fout = fopen(name, mode); 1555 closefunc = fclose; 1556 if (fout == NULL) { 1557 perror_reply(553, name); 1558 LOGCMD(*mode == 'w' ? "put" : "append", name); 1559 return; 1560 } 1561 byte_count = -1; 1562 if (restart_point) { 1563 if (type == TYPE_A) { 1564 off_t i, n; 1565 int c; 1566 1567 n = restart_point; 1568 i = 0; 1569 while (i++ < n) { 1570 if ((c=getc(fout)) == EOF) { 1571 perror_reply(550, name); 1572 goto done; 1573 } 1574 if (c == '\n') 1575 i++; 1576 } 1577 /* 1578 * We must do this seek to "current" position 1579 * because we are changing from reading to 1580 * writing. 1581 */ 1582 if (fseeko(fout, (off_t)0, SEEK_CUR) < 0) { 1583 perror_reply(550, name); 1584 goto done; 1585 } 1586 } else if (lseek(fileno(fout), restart_point, L_SET) < 0) { 1587 perror_reply(550, name); 1588 goto done; 1589 } 1590 } 1591 din = dataconn(name, (off_t)-1, "r"); 1592 if (din == NULL) 1593 goto done; 1594 if (receive_data(din, fout) == 0) { 1595 if (unique) 1596 reply(226, "Transfer complete (unique file name:%s).", 1597 name); 1598 else 1599 reply(226, "Transfer complete."); 1600 } 1601 (void) fclose(din); 1602 data = -1; 1603 pdata = -1; 1604 done: 1605 LOGBYTES(*mode == 'w' ? "put" : "append", name, byte_count); 1606 (*closefunc)(fout); 1607 } 1608 1609 static FILE * 1610 getdatasock(char *mode) 1611 { 1612 int on = 1, s, t, tries; 1613 1614 if (data >= 0) 1615 return (fdopen(data, mode)); 1616 (void) seteuid((uid_t)0); 1617 1618 s = socket(data_dest.su_family, SOCK_STREAM, 0); 1619 if (s < 0) 1620 goto bad; 1621 if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, 1622 (char *) &on, sizeof(on)) < 0) 1623 goto bad; 1624 /* anchor socket to avoid multi-homing problems */ 1625 data_source = ctrl_addr; 1626 data_source.su_port = htons(20); /* ftp-data port */ 1627 for (tries = 1; ; tries++) { 1628 if (bind(s, (struct sockaddr *)&data_source, 1629 data_source.su_len) >= 0) 1630 break; 1631 if (errno != EADDRINUSE || tries > 10) 1632 goto bad; 1633 sleep(tries); 1634 } 1635 (void) seteuid((uid_t)pw->pw_uid); 1636 #ifdef IP_TOS 1637 if (data_source.su_family == AF_INET) 1638 { 1639 on = IPTOS_THROUGHPUT; 1640 if (setsockopt(s, IPPROTO_IP, IP_TOS, (char *)&on, sizeof(int)) < 0) 1641 syslog(LOG_WARNING, "setsockopt (IP_TOS): %m"); 1642 } 1643 #endif 1644 #ifdef TCP_NOPUSH 1645 /* 1646 * Turn off push flag to keep sender TCP from sending short packets 1647 * at the boundaries of each write(). Should probably do a SO_SNDBUF 1648 * to set the send buffer size as well, but that may not be desirable 1649 * in heavy-load situations. 1650 */ 1651 on = 1; 1652 if (setsockopt(s, IPPROTO_TCP, TCP_NOPUSH, (char *)&on, sizeof on) < 0) 1653 syslog(LOG_WARNING, "setsockopt (TCP_NOPUSH): %m"); 1654 #endif 1655 #ifdef SO_SNDBUF 1656 on = 65536; 1657 if (setsockopt(s, SOL_SOCKET, SO_SNDBUF, (char *)&on, sizeof on) < 0) 1658 syslog(LOG_WARNING, "setsockopt (SO_SNDBUF): %m"); 1659 #endif 1660 1661 return (fdopen(s, mode)); 1662 bad: 1663 /* Return the real value of errno (close may change it) */ 1664 t = errno; 1665 (void) seteuid((uid_t)pw->pw_uid); 1666 (void) close(s); 1667 errno = t; 1668 return (NULL); 1669 } 1670 1671 static FILE * 1672 dataconn(char *name, off_t size, char *mode) 1673 { 1674 char sizebuf[32]; 1675 FILE *file; 1676 int retry = 0, tos; 1677 1678 file_size = size; 1679 byte_count = 0; 1680 if (size != (off_t) -1) 1681 (void) snprintf(sizebuf, sizeof(sizebuf), " (%qd bytes)", size); 1682 else 1683 *sizebuf = '\0'; 1684 if (pdata >= 0) { 1685 union sockunion from; 1686 int flags; 1687 int s, fromlen = ctrl_addr.su_len; 1688 struct timeval timeout; 1689 fd_set set; 1690 1691 FD_ZERO(&set); 1692 FD_SET(pdata, &set); 1693 1694 timeout.tv_usec = 0; 1695 timeout.tv_sec = 120; 1696 1697 /* 1698 * Granted a socket is in the blocking I/O mode, 1699 * accept() will block after a successful select() 1700 * if the selected connection dies in between. 1701 * Therefore set the non-blocking I/O flag here. 1702 */ 1703 if ((flags = fcntl(pdata, F_GETFL, 0)) == -1 || 1704 fcntl(pdata, F_SETFL, flags | O_NONBLOCK) == -1) 1705 goto pdata_err; 1706 if (select(pdata+1, &set, (fd_set *) 0, (fd_set *) 0, &timeout) <= 0 || 1707 (s = accept(pdata, (struct sockaddr *) &from, &fromlen)) < 0) 1708 goto pdata_err; 1709 (void) close(pdata); 1710 pdata = s; 1711 /* 1712 * Unset the blocking I/O flag on the child socket 1713 * again so stdio can work on it. 1714 */ 1715 if ((flags = fcntl(pdata, F_GETFL, 0)) == -1 || 1716 fcntl(pdata, F_SETFL, flags & ~O_NONBLOCK) == -1) 1717 goto pdata_err; 1718 #ifdef IP_TOS 1719 if (from.su_family == AF_INET) 1720 { 1721 tos = IPTOS_THROUGHPUT; 1722 (void) setsockopt(s, IPPROTO_IP, IP_TOS, (char *)&tos, 1723 sizeof(int)); 1724 } 1725 #endif 1726 reply(150, "Opening %s mode data connection for '%s'%s.", 1727 type == TYPE_A ? "ASCII" : "BINARY", name, sizebuf); 1728 return (fdopen(pdata, mode)); 1729 pdata_err: 1730 reply(425, "Can't open data connection."); 1731 (void) close(pdata); 1732 pdata = -1; 1733 return (NULL); 1734 } 1735 if (data >= 0) { 1736 reply(125, "Using existing data connection for '%s'%s.", 1737 name, sizebuf); 1738 usedefault = 1; 1739 return (fdopen(data, mode)); 1740 } 1741 if (usedefault) 1742 data_dest = his_addr; 1743 usedefault = 1; 1744 file = getdatasock(mode); 1745 if (file == NULL) { 1746 char hostbuf[BUFSIZ], portbuf[BUFSIZ]; 1747 getnameinfo((struct sockaddr *)&data_source, 1748 data_source.su_len, hostbuf, sizeof(hostbuf) - 1, 1749 portbuf, sizeof(portbuf), 1750 NI_NUMERICHOST|NI_NUMERICSERV|NI_WITHSCOPEID); 1751 reply(425, "Can't create data socket (%s,%s): %s.", 1752 hostbuf, portbuf, strerror(errno)); 1753 return (NULL); 1754 } 1755 data = fileno(file); 1756 while (connect(data, (struct sockaddr *)&data_dest, 1757 data_dest.su_len) < 0) { 1758 if (errno == EADDRINUSE && retry < swaitmax) { 1759 sleep((unsigned) swaitint); 1760 retry += swaitint; 1761 continue; 1762 } 1763 perror_reply(425, "Can't build data connection"); 1764 (void) fclose(file); 1765 data = -1; 1766 return (NULL); 1767 } 1768 reply(150, "Opening %s mode data connection for '%s'%s.", 1769 type == TYPE_A ? "ASCII" : "BINARY", name, sizebuf); 1770 return (file); 1771 } 1772 1773 /* 1774 * Tranfer the contents of "instr" to "outstr" peer using the appropriate 1775 * encapsulation of the data subject to Mode, Structure, and Type. 1776 * 1777 * NB: Form isn't handled. 1778 */ 1779 static int 1780 send_data(FILE *instr, FILE *outstr, off_t blksize, off_t filesize, int isreg) 1781 { 1782 int c, filefd, netfd; 1783 char *buf; 1784 off_t cnt; 1785 1786 transflag++; 1787 switch (type) { 1788 1789 case TYPE_A: 1790 while ((c = getc(instr)) != EOF) { 1791 if (recvurg) 1792 goto got_oob; 1793 byte_count++; 1794 if (c == '\n') { 1795 if (ferror(outstr)) 1796 goto data_err; 1797 (void) putc('\r', outstr); 1798 } 1799 (void) putc(c, outstr); 1800 } 1801 if (recvurg) 1802 goto got_oob; 1803 fflush(outstr); 1804 transflag = 0; 1805 if (ferror(instr)) 1806 goto file_err; 1807 if (ferror(outstr)) 1808 goto data_err; 1809 reply(226, "Transfer complete."); 1810 return (0); 1811 1812 case TYPE_I: 1813 case TYPE_L: 1814 /* 1815 * isreg is only set if we are not doing restart and we 1816 * are sending a regular file 1817 */ 1818 netfd = fileno(outstr); 1819 filefd = fileno(instr); 1820 1821 if (isreg) { 1822 1823 off_t offset; 1824 int err; 1825 1826 err = cnt = offset = 0; 1827 1828 while (err != -1 && filesize > 0) { 1829 err = sendfile(filefd, netfd, offset, 0, 1830 (struct sf_hdtr *) NULL, &cnt, 0); 1831 if (recvurg) 1832 goto got_oob; 1833 byte_count += cnt; 1834 offset += cnt; 1835 filesize -= cnt; 1836 1837 if (err == -1) { 1838 if (!cnt) 1839 goto oldway; 1840 1841 goto data_err; 1842 } 1843 } 1844 1845 reply(226, "Transfer complete."); 1846 return (0); 1847 } 1848 1849 oldway: 1850 if ((buf = malloc((u_int)blksize)) == NULL) { 1851 transflag = 0; 1852 perror_reply(451, "Local resource failure: malloc"); 1853 return (-1); 1854 } 1855 1856 while ((cnt = read(filefd, buf, (u_int)blksize)) > 0 && 1857 write(netfd, buf, cnt) == cnt) 1858 byte_count += cnt; 1859 transflag = 0; 1860 (void)free(buf); 1861 if (cnt != 0) { 1862 if (cnt < 0) 1863 goto file_err; 1864 goto data_err; 1865 } 1866 reply(226, "Transfer complete."); 1867 return (0); 1868 default: 1869 transflag = 0; 1870 reply(550, "Unimplemented TYPE %d in send_data", type); 1871 return (-1); 1872 } 1873 1874 data_err: 1875 transflag = 0; 1876 perror_reply(426, "Data connection"); 1877 return (-1); 1878 1879 file_err: 1880 transflag = 0; 1881 perror_reply(551, "Error on input file"); 1882 return (-1); 1883 1884 got_oob: 1885 myoob(); 1886 recvurg = 0; 1887 transflag = 0; 1888 return (-1); 1889 } 1890 1891 /* 1892 * Transfer data from peer to "outstr" using the appropriate encapulation of 1893 * the data subject to Mode, Structure, and Type. 1894 * 1895 * N.B.: Form isn't handled. 1896 */ 1897 static int 1898 receive_data(FILE *instr, FILE *outstr) 1899 { 1900 int c; 1901 int cnt, bare_lfs; 1902 char buf[BUFSIZ]; 1903 1904 transflag++; 1905 bare_lfs = 0; 1906 1907 switch (type) { 1908 1909 case TYPE_I: 1910 case TYPE_L: 1911 while ((cnt = read(fileno(instr), buf, sizeof(buf))) > 0) { 1912 if (recvurg) 1913 goto got_oob; 1914 if (write(fileno(outstr), buf, cnt) != cnt) 1915 goto file_err; 1916 byte_count += cnt; 1917 } 1918 if (recvurg) 1919 goto got_oob; 1920 if (cnt < 0) 1921 goto data_err; 1922 transflag = 0; 1923 return (0); 1924 1925 case TYPE_E: 1926 reply(553, "TYPE E not implemented."); 1927 transflag = 0; 1928 return (-1); 1929 1930 case TYPE_A: 1931 while ((c = getc(instr)) != EOF) { 1932 if (recvurg) 1933 goto got_oob; 1934 byte_count++; 1935 if (c == '\n') 1936 bare_lfs++; 1937 while (c == '\r') { 1938 if (ferror(outstr)) 1939 goto data_err; 1940 if ((c = getc(instr)) != '\n') { 1941 (void) putc ('\r', outstr); 1942 if (c == '\0' || c == EOF) 1943 goto contin2; 1944 } 1945 } 1946 (void) putc(c, outstr); 1947 contin2: ; 1948 } 1949 if (recvurg) 1950 goto got_oob; 1951 fflush(outstr); 1952 if (ferror(instr)) 1953 goto data_err; 1954 if (ferror(outstr)) 1955 goto file_err; 1956 transflag = 0; 1957 if (bare_lfs) { 1958 lreply(226, 1959 "WARNING! %d bare linefeeds received in ASCII mode", 1960 bare_lfs); 1961 (void)printf(" File may not have transferred correctly.\r\n"); 1962 } 1963 return (0); 1964 default: 1965 reply(550, "Unimplemented TYPE %d in receive_data", type); 1966 transflag = 0; 1967 return (-1); 1968 } 1969 1970 data_err: 1971 transflag = 0; 1972 perror_reply(426, "Data Connection"); 1973 return (-1); 1974 1975 file_err: 1976 transflag = 0; 1977 perror_reply(452, "Error writing file"); 1978 return (-1); 1979 1980 got_oob: 1981 myoob(); 1982 recvurg = 0; 1983 transflag = 0; 1984 return (-1); 1985 } 1986 1987 void 1988 statfilecmd(char *filename) 1989 { 1990 FILE *fin; 1991 int c; 1992 char line[LINE_MAX]; 1993 1994 (void)snprintf(line, sizeof(line), _PATH_LS " -lgA %s", filename); 1995 fin = ftpd_popen(line, "r"); 1996 lreply(211, "status of %s:", filename); 1997 while ((c = getc(fin)) != EOF) { 1998 if (c == '\n') { 1999 if (ferror(stdout)){ 2000 perror_reply(421, "control connection"); 2001 (void) ftpd_pclose(fin); 2002 dologout(1); 2003 /* NOTREACHED */ 2004 } 2005 if (ferror(fin)) { 2006 perror_reply(551, filename); 2007 (void) ftpd_pclose(fin); 2008 return; 2009 } 2010 (void) putc('\r', stdout); 2011 } 2012 (void) putc(c, stdout); 2013 } 2014 (void) ftpd_pclose(fin); 2015 reply(211, "End of Status"); 2016 } 2017 2018 void 2019 statcmd(void) 2020 { 2021 union sockunion *su; 2022 u_char *a, *p; 2023 char hname[INET6_ADDRSTRLEN]; 2024 int ispassive; 2025 2026 lreply(211, "%s FTP server status:", hostname, version); 2027 printf(" %s\r\n", version); 2028 printf(" Connected to %s", remotehost); 2029 if (!getnameinfo((struct sockaddr *)&his_addr, his_addr.su_len, 2030 hname, sizeof(hname) - 1, NULL, 0, 2031 NI_NUMERICHOST|NI_WITHSCOPEID)) { 2032 if (strcmp(hname, remotehost) != 0) 2033 printf(" (%s)", hname); 2034 } 2035 printf("\r\n"); 2036 if (logged_in) { 2037 if (guest) 2038 printf(" Logged in anonymously\r\n"); 2039 else 2040 printf(" Logged in as %s\r\n", pw->pw_name); 2041 } else if (askpasswd) 2042 printf(" Waiting for password\r\n"); 2043 else 2044 printf(" Waiting for user name\r\n"); 2045 printf(" TYPE: %s", typenames[type]); 2046 if (type == TYPE_A || type == TYPE_E) 2047 printf(", FORM: %s", formnames[form]); 2048 if (type == TYPE_L) 2049 #if NBBY == 8 2050 printf(" %d", NBBY); 2051 #else 2052 printf(" %d", bytesize); /* need definition! */ 2053 #endif 2054 printf("; STRUcture: %s; transfer MODE: %s\r\n", 2055 strunames[stru], modenames[mode]); 2056 if (data != -1) 2057 printf(" Data connection open\r\n"); 2058 else if (pdata != -1) { 2059 ispassive = 1; 2060 su = &pasv_addr; 2061 goto printaddr; 2062 } else if (usedefault == 0) { 2063 ispassive = 0; 2064 su = &data_dest; 2065 printaddr: 2066 #define UC(b) (((int) b) & 0xff) 2067 if (epsvall) { 2068 printf(" EPSV only mode (EPSV ALL)\r\n"); 2069 goto epsvonly; 2070 } 2071 2072 /* PORT/PASV */ 2073 if (su->su_family == AF_INET) { 2074 a = (u_char *) &su->su_sin.sin_addr; 2075 p = (u_char *) &su->su_sin.sin_port; 2076 printf(" %s (%d,%d,%d,%d,%d,%d)\r\n", 2077 ispassive ? "PASV" : "PORT", 2078 UC(a[0]), UC(a[1]), UC(a[2]), UC(a[3]), 2079 UC(p[0]), UC(p[1])); 2080 } 2081 2082 /* LPRT/LPSV */ 2083 { 2084 int alen, af, i; 2085 2086 switch (su->su_family) { 2087 case AF_INET: 2088 a = (u_char *) &su->su_sin.sin_addr; 2089 p = (u_char *) &su->su_sin.sin_port; 2090 alen = sizeof(su->su_sin.sin_addr); 2091 af = 4; 2092 break; 2093 case AF_INET6: 2094 a = (u_char *) &su->su_sin6.sin6_addr; 2095 p = (u_char *) &su->su_sin6.sin6_port; 2096 alen = sizeof(su->su_sin6.sin6_addr); 2097 af = 6; 2098 break; 2099 default: 2100 af = 0; 2101 break; 2102 } 2103 if (af) { 2104 printf(" %s (%d,%d,", ispassive ? "LPSV" : "LPRT", 2105 af, alen); 2106 for (i = 0; i < alen; i++) 2107 printf("%d,", UC(a[i])); 2108 printf("%d,%d,%d)\r\n", 2, UC(p[0]), UC(p[1])); 2109 } 2110 } 2111 2112 epsvonly:; 2113 /* EPRT/EPSV */ 2114 { 2115 int af; 2116 2117 switch (su->su_family) { 2118 case AF_INET: 2119 af = 1; 2120 break; 2121 case AF_INET6: 2122 af = 2; 2123 break; 2124 default: 2125 af = 0; 2126 break; 2127 } 2128 if (af) { 2129 if (!getnameinfo((struct sockaddr *)su, su->su_len, 2130 hname, sizeof(hname) - 1, NULL, 0, 2131 NI_NUMERICHOST)) { 2132 printf(" %s |%d|%s|%d|\r\n", 2133 ispassive ? "EPSV" : "EPRT", 2134 af, hname, htons(su->su_port)); 2135 } 2136 } 2137 } 2138 #undef UC 2139 } else 2140 printf(" No data connection\r\n"); 2141 reply(211, "End of status"); 2142 } 2143 2144 void 2145 fatalerror(char *s) 2146 { 2147 2148 reply(451, "Error in server: %s\n", s); 2149 reply(221, "Closing connection due to server error."); 2150 dologout(0); 2151 /* NOTREACHED */ 2152 } 2153 2154 void 2155 reply(int n, const char *fmt, ...) 2156 { 2157 va_list ap; 2158 2159 va_start(ap, fmt); 2160 (void)printf("%d ", n); 2161 (void)vprintf(fmt, ap); 2162 (void)printf("\r\n"); 2163 (void)fflush(stdout); 2164 if (ftpdebug) { 2165 syslog(LOG_DEBUG, "<--- %d ", n); 2166 vsyslog(LOG_DEBUG, fmt, ap); 2167 } 2168 } 2169 2170 void 2171 lreply(int n, const char *fmt, ...) 2172 { 2173 va_list ap; 2174 2175 va_start(ap, fmt); 2176 (void)printf("%d- ", n); 2177 (void)vprintf(fmt, ap); 2178 (void)printf("\r\n"); 2179 (void)fflush(stdout); 2180 if (ftpdebug) { 2181 syslog(LOG_DEBUG, "<--- %d- ", n); 2182 vsyslog(LOG_DEBUG, fmt, ap); 2183 } 2184 } 2185 2186 static void 2187 ack(char *s) 2188 { 2189 2190 reply(250, "%s command successful.", s); 2191 } 2192 2193 void 2194 nack(char *s) 2195 { 2196 2197 reply(502, "%s command not implemented.", s); 2198 } 2199 2200 /* ARGSUSED */ 2201 void 2202 yyerror(char *s) 2203 { 2204 char *cp; 2205 2206 if ((cp = strchr(cbuf,'\n'))) 2207 *cp = '\0'; 2208 reply(500, "'%s': command not understood.", cbuf); 2209 } 2210 2211 void 2212 delete(char *name) 2213 { 2214 struct stat st; 2215 2216 LOGCMD("delete", name); 2217 if (stat(name, &st) < 0) { 2218 perror_reply(550, name); 2219 return; 2220 } 2221 if ((st.st_mode&S_IFMT) == S_IFDIR) { 2222 if (rmdir(name) < 0) { 2223 perror_reply(550, name); 2224 return; 2225 } 2226 goto done; 2227 } 2228 if (unlink(name) < 0) { 2229 perror_reply(550, name); 2230 return; 2231 } 2232 done: 2233 ack("DELE"); 2234 } 2235 2236 void 2237 cwd(char *path) 2238 { 2239 2240 if (chdir(path) < 0) 2241 perror_reply(550, path); 2242 else 2243 ack("CWD"); 2244 } 2245 2246 void 2247 makedir(char *name) 2248 { 2249 2250 LOGCMD("mkdir", name); 2251 if (mkdir(name, 0777) < 0) 2252 perror_reply(550, name); 2253 else 2254 reply(257, "MKD command successful."); 2255 } 2256 2257 void 2258 removedir(char *name) 2259 { 2260 2261 LOGCMD("rmdir", name); 2262 if (rmdir(name) < 0) 2263 perror_reply(550, name); 2264 else 2265 ack("RMD"); 2266 } 2267 2268 void 2269 pwd(void) 2270 { 2271 char path[MAXPATHLEN + 1]; 2272 2273 if (getwd(path) == (char *)NULL) 2274 reply(550, "%s.", path); 2275 else 2276 reply(257, "\"%s\" is current directory.", path); 2277 } 2278 2279 char * 2280 renamefrom(char *name) 2281 { 2282 struct stat st; 2283 2284 if (stat(name, &st) < 0) { 2285 perror_reply(550, name); 2286 return ((char *)0); 2287 } 2288 reply(350, "File exists, ready for destination name"); 2289 return (name); 2290 } 2291 2292 void 2293 renamecmd(char *from, char *to) 2294 { 2295 struct stat st; 2296 2297 LOGCMD2("rename", from, to); 2298 2299 if (guest && (stat(to, &st) == 0)) { 2300 reply(550, "%s: permission denied", to); 2301 return; 2302 } 2303 2304 if (rename(from, to) < 0) 2305 perror_reply(550, "rename"); 2306 else 2307 ack("RNTO"); 2308 } 2309 2310 static void 2311 dolog(struct sockaddr *who) 2312 { 2313 int error; 2314 2315 realhostname_sa(remotehost, sizeof(remotehost) - 1, who, who->sa_len); 2316 2317 #ifdef SETPROCTITLE 2318 #ifdef VIRTUAL_HOSTING 2319 if (thishost != firsthost) 2320 snprintf(proctitle, sizeof(proctitle), "%s: connected (to %s)", 2321 remotehost, hostname); 2322 else 2323 #endif 2324 snprintf(proctitle, sizeof(proctitle), "%s: connected", 2325 remotehost); 2326 setproctitle("%s", proctitle); 2327 #endif /* SETPROCTITLE */ 2328 2329 if (logging) { 2330 #ifdef VIRTUAL_HOSTING 2331 if (thishost != firsthost) 2332 syslog(LOG_INFO, "connection from %s (to %s)", 2333 remotehost, hostname); 2334 else 2335 #endif 2336 { 2337 char who_name[MAXHOSTNAMELEN]; 2338 2339 error = getnameinfo(who, who->sa_len, 2340 who_name, sizeof(who_name) - 1, 2341 NULL, 0, 2342 NI_NUMERICHOST|NI_WITHSCOPEID); 2343 syslog(LOG_INFO, "connection from %s (%s)", remotehost, 2344 error == 0 ? who_name : ""); 2345 } 2346 } 2347 } 2348 2349 /* 2350 * Record logout in wtmp file 2351 * and exit with supplied status. 2352 */ 2353 void 2354 dologout(int status) 2355 { 2356 /* 2357 * Prevent reception of SIGURG from resulting in a resumption 2358 * back to the main program loop. 2359 */ 2360 transflag = 0; 2361 2362 if (logged_in) { 2363 (void) seteuid((uid_t)0); 2364 ftpd_logwtmp(ttyline, "", NULL); 2365 } 2366 /* beware of flushing buffers after a SIGPIPE */ 2367 _exit(status); 2368 } 2369 2370 static void 2371 sigurg(int signo) 2372 { 2373 2374 recvurg = 1; 2375 } 2376 2377 static void 2378 myoob(void) 2379 { 2380 char *cp; 2381 2382 /* only process if transfer occurring */ 2383 if (!transflag) 2384 return; 2385 cp = tmpline; 2386 if (getline(cp, 7, stdin) == NULL) { 2387 reply(221, "You could at least say goodbye."); 2388 dologout(0); 2389 } 2390 upper(cp); 2391 if (strcmp(cp, "ABOR\r\n") == 0) { 2392 tmpline[0] = '\0'; 2393 reply(426, "Transfer aborted. Data connection closed."); 2394 reply(226, "Abort successful"); 2395 } 2396 if (strcmp(cp, "STAT\r\n") == 0) { 2397 tmpline[0] = '\0'; 2398 if (file_size != (off_t) -1) 2399 reply(213, "Status: %qd of %qd bytes transferred", 2400 byte_count, file_size); 2401 else 2402 reply(213, "Status: %qd bytes transferred", byte_count); 2403 } 2404 } 2405 2406 /* 2407 * Note: a response of 425 is not mentioned as a possible response to 2408 * the PASV command in RFC959. However, it has been blessed as 2409 * a legitimate response by Jon Postel in a telephone conversation 2410 * with Rick Adams on 25 Jan 89. 2411 */ 2412 void 2413 passive(void) 2414 { 2415 int len; 2416 char *p, *a; 2417 2418 if (pdata >= 0) /* close old port if one set */ 2419 close(pdata); 2420 2421 pdata = socket(ctrl_addr.su_family, SOCK_STREAM, 0); 2422 if (pdata < 0) { 2423 perror_reply(425, "Can't open passive connection"); 2424 return; 2425 } 2426 2427 (void) seteuid((uid_t)0); 2428 2429 #ifdef IP_PORTRANGE 2430 if (ctrl_addr.su_family == AF_INET) { 2431 int on = restricted_data_ports ? IP_PORTRANGE_HIGH 2432 : IP_PORTRANGE_DEFAULT; 2433 2434 if (setsockopt(pdata, IPPROTO_IP, IP_PORTRANGE, 2435 (char *)&on, sizeof(on)) < 0) 2436 goto pasv_error; 2437 } 2438 #endif 2439 #ifdef IPV6_PORTRANGE 2440 if (ctrl_addr.su_family == AF_INET6) { 2441 int on = restricted_data_ports ? IPV6_PORTRANGE_HIGH 2442 : IPV6_PORTRANGE_DEFAULT; 2443 2444 if (setsockopt(pdata, IPPROTO_IPV6, IPV6_PORTRANGE, 2445 (char *)&on, sizeof(on)) < 0) 2446 goto pasv_error; 2447 } 2448 #endif 2449 2450 pasv_addr = ctrl_addr; 2451 pasv_addr.su_port = 0; 2452 if (bind(pdata, (struct sockaddr *)&pasv_addr, pasv_addr.su_len) < 0) 2453 goto pasv_error; 2454 2455 (void) seteuid((uid_t)pw->pw_uid); 2456 2457 len = sizeof(pasv_addr); 2458 if (getsockname(pdata, (struct sockaddr *) &pasv_addr, &len) < 0) 2459 goto pasv_error; 2460 if (listen(pdata, 1) < 0) 2461 goto pasv_error; 2462 if (pasv_addr.su_family == AF_INET) 2463 a = (char *) &pasv_addr.su_sin.sin_addr; 2464 else if (pasv_addr.su_family == AF_INET6 && 2465 IN6_IS_ADDR_V4MAPPED(&pasv_addr.su_sin6.sin6_addr)) 2466 a = (char *) &pasv_addr.su_sin6.sin6_addr.s6_addr[12]; 2467 else 2468 goto pasv_error; 2469 2470 p = (char *) &pasv_addr.su_port; 2471 2472 #define UC(b) (((int) b) & 0xff) 2473 2474 reply(227, "Entering Passive Mode (%d,%d,%d,%d,%d,%d)", UC(a[0]), 2475 UC(a[1]), UC(a[2]), UC(a[3]), UC(p[0]), UC(p[1])); 2476 return; 2477 2478 pasv_error: 2479 (void) seteuid((uid_t)pw->pw_uid); 2480 (void) close(pdata); 2481 pdata = -1; 2482 perror_reply(425, "Can't open passive connection"); 2483 return; 2484 } 2485 2486 /* 2487 * Long Passive defined in RFC 1639. 2488 * 228 Entering Long Passive Mode 2489 * (af, hal, h1, h2, h3,..., pal, p1, p2...) 2490 */ 2491 2492 void 2493 long_passive(char *cmd, int pf) 2494 { 2495 int len; 2496 char *p, *a; 2497 2498 if (pdata >= 0) /* close old port if one set */ 2499 close(pdata); 2500 2501 if (pf != PF_UNSPEC) { 2502 if (ctrl_addr.su_family != pf) { 2503 switch (ctrl_addr.su_family) { 2504 case AF_INET: 2505 pf = 1; 2506 break; 2507 case AF_INET6: 2508 pf = 2; 2509 break; 2510 default: 2511 pf = 0; 2512 break; 2513 } 2514 /* 2515 * XXX 2516 * only EPRT/EPSV ready clients will understand this 2517 */ 2518 if (strcmp(cmd, "EPSV") == 0 && pf) { 2519 reply(522, "Network protocol mismatch, " 2520 "use (%d)", pf); 2521 } else 2522 reply(501, "Network protocol mismatch"); /*XXX*/ 2523 2524 return; 2525 } 2526 } 2527 2528 pdata = socket(ctrl_addr.su_family, SOCK_STREAM, 0); 2529 if (pdata < 0) { 2530 perror_reply(425, "Can't open passive connection"); 2531 return; 2532 } 2533 2534 (void) seteuid((uid_t)0); 2535 2536 pasv_addr = ctrl_addr; 2537 pasv_addr.su_port = 0; 2538 len = pasv_addr.su_len; 2539 2540 #ifdef IP_PORTRANGE 2541 if (ctrl_addr.su_family == AF_INET) { 2542 int on = restricted_data_ports ? IP_PORTRANGE_HIGH 2543 : IP_PORTRANGE_DEFAULT; 2544 2545 if (setsockopt(pdata, IPPROTO_IP, IP_PORTRANGE, 2546 (char *)&on, sizeof(on)) < 0) 2547 goto pasv_error; 2548 } 2549 #endif 2550 #ifdef IPV6_PORTRANGE 2551 if (ctrl_addr.su_family == AF_INET6) { 2552 int on = restricted_data_ports ? IPV6_PORTRANGE_HIGH 2553 : IPV6_PORTRANGE_DEFAULT; 2554 2555 if (setsockopt(pdata, IPPROTO_IPV6, IPV6_PORTRANGE, 2556 (char *)&on, sizeof(on)) < 0) 2557 goto pasv_error; 2558 } 2559 #endif 2560 2561 if (bind(pdata, (struct sockaddr *)&pasv_addr, len) < 0) 2562 goto pasv_error; 2563 2564 (void) seteuid((uid_t)pw->pw_uid); 2565 2566 if (getsockname(pdata, (struct sockaddr *) &pasv_addr, &len) < 0) 2567 goto pasv_error; 2568 if (listen(pdata, 1) < 0) 2569 goto pasv_error; 2570 2571 #define UC(b) (((int) b) & 0xff) 2572 2573 if (strcmp(cmd, "LPSV") == 0) { 2574 p = (char *)&pasv_addr.su_port; 2575 switch (pasv_addr.su_family) { 2576 case AF_INET: 2577 a = (char *) &pasv_addr.su_sin.sin_addr; 2578 v4_reply: 2579 reply(228, 2580 "Entering Long Passive Mode (%d,%d,%d,%d,%d,%d,%d,%d,%d)", 2581 4, 4, UC(a[0]), UC(a[1]), UC(a[2]), UC(a[3]), 2582 2, UC(p[0]), UC(p[1])); 2583 return; 2584 case AF_INET6: 2585 if (IN6_IS_ADDR_V4MAPPED(&pasv_addr.su_sin6.sin6_addr)) { 2586 a = (char *) &pasv_addr.su_sin6.sin6_addr.s6_addr[12]; 2587 goto v4_reply; 2588 } 2589 a = (char *) &pasv_addr.su_sin6.sin6_addr; 2590 reply(228, 2591 "Entering Long Passive Mode " 2592 "(%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d)", 2593 6, 16, UC(a[0]), UC(a[1]), UC(a[2]), UC(a[3]), 2594 UC(a[4]), UC(a[5]), UC(a[6]), UC(a[7]), 2595 UC(a[8]), UC(a[9]), UC(a[10]), UC(a[11]), 2596 UC(a[12]), UC(a[13]), UC(a[14]), UC(a[15]), 2597 2, UC(p[0]), UC(p[1])); 2598 return; 2599 } 2600 } else if (strcmp(cmd, "EPSV") == 0) { 2601 switch (pasv_addr.su_family) { 2602 case AF_INET: 2603 case AF_INET6: 2604 reply(229, "Entering Extended Passive Mode (|||%d|)", 2605 ntohs(pasv_addr.su_port)); 2606 return; 2607 } 2608 } else { 2609 /* more proper error code? */ 2610 } 2611 2612 pasv_error: 2613 (void) seteuid((uid_t)pw->pw_uid); 2614 (void) close(pdata); 2615 pdata = -1; 2616 perror_reply(425, "Can't open passive connection"); 2617 return; 2618 } 2619 2620 /* 2621 * Generate unique name for file with basename "local". 2622 * The file named "local" is already known to exist. 2623 * Generates failure reply on error. 2624 */ 2625 static char * 2626 gunique(char *local) 2627 { 2628 static char new[MAXPATHLEN]; 2629 struct stat st; 2630 int count; 2631 char *cp; 2632 2633 cp = strrchr(local, '/'); 2634 if (cp) 2635 *cp = '\0'; 2636 if (stat(cp ? local : ".", &st) < 0) { 2637 perror_reply(553, cp ? local : "."); 2638 return ((char *) 0); 2639 } 2640 if (cp) 2641 *cp = '/'; 2642 /* -4 is for the .nn<null> we put on the end below */ 2643 (void) snprintf(new, sizeof(new) - 4, "%s", local); 2644 cp = new + strlen(new); 2645 *cp++ = '.'; 2646 for (count = 1; count < 100; count++) { 2647 (void)sprintf(cp, "%d", count); 2648 if (stat(new, &st) < 0) 2649 return (new); 2650 } 2651 reply(452, "Unique file name cannot be created."); 2652 return (NULL); 2653 } 2654 2655 /* 2656 * Format and send reply containing system error number. 2657 */ 2658 void 2659 perror_reply(int code, char *string) 2660 { 2661 2662 reply(code, "%s: %s.", string, strerror(errno)); 2663 } 2664 2665 static char *onefile[] = { 2666 "", 2667 0 2668 }; 2669 2670 void 2671 send_file_list(char *whichf) 2672 { 2673 struct stat st; 2674 DIR *dirp = NULL; 2675 struct dirent *dir; 2676 FILE *dout = NULL; 2677 char **dirlist, *dirname; 2678 int simple = 0; 2679 int freeglob = 0; 2680 glob_t gl; 2681 2682 if (strpbrk(whichf, "~{[*?") != NULL) { 2683 int flags = GLOB_BRACE|GLOB_NOCHECK|GLOB_QUOTE|GLOB_TILDE; 2684 2685 memset(&gl, 0, sizeof(gl)); 2686 gl.gl_matchc = MAXGLOBARGS; 2687 flags |= GLOB_LIMIT; 2688 freeglob = 1; 2689 if (glob(whichf, flags, 0, &gl)) { 2690 reply(550, "not found"); 2691 goto out; 2692 } else if (gl.gl_pathc == 0) { 2693 errno = ENOENT; 2694 perror_reply(550, whichf); 2695 goto out; 2696 } 2697 dirlist = gl.gl_pathv; 2698 } else { 2699 onefile[0] = whichf; 2700 dirlist = onefile; 2701 simple = 1; 2702 } 2703 2704 while ((dirname = *dirlist++)) { 2705 if (stat(dirname, &st) < 0) { 2706 /* 2707 * If user typed "ls -l", etc, and the client 2708 * used NLST, do what the user meant. 2709 */ 2710 if (dirname[0] == '-' && *dirlist == NULL && 2711 transflag == 0) { 2712 retrieve(_PATH_LS " %s", dirname); 2713 goto out; 2714 } 2715 perror_reply(550, whichf); 2716 if (dout != NULL) { 2717 (void) fclose(dout); 2718 transflag = 0; 2719 data = -1; 2720 pdata = -1; 2721 } 2722 goto out; 2723 } 2724 2725 if (S_ISREG(st.st_mode)) { 2726 if (dout == NULL) { 2727 dout = dataconn("file list", (off_t)-1, "w"); 2728 if (dout == NULL) 2729 goto out; 2730 transflag++; 2731 } 2732 fprintf(dout, "%s%s\n", dirname, 2733 type == TYPE_A ? "\r" : ""); 2734 byte_count += strlen(dirname) + 1; 2735 continue; 2736 } else if (!S_ISDIR(st.st_mode)) 2737 continue; 2738 2739 if ((dirp = opendir(dirname)) == NULL) 2740 continue; 2741 2742 while ((dir = readdir(dirp)) != NULL) { 2743 char nbuf[MAXPATHLEN]; 2744 2745 if (recvurg) { 2746 myoob(); 2747 recvurg = 0; 2748 transflag = 0; 2749 goto out; 2750 } 2751 2752 if (dir->d_name[0] == '.' && dir->d_namlen == 1) 2753 continue; 2754 if (dir->d_name[0] == '.' && dir->d_name[1] == '.' && 2755 dir->d_namlen == 2) 2756 continue; 2757 2758 snprintf(nbuf, sizeof(nbuf), 2759 "%s/%s", dirname, dir->d_name); 2760 2761 /* 2762 * We have to do a stat to insure it's 2763 * not a directory or special file. 2764 */ 2765 if (simple || (stat(nbuf, &st) == 0 && 2766 S_ISREG(st.st_mode))) { 2767 if (dout == NULL) { 2768 dout = dataconn("file list", (off_t)-1, 2769 "w"); 2770 if (dout == NULL) 2771 goto out; 2772 transflag++; 2773 } 2774 if (nbuf[0] == '.' && nbuf[1] == '/') 2775 fprintf(dout, "%s%s\n", &nbuf[2], 2776 type == TYPE_A ? "\r" : ""); 2777 else 2778 fprintf(dout, "%s%s\n", nbuf, 2779 type == TYPE_A ? "\r" : ""); 2780 byte_count += strlen(nbuf) + 1; 2781 } 2782 } 2783 (void) closedir(dirp); 2784 } 2785 2786 if (dout == NULL) 2787 reply(550, "No files found."); 2788 else if (ferror(dout) != 0) 2789 perror_reply(550, "Data connection"); 2790 else 2791 reply(226, "Transfer complete."); 2792 2793 transflag = 0; 2794 if (dout != NULL) 2795 (void) fclose(dout); 2796 data = -1; 2797 pdata = -1; 2798 out: 2799 if (freeglob) { 2800 freeglob = 0; 2801 globfree(&gl); 2802 } 2803 } 2804 2805 void 2806 reapchild(int signo) 2807 { 2808 while (wait3(NULL, WNOHANG, NULL) > 0); 2809 } 2810 2811 #ifdef OLD_SETPROCTITLE 2812 /* 2813 * Clobber argv so ps will show what we're doing. (Stolen from sendmail.) 2814 * Warning, since this is usually started from inetd.conf, it often doesn't 2815 * have much of an environment or arglist to overwrite. 2816 */ 2817 void 2818 setproctitle(const char *fmt, ...) 2819 { 2820 int i; 2821 va_list ap; 2822 char *p, *bp, ch; 2823 char buf[LINE_MAX]; 2824 2825 va_start(ap, fmt); 2826 (void)vsnprintf(buf, sizeof(buf), fmt, ap); 2827 2828 /* make ps print our process name */ 2829 p = Argv[0]; 2830 *p++ = '-'; 2831 2832 i = strlen(buf); 2833 if (i > LastArgv - p - 2) { 2834 i = LastArgv - p - 2; 2835 buf[i] = '\0'; 2836 } 2837 bp = buf; 2838 while (ch = *bp++) 2839 if (ch != '\n' && ch != '\r') 2840 *p++ = ch; 2841 while (p < LastArgv) 2842 *p++ = ' '; 2843 } 2844 #endif /* OLD_SETPROCTITLE */ 2845 2846 static void 2847 logxfer(char *name, off_t size, time_t start) 2848 { 2849 char buf[1024]; 2850 char path[MAXPATHLEN + 1]; 2851 time_t now; 2852 2853 if (statfd >= 0 && getwd(path) != NULL) { 2854 time(&now); 2855 snprintf(buf, sizeof(buf), "%.20s!%s!%s!%s/%s!%qd!%ld\n", 2856 ctime(&now)+4, ident, remotehost, 2857 path, name, (long long)size, 2858 (long)(now - start + (now == start))); 2859 write(statfd, buf, strlen(buf)); 2860 } 2861 } 2862