Sh3ll
OdayForums


Server : Apache
System : Linux server1.cgrithy.com 3.10.0-1160.95.1.el7.x86_64 #1 SMP Mon Jul 24 13:59:37 UTC 2023 x86_64
User : nobody ( 99)
PHP Version : 8.1.23
Disable Function : NONE
Directory :  /usr/local/bin/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Current File : //usr/local/bin/ea-passenger-runtime-applications-settings
#!/usr/local/cpanel/3rdparty/bin/perl
# cpanel - ea-passenger-runtime-applications-settings
#                                                  Copyright 2021 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::ea_passenger_settings;

use strict;
use warnings;
use Cpanel::JSON                            ();
use Path::Tiny                              ();
use Cpanel::Config::userdata::PassengerApps ();
use Cpanel::ConfigFiles::Apache 'apache_paths_facade';    # see POD for import specifics

run(@ARGV) if !caller;

sub run {
    my (@args) = @_;

    my $fix = grep( m/^--fix/, @args ) ? 1 : 0;
    if ( $fix && @args > 1 || !$fix && @args > 0 ) {
        die "Invalid arguments. Either pass no args (to report problems) or pass only --fix (to fix problems).\n";
    }

    _verify_defaults_and_settings($fix);

    my %settings = (
        ruby   => scalar( _load_setting("ruby") ),
        python => scalar( _load_setting("python") ),
        nodejs => scalar( _load_setting("nodejs") ),
    );

    my %needs_fixed;

  USER:
    for my $userapps ( glob('/var/cpanel/userdata/*/applications.json') ) {
        my $apps = Cpanel::JSON::LoadFile($userapps);

        my $user = $userapps;
        $user =~ s{^/var/cpanel/userdata/}{};
        $user =~ s{/applications\.json$}{};

      APP:
        for my $appname ( sort keys %{$apps} ) {
            my $app = $apps->{$appname};

          TYPE:
            for my $type ( keys %settings ) {
                my $path = $app->{$type};
                if ( !length($path) || !-x $path ) {
                    if ( length( $settings{$type} ) && !-x $settings{$type} ) {
                        warn "$user’s app “$appname” has an invalid “$type” setting but can’t be reset because the global “$type” seeting is invalid also. If this app uses “$type” it will not work until “$type” is installed!\n";
                        next TYPE;
                    }

                    $needs_fixed{$user}{$appname}{$type}{old} = $path;
                    $needs_fixed{$user}{$appname}{$type}{new} = $settings{$type};
                }
            }
        }
    }

    if ( !keys %needs_fixed ) {
        print "No passenger application settings need fixed.\n";
        return;
    }

    if ($fix) {
        print "Fixing passenger application settings …\n";
        _perform_fixes( \%needs_fixed );
    }
    else {
        print "Passenger application setting problems (pass --fix to fix problems):\n";
        print Cpanel::JSON::pretty_canonical_dump( \%needs_fixed );
    }

    return;
}

###############
#### helpers ##
###############

sub _load_setting {
    my ($type) = @_;
    my $value = Path::Tiny::path("/etc/cpanel/ea4/passenger.$type")->slurp;
    chomp $value;    # juuuust in case

    warn "“$type” setting “$value” is not executable!\n" if !-x $value;
    return $value;
}

sub _perform_fixes {
    my ($needs_fixed_hr) = @_;

    if ( !-x apache_paths_facade->bin_httpd() ) {
        warn "Apache binary is missing (not yet installed?) so we can’t fix the passenger config. Please re-run `$0 --fix` after Apache is installed.\n";
        return;
    }

    for my $user ( sort keys %{$needs_fixed_hr} ) {
        print "\t … user “$user” …\n";
        my $file = "/var/cpanel/userdata/$user/applications.json";
        my $apps = Cpanel::JSON::LoadFile($file);

        for my $appname ( sort keys %{ $needs_fixed_hr->{$user} } ) {
            print "\t\t … application “$appname” …\n";

            for my $type ( sort keys %{ $needs_fixed_hr->{$user}{$appname} } ) {
                my $new = $needs_fixed_hr->{$user}{$appname}{$type}{new};
                my $old = $needs_fixed_hr->{$user}{$appname}{$type}{old} // "";

                print "\t\t\t … type “$type”: changing from “$old” to “$new”.\n";
                $apps->{$appname}{$type} = $new;
            }
        }

        # save settings
        Cpanel::JSON::DumpFile( $file, $apps );

        # regen service confs
        my $obj  = Cpanel::Config::userdata::PassengerApps->new( { user => $user } );
        my $appz = $obj->list_applications();
        for my $name ( keys %{$appz} ) {
            if ( $appz->{$name}{enabled} ) { $obj->generate_apache_conf($name); }
        }

        if ( -x "/usr/local/cpanel/scripts/ea-nginx" ) {
            system( '/usr/local/cpanel/scripts/ea-nginx', 'config', $user, '--no-reload' );
        }
    }

    # restart services
    system("/usr/local/cpanel/scripts/restartsrv_httpd --restart");

    if ( -x "/usr/local/cpanel/scripts/ea-nginx" ) {
        system("/usr/local/cpanel/scripts/ea-nginx reload");
    }

    return;
}

sub _verify_defaults_and_settings {
    my ($fix) = @_;

    my $default_ruby   = `find /usr/bin -name 'ruby*' -executable | sort -r | head -n 1`;
    my $default_python = `find /usr/bin -name 'python*' -executable ! -name "*-config" ! -name "pythonw*" | sort -r | head -n 1`;
    my $default_nodejs = `find /usr/bin -name 'node*' -executable | sort -r | head -n 1`;

    chomp $default_ruby;
    chomp $default_python;
    chomp $default_nodejs;

    # 1. Verify defaults exist on system
    _verify_default( ruby   => $default_ruby,   $fix );
    _verify_default( python => $default_python, $fix );
    _verify_default( nodejs => $default_nodejs, $fix );

    print "\n";

    # 2. Verify settings exist on system
    _verify_passenger_setting( ruby   => $default_ruby,   $fix );
    _verify_passenger_setting( python => $default_python, $fix );
    _verify_passenger_setting( nodejs => $default_nodejs, $fix );
    print "\n";

    return;
}

sub _verify_default {
    my ( $name, $have, $fix ) = @_;

    my $path = "/etc/cpanel/ea4/passenger.$name.system-default";

    # if default does not even exist this will create it ($target will be empty)
    my $target      = readlink($path) || "";
    my $is_fallback = $target eq "/usr/local/bin/ea-passenger-runtime_$name-is-not-installed" ? 1 : 0;
    if ( !-x $target || $is_fallback ) {
        if ($is_fallback) {
            print "Default is fallback helper, attempting to re-set it\n";
        }
        else {
            print "Default $name, $target, is not executable\n";
        }

        if ( !$have ) {
            print "\t … no $name found on system, ";

            if ($fix) {
                print "leaving currently invalid value in place\n";
            }
            else {
                print "currently invalid value would remain in place\n";
            }
        }
        else {
            if ($fix) {
                print "\t … updating to “$have”\n";
                unlink $path;
                symlink $have, $path;
            }
            else {
                print "\t … would update to “$have” (pass --fix to fix this problem)\n";
            }
        }
    }
    else {
        print "Default $name, $target, is ok\n";
    }

    return;
}

sub _verify_passenger_setting {
    my ( $name, $have, $fix ) = @_;

    print "Verifying passenger setting for $name\n";
    my $path = "/etc/cpanel/ea4/passenger.$name";

    if ( -s $path ) {
        my $curr = Path::Tiny::path($path)->slurp;
        chomp $curr;    # juuuust in case

        my $is_fallback = $curr eq "/usr/local/bin/ea-passenger-runtime_$name-is-not-installed" ? 1 : 0;
        if ( !-x $curr || $is_fallback ) {
            if ($is_fallback) {
                print "\t$name’s setting is fallback helper\n";
            }
            else {
                print "\t$name’s setting, $curr, is not executable\n";
            }

            if ($have) {
                _reset_passenger_setting( $name => $have, $fix );
            }
            else {
                _set_to_default( $name, $fix );
            }
        }
        else {
            print "\t$name setting, $curr, is ok\n";
        }
    }
    else {
        print "\t$name is not configured for passenger, using default.\n";
        _set_to_default( $name, $fix );
    }

    return;
}

sub _set_to_default {
    my ( $name, $fix ) = @_;

    my $defaultpath   = readlink("/etc/cpanel/ea4/passenger.$name.system-default") || "";
    my $defdisp       = $defaultpath;
    my $isplaceholder = 0;
    if ( $defdisp eq "/usr/local/bin/ea-passenger-runtime_$name-is-not-installed" ) {
        $isplaceholder = 1;
        $defdisp       = $name;
    }

    if ($isplaceholder) {
        print "The default is invalid. Passenger apps using it will not work until $defdisp is installed!\n";
        print "Passenger itself will not work until until $defdisp is installed!\n" if $name eq "ruby";
    }
    elsif ( !-x $defaultpath ) {
        print "The default, $defaultpath, is not executable. Passenger apps using it will not work until $defdisp is installed!\n";
        print "Passenger itself will not work until until $defdisp is installed!\n" if $name eq "ruby";
    }

    _reset_passenger_setting( $name => $defaultpath, $fix );

    return;
}

sub _reset_passenger_setting {

    my ( $name, $value, $fix ) = @_;

    if ($fix) {
        print "\t\tResetting $name setting to $value\n";
        Path::Tiny::path("/etc/cpanel/ea4/passenger.$name")->spew($value);
    }
    else {
        print "\t\t“$name” needs reset to “$value” (pass --fix to fix this problem)\n";
    }

    return;
}

1;

ZeroDay Forums Mini