mirror of
https://github.com/InfrastructureServices/vsftpd.git
synced 2025-04-19 01:24:02 +03:00
Updated to v2.0.5
This commit is contained in:
parent
d201301b42
commit
c4e45fe8ac
27
Changelog
27
Changelog
@ -908,3 +908,30 @@ Mads Martin Joergensen <mmj@suse.de>.
|
||||
At this point: v2.0.4 released!
|
||||
===============================
|
||||
|
||||
- Apply fix for O_NONBLOCK vs. XFS DMAPI filesystem. Thanks to Sudha Srinivasan
|
||||
<sudhas@sgi.com>.
|
||||
- Fix build warnings exposed by my upgrade to Fedora Core 5 / GCC4.1.1.
|
||||
- Be more honest in FEAT response if PORT or PASV are disabled! Reported by
|
||||
Charles Honton <chas@honton.org>. Allows MS Explorer to get the transfer mode
|
||||
correct.
|
||||
- pam_pwdb.so -> pam_unix.so in example PAM file. Thanks to
|
||||
Rhodes, Colin <colin.rhodes@airways.co.nz>.
|
||||
- Add FAQ issue regarding "chroot fails with SSL" - in fact, sshd is being hit
|
||||
here instead ;-)
|
||||
- Minor man page doc tweaks.
|
||||
- Tiny bit of paranoia in privops.c.
|
||||
- Revert change to reject anonymous logins before asking for password. This
|
||||
fixes complaints about IE not showing the FTP login dialog.
|
||||
- Change SSL certificate load to cater for chaining too.
|
||||
- Added delay_failed_login and delay_successful_login to help limit resources
|
||||
taken by brute force attacks.
|
||||
- Kick session after a few login fails. Allows IP blocking solutions to be more
|
||||
immediately effective.
|
||||
- Replace setenv() with more portable putenv(). First part of Solaris fix.
|
||||
- Replace tm_gmtoff usage with timezone and daylight. Second part of Solaris
|
||||
fix.
|
||||
- Set PAM items TTY and RUSER if possible.
|
||||
- OpenBSD build warning fixes.
|
||||
- So, timezone and daylight are not available on BSD, so redo the whole TZ
|
||||
thing again. Should use only very portable constructs now.
|
||||
|
||||
|
5
FAQ
5
FAQ
@ -234,6 +234,11 @@ Q) Help! I'm getting the error "ftp: netin: Interrupted system call".
|
||||
A) Seems to be a bug in ftp-tls, particularly with SSL transfers with
|
||||
bandwidth limiting in effect.
|
||||
|
||||
Q) Help! When trying SSL transfers, users log in and are no longer restricted
|
||||
to their home directory! They can browse the entire filesystem!
|
||||
A) Most likely, your FTP client is in fact using the SSH protocol rather than
|
||||
the FTP protocol - so sshd is in control and not vsftpd!
|
||||
|
||||
Q) Blah.. blah..
|
||||
A) For a good idea of what vsftpd can do, read the vsftpd.conf.5 man page
|
||||
and the EXAMPLES.
|
||||
|
8
README
8
README
@ -1,4 +1,4 @@
|
||||
This is vsftpd, version 2.0.4
|
||||
This is vsftpd, version 2.0.5
|
||||
Author: Chris Evans
|
||||
Contact: chris@scary.beasts.org
|
||||
Website: http://vsftpd.beasts.org/
|
||||
@ -37,9 +37,3 @@ All configuration options are documented in the manual page vsftpd.conf.5.
|
||||
Various example configurations are discussed in the EXAMPLE directory.
|
||||
Frequently asked questions are tackled in the FAQ file.
|
||||
|
||||
Plug
|
||||
====
|
||||
|
||||
I'm always interested in security-related job offers. I specialize in
|
||||
application security testing and am very very good at it.
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
#%PAM-1.0
|
||||
auth required /lib/security/pam_listfile.so item=user sense=deny file=/etc/ftpusers onerr=succeed
|
||||
auth required /lib/security/pam_pwdb.so shadow nullok
|
||||
auth required /lib/security/pam_unix.so shadow nullok
|
||||
auth required /lib/security/pam_shells.so
|
||||
account required /lib/security/pam_pwdb.so
|
||||
session required /lib/security/pam_pwdb.so
|
||||
account required /lib/security/pam_unix.so
|
||||
session required /lib/security/pam_unix.so
|
||||
|
15
features.c
15
features.c
@ -21,10 +21,19 @@ handle_feat(struct vsf_session* p_sess)
|
||||
vsf_cmdio_write_raw(p_sess, " AUTH SSL\r\n");
|
||||
vsf_cmdio_write_raw(p_sess, " AUTH TLS\r\n");
|
||||
}
|
||||
vsf_cmdio_write_raw(p_sess, " EPRT\r\n");
|
||||
vsf_cmdio_write_raw(p_sess, " EPSV\r\n");
|
||||
if (tunable_port_enable)
|
||||
{
|
||||
vsf_cmdio_write_raw(p_sess, " EPRT\r\n");
|
||||
}
|
||||
if (tunable_pasv_enable)
|
||||
{
|
||||
vsf_cmdio_write_raw(p_sess, " EPSV\r\n");
|
||||
}
|
||||
vsf_cmdio_write_raw(p_sess, " MDTM\r\n");
|
||||
vsf_cmdio_write_raw(p_sess, " PASV\r\n");
|
||||
if (tunable_pasv_enable)
|
||||
{
|
||||
vsf_cmdio_write_raw(p_sess, " PASV\r\n");
|
||||
}
|
||||
if (tunable_ssl_enable)
|
||||
{
|
||||
vsf_cmdio_write_raw(p_sess, " PBSZ\r\n");
|
||||
|
@ -55,7 +55,7 @@ vsf_sysutil_parse_ipv6(const struct mystr* p_str)
|
||||
}
|
||||
str_append_str(&s_ret, &s_rhs_ret);
|
||||
}
|
||||
return str_getbuf(&s_ret);
|
||||
return (const unsigned char*) str_getbuf(&s_ret);
|
||||
}
|
||||
|
||||
const unsigned char*
|
||||
|
4
main.c
4
main.c
@ -61,7 +61,9 @@ main(int argc, const char* argv[])
|
||||
/* Home directory */
|
||||
INIT_MYSTR,
|
||||
/* Secure connection state */
|
||||
0, 0, 0, 0, 0, 0, -1, -1
|
||||
0, 0, 0, 0, 0, 0, -1, -1,
|
||||
/* Login fails */
|
||||
0
|
||||
};
|
||||
int config_specified = 0;
|
||||
const char* p_config_name = VSFTP_DEFAULT_CONFIG;
|
||||
|
@ -125,6 +125,9 @@ parseconf_uint_array[] =
|
||||
{ "file_open_mode", &tunable_file_open_mode },
|
||||
{ "max_per_ip", &tunable_max_per_ip },
|
||||
{ "trans_chunk_size", &tunable_trans_chunk_size },
|
||||
{ "delay_failed_login", &tunable_delay_failed_login },
|
||||
{ "delay_successful_login", &tunable_delay_successful_login },
|
||||
{ "max_login_fails", &tunable_max_login_fails },
|
||||
{ 0, 0 }
|
||||
};
|
||||
|
||||
|
13
postlogin.c
13
postlogin.c
@ -659,6 +659,10 @@ handle_retr(struct vsf_session* p_sess)
|
||||
vsf_cmdio_write(p_sess, FTP_FILEFAIL, "Failed to open file.");
|
||||
goto file_close_out;
|
||||
}
|
||||
/* Now deactive O_NONBLOCK, otherwise we have a problem on DMAPI filesystems
|
||||
* such as XFS DMAPI.
|
||||
*/
|
||||
vsf_sysutil_deactivate_noblock(opened_file);
|
||||
/* Optionally, we'll be paranoid and only serve publicly readable stuff */
|
||||
if (p_sess->is_anonymous && tunable_anon_world_readable_only &&
|
||||
!vsf_sysutil_statbuf_is_readable_other(s_p_statbuf))
|
||||
@ -942,6 +946,7 @@ handle_stor(struct vsf_session* p_sess)
|
||||
static void
|
||||
handle_upload_common(struct vsf_session* p_sess, int is_append, int is_unique)
|
||||
{
|
||||
static struct vsf_sysutil_statbuf* s_p_statbuf;
|
||||
static struct mystr s_filename;
|
||||
struct mystr* p_filename;
|
||||
struct vsf_transfer_ret trans_ret;
|
||||
@ -993,6 +998,14 @@ handle_upload_common(struct vsf_session* p_sess, int is_append, int is_unique)
|
||||
vsf_cmdio_write(p_sess, FTP_UPLOADFAIL, "Could not create file.");
|
||||
return;
|
||||
}
|
||||
vsf_sysutil_fstat(new_file_fd, &s_p_statbuf);
|
||||
if (vsf_sysutil_statbuf_is_regfile(s_p_statbuf))
|
||||
{
|
||||
/* Now deactive O_NONBLOCK, otherwise we have a problem on DMAPI filesystems
|
||||
* such as XFS DMAPI.
|
||||
*/
|
||||
vsf_sysutil_deactivate_noblock(new_file_fd);
|
||||
}
|
||||
/* Are we required to chown() this file for security? */
|
||||
if (p_sess->is_anonymous && tunable_chown_uploads)
|
||||
{
|
||||
|
10
prelogin.c
10
prelogin.c
@ -22,6 +22,7 @@
|
||||
#include "logging.h"
|
||||
#include "ssl.h"
|
||||
#include "features.h"
|
||||
#include "defs.h"
|
||||
|
||||
/* Functions used */
|
||||
static void emit_greeting(struct vsf_session* p_sess);
|
||||
@ -157,11 +158,6 @@ handle_user_command(struct vsf_session* p_sess)
|
||||
str_empty(&p_sess->user_str);
|
||||
return;
|
||||
}
|
||||
if (!tunable_anonymous_enable && is_anon)
|
||||
{
|
||||
vsf_cmdio_write(
|
||||
p_sess, FTP_LOGINERR, "This FTP server does not allow anonymous logins.");
|
||||
}
|
||||
if (is_anon && p_sess->control_use_ssl && !tunable_allow_anon_ssl &&
|
||||
!tunable_force_anon_logins_ssl)
|
||||
{
|
||||
@ -227,6 +223,10 @@ handle_pass_command(struct vsf_session* p_sess)
|
||||
vsf_two_process_login(p_sess, &p_sess->ftp_arg_str);
|
||||
}
|
||||
vsf_cmdio_write(p_sess, FTP_LOGINERR, "Login incorrect.");
|
||||
if (++p_sess->login_fails >= tunable_max_login_fails)
|
||||
{
|
||||
vsf_sysutil_exit(0);
|
||||
}
|
||||
str_empty(&p_sess->user_str);
|
||||
/* FALLTHRU if login fails */
|
||||
}
|
||||
|
12
privops.c
12
privops.c
@ -86,10 +86,18 @@ vsf_privop_do_login(struct vsf_session* p_sess,
|
||||
if (result == kVSFLoginFail)
|
||||
{
|
||||
vsf_log_do_log(p_sess, 0);
|
||||
if (tunable_delay_failed_login)
|
||||
{
|
||||
vsf_sysutil_sleep((double) tunable_delay_failed_login);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
vsf_log_do_log(p_sess, 1);
|
||||
if (tunable_delay_successful_login)
|
||||
{
|
||||
vsf_sysutil_sleep((double) tunable_delay_successful_login);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@ -145,6 +153,10 @@ handle_login(struct vsf_session* p_sess, const struct mystr* p_user_str,
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!tunable_local_enable)
|
||||
{
|
||||
die("unexpected local login in handle_login");
|
||||
}
|
||||
result = handle_local_login(p_sess, p_user_str, p_pass_str);
|
||||
}
|
||||
return result;
|
||||
|
@ -90,6 +90,7 @@ struct vsf_session
|
||||
int ssl_slave_active;
|
||||
int ssl_slave_fd;
|
||||
int ssl_consumer_fd;
|
||||
unsigned int login_fails;
|
||||
};
|
||||
|
||||
#endif /* VSF_SESSION_H */
|
||||
|
6
ssl.c
6
ssl.c
@ -71,8 +71,7 @@ ssl_init(struct vsf_session* p_sess)
|
||||
{
|
||||
p_key = tunable_rsa_cert_file;
|
||||
}
|
||||
if (SSL_CTX_use_certificate_file(
|
||||
p_ctx, tunable_rsa_cert_file, X509_FILETYPE_PEM) != 1)
|
||||
if (SSL_CTX_use_certificate_chain_file(p_ctx, tunable_rsa_cert_file) != 1)
|
||||
{
|
||||
die("SSL: cannot load RSA certificate");
|
||||
}
|
||||
@ -88,8 +87,7 @@ ssl_init(struct vsf_session* p_sess)
|
||||
{
|
||||
p_key = tunable_dsa_cert_file;
|
||||
}
|
||||
if (SSL_CTX_use_certificate_file(
|
||||
p_ctx, tunable_dsa_cert_file, X509_FILETYPE_PEM) != 1)
|
||||
if (SSL_CTX_use_certificate_chain_file(p_ctx, tunable_dsa_cert_file) != 1)
|
||||
{
|
||||
die("SSL: cannot load DSA certificate");
|
||||
}
|
||||
|
4
str.c
4
str.c
@ -436,6 +436,8 @@ str_locate_chars(const struct mystr* p_str, const char* p_chars)
|
||||
unsigned int num_chars = vsf_sysutil_strlen(p_chars);
|
||||
unsigned int i = 0;
|
||||
retval.found = 0;
|
||||
retval.char_found = 0;
|
||||
retval.index = 0;
|
||||
for (; i < p_str->len; ++i)
|
||||
{
|
||||
unsigned int j = 0;
|
||||
@ -461,6 +463,7 @@ str_locate_text(const struct mystr* p_str, const char* p_text)
|
||||
unsigned int i;
|
||||
unsigned int text_len = vsf_sysutil_strlen(p_text);
|
||||
retval.found = 0;
|
||||
retval.char_found = 0;
|
||||
retval.index = 0;
|
||||
if (text_len == 0 || text_len > p_str->len)
|
||||
{
|
||||
@ -487,6 +490,7 @@ str_locate_text_reverse(const struct mystr* p_str, const char* p_text)
|
||||
unsigned int i;
|
||||
unsigned int text_len = vsf_sysutil_strlen(p_text);
|
||||
retval.found = 0;
|
||||
retval.char_found = 0;
|
||||
retval.index = 0;
|
||||
if (text_len == 0 || text_len > p_str->len)
|
||||
{
|
||||
|
35
sysdeputil.c
35
sysdeputil.c
@ -201,9 +201,11 @@ static int do_sendfile(const int out_fd, const int in_fd,
|
||||
unsigned int num_send, filesize_t start_pos);
|
||||
static void vsf_sysutil_setproctitle_internal(const char* p_text);
|
||||
static struct mystr s_proctitle_prefix_str;
|
||||
static void vsf_insert_uwtmp(const struct mystr* p_user_str,
|
||||
const struct mystr* p_host_str);
|
||||
static void vsf_remove_uwtmp(void);
|
||||
|
||||
/* These two aren't static to avoid OpenBSD build warnings. */
|
||||
void vsf_insert_uwtmp(const struct mystr* p_user_str,
|
||||
const struct mystr* p_host_str);
|
||||
void vsf_remove_uwtmp(void);
|
||||
|
||||
#ifndef VSF_SYSDEP_HAVE_PAM
|
||||
int
|
||||
@ -310,6 +312,24 @@ vsf_sysdep_check_auth(const struct mystr* p_user_str,
|
||||
s_pamh = 0;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
#ifdef PAM_TTY
|
||||
retval = pam_set_item(s_pamh, PAM_TTY, "ftp");
|
||||
if (retval != PAM_SUCCESS)
|
||||
{
|
||||
(void) pam_end(s_pamh, 0);
|
||||
s_pamh = 0;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
#ifdef PAM_RUSER
|
||||
retval = pam_set_item(s_pamh, PAM_RUSER, str_getbuf(p_user_str));
|
||||
if (retval != PAM_SUCCESS)
|
||||
{
|
||||
(void) pam_end(s_pamh, 0);
|
||||
s_pamh = 0;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
retval = pam_authenticate(s_pamh, 0);
|
||||
if (retval != PAM_SUCCESS)
|
||||
@ -625,6 +645,7 @@ static int do_sendfile(const int out_fd, const int in_fd,
|
||||
int retval;
|
||||
enum EVSFSysUtilError error;
|
||||
(void) start_pos;
|
||||
(void) error;
|
||||
#if defined(VSF_SYSDEP_HAVE_LINUX_SENDFILE) || \
|
||||
defined(VSF_SYSDEP_HAVE_FREEBSD_SENDFILE) || \
|
||||
defined(VSF_SYSDEP_HAVE_HPUX_SENDFILE) || \
|
||||
@ -1087,7 +1108,7 @@ vsf_sysutil_recv_fd(int sock_fd)
|
||||
|
||||
#ifndef VSF_SYSDEP_HAVE_UTMPX
|
||||
|
||||
static void
|
||||
void
|
||||
vsf_insert_uwtmp(const struct mystr* p_user_str,
|
||||
const struct mystr* p_host_str)
|
||||
{
|
||||
@ -1095,7 +1116,7 @@ vsf_insert_uwtmp(const struct mystr* p_user_str,
|
||||
(void) p_host_str;
|
||||
}
|
||||
|
||||
static void
|
||||
void
|
||||
vsf_remove_uwtmp(void)
|
||||
{
|
||||
}
|
||||
@ -1107,7 +1128,7 @@ vsf_remove_uwtmp(void)
|
||||
static int s_uwtmp_inserted;
|
||||
static struct utmpx s_utent;
|
||||
|
||||
static void
|
||||
void
|
||||
vsf_insert_uwtmp(const struct mystr* p_user_str,
|
||||
const struct mystr* p_host_str)
|
||||
{
|
||||
@ -1147,7 +1168,7 @@ vsf_insert_uwtmp(const struct mystr* p_user_str,
|
||||
updwtmpx(WTMPX_FILE, &s_utent);
|
||||
}
|
||||
|
||||
static void
|
||||
void
|
||||
vsf_remove_uwtmp(void)
|
||||
{
|
||||
if (!s_uwtmp_inserted)
|
||||
|
74
sysutil.c
74
sysutil.c
@ -1740,7 +1740,7 @@ vsf_sysutil_connect_timeout(int fd, const struct vsf_sysutil_sockaddr* p_addr,
|
||||
}
|
||||
else
|
||||
{
|
||||
int socklen = sizeof(retval);
|
||||
socklen_t socklen = sizeof(retval);
|
||||
int sockoptret = getsockopt(fd, SOL_SOCKET, SO_ERROR, &retval, &socklen);
|
||||
if (sockoptret != 0)
|
||||
{
|
||||
@ -2415,34 +2415,6 @@ vsf_sysutil_chroot(const char* p_root_path)
|
||||
{
|
||||
die("chroot");
|
||||
}
|
||||
/* Set our timezone in the TZ environment variable to cater for the fact
|
||||
* that modern glibc does not cache /etc/localtime (which is of course now
|
||||
* inaccessible).
|
||||
*/
|
||||
if (s_timezone)
|
||||
{
|
||||
char envtz[sizeof("UTC-hh:mm:ss")];
|
||||
int hour, min, sec;
|
||||
|
||||
hour = s_timezone;
|
||||
if (hour < 0)
|
||||
{
|
||||
hour = -hour;
|
||||
}
|
||||
if (hour < 25*60*60)
|
||||
{
|
||||
sec = hour % 60;
|
||||
hour /= 60;
|
||||
min = hour % 60;
|
||||
hour /= 60;
|
||||
if (s_timezone < 0)
|
||||
{
|
||||
hour = -hour;
|
||||
}
|
||||
snprintf(envtz, sizeof(envtz), "UTC%+d:%d:%d", hour, min, sec);
|
||||
setenv("TZ", envtz, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unsigned int
|
||||
@ -2473,12 +2445,50 @@ vsf_sysutil_make_session_leader(void)
|
||||
void
|
||||
vsf_sysutil_tzset(void)
|
||||
{
|
||||
time_t the_time = 0;
|
||||
int retval;
|
||||
char tzbuf[sizeof("+HHMM!")];
|
||||
time_t the_time = time(NULL);
|
||||
struct tm* p_tm;
|
||||
tzset();
|
||||
the_time = time(NULL);
|
||||
p_tm = localtime(&the_time);
|
||||
s_timezone = -p_tm->tm_gmtoff;
|
||||
if (p_tm == NULL)
|
||||
{
|
||||
die("localtime");
|
||||
}
|
||||
/* Set our timezone in the TZ environment variable to cater for the fact
|
||||
* that modern glibc does not cache /etc/localtime (which becomes inaccessible
|
||||
* when we chroot().
|
||||
*/
|
||||
retval = strftime(tzbuf, sizeof(tzbuf), "%z", p_tm);
|
||||
tzbuf[sizeof(tzbuf) - 1] = '\0';
|
||||
if (retval == 5)
|
||||
{
|
||||
/* Static because putenv() does not copy the string. */
|
||||
static char envtz[sizeof("TZ=UTC-hh:mm")];
|
||||
/* Insert a colon so we have e.g. -05:00 instead of -0500 */
|
||||
tzbuf[5] = tzbuf[4];
|
||||
tzbuf[4] = tzbuf[3];
|
||||
tzbuf[3] = ':';
|
||||
/* Invert the sign - we just got the offset _from_ UTC but for TZ, we need
|
||||
* the offset _to_ UTC.
|
||||
*/
|
||||
if (tzbuf[0] == '+')
|
||||
{
|
||||
tzbuf[0] = '-';
|
||||
}
|
||||
else
|
||||
{
|
||||
tzbuf[0] = '+';
|
||||
}
|
||||
snprintf(envtz, sizeof(envtz), "TZ=UTC%s", tzbuf);
|
||||
putenv(envtz);
|
||||
s_timezone = ((tzbuf[1] - '0') * 10 + (tzbuf[2] - '0')) * 60 * 60;
|
||||
s_timezone += ((tzbuf[4] - '0') * 10 + (tzbuf[5] - '0')) * 60;
|
||||
if (tzbuf[0] == '-')
|
||||
{
|
||||
s_timezone *= -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const char*
|
||||
|
@ -91,6 +91,9 @@ unsigned int tunable_max_clients = 0;
|
||||
unsigned int tunable_file_open_mode = 0666;
|
||||
unsigned int tunable_max_per_ip = 0;
|
||||
unsigned int tunable_trans_chunk_size = 0;
|
||||
unsigned int tunable_delay_failed_login = 1;
|
||||
unsigned int tunable_delay_successful_login = 0;
|
||||
unsigned int tunable_max_login_fails = 3;
|
||||
|
||||
const char* tunable_secure_chroot_dir = "/usr/share/empty";
|
||||
const char* tunable_ftp_username = "ftp";
|
||||
|
@ -85,6 +85,9 @@ extern unsigned int tunable_max_clients;
|
||||
extern unsigned int tunable_file_open_mode;
|
||||
extern unsigned int tunable_max_per_ip;
|
||||
extern unsigned int tunable_trans_chunk_size;
|
||||
extern unsigned int tunable_delay_failed_login;
|
||||
extern unsigned int tunable_delay_successful_login;
|
||||
extern unsigned int tunable_max_login_fails;
|
||||
|
||||
/* String defines */
|
||||
extern const char* tunable_secure_chroot_dir;
|
||||
|
@ -63,7 +63,9 @@ If set to YES, anonymous users will be permitted to upload files under certain
|
||||
conditions. For this to work, the option
|
||||
.BR write_enable
|
||||
must be activated, and the anonymous ftp user must have write permission on
|
||||
desired upload locations.
|
||||
desired upload locations. This setting is also required for virtual users to
|
||||
upload; by default, virtual users are treated with anonymous (i.e. maximally
|
||||
restricted) privilege.
|
||||
|
||||
Default: NO
|
||||
.TP
|
||||
@ -268,7 +270,9 @@ Default: NO
|
||||
.TP
|
||||
.B local_enable
|
||||
Controls whether local logins are permitted or not. If enabled, normal
|
||||
user accounts in /etc/passwd may be used to log in.
|
||||
user accounts in /etc/passwd (or wherever your PAM config references) may be
|
||||
used to log in. This must be enable for any non-anonymous login to work,
|
||||
including virtual users.
|
||||
|
||||
Default: NO
|
||||
.TP
|
||||
@ -584,6 +588,16 @@ client is kicked off.
|
||||
|
||||
Default: 300
|
||||
.TP
|
||||
.B delay_failed_logins
|
||||
The number of seconds to pause prior to reporting a failed login.
|
||||
|
||||
Default: 1
|
||||
.TP
|
||||
.B delay_successful_logins
|
||||
The number of seconds to pause prior to allowing a successful login.
|
||||
|
||||
Default: 0
|
||||
.TP
|
||||
.B file_open_mode
|
||||
The permissions with which uploaded files are created. Umasks are applied
|
||||
on top of this value. You may wish to change to 0777 if you want uploaded
|
||||
@ -631,6 +645,11 @@ may be connected. Any additional clients connecting will get an error message.
|
||||
|
||||
Default: 0 (unlimited)
|
||||
.TP
|
||||
.B max_login_fails
|
||||
After this many login failures, the session is killed.
|
||||
|
||||
Default: 3
|
||||
.TP
|
||||
.B max_per_ip
|
||||
If vsftpd is in standalone mode, this is the maximum number of clients which
|
||||
may be connected from the same source internet address. A client will get an
|
||||
|
@ -1,7 +1,7 @@
|
||||
#ifndef VSF_VERSION_H
|
||||
#define VSF_VERSION_H
|
||||
|
||||
#define VSF_VERSION "2.0.4"
|
||||
#define VSF_VERSION "2.0.5"
|
||||
|
||||
#endif /* VSF_VERSION_H */
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user