#!/usr/local/cpanel/3rdparty/bin/perl
# cpanel - scripts/synccpaddonswithsqlhost Copyright 2022 cPanel, L.L.C.
# All rights reserved.
# copyright@cpanel.net http://cpanel.net
# This code is subject to the cPanel license. Unauthorized copying is prohibited
use strict;
use warnings;
use Carp;
use File::Spec;
use Cpanel::AccessIds ();
use Cpanel::OS ();
use Cpanel::cPAddons ();
my %valid_addons;
my $myhost;
my $cpaddons_base = '/usr/local/cpanel/cpaddons';
exit( run(@ARGV) // 0 ) unless caller;
sub run {
my (@args) = @_;
unshift @INC, $cpaddons_base;
if ( !Cpanel::OS::supports_cpaddons() ) {
die qq[cPAddons are not supported on this distro.\n];
}
if ( -e q[/var/cpanel/cpaddons.disabled] ) {
die qq[cPAddons are disabled on this server.\n];
}
%valid_addons = map { $_ => 1 } list_cpaddons();
$myhost = get_root_mysql_host();
print "Syncing Site Software installations with current MySQL host setting!\n\n";
for my $user ( @{ get_all_users_or_arg_ref() } ) {
process_user($user);
}
return;
}
sub process_user {
my ($user) = @_;
print "Processing $user...\n";
my $home = ( getpwnam($user) )[7];
if ( !defined $home ) {
carp "Could not determine home for $user";
return;
}
my @cpaddons;
if ( opendir my $cpaddons_dh, "$home/.cpaddons/" ) {
@cpaddons = grep { /\:\:/ } readdir $cpaddons_dh;
closedir $cpaddons_dh;
}
else {
carp "Can not read .cpaddons/ for $user, skipping: $!";
return;
}
my $cpaddons_processed = process_user_cpaddons( $user, $home, @cpaddons );
if ($cpaddons_processed) {
my $s = $cpaddons_processed == 1 ? '' : 's';
print "$user had $cpaddons_processed cpaddon$s synced\n";
}
else {
print "$user had no cpaddons needing their mysql host synced\n";
}
print "$user Done!\n\n";
return 1;
}
sub process_user_cpaddons {
my ( $user, $home, @cpaddons ) = @_;
my $cpaddons_processed = 0;
for my $aod (@cpaddons) {
print "\tChecking $aod...\n";
my $install_hashref = {};
if ( !Cpanel::cPAddons::_read_cache( "$home/.cpaddons/$aod", $install_hashref, $user ) ) {
carp "Could not read $aod: $!";
next;
}
my $mod = $aod;
$mod =~ s{\.yaml$}{};
$mod =~ s{\.\d+$}{};
if ( !exists( $valid_addons{$mod} ) ) {
carp "Skipping $aod, It does not appear that $mod is a valid or installed cPaddon.";
next;
}
my $mod_file = $mod;
$mod_file =~ s/::/\//g;
$mod_file = $mod_file . '.pm';
require $mod_file;
if ($@) {
carp "Skipping $aod, Could not get $mod info (is $mod installed?): $!";
next;
}
else {
no strict 'refs';
my $info_hr = ${"$mod\:\:meta_info"};
use strict 'refs';
for my $db ( @{ $info_hr->{'mysql'} } ) {
my $current_setting = $install_hashref->{"mysql.$db.sqlhost"} || '';
next if ( $myhost eq $current_setting ) || ( !$myhost || !$current_setting );
print "\t\tDifference detected, syncing...\n";
for my $conf ( @{ $info_hr->{'config_files'} } ) {
my $path = File::Spec->catdir( $install_hashref->{'installdir'}, $conf );
print "\t\t\tProcessing $path...";
process_user_config_file( $user, $current_setting, $myhost, $path );
print "Done!\n";
}
$install_hashref->{"mysql.$db.sqlhost"} = $myhost;
$install_hashref->{'mysql'}{$db}{'sqlhost'} = $myhost;
if ( !Cpanel::cPAddons::_write_cache( "$home/.cpaddons/$aod", $install_hashref, $user ) ) {
carp "Could not save $aod: $!";
next;
}
print "\t\t$aod is done\n";
$cpaddons_processed++;
}
}
}
return;
}
sub process_user_config_file {
my ( $user, $current_setting, $host, $path ) = @_;
Cpanel::AccessIds::do_as_user(
$user,
sub {
if ( open( my $fh, '+<', $path ) ) {
my @lines = map { my $s = $_; $s =~ s/$current_setting/$myhost/g; $s } <$fh>;
seek $fh, 0, 0;
print {$fh} join( '', @lines );
truncate( $fh, tell $fh );
close($fh);
}
else {
carp "Failed to open '$path' for reading and writing: $!";
}
},
);
return;
}
sub get_root_mysql_host {
my $myhost = '';
open my $mycnf_fh, '<', '/root/.my.cnf'
or croak "Set MySQL root passwd: $!";
while (<$mycnf_fh>) {
if ( $_ =~ m/host\s*\=/ ) {
($myhost) = $_ =~ m/host\s*\=\s*\"?([^\"\s]+)\"?/;
last;
}
}
close $mycnf_fh;
return $myhost || 'localhost';
}
sub get_all_users_or_arg_ref {
my $arg_location = shift || 0;
my $user_to_run = defined $ARGV[$arg_location]
&& $ARGV[$arg_location] ? $ARGV[$arg_location] : '';
my $user_lookup_ref = get_user_lookup_ref();
my @users_to_transform = keys %{$user_lookup_ref};
if ($user_to_run) {
if ( exists $user_lookup_ref->{$user_to_run} ) {
@users_to_transform = ($user_to_run);
}
else {
croak 'Unknown user';
}
}
return \@users_to_transform;
}
sub get_user_lookup_ref {
my $user_lookup = {};
open( my $TUD, '<', '/etc/trueuserdomains' ) or die "trueuserdomains failed: $!";
while (<$TUD>) {
my ($user) = $_ =~ m/\:\s+(\w+)/;
$user_lookup->{$user}++ if $user;
}
close $TUD;
return $user_lookup;
}
sub list_cpaddons {
my @cpaddons;
opendir( my $bdh, $cpaddons_base );
my @pals = grep !/^\.+$/, readdir $bdh;
closedir $bdh;
for my $pal (@pals) {
next if !-d "$cpaddons_base/$pal";
opendir( my $cdh, "$cpaddons_base/$pal" );
my @cats = grep !/^\.+$/, readdir $cdh;
closedir($cdh);
for my $cat (@cats) {
next if !-d "$cpaddons_base/$pal/$cat";
opendir( my $sdh, "$cpaddons_base/$pal/$cat" );
my @subs = grep /\.pm$/, readdir $sdh;
closedir($sdh);
for my $sub (@subs) {
$sub =~ s/\.pm$//;
push @cpaddons, "$pal\:\:$cat\:\:$sub";
}
}
}
return @cpaddons;
}
1;
Mr. DellatioNx196 GaLers xh3LL Backd00r 1.0, Coded By Mr. DellatioNx196 - Bogor BlackHat