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