MMCT TEAM
Server IP : 103.53.40.154  /  Your IP : 3.145.161.194
Web Server : Apache
System : Linux md-in-35.webhostbox.net 4.19.286-203.ELK.el7.x86_64 #1 SMP Wed Jun 14 04:33:55 CDT 2023 x86_64
User : ppcad7no ( 715)
PHP Version : 8.2.25
Disable Function : NONE
MySQL : OFF  |  cURL : ON  |  WGET : ON  |  Perl : ON  |  Python : ON
Directory (0755) :  /scripts/

[  Home  ][  C0mmand  ][  Upload File  ]

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

# cpanel - scripts/check_valid_server_hostname     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::check_valid_server_hostname;

use strict;
use warnings;

use Cpanel::Locale                  ();
use Cpanel::Usage                   ();
use Cpanel::Config::LoadWwwAcctConf ();
use Cpanel::Sys::Hostname           ();
use Cpanel::Redirect                ();
use Cpanel::DIp::MainIP             ();
use Socket                          ();

my $HOSTNAME_OK            = 0;
my $GENERIC_HOSTNAME_ERROR = 1;
my $NEEDS_SET_HOSTNAME     = 2;

sub script {
    my $self = shift;
    my $argv = shift;
    my $lc   = Cpanel::Locale->get_handle();
    my %opts = (
        notify => 0,
        quiet  => 0,
    );

    Cpanel::Usage::wrap_options(
        $argv,
        \&usage,
        { 'notify' => \$opts{'notify'}, 'quiet' => \$opts{'quiet'} },
    );

    my $hostname = Cpanel::Sys::Hostname::gethostname();

    if ( my $is_manual_hostname = $self->is_manual_hostname( $hostname, \%opts ) ) {
        if ( $is_manual_hostname == $NEEDS_SET_HOSTNAME ) {
            require Whostmgr::Hostname;
            my ( $status, $statusmsg, $msgref, $errref ) = Whostmgr::Hostname::sethostname( $hostname, 1 );
            unless ( $opts{'quiet'} ) {
                if ( $msgref && ref $msgref ) {
                    print "$_\n" for @$msgref;
                }

                if ( !$status ) {
                    warn $statusmsg;
                    if ( $errref && ref $errref ) {
                        warn "$_" for @$errref;
                    }
                }
            }
            exit 1 if !$status;
        }
        else {
            exit 1;
        }
    }
    exit 1 unless $self->is_resolv_hostname( $hostname, \%opts );

    print $lc->maketext(q{OK}), "\n" unless $opts{'quiet'};

    exit 0;
}

sub usage {
    my $lc = Cpanel::Locale->get_handle();

    print $lc->maketext(q{This tool verifies the server hostname configuration.}), "\n\n";
    print $lc->maketext( q{Usage: [_1][comment,a program name] ~[options~]}, $0 ), "\n\n";
    print $lc->maketext(q{Options:}),                                              "\n";
    print "\t--help     ",                                                         $lc->maketext(q{Display this help message.}),                                               "\n";
    print "\t--notify   ",                                                         $lc->maketext(q{Send a failure notification to the system administrator.}),                 "\n";
    print "\t--quiet    ",                                                         $lc->maketext(q{Do not display output, and instead set the [output,asis,UNIX] exit code.}), "\n\n";

    exit 0;
}

# Do not use Cpanel::Hostname::gethostname().  The purpose of this routine
# is to reliably detect from the definitive source on Linux, what it thinks
# it's running as.  That is then compared to the WHM setting.
sub is_manual_hostname {
    my $self     = shift;
    my $hostname = shift;
    my $opts     = shift;
    my $conf     = Cpanel::Config::LoadWwwAcctConf::loadwwwacctconf();
    my $lc       = Cpanel::Locale->get_handle();
    my $old      = $lc->set_context_plain();
    my $ip       = Cpanel::DIp::MainIP::getmainip();

    unless ($conf) {
        my $reason   = $lc->maketext(q{The system is unable to retrieve the [output,asis,WHM] hostname configuration information.});
        my $solution = $lc->maketext( q{Verify the file system permissions of the “[_1]” file on your server.}, q{/etc/wwwacct.conf} );
        $self->send_failure_notification( $opts, { 'status' => 'cannot_read_conf', 'reason' => $reason, 'solution' => $solution, 'hostname' => $hostname, 'ip' => $ip } );
        $lc->set_context($old);
        return $GENERIC_HOSTNAME_ERROR;
    }

    my $url      = sprintf( 'http://%s:2087/scripts2/changehostname', Cpanel::Redirect::getserviceSSLdomain('whm') );
    my $solution = $lc->maketext( q{The system will attempt to synchronize the current hostname “[_1]” to the system configuration.}, $hostname ) . ' ' . $lc->maketext( q{In the future, update your hostname in [output,url,_1,WHM’s] interface (Home » Networking Setup » Change Hostname).}, $url );

    unless ( $conf->{'HOST'} ) {
        my $reason = $lc->maketext(q{The system hostname is not configured in [output,asis,WHM].});
        $self->send_failure_notification( $opts, { 'status' => 'host_missing', 'reason' => $reason, 'solution' => $solution, 'hostname' => $hostname, 'ip' => $ip } );
        $lc->set_context($old);
        return $NEEDS_SET_HOSTNAME;
    }

    unless ( $hostname eq $conf->{'HOST'} ) {
        my $reason = $lc->maketext(q{[output,asis,WHM] has detected a manual hostname change.});
        $self->send_failure_notification( $opts, { 'status' => 'hostname_host_mismatch', 'reason' => $reason, 'solution' => $solution, 'hostname' => $hostname, 'ip' => $ip } );
        $lc->set_context($old);
        return $NEEDS_SET_HOSTNAME;
    }

    $lc->set_context($old);

    return $HOSTNAME_OK;
}

# This uses gethostbyname(), because Apache does.  If Apache is unable to resolve the
# hostname on the machine using the standard default EasyApache profile, then it won't
# start (due to mod_unique_id).
sub is_resolv_hostname {
    my $self     = shift;
    my $hostname = shift;
    my $opts     = shift;
    my $lc       = Cpanel::Locale->get_handle();
    my $old      = $lc->set_context_plain();
    my $solution = $lc->maketext( q{Update your system “[_1]” file and/or [output,asis,DNS] server.}, q{/etc/hosts} );
    my $ip       = Cpanel::DIp::MainIP::getmainip();

    my $resolved = gethostbyname($hostname);

    unless ($resolved) {
        my $reason = $lc->maketext( q{The system was unable to resolve the system hostname “[_1]” to an [output,asis,IP] address.}, $hostname );
        $self->send_failure_notification( $opts, { 'status' => 'cannot_resolve_hostname', 'reason' => $reason, 'solution' => $solution, 'hostname' => $hostname, 'ip' => $ip } );
        $lc->set_context($old);
        return 0;
    }

    $lc->set_context($old);

    return 1;
}

sub send_failure_notification {
    my $self = shift;
    my $opts = shift;
    my $args = shift;

    my $lc  = Cpanel::Locale->get_handle();
    my $old = $lc->set_context_plain();

    print STDERR $lc->maketext('ERROR:'), " $args->{'reason'}\n" unless $opts->{'quiet'};
    print STDERR "\n$args->{'solution'}\n" if $args->{'solution'};

    unless ( $opts->{'notify'} ) {
        $lc->set_context($old);
        return 1;
    }

    require Cpanel::Notify;
    Cpanel::Notify::notification_class(
        'class'            => 'Check::ValidServerHostname',
        'application'      => 'server_hostname_validator',
        'status'           => $args->{'status'},
        'interval'         => 86400 * 7,
        'constructor_args' => [
            'origin'   => 'server_hostname_validator',
            'reason'   => $args->{'reason'},
            'solution' => $args->{'solution'},
            'ip'       => $args->{'ip'},
        ]
    );

    $lc->set_context($old);

    return 1;
}

__PACKAGE__->script( \@ARGV ) unless caller;

__END__

=head1 NAME

check_valid_server_hostname - Verifies proper configuration of hostname

=head1 DESCRIPTION

This script checks the hostname of the machine and verifies that the user has
properly configured it in cPanel & WHM.  Additionally, it performs a DNS check
on the hostname.  Both of these verifications, in tandem, help to ensure the
user has a properly configured and functioning server.

MMCT - 2023