Lines 47-62
Link Here
|
47 |
|
47 |
|
48 |
#__DATA__ |
48 |
#__DATA__ |
49 |
|
49 |
|
50 |
# read_file(file, &assoc, [&order], [lowercase]) |
50 |
# read_file(file, &assoc, [&order], [lowercase], [split-char]) |
51 |
# Fill an associative array with name=value pairs from a file |
51 |
# Fill an associative array with name=value pairs from a file |
52 |
sub read_file |
52 |
sub read_file |
53 |
{ |
53 |
{ |
54 |
local $_; |
54 |
local $_; |
|
|
55 |
local $split = defined($_[4]) ? $_[4] : "="; |
55 |
open(ARFILE, $_[0]) || return 0; |
56 |
open(ARFILE, $_[0]) || return 0; |
56 |
while(<ARFILE>) { |
57 |
while(<ARFILE>) { |
57 |
chomp; |
58 |
chomp; |
58 |
local $hash = index($_, "#"); |
59 |
local $hash = index($_, "#"); |
59 |
local $eq = index($_, "="); |
60 |
local $eq = index($_, $split); |
60 |
if ($hash != 0 && $eq >= 0) { |
61 |
if ($hash != 0 && $eq >= 0) { |
61 |
local $n = substr($_, 0, $eq); |
62 |
local $n = substr($_, 0, $eq); |
62 |
local $v = substr($_, $eq+1); |
63 |
local $v = substr($_, $eq+1); |
Lines 80-107
Link Here
|
80 |
} |
81 |
} |
81 |
else { |
82 |
else { |
82 |
local %d; |
83 |
local %d; |
83 |
&read_file($_[0], \%d); |
84 |
&read_file($_[0], \%d, $_[2], $_[3], $_[4]); |
84 |
%{$main::read_file_cache{$_[0]}} = %d; |
85 |
%{$main::read_file_cache{$_[0]}} = %d; |
85 |
%{$_[1]} = ( %{$_[1]}, %d ); |
86 |
%{$_[1]} = ( %{$_[1]}, %d ); |
86 |
} |
87 |
} |
87 |
} |
88 |
} |
88 |
|
89 |
|
89 |
# write_file(file, array) |
90 |
# write_file(file, array, [join-char]) |
90 |
# Write out the contents of an associative array as name=value lines |
91 |
# Write out the contents of an associative array as name=value lines |
91 |
sub write_file |
92 |
sub write_file |
92 |
{ |
93 |
{ |
93 |
local(%old, @order); |
94 |
local(%old, @order); |
|
|
95 |
local $join = defined($_[2]) ? $_[2] : "="; |
94 |
&read_file($_[0], \%old, \@order); |
96 |
&read_file($_[0], \%old, \@order); |
95 |
open(ARFILE, ">$_[0]") || &error(&text("efilewrite", $_[0], $!)); |
97 |
open(ARFILE, ">$_[0]") || &error(&text("efilewrite", $_[0], $!)); |
96 |
foreach $k (@order) { |
98 |
foreach $k (@order) { |
97 |
if (exists($_[1]->{$k})) { |
99 |
if (exists($_[1]->{$k})) { |
98 |
(print ARFILE $k,"=",$_[1]->{$k},"\n") || |
100 |
(print ARFILE $k,$join,$_[1]->{$k},"\n") || |
99 |
&error(&text("efilewrite", $_[0], $!)); |
101 |
&error(&text("efilewrite", $_[0], $!)); |
100 |
} |
102 |
} |
101 |
} |
103 |
} |
102 |
foreach $k (keys %{$_[1]}) { |
104 |
foreach $k (keys %{$_[1]}) { |
103 |
if (!exists($old{$k})) { |
105 |
if (!exists($old{$k})) { |
104 |
(print ARFILE $k,"=",$_[1]->{$k},"\n") || |
106 |
(print ARFILE $k,$join,$_[1]->{$k},"\n") || |
105 |
&error(&text("efilewrite", $_[0], $!)); |
107 |
&error(&text("efilewrite", $_[0], $!)); |
106 |
} |
108 |
} |
107 |
} |
109 |
} |
Lines 145-161
Link Here
|
145 |
@remote_user_info ? $tmp_base."-".$remote_user : |
147 |
@remote_user_info ? $tmp_base."-".$remote_user : |
146 |
$< != 0 ? $tmp_base."-".getpwuid($<) : |
148 |
$< != 0 ? $tmp_base."-".getpwuid($<) : |
147 |
$tmp_base; |
149 |
$tmp_base; |
148 |
while(1) { |
150 |
local $tries = 0; |
|
|
151 |
while($tries++ < 10) { |
149 |
local @st = lstat($tmp_dir); |
152 |
local @st = lstat($tmp_dir); |
150 |
last if ($st[4] == $< && (-d _) && ($st[2] & 0777) == 0755); |
153 |
last if ($st[4] == $< && (-d _) && ($st[2] & 0777) == 0755); |
151 |
if (@st) { |
154 |
if (@st) { |
152 |
unlink($tmp_dir) || rmdir($tmp_dir) || |
155 |
unlink($tmp_dir) || rmdir($tmp_dir) || |
153 |
system("/bin/rm -rf \"$tmp_dir\""); |
156 |
system("/bin/rm -rf ".quotemeta($tmp_dir)); |
154 |
} |
157 |
} |
155 |
mkdir($tmp_dir, 0755) || next; |
158 |
mkdir($tmp_dir, 0755) || next; |
156 |
chown($<, $(, $tmp_dir); |
159 |
chown($<, $(, $tmp_dir); |
157 |
chmod(0755, $tmp_dir); |
160 |
chmod(0755, $tmp_dir); |
158 |
} |
161 |
} |
|
|
162 |
&error("Failed to create temp directory $tmp_dir") if ($tries >= 10); |
159 |
if (defined($_[0]) && $_[0] !~ /\.\./) { |
163 |
if (defined($_[0]) && $_[0] !~ /\.\./) { |
160 |
return "$tmp_dir/$_[0]"; |
164 |
return "$tmp_dir/$_[0]"; |
161 |
} |
165 |
} |
Lines 182-196
Link Here
|
182 |
return $str; |
186 |
return $str; |
183 |
} |
187 |
} |
184 |
|
188 |
|
185 |
# indexof |
189 |
# indexof(string, array) |
186 |
# Returns the index of some value in an array, or -1 |
190 |
# Returns the index of some value in an array, or -1 |
187 |
sub indexof { |
191 |
sub indexof { |
188 |
local($i); |
192 |
local($i); |
189 |
for($i=1; $i <= $#_; $i++) { |
193 |
for($i=1; $i <= $#_; $i++) { |
190 |
if ($_[$i] eq $_[0]) { return $i - 1; } |
194 |
if ($_[$i] eq $_[0]) { return $i - 1; } |
191 |
} |
|
|
192 |
return -1; |
193 |
} |
195 |
} |
|
|
196 |
return -1; |
197 |
} |
194 |
|
198 |
|
195 |
# unique |
199 |
# unique |
196 |
# Returns the unique elements of some array |
200 |
# Returns the unique elements of some array |
Lines 560-567
Link Here
|
560 |
if (!$_[4] && !$tconfig{'nomoduleindex'}) { |
564 |
if (!$_[4] && !$tconfig{'nomoduleindex'}) { |
561 |
local $idx = $module_info{'index_link'}; |
565 |
local $idx = $module_info{'index_link'}; |
562 |
local $mi = $module_index_link || "/$module_name/$idx"; |
566 |
local $mi = $module_index_link || "/$module_name/$idx"; |
563 |
print "<a href=\"$gconfig{'webprefix'}$mi\">", |
567 |
local $mt = $module_index_name || $text{'header_module'}; |
564 |
"$text{'header_module'}</a><br>\n"; |
568 |
print "<a href=\"$gconfig{'webprefix'}$mi\">$mt</a><br>\n"; |
565 |
} |
569 |
} |
566 |
if (ref($_[2]) eq "ARRAY" && !$ENV{'ANONYMOUS_USER'}) { |
570 |
if (ref($_[2]) eq "ARRAY" && !$ENV{'ANONYMOUS_USER'}) { |
567 |
print &hlink($text{'header_help'}, $_[2]->[0], $_[2]->[1]), |
571 |
print &hlink($text{'header_help'}, $_[2]->[0], $_[2]->[1]), |
Lines 701-713
Link Here
|
701 |
$prot = uc($ENV{'HTTPS'}) eq "ON" ? "https" : "http"; |
705 |
$prot = uc($ENV{'HTTPS'}) eq "ON" ? "https" : "http"; |
702 |
local $wp = $gconfig{'webprefixnoredir'} ? undef : $gconfig{'webprefix'}; |
706 |
local $wp = $gconfig{'webprefixnoredir'} ? undef : $gconfig{'webprefix'}; |
703 |
if ($_[0] =~ /^(http|https|ftp|gopher):/) { |
707 |
if ($_[0] =~ /^(http|https|ftp|gopher):/) { |
|
|
708 |
# Absolute URL (like http://...) |
704 |
$url = $_[0]; |
709 |
$url = $_[0]; |
705 |
} |
710 |
} |
706 |
elsif ($_[0] =~ /^\//) { |
711 |
elsif ($_[0] =~ /^\//) { |
|
|
712 |
# Absolute path (like /foo/bar.cgi) |
707 |
$url = "$prot://$ENV{'SERVER_NAME'}$port$wp$_[0]"; |
713 |
$url = "$prot://$ENV{'SERVER_NAME'}$port$wp$_[0]"; |
708 |
} |
714 |
} |
709 |
elsif ($ENV{'SCRIPT_NAME'} =~ /^(.*)\/[^\/]*$/) { |
715 |
elsif ($ENV{'SCRIPT_NAME'} =~ /^(.*)\/[^\/]*$/) { |
710 |
$url = "$prot://$ENV{'SERVER_NAME'}$port$1/$wp$_[0]"; |
716 |
# Relative URL (like foo.cgi) |
|
|
717 |
$url = "$prot://$ENV{'SERVER_NAME'}$port$wp$1/$_[0]"; |
711 |
} |
718 |
} |
712 |
else { |
719 |
else { |
713 |
$url = "$prot://$ENV{'SERVER_NAME'}$port/$wp$_[0]"; |
720 |
$url = "$prot://$ENV{'SERVER_NAME'}$port/$wp$_[0]"; |
Lines 1226-1231
Link Here
|
1226 |
if ($_[3]) { ${$_[3]} = "Failed to lookup IP address for $_[0]"; return 0; } |
1233 |
if ($_[3]) { ${$_[3]} = "Failed to lookup IP address for $_[0]"; return 0; } |
1227 |
else { &error("Failed to lookup IP address for $_[0]"); } |
1234 |
else { &error("Failed to lookup IP address for $_[0]"); } |
1228 |
} |
1235 |
} |
|
|
1236 |
if ($gconfig{'bind_proxy'}) { |
1237 |
if (!bind($h, pack_sockaddr_in(0, inet_aton($gconfig{'bind_proxy'})))) { |
1238 |
if ($_[3]) { ${$_[3]} = "Failed to bind to source address : $!"; return 0; } |
1239 |
else { &error("Failed to bind to source address : $!"); } |
1240 |
} |
1241 |
} |
1229 |
if (!connect($h, pack_sockaddr_in($_[1], $addr))) { |
1242 |
if (!connect($h, pack_sockaddr_in($_[1], $addr))) { |
1230 |
if ($_[3]) { ${$_[3]} = "Failed to connect to $_[0]:$_[1] : $!"; return 0; } |
1243 |
if ($_[3]) { ${$_[3]} = "Failed to connect to $_[0]:$_[1] : $!"; return 0; } |
1231 |
else { &error("Failed to connect to $_[0]:$_[1] : $!"); } |
1244 |
else { &error("Failed to connect to $_[0]:$_[1] : $!"); } |
Lines 1320-1326
Link Here
|
1320 |
if ($i%$cols == 0) { print "<tr>\n"; } |
1333 |
if ($i%$cols == 0) { print "<tr>\n"; } |
1321 |
print "<td width=$per% align=center valign=top>\n"; |
1334 |
print "<td width=$per% align=center valign=top>\n"; |
1322 |
&generate_icon($_[2]->[$i], $_[1]->[$i], $_[0]->[$i], |
1335 |
&generate_icon($_[2]->[$i], $_[1]->[$i], $_[0]->[$i], |
1323 |
$_[4], $_[5], $_[6]); |
1336 |
ref($_[4]) ? $_[4]->[$i] : $_[4], $_[5], $_[6]); |
1324 |
print "</td>\n"; |
1337 |
print "</td>\n"; |
1325 |
if ($i%$cols == $cols-1) { print "</tr>\n"; } |
1338 |
if ($i%$cols == $cols-1) { print "</tr>\n"; } |
1326 |
} |
1339 |
} |
Lines 1570-1575
Link Here
|
1570 |
{ |
1583 |
{ |
1571 |
local $u = defined($_[1]) ? $_[1] : $base_remote_user; |
1584 |
local $u = defined($_[1]) ? $_[1] : $base_remote_user; |
1572 |
local $m = defined($_[2]) ? $_[2] : $module_name; |
1585 |
local $m = defined($_[2]) ? $_[2] : $module_name; |
|
|
1586 |
if (&foreign_check("acl")) { |
1587 |
# Check if this user is a member of a group, and if he gets the |
1588 |
# module from a group. If so, update its ACL as well |
1589 |
&foreign_require("acl", "acl-lib.pl"); |
1590 |
local ($g, $group); |
1591 |
foreach $g (&acl::list_groups()) { |
1592 |
if (&indexof($u, @{$g->{'members'}}) >= 0 && |
1593 |
&indexof($m, @{$g->{'modules'}}) >= 0) { |
1594 |
$group = $g; |
1595 |
last; |
1596 |
} |
1597 |
} |
1598 |
if ($group) { |
1599 |
&save_module_acl($_[0], $group->{'name'}, $m); |
1600 |
} |
1601 |
} |
1573 |
&write_file("$config_directory/$m/$u.acl", $_[0]); |
1602 |
&write_file("$config_directory/$m/$u.acl", $_[0]); |
1574 |
} |
1603 |
} |
1575 |
|
1604 |
|
Lines 2209-2215
Link Here
|
2209 |
} |
2238 |
} |
2210 |
} |
2239 |
} |
2211 |
|
2240 |
|
2212 |
# webmin_log(action, type, object, ¶ms, [module]) |
2241 |
# webmin_log(action, type, object, ¶ms, [module], [host, script-on-host, client-ip]) |
2213 |
# Log some action taken by a user |
2242 |
# Log some action taken by a user |
2214 |
sub webmin_log |
2243 |
sub webmin_log |
2215 |
{ |
2244 |
{ |
Lines 2253-2260
Link Here
|
2253 |
$id, $tm[3], $text{"smonth_".($tm[4]+1)}, $tm[5]+1900, |
2282 |
$id, $tm[3], $text{"smonth_".($tm[4]+1)}, $tm[5]+1900, |
2254 |
$tm[2], $tm[1], $tm[0], |
2283 |
$tm[2], $tm[1], $tm[0], |
2255 |
$remote_user, $main::session_id ? $main::session_id : '-', |
2284 |
$remote_user, $main::session_id ? $main::session_id : '-', |
2256 |
$ENV{'REMOTE_HOST'}, |
2285 |
$_[7] || $ENV{'REMOTE_HOST'}, |
2257 |
$m, $script_name, |
2286 |
$m, $_[5] ? "$_[5]:$_[6]" : $script_name, |
2258 |
$_[0], $_[1] ne '' ? $_[1] : '-', $_[2] ne '' ? $_[2] : '-'; |
2287 |
$_[0], $_[1] ne '' ? $_[1] : '-', $_[2] ne '' ? $_[2] : '-'; |
2259 |
foreach $k (sort { $a cmp $b } keys %{$_[3]}) { |
2288 |
foreach $k (sort { $a cmp $b } keys %{$_[3]}) { |
2260 |
local $v = $_[3]->{$k}; |
2289 |
local $v = $_[3]->{$k}; |
Lines 2278-2283
Link Here
|
2278 |
open(WEBMINLOG, ">>$webmin_logfile"); |
2307 |
open(WEBMINLOG, ">>$webmin_logfile"); |
2279 |
print WEBMINLOG $line,"\n"; |
2308 |
print WEBMINLOG $line,"\n"; |
2280 |
close(WEBMINLOG); |
2309 |
close(WEBMINLOG); |
|
|
2310 |
if ($gconfig{'logperms'}) { |
2311 |
chmod(oct($gconfig{'logperms'}), $webmin_logfile); |
2312 |
} |
2281 |
|
2313 |
|
2282 |
if ($gconfig{'logfiles'}) { |
2314 |
if ($gconfig{'logfiles'}) { |
2283 |
# Find and record the changes made to any locked files |
2315 |
# Find and record the changes made to any locked files |
Lines 2288-2293
Link Here
|
2288 |
print DIFFLOG "$d->{'type'} $d->{'object'}\n"; |
2320 |
print DIFFLOG "$d->{'type'} $d->{'object'}\n"; |
2289 |
print DIFFLOG $d->{'data'}; |
2321 |
print DIFFLOG $d->{'data'}; |
2290 |
close(DIFFLOG); |
2322 |
close(DIFFLOG); |
|
|
2323 |
if ($gconfig{'logperms'}) { |
2324 |
chmod(oct($gconfig{'logperms'}), |
2325 |
"$ENV{'WEBMIN_VAR'}/diffs/$id.$i"); |
2326 |
} |
2291 |
$i++; |
2327 |
$i++; |
2292 |
} |
2328 |
} |
2293 |
@main::locked_file_diff = undef; |
2329 |
@main::locked_file_diff = undef; |
Lines 2894-2899
Link Here
|
2894 |
local $error; |
2930 |
local $error; |
2895 |
if ($gconfig{'http_proxy'} =~ /^http:\/\/(\S+):(\d+)/ && |
2931 |
if ($gconfig{'http_proxy'} =~ /^http:\/\/(\S+):(\d+)/ && |
2896 |
!&no_proxy($_[0])) { |
2932 |
!&no_proxy($_[0])) { |
|
|
2933 |
# Via a proxy |
2897 |
&open_socket($1, $2, $rv->{'fh'}, \$error); |
2934 |
&open_socket($1, $2, $rv->{'fh'}, \$error); |
2898 |
return $error if ($error); |
2935 |
return $error if ($error); |
2899 |
local $fh = $rv->{'fh'}; |
2936 |
local $fh = $rv->{'fh'}; |
Lines 2906-2911
Link Here
|
2906 |
} |
2943 |
} |
2907 |
} |
2944 |
} |
2908 |
else { |
2945 |
else { |
|
|
2946 |
# Connecting directly |
2909 |
&open_socket($_[0], $_[1], $rv->{'fh'}, \$error); |
2947 |
&open_socket($_[0], $_[1], $rv->{'fh'}, \$error); |
2910 |
return $error if ($error); |
2948 |
return $error if ($error); |
2911 |
local $fh = $rv->{'fh'}; |
2949 |
local $fh = $rv->{'fh'}; |
Lines 3123-3128
Link Here
|
3123 |
$rv =~ s/<\s*script[^>]*>([\000-\377]*?)<\s*\/script\s*>//gi; |
3161 |
$rv =~ s/<\s*script[^>]*>([\000-\377]*?)<\s*\/script\s*>//gi; |
3124 |
$rv =~ s/(on(Abort|Blur|Change|Click|DblClick|DragDrop|Error|Focus|KeyDown|KeyPress|KeyUp|Load|MouseDown|MouseMove|MouseOut|MouseOver|MouseUp|Move|Reset|Resize|Select|Submit|Unload)=)/x$1/gi; |
3162 |
$rv =~ s/(on(Abort|Blur|Change|Click|DblClick|DragDrop|Error|Focus|KeyDown|KeyPress|KeyUp|Load|MouseDown|MouseMove|MouseOut|MouseOver|MouseUp|Move|Reset|Resize|Select|Submit|Unload)=)/x$1/gi; |
3125 |
$rv =~ s/(javascript:)/x$1/gi; |
3163 |
$rv =~ s/(javascript:)/x$1/gi; |
|
|
3164 |
$rv =~ s/(vbscript:)/x$1/gi; |
3126 |
return $rv; |
3165 |
return $rv; |
3127 |
} |
3166 |
} |
3128 |
|
3167 |
|
Lines 3310-3319
Link Here
|
3310 |
# Relative URLs can also be parsed, if the base information is provided |
3349 |
# Relative URLs can also be parsed, if the base information is provided |
3311 |
sub parse_http_url |
3350 |
sub parse_http_url |
3312 |
{ |
3351 |
{ |
3313 |
if ($_[0] =~ /^(http|https):\/\/([^:\/]+)(:(\d+))?(\/\S*)$/) { |
3352 |
if ($_[0] =~ /^(http|https):\/\/([^:\/]+)(:(\d+))?(\/\S*)?$/) { |
3314 |
# An absolute URL |
3353 |
# An absolute URL |
3315 |
local $ssl = $1 eq 'https'; |
3354 |
local $ssl = $1 eq 'https'; |
3316 |
return ($2, $3 ? $4 : $ssl ? 443 : 80, $5, $ssl); |
3355 |
return ($2, $3 ? $4 : $ssl ? 443 : 80, $5 || "/", $ssl); |
3317 |
} |
3356 |
} |
3318 |
elsif (!$_[1]) { |
3357 |
elsif (!$_[1]) { |
3319 |
# Could not parse |
3358 |
# Could not parse |
Lines 3436-3453
Link Here
|
3436 |
&write_file("$config_directory/$m/config", $c); |
3475 |
&write_file("$config_directory/$m/config", $c); |
3437 |
} |
3476 |
} |
3438 |
|
3477 |
|
3439 |
# nice_size(bytes) |
3478 |
# nice_size(bytes, [min]) |
3440 |
# Converts a number of bytes into a number of bytes, kb, mb or gb |
3479 |
# Converts a number of bytes into a number of bytes, kb, mb or gb |
3441 |
sub nice_size |
3480 |
sub nice_size |
3442 |
{ |
3481 |
{ |
3443 |
if ($_[0] > 10*1024*1024*1024) { |
3482 |
if ($_[0] > 10*1024*1024*1024 || $_[1] >= 1024*1024*1024) { |
3444 |
return int($_[0]/1024/1024/1024)." GB"; |
3483 |
return int(($_[0]+1024*1024*1024-1)/1024/1024/1024)." GB"; |
3445 |
} |
3484 |
} |
3446 |
elsif ($_[0] > 10*1024*1024) { |
3485 |
elsif ($_[0] > 10*1024*1024 || $_[1] >= 1024*1024) { |
3447 |
return int($_[0]/1024/1024)." MB"; |
3486 |
return int(($_[0]+1024*1024-1)/1024/1024)." MB"; |
3448 |
} |
3487 |
} |
3449 |
elsif ($_[0] > 10*1024) { |
3488 |
elsif ($_[0] > 10*1024 || $_[1] >= 1024) { |
3450 |
return int($_[0]/1024)." kB"; |
3489 |
return int(($_[0]+1024-1)/1024)." kB"; |
3451 |
} |
3490 |
} |
3452 |
else { |
3491 |
else { |
3453 |
return int($_[0])." bytes"; |
3492 |
return int($_[0])." bytes"; |
Lines 3484-3488
Link Here
|
3484 |
return undef; |
3523 |
return undef; |
3485 |
} |
3524 |
} |
3486 |
|
3525 |
|
|
|
3526 |
# select_all_link(field, form, text) |
3527 |
# Returns HTML for a 'Select all' link that uses Javascript to select |
3528 |
# multiple checkboxes with the same name |
3529 |
sub select_all_link |
3530 |
{ |
3531 |
local ($field, $form, $text) = @_; |
3532 |
$form = int($form); |
3533 |
$text ||= "Select all"; |
3534 |
return "<a href='' onClick='document.forms[$form].$field.checked = true; for(i=0; i<document.forms[$form].$field.length; i++) { document.forms[$form].${field}[i].checked = true; } return false'>$text</a>"; |
3535 |
} |
3536 |
|
3537 |
# select_all_link(field, form, text) |
3538 |
# Returns HTML for a 'Select all' link that uses Javascript to invert the |
3539 |
# selection on multiple checkboxes with the same name |
3540 |
sub select_invert_link |
3541 |
{ |
3542 |
local ($field, $form, $text) = @_; |
3543 |
$form = int($form); |
3544 |
$text ||= "Invert selection"; |
3545 |
return "<a href='' onClick='document.forms[$form].$field.checked = !document.forms[$form].$field.checked; for(i=0; i<document.forms[$form].$field.length; i++) { document.forms[$form].${field}[i].checked = !document.forms[$form].${field}[i].checked; } return false'>$text</a>"; |
3546 |
} |
3547 |
|
3487 |
1; # return true? |
3548 |
1; # return true? |
3488 |
|
3549 |
|