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