ftpd.c (17433) | ftpd.c (17435) |
---|---|
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 --- 16 unchanged lines hidden (view full) --- 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 * | 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 --- 16 unchanged lines hidden (view full) --- 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 * $Id: ftpd.c,v 1.17 1996/05/31 03:10:25 peter Exp $ | 33 * $Id: ftpd.c,v 1.18 1996/08/04 22:40:35 pst Exp $ |
34 */ 35 36#ifndef lint 37static char copyright[] = 38"@(#) Copyright (c) 1985, 1988, 1990, 1992, 1993, 1994\n\ 39 The Regents of the University of California. All rights reserved.\n"; 40#endif /* not lint */ 41 --- 70 unchanged lines hidden (view full) --- 112jmp_buf errcatch, urgcatch; 113int logged_in; 114struct passwd *pw; 115int debug; 116int timeout = 900; /* timeout after 15 minutes of inactivity */ 117int maxtimeout = 7200;/* don't allow idle time to be set beyond 2 hours */ 118int logging; 119int restricted_data_ports = 1; | 34 */ 35 36#ifndef lint 37static char copyright[] = 38"@(#) Copyright (c) 1985, 1988, 1990, 1992, 1993, 1994\n\ 39 The Regents of the University of California. All rights reserved.\n"; 40#endif /* not lint */ 41 --- 70 unchanged lines hidden (view full) --- 112jmp_buf errcatch, urgcatch; 113int logged_in; 114struct passwd *pw; 115int debug; 116int timeout = 900; /* timeout after 15 minutes of inactivity */ 117int maxtimeout = 7200;/* don't allow idle time to be set beyond 2 hours */ 118int logging; 119int restricted_data_ports = 1; |
120int paranoid = 1; /* be extra careful about security */ |
|
120int guest; | 121int guest; |
121#ifdef STATS | 122int dochroot; |
122int stats; 123int statfd = -1; | 123int stats; 124int statfd = -1; |
124#endif | |
125int type; 126int form; 127int stru; /* avoid C keyword */ 128int mode; 129int usedefault = 1; /* for data transfers */ 130int pdata = -1; /* for passive mode */ 131sig_atomic_t transflag; 132off_t file_size; 133off_t byte_count; 134#if !defined(CMASK) || CMASK == 0 135#undef CMASK 136#define CMASK 027 137#endif 138int defumask = CMASK; /* default umask value */ 139char tmpline[7]; 140char hostname[MAXHOSTNAMELEN]; 141char remotehost[MAXHOSTNAMELEN]; | 125int type; 126int form; 127int stru; /* avoid C keyword */ 128int mode; 129int usedefault = 1; /* for data transfers */ 130int pdata = -1; /* for passive mode */ 131sig_atomic_t transflag; 132off_t file_size; 133off_t byte_count; 134#if !defined(CMASK) || CMASK == 0 135#undef CMASK 136#define CMASK 027 137#endif 138int defumask = CMASK; /* default umask value */ 139char tmpline[7]; 140char hostname[MAXHOSTNAMELEN]; 141char remotehost[MAXHOSTNAMELEN]; |
142#ifdef STATS | |
143char *ident = NULL; | 142char *ident = NULL; |
143 144static char ttyline[20]; 145char *tty = ttyline; /* for klogin */ 146 147#if defined(KERBEROS) 148int notickets = 1; 149char *krbtkfile_env = NULL; |
|
144#endif 145 146/* 147 * Timeout intervals for retrying connections 148 * to hosts that don't accept PORT cmds. This 149 * is a kludge, but given the problems with TCP... 150 */ 151#define SWAITMAX 90 /* wait at most 90 seconds */ --- 31 unchanged lines hidden (view full) --- 183 *(file) == '/' ? "" : curdir(), file); \ 184 else \ 185 syslog(LOG_INFO, "%s %s%s = %qd bytes", \ 186 cmd, (*(file) == '/') ? "" : curdir(), file, cnt); \ 187 } 188 189static void ack __P((char *)); 190static void myoob __P((int)); | 150#endif 151 152/* 153 * Timeout intervals for retrying connections 154 * to hosts that don't accept PORT cmds. This 155 * is a kludge, but given the problems with TCP... 156 */ 157#define SWAITMAX 90 /* wait at most 90 seconds */ --- 31 unchanged lines hidden (view full) --- 189 *(file) == '/' ? "" : curdir(), file); \ 190 else \ 191 syslog(LOG_INFO, "%s %s%s = %qd bytes", \ 192 cmd, (*(file) == '/') ? "" : curdir(), file, cnt); \ 193 } 194 195static void ack __P((char *)); 196static void myoob __P((int)); |
191static int checkuser __P((char *)); | 197static int checkuser __P((char *, char *)); |
192static FILE *dataconn __P((char *, off_t, char *)); 193static void dolog __P((struct sockaddr_in *)); 194static char *curdir __P((void)); 195static void end_login __P((void)); 196static FILE *getdatasock __P((char *)); 197static char *gunique __P((char *)); 198static void lostconn __P((int)); 199static int receive_data __P((FILE *, FILE *)); 200static void send_data __P((FILE *, FILE *, off_t, off_t, int)); 201static struct passwd * 202 sgetpwnam __P((char *)); 203static char *sgetsave __P((char *)); 204static void reapchild __P((int)); | 198static FILE *dataconn __P((char *, off_t, char *)); 199static void dolog __P((struct sockaddr_in *)); 200static char *curdir __P((void)); 201static void end_login __P((void)); 202static FILE *getdatasock __P((char *)); 203static char *gunique __P((char *)); 204static void lostconn __P((int)); 205static int receive_data __P((FILE *, FILE *)); 206static void send_data __P((FILE *, FILE *, off_t, off_t, int)); 207static struct passwd * 208 sgetpwnam __P((char *)); 209static char *sgetsave __P((char *)); 210static void reapchild __P((int)); |
205#ifdef STATS | |
206static void logxfer __P((char *, long, long)); | 211static void logxfer __P((char *, long, long)); |
207#endif | |
208 209static char * 210curdir() 211{ 212 static char path[MAXPATHLEN+1+1]; /* path + '/' + '\0' */ 213 214 if (getcwd(path, sizeof(path)-2) == NULL) 215 return (""); --- 21 unchanged lines hidden (view full) --- 237 */ 238 Argv = argv; 239 while (*envp) 240 envp++; 241 LastArgv = envp[-1] + strlen(envp[-1]); 242#endif /* OLD_SETPROCTITLE */ 243 244 | 212 213static char * 214curdir() 215{ 216 static char path[MAXPATHLEN+1+1]; /* path + '/' + '\0' */ 217 218 if (getcwd(path, sizeof(path)-2) == NULL) 219 return (""); --- 21 unchanged lines hidden (view full) --- 241 */ 242 Argv = argv; 243 while (*envp) 244 envp++; 245 LastArgv = envp[-1] + strlen(envp[-1]); 246#endif /* OLD_SETPROCTITLE */ 247 248 |
245#ifdef STATS 246 while ((ch = getopt(argc, argv, "dlDSt:T:u:v")) != EOF) { 247#else 248 while ((ch = getopt(argc, argv, "dlDUt:T:u:v")) != EOF) { 249#endif | 249 while ((ch = getopt(argc, argv, "dlDSUt:T:u:v")) != EOF) { |
250 switch (ch) { 251 case 'D': 252 daemon_mode++; 253 break; 254 255 case 'd': | 250 switch (ch) { 251 case 'D': 252 daemon_mode++; 253 break; 254 255 case 'd': |
256 debug = 1; | 256 debug++; |
257 break; 258 259 case 'l': 260 logging++; /* > 1 == extra logging */ 261 break; 262 | 257 break; 258 259 case 'l': 260 logging++; /* > 1 == extra logging */ 261 break; 262 |
263 case 'U': 264 restricted_data_ports = 0; | 263 case 'R': 264 paranoid = 0; |
265 break; 266 | 265 break; 266 |
267 case 't': 268 timeout = atoi(optarg); 269 if (maxtimeout < timeout) 270 maxtimeout = timeout; 271 break; 272#ifdef STATS | |
273 case 'S': | 267 case 'S': |
274 stats = 1; | 268 stats++; |
275 break; | 269 break; |
276#endif | 270 |
277 case 'T': 278 maxtimeout = atoi(optarg); 279 if (timeout > maxtimeout) 280 timeout = maxtimeout; 281 break; 282 | 271 case 'T': 272 maxtimeout = atoi(optarg); 273 if (timeout > maxtimeout) 274 timeout = maxtimeout; 275 break; 276 |
277 case 't': 278 timeout = atoi(optarg); 279 if (maxtimeout < timeout) 280 maxtimeout = timeout; 281 break; 282 283 case 'U': 284 restricted_data_ports = 0; 285 break; 286 |
|
283 case 'u': 284 { 285 long val = 0; 286 287 val = strtol(optarg, &optarg, 8); 288 if (*optarg != '\0' || val < 0) 289 warnx("bad value for -u"); 290 else --- 101 unchanged lines hidden (view full) --- 392 } 393#ifdef IP_TOS 394 tos = IPTOS_LOWDELAY; 395 if (setsockopt(0, IPPROTO_IP, IP_TOS, (char *)&tos, sizeof(int)) < 0) 396 syslog(LOG_WARNING, "setsockopt (IP_TOS): %m"); 397#endif 398 data_source.sin_port = htons(ntohs(ctrl_addr.sin_port) - 1); 399 | 287 case 'u': 288 { 289 long val = 0; 290 291 val = strtol(optarg, &optarg, 8); 292 if (*optarg != '\0' || val < 0) 293 warnx("bad value for -u"); 294 else --- 101 unchanged lines hidden (view full) --- 396 } 397#ifdef IP_TOS 398 tos = IPTOS_LOWDELAY; 399 if (setsockopt(0, IPPROTO_IP, IP_TOS, (char *)&tos, sizeof(int)) < 0) 400 syslog(LOG_WARNING, "setsockopt (IP_TOS): %m"); 401#endif 402 data_source.sin_port = htons(ntohs(ctrl_addr.sin_port) - 1); 403 |
404 /* set this here so klogin can use it... */ 405 (void)sprintf(ttyline, "ftp%d", getpid()); 406 |
|
400 /* Try to handle urgent data inline */ 401#ifdef SO_OOBINLINE 402 if (setsockopt(0, SOL_SOCKET, SO_OOBINLINE, (char *)&on, sizeof(on)) < 0) 403 syslog(LOG_ERR, "setsockopt: %m"); 404#endif 405 406#ifdef F_SETOWN 407 if (fcntl(fileno(stdin), F_SETOWN, getpid()) == -1) --- 45 unchanged lines hidden (view full) --- 453 int signo; 454{ 455 456 if (debug) 457 syslog(LOG_DEBUG, "lost connection"); 458 dologout(-1); 459} 460 | 407 /* Try to handle urgent data inline */ 408#ifdef SO_OOBINLINE 409 if (setsockopt(0, SOL_SOCKET, SO_OOBINLINE, (char *)&on, sizeof(on)) < 0) 410 syslog(LOG_ERR, "setsockopt: %m"); 411#endif 412 413#ifdef F_SETOWN 414 if (fcntl(fileno(stdin), F_SETOWN, getpid()) == -1) --- 45 unchanged lines hidden (view full) --- 460 int signo; 461{ 462 463 if (debug) 464 syslog(LOG_DEBUG, "lost connection"); 465 dologout(-1); 466} 467 |
461static char ttyline[20]; 462 | |
463/* 464 * Helper function for sgetpwnam(). 465 */ 466static char * 467sgetsave(s) 468 char *s; 469{ 470 char *new = malloc((unsigned) strlen(s) + 1); --- 57 unchanged lines hidden (view full) --- 528 char *name; 529{ 530 char *cp, *shell; 531 532 if (logged_in) { 533 if (guest) { 534 reply(530, "Can't change user from guest login."); 535 return; | 468/* 469 * Helper function for sgetpwnam(). 470 */ 471static char * 472sgetsave(s) 473 char *s; 474{ 475 char *new = malloc((unsigned) strlen(s) + 1); --- 57 unchanged lines hidden (view full) --- 533 char *name; 534{ 535 char *cp, *shell; 536 537 if (logged_in) { 538 if (guest) { 539 reply(530, "Can't change user from guest login."); 540 return; |
541 } else if (dochroot) { 542 reply(530, "Can't change user from chroot user."); 543 return; |
|
536 } 537 end_login(); 538 } 539 540 guest = 0; 541 if (strcmp(name, "ftp") == 0 || strcmp(name, "anonymous") == 0) { | 544 } 545 end_login(); 546 } 547 548 guest = 0; 549 if (strcmp(name, "ftp") == 0 || strcmp(name, "anonymous") == 0) { |
542 if (checkuser("ftp") || checkuser("anonymous")) | 550 if (checkuser(_PATH_FTPUSERS, "ftp") || 551 checkuser(_PATH_FTPUSERS, "anonymous")) |
543 reply(530, "User %s access denied.", name); 544 else if ((pw = sgetpwnam("ftp")) != NULL) { 545 guest = 1; 546 askpasswd = 1; 547 reply(331, 548 "Guest login ok, send your email address as password."); 549 } else 550 reply(530, "User %s unknown.", name); --- 5 unchanged lines hidden (view full) --- 556 if (pw = sgetpwnam(name)) { 557 if ((shell = pw->pw_shell) == NULL || *shell == 0) 558 shell = _PATH_BSHELL; 559 while ((cp = getusershell()) != NULL) 560 if (strcmp(cp, shell) == 0) 561 break; 562 endusershell(); 563 | 552 reply(530, "User %s access denied.", name); 553 else if ((pw = sgetpwnam("ftp")) != NULL) { 554 guest = 1; 555 askpasswd = 1; 556 reply(331, 557 "Guest login ok, send your email address as password."); 558 } else 559 reply(530, "User %s unknown.", name); --- 5 unchanged lines hidden (view full) --- 565 if (pw = sgetpwnam(name)) { 566 if ((shell = pw->pw_shell) == NULL || *shell == 0) 567 shell = _PATH_BSHELL; 568 while ((cp = getusershell()) != NULL) 569 if (strcmp(cp, shell) == 0) 570 break; 571 endusershell(); 572 |
564 if (cp == NULL || checkuser(name)) { | 573 if (cp == NULL || checkuser(_PATH_FTPUSERS, name)) { |
565 reply(530, "User %s access denied.", name); 566 if (logging) 567 syslog(LOG_NOTICE, 568 "FTP LOGIN REFUSED FROM %s, %s", 569 remotehost, name); 570 pw = (struct passwd *) NULL; 571 return; 572 } --- 11 unchanged lines hidden (view full) --- 584 * Delay before reading passwd after first failed 585 * attempt to slow down passwd-guessing programs. 586 */ 587 if (login_attempts) 588 sleep((unsigned) login_attempts); 589} 590 591/* | 574 reply(530, "User %s access denied.", name); 575 if (logging) 576 syslog(LOG_NOTICE, 577 "FTP LOGIN REFUSED FROM %s, %s", 578 remotehost, name); 579 pw = (struct passwd *) NULL; 580 return; 581 } --- 11 unchanged lines hidden (view full) --- 593 * Delay before reading passwd after first failed 594 * attempt to slow down passwd-guessing programs. 595 */ 596 if (login_attempts) 597 sleep((unsigned) login_attempts); 598} 599 600/* |
592 * Check if a user is in the file _PATH_FTPUSERS | 601 * Check if a user is in the file "fname" |
593 */ 594static int | 602 */ 603static int |
595checkuser(name) | 604checkuser(fname, name) 605 char *fname; |
596 char *name; 597{ 598 FILE *fd; 599 int found = 0; 600 char *p, line[BUFSIZ]; 601 | 606 char *name; 607{ 608 FILE *fd; 609 int found = 0; 610 char *p, line[BUFSIZ]; 611 |
602 if ((fd = fopen(_PATH_FTPUSERS, "r")) != NULL) { | 612 if ((fd = fopen(fname, "r")) != NULL) { |
603 while (fgets(line, sizeof(line), fd) != NULL) 604 if ((p = strchr(line, '\n')) != NULL) { 605 *p = '\0'; 606 if (line[0] == '#') 607 continue; 608 if (strcmp(line, name) == 0) { 609 found = 1; 610 break; --- 13 unchanged lines hidden (view full) --- 624{ 625 626 (void) seteuid((uid_t)0); 627 if (logged_in) 628 logwtmp(ttyline, "", ""); 629 pw = NULL; 630 logged_in = 0; 631 guest = 0; | 613 while (fgets(line, sizeof(line), fd) != NULL) 614 if ((p = strchr(line, '\n')) != NULL) { 615 *p = '\0'; 616 if (line[0] == '#') 617 continue; 618 if (strcmp(line, name) == 0) { 619 found = 1; 620 break; --- 13 unchanged lines hidden (view full) --- 634{ 635 636 (void) seteuid((uid_t)0); 637 if (logged_in) 638 logwtmp(ttyline, "", ""); 639 pw = NULL; 640 logged_in = 0; 641 guest = 0; |
642 dochroot = 0; |
|
632} 633 634void 635pass(passwd) 636 char *passwd; 637{ | 643} 644 645void 646pass(passwd) 647 char *passwd; 648{ |
638 char *salt, *xpasswd; | 649 int rval; |
639 FILE *fd; 640 static char homedir[MAXPATHLEN]; 641 642 if (logged_in || askpasswd == 0) { 643 reply(503, "Login with USER first."); 644 return; 645 } 646 askpasswd = 0; 647 if (!guest) { /* "ftp" is only account allowed no password */ | 650 FILE *fd; 651 static char homedir[MAXPATHLEN]; 652 653 if (logged_in || askpasswd == 0) { 654 reply(503, "Login with USER first."); 655 return; 656 } 657 askpasswd = 0; 658 if (!guest) { /* "ftp" is only account allowed no password */ |
648 if (pw == NULL) 649 salt = "xx"; 650 else 651 salt = pw->pw_passwd; | 659 if (pw == NULL) { 660 rval = 1; /* failure below */ 661 goto skip; 662 } 663#if defined(KERBEROS) 664 rval = klogin(pw, "", hostname, passwd); 665 if (rval == 0) 666 goto skip; 667#endif |
652#ifdef SKEY | 668#ifdef SKEY |
653 xpasswd = skey_crypt(passwd, salt, pw, pwok); | 669 rval = strcmp(skey_crypt(passwd, pw->pw_passwd, pw, pwok), 670 passwd); |
654 pwok = 0; 655#else | 671 pwok = 0; 672#else |
656 xpasswd = crypt(passwd, salt); | 673 rval = strcmp(crypt(passwd, pw->passwd), passwd); |
657#endif 658 /* The strcmp does not catch null passwords! */ | 674#endif 675 /* The strcmp does not catch null passwords! */ |
659 if (pw == NULL || *pw->pw_passwd == '\0' || 660 (pw->pw_expire && time(NULL) >= pw->pw_expire) || 661 strcmp(xpasswd, pw->pw_passwd)) { | 676 if (*pw->pw_passwd == '\0' || 677 (pw->pw_expire && time(NULL) >= pw->pw_expire)) 678 rval = 1; /* failure */ 679skip: 680 /* 681 * If rval == 1, the user failed the authentication check 682 * above. If rval == 0, either Kerberos or local authentication 683 * succeeded. 684 */ 685 if (rval) { |
662 reply(530, "Login incorrect."); 663 if (logging) 664 syslog(LOG_NOTICE, 665 "FTP LOGIN FAILED FROM %s, %s", 666 remotehost, curname); 667 pw = NULL; 668 if (login_attempts++ >= 5) { 669 syslog(LOG_NOTICE, --- 7 unchanged lines hidden (view full) --- 677 login_attempts = 0; /* this time successful */ 678 if (setegid((gid_t)pw->pw_gid) < 0) { 679 reply(550, "Can't set gid."); 680 return; 681 } 682 (void) initgroups(pw->pw_name, pw->pw_gid); 683 684 /* open wtmp before chroot */ | 686 reply(530, "Login incorrect."); 687 if (logging) 688 syslog(LOG_NOTICE, 689 "FTP LOGIN FAILED FROM %s, %s", 690 remotehost, curname); 691 pw = NULL; 692 if (login_attempts++ >= 5) { 693 syslog(LOG_NOTICE, --- 7 unchanged lines hidden (view full) --- 701 login_attempts = 0; /* this time successful */ 702 if (setegid((gid_t)pw->pw_gid) < 0) { 703 reply(550, "Can't set gid."); 704 return; 705 } 706 (void) initgroups(pw->pw_name, pw->pw_gid); 707 708 /* open wtmp before chroot */ |
685 (void)sprintf(ttyline, "ftp%d", getpid()); | |
686 logwtmp(ttyline, pw->pw_name, remotehost); 687 logged_in = 1; 688 | 709 logwtmp(ttyline, pw->pw_name, remotehost); 710 logged_in = 1; 711 |
689#ifdef STATS 690 if (guest && stats == 1 && statfd < 0) | 712 if (guest && stats && statfd < 0) |
691 if ((statfd = open(_PATH_FTPDSTATFILE, O_WRONLY|O_APPEND)) < 0) 692 stats = 0; | 713 if ((statfd = open(_PATH_FTPDSTATFILE, O_WRONLY|O_APPEND)) < 0) 714 stats = 0; |
693#endif | |
694 | 715 |
716 dochroot = checkuser(_PATH_FTPCHROOT, pw->pw_name); |
|
695 if (guest) { 696 /* 697 * We MUST do a chdir() after the chroot. Otherwise 698 * the old current directory will be accessible as "." 699 * outside the new root! 700 */ 701 if (chroot(pw->pw_dir) < 0 || chdir("/") < 0) { 702 reply(550, "Can't set guest privileges."); 703 goto bad; 704 } | 717 if (guest) { 718 /* 719 * We MUST do a chdir() after the chroot. Otherwise 720 * the old current directory will be accessible as "." 721 * outside the new root! 722 */ 723 if (chroot(pw->pw_dir) < 0 || chdir("/") < 0) { 724 reply(550, "Can't set guest privileges."); 725 goto bad; 726 } |
727 } else if (dochroot) { 728 if (chroot(pw->pw_dir) < 0 || chdir("/") < 0) { 729 reply(550, "Can't change root."); 730 goto bad; 731 } |
|
705 } else if (chdir(pw->pw_dir) < 0) { 706 if (chdir("/") < 0) { 707 reply(530, "User %s: can't change directory to %s.", 708 pw->pw_name, pw->pw_dir); 709 goto bad; 710 } else 711 lreply(230, "No directory! Logging in with home=/"); 712 } --- 19 unchanged lines hidden (view full) --- 732 if ((cp = strchr(line, '\n')) != NULL) 733 *cp = '\0'; 734 lreply(230, "%s", line); 735 } 736 (void) fflush(stdout); 737 (void) fclose(fd); 738 } 739 if (guest) { | 732 } else if (chdir(pw->pw_dir) < 0) { 733 if (chdir("/") < 0) { 734 reply(530, "User %s: can't change directory to %s.", 735 pw->pw_name, pw->pw_dir); 736 goto bad; 737 } else 738 lreply(230, "No directory! Logging in with home=/"); 739 } --- 19 unchanged lines hidden (view full) --- 759 if ((cp = strchr(line, '\n')) != NULL) 760 *cp = '\0'; 761 lreply(230, "%s", line); 762 } 763 (void) fflush(stdout); 764 (void) fclose(fd); 765 } 766 if (guest) { |
740#ifdef STATS 741 char * copy(); 742 | |
743 if (ident != NULL) 744 free(ident); 745 ident = strdup(passwd); 746 if (ident == NULL) 747 fatal("Ran out of memory."); 748 | 767 if (ident != NULL) 768 free(ident); 769 ident = strdup(passwd); 770 if (ident == NULL) 771 fatal("Ran out of memory."); 772 |
749#endif | |
750 reply(230, "Guest login ok, access restrictions apply."); 751#ifdef SETPROCTITLE 752 snprintf(proctitle, sizeof(proctitle), 753 "%s: anonymous/%.*s", remotehost, 754 sizeof(proctitle) - sizeof(remotehost) - 755 sizeof(": anonymous/"), passwd); 756 setproctitle("%s", proctitle); 757#endif /* SETPROCTITLE */ --- 20 unchanged lines hidden (view full) --- 778 779void 780retrieve(cmd, name) 781 char *cmd, *name; 782{ 783 FILE *fin, *dout; 784 struct stat st; 785 int (*closefunc) __P((FILE *)); | 773 reply(230, "Guest login ok, access restrictions apply."); 774#ifdef SETPROCTITLE 775 snprintf(proctitle, sizeof(proctitle), 776 "%s: anonymous/%.*s", remotehost, 777 sizeof(proctitle) - sizeof(remotehost) - 778 sizeof(": anonymous/"), passwd); 779 setproctitle("%s", proctitle); 780#endif /* SETPROCTITLE */ --- 20 unchanged lines hidden (view full) --- 801 802void 803retrieve(cmd, name) 804 char *cmd, *name; 805{ 806 FILE *fin, *dout; 807 struct stat st; 808 int (*closefunc) __P((FILE *)); |
786#ifdef STATS | |
787 long start; | 809 long start; |
788#endif | |
789 790 if (cmd == 0) { 791 fin = fopen(name, "r"), closefunc = fclose; 792 st.st_size = 0; 793 } else { 794 char line[BUFSIZ]; 795 796 (void) sprintf(line, cmd, name), name = line; --- 33 unchanged lines hidden (view full) --- 830 } else if (lseek(fileno(fin), restart_point, L_SET) < 0) { 831 perror_reply(550, name); 832 goto done; 833 } 834 } 835 dout = dataconn(name, st.st_size, "w"); 836 if (dout == NULL) 837 goto done; | 810 811 if (cmd == 0) { 812 fin = fopen(name, "r"), closefunc = fclose; 813 st.st_size = 0; 814 } else { 815 char line[BUFSIZ]; 816 817 (void) sprintf(line, cmd, name), name = line; --- 33 unchanged lines hidden (view full) --- 851 } else if (lseek(fileno(fin), restart_point, L_SET) < 0) { 852 perror_reply(550, name); 853 goto done; 854 } 855 } 856 dout = dataconn(name, st.st_size, "w"); 857 if (dout == NULL) 858 goto done; |
838#ifdef STATS | |
839 time(&start); | 859 time(&start); |
840#endif | |
841 send_data(fin, dout, st.st_blksize, st.st_size, 842 restart_point == 0 && cmd == 0 && S_ISREG(st.st_mode)); | 860 send_data(fin, dout, st.st_blksize, st.st_size, 861 restart_point == 0 && cmd == 0 && S_ISREG(st.st_mode)); |
843#ifdef STATS | |
844 if (cmd == 0 && guest && stats) 845 logxfer(name, st.st_size, start); | 862 if (cmd == 0 && guest && stats) 863 logxfer(name, st.st_size, start); |
846#endif | |
847 (void) fclose(dout); 848 data = -1; 849 pdata = -1; 850done: 851 if (cmd == 0) 852 LOGBYTES("get", name, byte_count); 853 (*closefunc)(fin); 854} --- 81 unchanged lines hidden (view full) --- 936 (void) seteuid((uid_t)0); 937 s = socket(AF_INET, SOCK_STREAM, 0); 938 if (s < 0) 939 goto bad; 940 if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, 941 (char *) &on, sizeof(on)) < 0) 942 goto bad; 943 /* anchor socket to avoid multi-homing problems */ | 864 (void) fclose(dout); 865 data = -1; 866 pdata = -1; 867done: 868 if (cmd == 0) 869 LOGBYTES("get", name, byte_count); 870 (*closefunc)(fin); 871} --- 81 unchanged lines hidden (view full) --- 953 (void) seteuid((uid_t)0); 954 s = socket(AF_INET, SOCK_STREAM, 0); 955 if (s < 0) 956 goto bad; 957 if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, 958 (char *) &on, sizeof(on)) < 0) 959 goto bad; 960 /* anchor socket to avoid multi-homing problems */ |
961 data_source.sin_len = sizeof(struct sockaddr_in); |
|
944 data_source.sin_family = AF_INET; 945 data_source.sin_addr = ctrl_addr.sin_addr; 946 for (tries = 1; ; tries++) { 947 if (bind(s, (struct sockaddr *)&data_source, 948 sizeof(data_source)) >= 0) 949 break; 950 if (errno != EADDRINUSE || tries > 10) 951 goto bad; --- 65 unchanged lines hidden (view full) --- 1017 reply(425, "Can't open data connection."); 1018 (void) close(pdata); 1019 pdata = -1; 1020 return (NULL); 1021 } 1022 (void) close(pdata); 1023 pdata = s; 1024#ifdef IP_TOS | 962 data_source.sin_family = AF_INET; 963 data_source.sin_addr = ctrl_addr.sin_addr; 964 for (tries = 1; ; tries++) { 965 if (bind(s, (struct sockaddr *)&data_source, 966 sizeof(data_source)) >= 0) 967 break; 968 if (errno != EADDRINUSE || tries > 10) 969 goto bad; --- 65 unchanged lines hidden (view full) --- 1035 reply(425, "Can't open data connection."); 1036 (void) close(pdata); 1037 pdata = -1; 1038 return (NULL); 1039 } 1040 (void) close(pdata); 1041 pdata = s; 1042#ifdef IP_TOS |
1025 tos = IPTOS_LOWDELAY; | 1043 tos = IPTOS_THROUGHPUT; |
1026 (void) setsockopt(s, IPPROTO_IP, IP_TOS, (char *)&tos, 1027 sizeof(int)); 1028#endif 1029 reply(150, "Opening %s mode data connection for '%s'%s.", 1030 type == TYPE_A ? "ASCII" : "BINARY", name, sizebuf); 1031 return (fdopen(pdata, mode)); 1032 } 1033 if (data >= 0) { --- 539 unchanged lines hidden (view full) --- 1573void 1574dologout(status) 1575 int status; 1576{ 1577 1578 if (logged_in) { 1579 (void) seteuid((uid_t)0); 1580 logwtmp(ttyline, "", ""); | 1044 (void) setsockopt(s, IPPROTO_IP, IP_TOS, (char *)&tos, 1045 sizeof(int)); 1046#endif 1047 reply(150, "Opening %s mode data connection for '%s'%s.", 1048 type == TYPE_A ? "ASCII" : "BINARY", name, sizebuf); 1049 return (fdopen(pdata, mode)); 1050 } 1051 if (data >= 0) { --- 539 unchanged lines hidden (view full) --- 1591void 1592dologout(status) 1593 int status; 1594{ 1595 1596 if (logged_in) { 1597 (void) seteuid((uid_t)0); 1598 logwtmp(ttyline, "", ""); |
1599#if defined(KERBEROS) 1600 if (!notickets && krbtkfile_env) 1601 unlink(krbtkfile_env); 1602#endif |
|
1581 } 1582 /* beware of flushing buffers after a SIGPIPE */ 1583 _exit(status); 1584} 1585 1586static void 1587myoob(signo) 1588 int signo; --- 312 unchanged lines hidden (view full) --- 1901 while (ch = *bp++) 1902 if (ch != '\n' && ch != '\r') 1903 *p++ = ch; 1904 while (p < LastArgv) 1905 *p++ = ' '; 1906} 1907#endif /* OLD_SETPROCTITLE */ 1908 | 1603 } 1604 /* beware of flushing buffers after a SIGPIPE */ 1605 _exit(status); 1606} 1607 1608static void 1609myoob(signo) 1610 int signo; --- 312 unchanged lines hidden (view full) --- 1923 while (ch = *bp++) 1924 if (ch != '\n' && ch != '\r') 1925 *p++ = ch; 1926 while (p < LastArgv) 1927 *p++ = ' '; 1928} 1929#endif /* OLD_SETPROCTITLE */ 1930 |
1909#ifdef STATS | |
1910static void 1911logxfer(name, size, start) 1912 char *name; 1913 long size; 1914 long start; 1915{ 1916 char buf[1024]; 1917 char path[MAXPATHLEN + 1]; 1918 long now; 1919 1920 if (statfd >= 0 && getwd(path) != NULL) { 1921 time(&now); 1922 snprintf(buf, sizeof(buf), "%.20s!%s!%s!%s/%s!%ld!%ld\n", 1923 ctime(&now)+4, ident, remotehost, 1924 path, name, size, now - start + (now == start)); 1925 write(statfd, buf, strlen(buf)); 1926 } 1927} | 1931static void 1932logxfer(name, size, start) 1933 char *name; 1934 long size; 1935 long start; 1936{ 1937 char buf[1024]; 1938 char path[MAXPATHLEN + 1]; 1939 long now; 1940 1941 if (statfd >= 0 && getwd(path) != NULL) { 1942 time(&now); 1943 snprintf(buf, sizeof(buf), "%.20s!%s!%s!%s/%s!%ld!%ld\n", 1944 ctime(&now)+4, ident, remotehost, 1945 path, name, size, now - start + (now == start)); 1946 write(statfd, buf, strlen(buf)); 1947 } 1948} |
1928#endif | |