Как проверить, может ли пользователь получить доступ к данному файлу?

60

* Пользовательские разрешения nix очень просты, но все может запутаться, если вам необходимо принять во внимание все родительские права доступа к каталогу, прежде чем получить доступ к данному файлу. Как я могу проверить, достаточно ли у пользователя прав? Если нет, то какой каталог запрещает доступ?

Например, предположим, что пользователь joeи файл /long/path/to/file.txt. Даже если он file.txtбыл переключен на 777, Джо все равно должен иметь доступ /long/, и то /long/path/и другое /long/path/to/раньше. Что мне нужно, это способ автоматически проверить это. Если joeнет доступа, я также хотел бы знать, где ему было отказано. Может быть, он может получить доступ /long/, но нет /long/path/.

Metalcoder
источник

Ответы:

71

Вы можете использовать

namei -m /path/to/really/long/directory/with/file/in

который выведет все разрешения в пути в вертикальном списке.

или же

namei -l /path/to/really/long/directory/with/file/in

перечислить всех владельцев и разрешения

exussum
источник
2
Это должен быть правильный ответ. Фактически использование namei <path> || exit 1позволяет вам легко обнаружить проблему с правами доступа в скрипте.
Лоренцог
5
он не отвечает напрямую, имеет ли Джо доступ к файлу.
JFS
15

Вы можете использовать bash для этого.

$ cat check-permissions.sh
#!/bin/bash
file=$1
# Handle non-absolute paths
if ! [[ "$file" == /* ]] ; then
    path=.
fi
dirname "$file" | tr '/' $'\n' | while read part ; do
    path="$path/$part"
    # Check for execute permissions
    if ! [[ -x "$path" ]] ; then
        echo "'$path' is blocking access."
    fi
done
if ! [[ -r "$file" ]] ; then
    echo "'$file' is not readable."
fi
$ ./check-permissions.sh /long/path/to/file.txt

Чтобы проверить это для конкретного пользователя, вы можете использовать sudo.

sudo -u joe ./check-permissions.sh /long/path/to/file.txt

источник
сценарий sudo -u joe. Здесь script это имя файла сценария, верно? так что ты сказал Судо вести себя так, как будто Джо вызывал сценарий?
tgkprog
Точно. Я изменил свой ответ, чтобы уточнить это.
Я сделал небольшую модификацию своего скрипта для обработки неабсолютных путей.
@EvanTeitelman С абсолютным путем, вы хотели инициализировать, pathчтобы быть пустым? или /?
Жиль "ТАК - перестань быть злым"
@ Жиль: Я хотел, чтобы это было пусто. В этом примере pathустановлено /longпервое время цикла, что является правильным. Должен ли я установить pathничего явно ( path=)? Кроме того, спасибо за упрощение моего использования tr.
3

Как я понял из вашего вопроса, вы должны проверить его для разных пользователей (не только для joe), поэтому в таком случае проще всего рекурсивно проверить это с помощью sudo следующим образом:

FILE=$1 ; T_USER=$2 ;
if sudo -u $T_USER [ -r "$FILE" ] ; then
    echo "original file $1 is readable for $T_USER"
else
    while sudo -u $T_USER [ ! -x "$FILE" ] ; do FILE=$(dirname "$FILE") ; done
    echo "only $FILE is readable for $T_USER"
fi

использование:

./script.sh /long/path/to/file.txt joe
порыв
источник
Джо нужны разрешения на выполнение для каталогов, а не права на чтение.
@EvanTeitelman да, ты прав. Исправлена.
Раш
@rush Я попытался проверить его с помощью следующего файла: /root/test/test.txt (права доступа 0755, 0700и 0777). Я выпустил, ./script.sh /root/test/test.txt joeи он повторил original file /root/test/test.txt is readable for joe. Также, пытаясь это сделать, я неправильно набрал тестовый dir:, ./script.sh /root/tst/test.txt joeи он повторил original file /root/tst/test.txt is readable for joe. Я что-то пропустил?
Металлокодер
@Metalcoder извините, это моя вина. Был еще один восклицательный знак. Теперь он удален, вы можете попробовать еще раз, теперь он должен работать нормально.
Раш
@ сработало! Это дополнительное восклицание сводит на нет результат -r $FILE, верно?
Металлокодер
1

Вот моя попытка предоставить эту функциональность. Я решил использовать stat, в whileпетлю, и dirname.

Я создал этот скрипт walkdir.bash:

#/bin/bash

cwd="$1"
while [ "x$cwd" != x/ ]; do
  info=`stat "$cwd" |grep "Access: ("`
  printf "%s : %s\n" "$info" "$cwd"

  cwd=`dirname "$cwd"`;
done

Вы запускаете это так:

$ walkdir.bash "/home/saml/blog/vmware_networking_tutorial/url.txt"
Access: (0664/-rw-rw-r--)  Uid: (  500/    saml)   Gid: (  501/    saml) : /home/saml/blog/vmware_networking_tutorial/url.txt
Access: (0775/drwxrwxr-x)  Uid: (  500/    saml)   Gid: (  501/    saml) : /home/saml/blog/vmware_networking_tutorial
Access: (0775/drwxrwxr-x)  Uid: (  500/    saml)   Gid: (  501/    saml) : /home/saml/blog
Access: (0700/drwx------)  Uid: (  500/    saml)   Gid: (  501/    saml) : /home/saml
Access: (0755/drwxr-xr-x)  Uid: (    0/    root)   Gid: (    0/    root) : /home
SLM
источник