Как в Linux найти все файлы и каталоги, которые доступны для записи (или, фактически, не для записи) конкретному пользователю?
Изменить: чтобы уточнить, я имел в виду под конкретным подкаталогом, а не в масштабе всей системы. И да, это означает все перестановки и комбинации возможности записи для пользователя, группы и мира, которые позволят этому пользователю писать. Я знаю, что влечет за собой вопрос семантически, я надеялся, что для получения списка этих файлов будет выполнена одна или несколько строк.
Используйте команду find, если у вас установлена программа findutils версии 4.3.0 или выше:
Для всех файлов в текущем каталоге, которые доступны для записи текущему пользователю:
find . -writable
Для всех файлов в текущем каталоге, которые не доступны для записи текущему пользователю:
find . ! -writable
Согласно странице руководства:
В этом тесте используется системный вызов access (2), поэтому серверы NFS могут обмануть его, выполняя сопоставление UID (или подавление корневого идентификатора), поскольку многие системы реализуют доступ (2) в ядре клиента и поэтому не могут использовать информация об отображении UID, хранящаяся на сервере.
Вы можете создать сценарий Perl (writable.pl
) как это:
#!/usr/bin/perl
use strict;
sub recurse {
my $path = shift;
my @files = glob "$path/{*,.*}";
for my $file (@files) {
if (-d $file) {
if ($file !~ /\/\.$/ && $file !~ /\/\.\.$/) {
recurse($file);
}
} else {
print "$file\n" if -w $file;
}
}
}
print "Writable files for " . getlogin() . "\n";
recurse($ARGV[0]);
а затем используйте этот сценарий как root, как показано ниже:
su USERNAME -c "./writable.pl DIRECTORY"
заполнение USERNAME
и DIRECTORY
по мере необходимости.
Вы уверены, что действительно хотите задать этот вопрос?
Сказать «Я хочу видеть все файлы, в которые может записывать учетная запись X» означает, что каждый файл, принадлежащий им с u + w, каждый файл, принадлежащий любой группе, к которой они принадлежат, установленной g + w, и каждый файл, доступный для записи (o + ш).
Не записывать было бы еще сложнее. Лучше составить список всех файлов, а затем исключить те, в которые они могут писать.
Для ответа Эдди, если вы добавите:
my $path = quotemeta shift;
Затем он также будет перемещаться по каталогам с пробелами в имени.
В этом примере я буду использовать синтаксис gnu find для флага -perm:
По сути, если вы выбрасываете дурацкие расширения, такие как списки контроля доступа, у вас есть 3 варианта: владелец, группа и "другой" доступ на запись. Звучит как работа для петли.
Есть много возможностей для оптимизации, но я оставлю это кому-нибудь другому ... Кроме того, я никогда не могу вспомнить все детали поиска и пересечения файловых систем и подобной чепухи. Кроме того, убедитесь, что вывод групп такой же, как в моей тестовой системе Linux.
$ groups snoopy
snoopy : snoopy doghouse linus admin wwI woodstock
$
Это грубый пример того, как вы можете найти файлы, доступные для записи пользователем. Это будет при запуске от имени любого пользователя, но если вы запустите его от имени пользователя, отличного от uid0, вы найдете только те вещи, которые находятся в каталогах, в которых пользователь, запускающий скрипт, имеет разрешения на чтение и выполнение.
#!/bin/sh
user=snoopy
directory=/
# first files owned by the user and writable
find "$directory" -follow -user "$user" -perm /u+w 2> /dev/null
# now for files that are group writable with the user in that group
for groups in $(groups snoopy 2> /dev/null | cut -f2 -d:)
do
find "$directory" -follow -group "$user" -perm /g+w 2> /dev/null
done
# now for everything else
find "$directory" -follow -perm /o+w 2> /dev/null
Эта команда должна найти все каталоги, доступные для записи, вы можете изменить разрешения по своему усмотрению:
find / -type d \( -perm -g+w -or -perm -o+w \) -exec ls -adl {} \;
Я не уверен, что это лучший способ, но следует сделать то, о чем вы просите:
for file in *
do
if [ -w $file ] ; then
echo $file
fi
done
ключ конечно в -w
переключатель, который также может быть инвертирован
РЕДАКТИРОВАТЬ: если подумать об этом, этот скрипт печатает то, что доступно для записи текущему пользователю, это, очевидно, не сработает для определенного пользователя.