PHP ini file IO user restriction

This commit is contained in:
Jamie Cameron
2009-07-02 23:51:56 +00:00
parent 1726d33b86
commit f5ca200daf
16 changed files with 81 additions and 11 deletions

File diff suppressed because one or more lines are too long

View File

@ -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.

View File

@ -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'};
}

View File

@ -1,3 +1,4 @@
global=1
anyfile=1
manual=1
user=root

View File

@ -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'}, "");

View File

@ -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

View File

@ -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;

View File

@ -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'});

View 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'});

View 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'});

View 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'});

View 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'});

View 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'});

View 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'});

View 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'});

View 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