Subject: | PATCH: Better control of Anonymous, chroot to non-homedirs |
Two items: first, there is a bug in the Full server in the way it
handles root directories: you cannot chroot a real user with a real home
directory to anywhere other than their home directory because their real
home directory overrides the configuration directive. Second, there
are situations where you don't want the anonymous ftp user to be the
user 'ftp' using ftp's home directory. In particular, with virtual
hosts it's often handy to have the anonymous user be somebody else and
chroot'ed to somewhere else.
My new configuration directives are:
anonymous user: specifies which user anonymous logins become
anonymous root: specifies the chroot directory for anonymous logins
I made a "patch" to fix these... My patch is a subclass of
Full::Server. To take my changes, simply replace Full::Server's
user_login_hook() with my version.
Subject: | Anon.pm |
package Net::FTPServer::Full::Server::Anon;
use strict;
use Net::FTPServer::Full::Server;
our @ISA = qw(Net::FTPServer::Full::Server);
our $VERSION = 1.0;
sub user_login_hook
{
my $self = shift;
my $user = shift;
my $user_is_anon = shift;
my ($login, $pass, $uid, $gid, $quota, $comment, $gecos, $homedir);
if (! $user_is_anon)
{
# Saved real Unix user (from the "password file" option)?
$user = $self->{full_unix_user} if exists $self->{full_unix_user};
($login, $pass, $uid, $gid) = getpwnam $user
or die "no user $user in password file";
# Chroot for this non-anonymous user? If using the "password file"
# option then we might have saved a root directory above.
my $root_directory = $self->config ("root directory")
|| $self->{full_root_directory}
|| undef;
if (defined $root_directory)
{
$root_directory =~ s/%m/(getpwnam $user)[7]/ge;
$root_directory =~ s/%U/$user/ge;
$root_directory =~ s/%%/%/g;
chroot $root_directory
or die "cannot chroot: $root_directory: $!";
}
}
else
{
my $getpwfunc = sub { getpwnam($_[0]) };
my $anonuser = $self->config("anonymous user") || 'ftp';
$getpwfunc = sub { getpwuid($_[0]) } if $anonuser =~ /^\d+$/;
($login, $pass, $uid, $gid, $quota, $comment, $gecos, $homedir)
= &$getpwfunc($anonuser)
or die "no $anonuser user in password file";
my $home = $self->config("anonymous root") || $homedir;
chroot $home or die "cannot chroot: $home: $!";
}
$self->_drop_privs ($uid, $gid, $login);
}
1;