php IHDR w Q )Ba pHYs sRGB gAMA a IDATxMk\U s&uo,mD )Xw+e?tw.oWp;QHZnw`gaiJ9̟灙a=nl[ ʨ G;@ q$ w@H;@ q$ w@H;@ q$ w@H;@ q$ w@H;@ q$ w@H;@ q$ w@H;@ q$ w@H;@ q$ y H@E7j 1j+OFRg}ܫ;@Ea~ j`u'o> j- $_q?qS XzG'ay
files >> /usr/libexec/webmin/virtual-server/ |
files >> //usr/libexec/webmin/virtual-server/wizard-lib.pl |
# Functions for the post-install wizard # If the wizard should be invoked, returns a URL for it. For calling by themes sub wizard_redirect { if (&master_admin() && ($config{'wizard_run'} eq '' && $config{'first_version'} >= 3.69 || $config{'wizard_run'} eq '0')) { return "$gconfig{'webprefix'}/$module_name/wizard.cgi"; } return undef; } sub get_wizard_steps { return ( "intro", "memory", $config{'virus'} ? ( "virus" ) : ( ), $config{'spam'} ? ( "spam" ) : ( ), "db", $config{'mysql'} ? ( "mysql", "mysize" ) : ( ), $config{'dns'} ? ( "dns" ) : ( ), "hashpass", &needs_xfs_quota_fix() ? ( "xfs" ) : ( ), "done" ); } sub wizard_show_intro { print &ui_table_row(undef, $text{'wizard_intro'}, 2); } # Show a form to enable or disable pre-loading and lookup-domain-daemon sub wizard_show_memory { print &ui_table_row(undef, $text{'wizard_memory'}, 2); local $mem = &get_uname_arch() =~ /64/ ? "40M" : "20M"; print &ui_table_row($text{'wizard_memory_preload'}, &ui_radio("preload", $config{'preload_mode'} ? 1 : 0, [ [ 1, &text('wizard_memory_preload1', $mem)."<br>" ], [ 0, $text{'wizard_memory_preload0'} ] ])); if ($config{'spam'}) { local $mem = &get_uname_arch() =~ /64/ ? "70M" : "35M"; print &ui_table_row($text{'wizard_memory_lookup'}, &ui_radio("lookup", &check_lookup_domain_daemon(), [ [ 1, &text('wizard_memory_lookup1', $mem)."<br>" ], [ 0, $text{'wizard_memory_lookup0'} ] ])); } } # Enable or disable pre-loading and lookup-domain-daemon sub wizard_parse_memory { local ($in) = @_; &push_all_print(); &set_all_null_print(); if ($in->{'preload'} && !$config{'preload_mode'}) { # Turn on preloading $config{'preload_mode'} = 2; &save_module_config(); &update_miniserv_preloads(2); &restart_miniserv(); } elsif (!$in->{'preload'} && $config{'preload_mode'}) { # Turn off preloading $config{'preload_mode'} = 0; &save_module_config(); &update_miniserv_preloads(0); &restart_miniserv(); } if ($config{'spam'}) { local $lud = &check_lookup_domain_daemon(); if ($in->{'lookup'} && !$lud) { # Startup lookup daemon &setup_lookup_domain_daemon(); } elsif (!$in->{'lookup'} && $lud) { # Stop lookup daemon &delete_lookup_domain_daemon(); } $config{'no_lookup_domain_daemon'} = !$in->{'lookup'}; &save_module_config(); } &pop_all_print(); return undef; } # Show a form asking the user if he wants to run clamd sub wizard_show_virus { print &ui_table_row(undef, $text{'wizard_virus'}, 2); local $cs = &check_clamd_status(); if ($cs != -1) { print &ui_table_row($text{'wizard_clamd'}, &ui_radio("clamd", $cs ? 1 : 0, [ [ 1, $text{'wizard_clamd1'}."<br>" ], [ 0, $text{'wizard_clamd0'} ] ])); } else { print &ui_table_row($text{'wizard_clamdnone'}); } } # Parse the clamd form, and enable or disable clamd sub wizard_parse_virus { local ($in) = @_; if (defined($in->{'clamd'})) { local $cs = &check_clamd_status(); if ($in->{'clamd'} && !$cs) { # Enable if needed &push_all_print(); &set_all_null_print(); local $ok = &enable_clamd(); &pop_all_print(); if ($ok) { # Switch to clamdscan, after testing local $last_err; for(my $try=0; $try<10; $try++) { $last_err = &test_virus_scanner("clamdscan"); last if (!$last_err); if ($try == 0 && &has_command("freshclam")) { # First time around, try running # freshclam &backquote_with_timeout("freshclam",60); } else { sleep($try); } } return &text('wizard_eclamdtest', $last_err) if ($last_err); &save_global_virus_scanner("clamdscan"); } else { return $text{'wizard_eclamdenable'}; } } elsif (!$in->{'clamd'} && $cs) { # Disable if needed &push_all_print(); &set_all_null_print(); &disable_clamd(); &pop_all_print(); &save_global_virus_scanner("clamscan"); } } return undef; } # Show a form asking the user if he wants to run spamd sub wizard_show_spam { print &ui_table_row(undef, $text{'wizard_spam'}, 2); local $cs = &check_spamd_status(); if ($cs != -1) { print &ui_table_row($text{'wizard_spamd'}, &ui_radio("spamd", $cs ? 1 : 0, [ [ 1, $text{'wizard_spamd1'}."<br>" ], [ 0, $text{'wizard_spamd0'} ] ])); } else { print &ui_table_row($text{'wizard_spamdnone'}); } } # Parse the spamd form, and enable or disable spamd sub wizard_parse_spam { local ($in) = @_; if (defined($in->{'spamd'})) { local $cs = &check_spamd_status(); if ($in->{'spamd'} && !$cs) { # Enable if needed &push_all_print(); &set_all_null_print(); local $ok = &enable_spamd(); &pop_all_print(); if ($ok) { # Switch to spamc &save_global_spam_client("spamc"); } else { return $text{'wizard_espamdenable'}; } } elsif (!$in->{'spamd'} && $cs) { # Disable if needed &push_all_print(); &set_all_null_print(); &disable_spamd(); &pop_all_print(); &save_global_spam_client("spamassassin"); } } return undef; } # Ask the user if he wants to run MySQL and/or PostgreSQL sub wizard_show_db { print &ui_table_row(undef, $text{'wizard_db'}, 2); print &ui_table_row($text{'wizard_db_mysql'}, &ui_radio("mysql", $config{'mysql'} ? 1 : 0, [ [ 1, $text{'wizard_db_mysql1'}."<br>" ], [ 0, $text{'wizard_db_mysql0'} ] ])); print &ui_table_row($text{'wizard_db_postgres'}, &ui_radio("postgres", $config{'postgres'} ? 1 : 0, [ [ 1, $text{'wizard_db_postgres1'}."<br>" ], [ 0, $text{'wizard_db_postgres0'} ] ])); } # Enable or disable MySQL and PostgreSQL, depending on user's selections sub wizard_parse_db { local ($in) = @_; &foreign_require("init", "init-lib.pl"); &require_mysql(); if ($in->{'mysql'}) { # Enable and start MySQL, if possible if (!&foreign_installed("mysql", 0)) { return $text{'wizard_emysqlinst'}; } $config{'mysql'} ||= 1; if (&mysql::is_mysql_running() == 0) { local $err = &mysql::start_mysql(); return &text('wizard_emysqlstart', $err) if ($err); } if (&init::action_status("mysql")) { &init::enable_at_boot("mysql"); } # Make sure MySQL can be used if (&foreign_installed("mysql", 1) != 2) { return &text('wizard_emysqlconf', '../mysql/'); } } else { # Disable and shut down MySQL $config{'mysql'} = 0; &mysql::stop_mysql(); &init::disable_at_boot("mysql"); } &require_postgres(); if ($in->{'postgres'}) { # Enable and start PostgreSQL if (!&foreign_installed("postgresql", 0)) { return $text{'wizard_epostgresinst'}; } $config{'postgres'} ||= 1; if (&postgresql::is_postgresql_running() == 0) { local $err = &postgresql::start_postgresql(); return &text('wizard_epostgresstart', $err) if ($err); } if (&init::action_status("postgresql")) { &init::enable_at_boot("postgresql"); } # Make sure PostgreSQL can be used if (&foreign_installed("postgresql", 1) != 2) { return &text('wizard_epostgresconf', '../postgresql/'); } } else { # Disable and shut down PostgreSQL $config{'postgres'} = 0; &postgresql::stop_postgresql(); &init::disable_at_boot("postgresql"); } &save_module_config(); return undef; } # Show a form to set the MySQL root password sub wizard_show_mysql { &require_mysql(); print &ui_table_row(undef, $text{'wizard_mysql'}. ($mysql::mysql_pass ? $text{'wizard_mysql3'} : $text{'wizard_mysql2'}), 2); if ($mysql::mysql_pass) { print &ui_table_row($text{'wizard_mysql_pass'}, &ui_opt_textbox("mypass", undef, 20, $text{'wizard_mysql_pass1'}."<br>", $text{'wizard_mysql_pass0'})); } else { print &ui_table_row($text{'wizard_mysql_empty'}, &ui_textbox("mypass", undef, 20)); } } # Set the MySQL password, if changed sub wizard_parse_mysql { local ($in) = @_; &require_mysql(); if (!$in{'mypass_def'}) { # Change in DB local $esc = &mysql::escapestr($in->{'mypass'}); local $user = $mysql::mysql_login || "root"; &mysql::execute_sql_logged($mysql::master_db, "update user set password = $mysql::password_func('$esc') ". "where user = '$user'"); &mysql::execute_sql_logged($mysql::master_db, 'flush privileges'); # Update Webmin $mysql::config{'pass'} = $in->{'mypass'}; &mysql::save_module_config(\%mysql::config, "mysql"); } return undef; } # Show a form to select the MySQL size configuration sub wizard_show_mysize { print &ui_table_row(undef, $text{'wizard_mysize'}, 2); local $mem = &get_real_memory_size(); local $mysize = $config{'mysql_size'}; if ($mem && !$mysize) { $mysize = $mem <= 256*1024*1024 ? "small" : $mem <= 512*1024*1024 ? "medium" : $mem <= 1024*1024*1024 ? "large" : "huge"; } print &ui_table_row($text{'wizard_mysize_type'}, &ui_radio("mysize", $mysize, [ [ "", $text{'wizard_mysize_def'}."<br>" ], [ "small", $text{'wizard_mysize_small'}."<br>" ], [ "medium", $text{'wizard_mysize_medium'}."<br>" ], [ "large", $text{'wizard_mysize_large'}."<br>" ], [ "huge", $text{'wizard_mysize_huge'}."<br>" ] ])); } sub wizard_parse_mysize { local ($in) = @_; &require_mysql(); if ($in->{'mysize'}) { # Stop MySQL local $running = &mysql::is_mysql_running(); if ($running) { &mysql::stop_mysql(); } # Adjust my.cnf my $temp = &transname(); ©_source_dest($mysql::config{'my_cnf'}, $temp); &lock_file($mysql::config{'my_cnf'}); my $conf = &mysql::get_mysql_config(); foreach my $s (&list_mysql_size_settings($in->{'mysize'})) { my $sname = $s->[2] || "mysqld"; my ($sect) = grep { $_->{'name'} eq $sname && $_->{'members'} } @$conf; if ($sect) { &mysql::save_directive($conf, $sect, $s->[0], $s->[1] ? [ $s->[1] ] : [ ]); } } &flush_file_lines($mysql::config{'my_cnf'}); &unlock_file($mysql::config{'my_cnf'}); $config{'mysql_size'} = $in->{'mysize'}; # Start it up again if ($running) { &mysql::stop_mysql(); my $err = &mysql::start_mysql(); if ($err) { # Panic! MySQL couldn't start with the new config .. # try to roll it back ©_source_dest($temp, $mysql::config{'my_cnf'}); &mysql::start_mysql(); return &text('wizard_emysizestart', $err); } } } &lock_file($module_config_file); &save_module_config(); &unlock_file($module_config_file); return undef; } # Show a form to set the primary nameservers sub wizard_show_dns { &require_bind(); print &ui_table_row(undef, $text{'wizard_dns'}, 2); # Primary nameserver local $tmpl = &get_template(0); local $tmaster = $tmpl->{'dns_master'} eq 'none' ? undef : $tmpl->{'dns_master'}; local $master = $tmaster || $bconfig{'default_prins'} || &get_system_hostname(); print &ui_table_row($text{'wizard_dns_prins'}, &ui_textbox("prins", $master, 40)." ". &ui_checkbox("prins_skip", 1, $text{'wizard_dns_skip'}, 0)); # Secondaries (optional) local @secns = split(/\s+/, $tmpl->{'dns_ns'}); print &ui_table_row($text{'wizard_dns_secns'}, &ui_textarea("secns", join("", map { "$_\n" } @secns), 4, 40)); } sub wizard_parse_dns { local ($in) = @_; &require_bind(); local @tmpls = &list_templates(); local ($tmpl) = grep { $_->{'id'} eq '0' } @tmpls; # Validate primary NS $in->{'prins'} =~ /^[a-z0-9\.\_\-]+$/i || return $text{'wizard_dns_eprins'}; if (!$in->{'prins_skip'}) { &to_ipaddress($in->{'prins'}) || return $text{'wizard_dns_eprins2'}; local ($ok, $msg) = &check_resolvability($in->{'prins'}); if (!$ok) { return &text('wizard_dns_eprins3', $msg); } } $tmpl->{'dns_master'} = $in->{'prins'}; &save_template($tmpl); # Validate any secondary NSs local @secns; foreach my $ns (split(/\s+/, $in->{'secns'})) { $ns =~ /^[a-z0-9\.\_\-]+$/i || return &text('wizard_dns_esecns', $ns); if (!$in->{'prins_skip'}) { &to_ipaddress($ns) || return &text('wizard_dns_esecns2', $ns); local ($ok, $msg) = &check_resolvability($ns); if (!$ok) { return &text('wizard_dns_esecns3', $ns, $msg); } } push(@secns, $ns); } $tmpl->{'dns_ns'} = join(" ", @secns); &save_template($tmpl); } sub wizard_show_done { print &ui_table_row(undef, &text('wizard_done', 'edit_newfeatures.cgi', 'edit_newsv.cgi'), 2); } sub wizard_parse_done { return undef; # Always works } sub wizard_show_hashpass { print &ui_table_row(undef, $text{'wizard_hashpass'}, 2); local $tmpl = &get_template(0); print &ui_table_row($text{'wizard_hashpass_mode'}, &ui_radio("hashpass", $tmpl->{'hashpass'} ? 1 : 0, [ [ 0, $text{'wizard_hashpass_mode0'}."<br>" ], [ 1, $text{'wizard_hashpass_mode1'} ] ])); print &ui_table_row(undef, "<b>$text{'wizard_hashpass_warn'}</b>", 2); } sub wizard_parse_hashpass { local ($in) = @_; # Update default template local @tmpls = &list_templates(); local ($tmpl) = grep { $_->{'id'} eq '0' } @tmpls; $tmpl->{'hashpass'} = $in->{'hashpass'}; &save_template($tmpl); # If not storing hashed passwords, need to have Usermin read mail files directly if ($in->{'hashpass'} && &foreign_check("usermin")) { # Make sure read mail module is installed, and setup to use local # mail files &foreign_require("usermin", "usermin-lib.pl"); return undef if (!&usermin::get_usermin_module_info("mailbox")); my %mconfig; my $cfile = "$usermin::config{'usermin_dir'}/mailbox/config"; &lock_file($cfile); &read_file($cfile, \%mconfig); return undef if ($mconfig{'mail_system'} != 4); # Force use of local mail files instead my ($mail_base, $mail_style, $mail_file, $mail_dir) = &get_mail_style(); if ($mail_dir) { $mconfig{'mail_system'} = 1; $mconfig{'mail_qmail'} = $mail_base; $mconfig{'mail_style'} = $mail_style; $mconfig{'mail_dir_qmail'} = $mail_dir; } else { $mconfig{'mail_system'} = 0; $mconfig{'mail_dir'} = $mail_base; $mconfig{'mail_style'} = $mail_style; $mconfig{'mail_file'} = $mail_file; } &write_file($cfile, \%mconfig); &unlock_file($cfile); } return undef; } sub wizard_show_xfs { print &ui_table_row(undef, $text{'wizard_xfs'}, 2); local $xfs = &needs_xfs_quota_fix(); if ($xfs == 1) { print &ui_table_row(undef, $text{'wizard_xfsreboot'}, 2); } elsif ($xfs == 2) { print &ui_table_row($text{'wizard_xfsgrub'}, &ui_radio("enable", 1, [ [ 0, $text{'wizard_xfsgrub0'} ], [ 1, $text{'wizard_xfsgrub1'} ] ])); } elsif ($xfs == 3) { print &ui_table_row(undef, $text{'wizard_xfsnoidea'}, 2); } } sub wizard_parse_xfs { local ($in) = @_; if ($in{'enable'}) { # Update the grub config file source my $grubfile = "/etc/default/grub"; my %grub; &read_env_file($grubfile, \%grub) || return &text('wizard_egrubfile', "<tt>$grubfile</tt>"); my $v = $grub{'GRUB_CMDLINE_LINUX'}; $v || return &text('wizard_egrubline', "<tt>GRUB_CMDLINE_LINUX</tt>"); if ($v =~ /rootflags=(\S+)/) { $v =~ s/rootflags=(\S+)/rootflags=$1,uquota,gquota/; } else { $v .= " rootflags=uquota,gquota"; } $grub{'GRUB_CMDLINE_LINUX'} = $v; &write_env_file($grubfile, \%grub); # Generate a new actual config file ©_source_dest("/boot/grub2/grub.cfg", "/boot/grub2/grub.cfg.orig"); my $out = &backquote_logged( "grub2-mkconfig -o /boot/grub2/grub.cfg 2>&1 </dev/null"); $? && return "<tt>".&html_escape($out)."</tt>"; } return undef; } # get_real_memory_size() # Returns the amount of RAM in bytes, or undef if we can't get it sub get_real_memory_size { return undef if (!&foreign_check("proc")); &foreign_require("proc"); return undef if (!defined(&proc::get_memory_info)); local ($real) = &proc::get_memory_info(); return $real * 1024; } # get_uname_arch() # Returns the architecture, like x86_64 or i386 sub get_uname_arch { local $out = &backquote_command("uname -m"); $out =~ s/\s+//g; return $out; } # needs_xfs_quota_fix() # Checks if quotas are enabled on the /home filesystem in /etc/fstab but # not for real in /etc/mtab. Returns 0 if all is OK, 1 if just a reboot is # needed, 2 if GRUB needs to be configured, or 3 if we don't know how to # fix GRUB. sub needs_xfs_quota_fix { return 0 if ($gconfig{'os_type'} !~ /-linux$/); # Some other OS return 0 if (!$config{'quotas'}); # Quotas not even in use return 0 if ($config{'quota_commands'}); # Using external commands &require_useradmin(); return 0 if (!$home_base); # Don't know base dir return 0 if (&running_in_zone()); # Zones have no quotas local ($home_mtab, $home_fstab) = &mount_point($home_base); return 0 if (!$home_mtab || !$home_fstab); # No mount found? return 0 if ($home_mtab->[2] ne "xfs"); # Other FS type return 0 if ($home_mtab->[0] ne "/"); # /home is not on the / FS return 0 if (!"a::quota_can($home_mtab, # Not enabled in fstab $home_fstab)); local $now = "a::quota_now($home_mtab, $home_fstab); $now -= 4 if ($now >= 4); # Ignore XFS always bit return 0 if ($now); # Already enabled in mtab # At this point, we are definite in a bad state my $grubfile = "/etc/default/grub"; return 3 if (!-r $grubfile); my %grub; &read_env_file($grubfile, \%grub); return 3 if (!$grub{'GRUB_CMDLINE_LINUX'}); # Enabled already, so just need to reboot return 1 if ($grub{'GRUB_CMDLINE_LINUX'} =~ /rootflags=\S*uquota,gquota/ || $grub{'GRUB_CMDLINE_LINUX'} =~ /rootflags=\S*gquota,uquota/); # Otherwise, flags need adding return 2; } 1;y~or5J={Eeu磝Qk ᯘG{?+]ן?wM3X^歌>{7پK>on\jy Rg/=fOroNVv~Y+ NGuÝHWyw[eQʨSb> >}Gmx[o[<{Ϯ_qFvM IENDB`