Làm thế nào để kiểm tra xem người dùng có thể truy cập một tập tin nhất định không?


60

Quyền của người dùng * nix thực sự đơn giản, nhưng mọi thứ có thể trở nên lộn xộn khi bạn phải tính đến tất cả quyền truy cập thư mục mẹ trước khi tiếp cận một tệp đã cho. Làm cách nào để kiểm tra xem người dùng có đủ đặc quyền không? Nếu không, thì thư mục nào đang từ chối truy cập?

Ví dụ: giả sử người dùng joevà tệp /long/path/to/file.txt. Ngay cả khi file.txtđược mã hóa thành 777, joe vẫn phải có thể truy cập /long/, và sau đó /long/path//long/path/to/trước đó . Những gì tôi cần là một cách để tự động kiểm tra này. Nếu joekhông có quyền truy cập, tôi cũng muốn biết nơi anh ta đã bị từ chối. Có lẽ anh ta có thể truy cập /long/, nhưng không /long/path/.

Câu trả lời:


71

Bạn có thể dùng

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

sẽ xuất ra tất cả các quyền trong đường dẫn trong một danh sách dọc.

hoặc là

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

liệt kê tất cả chủ sở hữu và quyền


2
Đây phải là câu trả lời đúng. Trong thực tế, việc sử dụng namei <path> || exit 1cho phép bạn phát hiện vấn đề cấp phép dễ dàng trong tập lệnh.
lorenzog

5
nó không trả lời trực tiếp liệu joe có quyền truy cập vào tập tin hay không.
jfs

15

Bạn có thể sử dụng bash để làm điều này.

$ 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

Để kiểm tra điều này cho một người dùng cụ thể, bạn có thể sử dụng sudo.

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

kịch bản sudo -u joe. Ở đây script là tên của tập tin script phải không? Vì vậy, nói sudo của bạn để hành động như joe đã gọi kịch bản?
tgkprog

Đúng. Tôi đã sửa đổi câu trả lời của tôi để làm rõ điều đó.

Tôi đã thực hiện một sửa đổi nhỏ cho kịch bản của mình để xử lý các đường dẫn không tuyệt đối.

@EvanTeitelman Với một đường dẫn tuyệt đối, ý bạn là khởi tạo pathđể trống? hay /?
Gilles 'SO- ngừng trở nên xấu xa'

@Gilles: Ý tôi là nó trống rỗng. Trong ví dụ này, pathđược đặt thành /longlần đầu tiên xung quanh vòng lặp, điều này đúng. Tôi có nên đặt paththành không có gì rõ ràng ( path=)? Ngoài ra, cảm ơn vì đã đơn giản hóa việc sử dụng của tôi tr.

3

Như tôi đã nhận được từ câu hỏi của bạn, bạn nên kiểm tra nó cho những người dùng khác nhau (không chỉ joe), vì vậy trong trường hợp đó, cách dễ nhất là kiểm tra lại nó qua sudo như thế này:

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

sử dụng:

./script.sh /long/path/to/file.txt joe

Joe cần thực thi quyền trên các thư mục, không đọc quyền.

@EvanTeitelman có, bạn đúng. Đã sửa.
vội vàng

@rush Tôi cố gắng để kiểm tra nó bằng cách sử dụng tập tin sau đây: /root/test/test.txt (quyền được 0755, 07000777). Tôi ban hành ./script.sh /root/test/test.txt joevà nó lặp lại original file /root/test/test.txt is readable for joe. Ngoài ra, trong khi thử điều này, tôi đã đánh dấu sai mục kiểm tra: ./script.sh /root/tst/test.txt joevà nó lặp lại original file /root/tst/test.txt is readable for joe. Tôi đã bỏ lỡ một cái gì đó?
Metalcoder

@Metcoder xin lỗi, đó là lỗi của tôi. Có thêm một câu cảm thán. Bây giờ nó đã được gỡ bỏ, bạn có thể thử lại một lần nữa, nó sẽ hoạt động tốt ngay bây giờ.
vội vàng

@rush nó làm việc! Câu cảm thán thêm đó phủ nhận kết quả của -r $FILE, phải không?
Metalcoder

1

Đây là nỗ lực của tôi trong việc cung cấp chức năng này. Tôi đã chọn sử dụng stat, một whilevòng lặp, và dirname.

Tôi đã tạo tập lệnh này , 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

Bạn chạy nó như vậy:

$ 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
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.