GIF89a=( õ' 7IAXKgNgYvYx\%wh…hŽth%ˆs%—x¨}9®Œ©€&©‰%¶†(¹–.¹5·œD¹&Çš)ÇŸ5ǘ;Í£*È¡&Õ²)ׯ7×µ<Ñ»4ï°3ø‘HÖ§KͯT÷¨Yÿšqÿ»qÿÔFØ !ù ' !ÿ NETSCAPE2.0 , =( þÀ“pH,È¤rÉl:ŸÐ¨tJ­Z¯Ø¬vËíz¿à°xL.›Ïè´zÍn»ßð¸|N¯Ûïø¼~Ïïûÿ€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§gª«ªE¯°¨¬ª±²Œ¹º¹E¾­”´ÂB¶¯ §Åȸ»ÑD¾¿Á•ÄÅ®° ÝH¾ÒLÀÆDÙ«D¶BÝïðÀ¾DÑÑÔTÌÍíH òGö¨A RÎڐ |¥ ٭&ºìE8œ¹kGÔAÞpx­a¶­ã R2XB®åE8I€Õ6Xî:vT)äžþÀq¦è³¥ì仕F~%xñ  4#ZÔ‰O|-4Bs‘X:= QÉ œš lºÒyXJŠGȦ|s hÏíK–3l7·B|¥$'7Jީܪ‰‡àá”Dæn=Pƒ ¤Òëí‰`䌨ljóá¯Éüv>á–Á¼5 ½.69ûϸd«­ºÀûnlv©‹ªîf{¬ÜãPbŸ  l5‘ޝpß ´ ˜3aÅùäI«O’ý·‘áÞ‡˜¾Æ‚ÙÏiÇÿ‹Àƒ #öó)pâš Þ½ ‘Ý{ó)vmÞü%D~ 6f s}ŃƒDØW Eþ`‡þ À…L8xá†ç˜{)x`X/> Ì}mø‚–RØ‘*|`D=‚Ø_ ^ð5 !_…'aä“OÚ—7âcð`D”Cx`ÝÂ¥ä‹éY¹—F¼¤¥Š?¡Õ™ n@`} lď’ÄÉ@4>ñd œ à‘vÒxNÃ×™@žd=ˆgsžG±æ ´²æud &p8Qñ)ˆ«lXD©øÜéAžHìySun jª×k*D¤LH] †¦§C™Jä–´Xb~ʪwStŽ6K,°£qÁœ:9ت:¨þªl¨@¡`‚ûÚ ».Û¬¯t‹ÆSÉ[:°=Š‹„‘Nåû”Ìî{¿ÂA ‡Rà›ÀÙ6úë°Ÿð0Ä_ ½;ÃϱîÉì^ÇÛÇ#Ëë¼ôº!±Ä˜íUîÅÇ;0L1óÁµö«p% AÀºU̬ݵ¼á%霼€‡¯Á~`ÏG¯»À× ­²± =4ªnpð3¾¤³¯­ü¾¦îuÙuµÙ®|%2ÊIÿür¦#0·ÔJ``8È@S@5ê¢ ö×Þ^`8EÜ]ý.뜃Âç 7 ú ȉÞj œ½Dç zý¸iþœÑÙûÄë!ˆÞÀl§Ïw‹*DçI€nEX¯¬¼ &A¬Go¼QföõFç°¯;é¦÷îŽêJ°îúôF5¡ÌQ|îúöXªæ»TÁÏyñêï]ê² o óÎC=öõ›ÒÓPB@ D×½œä(>èCÂxŽ`±«Ÿ–JЀ»Û á¤±p+eE0`ëŽ`A Ú/NE€Ø†À9‚@¤à H½7”à‡%B‰`Àl*ƒó‘–‡8 2ñ%¸ —€:Ù1Á‰E¸àux%nP1ð!‘ðC)¾P81lÑɸF#ˆ€{´âé°ÈB„0>±û °b¡Š´±O‚3È–Ù()yRpbµ¨E.Z‘D8ÊH@% òŒx+%Ù˜Æcü »¸˜fõ¬b·d`Fê™8èXH"ÉÈ-±|1Ô6iI, 2““¬$+](A*jÐ QTÂo‰.ÛU슬Œã„Ž`¯SN¡–¶Äåyše¯ª’­¬‚´b¦Éož œ)åyâ@Ì®3 ÎtT̉°&Ø+žLÀf"Ø-|žçÔ>‡Ðv¦Ðžì\‚ Q1)Ž@Žh#aP72”ˆ™¨$‚ !ù " , =( …7IAXG]KgNgYvYxR"k\%w]'}hŽth%ˆg+ˆs%—r.—m3šx3˜x¨}9®€&©€+¨‡7§‰%¶†(¹–.¹œD¹&ǘ;Í•&ײ)×»4ïÌ6ò§KÍ þ@‘pH,È¤rÉl:ŸÐ¨tJ­Z¯Ø¬vËíz¿à°xL.›Ïè´zÍn»ßð¸|N¯Ûïø¼~Ïïûÿ€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§g «¬ E ±± ¨­¶°ººE Á´”·®C¬²§Ç¶Œ»ÓDÃÕƷ¯Ê±H½ºM×ÁGÚ¬D¶BËÁ½î½DÓôTÏÛßîG»ôõC×CÌ l&âž:'òtU³6ɹ#·Ø)€'Ü.6±&ëÍÈ» K(8p0N?!æ2"ÛˆNIJX>R¼ÐO‚M '¡¨2¸*Ÿþ>#n↠å@‚<[:¡Iïf’ ¤TÚ˘CdbÜÙ“[«ŽEú5MBo¤×@€`@„€Êt W-3 ¶Ÿ¡BíêäjIÝ…Eò9[T…$íêﯧ„…•s»Óȳ¹€ÅÚdc®UUρ#±Ùïldj?´í¼²`\ŽÁðÞu|3'ÖŒ]ë6 ¶S#²‡˜FKLÈ *N E´‘áäŠ$˜›eÄYD„ºq«.è촁ƒs \-ÔjA 9²õ÷å- üúM[Âx(ís÷ì®x€|í¡Ù’p¦‚ ŽkÛTÇDpE@WÜ ²Ç]kŠ1¨ þ€·Yb ÓÁ‰l°*n0 ç™—žzBdОu¾7ĉBl€â‰-ºx~|UåU‰  h*Hœ|e"#"?vpÄiŠe6^ˆ„+qâŠm8 #VÇá ‘å–ÄV„œ|Аè•m"сœn|@›U¶ÆÎž—Špb¥G¨ED”€±Úê2FÌIç? >Éxå Œ± ¡¤„%‘žjŸ‘ꄯ<Ìaà9ijÐ2˜D¦È&›†Z`‚å]wþ¼Â:ç6àB¤7eFJ|õÒ§Õ,¨äàFÇ®cS·Ê¶+B°,‘Þ˜ºNûãØ>PADÌHD¹æž«ÄÀnÌ¥}­#Ë’ë QÀÉSÌÂÇ2ÌXÀ{æk²lQÁ2«ÊðÀ¯w|2Í h‹ÄÂG€,m¾¶ë3ÐÙ6-´ÅE¬L°ÆIij*K½ÀÇqï`DwVÍQXœÚÔpeœ±¬Ñ q˜§Tœ½µƒ°Œìu Â<¶aØ*At¯lmEØ ü ôÛN[P1ÔÛ¦­±$ÜÆ@`ùåDpy¶yXvCAyåB`ŽD¶ 0QwG#¯ æš[^Äþ $ÀÓÝǦ{„L™[±úKÄgÌ;ï£S~¹ìGX.ôgoT.»åˆ°ùŸûù¡?1zö¦Ÿž:ÅgÁ|ìL¹ „®£œŠ‚à0œ]PÁ^p F<"•ç?!,ñ‡N4—…PÄ Á„ö¨Û:Tè@hÀ‹%táÿ:ø-žI<`þ‹p I….)^ 40D#p@ƒj4–؀:²‰1Øâr˜¼F2oW¼#Z†;$Q q” ‘ ÂK¦ñNl#29 !’F@¥Bh·ᏀL!—XFóLH‘Kh¤.«hE&JòG¨¥<™WN!€ÑÙÚˆY„@†>Œž19J" 2,/ &.GXB%ÌRÈ9B6¹W]’î×ÔW¥’IÎ$ ñ‹ÓŒE8YÆ ¼³™ñA5“à®Q.aŸB€&Ø©³ JÁ—! ¦t)K%tœ-¦JF bòNMxLôþ)ÐR¸Ð™‘ èÝ6‘O!THÌ„HÛ ‰ !ù ) , =( …AXKgNgYvYxR"k\%wh…hŽh%ˆg+ˆs%—r.—x3˜x¨}9®€&©€+¨Œ,©‡7§‰%¶†(¹–.¹5·&Çš)ǘ;Í•&×£*Ȳ)ׯ7×»4ï°3øÌ6ò‘HÖ§KÍ»Hó¯T÷¨Yÿ»qÿÇhÿ þÀ”pH,È¤rÉl:ŸÐ¨tJ­Z¯Ø¬vËíz¿à°xL.›Ïè´zÍn»ßð¸|N¯Ûïø¼~Ïïûÿ€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§g ª« E$±²¨ª­ · °²½$E$ÂÕ««D· Í ¿¦Ç¶¸ÌŒ¾³CÃÅÆ E ééH½MÛÂGâªD­ çBêêϾD²ÒaÀà€Š1r­ðÓ¤ ÔožzU!L˜C'¾yW½UGtäÇïÙllê0×àÂuGþ)AÀs[þ·xì ÁxO%ƒûX2ó—  P£n›R/¡ÑšHše+êDm?# —‘Ç£6¡8íJ¡ŸâDiäªM¥Ö„ôj“¬¹£5oQ7°- <‡ *´lãÓŒ2r/a!l)dÈ A™ÈE¢ôÔ͆…ð ;Ö˜c ¡%ß‚’Ùˆâ¸b½—pe~C"BíëÚHïeF2§æŠ8qb t_`urŠeü wÅu3êæPv§h•"ß`íÍxçLĹÜÖ3á  ~Öº“®›¸ÏMDfJÙ °„ÛµáWõ%§œ‚à©–‚X ÓØ)@®Ñ›Eþ´wëuÅSxb8y\mÖzœ¥§ZbºE—ÂLªÌw!y(>¡™wú=Ç|ÅÝs¢d €CÁW)HÜcC$€L Ä7„r.á\{)@ð` @ äXÈ$PD” `šaG:§æˆOˆ72EÐamn]ù"ŒcÊxÑŒ° &dR8`g«iÙŸLR!¦P …d’ä¡“¦ðÎTƒ¦ià|À _ ¥ Qi#¦Šg›Æ ›noMµ ›V ã£)p ç£ÎW…š=Âeªk§†j„ ´®1ß²sÉxéW«jšl|0¯B0Û, \jÛ´›6±¬¶C ÛíWþï|ëÙ‹¸ñzĸV {ì;Ýñn¼òVˆm³I¼³.Ðã¤PN¥ ²µ¼„µCã+¹ÍByî£Ñ¾HŸ›ëê 7ìYÆFTk¨SaoaY$Dµœìï¿Ã29RÈkt Çïfñ ÇÒ:ÀÐSp¹3ÇI¨â¥DZÄ ü9Ïýögñ½­uÔ*3)O‘˜Ö[_hv ,àî×Et Ÿé¶BH€ Õ[ü±64M@ÔSÌM7dÐl5-ÄÙU܍´©zߌ3Ô€3ž„ „ ¶ÛPô½5×g› êÚ˜kN„Ý…0Îj4€Ìë°“#{þÕ3S2çKÜ'ợlø¼Ú2K{° {Û¶?žm𸧠ËI¼nEò='êüóºè^üæÃ_Û=°óž‚ì#Oý¿Í'¡½áo..ÏYìnüñCœO±Áa¿¢Kô½o,üÄËbö²çºíï{ËC Ú— "”Ï{ËK ÍÒw„õ±Oz dÕ¨à:$ ƒô—«v»] A#ð «€¿šéz)Rx׿ˆ¥‚d``èw-îyÏf×K!ð€þ­Ð|ìPľ„=Ì`ý(f” 'Pa ¥ÐBJa%Ðâf§„%Š¡}FàáÝ×6>ÉäŠG"éŽè=ø!oа^FP¼Ø©Q„ÀCÙÁ`(Ž\ÄÝ® ©Â$<n@dÄ E#ììUÒI! ‚#lù‹`k¦ÐÇ'Rró’ZýNBÈMF Í[¤+‹ðɈ-áwj¨¥þ8¾rá ,VÂh„"|½œ=×G_¦Ñ™EØ 0i*%̲˜Æda0mV‚k¾)›;„&6 p>ÓjK “¦Ç# âDÂ:ûc?:R Ó¬fÞéI-Ì“•Ã<ä=™Ï7˜3œ¨˜c2ŒW ,ˆ”8(T™P‰F¡Jhç"‚ ; 403WebShell
403Webshell
Server IP : 192.254.185.125  /  Your IP : 216.73.216.196
Web Server : Apache
System : Linux gator3151.hostgator.com 5.14.0-687.42.1.el9_8.x86_64 #1 SMP PREEMPT_DYNAMIC Thu Aug 27 11:55:12 EDT 2026 x86_64
User : diablo ( 32101)
PHP Version : 7.4.33
Disable Function : NONE
MySQL : OFF  |  cURL : ON  |  WGET : ON  |  Perl : ON  |  Python : OFF  |  Sudo : ON  |  Pkexec : ON
Directory :  /scripts/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Command :


[ Back ]     

Current File : /scripts/manage_mysql_profiles
#!/usr/local/cpanel/3rdparty/bin/perl

# cpanel - scripts/manage_mysql_profiles           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

package scripts::manage_mysql_profiles;

use strict;
use Try::Tiny;

use Cpanel::JSON                                    ();
use Getopt::Long                                    ();
use Cpanel::Backup::Config                          ();
use Cpanel::Logger                                  ();
use Cpanel::LoadFile                                ();
use Cpanel::Exception                               ();
use Cpanel::Hooks                                   ();
use Cpanel::DIp::MainIP                             ();
use Cpanel::SafeFile                                ();
use Cpanel::SafeRun::Errors                         ();
use Cpanel::Services::Enabled                       ();
use Cpanel::MysqlUtils::MyCnf::Basic                ();
use Cpanel::MysqlUtils::MyCnf                       ();
use Cpanel::MysqlUtils::Command                     ();
use Cpanel::MysqlUtils::Connect                     ();
use Cpanel::MysqlUtils::Quote                       ();
use Cpanel::MysqlUtils::Integration                 ();
use Cpanel::MysqlUtils::RemoteMySQL::ActivationJob  ();
use Cpanel::MysqlUtils::RemoteMySQL::ProfileManager ();
use Cpanel::Config::LoadCpConf                      ();
use Cpanel::Sys::Hostname                           ();

exit run(@ARGV) unless caller();

sub run {
    my @cmdline_args = @_;
    return usage(1) if !@cmdline_args;

    unless ( $> == 0 && $< == 0 ) {
        return usage( 1, "[!] This program can only be run by root!\n" );
    }

    my $opts = {};
    Getopt::Long::GetOptionsFromArray(
        \@cmdline_args,
        'activate=s'              => \$opts->{'activate'},
        'import=s'                => \$opts->{'import'},
        'force'                   => \$opts->{'force'},
        'export=s@'               => \$opts->{'export'},
        'export_to=s'             => \$opts->{'export_to'},
        'recreate_active_profile' => \$opts->{'recreate_active_profile'},
        'help|h'                  => \$opts->{'help'},
    );

    return usage(0)                                                   if $opts->{'help'};
    return activate_profile( $opts->{'activate'} )                    if $opts->{'activate'};
    return import_profiles( $opts->{'import'}, $opts->{'force'} )     if $opts->{'import'};
    return export_profiles( $opts->{'export'}, $opts->{'export_to'} ) if $opts->{'export'} && scalar @{ $opts->{'export'} };
    return recreate_active_profile( $opts->{'force'} )                if $opts->{'recreate_active_profile'};
    return usage(1);
}

sub recreate_active_profile {
    my $force = shift;
    try {
        my $profile_manager = Cpanel::MysqlUtils::RemoteMySQL::ProfileManager->new();

        my $active_profile = $profile_manager->get_active_profile('dont_die');
        if ( !$force && $active_profile ) {
            print "[!] '$active_profile' is already active.\n";
        }
        else {
            print "[*] Recreating active profile …\n";
            $profile_manager->generate_active_profile_if_none_set($force);
            $profile_manager->save_changes_to_disk();
            my $active_profile = $profile_manager->get_active_profile('dont_die');
            print "[+] New active profile created: $active_profile\n";
        }
    }
    catch {
        _handle_failure( { 'action' => 'recreate', 'exception' => $_ } );
    };

    return 0;
}

sub import_profiles {
    my ( $input_file, $force ) = @_;

    try {
        open( my $input_file_fh, '<', $input_file )
          or die Cpanel::Exception::create( 'IO::FileReadError', [ path => $input_file, error => $! ] );

        my $json = Cpanel::JSON::LoadFile( $input_file_fh, $input_file );
        die Cpanel::Exception::create( 'IO::FileReadError', [ path => $input_file, error => 'Invalid JSON data' ] )
          if !$json || ref $json ne 'HASH';

        print "[*] Importing MySQL profiles: " . join( ', ', ( keys %{$json} ) ) . "\n\n";
        my $profile_manager   = Cpanel::MysqlUtils::RemoteMySQL::ProfileManager->new();
        my $existing_profiles = $profile_manager->read_profiles();

        my $active_profile_exists = $profile_manager->get_active_profile('dont_die');
        foreach my $profile_name ( keys %{$json} ) {
            my $overwrite = $force ? 1 : 0;
            if ( !$overwrite and exists $existing_profiles->{$profile_name} ) {
                print "[*] '$profile_name' already exists …\n";
                next;    # skip
            }

            # If an active profile is already present, then mark the newly
            # imported profile as inactive to avoid conflicts.
            if ( $json->{$profile_name}->{'active'} && $active_profile_exists ) {
                $json->{$profile_name}->{'active'} = 0;
            }
            $profile_manager->create_profile( { 'name' => $profile_name, %{ $json->{$profile_name} } }, { 'overwrite' => $overwrite } );
            print "[+] '$profile_name' imported.\n";
        }
        $profile_manager->save_changes_to_disk();
    }
    catch {
        _handle_failure( { 'action' => 'import', 'exception' => $_ } );
    };

    return 0;
}

sub export_profiles {
    my ( $profiles_to_export_ar, $output_file ) = @_;

    print STDERR "[*] Exporting MySQL profiles: " . join( ', ', @{$profiles_to_export_ar} ) . "\n\n";
    try {
        my $profile_manager   = Cpanel::MysqlUtils::RemoteMySQL::ProfileManager->new( { 'read_only' => 1 } );
        my $existing_profiles = $profile_manager->read_profiles();
        my $output            = {};
        my $output_fh;

        if ($output_file) {
            open $output_fh, '>', $output_file or die Cpanel::Exception::create( 'IOError', 'Failed to open “[_1]” for writing: [_2]', [ $output_file, $! ] );
            print STDERR "[*] Saving to '$output_file'\n";
        }

        foreach my $profile_to_export ( @{$profiles_to_export_ar} ) {
            if ( not exists $existing_profiles->{$profile_to_export} ) {
                print STDERR "[!] Profile not found: $profile_to_export\n";
                next;
            }
            $output->{$profile_to_export} = $existing_profiles->{$profile_to_export};
        }

        # If there are any profiles to export, then output the json
        if ( scalar keys %{$output} ) {
            print { $output_fh ? $output_fh : \*STDOUT } Cpanel::JSON::pretty_dump($output);
        }
        else {
            print "\n[!] No profiles to export.\n";
        }
    }
    catch {
        _handle_failure( { 'action' => 'export', 'exception' => $_ } );
    };

    return 0;
}

sub activate_profile {
    my $profile_name = shift;

    Cpanel::Hooks::hook(
        {
            'category' => 'Whostmgr',
            'event'    => 'RemoteMySQL::activate_profile',
            'stage'    => 'pre',
        },
        { 'profile_name' => $profile_name, },
    );

    my $activation_job  = Cpanel::MysqlUtils::RemoteMySQL::ActivationJob->new($profile_name);
    my $profile_manager = Cpanel::MysqlUtils::RemoteMySQL::ProfileManager->new();
    try {
        my $current_active_profile = $profile_manager->get_active_profile('dont_die');

        # TODO: should we care about situations where the profile being switched to is the same as the active profile?
        print "[*] Current active MySQL profile: " . ( $current_active_profile || 'N/A' ) . " \n";
        print "[*] Activating MySQL profile: $profile_name\n\n";

        # Step 1: Validation.
        $activation_job->start_step('Validating profile');
        try {
            $profile_manager->validate_profile($profile_name);
        }
        catch {
            $activation_job->fail_step( 'Validating profile', { 'error' => $_->to_string() } );
            die Cpanel::Exception::create( 'RemoteMySQL::ActivationFailed', 'Failed to activate [asis,MySQL] profile, “[_1]”: [_2]', [ $profile_name, 'Failed to validate profile' ] );
        };
        $activation_job->done_step('Validating profile');

        my $profile = $profile_manager->read_profiles()->{$profile_name};

        # STEP 2: Update local root .my.cnf file
        $activation_job->start_step('Updating /root/.my.cnf');
        my $old_my_cnf   = Cpanel::LoadFile::loadfile('/root/.my.cnf');
        my $is_localhost = Cpanel::Services::Enabled::is_enabled('mysql') && Cpanel::MysqlUtils::MyCnf::Basic::is_local_mysql( $profile->{'mysql_host'} );
        if ( _update_local_mycnf( $profile, { localhost => $is_localhost } ) ) {
            $activation_job->done_step('Updating /root/.my.cnf');
        }
        else {
            $activation_job->fail_step( 'Updating /root/.my.cnf', { 'error' => 'Failed to update /root/.my.cnf' } );
            die Cpanel::Exception::create( 'RemoteMySQL::ActivationFailed', 'Failed to activate [asis,MySQL] profile, “[_1]”: [_2]', [ $profile_name, 'Failed to update /root/.my.cnf' ] );
        }

        # STEP 3: Verify root cnf changes allows mysql* tools to work. Test with mysqladmin
        $activation_job->start_step('Testing /root/.my.cnf changes with mysqladmin');

        my $ping_ok = eval {
            Cpanel::MysqlUtils::Connect::get_dbi_handle();
            1;
        };

        if ( !$ping_ok ) {
            my $err = $@;

            $activation_job->fail_step( 'Testing /root/.my.cnf changes with mysqladmin', { 'error' => $err } );

            $activation_job->start_step('Restoring /root/.my.cnf to previous version');
            if ( _restore_old_mycnf($old_my_cnf) ) {
                $activation_job->done_step('Restoring /root/.my.cnf to previous version');
            }
            else {
                $activation_job->fail_step( 'Restoring /root/.my.cnf to previous version', { 'error' => 'Failed to restore previous config.' } );
            }
            die Cpanel::Exception::create(
                'RemoteMySQL::ActivationFailed',
                'Failed to activate [asis,MySQL] profile, “[_1]”: [_2]',
                [ $profile_name, 'Failed to connect to MySQL server after updating /root/.my.cnf' ]
            );
        }
        $activation_job->done_step('Testing /root/.my.cnf changes with mysqladmin');

        # STEP 4: Update DB cache
        $activation_job->start_step('Updating DB Cache');
        Cpanel::SafeRun::Errors::saferunnoerror('/usr/local/cpanel/scripts/update_db_cache');
        $activation_job->done_step('Updating DB Cache');

        # STEP 5: Update cPanel Apps using MySQL
        $activation_job->start_step('Updating cPanel Apps that use MySQL');
        Cpanel::MysqlUtils::Integration::update_apps_that_use_mysql();
        $activation_job->done_step('Updating cPanel Apps that use MySQL');

        my $cpconf_ref = Cpanel::Config::LoadCpConf::loadcpconf();
        if ( !$is_localhost ) {

            # STEP 6: If going to remote host, then transfermysqlusers
            $activation_job->start_step('Transferring MySQL users to remote MySQL host');
            Cpanel::SafeRun::Errors::saferunnoerror( '/usr/local/cpanel/bin/transfermysqlusers', '--from', $current_active_profile );
            $activation_job->done_step('Transferring MySQL users to remote MySQL host');

            # This addresses concerns with edge cases where 'skip_name_resolve' is set
            # on the remote MySQL server, and we can't depend on the 'hostname' authentication.
            # Especially, when the mysql server sees the connecting ip as something different than what the 'main ip' is, etc.
            #
            # In order to ensure that we are granting access to the 'proper' IP - we check the process list in mysql
            # to see what the 'connecting' IP is according to the remote MySQL server, and apply the grants on that IP address.
            my $mainip   = Cpanel::MysqlUtils::Quote::safesqlstring( Cpanel::DIp::MainIP::getmainserverip() );
            my $hostname = Cpanel::MysqlUtils::Quote::safesqlstring( Cpanel::Sys::Hostname::gethostname() );
            my $clientip = Cpanel::MysqlUtils::Quote::safesqlstring( Cpanel::MysqlUtils::Command::sqlcmd('SELECT SUBSTRING_INDEX(`host`,":",1) FROM `information_schema`.`processlist` WHERE ID = CONNECTION_ID();') );
        }

        $profile_manager->mark_profile_as_active($profile_name);
        $profile_manager->save_changes_to_disk();

        # STEP 9: Update the backup config to not backup directories if remote
        if ( !$is_localhost ) {

            $activation_job->start_step('Updating backup settings');

            my $backup_conf = Cpanel::Backup::Config::load();

            if ( $backup_conf->{'MYSQLBACKUP'} eq 'both' or $backup_conf->{'MYSQLBACKUP'} eq 'dir' ) {

                $backup_conf->{'MYSQLBACKUP'} = 'accounts';
                Cpanel::Backup::Config::save($backup_conf);
            }

            $activation_job->done_step('Updating backup settings');
        }
        else {
            print "No need to adjust backup configuration since we are activating a local MySQL profile\n";
        }

        $activation_job->mark_job_done();
    }
    catch {
        $activation_job->mark_job_failed();
        _handle_failure( { 'action' => 'activate', 'exception' => $_ } );
    };

    Cpanel::Hooks::hook(
        {
            'category' => 'Whostmgr',
            'event'    => 'RemoteMySQL::activate_profile',
            'stage'    => 'post',
        },
        {
            'profile_name' => $profile_name,
            'result'       => $activation_job->{progress}{status} eq 'DONE' ? 1 : 0,
        },
    );

    return 0;
}

sub _restore_old_mycnf {
    my $old_my_cnf = shift;
    my $mylock     = Cpanel::SafeFile::safeopen( \*MYCNF, '>', '/root/.my.cnf' );
    if ($mylock) {
        print MYCNF $old_my_cnf;
        Cpanel::SafeFile::safeclose( \*MYCNF, $mylock );
        return 1;
    }
    return;
}

sub _update_local_mycnf {
    my ( $profile_hr, $opts_hr ) = @_;
    my $unix_socket_connection = $opts_hr->{'localhost'} && $profile_hr->{'mysql_port'} == 3306;
    return Cpanel::MysqlUtils::MyCnf::update_mycnf(
        user  => 'root',
        items => [
            {
                host => ( $unix_socket_connection ? undef : $profile_hr->{'mysql_host'} ),
                user => $profile_hr->{'mysql_user'},
                pass => $profile_hr->{'mysql_pass'},
                port => $profile_hr->{'mysql_port'},
            }
        ],
    );
}

sub usage {
    my ( $retval, $msg ) = @_;
    my $fh = $retval ? \*STDERR : \*STDOUT;

    if ( !defined $msg ) {
        $msg = <<USAGE;
$0

Utility to manage the MySQL profiles configured on the server. Available options:

    --import [/path/to/json/file]

            Imports the profiles contained in the specified JSON file.
            To force import and overwrite any existing profiles use the '--force' switch:
                $0 --import import.json --force

    --export [profile name]

            Exports one or more profiles.
            To export more than one profile, specify multiple switches:
                $0 --export profile1 --export profile2

            To export the profiles to a file, specify the 'export_to' switch:
                $0 --export profile1 --export_to  export.json
            Or redirect stdout:
                $0 --export profile1 > export.json

    --activate [profile name]

            Activates the profile specified.

    --recreate_active_profile

            If no active profile is present on the system, this option will allow you to (re)create
            the profile. It reads the current '/root/.my.cnf' file and creates a profile based on that information.

            If the 'force' flag is specified, this option will recreate the active profile, regardless of
            whether one exists or not, based on the content of '/root/.my.cnf'.

    --help

            Displays this help message.

USAGE
    }

    print {$fh} $msg;
    return $retval;
}

sub _handle_failure {
    my $opts = shift;

    my $action     = $opts->{'action'};
    my $exceptions = ref $opts->{'exception'} eq 'HASH' ? $opts->{'exception'}->{'exceptions'} : [ $opts->{'exception'} ];

    my $logger = Cpanel::Logger->new();
    $logger->info( "Failed to $action MySQL profile(s). " . scalar @{$exceptions} . " error(s) occurred." );

    my $index = 1;
    foreach my $error ( @{$exceptions} ) {
        $logger->info( "Error $index:  " . Cpanel::Exception::get_string($error) );
        $index++;
    }

    return 1;
}

1;

Youez - 2016 - github.com/yon3zu
LinuXploit