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 #define FTP_NAMES 35 #include "ftpd_locl.h" 36 #ifdef KRB5 37 #include <krb5.h> 38 #endif 39 #include "getarg.h" 40 41 RCSID("$Id: ftpd.c,v 1.137 2000/01/05 13:46:04 joda Exp $"); 42 43 static char version[] = "Version 6.00"; 44 45 extern off_t restart_point; 46 extern char cbuf[]; 47 48 struct sockaddr_storage ctrl_addr_ss; 49 struct sockaddr *ctrl_addr = (struct sockaddr *)&ctrl_addr_ss; 50 51 struct sockaddr_storage data_source_ss; 52 struct sockaddr *data_source = (struct sockaddr *)&data_source_ss; 53 54 struct sockaddr_storage data_dest_ss; 55 struct sockaddr *data_dest = (struct sockaddr *)&data_dest_ss; 56 57 struct sockaddr_storage his_addr_ss; 58 struct sockaddr *his_addr = (struct sockaddr *)&his_addr_ss; 59 60 struct sockaddr_storage pasv_addr_ss; 61 struct sockaddr *pasv_addr = (struct sockaddr *)&pasv_addr_ss; 62 63 int data; 64 jmp_buf errcatch, urgcatch; 65 int oobflag; 66 int logged_in; 67 struct passwd *pw; 68 int debug = 0; 69 int ftpd_timeout = 900; /* timeout after 15 minutes of inactivity */ 70 int maxtimeout = 7200;/* don't allow idle time to be set beyond 2 hours */ 71 int logging; 72 int guest; 73 int dochroot; 74 int type; 75 int form; 76 int stru; /* avoid C keyword */ 77 int mode; 78 int usedefault = 1; /* for data transfers */ 79 int pdata = -1; /* for passive mode */ 80 int transflag; 81 off_t file_size; 82 off_t byte_count; 83 #if !defined(CMASK) || CMASK == 0 84 #undef CMASK 85 #define CMASK 027 86 #endif 87 int defumask = CMASK; /* default umask value */ 88 int guest_umask = 0777; /* Paranoia for anonymous users */ 89 char tmpline[10240]; 90 char hostname[MaxHostNameLen]; 91 char remotehost[MaxHostNameLen]; 92 static char ttyline[20]; 93 94 #define AUTH_PLAIN (1 << 0) /* allow sending passwords */ 95 #define AUTH_OTP (1 << 1) /* passwords are one-time */ 96 #define AUTH_FTP (1 << 2) /* allow anonymous login */ 97 98 static int auth_level = 0; /* Only allow kerberos login by default */ 99 100 /* 101 * Timeout intervals for retrying connections 102 * to hosts that don't accept PORT cmds. This 103 * is a kludge, but given the problems with TCP... 104 */ 105 #define SWAITMAX 90 /* wait at most 90 seconds */ 106 #define SWAITINT 5 /* interval between retries */ 107 108 int swaitmax = SWAITMAX; 109 int swaitint = SWAITINT; 110 111 #ifdef HAVE_SETPROCTITLE 112 char proctitle[BUFSIZ]; /* initial part of title */ 113 #endif /* HAVE_SETPROCTITLE */ 114 115 #define LOGCMD(cmd, file) \ 116 if (logging > 1) \ 117 syslog(LOG_INFO,"%s %s%s", cmd, \ 118 *(file) == '/' ? "" : curdir(), file); 119 #define LOGCMD2(cmd, file1, file2) \ 120 if (logging > 1) \ 121 syslog(LOG_INFO,"%s %s%s %s%s", cmd, \ 122 *(file1) == '/' ? "" : curdir(), file1, \ 123 *(file2) == '/' ? "" : curdir(), file2); 124 #define LOGBYTES(cmd, file, cnt) \ 125 if (logging > 1) { \ 126 if (cnt == (off_t)-1) \ 127 syslog(LOG_INFO,"%s %s%s", cmd, \ 128 *(file) == '/' ? "" : curdir(), file); \ 129 else \ 130 syslog(LOG_INFO, "%s %s%s = %ld bytes", \ 131 cmd, (*(file) == '/') ? "" : curdir(), file, (long)cnt); \ 132 } 133 134 static void ack (char *); 135 static void myoob (int); 136 static int checkuser (char *, char *); 137 static int checkaccess (char *); 138 static FILE *dataconn (const char *, off_t, const char *); 139 static void dolog (struct sockaddr *sa, int len); 140 static void end_login (void); 141 static FILE *getdatasock (const char *); 142 static char *gunique (char *); 143 static RETSIGTYPE lostconn (int); 144 static int receive_data (FILE *, FILE *); 145 static void send_data (FILE *, FILE *); 146 static struct passwd * sgetpwnam (char *); 147 148 static char * 149 curdir(void) 150 { 151 static char path[MaxPathLen+1]; /* path + '/' + '\0' */ 152 153 if (getcwd(path, sizeof(path)-1) == NULL) 154 return (""); 155 if (path[1] != '\0') /* special case for root dir. */ 156 strlcat(path, "/", sizeof(path)); 157 /* For guest account, skip / since it's chrooted */ 158 return (guest ? path+1 : path); 159 } 160 161 #ifndef LINE_MAX 162 #define LINE_MAX 1024 163 #endif 164 165 static int 166 parse_auth_level(char *str) 167 { 168 char *p; 169 int ret = 0; 170 char *foo = NULL; 171 172 for(p = strtok_r(str, ",", &foo); 173 p; 174 p = strtok_r(NULL, ",", &foo)) { 175 if(strcmp(p, "user") == 0) 176 ; 177 #ifdef OTP 178 else if(strcmp(p, "otp") == 0) 179 ret |= AUTH_PLAIN|AUTH_OTP; 180 #endif 181 else if(strcmp(p, "ftp") == 0 || 182 strcmp(p, "safe") == 0) 183 ret |= AUTH_FTP; 184 else if(strcmp(p, "plain") == 0) 185 ret |= AUTH_PLAIN; 186 else if(strcmp(p, "none") == 0) 187 ret |= AUTH_PLAIN|AUTH_FTP; 188 else 189 warnx("bad value for -a: `%s'", p); 190 } 191 return ret; 192 } 193 194 /* 195 * Print usage and die. 196 */ 197 198 static int debug_flag; 199 static int interactive_flag; 200 static char *guest_umask_string; 201 static char *port_string; 202 static char *umask_string; 203 static char *auth_string; 204 205 int use_builtin_ls = -1; 206 207 static int help_flag; 208 static int version_flag; 209 210 struct getargs args[] = { 211 { NULL, 'a', arg_string, &auth_string, "required authentication" }, 212 { NULL, 'i', arg_flag, &interactive_flag, "don't assume stdin is a socket" }, 213 { NULL, 'p', arg_string, &port_string, "what port to listen to" }, 214 { NULL, 'g', arg_string, &guest_umask_string, "umask for guest logins" }, 215 { NULL, 'l', arg_counter, &logging, "log more stuff", "" }, 216 { NULL, 't', arg_integer, &ftpd_timeout, "initial timeout" }, 217 { NULL, 'T', arg_integer, &maxtimeout, "max timeout" }, 218 { NULL, 'u', arg_string, &umask_string, "umask for user logins" }, 219 { NULL, 'd', arg_flag, &debug_flag, "enable debugging" }, 220 { NULL, 'v', arg_flag, &debug_flag, "enable debugging" }, 221 { "builtin-ls", 'B', arg_flag, &use_builtin_ls, "use built-in ls to list files" }, 222 { "version", 0, arg_flag, &version_flag }, 223 { "help", 'h', arg_flag, &help_flag } 224 }; 225 226 static int num_args = sizeof(args) / sizeof(args[0]); 227 228 static void 229 usage (int code) 230 { 231 arg_printusage(args, num_args, NULL, ""); 232 exit (code); 233 } 234 235 /* output contents of a file */ 236 static int 237 show_file(const char *file, int code) 238 { 239 FILE *f; 240 char buf[128]; 241 242 f = fopen(file, "r"); 243 if(f == NULL) 244 return -1; 245 while(fgets(buf, sizeof(buf), f)){ 246 buf[strcspn(buf, "\r\n")] = '\0'; 247 lreply(code, "%s", buf); 248 } 249 fclose(f); 250 return 0; 251 } 252 253 int 254 main(int argc, char **argv) 255 { 256 int his_addr_len, ctrl_addr_len, on = 1, tos; 257 char *cp, line[LINE_MAX]; 258 FILE *fd; 259 int port; 260 struct servent *sp; 261 262 int optind = 0; 263 264 set_progname (argv[0]); 265 266 #ifdef KRB4 267 /* detach from any tickets and tokens */ 268 { 269 char tkfile[1024]; 270 snprintf(tkfile, sizeof(tkfile), 271 "/tmp/ftp_%u", (unsigned)getpid()); 272 krb_set_tkt_string(tkfile); 273 if(k_hasafs()) 274 k_setpag(); 275 } 276 #endif 277 if(getarg(args, num_args, argc, argv, &optind)) 278 usage(1); 279 280 if(help_flag) 281 usage(0); 282 283 if(version_flag) { 284 print_version(NULL); 285 exit(0); 286 } 287 288 if(auth_string) 289 auth_level = parse_auth_level(auth_string); 290 { 291 char *p; 292 long val = 0; 293 294 if(guest_umask_string) { 295 val = strtol(guest_umask_string, &p, 8); 296 if (*p != '\0' || val < 0) 297 warnx("bad value for -g"); 298 else 299 guest_umask = val; 300 } 301 if(umask_string) { 302 val = strtol(umask_string, &p, 8); 303 if (*p != '\0' || val < 0) 304 warnx("bad value for -u"); 305 else 306 defumask = val; 307 } 308 } 309 if(port_string) { 310 sp = getservbyname(port_string, "tcp"); 311 if(sp) 312 port = sp->s_port; 313 else 314 if(isdigit(port_string[0])) 315 port = htons(atoi(port_string)); 316 else 317 warnx("bad value for -p"); 318 } else { 319 sp = getservbyname("ftp", "tcp"); 320 if(sp) 321 port = sp->s_port; 322 else 323 port = htons(21); 324 } 325 326 if (maxtimeout < ftpd_timeout) 327 maxtimeout = ftpd_timeout; 328 329 #if 0 330 if (ftpd_timeout > maxtimeout) 331 ftpd_timeout = maxtimeout; 332 #endif 333 334 if(interactive_flag) 335 mini_inetd (port); 336 337 /* 338 * LOG_NDELAY sets up the logging connection immediately, 339 * necessary for anonymous ftp's that chroot and can't do it later. 340 */ 341 openlog("ftpd", LOG_PID | LOG_NDELAY, LOG_FTP); 342 his_addr_len = sizeof(his_addr_ss); 343 if (getpeername(STDIN_FILENO, his_addr, &his_addr_len) < 0) { 344 syslog(LOG_ERR, "getpeername (%s): %m",argv[0]); 345 exit(1); 346 } 347 ctrl_addr_len = sizeof(ctrl_addr_ss); 348 if (getsockname(STDIN_FILENO, ctrl_addr, &ctrl_addr_len) < 0) { 349 syslog(LOG_ERR, "getsockname (%s): %m",argv[0]); 350 exit(1); 351 } 352 #if defined(IP_TOS) && defined(HAVE_SETSOCKOPT) 353 tos = IPTOS_LOWDELAY; 354 if (setsockopt(STDIN_FILENO, IPPROTO_IP, IP_TOS, 355 (void *)&tos, sizeof(int)) < 0) 356 syslog(LOG_WARNING, "setsockopt (IP_TOS): %m"); 357 #endif 358 data_source->sa_family = ctrl_addr->sa_family; 359 socket_set_port (data_source, 360 htons(ntohs(socket_get_port(ctrl_addr)) - 1)); 361 362 /* set this here so it can be put in wtmp */ 363 snprintf(ttyline, sizeof(ttyline), "ftp%u", (unsigned)getpid()); 364 365 366 /* freopen(_PATH_DEVNULL, "w", stderr); */ 367 signal(SIGPIPE, lostconn); 368 signal(SIGCHLD, SIG_IGN); 369 #ifdef SIGURG 370 if (signal(SIGURG, myoob) == SIG_ERR) 371 syslog(LOG_ERR, "signal: %m"); 372 #endif 373 374 /* Try to handle urgent data inline */ 375 #if defined(SO_OOBINLINE) && defined(HAVE_SETSOCKOPT) 376 if (setsockopt(0, SOL_SOCKET, SO_OOBINLINE, (void *)&on, 377 sizeof(on)) < 0) 378 syslog(LOG_ERR, "setsockopt: %m"); 379 #endif 380 381 #ifdef F_SETOWN 382 if (fcntl(fileno(stdin), F_SETOWN, getpid()) == -1) 383 syslog(LOG_ERR, "fcntl F_SETOWN: %m"); 384 #endif 385 dolog(his_addr, his_addr_len); 386 /* 387 * Set up default state 388 */ 389 data = -1; 390 type = TYPE_A; 391 form = FORM_N; 392 stru = STRU_F; 393 mode = MODE_S; 394 tmpline[0] = '\0'; 395 396 /* If logins are disabled, print out the message. */ 397 if(show_file(_PATH_NOLOGIN, 530) == 0) { 398 reply(530, "System not available."); 399 exit(0); 400 } 401 show_file(_PATH_FTPWELCOME, 220); 402 /* reply(220,) must follow */ 403 gethostname(hostname, sizeof(hostname)); 404 405 reply(220, "%s FTP server (%s" 406 #ifdef KRB5 407 "+%s" 408 #endif 409 #ifdef KRB4 410 "+%s" 411 #endif 412 ") ready.", hostname, version 413 #ifdef KRB5 414 ,heimdal_version 415 #endif 416 #ifdef KRB4 417 ,krb4_version 418 #endif 419 ); 420 421 setjmp(errcatch); 422 for (;;) 423 yyparse(); 424 /* NOTREACHED */ 425 } 426 427 static RETSIGTYPE 428 lostconn(int signo) 429 { 430 431 if (debug) 432 syslog(LOG_DEBUG, "lost connection"); 433 dologout(-1); 434 } 435 436 /* 437 * Helper function for sgetpwnam(). 438 */ 439 static char * 440 sgetsave(char *s) 441 { 442 char *new = strdup(s); 443 444 if (new == NULL) { 445 perror_reply(421, "Local resource failure: malloc"); 446 dologout(1); 447 /* NOTREACHED */ 448 } 449 return new; 450 } 451 452 /* 453 * Save the result of a getpwnam. Used for USER command, since 454 * the data returned must not be clobbered by any other command 455 * (e.g., globbing). 456 */ 457 static struct passwd * 458 sgetpwnam(char *name) 459 { 460 static struct passwd save; 461 struct passwd *p; 462 463 if ((p = k_getpwnam(name)) == NULL) 464 return (p); 465 if (save.pw_name) { 466 free(save.pw_name); 467 free(save.pw_passwd); 468 free(save.pw_gecos); 469 free(save.pw_dir); 470 free(save.pw_shell); 471 } 472 save = *p; 473 save.pw_name = sgetsave(p->pw_name); 474 save.pw_passwd = sgetsave(p->pw_passwd); 475 save.pw_gecos = sgetsave(p->pw_gecos); 476 save.pw_dir = sgetsave(p->pw_dir); 477 save.pw_shell = sgetsave(p->pw_shell); 478 return (&save); 479 } 480 481 static int login_attempts; /* number of failed login attempts */ 482 static int askpasswd; /* had user command, ask for passwd */ 483 static char curname[10]; /* current USER name */ 484 #ifdef OTP 485 OtpContext otp_ctx; 486 #endif 487 488 /* 489 * USER command. 490 * Sets global passwd pointer pw if named account exists and is acceptable; 491 * sets askpasswd if a PASS command is expected. If logged in previously, 492 * need to reset state. If name is "ftp" or "anonymous", the name is not in 493 * _PATH_FTPUSERS, and ftp account exists, set guest and pw, then just return. 494 * If account doesn't exist, ask for passwd anyway. Otherwise, check user 495 * requesting login privileges. Disallow anyone who does not have a standard 496 * shell as returned by getusershell(). Disallow anyone mentioned in the file 497 * _PATH_FTPUSERS to allow people such as root and uucp to be avoided. 498 */ 499 void 500 user(char *name) 501 { 502 char *cp, *shell; 503 504 if(auth_level == 0 && !sec_complete){ 505 reply(530, "No login allowed without authorization."); 506 return; 507 } 508 509 if (logged_in) { 510 if (guest) { 511 reply(530, "Can't change user from guest login."); 512 return; 513 } else if (dochroot) { 514 reply(530, "Can't change user from chroot user."); 515 return; 516 } 517 end_login(); 518 } 519 520 guest = 0; 521 if (strcmp(name, "ftp") == 0 || strcmp(name, "anonymous") == 0) { 522 if ((auth_level & AUTH_FTP) == 0 || 523 checkaccess("ftp") || 524 checkaccess("anonymous")) 525 reply(530, "User %s access denied.", name); 526 else if ((pw = sgetpwnam("ftp")) != NULL) { 527 guest = 1; 528 defumask = guest_umask; /* paranoia for incoming */ 529 askpasswd = 1; 530 reply(331, "Guest login ok, type your name as password."); 531 } else 532 reply(530, "User %s unknown.", name); 533 if (!askpasswd && logging) { 534 char data_addr[256]; 535 536 if (inet_ntop (his_addr->sa_family, 537 socket_get_address(his_addr), 538 data_addr, sizeof(data_addr)) == NULL) 539 strlcpy (data_addr, "unknown address", 540 sizeof(data_addr)); 541 542 syslog(LOG_NOTICE, 543 "ANONYMOUS FTP LOGIN REFUSED FROM %s(%s)", 544 remotehost, data_addr); 545 } 546 return; 547 } 548 if((auth_level & AUTH_PLAIN) == 0 && !sec_complete){ 549 reply(530, "Only authorized and anonymous login allowed."); 550 return; 551 } 552 if ((pw = sgetpwnam(name))) { 553 if ((shell = pw->pw_shell) == NULL || *shell == 0) 554 shell = _PATH_BSHELL; 555 while ((cp = getusershell()) != NULL) 556 if (strcmp(cp, shell) == 0) 557 break; 558 endusershell(); 559 560 if (cp == NULL || checkaccess(name)) { 561 reply(530, "User %s access denied.", name); 562 if (logging) { 563 char data_addr[256]; 564 565 if (inet_ntop (his_addr->sa_family, 566 socket_get_address(his_addr), 567 data_addr, 568 sizeof(data_addr)) == NULL) 569 strlcpy (data_addr, 570 "unknown address", 571 sizeof(data_addr)); 572 573 syslog(LOG_NOTICE, 574 "FTP LOGIN REFUSED FROM %s(%s), %s", 575 remotehost, 576 data_addr, 577 name); 578 } 579 pw = (struct passwd *) NULL; 580 return; 581 } 582 } 583 if (logging) 584 strlcpy(curname, name, sizeof(curname)); 585 if(sec_complete) { 586 if(sec_userok(name) == 0) 587 do_login(232, name); 588 else 589 reply(530, "User %s access denied.", name); 590 } else { 591 char ss[256]; 592 593 #ifdef OTP 594 if (otp_challenge(&otp_ctx, name, ss, sizeof(ss)) == 0) { 595 reply(331, "Password %s for %s required.", 596 ss, name); 597 askpasswd = 1; 598 } else 599 #endif 600 if ((auth_level & AUTH_OTP) == 0) { 601 reply(331, "Password required for %s.", name); 602 askpasswd = 1; 603 } else { 604 char *s; 605 606 #ifdef OTP 607 if ((s = otp_error (&otp_ctx)) != NULL) 608 lreply(530, "OTP: %s", s); 609 #endif 610 reply(530, 611 "Only authorized, anonymous" 612 #ifdef OTP 613 " and OTP " 614 #endif 615 "login allowed."); 616 } 617 618 } 619 /* 620 * Delay before reading passwd after first failed 621 * attempt to slow down passwd-guessing programs. 622 */ 623 if (login_attempts) 624 sleep(login_attempts); 625 } 626 627 /* 628 * Check if a user is in the file "fname" 629 */ 630 static int 631 checkuser(char *fname, char *name) 632 { 633 FILE *fd; 634 int found = 0; 635 char *p, line[BUFSIZ]; 636 637 if ((fd = fopen(fname, "r")) != NULL) { 638 while (fgets(line, sizeof(line), fd) != NULL) 639 if ((p = strchr(line, '\n')) != NULL) { 640 *p = '\0'; 641 if (line[0] == '#') 642 continue; 643 if (strcmp(line, name) == 0) { 644 found = 1; 645 break; 646 } 647 } 648 fclose(fd); 649 } 650 return (found); 651 } 652 653 654 /* 655 * Determine whether a user has access, based on information in 656 * _PATH_FTPUSERS. The users are listed one per line, with `allow' 657 * or `deny' after the username. If anything other than `allow', or 658 * just nothing, is given after the username, `deny' is assumed. 659 * 660 * If the user is not found in the file, but the pseudo-user `*' is, 661 * the permission is taken from that line. 662 * 663 * This preserves the old semantics where if a user was listed in the 664 * file he was denied, otherwise he was allowed. 665 * 666 * Return 1 if the user is denied, or 0 if he is allowed. */ 667 668 static int 669 match(const char *pattern, const char *string) 670 { 671 return fnmatch(pattern, string, FNM_NOESCAPE); 672 } 673 674 static int 675 checkaccess(char *name) 676 { 677 #define ALLOWED 0 678 #define NOT_ALLOWED 1 679 FILE *fd; 680 int allowed = ALLOWED; 681 char *user, *perm, line[BUFSIZ]; 682 char *foo; 683 684 fd = fopen(_PATH_FTPUSERS, "r"); 685 686 if(fd == NULL) 687 return allowed; 688 689 while (fgets(line, sizeof(line), fd) != NULL) { 690 foo = NULL; 691 user = strtok_r(line, " \t\n", &foo); 692 if (user == NULL || user[0] == '#') 693 continue; 694 perm = strtok_r(NULL, " \t\n", &foo); 695 if (match(user, name) == 0){ 696 if(perm && strcmp(perm, "allow") == 0) 697 allowed = ALLOWED; 698 else 699 allowed = NOT_ALLOWED; 700 break; 701 } 702 } 703 fclose(fd); 704 return allowed; 705 } 706 #undef ALLOWED 707 #undef NOT_ALLOWED 708 709 710 int do_login(int code, char *passwd) 711 { 712 FILE *fd; 713 login_attempts = 0; /* this time successful */ 714 if (setegid((gid_t)pw->pw_gid) < 0) { 715 reply(550, "Can't set gid."); 716 return -1; 717 } 718 initgroups(pw->pw_name, pw->pw_gid); 719 720 /* open wtmp before chroot */ 721 ftpd_logwtmp(ttyline, pw->pw_name, remotehost); 722 logged_in = 1; 723 724 dochroot = checkuser(_PATH_FTPCHROOT, pw->pw_name); 725 if (guest) { 726 /* 727 * We MUST do a chdir() after the chroot. Otherwise 728 * the old current directory will be accessible as "." 729 * outside the new root! 730 */ 731 if (chroot(pw->pw_dir) < 0 || chdir("/") < 0) { 732 reply(550, "Can't set guest privileges."); 733 return -1; 734 } 735 } else if (dochroot) { 736 if (chroot(pw->pw_dir) < 0 || chdir("/") < 0) { 737 reply(550, "Can't change root."); 738 return -1; 739 } 740 } else if (chdir(pw->pw_dir) < 0) { 741 if (chdir("/") < 0) { 742 reply(530, "User %s: can't change directory to %s.", 743 pw->pw_name, pw->pw_dir); 744 return -1; 745 } else 746 lreply(code, "No directory! Logging in with home=/"); 747 } 748 if (seteuid((uid_t)pw->pw_uid) < 0) { 749 reply(550, "Can't set uid."); 750 return -1; 751 } 752 753 if(use_builtin_ls == -1) { 754 struct stat st; 755 /* if /bin/ls exist and is a regular file, use it, otherwise 756 use built-in ls */ 757 if(stat("/bin/ls", &st) == 0 && 758 S_ISREG(st.st_mode)) 759 use_builtin_ls = 0; 760 else 761 use_builtin_ls = 1; 762 } 763 764 /* 765 * Display a login message, if it exists. 766 * N.B. reply(code,) must follow the message. 767 */ 768 show_file(_PATH_FTPLOGINMESG, code); 769 if(show_file(_PATH_ISSUE_NET, code) != 0) 770 show_file(_PATH_ISSUE, code); 771 if (guest) { 772 reply(code, "Guest login ok, access restrictions apply."); 773 #ifdef HAVE_SETPROCTITLE 774 snprintf (proctitle, sizeof(proctitle), 775 "%s: anonymous/%s", 776 remotehost, 777 passwd); 778 setproctitle(proctitle); 779 #endif /* HAVE_SETPROCTITLE */ 780 if (logging) { 781 char data_addr[256]; 782 783 if (inet_ntop (his_addr->sa_family, 784 socket_get_address(his_addr), 785 data_addr, sizeof(data_addr)) == NULL) 786 strlcpy (data_addr, "unknown address", 787 sizeof(data_addr)); 788 789 syslog(LOG_INFO, "ANONYMOUS FTP LOGIN FROM %s(%s), %s", 790 remotehost, 791 data_addr, 792 passwd); 793 } 794 } else { 795 reply(code, "User %s logged in.", pw->pw_name); 796 #ifdef HAVE_SETPROCTITLE 797 snprintf(proctitle, sizeof(proctitle), "%s: %s", remotehost, pw->pw_name); 798 setproctitle(proctitle); 799 #endif /* HAVE_SETPROCTITLE */ 800 if (logging) { 801 char data_addr[256]; 802 803 if (inet_ntop (his_addr->sa_family, 804 socket_get_address(his_addr), 805 data_addr, sizeof(data_addr)) == NULL) 806 strlcpy (data_addr, "unknown address", 807 sizeof(data_addr)); 808 809 syslog(LOG_INFO, "FTP LOGIN FROM %s(%s) as %s", 810 remotehost, 811 data_addr, 812 pw->pw_name); 813 } 814 } 815 umask(defumask); 816 return 0; 817 } 818 819 /* 820 * Terminate login as previous user, if any, resetting state; 821 * used when USER command is given or login fails. 822 */ 823 static void 824 end_login(void) 825 { 826 827 seteuid((uid_t)0); 828 if (logged_in) 829 ftpd_logwtmp(ttyline, "", ""); 830 pw = NULL; 831 logged_in = 0; 832 guest = 0; 833 dochroot = 0; 834 } 835 836 void 837 pass(char *passwd) 838 { 839 int rval; 840 841 /* some clients insists on sending a password */ 842 if (logged_in && askpasswd == 0){ 843 reply(230, "Dumpucko!"); 844 return; 845 } 846 847 if (logged_in || askpasswd == 0) { 848 reply(503, "Login with USER first."); 849 return; 850 } 851 askpasswd = 0; 852 rval = 1; 853 if (!guest) { /* "ftp" is only account allowed no password */ 854 if (pw == NULL) 855 rval = 1; /* failure below */ 856 #ifdef OTP 857 else if (otp_verify_user (&otp_ctx, passwd) == 0) { 858 rval = 0; 859 } 860 #endif 861 else if((auth_level & AUTH_OTP) == 0) { 862 #ifdef KRB4 863 char realm[REALM_SZ]; 864 if((rval = krb_get_lrealm(realm, 1)) == KSUCCESS) 865 rval = krb_verify_user(pw->pw_name, 866 "", realm, 867 passwd, 868 KRB_VERIFY_SECURE, NULL); 869 if (rval == KSUCCESS ) { 870 chown (tkt_string(), pw->pw_uid, pw->pw_gid); 871 if(k_hasafs()) 872 krb_afslog(0, 0); 873 } else 874 #endif 875 rval = unix_verify_user(pw->pw_name, passwd); 876 } else { 877 char *s; 878 879 #ifdef OTP 880 if ((s = otp_error(&otp_ctx)) != NULL) 881 lreply(530, "OTP: %s", s); 882 #endif 883 } 884 memset (passwd, 0, strlen(passwd)); 885 886 /* 887 * If rval == 1, the user failed the authentication 888 * check above. If rval == 0, either Kerberos or 889 * local authentication succeeded. 890 */ 891 if (rval) { 892 char data_addr[256]; 893 894 if (inet_ntop (his_addr->sa_family, 895 socket_get_address(his_addr), 896 data_addr, sizeof(data_addr)) == NULL) 897 strlcpy (data_addr, "unknown address", 898 sizeof(data_addr)); 899 900 reply(530, "Login incorrect."); 901 if (logging) 902 syslog(LOG_NOTICE, 903 "FTP LOGIN FAILED FROM %s(%s), %s", 904 remotehost, 905 data_addr, 906 curname); 907 pw = NULL; 908 if (login_attempts++ >= 5) { 909 syslog(LOG_NOTICE, 910 "repeated login failures from %s(%s)", 911 remotehost, 912 data_addr); 913 exit(0); 914 } 915 return; 916 } 917 } 918 if(!do_login(230, passwd)) 919 return; 920 921 /* Forget all about it... */ 922 end_login(); 923 } 924 925 void 926 retrieve(const char *cmd, char *name) 927 { 928 FILE *fin = NULL, *dout; 929 struct stat st; 930 int (*closefunc) (FILE *); 931 char line[BUFSIZ]; 932 933 934 if (cmd == 0) { 935 fin = fopen(name, "r"); 936 closefunc = fclose; 937 st.st_size = 0; 938 if(fin == NULL){ 939 int save_errno = errno; 940 struct cmds { 941 const char *ext; 942 const char *cmd; 943 const char *rev_cmd; 944 } cmds[] = { 945 {".tar", "/bin/gtar cPf - %s", NULL}, 946 {".tar.gz", "/bin/gtar zcPf - %s", NULL}, 947 {".tar.Z", "/bin/gtar ZcPf - %s", NULL}, 948 {".gz", "/bin/gzip -c -- %s", "/bin/gzip -c -d -- %s"}, 949 {".Z", "/bin/compress -c -- %s", "/bin/uncompress -c -- %s"}, 950 {NULL, NULL} 951 }; 952 struct cmds *p; 953 for(p = cmds; p->ext; p++){ 954 char *tail = name + strlen(name) - strlen(p->ext); 955 char c = *tail; 956 957 if(strcmp(tail, p->ext) == 0 && 958 (*tail = 0) == 0 && 959 access(name, R_OK) == 0){ 960 snprintf (line, sizeof(line), p->cmd, name); 961 *tail = c; 962 break; 963 } 964 *tail = c; 965 if (p->rev_cmd != NULL) { 966 char *ext; 967 968 asprintf(&ext, "%s%s", name, p->ext); 969 if (ext != NULL) { 970 if (access(ext, R_OK) == 0) { 971 snprintf (line, sizeof(line), 972 p->rev_cmd, ext); 973 free(ext); 974 break; 975 } 976 free(ext); 977 } 978 } 979 980 } 981 if(p->ext){ 982 fin = ftpd_popen(line, "r", 0, 0); 983 closefunc = ftpd_pclose; 984 st.st_size = -1; 985 cmd = line; 986 } else 987 errno = save_errno; 988 } 989 } else { 990 snprintf(line, sizeof(line), cmd, name); 991 name = line; 992 fin = ftpd_popen(line, "r", 1, 0); 993 closefunc = ftpd_pclose; 994 st.st_size = -1; 995 } 996 if (fin == NULL) { 997 if (errno != 0) { 998 perror_reply(550, name); 999 if (cmd == 0) { 1000 LOGCMD("get", name); 1001 } 1002 } 1003 return; 1004 } 1005 byte_count = -1; 1006 if (cmd == 0){ 1007 if(fstat(fileno(fin), &st) < 0 || !S_ISREG(st.st_mode)) { 1008 reply(550, "%s: not a plain file.", name); 1009 goto done; 1010 } 1011 } 1012 if (restart_point) { 1013 if (type == TYPE_A) { 1014 off_t i, n; 1015 int c; 1016 1017 n = restart_point; 1018 i = 0; 1019 while (i++ < n) { 1020 if ((c=getc(fin)) == EOF) { 1021 perror_reply(550, name); 1022 goto done; 1023 } 1024 if (c == '\n') 1025 i++; 1026 } 1027 } else if (lseek(fileno(fin), restart_point, SEEK_SET) < 0) { 1028 perror_reply(550, name); 1029 goto done; 1030 } 1031 } 1032 dout = dataconn(name, st.st_size, "w"); 1033 if (dout == NULL) 1034 goto done; 1035 set_buffer_size(fileno(dout), 0); 1036 send_data(fin, dout); 1037 fclose(dout); 1038 data = -1; 1039 pdata = -1; 1040 done: 1041 if (cmd == 0) 1042 LOGBYTES("get", name, byte_count); 1043 (*closefunc)(fin); 1044 } 1045 1046 /* filename sanity check */ 1047 1048 int 1049 filename_check(char *filename) 1050 { 1051 static const char good_chars[] = "+-=_,."; 1052 char *p; 1053 1054 p = strrchr(filename, '/'); 1055 if(p) 1056 filename = p + 1; 1057 1058 p = filename; 1059 1060 if(isalnum(*p)){ 1061 p++; 1062 while(*p && (isalnum(*p) || strchr(good_chars, *p))) 1063 p++; 1064 if(*p == '\0') 1065 return 0; 1066 } 1067 lreply(553, "\"%s\" is an illegal filename.", filename); 1068 lreply(553, "The filename must start with an alphanumeric " 1069 "character and must only"); 1070 reply(553, "consist of alphanumeric characters or any of the following: %s", 1071 good_chars); 1072 return 1; 1073 } 1074 1075 void 1076 do_store(char *name, char *mode, int unique) 1077 { 1078 FILE *fout, *din; 1079 struct stat st; 1080 int (*closefunc) (FILE *); 1081 1082 if(guest && filename_check(name)) 1083 return; 1084 if (unique && stat(name, &st) == 0 && 1085 (name = gunique(name)) == NULL) { 1086 LOGCMD(*mode == 'w' ? "put" : "append", name); 1087 return; 1088 } 1089 1090 if (restart_point) 1091 mode = "r+"; 1092 fout = fopen(name, mode); 1093 closefunc = fclose; 1094 if (fout == NULL) { 1095 perror_reply(553, name); 1096 LOGCMD(*mode == 'w' ? "put" : "append", name); 1097 return; 1098 } 1099 byte_count = -1; 1100 if (restart_point) { 1101 if (type == TYPE_A) { 1102 off_t i, n; 1103 int c; 1104 1105 n = restart_point; 1106 i = 0; 1107 while (i++ < n) { 1108 if ((c=getc(fout)) == EOF) { 1109 perror_reply(550, name); 1110 goto done; 1111 } 1112 if (c == '\n') 1113 i++; 1114 } 1115 /* 1116 * We must do this seek to "current" position 1117 * because we are changing from reading to 1118 * writing. 1119 */ 1120 if (fseek(fout, 0L, SEEK_CUR) < 0) { 1121 perror_reply(550, name); 1122 goto done; 1123 } 1124 } else if (lseek(fileno(fout), restart_point, SEEK_SET) < 0) { 1125 perror_reply(550, name); 1126 goto done; 1127 } 1128 } 1129 din = dataconn(name, (off_t)-1, "r"); 1130 if (din == NULL) 1131 goto done; 1132 set_buffer_size(fileno(din), 1); 1133 if (receive_data(din, fout) == 0) { 1134 if (unique) 1135 reply(226, "Transfer complete (unique file name:%s).", 1136 name); 1137 else 1138 reply(226, "Transfer complete."); 1139 } 1140 fclose(din); 1141 data = -1; 1142 pdata = -1; 1143 done: 1144 LOGBYTES(*mode == 'w' ? "put" : "append", name, byte_count); 1145 (*closefunc)(fout); 1146 } 1147 1148 static FILE * 1149 getdatasock(const char *mode) 1150 { 1151 int s, t, tries; 1152 1153 if (data >= 0) 1154 return (fdopen(data, mode)); 1155 seteuid(0); 1156 s = socket(ctrl_addr->sa_family, SOCK_STREAM, 0); 1157 if (s < 0) 1158 goto bad; 1159 socket_set_reuseaddr (s, 1); 1160 /* anchor socket to avoid multi-homing problems */ 1161 socket_set_address_and_port (data_source, 1162 socket_get_address (ctrl_addr), 1163 socket_get_port (data_source)); 1164 1165 for (tries = 1; ; tries++) { 1166 if (bind(s, data_source, 1167 socket_sockaddr_size (data_source)) >= 0) 1168 break; 1169 if (errno != EADDRINUSE || tries > 10) 1170 goto bad; 1171 sleep(tries); 1172 } 1173 seteuid(pw->pw_uid); 1174 #ifdef IPTOS_THROUGHPUT 1175 socket_set_tos (s, IPTOS_THROUGHPUT); 1176 #endif 1177 return (fdopen(s, mode)); 1178 bad: 1179 /* Return the real value of errno (close may change it) */ 1180 t = errno; 1181 seteuid((uid_t)pw->pw_uid); 1182 close(s); 1183 errno = t; 1184 return (NULL); 1185 } 1186 1187 static FILE * 1188 dataconn(const char *name, off_t size, const char *mode) 1189 { 1190 char sizebuf[32]; 1191 FILE *file; 1192 int retry = 0; 1193 1194 file_size = size; 1195 byte_count = 0; 1196 if (size >= 0) 1197 snprintf(sizebuf, sizeof(sizebuf), " (%ld bytes)", (long)size); 1198 else 1199 *sizebuf = '\0'; 1200 if (pdata >= 0) { 1201 struct sockaddr_storage from_ss; 1202 struct sockaddr *from = (struct sockaddr *)&from_ss; 1203 int s; 1204 int fromlen = sizeof(from_ss); 1205 1206 s = accept(pdata, from, &fromlen); 1207 if (s < 0) { 1208 reply(425, "Can't open data connection."); 1209 close(pdata); 1210 pdata = -1; 1211 return (NULL); 1212 } 1213 close(pdata); 1214 pdata = s; 1215 #if defined(IP_TOS) && defined(HAVE_SETSOCKOPT) 1216 { 1217 int tos = IPTOS_THROUGHPUT; 1218 1219 setsockopt(s, IPPROTO_IP, IP_TOS, (void *)&tos, 1220 sizeof(tos)); 1221 } 1222 #endif 1223 reply(150, "Opening %s mode data connection for '%s'%s.", 1224 type == TYPE_A ? "ASCII" : "BINARY", name, sizebuf); 1225 return (fdopen(pdata, mode)); 1226 } 1227 if (data >= 0) { 1228 reply(125, "Using existing data connection for '%s'%s.", 1229 name, sizebuf); 1230 usedefault = 1; 1231 return (fdopen(data, mode)); 1232 } 1233 if (usedefault) 1234 data_dest = his_addr; 1235 usedefault = 1; 1236 file = getdatasock(mode); 1237 if (file == NULL) { 1238 char data_addr[256]; 1239 1240 if (inet_ntop (data_source->sa_family, 1241 socket_get_address(data_source), 1242 data_addr, sizeof(data_addr)) == NULL) 1243 strlcpy (data_addr, "unknown address", 1244 sizeof(data_addr)); 1245 1246 reply(425, "Can't create data socket (%s,%d): %s.", 1247 data_addr, 1248 socket_get_port (data_source), 1249 strerror(errno)); 1250 return (NULL); 1251 } 1252 data = fileno(file); 1253 while (connect(data, data_dest, 1254 socket_sockaddr_size(data_dest)) < 0) { 1255 if (errno == EADDRINUSE && retry < swaitmax) { 1256 sleep(swaitint); 1257 retry += swaitint; 1258 continue; 1259 } 1260 perror_reply(425, "Can't build data connection"); 1261 fclose(file); 1262 data = -1; 1263 return (NULL); 1264 } 1265 reply(150, "Opening %s mode data connection for '%s'%s.", 1266 type == TYPE_A ? "ASCII" : "BINARY", name, sizebuf); 1267 return (file); 1268 } 1269 1270 /* 1271 * Tranfer the contents of "instr" to "outstr" peer using the appropriate 1272 * encapsulation of the data subject * to Mode, Structure, and Type. 1273 * 1274 * NB: Form isn't handled. 1275 */ 1276 static void 1277 send_data(FILE *instr, FILE *outstr) 1278 { 1279 int c, cnt, filefd, netfd; 1280 static char *buf; 1281 static size_t bufsize; 1282 1283 transflag++; 1284 if (setjmp(urgcatch)) { 1285 transflag = 0; 1286 return; 1287 } 1288 switch (type) { 1289 1290 case TYPE_A: 1291 while ((c = getc(instr)) != EOF) { 1292 byte_count++; 1293 if(c == '\n') 1294 sec_putc('\r', outstr); 1295 sec_putc(c, outstr); 1296 } 1297 sec_fflush(outstr); 1298 transflag = 0; 1299 if (ferror(instr)) 1300 goto file_err; 1301 if (ferror(outstr)) 1302 goto data_err; 1303 reply(226, "Transfer complete."); 1304 return; 1305 1306 case TYPE_I: 1307 case TYPE_L: 1308 #if defined(HAVE_MMAP) && !defined(NO_MMAP) 1309 #ifndef MAP_FAILED 1310 #define MAP_FAILED (-1) 1311 #endif 1312 { 1313 struct stat st; 1314 char *chunk; 1315 int in = fileno(instr); 1316 if(fstat(in, &st) == 0 && S_ISREG(st.st_mode) 1317 && st.st_size > 0) { 1318 /* 1319 * mmap zero bytes has potential of loosing, don't do it. 1320 */ 1321 chunk = mmap(0, st.st_size, PROT_READ, 1322 MAP_SHARED, in, 0); 1323 if((void *)chunk != (void *)MAP_FAILED) { 1324 cnt = st.st_size - restart_point; 1325 sec_write(fileno(outstr), chunk + restart_point, cnt); 1326 if (munmap(chunk, st.st_size) < 0) 1327 warn ("munmap"); 1328 sec_fflush(outstr); 1329 byte_count = cnt; 1330 transflag = 0; 1331 } 1332 } 1333 } 1334 #endif 1335 if(transflag) { 1336 struct stat st; 1337 1338 netfd = fileno(outstr); 1339 filefd = fileno(instr); 1340 buf = alloc_buffer (buf, &bufsize, 1341 fstat(filefd, &st) >= 0 ? &st : NULL); 1342 if (buf == NULL) { 1343 transflag = 0; 1344 perror_reply(451, "Local resource failure: malloc"); 1345 return; 1346 } 1347 while ((cnt = read(filefd, buf, bufsize)) > 0 && 1348 sec_write(netfd, buf, cnt) == cnt) 1349 byte_count += cnt; 1350 sec_fflush(outstr); /* to end an encrypted stream */ 1351 transflag = 0; 1352 if (cnt != 0) { 1353 if (cnt < 0) 1354 goto file_err; 1355 goto data_err; 1356 } 1357 } 1358 reply(226, "Transfer complete."); 1359 return; 1360 default: 1361 transflag = 0; 1362 reply(550, "Unimplemented TYPE %d in send_data", type); 1363 return; 1364 } 1365 1366 data_err: 1367 transflag = 0; 1368 perror_reply(426, "Data connection"); 1369 return; 1370 1371 file_err: 1372 transflag = 0; 1373 perror_reply(551, "Error on input file"); 1374 } 1375 1376 /* 1377 * Transfer data from peer to "outstr" using the appropriate encapulation of 1378 * the data subject to Mode, Structure, and Type. 1379 * 1380 * N.B.: Form isn't handled. 1381 */ 1382 static int 1383 receive_data(FILE *instr, FILE *outstr) 1384 { 1385 int cnt, bare_lfs = 0; 1386 static char *buf; 1387 static size_t bufsize; 1388 struct stat st; 1389 1390 transflag++; 1391 if (setjmp(urgcatch)) { 1392 transflag = 0; 1393 return (-1); 1394 } 1395 1396 buf = alloc_buffer (buf, &bufsize, 1397 fstat(fileno(outstr), &st) >= 0 ? &st : NULL); 1398 if (buf == NULL) { 1399 transflag = 0; 1400 perror_reply(451, "Local resource failure: malloc"); 1401 return -1; 1402 } 1403 1404 switch (type) { 1405 1406 case TYPE_I: 1407 case TYPE_L: 1408 while ((cnt = sec_read(fileno(instr), buf, bufsize)) > 0) { 1409 if (write(fileno(outstr), buf, cnt) != cnt) 1410 goto file_err; 1411 byte_count += cnt; 1412 } 1413 if (cnt < 0) 1414 goto data_err; 1415 transflag = 0; 1416 return (0); 1417 1418 case TYPE_E: 1419 reply(553, "TYPE E not implemented."); 1420 transflag = 0; 1421 return (-1); 1422 1423 case TYPE_A: 1424 { 1425 char *p, *q; 1426 int cr_flag = 0; 1427 while ((cnt = sec_read(fileno(instr), 1428 buf + cr_flag, 1429 bufsize - cr_flag)) > 0){ 1430 byte_count += cnt; 1431 cnt += cr_flag; 1432 cr_flag = 0; 1433 for(p = buf, q = buf; p < buf + cnt;) { 1434 if(*p == '\n') 1435 bare_lfs++; 1436 if(*p == '\r') { 1437 if(p == buf + cnt - 1){ 1438 cr_flag = 1; 1439 p++; 1440 continue; 1441 }else if(p[1] == '\n'){ 1442 *q++ = '\n'; 1443 p += 2; 1444 continue; 1445 } 1446 } 1447 *q++ = *p++; 1448 } 1449 fwrite(buf, q - buf, 1, outstr); 1450 if(cr_flag) 1451 buf[0] = '\r'; 1452 } 1453 if(cr_flag) 1454 putc('\r', outstr); 1455 fflush(outstr); 1456 if (ferror(instr)) 1457 goto data_err; 1458 if (ferror(outstr)) 1459 goto file_err; 1460 transflag = 0; 1461 if (bare_lfs) { 1462 lreply(226, "WARNING! %d bare linefeeds received in ASCII mode\r\n" 1463 " File may not have transferred correctly.\r\n", 1464 bare_lfs); 1465 } 1466 return (0); 1467 } 1468 default: 1469 reply(550, "Unimplemented TYPE %d in receive_data", type); 1470 transflag = 0; 1471 return (-1); 1472 } 1473 1474 data_err: 1475 transflag = 0; 1476 perror_reply(426, "Data Connection"); 1477 return (-1); 1478 1479 file_err: 1480 transflag = 0; 1481 perror_reply(452, "Error writing file"); 1482 return (-1); 1483 } 1484 1485 void 1486 statfilecmd(char *filename) 1487 { 1488 FILE *fin; 1489 int c; 1490 char line[LINE_MAX]; 1491 1492 snprintf(line, sizeof(line), "/bin/ls -la -- %s", filename); 1493 fin = ftpd_popen(line, "r", 1, 0); 1494 lreply(211, "status of %s:", filename); 1495 while ((c = getc(fin)) != EOF) { 1496 if (c == '\n') { 1497 if (ferror(stdout)){ 1498 perror_reply(421, "control connection"); 1499 ftpd_pclose(fin); 1500 dologout(1); 1501 /* NOTREACHED */ 1502 } 1503 if (ferror(fin)) { 1504 perror_reply(551, filename); 1505 ftpd_pclose(fin); 1506 return; 1507 } 1508 putc('\r', stdout); 1509 } 1510 putc(c, stdout); 1511 } 1512 ftpd_pclose(fin); 1513 reply(211, "End of Status"); 1514 } 1515 1516 void 1517 statcmd(void) 1518 { 1519 #if 0 1520 struct sockaddr_in *sin; 1521 u_char *a, *p; 1522 1523 lreply(211, "%s FTP server (%s) status:", hostname, version); 1524 printf(" %s\r\n", version); 1525 printf(" Connected to %s", remotehost); 1526 if (!isdigit(remotehost[0])) 1527 printf(" (%s)", inet_ntoa(his_addr.sin_addr)); 1528 printf("\r\n"); 1529 if (logged_in) { 1530 if (guest) 1531 printf(" Logged in anonymously\r\n"); 1532 else 1533 printf(" Logged in as %s\r\n", pw->pw_name); 1534 } else if (askpasswd) 1535 printf(" Waiting for password\r\n"); 1536 else 1537 printf(" Waiting for user name\r\n"); 1538 printf(" TYPE: %s", typenames[type]); 1539 if (type == TYPE_A || type == TYPE_E) 1540 printf(", FORM: %s", formnames[form]); 1541 if (type == TYPE_L) 1542 #if NBBY == 8 1543 printf(" %d", NBBY); 1544 #else 1545 printf(" %d", bytesize); /* need definition! */ 1546 #endif 1547 printf("; STRUcture: %s; transfer MODE: %s\r\n", 1548 strunames[stru], modenames[mode]); 1549 if (data != -1) 1550 printf(" Data connection open\r\n"); 1551 else if (pdata != -1) { 1552 printf(" in Passive mode"); 1553 sin = &pasv_addr; 1554 goto printaddr; 1555 } else if (usedefault == 0) { 1556 printf(" PORT"); 1557 sin = &data_dest; 1558 printaddr: 1559 a = (u_char *) &sin->sin_addr; 1560 p = (u_char *) &sin->sin_port; 1561 #define UC(b) (((int) b) & 0xff) 1562 printf(" (%d,%d,%d,%d,%d,%d)\r\n", UC(a[0]), 1563 UC(a[1]), UC(a[2]), UC(a[3]), UC(p[0]), UC(p[1])); 1564 #undef UC 1565 } else 1566 printf(" No data connection\r\n"); 1567 #endif 1568 reply(211, "End of status"); 1569 } 1570 1571 void 1572 fatal(char *s) 1573 { 1574 1575 reply(451, "Error in server: %s\n", s); 1576 reply(221, "Closing connection due to server error."); 1577 dologout(0); 1578 /* NOTREACHED */ 1579 } 1580 1581 static void 1582 int_reply(int, char *, const char *, va_list) 1583 #ifdef __GNUC__ 1584 __attribute__ ((format (printf, 3, 0))) 1585 #endif 1586 ; 1587 1588 static void 1589 int_reply(int n, char *c, const char *fmt, va_list ap) 1590 { 1591 char buf[10240]; 1592 char *p; 1593 p=buf; 1594 if(n){ 1595 snprintf(p, sizeof(buf), "%d%s", n, c); 1596 p+=strlen(p); 1597 } 1598 vsnprintf(p, sizeof(buf) - strlen(p), fmt, ap); 1599 p+=strlen(p); 1600 snprintf(p, sizeof(buf) - strlen(p), "\r\n"); 1601 p+=strlen(p); 1602 sec_fprintf(stdout, "%s", buf); 1603 fflush(stdout); 1604 if (debug) 1605 syslog(LOG_DEBUG, "<--- %s- ", buf); 1606 } 1607 1608 void 1609 reply(int n, const char *fmt, ...) 1610 { 1611 va_list ap; 1612 va_start(ap, fmt); 1613 int_reply(n, " ", fmt, ap); 1614 delete_ftp_command(); 1615 va_end(ap); 1616 } 1617 1618 void 1619 lreply(int n, const char *fmt, ...) 1620 { 1621 va_list ap; 1622 va_start(ap, fmt); 1623 int_reply(n, "-", fmt, ap); 1624 va_end(ap); 1625 } 1626 1627 void 1628 nreply(const char *fmt, ...) 1629 { 1630 va_list ap; 1631 va_start(ap, fmt); 1632 int_reply(0, NULL, fmt, ap); 1633 va_end(ap); 1634 } 1635 1636 static void 1637 ack(char *s) 1638 { 1639 1640 reply(250, "%s command successful.", s); 1641 } 1642 1643 void 1644 nack(char *s) 1645 { 1646 1647 reply(502, "%s command not implemented.", s); 1648 } 1649 1650 /* ARGSUSED */ 1651 void 1652 yyerror(char *s) 1653 { 1654 char *cp; 1655 1656 if ((cp = strchr(cbuf,'\n'))) 1657 *cp = '\0'; 1658 reply(500, "'%s': command not understood.", cbuf); 1659 } 1660 1661 void 1662 do_delete(char *name) 1663 { 1664 struct stat st; 1665 1666 LOGCMD("delete", name); 1667 if (stat(name, &st) < 0) { 1668 perror_reply(550, name); 1669 return; 1670 } 1671 if ((st.st_mode&S_IFMT) == S_IFDIR) { 1672 if (rmdir(name) < 0) { 1673 perror_reply(550, name); 1674 return; 1675 } 1676 goto done; 1677 } 1678 if (unlink(name) < 0) { 1679 perror_reply(550, name); 1680 return; 1681 } 1682 done: 1683 ack("DELE"); 1684 } 1685 1686 void 1687 cwd(char *path) 1688 { 1689 1690 if (chdir(path) < 0) 1691 perror_reply(550, path); 1692 else 1693 ack("CWD"); 1694 } 1695 1696 void 1697 makedir(char *name) 1698 { 1699 1700 LOGCMD("mkdir", name); 1701 if(guest && filename_check(name)) 1702 return; 1703 if (mkdir(name, 0777) < 0) 1704 perror_reply(550, name); 1705 else{ 1706 if(guest) 1707 chmod(name, 0700); /* guest has umask 777 */ 1708 reply(257, "MKD command successful."); 1709 } 1710 } 1711 1712 void 1713 removedir(char *name) 1714 { 1715 1716 LOGCMD("rmdir", name); 1717 if (rmdir(name) < 0) 1718 perror_reply(550, name); 1719 else 1720 ack("RMD"); 1721 } 1722 1723 void 1724 pwd(void) 1725 { 1726 char path[MaxPathLen]; 1727 char *ret; 1728 1729 /* SunOS has a broken getcwd that does popen(pwd) (!!!), this 1730 * failes miserably when running chroot 1731 */ 1732 ret = getcwd(path, sizeof(path)); 1733 if (ret == NULL) 1734 reply(550, "%s.", strerror(errno)); 1735 else 1736 reply(257, "\"%s\" is current directory.", path); 1737 } 1738 1739 char * 1740 renamefrom(char *name) 1741 { 1742 struct stat st; 1743 1744 if (stat(name, &st) < 0) { 1745 perror_reply(550, name); 1746 return NULL; 1747 } 1748 reply(350, "File exists, ready for destination name"); 1749 return (name); 1750 } 1751 1752 void 1753 renamecmd(char *from, char *to) 1754 { 1755 1756 LOGCMD2("rename", from, to); 1757 if(guest && filename_check(to)) 1758 return; 1759 if (rename(from, to) < 0) 1760 perror_reply(550, "rename"); 1761 else 1762 ack("RNTO"); 1763 } 1764 1765 static void 1766 dolog(struct sockaddr *sa, int len) 1767 { 1768 getnameinfo_verified (sa, len, remotehost, sizeof(remotehost), 1769 NULL, 0, 0); 1770 #ifdef HAVE_SETPROCTITLE 1771 snprintf(proctitle, sizeof(proctitle), "%s: connected", remotehost); 1772 setproctitle(proctitle); 1773 #endif /* HAVE_SETPROCTITLE */ 1774 1775 if (logging) { 1776 char data_addr[256]; 1777 1778 if (inet_ntop (his_addr->sa_family, 1779 socket_get_address(his_addr), 1780 data_addr, sizeof(data_addr)) == NULL) 1781 strlcpy (data_addr, "unknown address", 1782 sizeof(data_addr)); 1783 1784 1785 syslog(LOG_INFO, "connection from %s(%s)", 1786 remotehost, 1787 data_addr); 1788 } 1789 } 1790 1791 /* 1792 * Record logout in wtmp file 1793 * and exit with supplied status. 1794 */ 1795 void 1796 dologout(int status) 1797 { 1798 transflag = 0; 1799 if (logged_in) { 1800 seteuid((uid_t)0); 1801 ftpd_logwtmp(ttyline, "", ""); 1802 #ifdef KRB4 1803 cond_kdestroy(); 1804 #endif 1805 } 1806 /* beware of flushing buffers after a SIGPIPE */ 1807 #ifdef XXX 1808 exit(status); 1809 #else 1810 _exit(status); 1811 #endif 1812 } 1813 1814 void abor(void) 1815 { 1816 } 1817 1818 static void 1819 myoob(int signo) 1820 { 1821 #if 0 1822 char *cp; 1823 #endif 1824 1825 /* only process if transfer occurring */ 1826 if (!transflag) 1827 return; 1828 1829 /* This is all XXX */ 1830 oobflag = 1; 1831 /* if the command resulted in a new command, 1832 parse that as well */ 1833 do{ 1834 yyparse(); 1835 } while(ftp_command); 1836 oobflag = 0; 1837 1838 #if 0 1839 cp = tmpline; 1840 if (ftpd_getline(cp, 7) == NULL) { 1841 reply(221, "You could at least say goodbye."); 1842 dologout(0); 1843 } 1844 upper(cp); 1845 if (strcmp(cp, "ABOR\r\n") == 0) { 1846 tmpline[0] = '\0'; 1847 reply(426, "Transfer aborted. Data connection closed."); 1848 reply(226, "Abort successful"); 1849 longjmp(urgcatch, 1); 1850 } 1851 if (strcmp(cp, "STAT\r\n") == 0) { 1852 if (file_size != (off_t) -1) 1853 reply(213, "Status: %ld of %ld bytes transferred", 1854 (long)byte_count, 1855 (long)file_size); 1856 else 1857 reply(213, "Status: %ld bytes transferred" 1858 (long)byte_count); 1859 } 1860 #endif 1861 } 1862 1863 /* 1864 * Note: a response of 425 is not mentioned as a possible response to 1865 * the PASV command in RFC959. However, it has been blessed as 1866 * a legitimate response by Jon Postel in a telephone conversation 1867 * with Rick Adams on 25 Jan 89. 1868 */ 1869 void 1870 pasv(void) 1871 { 1872 int len; 1873 char *p, *a; 1874 struct sockaddr_in *sin; 1875 1876 if (ctrl_addr->sa_family != AF_INET) { 1877 reply(425, 1878 "You cannot do PASV with something that's not IPv4"); 1879 return; 1880 } 1881 1882 pdata = socket(ctrl_addr->sa_family, SOCK_STREAM, 0); 1883 if (pdata < 0) { 1884 perror_reply(425, "Can't open passive connection"); 1885 return; 1886 } 1887 pasv_addr->sa_family = ctrl_addr->sa_family; 1888 socket_set_address_and_port (pasv_addr, 1889 socket_get_address (ctrl_addr), 1890 0); 1891 seteuid(0); 1892 if (bind(pdata, pasv_addr, socket_sockaddr_size (pasv_addr)) < 0) { 1893 seteuid(pw->pw_uid); 1894 goto pasv_error; 1895 } 1896 seteuid(pw->pw_uid); 1897 len = sizeof(pasv_addr_ss); 1898 if (getsockname(pdata, pasv_addr, &len) < 0) 1899 goto pasv_error; 1900 if (listen(pdata, 1) < 0) 1901 goto pasv_error; 1902 sin = (struct sockaddr_in *)pasv_addr; 1903 a = (char *) &sin->sin_addr; 1904 p = (char *) &sin->sin_port; 1905 1906 #define UC(b) (((int) b) & 0xff) 1907 1908 reply(227, "Entering Passive Mode (%d,%d,%d,%d,%d,%d)", UC(a[0]), 1909 UC(a[1]), UC(a[2]), UC(a[3]), UC(p[0]), UC(p[1])); 1910 return; 1911 1912 pasv_error: 1913 close(pdata); 1914 pdata = -1; 1915 perror_reply(425, "Can't open passive connection"); 1916 return; 1917 } 1918 1919 void 1920 epsv(char *proto) 1921 { 1922 int len; 1923 1924 pdata = socket(ctrl_addr->sa_family, SOCK_STREAM, 0); 1925 if (pdata < 0) { 1926 perror_reply(425, "Can't open passive connection"); 1927 return; 1928 } 1929 pasv_addr->sa_family = ctrl_addr->sa_family; 1930 socket_set_address_and_port (pasv_addr, 1931 socket_get_address (ctrl_addr), 1932 0); 1933 seteuid(0); 1934 if (bind(pdata, pasv_addr, socket_sockaddr_size (pasv_addr)) < 0) { 1935 seteuid(pw->pw_uid); 1936 goto pasv_error; 1937 } 1938 seteuid(pw->pw_uid); 1939 len = sizeof(pasv_addr_ss); 1940 if (getsockname(pdata, pasv_addr, &len) < 0) 1941 goto pasv_error; 1942 if (listen(pdata, 1) < 0) 1943 goto pasv_error; 1944 1945 reply(229, "Entering Extended Passive Mode (|||%d|)", 1946 ntohs(socket_get_port (pasv_addr))); 1947 return; 1948 1949 pasv_error: 1950 close(pdata); 1951 pdata = -1; 1952 perror_reply(425, "Can't open passive connection"); 1953 return; 1954 } 1955 1956 void 1957 eprt(char *str) 1958 { 1959 char *end; 1960 char sep; 1961 int af; 1962 int ret; 1963 int port; 1964 1965 usedefault = 0; 1966 if (pdata >= 0) { 1967 close(pdata); 1968 pdata = -1; 1969 } 1970 1971 sep = *str++; 1972 if (sep == '\0') { 1973 reply(500, "Bad syntax in EPRT"); 1974 return; 1975 } 1976 af = strtol (str, &end, 0); 1977 if (af == 0 || *end != sep) { 1978 reply(500, "Bad syntax in EPRT"); 1979 return; 1980 } 1981 str = end + 1; 1982 switch (af) { 1983 #ifdef HAVE_IPV6 1984 case 2 : 1985 data_dest->sa_family = AF_INET6; 1986 break; 1987 #endif 1988 case 1 : 1989 data_dest->sa_family = AF_INET; 1990 break; 1991 default : 1992 reply(522, "Network protocol %d not supported, use (1" 1993 #ifdef HAVE_IPV6 1994 ",2" 1995 #endif 1996 ")", af); 1997 return; 1998 } 1999 end = strchr (str, sep); 2000 if (end == NULL) { 2001 reply(500, "Bad syntax in EPRT"); 2002 return; 2003 } 2004 *end = '\0'; 2005 ret = inet_pton (data_dest->sa_family, str, 2006 socket_get_address (data_dest)); 2007 2008 if (ret != 1) { 2009 reply(500, "Bad address syntax in EPRT"); 2010 return; 2011 } 2012 str = end + 1; 2013 port = strtol (str, &end, 0); 2014 if (port == 0 || *end != sep) { 2015 reply(500, "Bad port syntax in EPRT"); 2016 return; 2017 } 2018 socket_set_port (data_dest, htons(port)); 2019 reply(200, "EPRT command successful."); 2020 } 2021 2022 /* 2023 * Generate unique name for file with basename "local". 2024 * The file named "local" is already known to exist. 2025 * Generates failure reply on error. 2026 */ 2027 static char * 2028 gunique(char *local) 2029 { 2030 static char new[MaxPathLen]; 2031 struct stat st; 2032 int count; 2033 char *cp; 2034 2035 cp = strrchr(local, '/'); 2036 if (cp) 2037 *cp = '\0'; 2038 if (stat(cp ? local : ".", &st) < 0) { 2039 perror_reply(553, cp ? local : "."); 2040 return NULL; 2041 } 2042 if (cp) 2043 *cp = '/'; 2044 for (count = 1; count < 100; count++) { 2045 snprintf (new, sizeof(new), "%s.%d", local, count); 2046 if (stat(new, &st) < 0) 2047 return (new); 2048 } 2049 reply(452, "Unique file name cannot be created."); 2050 return (NULL); 2051 } 2052 2053 /* 2054 * Format and send reply containing system error number. 2055 */ 2056 void 2057 perror_reply(int code, const char *string) 2058 { 2059 reply(code, "%s: %s.", string, strerror(errno)); 2060 } 2061 2062 static char *onefile[] = { 2063 "", 2064 0 2065 }; 2066 2067 void 2068 list_file(char *file) 2069 { 2070 if(use_builtin_ls) { 2071 FILE *dout; 2072 dout = dataconn(file, -1, "w"); 2073 if (dout == NULL) 2074 return; 2075 set_buffer_size(fileno(dout), 0); 2076 builtin_ls(dout, file); 2077 reply(226, "Transfer complete."); 2078 fclose(dout); 2079 data = -1; 2080 pdata = -1; 2081 } else { 2082 #ifdef HAVE_LS_A 2083 const char *cmd = "/bin/ls -lA -- %s"; 2084 #else 2085 const char *cmd = "/bin/ls -la -- %s"; 2086 #endif 2087 retrieve(cmd, file); 2088 } 2089 } 2090 2091 void 2092 send_file_list(char *whichf) 2093 { 2094 struct stat st; 2095 DIR *dirp = NULL; 2096 struct dirent *dir; 2097 FILE *dout = NULL; 2098 char **dirlist, *dirname; 2099 int simple = 0; 2100 int freeglob = 0; 2101 glob_t gl; 2102 char buf[MaxPathLen]; 2103 2104 if (strpbrk(whichf, "~{[*?") != NULL) { 2105 int flags = GLOB_BRACE|GLOB_NOCHECK|GLOB_QUOTE|GLOB_TILDE; 2106 2107 memset(&gl, 0, sizeof(gl)); 2108 freeglob = 1; 2109 if (glob(whichf, flags, 0, &gl)) { 2110 reply(550, "not found"); 2111 goto out; 2112 } else if (gl.gl_pathc == 0) { 2113 errno = ENOENT; 2114 perror_reply(550, whichf); 2115 goto out; 2116 } 2117 dirlist = gl.gl_pathv; 2118 } else { 2119 onefile[0] = whichf; 2120 dirlist = onefile; 2121 simple = 1; 2122 } 2123 2124 if (setjmp(urgcatch)) { 2125 transflag = 0; 2126 goto out; 2127 } 2128 while ((dirname = *dirlist++)) { 2129 if (stat(dirname, &st) < 0) { 2130 /* 2131 * If user typed "ls -l", etc, and the client 2132 * used NLST, do what the user meant. 2133 */ 2134 if (dirname[0] == '-' && *dirlist == NULL && 2135 transflag == 0) { 2136 retrieve("/bin/ls -- %s", dirname); 2137 goto out; 2138 } 2139 perror_reply(550, whichf); 2140 if (dout != NULL) { 2141 fclose(dout); 2142 transflag = 0; 2143 data = -1; 2144 pdata = -1; 2145 } 2146 goto out; 2147 } 2148 2149 if (S_ISREG(st.st_mode)) { 2150 if (dout == NULL) { 2151 dout = dataconn("file list", (off_t)-1, "w"); 2152 if (dout == NULL) 2153 goto out; 2154 transflag++; 2155 } 2156 snprintf(buf, sizeof(buf), "%s%s\n", dirname, 2157 type == TYPE_A ? "\r" : ""); 2158 sec_write(fileno(dout), buf, strlen(buf)); 2159 byte_count += strlen(dirname) + 1; 2160 continue; 2161 } else if (!S_ISDIR(st.st_mode)) 2162 continue; 2163 2164 if ((dirp = opendir(dirname)) == NULL) 2165 continue; 2166 2167 while ((dir = readdir(dirp)) != NULL) { 2168 char nbuf[MaxPathLen]; 2169 2170 if (!strcmp(dir->d_name, ".")) 2171 continue; 2172 if (!strcmp(dir->d_name, "..")) 2173 continue; 2174 2175 snprintf(nbuf, sizeof(nbuf), "%s/%s", dirname, dir->d_name); 2176 2177 /* 2178 * We have to do a stat to insure it's 2179 * not a directory or special file. 2180 */ 2181 if (simple || (stat(nbuf, &st) == 0 && 2182 S_ISREG(st.st_mode))) { 2183 if (dout == NULL) { 2184 dout = dataconn("file list", (off_t)-1, "w"); 2185 if (dout == NULL) 2186 goto out; 2187 transflag++; 2188 } 2189 if(strncmp(nbuf, "./", 2) == 0) 2190 snprintf(buf, sizeof(buf), "%s%s\n", nbuf +2, 2191 type == TYPE_A ? "\r" : ""); 2192 else 2193 snprintf(buf, sizeof(buf), "%s%s\n", nbuf, 2194 type == TYPE_A ? "\r" : ""); 2195 sec_write(fileno(dout), buf, strlen(buf)); 2196 byte_count += strlen(nbuf) + 1; 2197 } 2198 } 2199 closedir(dirp); 2200 } 2201 if (dout == NULL) 2202 reply(550, "No files found."); 2203 else if (ferror(dout) != 0) 2204 perror_reply(550, "Data connection"); 2205 else 2206 reply(226, "Transfer complete."); 2207 2208 transflag = 0; 2209 if (dout != NULL){ 2210 sec_write(fileno(dout), buf, 0); /* XXX flush */ 2211 2212 fclose(dout); 2213 } 2214 data = -1; 2215 pdata = -1; 2216 out: 2217 if (freeglob) { 2218 freeglob = 0; 2219 globfree(&gl); 2220 } 2221 } 2222 2223 2224 int 2225 find(char *pattern) 2226 { 2227 char line[1024]; 2228 FILE *f; 2229 2230 snprintf(line, sizeof(line), 2231 "/bin/locate -d %s -- %s", 2232 ftp_rooted("/etc/locatedb"), 2233 pattern); 2234 f = ftpd_popen(line, "r", 1, 1); 2235 if(f == NULL){ 2236 perror_reply(550, "/bin/locate"); 2237 return 1; 2238 } 2239 lreply(200, "Output from find."); 2240 while(fgets(line, sizeof(line), f)){ 2241 if(line[strlen(line)-1] == '\n') 2242 line[strlen(line)-1] = 0; 2243 nreply("%s", line); 2244 } 2245 reply(200, "Done"); 2246 ftpd_pclose(f); 2247 return 0; 2248 } 2249 2250