ftpd: Synchronize with FreeBSD 13.3.
This commit is contained in:
@@ -1,4 +1,3 @@
|
||||
/* $FreeBSD: src/libexec/ftpd/config.h,v 1.1 2001/07/19 17:45:14 obrien Exp $ */
|
||||
|
||||
|
||||
/* config.h. Generated automatically by configure. */
|
||||
@@ -199,7 +198,7 @@
|
||||
#define HAVE_SOCKLEN_T 1
|
||||
|
||||
/* Define if AF_INET6 exists in <sys/socket.h> */
|
||||
/* #define HAVE_AF_INET6 1 */
|
||||
#define HAVE_AF_INET6 1
|
||||
|
||||
/* Define if `struct sockaddr_in6' exists in <netinet/in.h> */
|
||||
#define HAVE_SOCKADDR_IN6 1
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
/*-
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*
|
||||
* Copyright (c) 1992, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
@@ -10,11 +12,7 @@
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* 3. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
@@ -31,7 +29,6 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)extern.h 8.2 (Berkeley) 4/4/94
|
||||
* $FreeBSD: src/libexec/ftpd/extern.h,v 1.19 2002/02/04 01:23:44 kris Exp $
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
@@ -46,7 +43,7 @@ void fatalerror(char *);
|
||||
void ftpd_logwtmp(char *, char *, struct sockaddr *addr);
|
||||
int ftpd_pclose(FILE *);
|
||||
FILE *ftpd_popen(char *, char *);
|
||||
int *ftpd_getline(char *, int, FILE *);
|
||||
int get_line(char *, int, FILE *);
|
||||
void lreply(int, const char *, ...) __printflike(2, 3);
|
||||
void makedir(char *);
|
||||
void nack(char *);
|
||||
@@ -70,6 +67,35 @@ void yyerror(char *);
|
||||
int yyparse(void);
|
||||
int ls_main(int, char **);
|
||||
|
||||
extern int assumeutf8;
|
||||
extern char cbuf[];
|
||||
extern union sockunion data_dest;
|
||||
extern int epsvall;
|
||||
extern int form;
|
||||
extern int ftpdebug;
|
||||
extern int guest;
|
||||
extern union sockunion his_addr;
|
||||
extern char *homedir;
|
||||
extern int hostinfo;
|
||||
extern char *hostname;
|
||||
extern int maxtimeout;
|
||||
extern int logged_in;
|
||||
extern int logging;
|
||||
extern int noepsv;
|
||||
extern int noguestretr;
|
||||
extern int noretr;
|
||||
extern int paranoid;
|
||||
extern struct passwd *pw;
|
||||
extern int pdata;
|
||||
extern char proctitle[];
|
||||
extern int readonly;
|
||||
extern off_t restart_point;
|
||||
extern int timeout;
|
||||
extern char tmpline[];
|
||||
extern int type;
|
||||
extern char *typenames[]; /* defined in <arpa/ftp.h> included from ftpd.c */
|
||||
extern int usedefault;
|
||||
|
||||
struct sockaddr_in;
|
||||
struct sockaddr_in6;
|
||||
union sockunion {
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
/*
|
||||
/*-
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*
|
||||
* Copyright (c) 1985, 1988, 1993, 1994
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
@@ -10,11 +12,7 @@
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* 3. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
@@ -47,8 +45,6 @@ static char sccsid[] = "@(#)ftpcmd.y 8.3 (Berkeley) 4/6/94";
|
||||
#endif /* not lint */
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD: src/libexec/ftpd/ftpcmd.y,v 1.66 2007/04/18 22:43:39 yar Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/stat.h>
|
||||
@@ -76,30 +72,7 @@ __FBSDID("$FreeBSD: src/libexec/ftpd/ftpcmd.y,v 1.66 2007/04/18 22:43:39 yar Exp
|
||||
#include "extern.h"
|
||||
#include "pathnames.h"
|
||||
|
||||
extern union sockunion data_dest, his_addr;
|
||||
extern int hostinfo;
|
||||
extern int logged_in;
|
||||
extern struct passwd *pw;
|
||||
extern int guest;
|
||||
extern char *homedir;
|
||||
extern int paranoid;
|
||||
extern int logging;
|
||||
extern int type;
|
||||
extern int form;
|
||||
extern int ftpdebug;
|
||||
extern int timeout;
|
||||
extern int maxtimeout;
|
||||
extern int pdata;
|
||||
extern char *hostname;
|
||||
extern char proctitle[];
|
||||
extern int usedefault;
|
||||
extern char tmpline[];
|
||||
extern int readonly;
|
||||
extern int assumeutf8;
|
||||
extern int noepsv;
|
||||
extern int noretr;
|
||||
extern int noguestretr;
|
||||
extern char *typenames[]; /* defined in <arpa/ftp.h> included from ftpd.c */
|
||||
#define yylex ftpcmd_yylex
|
||||
|
||||
off_t restart_point;
|
||||
|
||||
@@ -110,8 +83,6 @@ static int state;
|
||||
char cbuf[512];
|
||||
char *fromname = NULL;
|
||||
|
||||
extern int epsvall;
|
||||
|
||||
#define CMD 0 /* beginning of command */
|
||||
#define ARGS 1 /* expect miscellaneous arguments */
|
||||
#define STR1 2 /* expect SP followed by STRING */
|
||||
@@ -252,8 +223,8 @@ static int port_check(const char *);
|
||||
#ifdef INET6
|
||||
static int port_check_v6(const char *);
|
||||
#endif
|
||||
static int check_login1(void);
|
||||
static void sizecmd(char *);
|
||||
static int check_login1(void);
|
||||
static void toolong(int);
|
||||
#ifdef INET6
|
||||
static void v4map_data_dest(void);
|
||||
@@ -542,7 +513,7 @@ cmd
|
||||
case MODE_S:
|
||||
reply(200, "MODE S accepted.");
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
reply(502, "Unimplemented MODE type.");
|
||||
}
|
||||
@@ -915,7 +886,7 @@ rcmd
|
||||
free(fromname);
|
||||
fromname = NULL;
|
||||
restart_point = $4.o;
|
||||
reply(350, "Restarting at %lld. %s",
|
||||
reply(350, "Restarting at %jd. %s",
|
||||
(intmax_t)restart_point,
|
||||
"Send STORE or RETRIEVE to initiate transfer.");
|
||||
}
|
||||
@@ -1194,10 +1165,10 @@ lookup(struct tab *p, char *cmd)
|
||||
#include <arpa/telnet.h>
|
||||
|
||||
/*
|
||||
* ftpd_getline - a hacked up version of fgets to ignore TELNET escape codes.
|
||||
* get_line - a hacked up version of fgets to ignore TELNET escape codes.
|
||||
*/
|
||||
int *
|
||||
ftpd_getline(char *s, int n, FILE *iop)
|
||||
int
|
||||
get_line(char *s, int n, FILE *iop)
|
||||
{
|
||||
int c;
|
||||
register char *cs;
|
||||
@@ -1316,7 +1287,7 @@ yylex(void)
|
||||
case CMD:
|
||||
(void) signal(SIGALRM, toolong);
|
||||
(void) alarm(timeout);
|
||||
n = ftpd_getline(cbuf, sizeof(cbuf)-1, stdin);
|
||||
n = get_line(cbuf, sizeof(cbuf)-1, stdin);
|
||||
if (n == -1) {
|
||||
reply(221, "You could at least say goodbye.");
|
||||
dologout(0);
|
||||
@@ -1624,7 +1595,7 @@ sizecmd(char *filename)
|
||||
else if (!S_ISREG(stbuf.st_mode))
|
||||
reply(550, "%s: not a plain file.", filename);
|
||||
else
|
||||
reply(213, "%lld", (intmax_t)stbuf.st_size);
|
||||
reply(213, "%jd", (intmax_t)stbuf.st_size);
|
||||
break; }
|
||||
case TYPE_A: {
|
||||
FILE *fin;
|
||||
@@ -1658,7 +1629,7 @@ sizecmd(char *filename)
|
||||
}
|
||||
(void) fclose(fin);
|
||||
|
||||
reply(213, "%lld", (intmax_t)count);
|
||||
reply(213, "%jd", (intmax_t)count);
|
||||
break; }
|
||||
default:
|
||||
reply(504, "SIZE not implemented for type %s.",
|
||||
@@ -1750,7 +1721,7 @@ exptilde(char *s)
|
||||
* Avoid expanding to a pathname including '\r' or '\n' in order to
|
||||
* not disrupt the FTP protocol.
|
||||
* The expansion found must be unique.
|
||||
* Return the result as a malloced string, or NULL if an error occured.
|
||||
* Return the result as a malloced string, or NULL if an error occurred.
|
||||
*
|
||||
* Problem: this production is used for all pathname
|
||||
* processing, but only gives a 550 error reply.
|
||||
|
||||
+113
-79
@@ -1,4 +1,6 @@
|
||||
/*
|
||||
/*-
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*
|
||||
* Copyright (c) 1985, 1988, 1990, 1992, 1993, 1994
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
@@ -10,11 +12,7 @@
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* 3. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
@@ -46,14 +44,12 @@ static char sccsid[] = "@(#)ftpd.c 8.4 (Berkeley) 4/16/94";
|
||||
#endif /* not lint */
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD: src/libexec/ftpd/ftpd.c,v 1.212 2007/04/18 22:43:39 yar Exp $");
|
||||
|
||||
/*
|
||||
* FTP server.
|
||||
*/
|
||||
#include <sys/param.h>
|
||||
#include <sys/ioctl.h>
|
||||
//#include <sys/mman.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/time.h>
|
||||
@@ -111,9 +107,6 @@ __FBSDID("$FreeBSD: src/libexec/ftpd/ftpd.c,v 1.212 2007/04/18 22:43:39 yar Exp
|
||||
static char version[] = "Version 6.00LS";
|
||||
#undef main
|
||||
|
||||
extern off_t restart_point;
|
||||
extern char cbuf[];
|
||||
|
||||
union sockunion ctrl_addr;
|
||||
union sockunion data_source;
|
||||
union sockunion data_dest;
|
||||
@@ -153,6 +146,7 @@ int noretr = 0; /* RETR command is disabled. */
|
||||
int noguestretr = 0; /* RETR command is disabled for anon users. */
|
||||
int noguestmkd = 0; /* MKD command is disabled for anon users. */
|
||||
int noguestmod = 1; /* anon users may not modify existing files. */
|
||||
int use_blacklist = 0;
|
||||
|
||||
off_t file_size;
|
||||
off_t byte_count;
|
||||
@@ -182,8 +176,7 @@ static struct ftphost {
|
||||
char remotehost[NI_MAXHOST];
|
||||
char *ident = NULL;
|
||||
|
||||
static char ttyline[20];
|
||||
char *tty = ttyline; /* for klogin */
|
||||
static char wtmpid[20];
|
||||
|
||||
#ifdef USE_PAM
|
||||
static int auth_pam(struct passwd**, const char*);
|
||||
@@ -252,7 +245,7 @@ static void sigurg(int);
|
||||
static void maskurg(int);
|
||||
static void flagxfer(int);
|
||||
static int myoob(void);
|
||||
static int checkuser(char *, char *, int, char **);
|
||||
static int checkuser(char *, char *, int, char **, int *);
|
||||
static FILE *dataconn(char *, off_t, char *);
|
||||
static void dolog(struct sockaddr *);
|
||||
static void end_login(void);
|
||||
@@ -276,7 +269,7 @@ int
|
||||
main(int argc, char *argv[], char **envp)
|
||||
{
|
||||
socklen_t addrlen;
|
||||
int ch, on = 1, tos;
|
||||
int ch, on = 1, tos, s = STDIN_FILENO;
|
||||
char *cp, line[LINE_MAX];
|
||||
FILE *fd;
|
||||
char *bindname = NULL;
|
||||
@@ -303,7 +296,7 @@ main(int argc, char *argv[], char **envp)
|
||||
openlog("ftpd", LOG_PID | LOG_NDELAY, LOG_FTP);
|
||||
|
||||
while ((ch = getopt(argc, argv,
|
||||
"468a:AdDEhlmMoOp:P:rRSt:T:u:UvW")) != -1) {
|
||||
"468a:ABdDEhlmMoOp:P:rRSt:T:u:UvW")) != -1) {
|
||||
switch (ch) {
|
||||
case '4':
|
||||
family = (family == AF_INET6) ? AF_UNSPEC : AF_INET;
|
||||
@@ -325,6 +318,14 @@ main(int argc, char *argv[], char **envp)
|
||||
anon_only = 1;
|
||||
break;
|
||||
|
||||
case 'B':
|
||||
#ifdef USE_BLACKLIST
|
||||
use_blacklist = 1;
|
||||
#else
|
||||
syslog(LOG_WARNING, "not compiled with USE_BLACKLIST support");
|
||||
#endif
|
||||
break;
|
||||
|
||||
case 'd':
|
||||
ftpdebug++;
|
||||
break;
|
||||
@@ -422,6 +423,10 @@ main(int argc, char *argv[], char **envp)
|
||||
}
|
||||
}
|
||||
|
||||
/* handle filesize limit gracefully */
|
||||
sa.sa_handler = SIG_IGN;
|
||||
(void)sigaction(SIGXFSZ, &sa, NULL);
|
||||
|
||||
if (daemon_mode) {
|
||||
int *ctl_sock, fd, maxfd = -1, nfds, i;
|
||||
fd_set defreadfds, readfds;
|
||||
@@ -502,8 +507,8 @@ main(int argc, char *argv[], char **envp)
|
||||
switch (pid = fork()) {
|
||||
case 0:
|
||||
/* child */
|
||||
(void) dup2(fd, 0);
|
||||
(void) dup2(fd, 1);
|
||||
(void) dup2(fd, s);
|
||||
(void) dup2(fd, STDOUT_FILENO);
|
||||
(void) close(fd);
|
||||
for (i = 1; i <= *ctl_sock; i++)
|
||||
close(ctl_sock[i]);
|
||||
@@ -520,7 +525,7 @@ main(int argc, char *argv[], char **envp)
|
||||
}
|
||||
} else {
|
||||
addrlen = sizeof(his_addr);
|
||||
if (getpeername(0, (struct sockaddr *)&his_addr, &addrlen) < 0) {
|
||||
if (getpeername(s, (struct sockaddr *)&his_addr, &addrlen) < 0) {
|
||||
syslog(LOG_ERR, "getpeername (%s): %m",argv[0]);
|
||||
exit(1);
|
||||
}
|
||||
@@ -555,7 +560,7 @@ gotchild:
|
||||
(void)sigaction(SIGPIPE, &sa, NULL);
|
||||
|
||||
addrlen = sizeof(ctrl_addr);
|
||||
if (getsockname(0, (struct sockaddr *)&ctrl_addr, &addrlen) < 0) {
|
||||
if (getsockname(s, (struct sockaddr *)&ctrl_addr, &addrlen) < 0) {
|
||||
syslog(LOG_ERR, "getsockname (%s): %m",argv[0]);
|
||||
exit(1);
|
||||
}
|
||||
@@ -568,7 +573,7 @@ gotchild:
|
||||
if (ctrl_addr.su_family == AF_INET)
|
||||
{
|
||||
tos = IPTOS_LOWDELAY;
|
||||
if (setsockopt(0, IPPROTO_IP, IP_TOS, &tos, sizeof(int)) < 0)
|
||||
if (setsockopt(s, IPPROTO_IP, IP_TOS, &tos, sizeof(int)) < 0)
|
||||
syslog(LOG_WARNING, "control setsockopt (IP_TOS): %m");
|
||||
}
|
||||
#endif
|
||||
@@ -576,22 +581,21 @@ gotchild:
|
||||
* Disable Nagle on the control channel so that we don't have to wait
|
||||
* for peer's ACK before issuing our next reply.
|
||||
*/
|
||||
if (setsockopt(0, IPPROTO_TCP, TCP_NODELAY, &on, sizeof(on)) < 0)
|
||||
if (setsockopt(s, IPPROTO_TCP, TCP_NODELAY, &on, sizeof(on)) < 0)
|
||||
syslog(LOG_WARNING, "control setsockopt (TCP_NODELAY): %m");
|
||||
|
||||
data_source.su_port = htons(ntohs(ctrl_addr.su_port) - 1);
|
||||
|
||||
/* set this here so klogin can use it... */
|
||||
(void)snprintf(ttyline, sizeof(ttyline), "ftp%d", (int)getpid());
|
||||
(void)snprintf(wtmpid, sizeof(wtmpid), "%xftpd", getpid());
|
||||
|
||||
/* Try to handle urgent data inline */
|
||||
#ifdef SO_OOBINLINE
|
||||
if (setsockopt(0, SOL_SOCKET, SO_OOBINLINE, &on, sizeof(on)) < 0)
|
||||
if (setsockopt(s, SOL_SOCKET, SO_OOBINLINE, &on, sizeof(on)) < 0)
|
||||
syslog(LOG_WARNING, "control setsockopt (SO_OOBINLINE): %m");
|
||||
#endif
|
||||
|
||||
#ifdef F_SETOWN
|
||||
if (fcntl(fileno(stdin), F_SETOWN, getpid()) == -1)
|
||||
if (fcntl(s, F_SETOWN, getpid()) == -1)
|
||||
syslog(LOG_ERR, "fcntl F_SETOWN: %m");
|
||||
#endif
|
||||
dolog((struct sockaddr *)&his_addr);
|
||||
@@ -1009,6 +1013,7 @@ static char curname[MAXLOGNAME]; /* current USER name */
|
||||
void
|
||||
user(char *name)
|
||||
{
|
||||
int ecode;
|
||||
char *cp, *shell;
|
||||
|
||||
if (logged_in) {
|
||||
@@ -1029,8 +1034,11 @@ user(char *name)
|
||||
pw = sgetpwnam("ftp");
|
||||
#endif
|
||||
if (strcmp(name, "ftp") == 0 || strcmp(name, "anonymous") == 0) {
|
||||
if (checkuser(_PATH_FTPUSERS, "ftp", 0, NULL) ||
|
||||
checkuser(_PATH_FTPUSERS, "anonymous", 0, NULL))
|
||||
if (checkuser(_PATH_FTPUSERS, "ftp", 0, NULL, &ecode) ||
|
||||
(ecode != 0 && ecode != ENOENT))
|
||||
reply(530, "User %s access denied.", name);
|
||||
else if (checkuser(_PATH_FTPUSERS, "anonymous", 0, NULL, &ecode) ||
|
||||
(ecode != 0 && ecode != ENOENT))
|
||||
reply(530, "User %s access denied.", name);
|
||||
else if (pw != NULL) {
|
||||
guest = 1;
|
||||
@@ -1048,7 +1056,7 @@ user(char *name)
|
||||
reply(530, "Sorry, only anonymous ftp allowed.");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if ((pw = sgetpwnam(name))) {
|
||||
if ((shell = pw->pw_shell) == NULL || *shell == 0)
|
||||
shell = _PATH_BSHELL;
|
||||
@@ -1058,7 +1066,9 @@ user(char *name)
|
||||
break;
|
||||
endusershell();
|
||||
|
||||
if (cp == NULL || checkuser(_PATH_FTPUSERS, name, 1, NULL)) {
|
||||
if (cp == NULL ||
|
||||
(checkuser(_PATH_FTPUSERS, name, 1, NULL, &ecode) ||
|
||||
(ecode != 0 && ecode != ENOENT))) {
|
||||
reply(530, "User %s access denied.", name);
|
||||
if (logging)
|
||||
syslog(LOG_NOTICE,
|
||||
@@ -1103,13 +1113,15 @@ user(char *name)
|
||||
* of the matching line in "residue" if not NULL.
|
||||
*/
|
||||
static int
|
||||
checkuser(char *fname, char *name, int pwset, char **residue)
|
||||
checkuser(char *fname, char *name, int pwset, char **residue, int *ecode)
|
||||
{
|
||||
FILE *fd;
|
||||
int found = 0;
|
||||
size_t len;
|
||||
char *line, *mp, *p;
|
||||
|
||||
if (ecode != NULL)
|
||||
*ecode = 0;
|
||||
if ((fd = fopen(fname, "r")) != NULL) {
|
||||
while (!found && (line = fgetln(fd, &len)) != NULL) {
|
||||
/* skip comments */
|
||||
@@ -1178,7 +1190,8 @@ nextline:
|
||||
free(mp);
|
||||
}
|
||||
(void) fclose(fd);
|
||||
}
|
||||
} else if (ecode != NULL)
|
||||
*ecode = errno;
|
||||
return (found);
|
||||
}
|
||||
|
||||
@@ -1194,14 +1207,14 @@ end_login(void)
|
||||
#endif
|
||||
|
||||
(void) seteuid(0);
|
||||
if (logged_in && dowtmp)
|
||||
ftpd_logwtmp(ttyline, "", NULL);
|
||||
pw = NULL;
|
||||
#ifdef LOGIN_CAP
|
||||
setusercontext(NULL, getpwuid(0), 0,
|
||||
LOGIN_SETPRIORITY|LOGIN_SETRESOURCES|LOGIN_SETUMASK|
|
||||
LOGIN_SETMAC);
|
||||
setusercontext(NULL, getpwuid(0), 0, LOGIN_SETALL & ~(LOGIN_SETLOGIN |
|
||||
LOGIN_SETUSER | LOGIN_SETGROUP | LOGIN_SETPATH |
|
||||
LOGIN_SETENV));
|
||||
#endif
|
||||
if (logged_in && dowtmp)
|
||||
ftpd_logwtmp(wtmpid, NULL, NULL);
|
||||
pw = NULL;
|
||||
#ifdef USE_PAM
|
||||
if (pamh) {
|
||||
if ((e = pam_setcred(pamh, PAM_DELETE_CRED)) != PAM_SUCCESS)
|
||||
@@ -1375,7 +1388,7 @@ auth_pam(struct passwd **ppw, const char *pass)
|
||||
void
|
||||
pass(char *passwd)
|
||||
{
|
||||
int rval;
|
||||
int rval, ecode;
|
||||
FILE *fd;
|
||||
#ifdef LOGIN_CAP
|
||||
login_cap_t *lc = NULL;
|
||||
@@ -1495,12 +1508,36 @@ skip:
|
||||
}
|
||||
#endif
|
||||
|
||||
/* open wtmp before chroot */
|
||||
dochroot =
|
||||
checkuser(_PATH_FTPCHROOT, pw->pw_name, 1, &residue, &ecode)
|
||||
#ifdef LOGIN_CAP /* Allow login.conf configuration as well */
|
||||
|| login_getcapbool(lc, "ftp-chroot", 0)
|
||||
#endif
|
||||
;
|
||||
/*
|
||||
* It is possible that checkuser() failed to open the chroot file.
|
||||
* If this is the case, report that logins are un-available, since we
|
||||
* have no way of checking whether or not the user should be chrooted.
|
||||
* We ignore ENOENT since it is not required that this file be present.
|
||||
*/
|
||||
if (ecode != 0 && ecode != ENOENT) {
|
||||
reply(530, "Login not available right now.");
|
||||
return;
|
||||
}
|
||||
chrootdir = NULL;
|
||||
|
||||
/* Disable wtmp logging when chrooting. */
|
||||
if (dochroot || guest)
|
||||
dowtmp = 0;
|
||||
if (dowtmp)
|
||||
ftpd_logwtmp(ttyline, pw->pw_name,
|
||||
ftpd_logwtmp(wtmpid, pw->pw_name,
|
||||
(struct sockaddr *)&his_addr);
|
||||
logged_in = 1;
|
||||
|
||||
#ifdef LOGIN_CAP
|
||||
setusercontext(lc, pw, 0, LOGIN_SETRESOURCES);
|
||||
#endif
|
||||
|
||||
if (guest && stats && statfd < 0) {
|
||||
#ifdef VIRTUAL_HOSTING
|
||||
statfd = open(thishost->statfile, O_WRONLY|O_APPEND);
|
||||
@@ -1511,13 +1548,6 @@ skip:
|
||||
stats = 0;
|
||||
}
|
||||
|
||||
dochroot =
|
||||
checkuser(_PATH_FTPCHROOT, pw->pw_name, 1, &residue)
|
||||
#ifdef LOGIN_CAP /* Allow login.conf configuration as well */
|
||||
|| login_getcapbool(lc, "ftp-chroot", 0)
|
||||
#endif
|
||||
;
|
||||
chrootdir = NULL;
|
||||
#if (!defined(__BEOS__) && !defined(__HAIKU__))
|
||||
/*
|
||||
* For a chrooted local user,
|
||||
@@ -1579,13 +1609,20 @@ skip:
|
||||
* (uid 0 has no root power over NFS if not mapped explicitly.)
|
||||
*/
|
||||
if (seteuid(pw->pw_uid) < 0) {
|
||||
reply(550, "Can't set uid.");
|
||||
goto bad;
|
||||
if (guest || dochroot) {
|
||||
fatalerror("Can't set uid.");
|
||||
} else {
|
||||
reply(550, "Can't set uid.");
|
||||
goto bad;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Do not allow the session to live if we're chroot()'ed and chdir()
|
||||
* fails. Otherwise the chroot jail can be escaped.
|
||||
*/
|
||||
if (chdir(homedir) < 0) {
|
||||
if (guest || dochroot) {
|
||||
reply(550, "Can't change to base directory.");
|
||||
goto bad;
|
||||
fatalerror("Can't change to base directory.");
|
||||
} else {
|
||||
if (chdir("/") < 0) {
|
||||
reply(550, "Root is inaccessible.");
|
||||
@@ -1679,14 +1716,14 @@ retrieve(char *cmd, char *name)
|
||||
struct stat st;
|
||||
int (*closefunc)(FILE *);
|
||||
time_t start;
|
||||
char line[BUFSIZ];
|
||||
|
||||
if (cmd == 0) {
|
||||
fin = fopen(name, "r"), closefunc = fclose;
|
||||
st.st_size = 0;
|
||||
} else {
|
||||
char line[BUFSIZ];
|
||||
|
||||
(void) snprintf(line, sizeof(line), cmd, name), name = line;
|
||||
(void) snprintf(line, sizeof(line), cmd, name);
|
||||
name = line;
|
||||
fin = ftpd_popen(line, "r"), closefunc = ftpd_pclose;
|
||||
st.st_size = -1;
|
||||
st.st_blksize = BUFSIZ;
|
||||
@@ -1926,7 +1963,7 @@ dataconn(char *name, off_t size, char *mode)
|
||||
byte_count = 0;
|
||||
if (size != -1)
|
||||
(void) snprintf(sizebuf, sizeof(sizebuf),
|
||||
" (%lld bytes)", (intmax_t)size);
|
||||
" (%jd bytes)", (intmax_t)size);
|
||||
else
|
||||
*sizebuf = '\0';
|
||||
if (pdata >= 0) {
|
||||
@@ -2056,7 +2093,7 @@ pdata_err:
|
||||
} while (0)
|
||||
|
||||
/*
|
||||
* Tranfer the contents of "instr" to "outstr" peer using the appropriate
|
||||
* Transfer the contents of "instr" to "outstr" peer using the appropriate
|
||||
* encapsulation of the data subject to Mode, Structure, and Type.
|
||||
*
|
||||
* NB: Form isn't handled.
|
||||
@@ -2359,8 +2396,8 @@ statfilecmd(char *filename)
|
||||
(void)snprintf(line, sizeof(line), _PATH_LS " -lgA %s", filename);
|
||||
fin = ftpd_popen(line, "r");
|
||||
if (fin == NULL) {
|
||||
perror_reply(551, filename);
|
||||
return;
|
||||
perror_reply(551, filename);
|
||||
return;
|
||||
}
|
||||
lreply(code, "Status of %s:", filename);
|
||||
atstart = 1;
|
||||
@@ -2766,7 +2803,12 @@ dologout(int status)
|
||||
|
||||
if (logged_in && dowtmp) {
|
||||
(void) seteuid(0);
|
||||
ftpd_logwtmp(ttyline, "", NULL);
|
||||
#ifdef LOGIN_CAP
|
||||
setusercontext(NULL, getpwuid(0), 0, LOGIN_SETALL & ~(LOGIN_SETLOGIN |
|
||||
LOGIN_SETUSER | LOGIN_SETGROUP | LOGIN_SETPATH |
|
||||
LOGIN_SETENV));
|
||||
#endif
|
||||
ftpd_logwtmp(wtmpid, NULL, NULL);
|
||||
}
|
||||
/* beware of flushing buffers after a SIGPIPE */
|
||||
_exit(status);
|
||||
@@ -2830,13 +2872,13 @@ myoob(void)
|
||||
return (0);
|
||||
}
|
||||
cp = tmpline;
|
||||
ret = getline(cp, 7, stdin);
|
||||
ret = get_line(cp, 7, stdin);
|
||||
if (ret == -1) {
|
||||
reply(221, "You could at least say goodbye.");
|
||||
dologout(0);
|
||||
} else if (ret == -2) {
|
||||
/* Ignore truncated command. */
|
||||
return (0);
|
||||
/* Ignore truncated command. */
|
||||
return (0);
|
||||
}
|
||||
upper(cp);
|
||||
if (strcmp(cp, "ABOR\r\n") == 0) {
|
||||
@@ -2848,10 +2890,10 @@ myoob(void)
|
||||
if (strcmp(cp, "STAT\r\n") == 0) {
|
||||
tmpline[0] = '\0';
|
||||
if (file_size != -1)
|
||||
reply(213, "Status: %lld of %lld bytes transferred.",
|
||||
reply(213, "Status: %jd of %jd bytes transferred.",
|
||||
(intmax_t)byte_count, (intmax_t)file_size);
|
||||
else
|
||||
reply(213, "Status: %lld bytes transferred.",
|
||||
reply(213, "Status: %jd bytes transferred.",
|
||||
(intmax_t)byte_count);
|
||||
}
|
||||
return (0);
|
||||
@@ -2919,14 +2961,12 @@ passive(void)
|
||||
goto pasv_error;
|
||||
if (pasv_addr.su_family == AF_INET)
|
||||
a = (char *) &pasv_addr.su_sin.sin_addr;
|
||||
#ifdef HAVE_AF_INET6
|
||||
else if (pasv_addr.su_family == AF_INET6 &&
|
||||
IN6_IS_ADDR_V4MAPPED(&pasv_addr.su_sin6.sin6_addr))
|
||||
a = (char *) &pasv_addr.su_sin6.sin6_addr.s6_addr[12];
|
||||
#endif
|
||||
else
|
||||
goto pasv_error;
|
||||
|
||||
|
||||
p = (char *) &pasv_addr.su_port;
|
||||
|
||||
#define UC(b) (((int) b) & 0xff)
|
||||
@@ -2985,7 +3025,7 @@ long_passive(char *cmd, int pf)
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
pdata = socket(ctrl_addr.su_family, SOCK_STREAM, 0);
|
||||
if (pdata < 0) {
|
||||
perror_reply(425, "Can't open passive connection");
|
||||
@@ -3039,15 +3079,12 @@ long_passive(char *cmd, int pf)
|
||||
switch (pasv_addr.su_family) {
|
||||
case AF_INET:
|
||||
a = (char *) &pasv_addr.su_sin.sin_addr;
|
||||
#ifdef HAVE_AF_INET6
|
||||
v4_reply:
|
||||
#endif
|
||||
reply(228,
|
||||
"Entering Long Passive Mode (%d,%d,%d,%d,%d,%d,%d,%d,%d)",
|
||||
4, 4, UC(a[0]), UC(a[1]), UC(a[2]), UC(a[3]),
|
||||
2, UC(p[0]), UC(p[1]));
|
||||
return;
|
||||
#ifdef HAVE_AF_INET6
|
||||
case AF_INET6:
|
||||
if (IN6_IS_ADDR_V4MAPPED(&pasv_addr.su_sin6.sin6_addr)) {
|
||||
a = (char *) &pasv_addr.su_sin6.sin6_addr.s6_addr[12];
|
||||
@@ -3063,7 +3100,6 @@ long_passive(char *cmd, int pf)
|
||||
UC(a[12]), UC(a[13]), UC(a[14]), UC(a[15]),
|
||||
2, UC(p[0]), UC(p[1]));
|
||||
return;
|
||||
#endif
|
||||
}
|
||||
} else if (strcmp(cmd, "EPSV") == 0) {
|
||||
switch (pasv_addr.su_family) {
|
||||
@@ -3124,7 +3160,7 @@ guniquefd(char *local, char **name)
|
||||
/* -4 is for the .nn<null> we put on the end below */
|
||||
(void) snprintf(new, sizeof(new) - 4, "%s", local);
|
||||
cp = new + strlen(new);
|
||||
/*
|
||||
/*
|
||||
* Don't generate dotfile unless requested explicitly.
|
||||
* This covers the case when basename gets truncated off
|
||||
* by buffer size.
|
||||
@@ -3356,7 +3392,7 @@ logcmd(char *cmd, char *file1, char *file2, off_t cnt)
|
||||
if (file2)
|
||||
appendf(&msg, " %s", file2);
|
||||
if (cnt >= 0)
|
||||
appendf(&msg, " = %lld bytes", (intmax_t)cnt);
|
||||
appendf(&msg, " = %jd bytes", (intmax_t)cnt);
|
||||
appendf(&msg, " (wd: %s", wd);
|
||||
if (guest || dochroot)
|
||||
appendf(&msg, "; chrooted");
|
||||
@@ -3378,7 +3414,7 @@ logxfer(char *name, off_t size, time_t start)
|
||||
syslog(LOG_NOTICE, "realpath failed on %s: %m", path);
|
||||
return;
|
||||
}
|
||||
snprintf(buf, sizeof(buf), "%.20s!%s!%s!%s!%lld!%ld\n",
|
||||
snprintf(buf, sizeof(buf), "%.20s!%s!%s!%s!%jd!%ld\n",
|
||||
ctime(&now)+4, ident, remotehost,
|
||||
path, (intmax_t)size,
|
||||
(long)(now - start + (now == start)));
|
||||
@@ -3452,14 +3488,12 @@ socksetup(int af, char *bindname, const char *bindport)
|
||||
&on, sizeof(on)) < 0)
|
||||
syslog(LOG_WARNING,
|
||||
"control setsockopt (SO_REUSEADDR): %m");
|
||||
#ifdef HAVE_AF_INET6
|
||||
if (r->ai_family == AF_INET6) {
|
||||
if (setsockopt(*s, IPPROTO_IPV6, IPV6_V6ONLY,
|
||||
&on, sizeof(on)) < 0)
|
||||
syslog(LOG_WARNING,
|
||||
"control setsockopt (IPV6_V6ONLY): %m");
|
||||
}
|
||||
#endif
|
||||
if (bind(*s, r->ai_addr, r->ai_addrlen) < 0) {
|
||||
syslog(LOG_DEBUG, "control bind: %m");
|
||||
close(*s);
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
/*
|
||||
/*-
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*
|
||||
* Copyright (c) 1988, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
@@ -10,11 +12,7 @@
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* 3. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
@@ -38,59 +36,42 @@ static char sccsid[] = "@(#)logwtmp.c 8.1 (Berkeley) 6/4/93";
|
||||
#endif /* not lint */
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD: src/libexec/ftpd/logwtmp.c,v 1.13 2004/11/18 13:46:29 yar Exp $");
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <time.h>
|
||||
#if (!defined(__BEOS__) && !defined(__HAIKU__))
|
||||
#include <timeconv.h>
|
||||
#include <utmp.h>
|
||||
#endif
|
||||
#include <netdb.h>
|
||||
#include <unistd.h>
|
||||
#include <libutil.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <libutil.h>
|
||||
#include <unistd.h>
|
||||
#include <utmpx.h>
|
||||
#include "extern.h"
|
||||
|
||||
static int fd = -1;
|
||||
|
||||
/*
|
||||
* Modified version of logwtmp that holds wtmp file open
|
||||
* after first call, for use with ftp (which may chroot
|
||||
* after login, but before logout).
|
||||
*/
|
||||
void
|
||||
ftpd_logwtmp(line, name, addr)
|
||||
char *line, *name;
|
||||
struct sockaddr *addr;
|
||||
ftpd_logwtmp(char *id, char *user, struct sockaddr *addr)
|
||||
{
|
||||
#if (!defined(__BEOS__) && !defined(__HAIKU__))
|
||||
struct utmp ut;
|
||||
struct stat buf;
|
||||
char host[UT_HOSTSIZE];
|
||||
struct utmpx ut;
|
||||
|
||||
if (addr == NULL)
|
||||
host[0] = '\0';
|
||||
else
|
||||
realhostname_sa(host, sizeof(host), addr, addr->sa_len);
|
||||
memset(&ut, 0, sizeof(ut));
|
||||
|
||||
if (fd < 0 && (fd = open(_PATH_WTMP, O_WRONLY|O_APPEND, 0)) < 0)
|
||||
return;
|
||||
if (fstat(fd, &buf) == 0) {
|
||||
(void)strncpy(ut.ut_line, line, sizeof(ut.ut_line));
|
||||
(void)strncpy(ut.ut_name, name, sizeof(ut.ut_name));
|
||||
(void)strncpy(ut.ut_host, host, sizeof(ut.ut_host));
|
||||
ut.ut_time = _time_to_time32(time(NULL));
|
||||
if (write(fd, &ut, sizeof(struct utmp)) !=
|
||||
sizeof(struct utmp))
|
||||
(void)ftruncate(fd, buf.st_size);
|
||||
if (user != NULL) {
|
||||
/* Log in. */
|
||||
ut.ut_type = USER_PROCESS;
|
||||
(void)strncpy(ut.ut_user, user, sizeof(ut.ut_user));
|
||||
if (addr != NULL)
|
||||
realhostname_sa(ut.ut_host, sizeof(ut.ut_host),
|
||||
addr, addr->sa_len);
|
||||
} else {
|
||||
/* Log out. */
|
||||
ut.ut_type = DEAD_PROCESS;
|
||||
}
|
||||
#endif
|
||||
|
||||
ut.ut_pid = getpid();
|
||||
gettimeofday(&ut.ut_tv, NULL);
|
||||
(void)strncpy(ut.ut_id, id, sizeof(ut.ut_id));
|
||||
(void)strncpy(ut.ut_line, "ftpd", sizeof(ut.ut_line));
|
||||
|
||||
pututxline(&ut);
|
||||
}
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
/*
|
||||
/*-
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*
|
||||
* Copyright (c) 1989, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
@@ -10,11 +12,7 @@
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* 3. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
@@ -31,7 +29,6 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)pathnames.h 8.1 (Berkeley) 6/4/93
|
||||
* $FreeBSD: src/libexec/ftpd/pathnames.h,v 1.11 1999/08/28 00:09:31 peter Exp $
|
||||
*/
|
||||
|
||||
#include <paths.h>
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
/*
|
||||
/*-
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*
|
||||
* Copyright (c) 1988, 1993, 1994
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
@@ -13,11 +15,7 @@
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* 3. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
@@ -41,8 +39,6 @@ static char sccsid[] = "@(#)popen.c 8.3 (Berkeley) 4/6/94";
|
||||
#endif /* not lint */
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD: src/libexec/ftpd/popen.c,v 1.26 2004/11/18 13:46:29 yar Exp $");
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/wait.h>
|
||||
#include <netinet/in.h>
|
||||
@@ -64,7 +60,7 @@ __FBSDID("$FreeBSD: src/libexec/ftpd/popen.c,v 1.26 2004/11/18 13:46:29 yar Exp
|
||||
#define MAXGLOBARGS 1000
|
||||
|
||||
/*
|
||||
* Special version of popen which avoids call to shell. This ensures noone
|
||||
* Special version of popen which avoids call to shell. This ensures no one
|
||||
* may create a pipe to a hidden program as a side effect of a list or dir
|
||||
* command.
|
||||
*/
|
||||
@@ -147,6 +143,9 @@ ftpd_popen(char *program, char *type)
|
||||
(void)close(pdes[1]);
|
||||
}
|
||||
#ifdef BUILTIN_LS
|
||||
/* Drop privileges before proceeding */
|
||||
if (getuid() != geteuid() && setuid(geteuid()) < 0)
|
||||
_exit(1);
|
||||
if (strcmp(gargv[0], _PATH_LS) == 0) {
|
||||
/* Reset getopt for ls_main() */
|
||||
optreset = optind = optopt = 1;
|
||||
|
||||
Reference in New Issue
Block a user