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