Viewing File: /usr/local/cpanel/whostmgr/docroot/cgi/shake_up_ips/index.cgi

#!/usr/local/cpanel/3rdparty/bin/perl
##!/usr/local/bin/perl

BEGIN { unshift @INC, '/usr/local/cpanel'; }
BEGIN {
  push(@INC,"/usr/local/cpanel");
  push(@INC,"/usr/local/cpanel/whostmgr/docroot/cgi");
}

use strict;
use warnings "all";
use CGI::Carp qw ( fatalsToBrowser );
use Cpanel::Encoder::Tiny;
use Cpanel::Sys::Hostname           ();
use Cpanel::OS                      ();
use Cpanel::SafeRun                 ();
use Cpanel::SafeRun::Dynamic        ();
use Cpanel::Config                  ();
use Cpanel::Config::LoadUserDomains ();
use Cpanel::Config::userdata::Load  ();
use Cpanel::Config::userdata::Cache ();
use Cpanel::DIp::MainIP             ();
use CGI qw(:standard);
#use whmlib;
use File::Copy;
#use Cpanel::Form                   ();
use Whostmgr::ACLS          ();
use Whostmgr::HTMLInterface ();



require "parseform.pl";
our %FORM = parseform();

#my %FORM = Cpanel::Form::parseform();
#my %FORM = parseform();
#my $cgiaction = $FORM{'cgiaction'};

if (defined $FORM{'action'}) {

    if ($FORM{'action'} eq "process"){
        &process;
    }
    elsif ($FORM{'action'} eq "get_form"){
        &get_form;
    }
    elsif ($FORM{'action'} eq "rollback"){
        &rollback;
    }
}

my $freebsd       = Cpanel::OS::distro() eq 'freebsd' ? 1 : 0;
my $wwwacct_ref   = Cpanel::Config::loadwwwacctconf();
my $ethdev        = $wwwacct_ref->{'ETHDEV'} || 'eth0';
my $hostname      = Cpanel::Sys::Hostname::gethostname();
#my $js;

Cpanel::SafeRun::saferun('/bin/sh','-c','/usr/local/cpanel/scripts/updatedomainips');

my @addresses;
my @freeips;
my $out;
my $mainip;

foreach my $ipx (split(/\n/, Cpanel::SafeRun::saferun('/bin/sh','-c',"/sbin/ip -4 addr show $ethdev"))) {
    if ( $ipx =~ /inet\s(\d*\.\d*\.\d*\.\d*)/ ) {
        $mainip = $1;
        last;
    }
}

foreach my $addr (split(/\n/, Cpanel::SafeRun::saferun('/bin/sh','-c','/sbin/ip -4 addr show'))){
    unless ( $addr =~ /inet\s(\d*\.\d*\.\d*\.\d*)/ ){
        next;
    }
    my $ip = $1;
    if (check_free($ip) == 0){
        push @addresses, $ip;
    } else {
        push @freeips, $ip;
    }
}

my %accts = chk_accts(@addresses);

$out = <<"[END]";
<fieldset><legend>Shake up IP of accounts</legend>
<form method=POST action="$ENV{'cp_security_token'}/cgi/shake_up_ips/index.cgi">
<table align="center" width="100%" class="datatable brick" border="0" cellpadding="5" cellspacing="2">
<tr class="tdshade1_noborder"><th align="left" colspan="100">Select an IP address you want to release and select IP addresses you want to migrate accounts from selected IP</th></tr>
<tr class="tdshade1_noborder"><td colspan="2" class="label_and_help"><b>Select IP to release:</b>&nbsp;&nbsp;&nbsp;<select name="ipaddr" id="ipaddr" onChange="getForm();">&nbsp;<option selected value=""> ---------
[END]

my $jshead = <<"[END]";
<script type="text/javascript">
function getForm(){
    jQuery.post("$ENV{'cp_security_token'}/cgi/shake_up_ips/index.cgi",{ action:'get_form', ipaddr:jQuery("select#ipaddr").val() },function(data){
    jQuery("#excluder").html(data);
    });
}
</script>
<script type="text/javascript">
    function toggleDiv(){
    jQuery('#hide_text').toggle();
    }
</script>
[END]

@addresses = map {s/\s+//g; $_} sort map {s/(\d+)/sprintf "%3s", $1/eg; $_} @addresses;

foreach my $adr (@addresses){
    chomp($adr);
    my $coll;
    if ( defined $accts{$adr} ){
        $coll = $accts{$adr}
    }
    else {
        $coll = 0;
    }
    if ( $coll > 0 ){
        $out = $out."<option value=\"$adr\">$adr - ($coll)</option>";
    }
}
$out = $out.<<"[END]";
</select>&nbsp;<span id="excluder"></span></td></tr>
<tr class="tdshade1_noborder"><td class="label_and_help" colspan="2">
[END]

$out = $out."<br><b>Free IP Addresses</b>  <a href=\"javascript:void(0);\" onclick=\"toggleDiv();\">>></a> <br>&nbsp;<div id=\"hide_text\" style=\"display:block\">";
my $i = 0;

@freeips = map {s/\s+//g; $_} sort map {s/(\d+)/sprintf "%3s", $1/eg; $_} @freeips;

foreach(@freeips){
    $out = $out."<input type=\"checkbox\" name=\"id$i\" class=\"\freeip\" id=\"freeip\" value=\"$_\" />&nbsp;$_<br>\n";
    ++$i;
}

my %reserved = get_reserved_ips();

$out = $out."</div><br><b>Reserved IPs:</b><br>&nbsp;<br>";

while ( my ( $key, $value ) = each %reserved ){
    my %chk = chk_accts($key);
    my $accts = 0;
    if ( defined $chk{$key} ){
        $accts = $chk{$key};
    }
    $out = $out."<input type=\"checkbox\" name=\"id$i\" class=\"reserved\" id=\"reserved\" value=\"$key\" />&nbsp;$key&nbsp;($value) (Accounts: $accts)<br>\n";
++$i;
}

$out=$out.<<"[END]";
&nbsp;<br>
<input type="checkbox" name="set" onclick="setCheckedReserved(this);" /><b>&nbsp;<span id="text2">Check</span>&nbsp;all reserved</b>
<input type="checkbox" name="set" onclick="setChecked(this);" /><b>&nbsp;<span id="text">Check</span>&nbsp;all</b>
</td></tr>
<tr class="tdshade1_noborder"><td align="center" colspan="2" class="label_and_help">
<input type="hidden" name="chkcount" value="$i">
<input type=hidden name="action"value="process">
<input class="btn btn-primary btn-md" style="margin-top:2%;" type="Submit" value="Ok" size="30"></td></tr>
</table>
</form>
</fieldset>
[END]

my $js = <<"[END]";
<script type="text/javascript">
function setChecked(obj){
    var str = document.getElementById("text").innerHTML;
    str = (str == "Check" ? "Uncheck" : "Check");
    document.getElementById("text").innerHTML = str;
    var str1 = document.getElementById("text2").innerHTML;
    str1 = (str1 == "Check" ? "Uncheck" : "Check");
    document.getElementById("text2").innerHTML = str1;
    var check = document.getElementsByTagName("input");
    for (var i=0; i<check.length; i++) {
            check[i].checked = obj.checked;
    }
}

function setCheckedReserved(obj){
    var str = document.getElementById("text2").innerHTML;
    str = (str == "Check" ? "Uncheck" : "Check");
    document.getElementById("text2").innerHTML = str;
    var check = document.getElementsByClassName("reserved");
    for (var i=0; i<check.length; i++) {
            check[i].checked = obj.checked;
    }
}
</script>
[END]

my $sout = get_rollback_form();
if ( defined $sout ){
    $out = $out.$sout;
}
else{
    $out = $out;
}
printHTML($out,$js,$jshead);

exit;

############################################################################################################################
# Rollback changes form

sub get_rollback_form {
    my $out;
    my $ret;
    my $js;

$out = <<"[END]";
<br>&nbsp;<br>
<fieldset><legend>Shake up IP of accounts</legend>
<form method=POST action="$ENV{'cp_security_token'}/cgi/shake_up_ips/index.cgi">
<table align="center" width="100%" class="datatable brick" border="0" cellpadding="5" cellspacing="2">
<tr class="tdshade1_noborder"><th align="left">Select the addresses accounts of which you want to return changes.</th></tr>
<tr class="tdshade1_noborder"><td class="label_and_help">
<b>Select IP addresses:</b><br>&nbsp;<br>
[END]

my @ips = get_feat();
my $ii = 0;
my %accts = chk_accts(@ips);

foreach my $ip (@ips){
    my $ipcnt = 0;
    $ipcnt = $accts{$ip} if ($accts{$ip});
    my @newips = get_newips_list($ip);
    $out = $out."<input type=\"checkbox\" name=\"ip$ii\" value=\"$ip\">&nbsp;$ip ($ipcnt)&nbsp;Exclude Address:&nbsp;<select name=exclude><option value=\"\">-------------\n";
    foreach (@newips){
        $out = $out."<option value=\"$_\">$_&nbsp;";
    }
    $out = $out."</select><br>";
++$ii;
}

$out = $out.<<"[END]";
</td></tr>
<tr class="tdshade1_noborder" align="center"><td class="label_and_help">
<input type=hidden name="action"value="rollback"><input type=hidden name="cnt" value="$ii"><input type=submit class="btn btn-primary btn-md" style="margin-top:2%;" value="Ok" size="30">
</td></tr>
</table>
</form>
</fieldset>
<br>&nbsp;<br>
[END]

if ( defined $ips[0] ){
    $ret = $out;
}
return ($ret);
}

############################################################################################################################
# Get list of IP addresses where accounts has been moved to

sub get_newips_list {
    my $ip = shift;
    my @list;
    my @accts;
    my $file = '/etc/movedaccts';
    open (FILE, "$file");
    my @lines = <FILE>;
    close (FILE);

        foreach my $line (@lines){
            chomp($line);
            my ( $user, $adr ) = split ( /=/, $line );
            if ( $adr eq $ip ){
                push @accts, $user;
            }
        }

    foreach my $acct (@accts){
        my %usr = get_params($acct);
        my $cc = 0;
        foreach (@list){
            if ( $usr{'IP'} eq $_ ){
                $cc = 1;
            }
        }
        if ( $cc == 0 ){
            push @list, $usr{'IP'};
        }
    }

return (@list);
}

############################################################################################################################
# Rollback changes

sub rollback {
    my @ips;
    my $count = $FORM{'cnt'};
    my $exclude = $FORM{'exclude'};
    my $i;
    my $file = '/etc/movedaccts';
    open (FILE, "$file");
    my @data = <FILE>;
    close(FILE);

    print "Content-type: text/html\n\n";
    Whostmgr::HTMLInterface::defheader("Release IP Address", "/cPanel_magic_revision_1507622748/themes/x/icons/change_ownership_of_multiple_accounts.png");
    print "<fieldset><legend>IP Address remaper</legend>";

print "<p>Saving main IP</p>";
    save_wh_mainip();

    for ( $i = 0; $i <= $count; ++$i ){
        my $formid = "ip".$i;
        if ( defined $FORM{$formid} ){
            push @ips, $FORM{$formid};
        }
    }

    my $mainipfile = '/var/cpanel/mainips/wh';
    add_to_file($mainipfile,@ips);
print "<p>Adding new IP addresses as main shared to user WH</p>";
    Cpanel::SafeRun::saferun('/bin/sh','-c','/usr/local/cpanel/scripts/rebuildippool');

my %do;

foreach my $ip (@ips){
    foreach my $line (@data){
        chomp($line);
        my ($user,$uaddr) = split ( /=/, $line );
        if ( $uaddr eq $ip ){
            $do{$user} = $uaddr;
        }
    }
}

my @xcluded;

while ( my ( $key, $value ) = each %do ){
    my %set = get_params($key);
    my $oldip = $set{'IP'};
    if ( $oldip ne $exclude ){
        print "Account $key has been transferred back to $value<br>";
        my $answer = Cpanel::SafeRun::saferun('/bin/sh','-c',"/usr/local/cpanel/bin/setsiteip -u $key $value");
        print "$answer\n";
    }
    else {
        print "<font color=\"red\">Account $key pointed to excluded IP address ($exclude).</font><br>";
        push @xcluded, $key;
    }
}

print "<p>Restoring Main IP... </p>";
restore_wh_mainip();

print "<p>Deleting from stored history... ";

my @newdata;

    foreach my $dataline (@data){
        chomp( $dataline );
        my ( $du, $da ) = split ( /=/, $dataline );
        my $cc = 0;
        foreach my $dr (@ips){
            if ( $da eq $dr ){
                $cc = 1;
            }
        }
        foreach (@xcluded){
            if ( $du eq $_ ){
                $cc = 0;
            }
        }
        if ( $cc == 0 ){
            push @newdata, $dataline;
        }
    }
    open (OUT, ">$file");
    foreach (@newdata){
        print OUT "$_\n";
    }
    close (OUT);

print "<p><b>Done...</b></p><p><a href=\"$ENV{'cp_security_token'}/cgi/addon_shake_up_ips.cgi\">Back</a></p><br>&nbsp;<br>";
print "</fieldset></body></html>";
exit;
}

############################################################################################################################
# Get featured IP list

sub get_feat {
    my @ip;
    my $file = '/etc/movedaccts';
    open (FILE,"$file");
    my @lines = <FILE>;
    close(FILE);
    my $i = 0;
    foreach my $line (@lines){
        chomp($line);
        my ($acctname, $acctip) = split ( /=/, $line);
        my $i = 0;
        foreach (@ip){
            if ( $_ eq $acctip ){
                $i = 1;
            }
        }
        if ( $i == 0 ){
            push @ip, $acctip;
        }
    }
return(@ip);
}


############################################################################################################################
# Get from with ajax

sub get_form {
    my $ip = $FORM{'ipaddr'};
    my @names = get_accounts_by_ip($ip);
    my $i;
    my $file='/etc/movedaccts';
    my @ips;

    open (LOG,"$file");
    my @logs = <LOG>;
    close(LOG);

    print "Content-type: text/html\n\n";
    if ( defined $ip ){
        foreach my $name (@names){
            foreach my $log (@logs){
                my ($lname,$lip) = split( /\=/, $log);
                chomp($lip);
                if ( $name eq $lname){
                    my $chk = grep $_ eq $lip, @ips;
                    if ($chk == 0){
                        push @ips, $lip;
                    }
                }
            }
        }
        if ( defined $ips[0] ){
            print "<b>Select account\'s source IP to exclude</b><select name=\"exclude\"><option selected value=\"\">---------";
            foreach (@ips){
                print "<option value=\"$_\">$_\n";
            }
            print "</select>";
        }
    }
exit;
}

############################################################################################################################
# Get list of reserved IP addresses
#

sub get_reserved_ips {
    my %out;
    my $file = '/etc/reservedipreasons';
    open (IPS, "$file");
    my @lines = <IPS>;

    close(IPS);
    foreach my $line (@lines){
        chomp($line);
        my ($ip,$reason) = split( /=/, $line );
        $out{$ip} = $reason;
    }

return(%out);
}

############################################################################################################################
# Assigning IP to accounts
#

sub process {

    print "Content-type: text/html\n\n";
    Whostmgr::HTMLInterface::defheader("Release IP Address", "/cPanel_magic_revision_1507622748/themes/x/icons/change_ownership_of_multiple_accounts.png");
    print "<fieldset><legend>IP Address remaper</legend>";

    my $out;
    my @id;
    my $ip = $FORM{'ipaddr'};
    my $chkcount = $FORM{'chkcount'};
    my $i;
    my $exclude = $FORM{'exclude'};

print "<p>Saving main IP</p>";
    save_wh_mainip();

    for ( $i = 0; $i <= $chkcount; ++$i ){
        my $formid = "id".$i;
        if ( defined $FORM{$formid} ){
            push @id, $FORM{$formid};
        }
    }
    my $total = @id;

    #my $dipfile = '/var/cpanel/dips/wh';
    my $mainipfile = '/var/cpanel/mainips/wh';
    #add_to_file($dipfile,@id);
    add_to_file($mainipfile,@id);
print "<p>Adding new IP addresses as main shared to user WH</p>";
    Cpanel::SafeRun::saferun('/bin/sh','-c','/usr/local/cpanel/scripts/rebuildippool');

    my @names = get_accounts_by_ip($ip);

    my $s=0;
    my %list;
    foreach my $name (@names){
        if ( $s >= $total ){
            $s = 0;
        }
        $list{$name} = $id[$s];
        ++$s;
    }

        while( my ($key,$value) = each %list){
            if ( $value ne $ip ){
                    my $answer;
                    print "User: $key new IP: $value";
                    my ($chkres,$oldip) = check_moved($key,$ip,$value);
                    if ( defined $exclude ){
                        if ( $oldip ne $exclude ){
                            print " ($chkres) ";
                            $answer = Cpanel::SafeRun::saferun('/bin/sh','-c',"/usr/local/cpanel/bin/setsiteip -u $key $value");
                            print "$answer<br>\n";
                        }
                        else {
                            print " <b><font color=\"red\">Source IP $exclude excluded</font></b><br>";
                        }
                    }
                    else {
                            print " ($chkres) ";
                            $answer = Cpanel::SafeRun::saferun('/bin/sh','-c',"/usr/local/cpanel/bin/setsiteip -u $key $value");
                            print "$answer<br>\n";
                    }
            }
            else {
                print "User $key pointed to $value already<br>";
            }
        };

print "<p>Restoring Main IP</p>";
restore_wh_mainip();
print "<p><b>Done...</b></p><p><a href=\"$ENV{'cp_security_token'}/cgi/addon_shake_up_ips.cgi\">Back</a></p><br>&nbsp;<br>";

print "</fieldset></body></html>";
exit;
}

############################################################################################################################
# Writing original IP to LOG, looking for LOG updates
#

sub check_moved {
    my $user = shift;
    my $oldip = shift;
    my $newip = shift;
    chomp($user);
    my $result;
    my $file = '/etc/movedaccts';

    open (LOG,"$file");
    my @lines = <LOG>;
    close(LOG);
    my $chk = 0;
    my $logip;

    open (OUT,">$file") || die 'Cannot open file for writing';

    foreach my $line (@lines){
        chomp($line);
        my ($login, $ip) = split ( /\=/, $line );
        if ( $login eq $user ){
            $logip = $ip;
            if ( $ip eq $newip ){
                $chk = 1;
                $result = "Account $user pointed to original address ($ip)";
            }
            else {
                print OUT "$line\n";
                $result = "Account $user pointed to non original address ($newip). Original address is $ip";
                $chk = 2;
            }
        }
        else {
            print OUT "$line\n";
        }
    }
    if ( $chk == 0 ){
        $result = "Account $user has been added to log file";
        print OUT "$user=$oldip\n";
    }
    close(OUT);

return($result,$logip);
}

############################################################################################################################
# Restore old Main IP
#

sub restore_wh_mainip {
    my $file = "/var/cpanel/mainips/wh";
    my $backup = "/var/cpanel/mainips/wh.bk";
    move ($backup,$file);
}

############################################################################################################################
# Maiking backup copy of Main IP file
#

sub save_wh_mainip {
    my $file = "/var/cpanel/mainips/wh";
    my $backup = "/var/cpanel/mainips/wh.bk";
    copy ($file,$backup);
}

############################################################################################################################
# Adding temporary settings to Main IP file
#

sub add_to_file {
    my $file = shift;
    my @ips = @_;
    open (FILE,"$file");
    my @lines = <FILE>;
    close(FILE);
    open (OUT,">$file");
        foreach my $fileip (@lines){
            chomp($fileip);
            my $chk = 0;
            foreach my $ip (@ips){
                if ( $ip eq $fileip ){
                    $chk = 1;
                }
            }
            if ($chk == 0){
                push @ips, $fileip;
            }
        }
        foreach my $addr (@ips){
            print OUT "$addr\n";
        }
    close(OUT);
}

############################################################################################################################
# Get list of usernames for IPs
#

sub get_accounts_by_ip {
    my $ip = shift;
    my @names;
    my $userlist = Cpanel::SafeRun::saferun('/bin/sh','-c','/bin/ls -1 /var/cpanel/users');
    my (@unames) = split (/\n/, $userlist );
    foreach my $uname (@unames){
        chomp($uname);
        if ( defined $uname ){
            my %p = get_params($uname);
            if ( $p{'IP'} eq $ip ){
                push @names,$uname;
            }
        }
    }
return (@names);
}

############################################################################################################################
# Get accounts count for IPs
#

sub chk_accts {
    my @ips = shift;
    my %c;
    my $userlist = Cpanel::SafeRun::saferun('/bin/sh','-c','/bin/ls -1 /var/cpanel/users');
    my ( @users ) = split(/\n/, $userlist);
    foreach my $user (@users){
        chomp($user);
        if (defined $user){
            my %p = get_params($user);
            my $tempip = $p{'IP'};
            $c{$tempip} = ++$c{$tempip};
        }
    }
return (%c);
}

############################################################################################################################
# Get user parameters from /usr/local/users/<user>
#

sub get_params {
        my $file = shift;
        my $userfile = "/var/cpanel/users/$file";
        my $list = Cpanel::SafeRun::saferun('/bin/sh','-c',"/bin/cat $userfile");
        my ( @lines ) = split ( /\n/, $list );
        my %set;
        foreach my $line (@lines){
                next if $line =~ /^(\s*(#.*)?)?$/;
                chomp($line);
                my ($par, $val) = split( /=/, $line);
                $set{$par} = $val;
        }
return %set;
}

############################################################################################################################
# Check for free IP address
#

sub check_free {
    my $ip = shift;
    my $ret = 0;
    my $freeips = "/etc/ipaddrpool";
    open (POOL,"$freeips");
    my @adr_arr = <POOL>;
    close(POOL);
    foreach my $adr (@adr_arr){
        chomp($adr);
        chomp($ip);
        if ( $ip eq $adr ){
            $ret = 1;
        }
    }
    return($ret);
}

############################################################################################################################
# HTML Template
#

sub printHTML {
    my $data = shift;
    my $js = shift;
    my $jshead = shift;

    print "Content-type: text/html\n\n";

    Whostmgr::HTMLInterface::defheader("Release IP Address", "/cPanel_magic_revision_1507622748/themes/x/icons/change_ownership_of_multiple_accounts.png");

    print <<"[END]";
<script type=\"text/javascript\" src=\"https://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js\"></script>
$jshead
$js
$data
</body></html>
[END]
    exit;
}
Back to Directory File Manager