Make all user and group links be by name instead of by index.

This commit is contained in:
Jamie Cameron
2011-05-30 18:09:29 -07:00
parent 52acd66bb4
commit e96015a92c
12 changed files with 45 additions and 36 deletions

View File

@ -66,3 +66,5 @@ When deleting a user's personal group and user deletion in other modules is enab
Added support for SHA512 format passwords.
---- Changes since 1.540 ----
Fixed an XSS vulnerability that can be triggered if an attacker has the ability to change the real name of a Unix user.
---- Changes since 1.550 ----
Updated all links to users and groups to be by name instead of by index, to avoid incorrect links if the passwd or group files are changed manually or by another Webmin session.

View File

@ -8,12 +8,12 @@ if ($cgi eq 'edit_user.cgi') {
# Link to first available user
my @allulist = &list_users();
my @ulist = &list_allowed_users(\%access, \@allulist);
return @ulist ? "num=".&urlize($ulist[0]->{'num'}) : "none";
return @ulist ? "user=".&urlize($ulist[0]->{'user'}) : "none";
}
elsif ($cgi eq 'edit_group.cgi') {
my @allglist = &list_groups();
my @glist = &list_allowed_groups(\%access, \@allglist);
return @glist ? "num=".&urlize($glist[0]->{'num'}) : "none";
return @glist ? "group=".&urlize($glist[0]->{'group'}) : "none";
}
return undef;
}

View File

@ -5,8 +5,8 @@
require './user-lib.pl';
&ReadParse();
@glist = &list_groups();
$group = $glist[$in{'num'}];
$group || &error($text{'gdel_enum'});
($group) = grep { $_->{'group'} eq $in{'group'} } @glist;
$group || &error($text{'gedit_egone'});
$| = 1;
&error_setup($text{'gdel_err'});
&can_edit_group(\%access, $group) || &error($text{'gdel_egroup'});
@ -55,7 +55,7 @@ if ($in{'confirmed'}) {
print "$text{'gdel_done'}<p>\n";
done:
&ui_print_footer("", $text{'index_return'});
&ui_print_footer("index.cgi?mode=groups", $text{'index_return'});
}
else {
# check if this is anyone's primary group
@ -71,13 +71,12 @@ else {
# Ask if the user is sure
print &ui_confirmation_form("delete_group.cgi",
&text('gdel_sure', $group->{'group'}),
[ [ "num", $in{'num'} ],
[ "group", $group->{'group'} ] ],
[ [ "group", $group->{'group'} ] ],
[ [ "confirmed", $text{'gdel_del'} ] ],
ui_checkbox("others", 1, $text{'gdel_dothers'},
$config{'default_other'}),
);
&ui_print_footer("", $text{'index_return'});
&ui_print_footer("index.cgi?mode=groups", $text{'index_return'});
}

View File

@ -6,8 +6,8 @@ require './user-lib.pl';
&ReadParse();
&lock_user_files();
@ulist = &list_users();
$user = $ulist[$in{'num'}];
$user || &error($text{'udel_enum'});
($user) = grep { $_->{'user'} eq $in{'user'} } @ulist;
$user || &error($text{'uedit_egone'});
&error_setup($text{'udel_err'});
&can_edit_user(\%access, $user) || &error($text{'udel_euser'});
$access{'udelete'} || &error($text{'udel_euser'});
@ -156,8 +156,7 @@ else {
}
print &ui_confirmation_form("delete_user.cgi", $msg,
[ [ "num", $in{'num'} ],
[ "user", $user->{'user'} ],
[ [ "user", $user->{'user'} ],
[ "confirmed", 1 ] ],
\@buts,
$access{'dothers'} == 1 ?

View File

@ -6,14 +6,16 @@ require './user-lib.pl';
&ReadParse();
# Get group and show page header
$n = $in{'num'};
$n = $in{'group'};
if ($n eq "") {
$access{'gcreate'} == 1 || &error($text{'gedit_ecreate'});
&ui_print_header(undef, $text{'gedit_title2'}, "", "create_group");
}
else {
@glist = &list_groups();
%group = %{$glist[$n]};
($ginfo_hash) = grep { $_->{'group'} eq $n } @glist;
$ginfo_hash || &error($text{'gedit_egone'});
%group = %$ginfo_hash;
&can_edit_group(\%access, \%group) ||
&error($text{'gedit_eedit'});
&ui_print_header(undef, $text{'gedit_title'}, "", "edit_group");
@ -24,7 +26,7 @@ else {
# Start of form
print &ui_form_start("save_group.cgi", "post");
print &ui_hidden("num", $n) if ($n ne "");
print &ui_hidden("old", $n) if ($n ne "");
print &ui_table_start($text{'gedit_details'}, "width=100%", 2, [ "width=30%" ]);
# Group name
@ -99,7 +101,7 @@ if ($n ne "") {
foreach $u (@upri) {
if (&can_edit_user(\%access, $u)) {
push(@uprilinks, "<a href='edit_user.cgi?".
"num=$u->{'num'}'>$u->{'user'}</a>");
"user=$u->{'user'}'>$u->{'user'}</a>");
}
else {
push(@uprilinks, $u->{'user'});

View File

@ -7,14 +7,16 @@ require 'timelocal.pl';
&ReadParse();
# Show header and get the user
$n = $in{'num'};
$n = $in{'user'};
if ($n eq "") {
$access{'ucreate'} || &error($text{'uedit_ecreate'});
&ui_print_header(undef, $text{'uedit_title2'}, "", "create_user");
}
else {
@ulist = &list_users();
%uinfo = %{$ulist[$n]};
($uinfo_hash) = grep { $_->{'user'} eq $n } @ulist;
$uinfo_hash || &error($text{'uedit_egone'});
%uinfo = %$uinfo_hash;
&can_edit_user(\%access, \%uinfo) || &error($text{'uedit_eedit'});
&ui_print_header(undef, $text{'uedit_title'}, "", "edit_user");
}
@ -37,8 +39,7 @@ if ($shells{'shells'}) {
# Start of the form
print &ui_form_start("save_user.cgi", "post");
print &ui_hidden("num", $n) if ($n ne "");
print &ui_hidden("old", $uinfo{'user'}) if ($n ne "");
print &ui_hidden("old", $n) if ($n ne "");
print &ui_table_start($text{'uedit_details'}, "width=100%", 2, \@tds);
# Username

View File

@ -111,6 +111,7 @@ uedit_logins=Show Logins
uedit_mail=Read Email
uedit_swit=Login to Usermin
uedit_ecreate=You cannot create new users
uedit_egone=Selected user no longer exists!
uedit_eedit=You cannot edit this user
uedit_admin=Only root can change password
uedit_admchg=User must choose new password
@ -188,6 +189,7 @@ gedit_oneperline=(One per line)
gedit_homedirs=Home directories
gedit_allfiles=All files
gedit_ecreate=You cannot create new groups
gedit_egone=Selected group no longer exists!
gedit_eedit=You cannot edit this group
gedit_cothers=Create group in other modules?
gedit_mothers=Modify group in other modules?

View File

@ -9,7 +9,7 @@ require 'timelocal.pl';
if ($in{'delete'}) {
# Redirect to deletion page
&redirect("delete_group.cgi?num=$in{'num'}");
&redirect("delete_group.cgi?group=$in{'old'}");
return;
}
@ -24,9 +24,12 @@ $in{'gid'} =~ s/\r|\n//g;
&lock_user_files();
@glist = &list_groups();
if ($in{'num'} ne "") {
if ($in{'old'} ne "") {
# get old group
%ogroup = %{$glist[$in{'num'}]};
@glist = &list_groups();
($ginfo_hash) = grep { $_->{'group'} eq $in{'old'} } @glist;
$ginfo_hash || &error($text{'gedit_egone'});
%ogroup = %$ginfo_hash;
$group{'group'} = $ogroup{'group'};
&can_edit_group(\%access, \%ogroup) || &error($text{'gsave_eedit'});
}
@ -43,7 +46,7 @@ else {
}
# Validate and save inputs
if (!$in{'gid_def'} || $in{'num'} ne '') {
if (!$in{'gid_def'} || $in{'old'} ne '') {
# Only do GID checks if not automatic
$in{'gid'} =~ /^[0-9]+$/ || &error(&text('gsave_egid', $in{'gid'}));
!$access{'lowgid'} || $in{'gid'} >= $access{'lowgid'} ||

View File

@ -22,8 +22,7 @@ elsif ($in{'switch'}) {
return;
}
elsif ($in{'delete'}) {
&redirect("delete_user.cgi?user=".&urlize($in{'old'}).
"&num=".$in{'num'});
&redirect("delete_user.cgi?user=".&urlize($in{'old'}));
return;
}
@ -54,9 +53,11 @@ $err = &check_username_restrictions($in{'user'});
&lock_user_files();
@ulist = &list_users();
@glist = &list_groups();
if ($in{'num'} ne "") {
if ($in{'old'} ne "") {
# Get old user info
%ouser = %{$ulist[$in{'num'}]};
($ouser_hash) = grep { $_->{'user'} eq $in{'old'} } @ulist;
$ouser_hash || &error($text{'uedit_egone'});
%ouser = %$ouser_hash;
if (!$access{'urename'} && $ouser{'user'} ne $user{'user'}) {
&error($text{'usave_erename'});
}
@ -79,7 +80,7 @@ else {
if ($ou->{'user'} eq $in{'user'});
}
}
if (($in{'num'} eq '' || $user{'user'} ne $ouser{'user'}) &&
if (($in{'old'} eq '' || $user{'user'} ne $ouser{'user'}) &&
$config{'alias_check'} && &foreign_check("sendmail")) {
# Check if the new username conflicts with a sendmail alias
&foreign_require("sendmail", "sendmail-lib.pl");
@ -93,7 +94,7 @@ if (($in{'num'} eq '' || $user{'user'} ne $ouser{'user'}) &&
}
# Validate and store basic inputs
if (!$in{'uid_def'} || $in{'num'} ne '') {
if (!$in{'uid_def'} || $in{'old'} ne '') {
# Only do UID checks if not automatic
$in{'uid'} =~ /^\-?[0-9]+$/ || &error(&text('usave_euid', $in{'uid'}));
if (!%ouser || $ouser{'uid'} != $in{'uid'}) {
@ -154,7 +155,7 @@ if ($access{'shells'} ne "*") {
}
}
$user{'uid'} = $in{'uid'};
if ($in{'num'} ne "" || !$in{'gidmode'}) {
if ($in{'old'} ne "" || !$in{'gidmode'}) {
# Selecting existing group
$user{'gid'} = &my_getgrnam($in{'gid'});
if ($user{'gid'} eq "") { &error(&text('usave_egid', $in{'gid'})); }
@ -239,7 +240,7 @@ foreach $gname (@sgnames) {
}
if ($access{'ugroups'} ne "*") {
if ($in{'num'} ne "") {
if ($in{'old'} ne "") {
# existing users can only be added to or removed from
# allowed groups
if ($ouser{'gid'} != $user{'gid'}) {

View File

@ -22,7 +22,7 @@ for($i=0; $i<@glist; $i++) {
}
}
if (@match == 1) {
&redirect("edit_group.cgi?num=".$match[0]->{'num'});
&redirect("edit_group.cgi?group=".$match[0]->{'group'});
}
else {
&ui_print_header(undef, $text{'search_title'}, "");

View File

@ -42,7 +42,7 @@ for($i=0; $i<@ulist; $i++) {
}
}
if (@match == 1) {
&redirect("edit_user.cgi?num=".$match[0]->{'num'});
&redirect("edit_user.cgi?user=".$match[0]->{'user'});
}
else {
&ui_print_header(undef, $text{'search_title'}, "");

View File

@ -2463,7 +2463,7 @@ elsif ($_[0]->{'dn'}) {
"$dis</a>";
}
else {
return "<a href='edit_user.cgi?num=$_[0]->{'num'}'>".
return "<a href='edit_user.cgi?user=".&urlize($_[0]->{'user'})."'>".
"$dis</a>";
}
}
@ -2483,7 +2483,7 @@ elsif ($_[0]->{'dn'}) {
&html_escape($_[0]->{'group'})."</a>";
}
else {
return "<a href='edit_group.cgi?num=$_[0]->{'num'}'>".
return "<a href='edit_group.cgi?group=".&urlize($_[0]->{'group'})."'>".
&html_escape($_[0]->{'group'})."</a>";
}
}