如何检查用户是否可以访问给定文件?


60

* nix用户权限确实很简单,但是当您在到达给定文件之前必须考虑所有父目录访问权限时,事情可能会变得混乱。如何检查用户是否具有足够的特权?如果不是,那么哪个目录拒绝访问?

例如,假设一个用户joe和一个文件/long/path/to/file.txt。即使file.txt已更改为777,joe仍必须能够访问/long/,然后/long/path/再访问/long/path/to/。我需要的是一种自动检查此方法的方法。如果joe没有访问权限,我也想知道他在哪里被拒绝了。也许他可以访问/long/,但不能/long/path/

Answers:


71

您可以使用

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

它将在垂直列表中输出路径中的所有权限。

要么

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

列出所有所有者和权限


2
这应该是正确的答案。实际上,使用namei <path> || exit 1可以使您轻松地在脚本中检测权限问题。
lorenzog

5
它不会直接回答joe是否有权访问该文件。
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脚本。脚本是脚本文件的名称吗?所以你让sudo扮演乔的角色正在调用脚本吗?
tgkprog 2013年

精确地 我已经修改了答案以澄清这一点。

我对脚本进行了少许修改,以处理非绝对路径。

@EvanTeitelman使用绝对路径,您是要初始化path为空吗?还是/
吉尔斯2013年

@吉尔斯:我是说它是空的。在该示例中,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

Joe需要目录的执行权限,而不是读取权限。

@EvanTeitelman是的,您是对的。固定。
2013年

@rush我尝试使用以下文件来测试它:/root/test/test.txt(权限075507000777)。我发出了./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

@Metalcoder抱歉,这是我的错。还有一个额外的感叹。现在已将其删除,您可以再尝试一次,现在应该可以正常使用了。
2013年

@rush成功了!那额外的感叹否定了的结果-r $FILE,对吗?
Metalcoder

1

这是我提供此功能的尝试。我选择使用statwhile循环和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
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.