From 2075fffe70a8c593d5045f76993793fe5c511356 Mon Sep 17 00:00:00 2001 From: Jamie Cameron Date: Sat, 7 Dec 2019 08:03:34 -0800 Subject: [PATCH] Work on safe-mode user creation --- acl/acl-lib.pl | 11 +++++++++++ acl/edit_user.cgi | 21 ++++++++++++++++++--- acl/index.cgi | 25 +++++++++++++++++-------- acl/lang/en | 5 +++-- acl/save_user.cgi | 13 +++++++++++++ 5 files changed, 62 insertions(+), 13 deletions(-) diff --git a/acl/acl-lib.pl b/acl/acl-lib.pl index 14e5a8e42..928ca14a2 100755 --- a/acl/acl-lib.pl +++ b/acl/acl-lib.pl @@ -2167,5 +2167,16 @@ foreach $a (split(/\s+/, $miniserv{'anonymous'})) { return @rv; } +# get_safe_acl(module) +# Returns the safe ACL hash ref for a module, if there is one, or undef +sub get_safe_acl +{ +my ($m) = @_; +my $mdir = &module_root_directory($m); +my %rv; +&read_file_cached("$mdir/safeacl", \%rv) || return undef; +return \%rv; +} + 1; diff --git a/acl/edit_user.cgi b/acl/edit_user.cgi index 5ba054725..7627246c9 100755 --- a/acl/edit_user.cgi +++ b/acl/edit_user.cgi @@ -17,20 +17,27 @@ if ($in{'user'}) { $u = &get_user($in{'user'}); $u || &error($text{'edit_egone'}); %user = %$u; + my %gacl = &get_module_acl($in{'user'}, ''); + $safe = $gacl{'_safe'}; } else { # Creating a new user $access{'create'} || &error($text{'edit_ecreate'}); - &ui_print_header(undef, $text{'edit_title2'}, ""); if ($in{'clone'}) { # Initial settings come from clone $u = &get_user($in{'clone'}); %user = %$u; delete($user{'name'}); + my %gacl = &get_module_acl($in{'clone'}, ''); + $safe = $gacl{'_safe'}; } else { + # User starts out empty %user = ( ); + $safe = $in{'safe'}; } + &ui_print_header(undef, $safe ? $text{'edit_title3'} + : $text{'edit_title2'}, ""); } my $me = &get_user($base_remote_user); @@ -51,6 +58,7 @@ if ($in{'user'}) { if ($in{'clone'}) { print &ui_hidden("clone", $in{'clone'}); } +print &ui_hidden("safe", $safe); print &ui_hidden_table_start($text{'edit_rights'}, "width=100%", 2, "rights", 1, [ "width=30%" ]); @@ -332,9 +340,16 @@ my @groups = &list_groups(); print &ui_hidden_table_start(@groups ? $text{'edit_modsg'} : $text{'edit_mods'}, "width=100%", 2, "mods"); +# Build list of modules, based on safe mode +@allmods = &list_module_infos(); +if ($safe) { + @allmods = grep { $has{$_->{'dir'}} || + &get_safe_acl($_->{'dir'}) } @allmods; + } + # Show available modules, under categories my @mlist = grep { $access{'others'} || $has{$_->{'dir'}} || - $mcan{$_->{'dir'}} } &list_module_infos(); + $mcan{$_->{'dir'}} } @allmods; my @links = ( &select_all_link("mod", 0, $text{'edit_selall'}), &select_invert_link("mod", 0, $text{'edit_invert'}) ); my @cats = &unique(map { $_->{'category'} || '' } @mlist); @@ -359,7 +374,7 @@ foreach my $c (sort { $b cmp $a } @cats) { } elsif ($mcan{$md}) { my $label; - if ($access{'acl'} && $in{'user'}) { + if ($access{'acl'} && $in{'user'} && !$safe) { # Show link for editing ACL $label = ui_link("edit_acl.cgi?" . "mod=" . urlize($m->{'dir'}) . diff --git a/acl/index.cgi b/acl/index.cgi index 36f69968c..8af8fec19 100755 --- a/acl/index.cgi +++ b/acl/index.cgi @@ -54,7 +54,10 @@ if (!@canulist) { print &ui_subheading($text{'index_users'}) if (!$config{'display'}); print "$text{'index_nousers'}

\n"; - print ui_link("edit_user.cgi", $text{'index_create'}) . "\n"; + print &ui_links_row([ + &ui_link("edit_user.cgi", $text{'index_create'}), + &ui_link("edit_user.cgi?ssfe=1", $text{'index_screate'}) + ]); $shown_users = 1; } } @@ -64,7 +67,8 @@ elsif ($config{'display'}) { print &ui_form_start("delete_users.cgi", "post"); &show_name_table(\@canulist, "edit_user.cgi", $access{'create'} ? $text{'index_create'} : undef, - $text{'index_users'}, "user"); + $text{'index_users'}, "user", + $access{'create'} ? $text{'index_screate'} : undef); print &ui_form_end([ [ "delete", $text{'index_delete'} ], @gbut ]); $shown_users = 1; @@ -77,7 +81,8 @@ else { print &ui_form_start("delete_users.cgi", "post"); push(@rowlinks, &select_all_link("d", $form), &select_invert_link("d", $form)); - push(@rowlinks, ui_link("edit_user.cgi", $text{'index_create'})) + push(@rowlinks, ui_link("edit_user.cgi", $text{'index_create'}), + ui_link("edit_user.cgi?safe=1", $text{'index_screate'}); if ($access{'create'}); print &ui_links_row(\@rowlinks); @@ -251,20 +256,24 @@ $rv .= &ui_grid_table(\@grid, 3, 100, return $rv; } -# show_name_table(&users|&groups, cgi, create-text, header-text, param) +# show_name_table(&users|&groups, cgi, create-text, header-text, param, +# safe-text) sub show_name_table { +my ($users, $cgi, $ctext, $htext, $param, $stext) = @_; + # Show table of users, and maybe create links my @rowlinks = ( &select_all_link("d", $form), &select_invert_link("d", $form) ); -push(@rowlinks, ui_link("$_[1]", $_[2])) if ($_[2]); +push(@rowlinks, ui_link($cgi, $ctext)) if ($ctext); +push(@rowlinks, ui_link($cgi."?safe=1", $stext)) if ($stext); print &ui_links_row(\@rowlinks); my @links; -for(my $i=0; $i<@{$_[0]}; $i++) { - push(@links, &user_link($_[0]->[$i], $_[1], $_[4])); +for(my $i=0; $i<@$users; $i++) { + push(@links, &user_link($users->[$i], $cgi, $param)); } print &ui_grid_table(\@links, 4, 100, - [ "width=25%", "width=25%", "width=25%", "width=25%" ], undef, $_[3]); + [ "width=25%", "width=25%", "width=25%", "width=25%" ], undef, $htext); print &ui_links_row(\@rowlinks); } diff --git a/acl/lang/en b/acl/lang/en index 731f9fe70..472e5c683 100644 --- a/acl/lang/en +++ b/acl/lang/en @@ -1,8 +1,8 @@ index_title=Webmin Users index_user=User index_modules=Modules -index_create=Create a new Webmin user. -index_rcreate=Create a new risk-level user. +index_create=Create a new privileged user. +index_screate=Create a new safe user. index_convert=Convert Unix To Webmin Users index_cert=Request an SSL Certificate index_twofactor=Two-Factor Authentication @@ -30,6 +30,7 @@ index_eglist=Failed to list groups : $1 edit_title=Edit Webmin User edit_title2=Create Webmin User +edit_title3=Create Safe Webmin User edit_readonly=This Webmin user should not be edited as it is managed by the $1 module. Click here to bypass this warning and edit the user anyway - but beware that any manual changes may be over-written! edit_rights=Webmin user access rights edit_user=Username diff --git a/acl/save_user.cgi b/acl/save_user.cgi index 37bf5baff..f39ee499c 100755 --- a/acl/save_user.cgi +++ b/acl/save_user.cgi @@ -371,6 +371,19 @@ if ($in{'old'} && $in{'acl_security_form'} && !$newgroup) { &unlock_file($aclfile); } +# If the user is in safe mode, set ACLs on all new modules +if ($in{'safe'}) { + foreach my $m ("", @mods) { + my %macl = &get_module_acl($in{'name'}, $m, 0, 1); + my $safe = &get_safe_acl($m); + if (!%macl && $safe) { + %macl = %$safe; + $macl{'_safe'} = 1; + &save_module_acl(\%macl, $in{'name'}, $m); + } + } + } + # Log the event delete($in{'pass'}); delete($in{'oldpass'});