?
package Cpanel::RestoreManager;
our $VERSION = '1.0.1';
use strict;
use POSIX qw( strftime );
use File::Glob qw( bsd_glob );
use Data::Dumper qw(Dumper);
use Cpanel::LiveAPI ();
use Data::Dumper ();
use Cpanel::Wrap ();
use Cpanel::AdminBin::Serializer ();
use Cpanel::Postgres ();
use Cpanel::MysqlFE::DB ();
use Cpanel::Encoder::Tiny ();
use Cpanel::AdminBin ();
use Cpanel::CachedCommand::Utils ();
use Cpanel::Email ();
use Cpanel::Version::Tiny;
use Cpanel::API ();
use Cpanel::API::Email ();
sub api2 {
my ($func) = @_;
my $api_ref = _get_api2_ref();
return $api_ref->{$func};
}
sub _get_api2_ref {
my $api_ref = {
'remconf' => {},
'showedbackupsconf' => {},
'excludeconf' => {},
'sendtolog' => {},
'browse' => {},
'backupmode' => {},
'getremtrash' => {},
'getremtrashstatus' => {},
'restorefromremtrash' => {},
'emptyremtrash' => {},
'fileinfo' => {},
'restore' => {},
'restoredb' => {},
'localrestore' => {},
'localrestoredb' => {},
'fixownership' => {},
'fixaddonownership' => {},
'fixemailownership' => {},
'restorefullaccount' => {},
};
return $api_ref;
}
sub api2_remconf {
my $getremconf = do_rem_api("remconf");
if ($getremconf->{'licensestatus'} ne 'Active') {
$Cpanel::CPERROR{'restoremanager'} = "License is not active";
} elsif ($getremconf->{'backupmode'} ne 'remote' && $getremconf->{'backupmode'} ne 'local') {
$Cpanel::CPERROR{'restoremanager'} = "Cannot detect backup mode";
}
return $getremconf;
}
sub api2_showedbackupsconf {
my $showedbackupsconf = do_rem_api("showedbackupsconf");
my $backupmode = do_rem_api("getbackupmode");
if ($backupmode ne 'local') {
$Cpanel::CPERROR{'restoremanager'} = "Backup mode is not local";
}
return {'allowbackups'=>$showedbackupsconf};
}
sub api2_excludeconf {
my $excludeconf = do_rem_api("excludeconf");
return $excludeconf;
}
sub api2_browse {
my %OPTS = @_;
my $browse;
if ($OPTS{'get'} eq 'homedir') {
$browse = do_rem_api("browse","$OPTS{'get'}:$OPTS{'path'}:$OPTS{'date'}");
} elsif ($OPTS{'get'} eq 'dates') {
$browse = do_rem_api("browse","$OPTS{'get'}:$OPTS{'type'}");
} elsif ($OPTS{'get'} eq 'dbs') {
$browse = do_rem_api("browse","$OPTS{'get'}:$OPTS{'date'}");
} else {
$Cpanel::CPERROR{'restoremanager'} = "Invalid get value";
return;
}
my $data = {
'browseresults' => $browse,
};
return $data;
}
sub api2_backupmode {
my $backupmode = do_rem_api("getbackupmode");
if ($backupmode ne 'remote' && $backupmode ne 'local') {
$Cpanel::CPERROR{'restoremanager'} = "Backup mode is not set";
}
my $data = {
'backupmode' => $backupmode,
};
return $data;
}
sub api2_fileinfo {
my %OPTS = @_;
my $newdate;
my $cpuser = $ENV{'USER'};
my $date = $OPTS{'date'};
my $cpmajor = $Cpanel::Version::Tiny::major_version;
if ($cpmajor >= 64) {
$newdate = "$date";
} else {
$newdate = "$date/accounts/$cpuser";
}
my $fileinfo = do_rem_api("fileinfo","$OPTS{'get'}:$newdate:$OPTS{'domain'}");
my $data = {
'fileinfo' => $fileinfo,
};
return $data;
}
sub api2_getremtrash {
my %OPTS = @_;
my @resfiles;
my @resfolders;
my $path;
my @excludeinpath = qw('../','./','//','/..');
if ($OPTS{'path'} ne '') {
my @excludefound = grep /$OPTS{'path'}/, @excludeinpath;
if (@excludefound) {
$Cpanel::CPERROR{'restoremanager'} = "Invalid Path";
return;
}
$path = "/$OPTS{'path'}";
}
my $fulldirpath = "$ENV{'HOME'}/.remtrash$path";
my $results = do_rem_api("remtrashbrowse","$fulldirpath");
return {'browseresults'=> $results};
}
sub api2_getremtrashstatus {
my %OPTS = @_;
my $fullpath = "$ENV{'HOME'}/.remtrash";
if (-d $fullpath) {
if (!folder_empty($fullpath)) {
return {'remtrashstatus' => "1"};
} else {
return {'remtrashstatus' => "0"};
}
} else {
return {'remtrashstatus' => "0"};
}
}
sub api2_restorefromremtrash {
my %OPTS = @_;
my $filepath = $OPTS{'filepath'};
my ($home, $des) = split /.remtrash/, $filepath;
if ("$ENV{'HOME'}/" ne $home) {
return {'restoreresults'=> 'ALERT', 'PATH'=> $home};
}
$des =~ s/^.//;
my $restorecommand = "mv -f $filepath $home$des";
my $results = do_rem_api("localrestore","$restorecommand:$ENV{'HOME'}:$des:$filepath");
return $results;
}
sub api2_emptyremtrash {
my $fullpath = "$ENV{'HOME'}/.remtrash";
my $removecommand = "rm -rf $fullpath";
my $removeresults = do_rem_api("localrestore","$removecommand:");
return $removeresults;
}
sub api2_restore {
my %OPTS = @_;
my $restoreresults = do_rem_api("restore","$OPTS{'get'}:$OPTS{'date'}");
return $restoreresults;
}
sub api2_restoredb {
my %OPTS = @_;
my $restoreresults;
my $date = $OPTS{'date'};
my $dbtype = $OPTS{'dbtype'};
my $dbname = $OPTS{'dbname'};
my $dbexistuser = $OPTS{'dbexistuser'};
if ($dbtype eq 'pdb') {
Cpanel::CachedCommand::Utils::destroy( 'name' => 'postgres-db-count' );
Cpanel::AdminBin::adminrun( 'postgres', "DELDB", $dbname );
Cpanel::AdminBin::adminrun( 'postgres', "ADDDB", $dbname );
$restoreresults = do_rem_api("restoredb","$date:$dbtype:$dbname");
if ($dbexistuser ne '') {
Cpanel::AdminBin::adminrun( 'postgres', "ADDUSERDB", $dbexistuser, $dbname );
}
Cpanel::AdminBin::adminrun( 'postgres', "UPDATEPRIVS" );
} elsif ($dbtype eq 'mdb') {
$restoreresults = do_rem_api("restoredb","$date:$dbtype:$dbname");
}
return {'restoreresults'=> $restoreresults};
}
sub api2_localrestore {
my %OPTS = @_;
my $command;
my $restoreresults;
my $fullpath;
my $strip;
my $newdate;
my $cpuserrootdir = $ENV{'HOME'};
my $cpuser = $ENV{'USER'};
my $itemtype = $OPTS{'itemtype'};
my $date = $OPTS{'date'};
my $source = $OPTS{'source'};
my $destination = $OPTS{'destination'};
my $domain = $OPTS{'domain'};
my $tmppass = $OPTS{'tmppass'};
my $backups_dir = do_rem_api("localbackupdir");
my $backuptype = do_rem_api("localbackuptype");
if ($backuptype eq 'incremental') {
my $cpmajor = $Cpanel::Version::Tiny::major_version;
if ($cpmajor >= 64) {
$newdate = "$date";
} else {
$newdate = "$date/accounts/$cpuser";
}
if ($itemtype eq 'dir') {
$command = "cp -rn $backups_dir/$newdate/homedir/$source $cpuserrootdir/$destination";
$restoreresults = do_rem_api("localrestore","$command:$cpuserrootdir:$source");
} elsif ($itemtype eq 'file') {
$command = "cp -f $backups_dir/$newdate/homedir/$source $cpuserrootdir/$destination";
$restoreresults = do_rem_api("localrestore","$command:$cpuserrootdir:$destination");
} elsif ($itemtype eq 'emaildir') {
$command = "cp -rn $backups_dir/$newdate/homedir/mail/$domain/$destination $cpuserrootdir/mail/$domain/";
$restoreresults = do_rem_api("localrestore","$command:$cpuserrootdir:mail/$domain/$destination");
} elsif ($itemtype eq 'ssldir') {
$command = "cp -r $backups_dir/$newdate/homedir/ssl $cpuserrootdir/";
$restoreresults = do_rem_api("localrestore","$command:$cpuserrootdir:ssl");
}
} elsif ($backuptype eq 'uncompressed') {
if ($itemtype eq 'dir' || $itemtype eq 'file') {
$fullpath = "$cpuser/homedir/$source";
$strip = ($fullpath) =~ tr!/!!;
$command = "tar xvf $backups_dir/$date --strip=$strip -C $cpuserrootdir/$destination $fullpath";
$restoreresults = do_rem_api("localrestore","$command:$cpuserrootdir:$destination");
} elsif ($itemtype eq 'emaildir') {
$fullpath = "$cpuser/homedir/mail/$domain/$destination";
$strip = ($fullpath) =~ tr!/!!;
$command = "tar xvf $backups_dir/$date --strip=$strip -C $cpuserrootdir/mail/$domain/ $fullpath";
$restoreresults = do_rem_api("localrestore","$command:$cpuserrootdir:mail/$domain");
} elsif ($itemtype eq 'ssldir') {
$fullpath = "$cpuser/homedir/ssl";
$strip = ($fullpath) =~ tr!/!!;
$command = "tar xvf $backups_dir/$date --strip=$strip -C $cpuserrootdir/ $fullpath";
$restoreresults = do_rem_api("localrestore","$command:$cpuserrootdir:ssl");
}
} elsif ($backuptype eq 'compressed') {
if ($itemtype eq 'dir' || $itemtype eq 'file') {
$fullpath = "$cpuser/homedir/$source";
$strip = ($fullpath) =~ tr!/!!;
$command = "tar -zxvf $backups_dir/$date --strip=$strip -C $cpuserrootdir/$destination $fullpath";
$restoreresults = do_rem_api("localrestore","$command:$cpuserrootdir:$destination");
} elsif ($itemtype eq 'emaildir') {
$fullpath = "$cpuser/homedir/mail/$domain/$destination";
$strip = ($fullpath) =~ tr!/!!;
$command = "tar -zxvf $backups_dir/$date --strip=$strip -C $cpuserrootdir/mail/$domain/ $fullpath";
$restoreresults = do_rem_api("localrestore","$command:$cpuserrootdir:mail/$domain");
} elsif ($itemtype eq 'ssldir') {
$fullpath = "$cpuser/homedir/ssl";
$strip = ($fullpath) =~ tr!/!!;
$command = "tar -zxvf $backups_dir/$date --strip=$strip -C $cpuserrootdir/ $fullpath";
$restoreresults = do_rem_api("localrestore","$command:$cpuserrootdir:ssl");
}
}
return $restoreresults;
}
sub api2_localrestoredb {
my %OPTS = @_;
my $restoreresults;
my $backuptype = do_rem_api("localbackuptype");
my $date = $OPTS{'date'};
my $dbtype = $OPTS{'dbtype'};
my $dbname = $OPTS{'dbname'};
my $dbexistuser = $OPTS{'dbexistuser'};
my $envcpuser = $ENV{'USER'};
my $mcpmajor = $Cpanel::Version::Tiny::major_version;
my $newdate;
if ($mcpmajor >= 64) {
$newdate = "$date";
} else {
$newdate = "$date/accounts/$envcpuser";
}
if ($dbtype eq 'pdb') {
Cpanel::CachedCommand::Utils::destroy( 'name' => 'postgres-db-count' );
Cpanel::AdminBin::adminrun( 'postgres', "DELDB", $dbname );
Cpanel::AdminBin::adminrun( 'postgres', "ADDDB", $dbname );
$restoreresults = do_rem_api("localrestoredb","$backuptype:$newdate:$dbtype:$dbname");
if ($dbexistuser ne '') {
Cpanel::AdminBin::adminrun( 'postgres', "ADDUSERDB", $dbexistuser, $dbname );
}
Cpanel::AdminBin::adminrun( 'postgres', "UPDATEPRIVS" );
} elsif ($dbtype eq 'mdb') {
$restoreresults = do_rem_api("localrestoredb","$backuptype:$newdate:$dbtype:$dbname");
}
return $restoreresults;
}
sub api2_sendtolog {
my %OPTS = @_;
my $cpuser = $OPTS{'cpuser'};
my $logline = $OPTS{'logline'};
my $envcpuser = $ENV{'USER'};
if ($envcpuser eq $cpuser) {
return do_rem_api("sendtolog","$logline");
} else {
return {'error'=>'Unauthorized user'};
}
}
sub api2_fixownership {
my %OPTS = @_;
my $homedir = $ENV{'HOME'};
my $url = $ENV{'REQUEST_URI'};
return do_rem_api("fixownership","$homedir:$url");
}
sub api2_fixaddonownership {
my %OPTS = @_;
my $domainrootdir = $OPTS{'domainrootdir'};
my $url = $ENV{'REQUEST_URI'};
return do_rem_api("fixaddonownership","$domainrootdir:$url");
}
sub api2_fixemailownership {
my %OPTS = @_;
my $homedir = $ENV{'HOME'};
my $url = $ENV{'REQUEST_URI'};
return do_rem_api("fixemailownership","$homedir:$url");
}
sub api2_restorefullaccount {
my %OPTS = @_;
my $userbackupdate = $OPTS{'userbackupdate'};
my $url = $ENV{'REQUEST_URI'};
return do_rem_api("restorefullaccount","$userbackupdate:$url");
}
sub folder_empty {
my $dirname = shift;
opendir(my $dh, $dirname) or die "Not a directory";
return scalar(grep { $_ ne "." && $_ ne ".." } readdir($dh)) == 0;
}
sub do_rem_api {
my $call_func = shift;
my $string = shift;
my $result = Cpanel::Wrap::send_cpwrapd_request(
'namespace' => 'RestoreManager',
'module' => 'rem',
'function' => $call_func,
'data' => $string,
'env' => Cpanel::Wrap::Config::safe_hashref_of_allowed_env()
);
if ( $result->{'error'} ) {
return "Error code $result->{'exit_code'} returned: $result->{'data'}";
}
# elsif ( ref ( $result->{'data'} ) ) {
# return Data::Dumper::Dumper($result->{'data'});
# }
elsif ( defined( $result->{'data'}) ) {
return $result->{'data'};
}
return 'cpwrapd request failed: ' . $result->{'statusmsg'};
}