mirror of
https://github.com/webmin/webmin.git
synced 2026-03-20 08:40:24 +00:00
Add ACLs listing support
This commit is contained in:
@@ -32,6 +32,7 @@ print &ui_table_row($text{'config_columns_to_display'},
|
||||
&ui_checkbox('columns', 'size', $text{'size'}, $config{'columns'} =~ /size/).
|
||||
&ui_checkbox('columns', 'owner_user', $text{'ownership'}, $config{'columns'} =~ /owner_user/).
|
||||
&ui_checkbox('columns', 'permissions', $text{'permissions'}, $config{'columns'} =~ /permissions/).
|
||||
(get_acls_status() ? &ui_checkbox('columns', 'acls', $text{'acls'}, $config{'columns'} =~ /acls/) : undef).
|
||||
(get_attr_status() ? &ui_checkbox('columns', 'attributes', $text{'attributes'}, $config{'columns'} =~ /attributes/) : undef).
|
||||
(get_selinux_status() ? &ui_checkbox('columns', 'selinux', $text{'selinux'}, $config{'columns'} =~ /selinux/) : undef).
|
||||
&ui_checkbox('columns', 'last_mod_time', $text{'last_mod_time'}, $config{'columns'} =~ /last_mod_time/)
|
||||
|
||||
@@ -14,14 +14,22 @@ sub get_attr_status {
|
||||
return has_command('lsattr');
|
||||
}
|
||||
|
||||
sub get_acls_status {
|
||||
return has_command('getfacl');
|
||||
}
|
||||
|
||||
sub get_list_acls_command {
|
||||
return has_command('getfacl') . " -p ";
|
||||
}
|
||||
|
||||
sub get_attr_command {
|
||||
return 'lsattr -d ';
|
||||
}
|
||||
|
||||
sub get_selinux_status {
|
||||
# return 1;
|
||||
return is_selinux_enabled();
|
||||
}
|
||||
|
||||
sub get_selinux_command_type {
|
||||
my $out = backquote_command("ls --help 2>&1 </dev/null");
|
||||
return $out =~ /--scontext/ ? 1 : 0;
|
||||
@@ -291,6 +299,7 @@ sub print_interface {
|
||||
push @ui_columns, ('<span data-head-size>' . $text{'size'} . '</span>') if($userconfig{'columns'} =~ /size/);
|
||||
push @ui_columns, ('<span data-head-owner_user>' . $text{'ownership'} . '</span>') if($userconfig{'columns'} =~ /owner_user/);
|
||||
push @ui_columns, ('<span data-head-permissions>' . $text{'permissions'} . '</span>') if($userconfig{'columns'} =~ /permissions/);
|
||||
push @ui_columns, ('<span data-head-acls>' . $text{'acls'} . '</span>') if(get_acls_status() && $userconfig{'columns'} =~ /acls/);
|
||||
push @ui_columns, ('<span data-head-attributes>' . $text{'attributes'} . '</span>') if(get_attr_status() && $userconfig{'columns'} =~ /attributes/);
|
||||
push @ui_columns, ('<span data-head-selinux>' . $text{'selinux'} . '</span>') if(get_selinux_status() && $userconfig{'columns'} =~ /selinux/);
|
||||
push @ui_columns, ('<span data-head-last_mod_time>' . $text{'last_mod_time'} . '</span>') if($userconfig{'columns'} =~ /last_mod_time/);
|
||||
@@ -301,8 +310,9 @@ sub print_interface {
|
||||
if ($count > scalar(@list)) { last; }
|
||||
my $class = $count & 1 ? "odd" : "even";
|
||||
my $link = $list[$count - 1][0];
|
||||
my $selinux;
|
||||
my $acls;
|
||||
my $attributes;
|
||||
my $selinux;
|
||||
$link =~ s/\Q$cwd\E\///;
|
||||
$link =~ s/^\///g;
|
||||
$vlink = html_escape($link);
|
||||
@@ -328,6 +338,10 @@ sub print_interface {
|
||||
$attributes = $list[$count - 1][18];
|
||||
}
|
||||
|
||||
if(get_acls_status() && $userconfig{'columns'} =~ /acls/) {
|
||||
$acls = $list[$count - 1][19];
|
||||
}
|
||||
|
||||
$mod_time = POSIX::strftime('%Y/%m/%d - %T', localtime($list[$count - 1][10]));
|
||||
|
||||
$actions = "<a class='action-link' href='javascript:void(0)' onclick='renameDialog(\"$vlink\")' title='$text{'rename'}' data-container='body'>$rename_icon</a>";
|
||||
@@ -381,6 +395,7 @@ sub print_interface {
|
||||
push @row_data, $size if($userconfig{'columns'} =~ /size/);
|
||||
push @row_data, $user.':'.$group if($userconfig{'columns'} =~ /owner_user/);
|
||||
push @row_data, $permissions if($userconfig{'columns'} =~ /permissions/);
|
||||
push @row_data, $acls if(get_acls_status() && $userconfig{'columns'} =~ /acls/);
|
||||
push @row_data, $attributes if(get_attr_status() && $userconfig{'columns'} =~ /attributes/);
|
||||
push @row_data, $selinux if(get_selinux_status() && $userconfig{'columns'} =~ /selinux/);
|
||||
push @row_data, $mod_time if($userconfig{'columns'} =~ /last_mod_time/);
|
||||
|
||||
@@ -12,9 +12,10 @@ unless (opendir ( DIR, $cwd )) {
|
||||
} else {
|
||||
&ui_print_header(undef, $module_info{'name'}, "", undef, 0 , 0, 0, "<a href='config.cgi?path=".&urlize($path)."' data-config-pagination='$userconfig{'per_page'}'>$text{'module_config'}</a>");
|
||||
|
||||
my %acls;
|
||||
my %attributes;
|
||||
my $setype = get_selinux_command_type();
|
||||
my %secontext;
|
||||
my %attributes;
|
||||
|
||||
# Push file names with full paths to array, filtering out "." and ".."
|
||||
@list = map { &simplify_path("$cwd/$_") } grep { $_ ne '.' && $_ ne '..' } readdir(DIR);
|
||||
@@ -34,13 +35,27 @@ unless (opendir ( DIR, $cwd )) {
|
||||
@list = keys %hash;
|
||||
}
|
||||
|
||||
# List ACLs
|
||||
if ($userconfig{'columns'} =~ /acls/ && get_acls_status()) {
|
||||
my $command = get_list_acls_command() . " " . join(' ', map {quotemeta("$_")} @list);
|
||||
my $output = `$command`;
|
||||
my @aclsArr;
|
||||
foreach my $aclsStr (split(/\n\n/, $output)) {
|
||||
$aclsStr =~ /#\s+file:\s*(.*)/;
|
||||
my ($file) = ($aclsStr =~ /#\s+file:\s*(.*)/);
|
||||
my @aclsA = ($aclsStr =~ /^(?!#)([\w:-]+)/gm);
|
||||
push(@aclsArr, [$file, \@aclsA]);
|
||||
}
|
||||
%acls = map {$_->[0] => ('<span data-acls>' . join("<br>", @{$_->[1]}) . '</span>')} @aclsArr;
|
||||
}
|
||||
|
||||
# List attributes
|
||||
if ( $userconfig{'columns'} =~ /attributes/ && get_attr_status() ) {
|
||||
my $command = get_attr_command() . join( ' ', map { quotemeta("$_") } @list );
|
||||
my $output = `$command`;
|
||||
my @attributesArr =
|
||||
map { [ split( /\s+/, $_, 2 ) ] } split( /\n/, $output );
|
||||
%attributes = map { $_->[1] => ('<span data-attributes="x">' . $_->[0] . '</span>') } @attributesArr;
|
||||
%attributes = map { $_->[1] => ('<span data-attributes>' . $_->[0] . '</span>') } @attributesArr;
|
||||
}
|
||||
|
||||
# List security context
|
||||
@@ -51,11 +66,11 @@ unless (opendir ( DIR, $cwd )) {
|
||||
my $delimiter = ( $setype ? '\n' : ',' );
|
||||
my @searray =
|
||||
map { [ split( /\s+/, $_, 2 ) ] } split( /$delimiter/, $output );
|
||||
%secontext = map { $_->[1] => ($_->[0] eq "?" ? undef : ('<span>' . $_->[0] . '</span>') ) } @searray;
|
||||
%secontext = map { $_->[1] => ($_->[0] eq "?" ? undef : ('<span data-secontext>' . $_->[0] . '</span>') ) } @searray;
|
||||
}
|
||||
|
||||
# Get info about directory entries
|
||||
@info = map { [ $_, lstat($_), &clean_mimetype($_), -d, -l $_, $secontext{$_}, $attributes{$_} ] } @list;
|
||||
@info = map { [ $_, lstat($_), &clean_mimetype($_), -d, -l $_, $secontext{$_}, $attributes{$_}, $acls{$_} ] } @list;
|
||||
|
||||
# Filter out folders
|
||||
@folders = map {$_} grep {$_->[15] == 1 } @info;
|
||||
|
||||
@@ -25,7 +25,7 @@ size=Size
|
||||
owner_user=Owner user
|
||||
owner_group=Owner group
|
||||
permissions=Mode
|
||||
selinux=Security context
|
||||
selinux=Security Context
|
||||
attributes=Attributes
|
||||
last_mod_time=Modified
|
||||
rename=Rename
|
||||
@@ -162,3 +162,4 @@ info_total3=Total: $1 file and $2 directories
|
||||
info_total4=Total: $1 files and $2 directories
|
||||
|
||||
ownership=Owner
|
||||
acls=Access Control List
|
||||
@@ -152,8 +152,9 @@ a.pages {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
span[data-attributes="s"],
|
||||
span[data-attributes="x"] {
|
||||
span[data-acls],
|
||||
span[data-attributes],
|
||||
span[data-secontext] {
|
||||
font-family: monospace;
|
||||
font-size: 10px;
|
||||
font-size: 11px;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user