X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=server-src%2Famidxtaped.pl;fp=server-src%2Famidxtaped.pl;h=ea22fc28e9f88e564f22fca30f1c73be6f4bc69d;hb=b116e9366c7b2ea2c2eb53b0a13df4090e176235;hp=43648dcc0d13f44d1c6bd44020eb8149ffc07cff;hpb=fd48f3e498442f0cbff5f3606c7c403d0566150e;p=debian%2Famanda diff --git a/server-src/amidxtaped.pl b/server-src/amidxtaped.pl index 43648dc..ea22fc2 100644 --- a/server-src/amidxtaped.pl +++ b/server-src/amidxtaped.pl @@ -108,44 +108,6 @@ sub user_request { }; }; -## -# Clerk Feedback class - -package main::Feedback; -use Amanda::Recovery::Clerk; -use Amanda::Util qw( weaken_ref ); -use base 'Amanda::Recovery::Clerk::Feedback'; - -sub new { - my $class = shift; - my %params = @_; - - my $self = bless { - clientservice => $params{'clientservice'} - }, $class; - - # (weak ref here to eliminate reference loop) - weaken_ref($self->{'clientservice'}); - - return $self; -} - -sub part_notif { - my $self = shift; - - my ($label, $filenum, $hdr) = @_; - $self->{'clientservice'}->sendmessage("restoring part $hdr->{'partnum'} " . - "from '$label' file $filenum"); -} - -sub holding_notif { - my $self = shift; - - my ($holding_file, $hdr) = @_; - $self->{'clientservice'}->sendmessage("restoring from holding " . - "file $holding_file"); -} - ## # ClientService class @@ -164,6 +126,8 @@ use Amanda::Recovery::Clerk; use Amanda::Recovery::Planner; use Amanda::Recovery::Scan; use Amanda::DB::Catalog; +use Amanda::Disklist; +use Amanda::Logfile qw( match_disk match_host ); # Note that this class performs its control IO synchronously. This is adequate # for this service, as it never receives unsolicited input from the remote @@ -266,13 +230,22 @@ sub read_command { $self->{'their_features'} = Amanda::Feature::Set->from_string($command->{'FEATURES'}); } - if ($command->{'CONFIG'}) { - config_init($CONFIG_INIT_EXPLICIT_NAME, $command->{'CONFIG'}); - my ($cfgerr_level, @cfgerr_errors) = config_errors(); - if ($cfgerr_level >= $CFGERR_ERRORS) { - die "configuration errors; aborting connection"; - } - Amanda::Util::finish_setup($RUNNING_AS_DUMPUSER_PREFERRED); + # load the configuration + if (!$command->{'CONFIG'}) { + die "no CONFIG line given"; + } + config_init($CONFIG_INIT_EXPLICIT_NAME, $command->{'CONFIG'}); + my ($cfgerr_level, @cfgerr_errors) = config_errors(); + if ($cfgerr_level >= $CFGERR_ERRORS) { + die "configuration errors; aborting connection"; + } + Amanda::Util::finish_setup($RUNNING_AS_DUMPUSER_PREFERRED); + + # and the disklist + my $diskfile = Amanda::Config::config_dir_relative(getconf($CNF_DISKFILE)); + $cfgerr_level = Amanda::Disklist::read_disklist('filename' => $diskfile); + if ($cfgerr_level >= $CFGERR_ERRORS) { + die "Errors processing disklist"; } $self->setup_data_stream(); @@ -334,7 +307,8 @@ sub make_plan { $self->{'command'}{'HOST'}, $disk, $self->{'command'}{'DATESTAMP'}, - undef); # amidxtaped protocol does not provide a level (!?) + undef, # amidxtaped protocol does not provide a level (!?) + undef); # amidxtaped protocol does not provide a write timestamp } # figure out if this is a holding-disk recovery @@ -382,7 +356,8 @@ sub make_plan { $scan->{'scan_conf'}->{'notfound'} = Amanda::Recovery::Scan::SCAN_ASK; $self->{'clerk'} = Amanda::Recovery::Clerk->new( - feedback => main::Feedback->new($chg, undef), + # note that we don't have any use for clerk_notif's, so we don't pass + # a feedback object scan => $scan); if ($is_holding) { @@ -438,6 +413,51 @@ sub plan_cb { return $self->quit(); } + # check that the request-limit for this DLE allows this recovery. because + # of the bass-ackward way that amrecover specifies the dump to us, we can't + # check the results until *after* the plan was created. + my $dump = $plan->{'dumps'}->[0]; + my $dle = Amanda::Disklist::get_disk($dump->{'hostname'}, $dump->{'diskname'}); + my $recovery_limit; + if ($dle && dumptype_seen($dle->{'config'}, $DUMPTYPE_RECOVERY_LIMIT)) { + debug("using DLE recovery limit"); + $recovery_limit = dumptype_getconf($dle->{'config'}, $DUMPTYPE_RECOVERY_LIMIT); + } elsif (getconf_seen($CNF_RECOVERY_LIMIT)) { + debug("using global recovery limit as default"); + $recovery_limit = getconf($CNF_RECOVERY_LIMIT); + } + my $peer = $ENV{'AMANDA_AUTHENTICATED_PEER'}; + if (defined $recovery_limit) { # undef -> no recovery limit + if (!$peer) { + warning("a recovery limit is specified for this DLE, but no authenticted ". + "peer name is available; rejecting request."); + $self->sendmessage("No matching dumps found"); + return $self->quit(); + } + my $matched = 0; + for my $rl (@$recovery_limit) { + if (!defined $rl) { + # handle same-host with a case-insensitive string compare, not match_host + if (lc($peer) eq lc($dump->{'hostname'})) { + $matched = 1; + last; + } + } + + # otherwise use match_host to allow match expressions + if (match_host($rl, $peer)) { + $matched = 1; + last; + } + } + if (!$matched) { + warning("authenticated peer '$peer' did not match recovery-limit ". + "config; rejecting request"); + $self->sendmessage("No matching dumps found"); + return $self->quit(); + } + } + if (!$self->{'their_features'}->has($Amanda::Feature::fe_recover_splits)) { # if we have greater than one volume, we may need to prompt for a new # volume in mid-recovery. Sadly, we have no way to inform the client of @@ -476,11 +496,11 @@ sub xfer_src_cb { if ($header->{'srv_encrypt'}) { push @filters, Amanda::Xfer::Filter::Process->new( - [ $header->{'srv_encrypt'}, $header->{'srv_decrypt_opt'} ], 0); + [ $header->{'srv_encrypt'}, $header->{'srv_decrypt_opt'} ], 0, 1); } elsif ($header->{'clnt_encrypt'}) { push @filters, Amanda::Xfer::Filter::Process->new( - [ $header->{'clnt_encrypt'}, $header->{'clnt_decrypt_opt'} ], 0); + [ $header->{'clnt_encrypt'}, $header->{'clnt_decrypt_opt'} ], 0, 1); } else { $self->sendmessage("could not decrypt encrypted dump: no program specified"); return $self->quit(); @@ -502,17 +522,17 @@ sub xfer_src_cb { # TODO: this assumes that srvcompprog takes "-d" to decrypt push @filters, Amanda::Xfer::Filter::Process->new( - [ $header->{'srvcompprog'}, "-d" ], 0); + [ $header->{'srvcompprog'}, "-d" ], 0, 1); } elsif ($header->{'clntcompprog'}) { # TODO: this assumes that clntcompprog takes "-d" to decrypt push @filters, Amanda::Xfer::Filter::Process->new( - [ $header->{'clntcompprog'}, "-d" ], 0); + [ $header->{'clntcompprog'}, "-d" ], 0, 1); } else { push @filters, Amanda::Xfer::Filter::Process->new( [ $Amanda::Constants::UNCOMPRESS_PATH, - $Amanda::Constants::UNCOMPRESS_OPT ], 0); + $Amanda::Constants::UNCOMPRESS_OPT ], 0, 1); } # adjust the header