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.157 2001/04/19 14:41:29 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 setprogname (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((*closefunc)(fout) < 0) 1191 perror_reply(552, name); 1192 else { 1193 if (unique) 1194 reply(226, "Transfer complete (unique file name:%s).", 1195 name); 1196 else 1197 reply(226, "Transfer complete."); 1198 } 1199 } else 1200 (*closefunc)(fout); 1201 fclose(din); 1202 data = -1; 1203 pdata = -1; 1204 done: 1205 LOGBYTES(*mode == 'w' ? "put" : "append", name, byte_count); 1206 } 1207 1208 static FILE * 1209 getdatasock(const char *mode) 1210 { 1211 int s, t, tries; 1212 1213 if (data >= 0) 1214 return (fdopen(data, mode)); 1215 seteuid(0); 1216 s = socket(ctrl_addr->sa_family, SOCK_STREAM, 0); 1217 if (s < 0) 1218 goto bad; 1219 socket_set_reuseaddr (s, 1); 1220 /* anchor socket to avoid multi-homing problems */ 1221 socket_set_address_and_port (data_source, 1222 socket_get_address (ctrl_addr), 1223 socket_get_port (data_source)); 1224 1225 for (tries = 1; ; tries++) { 1226 if (bind(s, data_source, 1227 socket_sockaddr_size (data_source)) >= 0) 1228 break; 1229 if (errno != EADDRINUSE || tries > 10) 1230 goto bad; 1231 sleep(tries); 1232 } 1233 seteuid(pw->pw_uid); 1234 #ifdef IPTOS_THROUGHPUT 1235 socket_set_tos (s, IPTOS_THROUGHPUT); 1236 #endif 1237 return (fdopen(s, mode)); 1238 bad: 1239 /* Return the real value of errno (close may change it) */ 1240 t = errno; 1241 seteuid((uid_t)pw->pw_uid); 1242 close(s); 1243 errno = t; 1244 return (NULL); 1245 } 1246 1247 static FILE * 1248 dataconn(const char *name, off_t size, const char *mode) 1249 { 1250 char sizebuf[32]; 1251 FILE *file; 1252 int retry = 0; 1253 1254 file_size = size; 1255 byte_count = 0; 1256 if (size >= 0) 1257 snprintf(sizebuf, sizeof(sizebuf), " (%ld bytes)", (long)size); 1258 else 1259 *sizebuf = '\0'; 1260 if (pdata >= 0) { 1261 struct sockaddr_storage from_ss; 1262 struct sockaddr *from = (struct sockaddr *)&from_ss; 1263 int s; 1264 socklen_t fromlen = sizeof(from_ss); 1265 1266 s = accept(pdata, from, &fromlen); 1267 if (s < 0) { 1268 reply(425, "Can't open data connection."); 1269 close(pdata); 1270 pdata = -1; 1271 return (NULL); 1272 } 1273 close(pdata); 1274 pdata = s; 1275 #if defined(IP_TOS) && defined(HAVE_SETSOCKOPT) 1276 { 1277 int tos = IPTOS_THROUGHPUT; 1278 1279 setsockopt(s, IPPROTO_IP, IP_TOS, (void *)&tos, 1280 sizeof(tos)); 1281 } 1282 #endif 1283 reply(150, "Opening %s mode data connection for '%s'%s.", 1284 type == TYPE_A ? "ASCII" : "BINARY", name, sizebuf); 1285 return (fdopen(pdata, mode)); 1286 } 1287 if (data >= 0) { 1288 reply(125, "Using existing data connection for '%s'%s.", 1289 name, sizebuf); 1290 usedefault = 1; 1291 return (fdopen(data, mode)); 1292 } 1293 if (usedefault) 1294 data_dest = his_addr; 1295 usedefault = 1; 1296 file = getdatasock(mode); 1297 if (file == NULL) { 1298 char data_addr[256]; 1299 1300 if (inet_ntop (data_source->sa_family, 1301 socket_get_address(data_source), 1302 data_addr, sizeof(data_addr)) == NULL) 1303 strlcpy (data_addr, "unknown address", 1304 sizeof(data_addr)); 1305 1306 reply(425, "Can't create data socket (%s,%d): %s.", 1307 data_addr, 1308 socket_get_port (data_source), 1309 strerror(errno)); 1310 return (NULL); 1311 } 1312 data = fileno(file); 1313 while (connect(data, data_dest, 1314 socket_sockaddr_size(data_dest)) < 0) { 1315 if (errno == EADDRINUSE && retry < swaitmax) { 1316 sleep(swaitint); 1317 retry += swaitint; 1318 continue; 1319 } 1320 perror_reply(425, "Can't build data connection"); 1321 fclose(file); 1322 data = -1; 1323 return (NULL); 1324 } 1325 reply(150, "Opening %s mode data connection for '%s'%s.", 1326 type == TYPE_A ? "ASCII" : "BINARY", name, sizebuf); 1327 return (file); 1328 } 1329 1330 /* 1331 * Tranfer the contents of "instr" to "outstr" peer using the appropriate 1332 * encapsulation of the data subject * to Mode, Structure, and Type. 1333 * 1334 * NB: Form isn't handled. 1335 */ 1336 static void 1337 send_data(FILE *instr, FILE *outstr) 1338 { 1339 int c, cnt, filefd, netfd; 1340 static char *buf; 1341 static size_t bufsize; 1342 1343 transflag++; 1344 if (setjmp(urgcatch)) { 1345 transflag = 0; 1346 return; 1347 } 1348 switch (type) { 1349 1350 case TYPE_A: 1351 while ((c = getc(instr)) != EOF) { 1352 byte_count++; 1353 if(c == '\n') 1354 sec_putc('\r', outstr); 1355 sec_putc(c, outstr); 1356 } 1357 sec_fflush(outstr); 1358 transflag = 0; 1359 if (ferror(instr)) 1360 goto file_err; 1361 if (ferror(outstr)) 1362 goto data_err; 1363 reply(226, "Transfer complete."); 1364 return; 1365 1366 case TYPE_I: 1367 case TYPE_L: 1368 #if defined(HAVE_MMAP) && !defined(NO_MMAP) 1369 #ifndef MAP_FAILED 1370 #define MAP_FAILED (-1) 1371 #endif 1372 { 1373 struct stat st; 1374 char *chunk; 1375 int in = fileno(instr); 1376 if(fstat(in, &st) == 0 && S_ISREG(st.st_mode) 1377 && st.st_size > 0) { 1378 /* 1379 * mmap zero bytes has potential of loosing, don't do it. 1380 */ 1381 chunk = mmap(0, st.st_size, PROT_READ, 1382 MAP_SHARED, in, 0); 1383 if((void *)chunk != (void *)MAP_FAILED) { 1384 cnt = st.st_size - restart_point; 1385 sec_write(fileno(outstr), chunk + restart_point, cnt); 1386 if (munmap(chunk, st.st_size) < 0) 1387 warn ("munmap"); 1388 sec_fflush(outstr); 1389 byte_count = cnt; 1390 transflag = 0; 1391 } 1392 } 1393 } 1394 #endif 1395 if(transflag) { 1396 struct stat st; 1397 1398 netfd = fileno(outstr); 1399 filefd = fileno(instr); 1400 buf = alloc_buffer (buf, &bufsize, 1401 fstat(filefd, &st) >= 0 ? &st : NULL); 1402 if (buf == NULL) { 1403 transflag = 0; 1404 perror_reply(451, "Local resource failure: malloc"); 1405 return; 1406 } 1407 while ((cnt = read(filefd, buf, bufsize)) > 0 && 1408 sec_write(netfd, buf, cnt) == cnt) 1409 byte_count += cnt; 1410 sec_fflush(outstr); /* to end an encrypted stream */ 1411 transflag = 0; 1412 if (cnt != 0) { 1413 if (cnt < 0) 1414 goto file_err; 1415 goto data_err; 1416 } 1417 } 1418 reply(226, "Transfer complete."); 1419 return; 1420 default: 1421 transflag = 0; 1422 reply(550, "Unimplemented TYPE %d in send_data", type); 1423 return; 1424 } 1425 1426 data_err: 1427 transflag = 0; 1428 perror_reply(426, "Data connection"); 1429 return; 1430 1431 file_err: 1432 transflag = 0; 1433 perror_reply(551, "Error on input file"); 1434 } 1435 1436 /* 1437 * Transfer data from peer to "outstr" using the appropriate encapulation of 1438 * the data subject to Mode, Structure, and Type. 1439 * 1440 * N.B.: Form isn't handled. 1441 */ 1442 static int 1443 receive_data(FILE *instr, FILE *outstr) 1444 { 1445 int cnt, bare_lfs = 0; 1446 static char *buf; 1447 static size_t bufsize; 1448 struct stat st; 1449 1450 transflag++; 1451 if (setjmp(urgcatch)) { 1452 transflag = 0; 1453 return (-1); 1454 } 1455 1456 buf = alloc_buffer (buf, &bufsize, 1457 fstat(fileno(outstr), &st) >= 0 ? &st : NULL); 1458 if (buf == NULL) { 1459 transflag = 0; 1460 perror_reply(451, "Local resource failure: malloc"); 1461 return -1; 1462 } 1463 1464 switch (type) { 1465 1466 case TYPE_I: 1467 case TYPE_L: 1468 while ((cnt = sec_read(fileno(instr), buf, bufsize)) > 0) { 1469 if (write(fileno(outstr), buf, cnt) != cnt) 1470 goto file_err; 1471 byte_count += cnt; 1472 } 1473 if (cnt < 0) 1474 goto data_err; 1475 transflag = 0; 1476 return (0); 1477 1478 case TYPE_E: 1479 reply(553, "TYPE E not implemented."); 1480 transflag = 0; 1481 return (-1); 1482 1483 case TYPE_A: 1484 { 1485 char *p, *q; 1486 int cr_flag = 0; 1487 while ((cnt = sec_read(fileno(instr), 1488 buf + cr_flag, 1489 bufsize - cr_flag)) > 0){ 1490 byte_count += cnt; 1491 cnt += cr_flag; 1492 cr_flag = 0; 1493 for(p = buf, q = buf; p < buf + cnt;) { 1494 if(*p == '\n') 1495 bare_lfs++; 1496 if(*p == '\r') { 1497 if(p == buf + cnt - 1){ 1498 cr_flag = 1; 1499 p++; 1500 continue; 1501 }else if(p[1] == '\n'){ 1502 *q++ = '\n'; 1503 p += 2; 1504 continue; 1505 } 1506 } 1507 *q++ = *p++; 1508 } 1509 fwrite(buf, q - buf, 1, outstr); 1510 if(cr_flag) 1511 buf[0] = '\r'; 1512 } 1513 if(cr_flag) 1514 putc('\r', outstr); 1515 fflush(outstr); 1516 if (ferror(instr)) 1517 goto data_err; 1518 if (ferror(outstr)) 1519 goto file_err; 1520 transflag = 0; 1521 if (bare_lfs) { 1522 lreply(226, "WARNING! %d bare linefeeds received in ASCII mode\r\n" 1523 " File may not have transferred correctly.\r\n", 1524 bare_lfs); 1525 } 1526 return (0); 1527 } 1528 default: 1529 reply(550, "Unimplemented TYPE %d in receive_data", type); 1530 transflag = 0; 1531 return (-1); 1532 } 1533 1534 data_err: 1535 transflag = 0; 1536 perror_reply(426, "Data Connection"); 1537 return (-1); 1538 1539 file_err: 1540 transflag = 0; 1541 perror_reply(452, "Error writing file"); 1542 return (-1); 1543 } 1544 1545 void 1546 statfilecmd(char *filename) 1547 { 1548 FILE *fin; 1549 int c; 1550 char line[LINE_MAX]; 1551 1552 snprintf(line, sizeof(line), "/bin/ls -la -- %s", filename); 1553 fin = ftpd_popen(line, "r", 1, 0); 1554 lreply(211, "status of %s:", filename); 1555 while ((c = getc(fin)) != EOF) { 1556 if (c == '\n') { 1557 if (ferror(stdout)){ 1558 perror_reply(421, "control connection"); 1559 ftpd_pclose(fin); 1560 dologout(1); 1561 /* NOTREACHED */ 1562 } 1563 if (ferror(fin)) { 1564 perror_reply(551, filename); 1565 ftpd_pclose(fin); 1566 return; 1567 } 1568 putc('\r', stdout); 1569 } 1570 putc(c, stdout); 1571 } 1572 ftpd_pclose(fin); 1573 reply(211, "End of Status"); 1574 } 1575 1576 void 1577 statcmd(void) 1578 { 1579 #if 0 1580 struct sockaddr_in *sin; 1581 u_char *a, *p; 1582 1583 lreply(211, "%s FTP server (%s) status:", hostname, version); 1584 printf(" %s\r\n", version); 1585 printf(" Connected to %s", remotehost); 1586 if (!isdigit(remotehost[0])) 1587 printf(" (%s)", inet_ntoa(his_addr.sin_addr)); 1588 printf("\r\n"); 1589 if (logged_in) { 1590 if (guest) 1591 printf(" Logged in anonymously\r\n"); 1592 else 1593 printf(" Logged in as %s\r\n", pw->pw_name); 1594 } else if (askpasswd) 1595 printf(" Waiting for password\r\n"); 1596 else 1597 printf(" Waiting for user name\r\n"); 1598 printf(" TYPE: %s", typenames[type]); 1599 if (type == TYPE_A || type == TYPE_E) 1600 printf(", FORM: %s", formnames[form]); 1601 if (type == TYPE_L) 1602 #if NBBY == 8 1603 printf(" %d", NBBY); 1604 #else 1605 printf(" %d", bytesize); /* need definition! */ 1606 #endif 1607 printf("; STRUcture: %s; transfer MODE: %s\r\n", 1608 strunames[stru], modenames[mode]); 1609 if (data != -1) 1610 printf(" Data connection open\r\n"); 1611 else if (pdata != -1) { 1612 printf(" in Passive mode"); 1613 sin = &pasv_addr; 1614 goto printaddr; 1615 } else if (usedefault == 0) { 1616 printf(" PORT"); 1617 sin = &data_dest; 1618 printaddr: 1619 a = (u_char *) &sin->sin_addr; 1620 p = (u_char *) &sin->sin_port; 1621 #define UC(b) (((int) b) & 0xff) 1622 printf(" (%d,%d,%d,%d,%d,%d)\r\n", UC(a[0]), 1623 UC(a[1]), UC(a[2]), UC(a[3]), UC(p[0]), UC(p[1])); 1624 #undef UC 1625 } else 1626 printf(" No data connection\r\n"); 1627 #endif 1628 reply(211, "End of status"); 1629 } 1630 1631 void 1632 fatal(char *s) 1633 { 1634 1635 reply(451, "Error in server: %s\n", s); 1636 reply(221, "Closing connection due to server error."); 1637 dologout(0); 1638 /* NOTREACHED */ 1639 } 1640 1641 static void 1642 int_reply(int, char *, const char *, va_list) 1643 #ifdef __GNUC__ 1644 __attribute__ ((format (printf, 3, 0))) 1645 #endif 1646 ; 1647 1648 static void 1649 int_reply(int n, char *c, const char *fmt, va_list ap) 1650 { 1651 char buf[10240]; 1652 char *p; 1653 p=buf; 1654 if(n){ 1655 snprintf(p, sizeof(buf), "%d%s", n, c); 1656 p+=strlen(p); 1657 } 1658 vsnprintf(p, sizeof(buf) - strlen(p), fmt, ap); 1659 p+=strlen(p); 1660 snprintf(p, sizeof(buf) - strlen(p), "\r\n"); 1661 p+=strlen(p); 1662 sec_fprintf(stdout, "%s", buf); 1663 fflush(stdout); 1664 if (debug) 1665 syslog(LOG_DEBUG, "<--- %s- ", buf); 1666 } 1667 1668 void 1669 reply(int n, const char *fmt, ...) 1670 { 1671 va_list ap; 1672 va_start(ap, fmt); 1673 int_reply(n, " ", fmt, ap); 1674 delete_ftp_command(); 1675 va_end(ap); 1676 } 1677 1678 void 1679 lreply(int n, const char *fmt, ...) 1680 { 1681 va_list ap; 1682 va_start(ap, fmt); 1683 int_reply(n, "-", fmt, ap); 1684 va_end(ap); 1685 } 1686 1687 void 1688 nreply(const char *fmt, ...) 1689 { 1690 va_list ap; 1691 va_start(ap, fmt); 1692 int_reply(0, NULL, fmt, ap); 1693 va_end(ap); 1694 } 1695 1696 static void 1697 ack(char *s) 1698 { 1699 1700 reply(250, "%s command successful.", s); 1701 } 1702 1703 void 1704 nack(char *s) 1705 { 1706 1707 reply(502, "%s command not implemented.", s); 1708 } 1709 1710 /* ARGSUSED */ 1711 void 1712 yyerror(char *s) 1713 { 1714 char *cp; 1715 1716 if ((cp = strchr(cbuf,'\n'))) 1717 *cp = '\0'; 1718 reply(500, "'%s': command not understood.", cbuf); 1719 } 1720 1721 void 1722 do_delete(char *name) 1723 { 1724 struct stat st; 1725 1726 LOGCMD("delete", name); 1727 if (stat(name, &st) < 0) { 1728 perror_reply(550, name); 1729 return; 1730 } 1731 if ((st.st_mode&S_IFMT) == S_IFDIR) { 1732 if (rmdir(name) < 0) { 1733 perror_reply(550, name); 1734 return; 1735 } 1736 goto done; 1737 } 1738 if (unlink(name) < 0) { 1739 perror_reply(550, name); 1740 return; 1741 } 1742 done: 1743 ack("DELE"); 1744 } 1745 1746 void 1747 cwd(char *path) 1748 { 1749 1750 if (chdir(path) < 0) 1751 perror_reply(550, path); 1752 else 1753 ack("CWD"); 1754 } 1755 1756 void 1757 makedir(char *name) 1758 { 1759 1760 LOGCMD("mkdir", name); 1761 if(guest && filename_check(name)) 1762 return; 1763 if (mkdir(name, 0777) < 0) 1764 perror_reply(550, name); 1765 else{ 1766 if(guest) 1767 chmod(name, 0700); /* guest has umask 777 */ 1768 reply(257, "MKD command successful."); 1769 } 1770 } 1771 1772 void 1773 removedir(char *name) 1774 { 1775 1776 LOGCMD("rmdir", name); 1777 if (rmdir(name) < 0) 1778 perror_reply(550, name); 1779 else 1780 ack("RMD"); 1781 } 1782 1783 void 1784 pwd(void) 1785 { 1786 char path[MaxPathLen]; 1787 char *ret; 1788 1789 /* SunOS has a broken getcwd that does popen(pwd) (!!!), this 1790 * failes miserably when running chroot 1791 */ 1792 ret = getcwd(path, sizeof(path)); 1793 if (ret == NULL) 1794 reply(550, "%s.", strerror(errno)); 1795 else 1796 reply(257, "\"%s\" is current directory.", path); 1797 } 1798 1799 char * 1800 renamefrom(char *name) 1801 { 1802 struct stat st; 1803 1804 if (stat(name, &st) < 0) { 1805 perror_reply(550, name); 1806 return NULL; 1807 } 1808 reply(350, "File exists, ready for destination name"); 1809 return (name); 1810 } 1811 1812 void 1813 renamecmd(char *from, char *to) 1814 { 1815 1816 LOGCMD2("rename", from, to); 1817 if(guest && filename_check(to)) 1818 return; 1819 if (rename(from, to) < 0) 1820 perror_reply(550, "rename"); 1821 else 1822 ack("RNTO"); 1823 } 1824 1825 static void 1826 dolog(struct sockaddr *sa, int len) 1827 { 1828 getnameinfo_verified (sa, len, remotehost, sizeof(remotehost), 1829 NULL, 0, 0); 1830 #ifdef HAVE_SETPROCTITLE 1831 snprintf(proctitle, sizeof(proctitle), "%s: connected", remotehost); 1832 setproctitle("%s", proctitle); 1833 #endif /* HAVE_SETPROCTITLE */ 1834 1835 if (logging) { 1836 char data_addr[256]; 1837 1838 if (inet_ntop (his_addr->sa_family, 1839 socket_get_address(his_addr), 1840 data_addr, sizeof(data_addr)) == NULL) 1841 strlcpy (data_addr, "unknown address", 1842 sizeof(data_addr)); 1843 1844 1845 syslog(LOG_INFO, "connection from %s(%s)", 1846 remotehost, 1847 data_addr); 1848 } 1849 } 1850 1851 /* 1852 * Record logout in wtmp file 1853 * and exit with supplied status. 1854 */ 1855 void 1856 dologout(int status) 1857 { 1858 transflag = 0; 1859 if (logged_in) { 1860 seteuid((uid_t)0); 1861 ftpd_logwtmp(ttyline, "", ""); 1862 #ifdef KRB4 1863 cond_kdestroy(); 1864 #endif 1865 } 1866 /* beware of flushing buffers after a SIGPIPE */ 1867 #ifdef XXX 1868 exit(status); 1869 #else 1870 _exit(status); 1871 #endif 1872 } 1873 1874 void abor(void) 1875 { 1876 } 1877 1878 static void 1879 myoob(int signo) 1880 { 1881 #if 0 1882 char *cp; 1883 #endif 1884 1885 /* only process if transfer occurring */ 1886 if (!transflag) 1887 return; 1888 1889 /* This is all XXX */ 1890 oobflag = 1; 1891 /* if the command resulted in a new command, 1892 parse that as well */ 1893 do{ 1894 yyparse(); 1895 } while(ftp_command); 1896 oobflag = 0; 1897 1898 #if 0 1899 cp = tmpline; 1900 if (ftpd_getline(cp, 7) == NULL) { 1901 reply(221, "You could at least say goodbye."); 1902 dologout(0); 1903 } 1904 upper(cp); 1905 if (strcmp(cp, "ABOR\r\n") == 0) { 1906 tmpline[0] = '\0'; 1907 reply(426, "Transfer aborted. Data connection closed."); 1908 reply(226, "Abort successful"); 1909 longjmp(urgcatch, 1); 1910 } 1911 if (strcmp(cp, "STAT\r\n") == 0) { 1912 if (file_size != (off_t) -1) 1913 reply(213, "Status: %ld of %ld bytes transferred", 1914 (long)byte_count, 1915 (long)file_size); 1916 else 1917 reply(213, "Status: %ld bytes transferred" 1918 (long)byte_count); 1919 } 1920 #endif 1921 } 1922 1923 /* 1924 * Note: a response of 425 is not mentioned as a possible response to 1925 * the PASV command in RFC959. However, it has been blessed as 1926 * a legitimate response by Jon Postel in a telephone conversation 1927 * with Rick Adams on 25 Jan 89. 1928 */ 1929 void 1930 pasv(void) 1931 { 1932 socklen_t len; 1933 char *p, *a; 1934 struct sockaddr_in *sin; 1935 1936 if (ctrl_addr->sa_family != AF_INET) { 1937 reply(425, 1938 "You cannot do PASV with something that's not IPv4"); 1939 return; 1940 } 1941 1942 if(pdata != -1) 1943 close(pdata); 1944 1945 pdata = socket(ctrl_addr->sa_family, SOCK_STREAM, 0); 1946 if (pdata < 0) { 1947 perror_reply(425, "Can't open passive connection"); 1948 return; 1949 } 1950 pasv_addr->sa_family = ctrl_addr->sa_family; 1951 socket_set_address_and_port (pasv_addr, 1952 socket_get_address (ctrl_addr), 1953 0); 1954 seteuid(0); 1955 if (bind(pdata, pasv_addr, socket_sockaddr_size (pasv_addr)) < 0) { 1956 seteuid(pw->pw_uid); 1957 goto pasv_error; 1958 } 1959 seteuid(pw->pw_uid); 1960 len = sizeof(pasv_addr_ss); 1961 if (getsockname(pdata, pasv_addr, &len) < 0) 1962 goto pasv_error; 1963 if (listen(pdata, 1) < 0) 1964 goto pasv_error; 1965 sin = (struct sockaddr_in *)pasv_addr; 1966 a = (char *) &sin->sin_addr; 1967 p = (char *) &sin->sin_port; 1968 1969 #define UC(b) (((int) b) & 0xff) 1970 1971 reply(227, "Entering Passive Mode (%d,%d,%d,%d,%d,%d)", UC(a[0]), 1972 UC(a[1]), UC(a[2]), UC(a[3]), UC(p[0]), UC(p[1])); 1973 return; 1974 1975 pasv_error: 1976 close(pdata); 1977 pdata = -1; 1978 perror_reply(425, "Can't open passive connection"); 1979 return; 1980 } 1981 1982 void 1983 epsv(char *proto) 1984 { 1985 socklen_t len; 1986 1987 pdata = socket(ctrl_addr->sa_family, SOCK_STREAM, 0); 1988 if (pdata < 0) { 1989 perror_reply(425, "Can't open passive connection"); 1990 return; 1991 } 1992 pasv_addr->sa_family = ctrl_addr->sa_family; 1993 socket_set_address_and_port (pasv_addr, 1994 socket_get_address (ctrl_addr), 1995 0); 1996 seteuid(0); 1997 if (bind(pdata, pasv_addr, socket_sockaddr_size (pasv_addr)) < 0) { 1998 seteuid(pw->pw_uid); 1999 goto pasv_error; 2000 } 2001 seteuid(pw->pw_uid); 2002 len = sizeof(pasv_addr_ss); 2003 if (getsockname(pdata, pasv_addr, &len) < 0) 2004 goto pasv_error; 2005 if (listen(pdata, 1) < 0) 2006 goto pasv_error; 2007 2008 reply(229, "Entering Extended Passive Mode (|||%d|)", 2009 ntohs(socket_get_port (pasv_addr))); 2010 return; 2011 2012 pasv_error: 2013 close(pdata); 2014 pdata = -1; 2015 perror_reply(425, "Can't open passive connection"); 2016 return; 2017 } 2018 2019 void 2020 eprt(char *str) 2021 { 2022 char *end; 2023 char sep; 2024 int af; 2025 int ret; 2026 int port; 2027 2028 usedefault = 0; 2029 if (pdata >= 0) { 2030 close(pdata); 2031 pdata = -1; 2032 } 2033 2034 sep = *str++; 2035 if (sep == '\0') { 2036 reply(500, "Bad syntax in EPRT"); 2037 return; 2038 } 2039 af = strtol (str, &end, 0); 2040 if (af == 0 || *end != sep) { 2041 reply(500, "Bad syntax in EPRT"); 2042 return; 2043 } 2044 str = end + 1; 2045 switch (af) { 2046 #ifdef HAVE_IPV6 2047 case 2 : 2048 data_dest->sa_family = AF_INET6; 2049 break; 2050 #endif 2051 case 1 : 2052 data_dest->sa_family = AF_INET; 2053 break; 2054 default : 2055 reply(522, "Network protocol %d not supported, use (1" 2056 #ifdef HAVE_IPV6 2057 ",2" 2058 #endif 2059 ")", af); 2060 return; 2061 } 2062 end = strchr (str, sep); 2063 if (end == NULL) { 2064 reply(500, "Bad syntax in EPRT"); 2065 return; 2066 } 2067 *end = '\0'; 2068 ret = inet_pton (data_dest->sa_family, str, 2069 socket_get_address (data_dest)); 2070 2071 if (ret != 1) { 2072 reply(500, "Bad address syntax in EPRT"); 2073 return; 2074 } 2075 str = end + 1; 2076 port = strtol (str, &end, 0); 2077 if (port == 0 || *end != sep) { 2078 reply(500, "Bad port syntax in EPRT"); 2079 return; 2080 } 2081 socket_set_port (data_dest, htons(port)); 2082 reply(200, "EPRT command successful."); 2083 } 2084 2085 /* 2086 * Generate unique name for file with basename "local". 2087 * The file named "local" is already known to exist. 2088 * Generates failure reply on error. 2089 */ 2090 static char * 2091 gunique(char *local) 2092 { 2093 static char new[MaxPathLen]; 2094 struct stat st; 2095 int count; 2096 char *cp; 2097 2098 cp = strrchr(local, '/'); 2099 if (cp) 2100 *cp = '\0'; 2101 if (stat(cp ? local : ".", &st) < 0) { 2102 perror_reply(553, cp ? local : "."); 2103 return NULL; 2104 } 2105 if (cp) 2106 *cp = '/'; 2107 for (count = 1; count < 100; count++) { 2108 snprintf (new, sizeof(new), "%s.%d", local, count); 2109 if (stat(new, &st) < 0) 2110 return (new); 2111 } 2112 reply(452, "Unique file name cannot be created."); 2113 return (NULL); 2114 } 2115 2116 /* 2117 * Format and send reply containing system error number. 2118 */ 2119 void 2120 perror_reply(int code, const char *string) 2121 { 2122 reply(code, "%s: %s.", string, strerror(errno)); 2123 } 2124 2125 static char *onefile[] = { 2126 "", 2127 0 2128 }; 2129 2130 void 2131 list_file(char *file) 2132 { 2133 if(use_builtin_ls) { 2134 FILE *dout; 2135 dout = dataconn(file, -1, "w"); 2136 if (dout == NULL) 2137 return; 2138 set_buffer_size(fileno(dout), 0); 2139 builtin_ls(dout, file); 2140 reply(226, "Transfer complete."); 2141 fclose(dout); 2142 data = -1; 2143 pdata = -1; 2144 } else { 2145 #ifdef HAVE_LS_A 2146 const char *cmd = "/bin/ls -lA %s"; 2147 #else 2148 const char *cmd = "/bin/ls -la %s"; 2149 #endif 2150 retrieve(cmd, file); 2151 } 2152 } 2153 2154 void 2155 send_file_list(char *whichf) 2156 { 2157 struct stat st; 2158 DIR *dirp = NULL; 2159 struct dirent *dir; 2160 FILE *dout = NULL; 2161 char **dirlist, *dirname; 2162 int simple = 0; 2163 int freeglob = 0; 2164 glob_t gl; 2165 char buf[MaxPathLen]; 2166 2167 if (strpbrk(whichf, "~{[*?") != NULL) { 2168 int flags = GLOB_BRACE|GLOB_NOCHECK|GLOB_QUOTE|GLOB_TILDE|GLOB_LIMIT; 2169 2170 memset(&gl, 0, sizeof(gl)); 2171 freeglob = 1; 2172 if (glob(whichf, flags, 0, &gl)) { 2173 reply(550, "not found"); 2174 goto out; 2175 } else if (gl.gl_pathc == 0) { 2176 errno = ENOENT; 2177 perror_reply(550, whichf); 2178 goto out; 2179 } 2180 dirlist = gl.gl_pathv; 2181 } else { 2182 onefile[0] = whichf; 2183 dirlist = onefile; 2184 simple = 1; 2185 } 2186 2187 if (setjmp(urgcatch)) { 2188 transflag = 0; 2189 goto out; 2190 } 2191 while ((dirname = *dirlist++)) { 2192 if (stat(dirname, &st) < 0) { 2193 /* 2194 * If user typed "ls -l", etc, and the client 2195 * used NLST, do what the user meant. 2196 */ 2197 if (dirname[0] == '-' && *dirlist == NULL && 2198 transflag == 0) { 2199 list_file(dirname); 2200 goto out; 2201 } 2202 perror_reply(550, whichf); 2203 if (dout != NULL) { 2204 fclose(dout); 2205 transflag = 0; 2206 data = -1; 2207 pdata = -1; 2208 } 2209 goto out; 2210 } 2211 2212 if (S_ISREG(st.st_mode)) { 2213 if (dout == NULL) { 2214 dout = dataconn("file list", (off_t)-1, "w"); 2215 if (dout == NULL) 2216 goto out; 2217 transflag++; 2218 } 2219 snprintf(buf, sizeof(buf), "%s%s\n", dirname, 2220 type == TYPE_A ? "\r" : ""); 2221 sec_write(fileno(dout), buf, strlen(buf)); 2222 byte_count += strlen(dirname) + 1; 2223 continue; 2224 } else if (!S_ISDIR(st.st_mode)) 2225 continue; 2226 2227 if ((dirp = opendir(dirname)) == NULL) 2228 continue; 2229 2230 while ((dir = readdir(dirp)) != NULL) { 2231 char nbuf[MaxPathLen]; 2232 2233 if (!strcmp(dir->d_name, ".")) 2234 continue; 2235 if (!strcmp(dir->d_name, "..")) 2236 continue; 2237 2238 snprintf(nbuf, sizeof(nbuf), "%s/%s", dirname, dir->d_name); 2239 2240 /* 2241 * We have to do a stat to insure it's 2242 * not a directory or special file. 2243 */ 2244 if (simple || (stat(nbuf, &st) == 0 && 2245 S_ISREG(st.st_mode))) { 2246 if (dout == NULL) { 2247 dout = dataconn("file list", (off_t)-1, "w"); 2248 if (dout == NULL) 2249 goto out; 2250 transflag++; 2251 } 2252 if(strncmp(nbuf, "./", 2) == 0) 2253 snprintf(buf, sizeof(buf), "%s%s\n", nbuf +2, 2254 type == TYPE_A ? "\r" : ""); 2255 else 2256 snprintf(buf, sizeof(buf), "%s%s\n", nbuf, 2257 type == TYPE_A ? "\r" : ""); 2258 sec_write(fileno(dout), buf, strlen(buf)); 2259 byte_count += strlen(nbuf) + 1; 2260 } 2261 } 2262 closedir(dirp); 2263 } 2264 if (dout == NULL) 2265 reply(550, "No files found."); 2266 else if (ferror(dout) != 0) 2267 perror_reply(550, "Data connection"); 2268 else 2269 reply(226, "Transfer complete."); 2270 2271 transflag = 0; 2272 if (dout != NULL){ 2273 sec_write(fileno(dout), buf, 0); /* XXX flush */ 2274 2275 fclose(dout); 2276 } 2277 data = -1; 2278 pdata = -1; 2279 out: 2280 if (freeglob) { 2281 freeglob = 0; 2282 globfree(&gl); 2283 } 2284 } 2285 2286 2287 int 2288 find(char *pattern) 2289 { 2290 char line[1024]; 2291 FILE *f; 2292 2293 snprintf(line, sizeof(line), 2294 "/bin/locate -d %s -- %s", 2295 ftp_rooted("/etc/locatedb"), 2296 pattern); 2297 f = ftpd_popen(line, "r", 1, 1); 2298 if(f == NULL){ 2299 perror_reply(550, "/bin/locate"); 2300 return 1; 2301 } 2302 lreply(200, "Output from find."); 2303 while(fgets(line, sizeof(line), f)){ 2304 if(line[strlen(line)-1] == '\n') 2305 line[strlen(line)-1] = 0; 2306 nreply("%s", line); 2307 } 2308 reply(200, "Done"); 2309 ftpd_pclose(f); 2310 return 0; 2311 } 2312 2313