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