mirror of
https://github.com/webmin/webmin.git
synced 2025-08-17 19:06:28 +00:00
PHP ini file IO user restriction
This commit is contained in:
File diff suppressed because one or more lines are too long
@ -1,2 +1,4 @@
|
||||
---- Changes since 1.310 ----
|
||||
First version of this module, which can edit the global PHP configuration file and other per-domain files.
|
||||
---- Changes since 1.480 ----
|
||||
Added an access control option to limit file IO to a particular Unix user.
|
||||
|
@ -17,6 +17,9 @@ print &ui_table_row($text{'acl_manual'},
|
||||
print &ui_table_row($text{'acl_inis'},
|
||||
&ui_textarea("inis", join("\n", split(/\t+/, $o->{'php_inis'})),
|
||||
5, 70), 3);
|
||||
|
||||
print &ui_table_row($text{'acl_user'},
|
||||
&ui_user_textbox("user", $o->{'user'}));
|
||||
}
|
||||
|
||||
# acl_security_save(&options)
|
||||
@ -28,5 +31,6 @@ $o->{'global'} = $in{'global'};
|
||||
$o->{'anyfile'} = $in{'anyfile'};
|
||||
$o->{'manual'} = $in{'manual'};
|
||||
$o->{'php_inis'} = join("\t", split(/\n/, $in{'inis'}));
|
||||
$o->{'user'} = $in{'user'};
|
||||
}
|
||||
|
||||
|
@ -1,3 +1,4 @@
|
||||
global=1
|
||||
anyfile=1
|
||||
manual=1
|
||||
user=root
|
||||
|
@ -4,7 +4,7 @@
|
||||
require './phpini-lib.pl';
|
||||
&ReadParse();
|
||||
&can_php_config($in{'file'}) || &error($text{'list_ecannot'});
|
||||
$conf = &get_config($in{'file'});
|
||||
$conf = &get_config_as_user($in{'file'});
|
||||
|
||||
&ui_print_header("<tt>$in{'file'}</tt>", $text{'vars_title'}, "");
|
||||
|
||||
|
@ -11,6 +11,7 @@ index_anyfile=Edit other PHP configuration file:
|
||||
index_return=configuration files
|
||||
|
||||
file_global=Global PHP configuration
|
||||
file_eread=Failed to read $1 : $2
|
||||
|
||||
manual_title=Edit Configuration Manually
|
||||
manual_desc=This page can be used to manually edit a PHP configuration file. This should be done carefully, as no syntax or other validity checking will be performed on your changes.
|
||||
@ -166,3 +167,4 @@ acl_global=Can edit global PHP configuration?
|
||||
acl_anyfile=Can edit any file as a PHP configuration?
|
||||
acl_manual=Can manually edit configuration files?
|
||||
acl_inis=Additional configuration files<br>(In <i>filename</i>=<i>description</i> format)
|
||||
acl_user=Read and write files as user
|
||||
|
@ -15,7 +15,7 @@ if (!defined($get_config_cache{$file})) {
|
||||
local @rv = ( );
|
||||
local $lnum = 0;
|
||||
local $section;
|
||||
open(CONFIG, $file);
|
||||
open(CONFIG, $file) || return undef;
|
||||
while(<CONFIG>) {
|
||||
s/\r|\n//g;
|
||||
s/\s+$//;
|
||||
@ -194,5 +194,37 @@ if (&foreign_installed("apache")) {
|
||||
}
|
||||
}
|
||||
|
||||
# get_config_as_user([file])
|
||||
# Like get_config, but reads with permissions of the ACL user
|
||||
sub get_config_as_user
|
||||
{
|
||||
local ($file) = @_;
|
||||
if ($access{'user'} && $access{'user'} ne 'root' && $< == 0) {
|
||||
local $rv = &eval_as_unix_user(
|
||||
$access{'user'}, sub { &get_config($file) });
|
||||
if ((!$rv || !@$rv) && $!) {
|
||||
&error(&text('file_eread', &html_escape($file), $!));
|
||||
}
|
||||
return $rv;
|
||||
}
|
||||
else {
|
||||
return &get_config($file);
|
||||
}
|
||||
}
|
||||
|
||||
# flush_file_lines_as_user(file)
|
||||
# Writes out a file as the Unix user configured in this module's ACL
|
||||
sub flush_file_lines_as_user
|
||||
{
|
||||
local ($file) = @_;
|
||||
if ($access{'user'} && $access{'user'} ne 'root' && $< == 0) {
|
||||
&eval_as_unix_user($access{'user'},
|
||||
sub { &flush_file_lines($file) });
|
||||
}
|
||||
else {
|
||||
&flush_file_lines($file);
|
||||
}
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
|
@ -89,7 +89,7 @@ else {
|
||||
$in{"pgsql.max_links"});
|
||||
}
|
||||
|
||||
&flush_file_lines($in{'file'});
|
||||
&flush_file_lines_as_user($in{'file'});
|
||||
&unlock_file($in{'file'});
|
||||
&graceful_apache_restart();
|
||||
&webmin_log("db", undef, $in{'file'});
|
||||
|
@ -27,7 +27,7 @@ $in{'ext_def'} || $in{'ext'} =~ /\S/ || &error($text{'dirs_eext'});
|
||||
$in{'utmp_def'} || -d $in{'utmp'} || &error($text{'dirs_eutmp'});
|
||||
&save_directive($conf, "upload_tmp_dir", $in{'utmp_def'} ? undef : $in{'utmp'});
|
||||
|
||||
&flush_file_lines($in{'file'});
|
||||
&flush_file_lines_as_user($in{'file'});
|
||||
&unlock_file($in{'file'});
|
||||
&graceful_apache_restart();
|
||||
&webmin_log("dirs", undef, $in{'file'});
|
||||
|
@ -51,7 +51,7 @@ elsif ($in{"error_log_def"} == 2) {
|
||||
&save_directive($conf, "error_log", $in{"error_log"});
|
||||
}
|
||||
|
||||
&flush_file_lines($in{'file'});
|
||||
&flush_file_lines_as_user($in{'file'});
|
||||
&unlock_file($in{'file'});
|
||||
&graceful_apache_restart();
|
||||
&webmin_log("errors", undef, $in{'file'});
|
||||
|
@ -41,7 +41,7 @@ $in{"max_input_time_def"} || $in{"max_input_time"} =~ /^\d+$/ ||
|
||||
&save_directive($conf, "max_input_time",
|
||||
$in{"max_input_time_def"} ? undef : $in{"max_input_time"});
|
||||
|
||||
&flush_file_lines($in{'file'});
|
||||
&flush_file_lines_as_user($in{'file'});
|
||||
&unlock_file($in{'file'});
|
||||
&graceful_apache_restart();
|
||||
&webmin_log("limits", undef, $in{'file'});
|
||||
|
@ -45,7 +45,7 @@ else {
|
||||
&save_directive($conf, "sendmail_path", $in{"sendmail_path"});
|
||||
}
|
||||
|
||||
&flush_file_lines($in{'file'});
|
||||
&flush_file_lines_as_user($in{'file'});
|
||||
&unlock_file($in{'file'});
|
||||
&graceful_apache_restart();
|
||||
&webmin_log("misc", undef, $in{'file'});
|
||||
|
@ -25,7 +25,7 @@ foreach $d ([ "safe_mode_include_dir", "safe_einclude" ],
|
||||
}
|
||||
}
|
||||
|
||||
&flush_file_lines($in{'file'});
|
||||
&flush_file_lines_as_user($in{'file'});
|
||||
&unlock_file($in{'file'});
|
||||
&graceful_apache_restart();
|
||||
&webmin_log("safe", undef, $in{'file'});
|
||||
|
@ -43,7 +43,7 @@ else {
|
||||
$in{"session.gc_maxlifetime"});
|
||||
}
|
||||
|
||||
&flush_file_lines($in{'file'});
|
||||
&flush_file_lines_as_user($in{'file'});
|
||||
&unlock_file($in{'file'});
|
||||
&graceful_apache_restart();
|
||||
&webmin_log("session", undef, $in{'file'});
|
||||
|
@ -14,7 +14,7 @@ foreach $v ("magic_quotes_gpc", "magic_quotes_runtime",
|
||||
"register_argc_argv") {
|
||||
&save_directive($conf, $v, $in{$v} || undef);
|
||||
}
|
||||
&flush_file_lines($in{'file'});
|
||||
&flush_file_lines_as_user($in{'file'});
|
||||
&unlock_file($in{'file'});
|
||||
&graceful_apache_restart();
|
||||
&webmin_log("vars", undef, $in{'file'});
|
||||
|
@ -6342,6 +6342,35 @@ if ($< != $uinfo->[2] || $> != $uinfo->[2]) {
|
||||
}
|
||||
}
|
||||
|
||||
=head2 eval_as_unix_user(username, &code)
|
||||
|
||||
Runs some code fragment with the effective UID and GID switch to that
|
||||
of the given Unix user, so that file IO takes place with his permissions.
|
||||
|
||||
=cut
|
||||
|
||||
sub eval_as_unix_user
|
||||
{
|
||||
my ($user, $code) = @_;
|
||||
my @uinfo = getpwnam($user);
|
||||
defined(@uinfo) || &error("eval_as_unix_user called with invalid user $user");
|
||||
$) = $uinfo[3]." ".join(" ", $uinfo[3], &other_groups($user));
|
||||
$> = $uinfo[2];
|
||||
my @rv;
|
||||
eval {
|
||||
local $main::error_must_die = 1;
|
||||
@rv = &$code();
|
||||
};
|
||||
my $err = $@;
|
||||
$) = 0;
|
||||
$> = 0;
|
||||
if ($err) {
|
||||
$err =~ s/\s+at\s+(\/\S+)\s+line\s+(\d+)\.?//;
|
||||
&error($err);
|
||||
}
|
||||
return wantarray ? @rv : $rv[0];
|
||||
}
|
||||
|
||||
=head2 create_user_config_dirs
|
||||
|
||||
Creates per-user config directories and sets $user_config_directory and
|
||||
|
Reference in New Issue
Block a user