Терминал: список всех каталогов, для которых у пользователя или группы есть разрешение на запись

7

Я бы хотел указать все каталоги, для которых у пользователя или группы есть права на запись.

Я нашел этот вопрос на ServerFault , но он обращается к Windows Server, поэтому я оптимист, что в сообществе Linux есть что-то лучшее. В то же время я понимаю, что в этом вопросе есть рекурсивный поворот, который может сделать невозможным без долгого сценария.

Мне известны следующие полезные команды:

Однако, когда я не знаю, что такое цель пользователя, было бы неплохо подтянуть список ВСЕХ каталогов, на которые у них есть разрешение на запись, и начать искать оттуда. Если ничего больше, это супер-полезный аудит.

Если это помогает понять мою цель, я унаследовал (или, по крайней мере, детское сидение?) пару систем после того, как наш SysAdmin занял новую позицию. Поэтому я пытался понять эволюцию этих двух систем, например, какое программное обеспечение установлено, и где (..ugh), где живут различные файлы конфигурации, и теперь, какие разные группы и пользователи были созданы, в том числе каталоги, которым им разрешено писать. Обычно я могу найти такие полезные терминальные команды здесь, на askubuntu, но не найдя этого, я думал, что буду идти дальше и спрашивать.

Точная система - Ubuntu 10.04.2, но мы также поддерживаем Ubuntu 12.04.5, поэтому наиболее оптимальным вариантом было бы лучшее решение. Заранее благодарим за любую помощь.

[Обновить: начальные результаты для двух быстрых ответов]

Стоит отметить, что я зарегистрирован как root для них, а / - мой рабочий каталог. Кроме того, им потребовалось сопоставимое количество времени для запуска.

@ Объединенная команда Rinzwind получила следующий результат примерно за 5,5 минут.

[email protected]:/# sudo find -type d \( \( -user ftpgisdata -perm /u=w \) -o \( -group ftpgisdata -perm /g=w \) -o -perm /o=w \)
./tmp
./tmp/.ICE-unix
./tmp/.X11-unix
find: './proc/6594/task/6594/fd/5': No such file or directory
find: './proc/6594/task/6594/fdinfo/5': No such file or directory
find: './proc/6594/fd/5': No such file or directory
find: './proc/6594/fdinfo/5': No such file or directory
./var/tmp
./var/lib/php5
./var/crash
./var/lock
./home/ftpgisdata
./home/ftpgisdata/.ssh
./home/ftpgisdata/.cache
./home/sitename-i-changed.com/wp-content/profile-pics
./dev/shm

@ Измененная команда Оли получает что-то очень похожее, также примерно через 5,5 минут.

[email protected]:/# sudo find / -type d -print0 | sudo -u ftpgisdata xargs -0 sh -c 'for p; do [ -w "$p" ] && echo "$p"; done' -
/tmp
/tmp/.ICE-unix
/tmp/.X11-unix
find: '/proc/15541': No such file or directory
find: '/proc/15542': No such file or directory
find: '/proc/15543': No such file or directory
find: '/proc/15567': No such file or directory
find: '/proc/15568/task/15568/fd/5': No such file or directory
find: '/proc/15568/task/15568/fdinfo/5': No such file or directory
find: '/proc/15568/fd/5': No such file or directory
find: '/proc/15568/fdinfo/5': No such file or directory
/var/tmp
/var/lib/php5
/var/crash
/var/lock
/home/ftpgisdata
/home/ftpgisdata/.ssh
/home/ftpgisdata/.cache
/home/sitename-i-changed.com/wp-content/profile-pics
/dev/shm
Ответ на

@PeterCordes также возвратил аналогичные результаты примерно через 5,5 минут.

[email protected]:~# username_to_check=ftpgisdata base_dir=/   # for example
[email protected]:~# sudo -u "$username_to_check" find "$base_dir" -type d -writable  2>/dev/null ## GNU find, not POSIX
/tmp
/tmp/.ICE-unix
/tmp/.X11-unix
/proc/7159/task/7159/fd
/proc/7159/fd
/proc/7159/map_files
/var/tmp
/var/lib/php5
/var/crash
/var/lock
/home/ftpgisdata
/home/ftpgisdata/.ssh
/home/ftpgisdata/.cache
/home/sitename-i-changed.com/wp-content/profile-pics
/dev/shm
    
задан elrobis 16.03.2016 в 18:28
источник

4 ответа

7

Разработка того, что может сделать пользователь, сложно, если вы не тот пользователь. Вы можете протестировать различные вещи (это владелец, одна и та же группа и т. Д.), Но ACL может применяться, не может быть никаких прав в mount, кто знает. Это сложно.

Если вы можете превратиться в этого пользователя, вы можете test -w <path> посмотреть, могут ли они писать. Это не так быстро, как просто смотреть на индекс, но это возможно с sudo .

sudo -u oli test -w <path> && echo "HOORAY"

Затем мы можем искривить это на back-end find . Вместо того, чтобы просто использовать -exec для изменения пользователя oli снова и снова (см. Предыдущие версии), мы передаем все в экземпляр xargs, работающий как oli. Это намного быстрее.

sudo find / -type d -print0 | sudo -u oli xargs -0 -I{} sh -c 'test -w "$0" && echo "$0"' {}

Несколько оптимизированная (но визуально более мягкая) версия включает в себя минимизацию количества подсетей, которые xargs выполняет, проводя поток потоков в небольшое количество подклассов bash. Это, несомненно, быстрее для больших поисков.

sudo find / -type d -print0 | sudo -u oli xargs -0 sh -c 'for p; do [ -w "$p" ] && echo "$p"; done' -
    
ответ дан Oli 16.03.2016 в 18:49
источник
4

В чате мы пришли к следующим инструкциям для пользователя и группы:

sudo find / -type d -user rinzwind -perm /u=w
sudo find / -type d -group rinzwind -perm /g=w
sudo find / -type d -perm /o=w

Или объедините все три в один:

sudo find -type d \( \( -user rinzwind -perm /u=w \) -o \( -group rinzwind -perm /g=w \) -o -perm /o=w \)

Без / он ищет текущий каталог.

Взял менее 2 секунд на 67 Гб данных в моей системе;)

    
ответ дан Rinzwind 16.03.2016 в 18:58
2

Ответ под строительство, пожалуйста, будьте терпеливы

Тестирование для себя

Можно проверить права на запись для себя со следующим кодом:

[ -w /home/$USER ] && echo yes # using home directory as example

Используя флаг -d для теста, мы можем проверить, является ли что-то каталогом.

Зная все это и find , мы можем сделать

find /home/ -print0 2> /dev/null | while IFS=""  read -r -d "" file ; do [ -d "$file"  ] &&  [ -w "$file" ]  && echo "$file" is writeable ; done

Боковое примечание: Очевидно, что если вы получаете ошибки разрешения с помощью find, вы не можете прочитать этот файл, поэтому нет причин выводить эти ошибки, поэтому перенаправление на dev null. Очевидно, что это не сработает, если мы хотим узнать разрешения для пользователей, отличных от себя, и обратите внимание - / home - только пример. Такие папки, как /var , имеют папки, совместно используемые несколькими пользователями.

Тестирование для других

Можно использовать stat для каждого файла, find находит и фильтрует его с помощью awk

 find /var -type d -exec stat --format '%g %n'  {} \; 2> /dev/null | awk '$1=='1000'{print}' 

Здесь я фильтрую числовой идентификатор моего собственного пользователя, 1000, но это может быть идентификатор любого пользователя. Конечно, можно играть с опциями, использовать имя группы вместо числовых идентификаторов. Это что-то очень гибкое и адаптируемое к вашей цели.

Малые настройки

Итак, я заметил, что вы упоминаете, что вы вошли в систему под именем root. Вот результат моей команды, где я статирую файлы и печатаю их группу и имя файла, а затем отфильтровываю AWK с помощью соответствующего имени группы.

$ find /proc -type d -exec stat --format '%G %n'  {} \; 2> /dev/null  | awk '$1=="syslog"{print}'
syslog /proc/560
syslog /proc/560/task
syslog /proc/560/task/560
syslog /proc/560/task/560/net
syslog /proc/560/task/560/attr
syslog /proc/560/task/562
syslog /proc/560/task/562/net
syslog /proc/560/task/562/attr
syslog /proc/560/task/563
syslog /proc/560/task/563/net
syslog /proc/560/task/563/attr
syslog /proc/560/task/564
syslog /proc/560/task/564/net
syslog /proc/560/task/564/attr
syslog /proc/560/net
syslog /proc/560/attr
^C
    
ответ дан Sergiy Kolodyazhnyy 16.03.2016 в 19:26
2

Если у вас есть GNU find, вы можете использовать тест -writable (обратите внимание на орфографию, это не writeable ). Это использует системный вызов access(2) вместо того, чтобы просто пытаться понять, что происходит от просмотра разрешений, поэтому он корректно работает с ACL. (Но может разбиться на NFS с сопоставлениями идентификаторов).

Он также найдет каталоги, которые могут быть записаны пользователем благодаря тому, что он является членом второй группы. (например, каталог в /usr/local , записываемый пользователями из группы admin или что-то вроде chown root:users /data/share && chmod 2775 /data/share , где некоторые учетные записи являются членами группы users .)

username_to_check=peter base_dir=/   # for example
sudo -u "$username_to_check" find "$base_dir" -type d -writable  2>/dev/null ## GNU find, not POSIX

Будут ошибки, когда find сталкивается с каталогами, к которым пользователь не может спуститься, поэтому мы перенаправляем ошибки на /dev/null .

Это будет not найти любые каталоги, которые могут быть записаны, но внутри каталогов без разрешения на выполнение, потому что find работает, поскольку пользователь не может перемещаться по более высоким каталогам. Однако, если процесс, который им принадлежит, запускается внутри такого каталога, они смогут писать с ним относительные пути. (или они захватывают дескриптор открытого файла в такой каталог, они могут использовать openat(2) ). pwd не будет работать, если у них нет разрешения на исполнение для одного из компонентов каталога полного пути, поэтому это не обычная настройка.

Это также пропускает записываемые каталоги, которые находятся внутри исполняемых, но не читаемых каталогов . Чтобы обойти эти ограничения, вероятно, запустите find -type d как root и используйте find -writable в качестве пользователя для проверки полученных путей. Это может быть более эффективным, чем цикл оболочки, используя [ -w "$f" ] .

POSIX find(1) имеет гораздо меньше возможностей, чем поиск GNU. Если ваш сценарий должен быть переносимым в POSIX, возможно, проще всего подключиться к чему-то другому, который проверяет разрешения, например, оболочку с [ -w "$f" ] (см. Другой ответ, который предлагает это.)

    
ответ дан Peter Cordes 17.03.2016 в 01:55