Como fazer um ls como se você estivesse no grupo 'other'?

0

Em um sistema linux, eu fiz um chmod o + r -R mydir / e eu quero verificar se os usuários no grupo 'o' são capazes de ler o conteúdo do mydir. Como posso fazer um 'ls mydir' como se eu fosse um usuário nos outros usuários que não estão no grupo do arquivo (o)?

Obrigado

    
por 719016 06.06.2011 / 12:56

2 respostas

1

Quando estou em um sistema com acesso somente a uma conta, pelo menos o que eu faço quando quero verificar se 'resto-do-mundo' pode acessar os arquivos, é verificar as permissões para o arquivo E o caminho completo para isso:

# 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'

Isto é fácil de implementar com perl e File :: Specs, Cwd, File :: stat e Fncl

Este é um exemplo de script (infelizmente eu esqueci como usar as constantes S_I * de Fnctl (: mode) para operar a lógica bitwise com mode, ou o: FIELDS from File :: stat).

#!/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};

Resultado:

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

Aviso: esta é uma abordagem de meia força bruta (estou certo de que haveria melhores funções para verificar as permissões), mas pelo menos não usa chamadas de sistema e regex. E, pelo menos, aponte o fato de que você deve verificar todos os diretórios no caminho.

Por favor, comentários são bem-vindos para refatoração deste script. Eu apreciarei sugestões para remover o uso de substr para capturar o modo para outros.

    
por 07.06.2011 / 14:35
0

O único método que conheço é criar um usuário desse tipo (se já não existir) e, em seguida, usar su -c "ls mydir" user .

    
por 06.06.2011 / 13:00

Tags