maxfilesize set the maximum size of uploaded files
sanenames if set, only permit uploaded filenames that contain
characters from the set "-+,._A-Za-z0-9" and that
don't start with `.'
- new/changed command line options:
-e emailaddr define email address for %E (see below)
-P dataport use dataport as the dataport (instead of ctrlport-1)
-q use pid files to count users [default]
-Q don't use pid files to count users
-u write entries to utmp
-U don't write entries to utmp [default]
-w write entries to wtmp [default]
-W don't write entries to wtmp
NOTE: -U used to mean `write utmp entries'. Its meaning has changed
so that it's orthogonal with -q/-Q and -w/-W. This isn't
considered a major problem, because using -U isn't going to
enable something you don't want, but will disable something
you did want (which is safer).
- new display file escape sequences:
%E email address
%s literal `s' if the previous %M or %N wasn't ``1''.
%S literal `S' if the previous %M or %N wasn't ``1''.
- expand the description of building ~ftp/incoming to cover the
appropriate ftpd.conf(5) directives (which are defaults, but it pays
to explicitly explain them)
- replace strsuftoi() with strsuftoll(), which returns a long long if
supported, otherwise a long
- rework the way that check_modify and check_upload are done in the yacc
parser; they're merged into a common check_write() function which is
called explicitly
- merge all ftpclass `flag variables' into a single bitfield-based flag element
- move various common bits of parse_conf() into a couple of macros
- clean up some comments
* replace union sockunion {} with struct sockinet {}, and modify the code
accordingly. this is possibly more portable, as it doesn't rely upon
the structure alignment within the union for our own stuff. uses local
su_len unless HAVE_SOCKADDR_SA_LEN is defined (set ifdef BSD4_4)
(XXX: haven't tested the ipv6 stuff)
* always use getaddrinfo() and getnameinfo() instead of maintaining two code
paths. (lukemftpd will provide replacements for these on older systems)
* use lockf() instead of open(.., O_EXLOCK) to lock the pid file
* minor KNF
* clean up long long support: create helper #defines and use as appropriate:
#define NO_LONG_LONG ! NO_LONG_LONG
------- ------------ --------------
LLF "%ld" "%lld"
LLFP(x) "%" x "ld" "%" x "lld"
LLT long long long
ULLF "%lu" "%llu"
ULLFP(x) "%" x "lu" "%" x "llu"
ULLT unsigned long unsigned long long
STRTOLL(x,y,z) strtol(x,y,z) strtoll(x,y,z)
return 522 on unknown protocol identifier on EPRT.
- clarify EPSV/EPRT/LPSV/LPRT behavior.
- repair memory leak and lack of boundary check on EPRT.
- make sure we do not resolve DNS on EPRT.
sync with kame.
This ftpd now compiles and runs on NetBSD/1.4.2 with:
CPPFLAGS+= \
'-Dstrlcpy(a,b,c)=(strncpy(a,b,c),strlen(a))' \
'-Dstrlcat=strncat' \
'-Dsl_add(a,b)=(sl_add(a,b),0)'
prevents the ftp bounce attack, and we should be secure out of the
box, not require users to tweak obscure stuff.
* allow the version string reported to clients to be changed with '-V vers'.
if vers is empty or `-', don't report a version.
* if -r is given, permanently drop root privs
* if not a REAL user (i.e, GUEST or CHROOT), and ftpd is running on a port
> IPPORT_RESERVED+1, permanently drop root privs
* don't bother reverting to root privs to logout of wtmp/utmp; since the
file descriptor is already open this isn't necessary.
* fix the binding of the port for the PORT/LPRT/EPRT connection to be the
ctrl_addr.su_port-1, not hardcoded to `20' (this was broken in the ipv6
merge). if root privs have been dropped, and this would be a port <
IPPORT_RESERVED, use a random port instead (which isn't RFC959 compliant
but it doesn't appear that many clients care).
* prevent login of a new user if privs have been dropped and already logged
in as a REAL user (existing check already stops GUEST & CHROOT users).
* move the port check stuff into a separate port_check() function, and use
for PORT, LPRT, and EPRT checks. inspired by freebsd
* minor KNF
* minor man page cleanup
chroot specify dir to chroot to for GUEST and CHROOT users, to
override -a anondir or the user's homedir.
homedir specify dir to change to upon login; also used for ~ expansion
and $HOME for subprocesses)
both of these can take % escapes: %u (username), %d (homedir), %c (class).
* fix NLST to take a pathname not a STRING, so that ~ expansion works
* modify CWD to use the homedir parsed from curclass.homedir
* implement format_path(dst, src), to parse src expanding % escapes (see above)
into dst.
* rename format_file() to display_file()
* fix RATE{GET,PUT} under some situations when the client is slower than
the server (something i missed when migrating the rate limiting code
i wrote in ftp(1) to ftpd(8))
* document what units RATE{GET,PUT} use
* implement closedataconn() and use appropriately (including in mlsd())
* only put leading space in front of MLST output (not MLSD output)
* MLSD: only output pdir and cdir entries when the type fact is requested.
* change error code for giving MLSD a non-directory from 550 to 501
* remove MLSx Type fact support for UNIX.* for now; it's not standardised yet.
* do a check_login when MLSD and MLST are given no args
* detect & complain about null facts in OPTS MLST
* cache getgroups() at login instead of calling each time in fact_perm()
other mods:
* implement cprintf(); as per fprintf() but increments total_bytes{,_out}
* implement CPUTC(); as per putc() but increments total_bytes{,_out}
* implement base64_encode()
* fact_unique() display base64 encoding of dev_t and ino_t rather than
hex output; should scale if size of those changes
* change reply() so that a negative code acts as the initial line in a reply,
code == 0 prefixes the line with 4 spaces, and code > 0 works as before.
deprecate lreply(code, ) and lreply(0, ) in favour of reply(-code, ) and
reply(0, ) respectively.
* use cprintf() and CPUTC() appropriately (often instead of printf(),
lreply(-2, ) or lreply(-1, ).
now we actually account for the data sent by MLST and MLSD.
* remove DEBUG support for sending MLSD output to control connection instead
of data connection (my ftp client now supports MLSD :-)
* implement draft-ietf-ftpext-mlst-10 commands, especially MLST and MLSD.
we already supported SIZE and MDTM. add the appropriate FEAT output lines.
* migrate a lot of the command code from ftpcmd.y and ftpd.c to cmds.c
* make dataconn(), feat(), lookup(), opts() and sizecmd() public
* modify struct tab so that it has a `flags' instead of `implemented' element,
and remove the `hasopts' element. If flags == 1, the command is implemented.
if flags == 2, the command is implemented and takes options
* add macros ISDOTDIR(x) (is x ".") and ISDOTDOTDIR(x) (is x "..")
* modify lreply() so that lreply(-2, ...) just outputs the given info without
a prefix or trailing \r\n. this saves doing b = printf(); total_* += b;
* enhance statcmd(). still needs work in the LPRT status stuff.
* crank version
Problem noted in [bin/9642] by Takahiro Kambe <taca@sky.yamashina.kyoto.jp>,
(part of which already had been solved by itojun a while ago), and provided
patch covered most of the fixes needed. (Thanks Takahiro!)
- Consistently indent goto labels by one space.
of the port range used by passive connections. based on work in [bin/9158]
from Takahiro Kambe <taca@sky.yamashina.kyoto.jp>
* change the way global variables are defined and extern-ed to be more
consistent.
* add connection limits (`limit' keyword in ftpd.conf)
* move initialisation of curclass from parse_conf() to new function
init_curclass()
* implement count_users(), which determines the number of users in a given
class. a file - /var/run/ftpd.pids-<class> - is used to store a list
of pids in use (effectively an array of pid_t's), and its size is reduced
as necessary.
* new % modifiers in format_file:
%c class
%M maximum connection count
%N current connection count
* always end_login()s, even for refused connections
bugs fixed:
* remove \n from %T output
* fix some inconsistencies in the man pages
* ensure that both `ftp' *and* `anonymous' are allowed in ftpusers.
(this was accidently broken in a recent commit to be ``or'' not ``and'')
* use MAXPATHLEN not MAXPATHLEN+1
* crank copyright date on modified files
* crank version
the name advertised to the client, even if ftpd can determine it from
the ip address that ftpd is bound to. requested by mrg.
* remove -4/-6; they were effectively no-ops since itojun's change in 1.75.
* crank version
* use .Dv and .Tn in the man pages as appropriate
* KNF a bit
The following were inspired by similar changes in openbsd, but may
have additional improvements by me:
* add more check_login tests to the parser rules
* nuke a few memory leaks in the parser rules
* clear passwords before free()ing them, for safety
* don't display \r\n in setproctitle() output
* add support for -U, which enables managing /var/run/utmp entries for
connections. solves [bin/2217] by Jason Downs <downsj@teeny.org>
* fix oob handling for STAT command
* use SIG_ERR instead of -1
as (useful for virtual ftp servers in conjunction with inetd.conf(5)'s
ability to bind to a specific address).
if this option is used, add `hostname' to the syslog messages.
* improve documentation of command-line options
* don't allow class names of `all' or `none' in ftpusers
userglob [allow|deny]
to
userglob[@host] [allow|deny [classname]]
where class is a userdefined classname.
- if host is given it may either be a CIDR address (e.g, `1.2.3.0/24') or a
hostglob (e.g, `*.foo.com'), and the remote host is matched against that.
- if classname is given, use that to match entries in ftpd.conf (defaults
to `guest' for `anonymous'/`ftp' logins, `chroot' for users found in
/etc/ftpchroot, and `real' for everyone else.
* implement new /etc/ftpd.conf directives:
classtype classname type set type of classname to GUEST, CHROOT, or REAL
motd classname file file to use instead of /etc/motd
rateget classname rate set rateget throttle to rate
rateput classname rate set rateput throttle to rate
upload classname allow/deny uploads (STOU, STOR, APPE). if
denied, also acts as `modify deny'.
* implement new `SITE' commands:
RATEGET as per /etc/ftpd.conf rateget, but cannot exceed that
RATEPUT as per /etc/ftpd.conf rateput, but cannot exceed that
* implement format_file(), which outputs a file to the user, parsing %
escapes. use to print /etc/ftpwelcome, /etc/motd, and the `display' file.
* implement strsuftoi() (from ftp(1)), which parses a number and
optional suffix (for use with rateget, etc)
* don't bother seteuid(0) ; bind(...) ; seteuid(pw->pw_uid), since
we don't need reserved ports (at wasn't getting them anyway).
* update & reorder copyrights
* use strlcpy() as appropriate
the string tokenisation must be performed by the caller (which is
generally easy because it's almost always a static command).
* change do_conversion() to return a char *argv[] instead of char *cmd.
tokenisation of the command is done internally.
* change retrieve() to take char *argv[] instead of char *cmd.
(to take advantage of the above changes). fixes [bin/8173]
* use fparseln() instead of fgetln()
* store conversions in listed order (rather than reverse order)
* use stringlists instead of handrolling code to manage an argv.