1#!/usr/local/bin/perl 2# change_bind.cgi 3# Update the binding IP address and port for miniserv 4 5require './usermin-lib.pl'; 6$access{'bind'} || &error($text{'acl_ecannot'}); 7use Socket; 8&ReadParse(); 9&get_usermin_miniserv_config(\%miniserv); 10%oldminiserv = %miniserv; 11&error_setup($text{'bind_err'}); 12 13# Validate inputs 14for($i=0; defined($in{"ip_def_$i"}); $i++) { 15 next if (!$in{"ip_def_$i"}); 16 if ($in{"ip_def_$i"} == 1) { 17 $ip = "*"; 18 } 19 else { 20 $ip = $in{"ip_$i"}; 21 &check_ipaddress($ip) || 22 $in{'ipv6'} && &check_ip6address($ip) || 23 &error(&text('bind_eip2', $ip)); 24 } 25 if ($in{"port_def_$i"} == 1) { 26 $port = $in{"port_$i"}; 27 $port =~ /^\d+$/ && $port < 65536 || 28 &error(&text('bind_eport2', $port)); 29 } 30 else { 31 $port = "*"; 32 } 33 push(@sockets, [ $ip, $port ]); 34 push(@ports, $port) if ($port && $port ne "*"); 35 } 36@sockets || &error($text{'bind_enone'}); 37$in{'hostname_def'} || $in{'hostname'} =~ /^[a-z0-9\.\-]+$/i || 38 &error($text{'bind_ehostname'}); 39if ($in{'ipv6'}) { 40 eval "use Socket6"; 41 $@ && &error(&text('bind_eipv6', "<tt>Socket6</tt>")); 42 } 43 44# For any new ports, check if they are already in use 45@oldports = split(/\s+/, $in{'oldports'}); 46@newports = &unique(grep { &indexof($_, @oldports) < 0 } @ports); 47if (&has_command("lsof")) { 48 foreach my $p (@newports) { 49 $out = &backquote_command("lsof -t -i tcp:$p 2>/dev/null"); 50 if ($out =~ /\d+/) { 51 &error(&text('bind_elsof', $p)); 52 } 53 } 54 } 55 56# Update config file 57&lock_file($usermin_miniserv_config); 58$first = shift(@sockets); 59$miniserv{'port'} = $first->[1]; 60if ($first->[0] eq "*") { 61 delete($miniserv{'bind'}); 62 } 63else { 64 $miniserv{'bind'} = $first->[0]; 65 } 66$miniserv{'sockets'} = join(" ", map { "$_->[0]:$_->[1]" } @sockets); 67$miniserv{'ipv6'} = $in{'ipv6'}; 68if ($in{'listen_def'}) { 69 delete($miniserv{'listen'}); 70 } 71else { 72 $miniserv{'listen'} = $in{'listen'}; 73 } 74if ($in{'hostname_def'}) { 75 delete($miniserv{'host'}); 76 } 77else { 78 $miniserv{'host'} = $in{'hostname'}; 79 } 80&put_usermin_miniserv_config(\%miniserv); 81&unlock_file($usermin_miniserv_config); 82 83# Attempt to re-start miniserv 84$SIG{'TERM'} = 'ignore'; 85&system_logged("$config{'usermin_dir'}/stop >/dev/null 2>&1 </dev/null"); 86$temp = &transname(); 87$rv = &system_logged("$config{'usermin_dir'}/start >$temp 2>&1 </dev/null"); 88$out = &read_file_contents($temp); 89$out =~ s/^Starting Usermin server in.*\n//; 90$out =~ s/at.*line.*//; 91unlink($temp); 92if ($rv) { 93 # Failed! Roll back config and start again 94 &lock_file($usermin_miniserv_config); 95 &put_usermin_miniserv_config(\%oldminiserv); 96 &unlock_file($usermin_miniserv_config); 97 &system_logged("$config{'usermin_dir'}/start >/dev/null 2>&1 </dev/null"); 98 &error(&text('bind_erestart', $out)); 99 } 100 101# If possible, open the new ports 102foreach my $mod ("firewall", "firewalld") { 103 if (&foreign_check($mod) && $in{'firewall'}) { 104 if (@newports) { 105 &clean_environment(); 106 $ENV{'WEBMIN_CONFIG'} = $config_directory; 107 &system_logged( 108 &module_root_directory($mod)."/open-ports.pl ". 109 join(" ", map { $_.":".($_+10) } @newports). 110 " >/dev/null 2>&1"); 111 &reset_environment(); 112 } 113 } 114 } 115 116&webmin_log("bind", undef, undef, \%in); 117 118&redirect(""); 119 120