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