如何像在“其他”组中一样执行 ls?

如何像在“其他”组中一样执行 ls?

在 Linux 系统中,我执行了 chmod o+r -R mydir/,我想检查“o”组中的用户是否能够读取 mydir 的内容。我怎样才能像文件组 (o) 以外的其他用户一样执行“ls mydir”?

谢谢

答案1

当我处于只能访问一个帐户的系统中时,至少当我想检查“世界其他地方”是否可以访问这些文件时,我会检查文件的权限和它的完整路径:

# take the cannonic absolute path
# split the dirs and check for each one if it is x and r by 'others'
# check that the final file is readable by 'others'

使用 perl 和 File::Specs、Cwd、File::stat 和 Fncl 可以轻松实现这一点

这是一个示例脚本(不幸的是,我忘记了如何使用 Fnctl (:mode) 中的 S_I* 常量来操作带模式的按位逻辑,或者使用 File::stat 中的 :FIELDS)。

#!/usr/bin/env perl

=head check_file_access_for_all_users.pl

    -- Given a path this script checks that all subpaths are
       accessible for all users in the system. If no path is given, 
       then uses the current path

    -- <TO_DO> add an option for testing access to all files and dirs
       in the last dir of the path

=cut

use strict;
use File::Spec;
use Cwd  'realpath';
use File::stat;
use Fcntl qw(:mode);

my $path = shift;
$path ||='.'; # test current paths if no paths as an argument


# make it absolute and resolve symlinks
my $realpath = realpath($path);

print "realpath: $realpath\n";

# you can split with regex or split but I prefer splitdir
my @dirs= File::Spec->splitdir($realpath);

# last item of @dirs could be a file or symlink (check for (! -d) )
# Remove it: the dirs should be checked for rx and the file only for r
my $file;
if (! -d $dirs[-1]) {
    $file = pop @dirs;
}

# prepend / to first element in @dirs: it is an absolute path
# create an array for all the paths to check
my $path_str;
my @paths_list = map {$path_str.='/'.$_;} grep {$_} @dirs;

# list of paths win no access for others
my @paths_for_chmod;
$DB::single=1;
foreach my $path_to_check (@paths_list) {

    # this is a dir, so test is 'rw'
    my $test = 'rw';
    check_path_access($path_to_check, $test);
}

if ($file) {
    # check that is readable
    my $path_to_check = "$path_str/$file";

    # this is a file, so test is 'r'
    my $test = 'r';
    check_path_access($path_to_check, $test);
}


$DB::single=1;
if (@paths_for_chmod){
    print "#[NOT_OK]: Some elements of the path are not accesible by OTHER:\n";
    printf (("  %s %s\n" x @paths_for_chmod), map{$_->[0], $_->[1]} @paths_for_chmod);
}
else {
    print "The path $path and all its subpaths are accesible by OTHER\n";
}

print "end\n";

##################################################
#   Methods
##################################################

sub check_path_access{
    my ($path_to_check,$test) = @_;

    # dispatch table
    my $wanted_test = {
                       rw => {
                              test=> \&is_other_rx_bf,
                              msg => '',
                             },
                       r  => {
                              test => \&is_other_r_bf,
                              msg => '',
                             },
                      };


    my $mode = stat($path_to_check)->mode;
    # get if is rw by others and the octal value of the file permisions
    my ($has_o_access, $mode_oct) = $wanted_test->{$test}{test}->($mode);

    my $status   = $has_o_access?'':' NOT';
    my $mode_str = $has_o_access?'':" (mode=$mode_oct)";

    print {*STDERR} 'Others can '.$status .' access to ' .$path_to_check. $mode_str."\n";

    push @paths_for_chmod,  [$mode_str, $path_to_check] unless $has_o_access;

}

# brute force method for obaining mode for others (direct substr to mode string)
sub is_other_rx_bf{
    my $mode =shift;
    my $mode_oct = sprintf ("%04o", $mode & 07777);
    my $oth_mod  = substr($mode_oct,3,1);

    return $oth_mod>=4?1:0, $mode_oct;
}

sub is_other_r_bf{
    my $mode =shift;
    my $mode_oct = sprintf ("%04o", $mode & 07777);
    my $oth_mod  = substr($mode_oct,3,1);

    return $oth_mod>=4?1:0, $mode_oct;
}
# unfinished exploration for Fncl :mode constants
sub is_other_rx {
    my $mode =shift;
    die "not implemented yet\n";

    # ?? I can remember how to do this test properly
    my $allCanAccess = ($mode & S_IRUSR)   # User can read
        && ($mode & S_IRGRP)   # Group can read
            && ($mode & S_IROTH);  # Others can read

#### perldoc -f stat
##          use Fcntl ’:mode’;
##
##          $mode = (stat($filename))[2];
##
##          $user_rwx      = ($mode & S_IRWXU) >> 6;
##          $group_read    = ($mode & S_IRGRP) >> 3;
##          $other_execute =  $mode & S_IXOTH;
##
##          printf "Permissions are %04o\n", S_IMODE($mode), "\n";
##
##          $is_setuid     =  $mode & S_ISUID;
##          $is_setgid     =  S_ISDIR($mode);
##
##          # Permissions: read, write, execute, for user, group, others.
##
##          S_IRWXU S_IRUSR S_IWUSR S_IXUSR
##          S_IRWXG S_IRGRP S_IWGRP S_IXGRP
##          S_IRWXO S_IROTH S_IWOTH S_IXOTH
##

}



# chdir $path;
# my $canonical_path =qx{pwd -P};

结果:

perl check_file_access_for_all_users.pl /Users/pablo/tmp/dir1/dir2/dir3/txt1
Others can  access to /Users
Others can  access to /Users/pablo
Others can  access to /Users/pablo/tmp
Others can  NOT access to /Uspablo/pmg/tmp/dir1 (mode=0750)
Others can  access to /Users/pablo/tmp/dir1/dir2
Others can  access to /Users/pablo/tmp/dir1/dir2/dir3
Others can  access to /Users/pablo/tmp/dir1/dir2/dir3/txt1
realpath: /Users/pablo/tmp/dir1/dir2/dir3/txt1
#[NOT_OK]: Some elements of the path are not accesible by OTHER:
   (mode=0750) /Users/pablo/tmp/dir1
end

免责声明:这是一种半暴力方法(我相信会有更好的函数来检查权限),但至少它不使用系统调用和正则表达式。并且至少指出你应该检查路径中的所有目录。

欢迎评论以重构此脚本。我将非常感激大家提出建议,删除使用 substr 来捕获模式。

答案2

我知道的唯一方法是创建这样的用户(如果尚不存在),然后使用su -c "ls mydir" user

相关内容