Deleted Added
full compact
ftpd.c (51433) ftpd.c (56668)
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

--- 30 unchanged lines hidden (view full) ---

39#endif /* not lint */
40#endif
41
42#ifndef lint
43#if 0
44static char sccsid[] = "@(#)ftpd.c 8.4 (Berkeley) 4/16/94";
45#endif
46static const char rcsid[] =
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

--- 30 unchanged lines hidden (view full) ---

39#endif /* not lint */
40#endif
41
42#ifndef lint
43#if 0
44static char sccsid[] = "@(#)ftpd.c 8.4 (Berkeley) 4/16/94";
45#endif
46static const char rcsid[] =
47 "$FreeBSD: head/libexec/ftpd/ftpd.c 51433 1999-09-19 22:05:32Z markm $";
47 "$FreeBSD: head/libexec/ftpd/ftpd.c 56668 2000-01-27 09:28:38Z shin $";
48#endif /* not lint */
49
50/*
51 * FTP server.
52 */
53#include <sys/param.h>
54#include <sys/stat.h>
55#include <sys/ioctl.h>

--- 49 unchanged lines hidden (view full) ---

105#include <stdarg.h>
106#else
107#include <varargs.h>
108#endif
109
110static char version[] = "Version 6.00LS";
111#undef main
112
48#endif /* not lint */
49
50/*
51 * FTP server.
52 */
53#include <sys/param.h>
54#include <sys/stat.h>
55#include <sys/ioctl.h>

--- 49 unchanged lines hidden (view full) ---

105#include <stdarg.h>
106#else
107#include <varargs.h>
108#endif
109
110static char version[] = "Version 6.00LS";
111#undef main
112
113/* wrapper for KAME-special getnameinfo() */
114#ifndef NI_WITHSCOPEID
115#define NI_WITHSCOPEID 0
116#endif
117
113extern off_t restart_point;
114extern char cbuf[];
115
118extern off_t restart_point;
119extern char cbuf[];
120
116struct sockaddr_in server_addr;
117struct sockaddr_in ctrl_addr;
118struct sockaddr_in data_source;
119struct sockaddr_in data_dest;
120struct sockaddr_in his_addr;
121struct sockaddr_in pasv_addr;
121union sockunion server_addr;
122union sockunion ctrl_addr;
123union sockunion data_source;
124union sockunion data_dest;
125union sockunion his_addr;
126union sockunion pasv_addr;
122
123int daemon_mode;
124int data;
125jmp_buf errcatch, urgcatch;
126int logged_in;
127struct passwd *pw;
128int debug;
129int timeout = 900; /* timeout after 15 minutes of inactivity */

--- 20 unchanged lines hidden (view full) ---

150#define CMASK 027
151#endif
152int defumask = CMASK; /* default umask value */
153char tmpline[7];
154char *hostname;
155#ifdef VIRTUAL_HOSTING
156char *ftpuser;
157
127
128int daemon_mode;
129int data;
130jmp_buf errcatch, urgcatch;
131int logged_in;
132struct passwd *pw;
133int debug;
134int timeout = 900; /* timeout after 15 minutes of inactivity */

--- 20 unchanged lines hidden (view full) ---

155#define CMASK 027
156#endif
157int defumask = CMASK; /* default umask value */
158char tmpline[7];
159char *hostname;
160#ifdef VIRTUAL_HOSTING
161char *ftpuser;
162
163int epsvall = 0;
164
158static struct ftphost {
159 struct ftphost *next;
165static struct ftphost {
166 struct ftphost *next;
160 struct in_addr hostaddr;
167 union sockunion hostaddr;
161 char *hostname;
162 char *anonuser;
163 char *statfile;
164 char *welcome;
165 char *loginmsg;
166} *thishost, *firsthost;
167
168#endif
169char remotehost[MAXHOSTNAMELEN];
170char *ident = NULL;
171
172static char ttyline[20];
173char *tty = ttyline; /* for klogin */
174
175#if !defined(NOPAM)
176static int auth_pam __P((struct passwd**, const char*));
177#endif
178
168 char *hostname;
169 char *anonuser;
170 char *statfile;
171 char *welcome;
172 char *loginmsg;
173} *thishost, *firsthost;
174
175#endif
176char remotehost[MAXHOSTNAMELEN];
177char *ident = NULL;
178
179static char ttyline[20];
180char *tty = ttyline; /* for klogin */
181
182#if !defined(NOPAM)
183static int auth_pam __P((struct passwd**, const char*));
184#endif
185
179struct in_addr bind_address;
180char *pid_file = NULL;
181
182/*
183 * Timeout intervals for retrying connections
184 * to hosts that don't accept PORT cmds. This
185 * is a kludge, but given the problems with TCP...
186 */
187#define SWAITMAX 90 /* wait at most 90 seconds */

--- 7 unchanged lines hidden (view full) ---

195char **Argv = NULL; /* pointer to argument vector */
196char *LastArgv = NULL; /* end of argv */
197#endif /* OLD_SETPROCTITLE */
198char proctitle[LINE_MAX]; /* initial part of title */
199#endif /* SETPROCTITLE */
200
201#ifdef SKEY
202int pwok = 0;
186char *pid_file = NULL;
187
188/*
189 * Timeout intervals for retrying connections
190 * to hosts that don't accept PORT cmds. This
191 * is a kludge, but given the problems with TCP...
192 */
193#define SWAITMAX 90 /* wait at most 90 seconds */

--- 7 unchanged lines hidden (view full) ---

201char **Argv = NULL; /* pointer to argument vector */
202char *LastArgv = NULL; /* end of argv */
203#endif /* OLD_SETPROCTITLE */
204char proctitle[LINE_MAX]; /* initial part of title */
205#endif /* SETPROCTITLE */
206
207#ifdef SKEY
208int pwok = 0;
203char addr_string[20]; /* XXX */
209char addr_string[INET6_ADDRSTRLEN]; /* XXX */
204#endif
205
206#define LOGCMD(cmd, file) \
207 if (logging > 1) \
208 syslog(LOG_INFO,"%s %s%s", cmd, \
209 *(file) == '/' ? "" : curdir(), file);
210#define LOGCMD2(cmd, file1, file2) \
211 if (logging > 1) \

--- 7 unchanged lines hidden (view full) ---

219 *(file) == '/' ? "" : curdir(), file); \
220 else \
221 syslog(LOG_INFO, "%s %s%s = %qd bytes", \
222 cmd, (*(file) == '/') ? "" : curdir(), file, cnt); \
223 }
224
225#ifdef VIRTUAL_HOSTING
226static void inithosts __P((void));
210#endif
211
212#define LOGCMD(cmd, file) \
213 if (logging > 1) \
214 syslog(LOG_INFO,"%s %s%s", cmd, \
215 *(file) == '/' ? "" : curdir(), file);
216#define LOGCMD2(cmd, file1, file2) \
217 if (logging > 1) \

--- 7 unchanged lines hidden (view full) ---

225 *(file) == '/' ? "" : curdir(), file); \
226 else \
227 syslog(LOG_INFO, "%s %s%s = %qd bytes", \
228 cmd, (*(file) == '/') ? "" : curdir(), file, cnt); \
229 }
230
231#ifdef VIRTUAL_HOSTING
232static void inithosts __P((void));
227static void selecthost __P((struct in_addr *));
233static void selecthost __P((union sockunion *));
228#endif
229static void ack __P((char *));
230static void myoob __P((int));
231static int checkuser __P((char *, char *, int));
232static FILE *dataconn __P((char *, off_t, char *));
234#endif
235static void ack __P((char *));
236static void myoob __P((int));
237static int checkuser __P((char *, char *, int));
238static FILE *dataconn __P((char *, off_t, char *));
233static void dolog __P((struct sockaddr_in *));
239static void dolog __P((struct sockaddr *));
234static char *curdir __P((void));
235static void end_login __P((void));
236static FILE *getdatasock __P((char *));
237static char *gunique __P((char *));
238static void lostconn __P((int));
239static int receive_data __P((FILE *, FILE *));
240static void send_data __P((FILE *, FILE *, off_t, off_t, int));
241static struct passwd *

--- 19 unchanged lines hidden (view full) ---

261main(argc, argv, envp)
262 int argc;
263 char *argv[];
264 char **envp;
265{
266 int addrlen, ch, on = 1, tos;
267 char *cp, line[LINE_MAX];
268 FILE *fd;
240static char *curdir __P((void));
241static void end_login __P((void));
242static FILE *getdatasock __P((char *));
243static char *gunique __P((char *));
244static void lostconn __P((int));
245static int receive_data __P((FILE *, FILE *));
246static void send_data __P((FILE *, FILE *, off_t, off_t, int));
247static struct passwd *

--- 19 unchanged lines hidden (view full) ---

267main(argc, argv, envp)
268 int argc;
269 char *argv[];
270 char **envp;
271{
272 int addrlen, ch, on = 1, tos;
273 char *cp, line[LINE_MAX];
274 FILE *fd;
275 int error;
276 char *bindname = NULL;
277 int family = AF_UNSPEC;
278 int enable_v4 = 0;
269
270 tzset(); /* in case no timezone database in ~ftp */
271
272#ifdef OLD_SETPROCTITLE
273 /*
274 * Save start and extent of argv for setproctitle.
275 */
276 Argv = argv;
277 while (*envp)
278 envp++;
279 LastArgv = envp[-1] + strlen(envp[-1]);
280#endif /* OLD_SETPROCTITLE */
281
282
279
280 tzset(); /* in case no timezone database in ~ftp */
281
282#ifdef OLD_SETPROCTITLE
283 /*
284 * Save start and extent of argv for setproctitle.
285 */
286 Argv = argv;
287 while (*envp)
288 envp++;
289 LastArgv = envp[-1] + strlen(envp[-1]);
290#endif /* OLD_SETPROCTITLE */
291
292
283 bind_address.s_addr = htonl(INADDR_ANY);
284 while ((ch = getopt(argc, argv, "AdlDSURt:T:u:va:p:")) != -1) {
293 while ((ch = getopt(argc, argv, "AdlDSURt:T:u:va:p:46")) != -1) {
285 switch (ch) {
286 case 'D':
287 daemon_mode++;
288 break;
289
290 case 'd':
291 debug++;
292 break;

--- 22 unchanged lines hidden (view full) ---

315 maxtimeout = timeout;
316 break;
317
318 case 'U':
319 restricted_data_ports = 0;
320 break;
321
322 case 'a':
294 switch (ch) {
295 case 'D':
296 daemon_mode++;
297 break;
298
299 case 'd':
300 debug++;
301 break;

--- 22 unchanged lines hidden (view full) ---

324 maxtimeout = timeout;
325 break;
326
327 case 'U':
328 restricted_data_ports = 0;
329 break;
330
331 case 'a':
323 if (!inet_aton(optarg, &bind_address))
324 errx(1, "invalid address for -a");
332 bindname = optarg;
325 break;
326
327 case 'p':
328 pid_file = optarg;
329 break;
330
331 case 'u':
332 {

--- 9 unchanged lines hidden (view full) ---

342 case 'A':
343 anon_only = 1;
344 break;
345
346 case 'v':
347 debug = 1;
348 break;
349
333 break;
334
335 case 'p':
336 pid_file = optarg;
337 break;
338
339 case 'u':
340 {

--- 9 unchanged lines hidden (view full) ---

350 case 'A':
351 anon_only = 1;
352 break;
353
354 case 'v':
355 debug = 1;
356 break;
357
358 case '4':
359 enable_v4 = 1;
360 if (family == AF_UNSPEC)
361 family = AF_INET;
362 break;
363
364 case '6':
365 family = AF_INET6;
366 break;
367
350 default:
351 warnx("unknown flag -%c ignored", optopt);
352 break;
353 }
354 }
355
356#ifdef VIRTUAL_HOSTING
357 inithosts();
358#endif
359 (void) freopen(_PATH_DEVNULL, "w", stderr);
360
361 /*
362 * LOG_NDELAY sets up the logging connection immediately,
363 * necessary for anonymous ftp's that chroot and can't do it later.
364 */
365 openlog("ftpd", LOG_PID | LOG_NDELAY, LOG_FTP);
366
367 if (daemon_mode) {
368 int ctl_sock, fd;
368 default:
369 warnx("unknown flag -%c ignored", optopt);
370 break;
371 }
372 }
373
374#ifdef VIRTUAL_HOSTING
375 inithosts();
376#endif
377 (void) freopen(_PATH_DEVNULL, "w", stderr);
378
379 /*
380 * LOG_NDELAY sets up the logging connection immediately,
381 * necessary for anonymous ftp's that chroot and can't do it later.
382 */
383 openlog("ftpd", LOG_PID | LOG_NDELAY, LOG_FTP);
384
385 if (daemon_mode) {
386 int ctl_sock, fd;
369 struct servent *sv;
387 struct addrinfo hints, *res;
370
371 /*
372 * Detach from parent.
373 */
374 if (daemon(1, 1) < 0) {
375 syslog(LOG_ERR, "failed to become a daemon");
376 exit(1);
377 }
378 (void) signal(SIGCHLD, reapchild);
388
389 /*
390 * Detach from parent.
391 */
392 if (daemon(1, 1) < 0) {
393 syslog(LOG_ERR, "failed to become a daemon");
394 exit(1);
395 }
396 (void) signal(SIGCHLD, reapchild);
379 /*
380 * Get port number for ftp/tcp.
381 */
382 sv = getservbyname("ftp", "tcp");
383 if (sv == NULL) {
384 syslog(LOG_ERR, "getservbyname for ftp failed");
397 /* init bind_sa */
398 memset(&hints, 0, sizeof(hints));
399
400 hints.ai_family = family == AF_UNSPEC ? AF_INET : family;
401 hints.ai_socktype = SOCK_STREAM;
402 hints.ai_protocol = 0;
403 hints.ai_flags = AI_PASSIVE;
404 error = getaddrinfo(bindname, "ftp", &hints, &res);
405 if (error) {
406 if (family == AF_UNSPEC) {
407 hints.ai_family = AF_UNSPEC;
408 error = getaddrinfo(bindname, "ftp", &hints,
409 &res);
410 }
411 if (error == 0 && res->ai_addr != NULL)
412 family = res->ai_addr->sa_family;
413 }
414 if (error) {
415 syslog(LOG_ERR, gai_strerror(error));
416 if (error == EAI_SYSTEM)
417 syslog(LOG_ERR, strerror(errno));
385 exit(1);
386 }
418 exit(1);
419 }
420 if (res->ai_addr == NULL) {
421 syslog(LOG_ERR, "-a %s: getaddrinfo failed", hostname);
422 exit(1);
423 }
387 /*
388 * Open a socket, bind it to the FTP port, and start
389 * listening.
390 */
424 /*
425 * Open a socket, bind it to the FTP port, and start
426 * listening.
427 */
391 ctl_sock = socket(AF_INET, SOCK_STREAM, 0);
428 ctl_sock = socket(family, SOCK_STREAM, 0);
392 if (ctl_sock < 0) {
393 syslog(LOG_ERR, "control socket: %m");
394 exit(1);
395 }
396 if (setsockopt(ctl_sock, SOL_SOCKET, SO_REUSEADDR,
397 (char *)&on, sizeof(on)) < 0)
429 if (ctl_sock < 0) {
430 syslog(LOG_ERR, "control socket: %m");
431 exit(1);
432 }
433 if (setsockopt(ctl_sock, SOL_SOCKET, SO_REUSEADDR,
434 (char *)&on, sizeof(on)) < 0)
398 syslog(LOG_ERR, "control setsockopt: %m");;
399 server_addr.sin_family = AF_INET;
400 server_addr.sin_addr = bind_address;
401 server_addr.sin_port = sv->s_port;
402 if (bind(ctl_sock, (struct sockaddr *)&server_addr, sizeof(server_addr))) {
435 syslog(LOG_ERR, "control setsockopt: %m");
436#ifdef IPV6_BINDV6ONLY
437 if (family == AF_INET6 && enable_v4 == 0) {
438 if (setsockopt(ctl_sock, IPPROTO_IPV6, IPV6_BINDV6ONLY,
439 (char *)&on, sizeof (on)) < 0)
440 syslog(LOG_ERR,
441 "control setsockopt(IPV6_BINDV6ONLY): %m");
442 }
443#endif /* IPV6_BINDV6ONLY */
444 memcpy(&server_addr, res->ai_addr, res->ai_addr->sa_len);
445 if (bind(ctl_sock, (struct sockaddr *)&server_addr,
446 server_addr.su_len) < 0) {
403 syslog(LOG_ERR, "control bind: %m");
404 exit(1);
405 }
406 if (listen(ctl_sock, 32) < 0) {
407 syslog(LOG_ERR, "control listen: %m");
408 exit(1);
409 }
410 /*

--- 18 unchanged lines hidden (view full) ---

429 err(1, "%s: write", pid_file);
430 /* Leave the pid file open and locked */
431 }
432 /*
433 * Loop forever accepting connection requests and forking off
434 * children to handle them.
435 */
436 while (1) {
447 syslog(LOG_ERR, "control bind: %m");
448 exit(1);
449 }
450 if (listen(ctl_sock, 32) < 0) {
451 syslog(LOG_ERR, "control listen: %m");
452 exit(1);
453 }
454 /*

--- 18 unchanged lines hidden (view full) ---

473 err(1, "%s: write", pid_file);
474 /* Leave the pid file open and locked */
475 }
476 /*
477 * Loop forever accepting connection requests and forking off
478 * children to handle them.
479 */
480 while (1) {
437 addrlen = sizeof(his_addr);
481 addrlen = server_addr.su_len;
438 fd = accept(ctl_sock, (struct sockaddr *)&his_addr, &addrlen);
439 if (fork() == 0) {
440 /* child */
441 (void) dup2(fd, 0);
442 (void) dup2(fd, 1);
443 close(ctl_sock);
444 break;
445 }

--- 8 unchanged lines hidden (view full) ---

454 }
455
456 (void) signal(SIGCHLD, SIG_IGN);
457 (void) signal(SIGPIPE, lostconn);
458 if (signal(SIGURG, myoob) == SIG_ERR)
459 syslog(LOG_ERR, "signal: %m");
460
461#ifdef SKEY
482 fd = accept(ctl_sock, (struct sockaddr *)&his_addr, &addrlen);
483 if (fork() == 0) {
484 /* child */
485 (void) dup2(fd, 0);
486 (void) dup2(fd, 1);
487 close(ctl_sock);
488 break;
489 }

--- 8 unchanged lines hidden (view full) ---

498 }
499
500 (void) signal(SIGCHLD, SIG_IGN);
501 (void) signal(SIGPIPE, lostconn);
502 if (signal(SIGURG, myoob) == SIG_ERR)
503 syslog(LOG_ERR, "signal: %m");
504
505#ifdef SKEY
462 strncpy(addr_string, inet_ntoa(his_addr.sin_addr), sizeof(addr_string));
506 getnameinfo((struct sockaddr *)&his_addr, his_addr.su_len,
507 addr_string, sizeof(addr_string) - 1, NULL, 0,
508 NI_NUMERICHOST|NI_WITHSCOPEID);
463#endif
464 addrlen = sizeof(ctrl_addr);
465 if (getsockname(0, (struct sockaddr *)&ctrl_addr, &addrlen) < 0) {
466 syslog(LOG_ERR, "getsockname (%s): %m",argv[0]);
467 exit(1);
468 }
469#ifdef VIRTUAL_HOSTING
470 /* select our identity from virtual host table */
509#endif
510 addrlen = sizeof(ctrl_addr);
511 if (getsockname(0, (struct sockaddr *)&ctrl_addr, &addrlen) < 0) {
512 syslog(LOG_ERR, "getsockname (%s): %m",argv[0]);
513 exit(1);
514 }
515#ifdef VIRTUAL_HOSTING
516 /* select our identity from virtual host table */
471 selecthost(&ctrl_addr.sin_addr);
517 selecthost(&ctrl_addr);
472#endif
473#ifdef IP_TOS
518#endif
519#ifdef IP_TOS
520 if (ctrl_addr.su_family == AF_INET)
521 {
474 tos = IPTOS_LOWDELAY;
475 if (setsockopt(0, IPPROTO_IP, IP_TOS, (char *)&tos, sizeof(int)) < 0)
476 syslog(LOG_WARNING, "setsockopt (IP_TOS): %m");
522 tos = IPTOS_LOWDELAY;
523 if (setsockopt(0, IPPROTO_IP, IP_TOS, (char *)&tos, sizeof(int)) < 0)
524 syslog(LOG_WARNING, "setsockopt (IP_TOS): %m");
525 }
477#endif
478 /*
479 * Disable Nagle on the control channel so that we don't have to wait
480 * for peer's ACK before issuing our next reply.
481 */
482 if (setsockopt(0, IPPROTO_TCP, TCP_NODELAY, &on, sizeof(on)) < 0)
483 syslog(LOG_WARNING, "control setsockopt TCP_NODELAY: %m");
484
526#endif
527 /*
528 * Disable Nagle on the control channel so that we don't have to wait
529 * for peer's ACK before issuing our next reply.
530 */
531 if (setsockopt(0, IPPROTO_TCP, TCP_NODELAY, &on, sizeof(on)) < 0)
532 syslog(LOG_WARNING, "control setsockopt TCP_NODELAY: %m");
533
485 data_source.sin_port = htons(ntohs(ctrl_addr.sin_port) - 1);
534 data_source.su_port = htons(ntohs(ctrl_addr.su_port) - 1);
486
487 /* set this here so klogin can use it... */
488 (void)snprintf(ttyline, sizeof(ttyline), "ftp%d", getpid());
489
490 /* Try to handle urgent data inline */
491#ifdef SO_OOBINLINE
492 if (setsockopt(0, SOL_SOCKET, SO_OOBINLINE, (char *)&on, sizeof(on)) < 0)
493 syslog(LOG_ERR, "setsockopt: %m");
494#endif
495
496#ifdef F_SETOWN
497 if (fcntl(fileno(stdin), F_SETOWN, getpid()) == -1)
498 syslog(LOG_ERR, "fcntl F_SETOWN: %m");
499#endif
535
536 /* set this here so klogin can use it... */
537 (void)snprintf(ttyline, sizeof(ttyline), "ftp%d", getpid());
538
539 /* Try to handle urgent data inline */
540#ifdef SO_OOBINLINE
541 if (setsockopt(0, SOL_SOCKET, SO_OOBINLINE, (char *)&on, sizeof(on)) < 0)
542 syslog(LOG_ERR, "setsockopt: %m");
543#endif
544
545#ifdef F_SETOWN
546 if (fcntl(fileno(stdin), F_SETOWN, getpid()) == -1)
547 syslog(LOG_ERR, "fcntl F_SETOWN: %m");
548#endif
500 dolog(&his_addr);
549 dolog((struct sockaddr *)&his_addr);
501 /*
502 * Set up default state
503 */
504 data = -1;
505 type = TYPE_A;
506 form = FORM_N;
507 stru = STRU_F;
508 mode = MODE_S;

--- 53 unchanged lines hidden (view full) ---

562 * read in virtual host tables (if they exist)
563 */
564
565static void
566inithosts()
567{
568 FILE *fp;
569 char *cp;
550 /*
551 * Set up default state
552 */
553 data = -1;
554 type = TYPE_A;
555 form = FORM_N;
556 stru = STRU_F;
557 mode = MODE_S;

--- 53 unchanged lines hidden (view full) ---

611 * read in virtual host tables (if they exist)
612 */
613
614static void
615inithosts()
616{
617 FILE *fp;
618 char *cp;
570 struct hostent *hp;
571 struct ftphost *hrp, *lhrp;
572 char line[1024];
619 struct ftphost *hrp, *lhrp;
620 char line[1024];
621 struct addrinfo hints, *res, *ai;
573
574 /*
575 * Fill in the default host information
576 */
577 if (gethostname(line, sizeof(line)) < 0)
578 line[0] = '\0';
579 if ((hrp = malloc(sizeof(struct ftphost))) == NULL ||
580 (hrp->hostname = strdup(line)) == NULL)
581 fatal("Ran out of memory.");
622
623 /*
624 * Fill in the default host information
625 */
626 if (gethostname(line, sizeof(line)) < 0)
627 line[0] = '\0';
628 if ((hrp = malloc(sizeof(struct ftphost))) == NULL ||
629 (hrp->hostname = strdup(line)) == NULL)
630 fatal("Ran out of memory.");
582 memset(&hrp->hostaddr, 0, sizeof hrp->hostaddr);
583 if ((hp = gethostbyname(hrp->hostname)) != NULL)
584 (void) memcpy(&hrp->hostaddr,
585 hp->h_addr_list[0],
586 sizeof(hrp->hostaddr));
631 memset(&hrp->hostaddr, 0, sizeof(hrp->hostaddr));
632
633 memset(&hints, 0, sizeof(hints));
634 hints.ai_flags = AI_CANONNAME;
635 hints.ai_family = AF_UNSPEC;
636 getaddrinfo(hrp->hostname, NULL, &hints, &res);
637 if (res)
638 memcpy(&hrp->hostaddr, res->ai_addr, res->ai_addrlen);
587 hrp->statfile = _PATH_FTPDSTATFILE;
588 hrp->welcome = _PATH_FTPWELCOME;
589 hrp->loginmsg = _PATH_FTPLOGINMESG;
590 hrp->anonuser = "ftp";
591 hrp->next = NULL;
592 thishost = firsthost = lhrp = hrp;
639 hrp->statfile = _PATH_FTPDSTATFILE;
640 hrp->welcome = _PATH_FTPWELCOME;
641 hrp->loginmsg = _PATH_FTPLOGINMESG;
642 hrp->anonuser = "ftp";
643 hrp->next = NULL;
644 thishost = firsthost = lhrp = hrp;
645 freeaddrinfo(res);
593 if ((fp = fopen(_PATH_FTPHOSTS, "r")) != NULL) {
646 if ((fp = fopen(_PATH_FTPHOSTS, "r")) != NULL) {
647 int addrsize, error;
648 void *addr;
649 struct hostent *hp;
650
594 while (fgets(line, sizeof(line), fp) != NULL) {
651 while (fgets(line, sizeof(line), fp) != NULL) {
595 int i;
652 int i, hp_error;
596
597 if ((cp = strchr(line, '\n')) == NULL) {
598 /* ignore long lines */
599 while (fgets(line, sizeof(line), fp) != NULL &&
600 strchr(line, '\n') == NULL)
601 ;
602 continue;
603 }
604 *cp = '\0';
605 cp = strtok(line, " \t");
606 /* skip comments and empty lines */
607 if (cp == NULL || line[0] == '#')
608 continue;
653
654 if ((cp = strchr(line, '\n')) == NULL) {
655 /* ignore long lines */
656 while (fgets(line, sizeof(line), fp) != NULL &&
657 strchr(line, '\n') == NULL)
658 ;
659 continue;
660 }
661 *cp = '\0';
662 cp = strtok(line, " \t");
663 /* skip comments and empty lines */
664 if (cp == NULL || line[0] == '#')
665 continue;
609 /* first, try a standard gethostbyname() */
610 if ((hp = gethostbyname(cp)) == NULL)
666
667 hints.ai_flags = 0;
668 hints.ai_family = AF_UNSPEC;
669 hints.ai_flags = AI_PASSIVE;
670 error = getaddrinfo(cp, NULL, &hints, &res);
671 if (error != NULL)
611 continue;
672 continue;
673 for (ai = res; ai != NULL && ai->ai_addr != NULL;
674 ai = ai->ai_next)
675 {
676
612 for (hrp = firsthost; hrp != NULL; hrp = hrp->next) {
613 if (memcmp(&hrp->hostaddr,
677 for (hrp = firsthost; hrp != NULL; hrp = hrp->next) {
678 if (memcmp(&hrp->hostaddr,
614 hp->h_addr_list[0],
615 sizeof(hrp->hostaddr)) == 0)
679 ai->ai_addr,
680 ai->ai_addr->sa_len) == 0)
616 break;
617 }
618 if (hrp == NULL) {
619 if ((hrp = malloc(sizeof(struct ftphost))) == NULL)
620 continue;
621 /* defaults */
622 hrp->statfile = _PATH_FTPDSTATFILE;
623 hrp->welcome = _PATH_FTPWELCOME;
624 hrp->loginmsg = _PATH_FTPLOGINMESG;
625 hrp->anonuser = "ftp";
626 hrp->next = NULL;
627 lhrp->next = hrp;
628 lhrp = hrp;
629 }
630 (void) memcpy(&hrp->hostaddr,
681 break;
682 }
683 if (hrp == NULL) {
684 if ((hrp = malloc(sizeof(struct ftphost))) == NULL)
685 continue;
686 /* defaults */
687 hrp->statfile = _PATH_FTPDSTATFILE;
688 hrp->welcome = _PATH_FTPWELCOME;
689 hrp->loginmsg = _PATH_FTPLOGINMESG;
690 hrp->anonuser = "ftp";
691 hrp->next = NULL;
692 lhrp->next = hrp;
693 lhrp = hrp;
694 }
695 (void) memcpy(&hrp->hostaddr,
631 hp->h_addr_list[0],
632 sizeof(hrp->hostaddr));
696 ai->ai_addr,
697 ai->ai_addr->sa_len);
633 /*
634 * determine hostname to use.
698 /*
699 * determine hostname to use.
635 * force defined name if it is a valid alias
700 * force defined name if there is a valid alias
636 * otherwise fallback to primary hostname
637 */
701 * otherwise fallback to primary hostname
702 */
638 if ((hp = gethostbyaddr((char*)&hrp->hostaddr,
639 sizeof(hrp->hostaddr),
640 AF_INET)) != NULL) {
703 /* XXX: getaddrinfo() can't do alias check */
704 switch(hrp->hostaddr.su_family) {
705 case AF_INET:
706 addr = &((struct sockaddr_in *)&hrp->hostaddr)->sin_addr;
707 addrsize = sizeof(struct sockaddr_in);
708 break;
709 case AF_INET6:
710 addr = &((struct sockaddr_in6 *)&hrp->hostaddr)->sin6_addr;
711 addrsize = sizeof(struct sockaddr_in6);
712 break;
713 default:
714 /* should not reach here */
715 free(hrp);
716 continue;
717 /* NOTREACHED */
718 }
719 if ((hp = getipnodebyaddr((char*)addr, addrsize,
720 hrp->hostaddr.su_family,
721 &hp_error)) != NULL) {
641 if (strcmp(cp, hp->h_name) != 0) {
642 if (hp->h_aliases == NULL)
643 cp = hp->h_name;
644 else {
645 i = 0;
646 while (hp->h_aliases[i] &&
647 strcmp(cp, hp->h_aliases[i]) != 0)
648 ++i;
649 if (hp->h_aliases[i] == NULL)
650 cp = hp->h_name;
651 }
652 }
653 }
654 hrp->hostname = strdup(cp);
722 if (strcmp(cp, hp->h_name) != 0) {
723 if (hp->h_aliases == NULL)
724 cp = hp->h_name;
725 else {
726 i = 0;
727 while (hp->h_aliases[i] &&
728 strcmp(cp, hp->h_aliases[i]) != 0)
729 ++i;
730 if (hp->h_aliases[i] == NULL)
731 cp = hp->h_name;
732 }
733 }
734 }
735 hrp->hostname = strdup(cp);
736 freehostent(hp);
655 /* ok, now we now peel off the rest */
656 i = 0;
657 while (i < 4 && (cp = strtok(NULL, " \t")) != NULL) {
658 if (*cp != '-' && (cp = strdup(cp)) != NULL) {
659 switch (i) {
660 case 0: /* anon user permissions */
661 hrp->anonuser = cp;
662 break;

--- 5 unchanged lines hidden (view full) ---

668 break;
669 case 3: /* login message */
670 hrp->loginmsg = cp;
671 break;
672 }
673 }
674 ++i;
675 }
737 /* ok, now we now peel off the rest */
738 i = 0;
739 while (i < 4 && (cp = strtok(NULL, " \t")) != NULL) {
740 if (*cp != '-' && (cp = strdup(cp)) != NULL) {
741 switch (i) {
742 case 0: /* anon user permissions */
743 hrp->anonuser = cp;
744 break;

--- 5 unchanged lines hidden (view full) ---

750 break;
751 case 3: /* login message */
752 hrp->loginmsg = cp;
753 break;
754 }
755 }
756 ++i;
757 }
758 /* XXX: re-initialization for getaddrinfo() loop */
759 cp = strtok(line, " \t");
760 }
676 }
677 (void) fclose(fp);
678 }
679}
680
681static void
761 }
762 (void) fclose(fp);
763 }
764}
765
766static void
682selecthost(a)
683 struct in_addr *a;
767selecthost(su)
768 union sockunion *su;
684{
685 struct ftphost *hrp;
769{
770 struct ftphost *hrp;
771 u_int16_t port;
772#ifdef INET6
773 struct in6_addr *mapped_in6 = NULL;
774#endif
686
775
776#ifdef INET6
777 /*
778 * XXX IPv4 mapped IPv6 addr consideraton,
779 * specified in rfc2373.
780 */
781 if (su->su_family == AF_INET6 &&
782 IN6_IS_ADDR_V4MAPPED(&su->su_sin6.sin6_addr))
783 mapped_in6 = &su->su_sin6.sin6_addr;
784#endif
785
687 hrp = thishost = firsthost; /* default */
786 hrp = thishost = firsthost; /* default */
787 port = su->su_port;
788 su->su_port = 0;
688 while (hrp != NULL) {
789 while (hrp != NULL) {
689 if (memcmp(a, &hrp->hostaddr, sizeof(hrp->hostaddr)) == 0) {
790 if (memcmp(su, &hrp->hostaddr, sizeof(hrp->hostaddr)) == 0) {
690 thishost = hrp;
691 break;
692 }
791 thishost = hrp;
792 break;
793 }
794#ifdef INET6
795 /* XXX IPv4 mapped IPv6 addr consideraton */
796 if (hrp->hostaddr.su_family == AF_INET && mapped_in6 != NULL &&
797 (memcmp(&mapped_in6->s6_addr[12],
798 &hrp->hostaddr.su_sin.sin_addr,
799 sizeof(struct in_addr)) == 0)) {
800 thishost = hrp;
801 break;
802 }
803#endif
693 hrp = hrp->next;
694 }
804 hrp = hrp->next;
805 }
806 su->su_port = port;
695 /* setup static variables as appropriate */
696 hostname = thishost->hostname;
697 ftpuser = thishost->anonuser;
698}
699#endif
700
701/*
702 * Helper function for sgetpwnam().

--- 399 unchanged lines hidden (view full) ---

1102 return;
1103 }
1104 /* May be overridden by login.conf */
1105 (void) umask(defumask);
1106#ifdef LOGIN_CAP
1107 if ((lc = login_getpwclass(pw)) != NULL) {
1108 char remote_ip[MAXHOSTNAMELEN];
1109
807 /* setup static variables as appropriate */
808 hostname = thishost->hostname;
809 ftpuser = thishost->anonuser;
810}
811#endif
812
813/*
814 * Helper function for sgetpwnam().

--- 399 unchanged lines hidden (view full) ---

1214 return;
1215 }
1216 /* May be overridden by login.conf */
1217 (void) umask(defumask);
1218#ifdef LOGIN_CAP
1219 if ((lc = login_getpwclass(pw)) != NULL) {
1220 char remote_ip[MAXHOSTNAMELEN];
1221
1110 strncpy(remote_ip, inet_ntoa(his_addr.sin_addr),
1111 sizeof(remote_ip) - 1);
1222 getnameinfo((struct sockaddr *)&his_addr, his_addr.su_len,
1223 remote_ip, sizeof(remote_ip) - 1, NULL, 0,
1224 NI_NUMERICHOST|NI_WITHSCOPEID);
1112 remote_ip[sizeof(remote_ip) - 1] = 0;
1113 if (!auth_hostok(lc, remotehost, remote_ip)) {
1114 syslog(LOG_INFO|LOG_AUTH,
1115 "FTP LOGIN FAILED (HOST) as %s: permission denied.",
1116 pw->pw_name);
1117 reply(530, "Permission denied.\n");
1118 pw = NULL;
1119 return;

--- 277 unchanged lines hidden (view full) ---

1397getdatasock(mode)
1398 char *mode;
1399{
1400 int on = 1, s, t, tries;
1401
1402 if (data >= 0)
1403 return (fdopen(data, mode));
1404 (void) seteuid((uid_t)0);
1225 remote_ip[sizeof(remote_ip) - 1] = 0;
1226 if (!auth_hostok(lc, remotehost, remote_ip)) {
1227 syslog(LOG_INFO|LOG_AUTH,
1228 "FTP LOGIN FAILED (HOST) as %s: permission denied.",
1229 pw->pw_name);
1230 reply(530, "Permission denied.\n");
1231 pw = NULL;
1232 return;

--- 277 unchanged lines hidden (view full) ---

1510getdatasock(mode)
1511 char *mode;
1512{
1513 int on = 1, s, t, tries;
1514
1515 if (data >= 0)
1516 return (fdopen(data, mode));
1517 (void) seteuid((uid_t)0);
1405 s = socket(AF_INET, SOCK_STREAM, 0);
1518
1519 s = socket(data_dest.su_family, SOCK_STREAM, 0);
1406 if (s < 0)
1407 goto bad;
1408 if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR,
1409 (char *) &on, sizeof(on)) < 0)
1410 goto bad;
1411 /* anchor socket to avoid multi-homing problems */
1520 if (s < 0)
1521 goto bad;
1522 if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR,
1523 (char *) &on, sizeof(on)) < 0)
1524 goto bad;
1525 /* anchor socket to avoid multi-homing problems */
1412 data_source.sin_len = sizeof(struct sockaddr_in);
1413 data_source.sin_family = AF_INET;
1414 data_source.sin_addr = ctrl_addr.sin_addr;
1526 data_source = ctrl_addr;
1527 data_source.su_port = htons(20); /* ftp-data port */
1415 for (tries = 1; ; tries++) {
1416 if (bind(s, (struct sockaddr *)&data_source,
1528 for (tries = 1; ; tries++) {
1529 if (bind(s, (struct sockaddr *)&data_source,
1417 sizeof(data_source)) >= 0)
1530 data_source.su_len) >= 0)
1418 break;
1419 if (errno != EADDRINUSE || tries > 10)
1420 goto bad;
1421 sleep(tries);
1422 }
1423 (void) seteuid((uid_t)pw->pw_uid);
1424#ifdef IP_TOS
1531 break;
1532 if (errno != EADDRINUSE || tries > 10)
1533 goto bad;
1534 sleep(tries);
1535 }
1536 (void) seteuid((uid_t)pw->pw_uid);
1537#ifdef IP_TOS
1538 if (data_source.su_family == AF_INET)
1539 {
1425 on = IPTOS_THROUGHPUT;
1426 if (setsockopt(s, IPPROTO_IP, IP_TOS, (char *)&on, sizeof(int)) < 0)
1427 syslog(LOG_WARNING, "setsockopt (IP_TOS): %m");
1540 on = IPTOS_THROUGHPUT;
1541 if (setsockopt(s, IPPROTO_IP, IP_TOS, (char *)&on, sizeof(int)) < 0)
1542 syslog(LOG_WARNING, "setsockopt (IP_TOS): %m");
1543 }
1428#endif
1429#ifdef TCP_NOPUSH
1430 /*
1431 * Turn off push flag to keep sender TCP from sending short packets
1432 * at the boundaries of each write(). Should probably do a SO_SNDBUF
1433 * to set the send buffer size as well, but that may not be desirable
1434 * in heavy-load situations.
1435 */

--- 29 unchanged lines hidden (view full) ---

1465
1466 file_size = size;
1467 byte_count = 0;
1468 if (size != (off_t) -1)
1469 (void) snprintf(sizebuf, sizeof(sizebuf), " (%qd bytes)", size);
1470 else
1471 *sizebuf = '\0';
1472 if (pdata >= 0) {
1544#endif
1545#ifdef TCP_NOPUSH
1546 /*
1547 * Turn off push flag to keep sender TCP from sending short packets
1548 * at the boundaries of each write(). Should probably do a SO_SNDBUF
1549 * to set the send buffer size as well, but that may not be desirable
1550 * in heavy-load situations.
1551 */

--- 29 unchanged lines hidden (view full) ---

1581
1582 file_size = size;
1583 byte_count = 0;
1584 if (size != (off_t) -1)
1585 (void) snprintf(sizebuf, sizeof(sizebuf), " (%qd bytes)", size);
1586 else
1587 *sizebuf = '\0';
1588 if (pdata >= 0) {
1473 struct sockaddr_in from;
1474 int s, fromlen = sizeof(from);
1589 union sockunion from;
1590 int s, fromlen = ctrl_addr.su_len;
1475 struct timeval timeout;
1476 fd_set set;
1477
1478 FD_ZERO(&set);
1479 FD_SET(pdata, &set);
1480
1481 timeout.tv_usec = 0;
1482 timeout.tv_sec = 120;
1483
1484 if (select(pdata+1, &set, (fd_set *) 0, (fd_set *) 0, &timeout) == 0 ||
1485 (s = accept(pdata, (struct sockaddr *) &from, &fromlen)) < 0) {
1486 reply(425, "Can't open data connection.");
1487 (void) close(pdata);
1488 pdata = -1;
1489 return (NULL);
1490 }
1491 (void) close(pdata);
1492 pdata = s;
1493#ifdef IP_TOS
1591 struct timeval timeout;
1592 fd_set set;
1593
1594 FD_ZERO(&set);
1595 FD_SET(pdata, &set);
1596
1597 timeout.tv_usec = 0;
1598 timeout.tv_sec = 120;
1599
1600 if (select(pdata+1, &set, (fd_set *) 0, (fd_set *) 0, &timeout) == 0 ||
1601 (s = accept(pdata, (struct sockaddr *) &from, &fromlen)) < 0) {
1602 reply(425, "Can't open data connection.");
1603 (void) close(pdata);
1604 pdata = -1;
1605 return (NULL);
1606 }
1607 (void) close(pdata);
1608 pdata = s;
1609#ifdef IP_TOS
1610 if (from.su_family == AF_INET)
1611 {
1494 tos = IPTOS_THROUGHPUT;
1495 (void) setsockopt(s, IPPROTO_IP, IP_TOS, (char *)&tos,
1496 sizeof(int));
1612 tos = IPTOS_THROUGHPUT;
1613 (void) setsockopt(s, IPPROTO_IP, IP_TOS, (char *)&tos,
1614 sizeof(int));
1615 }
1497#endif
1498 reply(150, "Opening %s mode data connection for '%s'%s.",
1499 type == TYPE_A ? "ASCII" : "BINARY", name, sizebuf);
1500 return (fdopen(pdata, mode));
1501 }
1502 if (data >= 0) {
1503 reply(125, "Using existing data connection for '%s'%s.",
1504 name, sizebuf);
1505 usedefault = 1;
1506 return (fdopen(data, mode));
1507 }
1508 if (usedefault)
1509 data_dest = his_addr;
1510 usedefault = 1;
1511 file = getdatasock(mode);
1512 if (file == NULL) {
1616#endif
1617 reply(150, "Opening %s mode data connection for '%s'%s.",
1618 type == TYPE_A ? "ASCII" : "BINARY", name, sizebuf);
1619 return (fdopen(pdata, mode));
1620 }
1621 if (data >= 0) {
1622 reply(125, "Using existing data connection for '%s'%s.",
1623 name, sizebuf);
1624 usedefault = 1;
1625 return (fdopen(data, mode));
1626 }
1627 if (usedefault)
1628 data_dest = his_addr;
1629 usedefault = 1;
1630 file = getdatasock(mode);
1631 if (file == NULL) {
1513 reply(425, "Can't create data socket (%s,%d): %s.",
1514 inet_ntoa(data_source.sin_addr),
1515 ntohs(data_source.sin_port), strerror(errno));
1632 char hostbuf[BUFSIZ], portbuf[BUFSIZ];
1633 getnameinfo((struct sockaddr *)&data_source,
1634 data_source.su_len, hostbuf, sizeof(hostbuf) - 1,
1635 portbuf, sizeof(portbuf),
1636 NI_NUMERICHOST|NI_NUMERICSERV|NI_WITHSCOPEID);
1637 reply(425, "Can't create data socket (%s,%s): %s.",
1638 hostbuf, portbuf, strerror(errno));
1516 return (NULL);
1517 }
1518 data = fileno(file);
1519 while (connect(data, (struct sockaddr *)&data_dest,
1639 return (NULL);
1640 }
1641 data = fileno(file);
1642 while (connect(data, (struct sockaddr *)&data_dest,
1520 sizeof(data_dest)) < 0) {
1643 data_dest.su_len) < 0) {
1521 if (errno == EADDRINUSE && retry < swaitmax) {
1522 sleep((unsigned) swaitint);
1523 retry += swaitint;
1524 continue;
1525 }
1526 perror_reply(425, "Can't build data connection");
1527 (void) fclose(file);
1528 data = -1;

--- 234 unchanged lines hidden (view full) ---

1763 }
1764 (void) ftpd_pclose(fin);
1765 reply(211, "End of Status");
1766}
1767
1768void
1769statcmd()
1770{
1644 if (errno == EADDRINUSE && retry < swaitmax) {
1645 sleep((unsigned) swaitint);
1646 retry += swaitint;
1647 continue;
1648 }
1649 perror_reply(425, "Can't build data connection");
1650 (void) fclose(file);
1651 data = -1;

--- 234 unchanged lines hidden (view full) ---

1886 }
1887 (void) ftpd_pclose(fin);
1888 reply(211, "End of Status");
1889}
1890
1891void
1892statcmd()
1893{
1771 struct sockaddr_in *sin;
1894 union sockunion *su;
1772 u_char *a, *p;
1895 u_char *a, *p;
1896 char hname[INET6_ADDRSTRLEN];
1897 int ispassive;
1773
1774 lreply(211, "%s FTP server status:", hostname, version);
1775 printf(" %s\r\n", version);
1776 printf(" Connected to %s", remotehost);
1898
1899 lreply(211, "%s FTP server status:", hostname, version);
1900 printf(" %s\r\n", version);
1901 printf(" Connected to %s", remotehost);
1777 if (!isdigit(remotehost[0]))
1778 printf(" (%s)", inet_ntoa(his_addr.sin_addr));
1902 if (!getnameinfo((struct sockaddr *)&his_addr, his_addr.su_len,
1903 hname, sizeof(hname) - 1, NULL, 0,
1904 NI_NUMERICHOST|NI_WITHSCOPEID)) {
1905 if (strcmp(hname, remotehost) != 0)
1906 printf(" (%s)", hname);
1907 }
1779 printf("\r\n");
1780 if (logged_in) {
1781 if (guest)
1782 printf(" Logged in anonymously\r\n");
1783 else
1784 printf(" Logged in as %s\r\n", pw->pw_name);
1785 } else if (askpasswd)
1786 printf(" Waiting for password\r\n");

--- 8 unchanged lines hidden (view full) ---

1795#else
1796 printf(" %d", bytesize); /* need definition! */
1797#endif
1798 printf("; STRUcture: %s; transfer MODE: %s\r\n",
1799 strunames[stru], modenames[mode]);
1800 if (data != -1)
1801 printf(" Data connection open\r\n");
1802 else if (pdata != -1) {
1908 printf("\r\n");
1909 if (logged_in) {
1910 if (guest)
1911 printf(" Logged in anonymously\r\n");
1912 else
1913 printf(" Logged in as %s\r\n", pw->pw_name);
1914 } else if (askpasswd)
1915 printf(" Waiting for password\r\n");

--- 8 unchanged lines hidden (view full) ---

1924#else
1925 printf(" %d", bytesize); /* need definition! */
1926#endif
1927 printf("; STRUcture: %s; transfer MODE: %s\r\n",
1928 strunames[stru], modenames[mode]);
1929 if (data != -1)
1930 printf(" Data connection open\r\n");
1931 else if (pdata != -1) {
1803 printf(" in Passive mode");
1804 sin = &pasv_addr;
1932 ispassive = 1;
1933 su = &pasv_addr;
1805 goto printaddr;
1806 } else if (usedefault == 0) {
1934 goto printaddr;
1935 } else if (usedefault == 0) {
1807 printf(" PORT");
1808 sin = &data_dest;
1936 ispassive = 0;
1937 su = &data_dest;
1809printaddr:
1938printaddr:
1810 a = (u_char *) &sin->sin_addr;
1811 p = (u_char *) &sin->sin_port;
1812#define UC(b) (((int) b) & 0xff)
1939#define UC(b) (((int) b) & 0xff)
1813 printf(" (%d,%d,%d,%d,%d,%d)\r\n", UC(a[0]),
1814 UC(a[1]), UC(a[2]), UC(a[3]), UC(p[0]), UC(p[1]));
1940 if (epsvall) {
1941 printf(" EPSV only mode (EPSV ALL)\r\n");
1942 goto epsvonly;
1943 }
1944
1945 /* PORT/PASV */
1946 if (su->su_family == AF_INET) {
1947 a = (u_char *) &su->su_sin.sin_addr;
1948 p = (u_char *) &su->su_sin.sin_port;
1949 printf(" %s (%d,%d,%d,%d,%d,%d)\r\n",
1950 ispassive ? "PASV" : "PORT",
1951 UC(a[0]), UC(a[1]), UC(a[2]), UC(a[3]),
1952 UC(p[0]), UC(p[1]));
1953 }
1954
1955 /* LPRT/LPSV */
1956 {
1957 int alen, af, i;
1958
1959 switch (su->su_family) {
1960 case AF_INET:
1961 a = (u_char *) &su->su_sin.sin_addr;
1962 p = (u_char *) &su->su_sin.sin_port;
1963 alen = sizeof(su->su_sin.sin_addr);
1964 af = 4;
1965 break;
1966 case AF_INET6:
1967 a = (u_char *) &su->su_sin6.sin6_addr;
1968 p = (u_char *) &su->su_sin6.sin6_port;
1969 alen = sizeof(su->su_sin6.sin6_addr);
1970 af = 6;
1971 break;
1972 default:
1973 af = 0;
1974 break;
1975 }
1976 if (af) {
1977 printf(" %s (%d,%d,", ispassive ? "LPSV" : "LPRT",
1978 af, alen);
1979 for (i = 0; i < alen; i++)
1980 printf("%d,", UC(a[i]));
1981 printf("%d,%d,%d)\r\n", 2, UC(p[0]), UC(p[1]));
1982 }
1983 }
1984
1985epsvonly:;
1986 /* EPRT/EPSV */
1987 {
1988 int af;
1989
1990 switch (su->su_family) {
1991 case AF_INET:
1992 af = 1;
1993 break;
1994 case AF_INET6:
1995 af = 2;
1996 break;
1997 default:
1998 af = 0;
1999 break;
2000 }
2001 if (af) {
2002 if (!getnameinfo((struct sockaddr *)su, su->su_len,
2003 hname, sizeof(hname) - 1, NULL, 0,
2004 NI_NUMERICHOST)) {
2005 printf(" %s |%d|%s|%d|\r\n",
2006 ispassive ? "EPSV" : "EPRT",
2007 af, hname, htons(su->su_port));
2008 }
2009 }
2010 }
1815#undef UC
1816 } else
1817 printf(" No data connection\r\n");
1818 reply(211, "End of status");
1819}
1820
1821void
1822fatal(s)

--- 187 unchanged lines hidden (view full) ---

2010
2011 if (rename(from, to) < 0)
2012 perror_reply(550, "rename");
2013 else
2014 ack("RNTO");
2015}
2016
2017static void
2011#undef UC
2012 } else
2013 printf(" No data connection\r\n");
2014 reply(211, "End of status");
2015}
2016
2017void
2018fatal(s)

--- 187 unchanged lines hidden (view full) ---

2206
2207 if (rename(from, to) < 0)
2208 perror_reply(550, "rename");
2209 else
2210 ack("RNTO");
2211}
2212
2213static void
2018dolog(sin)
2019 struct sockaddr_in *sin;
2214dolog(who)
2215 struct sockaddr *who;
2020{
2216{
2021 realhostname(remotehost, sizeof(remotehost) - 1, &sin->sin_addr);
2217 int error;
2022
2218
2219 realhostname_sa(remotehost, sizeof(remotehost) - 1, who, who->sa_len);
2220
2023#ifdef SETPROCTITLE
2024#ifdef VIRTUAL_HOSTING
2025 if (thishost != firsthost)
2026 snprintf(proctitle, sizeof(proctitle), "%s: connected (to %s)",
2027 remotehost, hostname);
2028 else
2029#endif
2030 snprintf(proctitle, sizeof(proctitle), "%s: connected",
2031 remotehost);
2032 setproctitle("%s", proctitle);
2033#endif /* SETPROCTITLE */
2034
2035 if (logging) {
2036#ifdef VIRTUAL_HOSTING
2037 if (thishost != firsthost)
2038 syslog(LOG_INFO, "connection from %s (to %s)",
2039 remotehost, hostname);
2040 else
2041#endif
2221#ifdef SETPROCTITLE
2222#ifdef VIRTUAL_HOSTING
2223 if (thishost != firsthost)
2224 snprintf(proctitle, sizeof(proctitle), "%s: connected (to %s)",
2225 remotehost, hostname);
2226 else
2227#endif
2228 snprintf(proctitle, sizeof(proctitle), "%s: connected",
2229 remotehost);
2230 setproctitle("%s", proctitle);
2231#endif /* SETPROCTITLE */
2232
2233 if (logging) {
2234#ifdef VIRTUAL_HOSTING
2235 if (thishost != firsthost)
2236 syslog(LOG_INFO, "connection from %s (to %s)",
2237 remotehost, hostname);
2238 else
2239#endif
2240 {
2241 char who_name[MAXHOSTNAMELEN];
2242
2243 error = getnameinfo(who, who->sa_len,
2244 who_name, sizeof(who_name) - 1,
2245 NULL, 0,
2246 NI_NUMERICHOST|NI_WITHSCOPEID);
2042 syslog(LOG_INFO, "connection from %s (%s)", remotehost,
2247 syslog(LOG_INFO, "connection from %s (%s)", remotehost,
2043 inet_ntoa(sin->sin_addr));
2248 error == 0 ? who_name : "");
2249 }
2044 }
2045}
2046
2047/*
2048 * Record logout in wtmp file
2049 * and exit with supplied status.
2050 */
2051void

--- 55 unchanged lines hidden (view full) ---

2107passive()
2108{
2109 int len;
2110 char *p, *a;
2111
2112 if (pdata >= 0) /* close old port if one set */
2113 close(pdata);
2114
2250 }
2251}
2252
2253/*
2254 * Record logout in wtmp file
2255 * and exit with supplied status.
2256 */
2257void

--- 55 unchanged lines hidden (view full) ---

2313passive()
2314{
2315 int len;
2316 char *p, *a;
2317
2318 if (pdata >= 0) /* close old port if one set */
2319 close(pdata);
2320
2115 pdata = socket(AF_INET, SOCK_STREAM, 0);
2321 pdata = socket(ctrl_addr.su_family, SOCK_STREAM, 0);
2116 if (pdata < 0) {
2117 perror_reply(425, "Can't open passive connection");
2118 return;
2119 }
2120
2121 (void) seteuid((uid_t)0);
2122
2123#ifdef IP_PORTRANGE
2322 if (pdata < 0) {
2323 perror_reply(425, "Can't open passive connection");
2324 return;
2325 }
2326
2327 (void) seteuid((uid_t)0);
2328
2329#ifdef IP_PORTRANGE
2124 {
2330 if (ctrl_addr.su_family == AF_INET) {
2125 int on = restricted_data_ports ? IP_PORTRANGE_HIGH
2126 : IP_PORTRANGE_DEFAULT;
2127
2128 if (setsockopt(pdata, IPPROTO_IP, IP_PORTRANGE,
2129 (char *)&on, sizeof(on)) < 0)
2130 goto pasv_error;
2131 }
2132#endif
2133
2134 pasv_addr = ctrl_addr;
2331 int on = restricted_data_ports ? IP_PORTRANGE_HIGH
2332 : IP_PORTRANGE_DEFAULT;
2333
2334 if (setsockopt(pdata, IPPROTO_IP, IP_PORTRANGE,
2335 (char *)&on, sizeof(on)) < 0)
2336 goto pasv_error;
2337 }
2338#endif
2339
2340 pasv_addr = ctrl_addr;
2135 pasv_addr.sin_port = 0;
2136 if (bind(pdata, (struct sockaddr *)&pasv_addr,
2137 sizeof(pasv_addr)) < 0)
2341 pasv_addr.su_port = 0;
2342 if (bind(pdata, (struct sockaddr *)&pasv_addr, pasv_addr.su_len) < 0)
2138 goto pasv_error;
2139
2140 (void) seteuid((uid_t)pw->pw_uid);
2141
2142 len = sizeof(pasv_addr);
2143 if (getsockname(pdata, (struct sockaddr *) &pasv_addr, &len) < 0)
2144 goto pasv_error;
2145 if (listen(pdata, 1) < 0)
2146 goto pasv_error;
2343 goto pasv_error;
2344
2345 (void) seteuid((uid_t)pw->pw_uid);
2346
2347 len = sizeof(pasv_addr);
2348 if (getsockname(pdata, (struct sockaddr *) &pasv_addr, &len) < 0)
2349 goto pasv_error;
2350 if (listen(pdata, 1) < 0)
2351 goto pasv_error;
2147 a = (char *) &pasv_addr.sin_addr;
2148 p = (char *) &pasv_addr.sin_port;
2352 if (pasv_addr.su_family == AF_INET)
2353 a = (char *) &pasv_addr.su_sin.sin_addr;
2354 else if (pasv_addr.su_family == AF_INET6 &&
2355 IN6_IS_ADDR_V4MAPPED(&pasv_addr.su_sin6.sin6_addr))
2356 a = (char *) &pasv_addr.su_sin6.sin6_addr.s6_addr[12];
2357 else
2358 goto pasv_error;
2359
2360 p = (char *) &pasv_addr.su_port;
2149
2150#define UC(b) (((int) b) & 0xff)
2151
2152 reply(227, "Entering Passive Mode (%d,%d,%d,%d,%d,%d)", UC(a[0]),
2153 UC(a[1]), UC(a[2]), UC(a[3]), UC(p[0]), UC(p[1]));
2154 return;
2155
2156pasv_error:
2157 (void) seteuid((uid_t)pw->pw_uid);
2158 (void) close(pdata);
2159 pdata = -1;
2160 perror_reply(425, "Can't open passive connection");
2161 return;
2162}
2163
2164/*
2361
2362#define UC(b) (((int) b) & 0xff)
2363
2364 reply(227, "Entering Passive Mode (%d,%d,%d,%d,%d,%d)", UC(a[0]),
2365 UC(a[1]), UC(a[2]), UC(a[3]), UC(p[0]), UC(p[1]));
2366 return;
2367
2368pasv_error:
2369 (void) seteuid((uid_t)pw->pw_uid);
2370 (void) close(pdata);
2371 pdata = -1;
2372 perror_reply(425, "Can't open passive connection");
2373 return;
2374}
2375
2376/*
2377 * Long Passive defined in RFC 1639.
2378 * 228 Entering Long Passive Mode
2379 * (af, hal, h1, h2, h3,..., pal, p1, p2...)
2380 */
2381
2382void
2383long_passive(cmd, pf)
2384 char *cmd;
2385 int pf;
2386{
2387 int len;
2388 char *p, *a;
2389
2390 if (pdata >= 0) /* close old port if one set */
2391 close(pdata);
2392
2393 if (pf != PF_UNSPEC) {
2394 if (ctrl_addr.su_family != pf) {
2395 switch (ctrl_addr.su_family) {
2396 case AF_INET:
2397 pf = 1;
2398 break;
2399 case AF_INET6:
2400 pf = 2;
2401 break;
2402 default:
2403 pf = 0;
2404 break;
2405 }
2406 /*
2407 * XXX
2408 * only EPRT/EPSV ready clients will understand this
2409 */
2410 if (strcmp(cmd, "EPSV") == 0 && pf) {
2411 reply(522, "Network protocol mismatch, "
2412 "use (%d)", pf);
2413 } else
2414 reply(501, "Network protocol mismatch"); /*XXX*/
2415
2416 return;
2417 }
2418 }
2419
2420 pdata = socket(ctrl_addr.su_family, SOCK_STREAM, 0);
2421 if (pdata < 0) {
2422 perror_reply(425, "Can't open passive connection");
2423 return;
2424 }
2425
2426 (void) seteuid((uid_t)0);
2427
2428 pasv_addr = ctrl_addr;
2429 pasv_addr.su_port = 0;
2430 len = pasv_addr.su_len;
2431
2432 if (bind(pdata, (struct sockaddr *)&pasv_addr, len) < 0)
2433 goto pasv_error;
2434
2435 (void) seteuid((uid_t)pw->pw_uid);
2436
2437 if (getsockname(pdata, (struct sockaddr *) &pasv_addr, &len) < 0)
2438 goto pasv_error;
2439 if (listen(pdata, 1) < 0)
2440 goto pasv_error;
2441
2442#define UC(b) (((int) b) & 0xff)
2443
2444 if (strcmp(cmd, "LPSV") == 0) {
2445 p = (char *)&pasv_addr.su_port;
2446 switch (pasv_addr.su_family) {
2447 case AF_INET:
2448 a = (char *) &pasv_addr.su_sin.sin_addr;
2449 v4_reply:
2450 reply(228,
2451"Entering Long Passive Mode (%d,%d,%d,%d,%d,%d,%d,%d,%d)",
2452 4, 4, UC(a[0]), UC(a[1]), UC(a[2]), UC(a[3]),
2453 2, UC(p[0]), UC(p[1]));
2454 return;
2455 case AF_INET6:
2456 if (IN6_IS_ADDR_V4MAPPED(&pasv_addr.su_sin6.sin6_addr)) {
2457 a = (char *) &pasv_addr.su_sin6.sin6_addr.s6_addr[12];
2458 goto v4_reply;
2459 }
2460 a = (char *) &pasv_addr.su_sin6.sin6_addr;
2461 reply(228,
2462"Entering Long Passive Mode "
2463"(%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d)",
2464 6, 16, UC(a[0]), UC(a[1]), UC(a[2]), UC(a[3]),
2465 UC(a[4]), UC(a[5]), UC(a[6]), UC(a[7]),
2466 UC(a[8]), UC(a[9]), UC(a[10]), UC(a[11]),
2467 UC(a[12]), UC(a[13]), UC(a[14]), UC(a[15]),
2468 2, UC(p[0]), UC(p[1]));
2469 return;
2470 }
2471 } else if (strcmp(cmd, "EPSV") == 0) {
2472 switch (pasv_addr.su_family) {
2473 case AF_INET:
2474 case AF_INET6:
2475 reply(229, "Entering Extended Passive Mode (|||%d|)",
2476 ntohs(pasv_addr.su_port));
2477 return;
2478 }
2479 } else {
2480 /* more proper error code? */
2481 }
2482
2483pasv_error:
2484 (void) seteuid((uid_t)pw->pw_uid);
2485 (void) close(pdata);
2486 pdata = -1;
2487 perror_reply(425, "Can't open passive connection");
2488 return;
2489}
2490
2491/*
2165 * Generate unique name for file with basename "local".
2166 * The file named "local" is already known to exist.
2167 * Generates failure reply on error.
2168 */
2169static char *
2170gunique(local)
2171 char *local;
2172{

--- 245 unchanged lines hidden ---
2492 * Generate unique name for file with basename "local".
2493 * The file named "local" is already known to exist.
2494 * Generates failure reply on error.
2495 */
2496static char *
2497gunique(local)
2498 char *local;
2499{

--- 245 unchanged lines hidden ---