linux - 如何“cd”到显示“权限被拒绝”的符号链接目录?
问题描述
我目前在我的 Linux 操作系统上有两个用户,用于两个不同的 DE。但是,我想尽可能地消除帐户之间的文件重复性。具体来说,我一直在尝试将~/german-capstone
文件夹从用户链接segeeslice
到lucifer
.
为此lucifer
,我打电话给:
ln -s /home/segeeslice/german-capstone /home/lucifer/
它按预期运行,将链接放在正确的位置。但是,尝试访问它会引发如下错误:
bash: cd: german-capstone: Permission denied
我知道这可能只是一个权限问题,但我找不到来源!我已经尽可能让双方完全访问该文件夹及其内容,但似乎没有任何效果。我错过了什么?
作为对评论的回应,以下是完整的权限列表:
------ /home/lucifer/german-capstone ------
drwxr-xr-x 755 root root /
drwxr-xr-x 755 root root /home
drwxr--r-- 744 lucifer lucifer /home/lucifer
lrwxrwxrwx 777 lucifer lucifer /home/lucifer/german-capstone
-> /home/segeeslice/german-capstone
drwxr--r-- 744 segeeslice segeeslice /home/segeeslice
drwxrwxrwx 777 segeeslice segeeslice /home/segeeslice/german-capstone
更高级别仍然具有正确的读取属性...我需要在某处授予更多权限吗?
解决方案
它可能是源目录或符号链接路径上任何位置的权限,还包括在这些东西的路径中遇到的任何其他符号链接。
这是一个脚本,它将为您显示所有这些权限。它将显示从根目录到相关路径的所有内容的权限,如果遇到符号链接,它将根据链接目标重新启动,除了它不会重复它拥有的任何目录的输出已经向您展示了(例如,权限/
仅显示一次)。
#!/usr/bin/perl
#
use strict;
my $usage=<<EOF;
Usage: $0 file [file ...]
Shows permissions on every path component from root directory to the named
file(s), including paths traversed while following symlinks.
Also shows permissions and contents of any .ftpaccess or .htaccess files
encountered.
If multiple files are specified, gives a listing for them all, but for later
files does not show again the permissions on a path component already shown
for earlier files.
EOF
#----------------------------------------------------------------------
use Cwd;
my $cwd = cwd;
chomp $cwd;
if ($#ARGV==-1) {
print $usage;
exit 1;
};
my @history=();
my @accessfiles=();
# loop over files on command line.
FILE: foreach my $fullpath (@ARGV) {
# prepend cwd if relative path
$fullpath="$cwd/$fullpath" unless $fullpath =~ /^\//;
# fix pathname..
$fullpath=stripslashes($fullpath);
print "\n------ $fullpath ------\n\n";
my $len=length $fullpath;
my $pos=-1;
my @targets=($fullpath);
ELEMENT: while ($pos<$len) {
# get full pathname of next element (etc)
my $stem=($pos>=0) ? substr($fullpath,0,$pos) : ''; # parent
$pos=index($fullpath,'/',$pos+1);
$pos=$len if $pos==-1;
my $path=($pos>0) ? substr($fullpath,0,$pos) : '/';
my $remainder=substr($fullpath,$pos);
#
# stat the path element.
#
my @stat=lstat($path);
my $okay=($#stat != -1);
# tidy up as follows:
# if trailing "/foo/.." or "/." strip it and move to next element.
#
# We can do this because at this stage "foo" isn't a link,
# or we would already have followed it, but only do it if stat
# succeeded as parent might not be a directory (in that case, the
# error trap later will be executed).
#
my ($newpath, $subst);
if ($okay) {
$subst=1;
if ( $path =~ /\.\.$/ ) {
if ($stem eq '') {
$newpath='/';
$fullpath=$remainder;
} else {
($newpath = $stem) =~ s,/([^/]*?)$,, ;
$fullpath=$newpath.$remainder;
if ($newpath eq '') {$newpath='/';}
}
}
elsif ( $path =~ /\.$/ ) {
if ($stem eq '') {
$newpath='/';
$fullpath=$remainder;
} else {
$newpath = $stem;
$fullpath=$newpath.$remainder;
}
}
else {
$subst=0;
}
if ($subst) {
$path=$newpath;
$pos=length $path;
$len=length $fullpath;
next ELEMENT;
}
}
# have we been here before?
my $beenthere=grep {$_ eq $path} @history;
push @history,$path;
# is it a symlink?
if (-l _) {
# yes. see where it points
my $pointsto=readlink $path;
my $newfile;
if ($pointsto =~ /^\//) {
# link is absolute pathname
$newfile=$pointsto.substr($fullpath,$pos);
$pos=-1;
} else {
# link is relative pathname
$newfile=$stem.'/'.$pointsto.substr($fullpath,$pos);
$pos=length $stem;
}
if (!$beenthere) {
show_stat(\@stat,$path,$pointsto);
}
# strip extra "/"
$newfile=stripslashes($newfile);
# check for recursive links
my $beenthere2=grep {$_ eq $newfile} @targets;
push @targets,$newfile;
if ($beenthere2) {
print " === SYMLINK LOOP DETECTED ===\n";
next FILE;
}
# follow the link (stripping extra "/"s)
$fullpath=$newfile;
$len=length $fullpath;
} else {
# no, not a symlink
# print info, with usernames/groupnames where possible
# unless we've been here before...
if (!$beenthere) {
if (! $okay) {
print "\n*** ERROR : $path : $! ***\n";
next FILE;
}
show_stat(\@stat,$path);
#
# check for any {.htaccess,.ftpaccess} files
#
for my $name (qw(.htaccess .ftpaccess)) {
my $file = "$path/$name";
if (-e $file) {
push @accessfiles,$file;
}
}
}
}
} # end ELEMENT loop
} # end FILE loop
continue {
print "\n";
}
if ($#accessfiles > -1) {
print "Access control files of possible relevance:\n\n";
for my $file (@accessfiles) {
my @stat = stat($file);
show_stat(\@stat,$file);
if (open my $access,$file) {
print "\n ---- Contents of $file ----\n";
while (defined (my $line=<$access>)){
chomp $line;
print " $line\n";
}
close $access;
print " ------- End of $file -------\n";
} else {
print " Could not open $file: $!\n";
}
}
print "\n";
}
exit 0;
#-------------------------------------------------------------
sub stripslashes
{
my $line = shift;
# strip trailing or repeated '/'s
$line =~ s,/*$,,;
$line =~ s,//+,/,g;
$line =~ s,^$,/,;
return $line;
}
sub show_stat
{
use Fcntl ':mode';
my ($stat,$path,$linktarget) = @_;
my ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,
$atime,$mtime,$ctime,$blksize,$blocks) = @$stat;
my @pwent=getpwuid($uid);
my $username=($#pwent == -1) ? "($uid)" : $pwent[0];
my @grent=getgrgid($gid);
my $grpname=($#grent == -1) ? "($gid)" : $grent[0];
printf ("%s %4o %-8s %-8s %s\n",
symbolic_mode($mode),
$mode&07777,$username,$grpname,$path);
if (S_ISLNK($mode) and defined($linktarget)) {
print " -> $linktarget\n";
}
}
sub symbolic_mode
{
# takes a numerical mode returned by stat,
# returns a symbolic string as per "ls -l"
# e.g. for 0640 returns "-rw-r-----"
my $mode = shift;
use Fcntl ':mode';
my $typechar =
S_ISREG($mode) ? '-' :
S_ISDIR($mode) ? 'd' :
S_ISLNK($mode) ? 'l' :
S_ISBLK($mode) ? 'b' :
S_ISCHR($mode) ? 'c' :
S_ISFIFO($mode) ? 'p' :
S_ISSOCK($mode) ? 's' :
'?';
my $modestr = $typechar . 'rwxrwxrwx';
for (my $bit=0; $bit <= 8 ; $bit++) {
if (($mode & (1<<$bit)) == 0) {
substchar(\$modestr,9-$bit,"-");
}
}
if ($mode & 01000) {
substchar(\$modestr,9,
($mode & 0001) ? "t" : "T");
}
if ($mode & 02000) {
substchar(\$modestr,6,
($mode & 0010) ? "s" : "S");
}
if ($mode & 04000) {
substchar(\$modestr,3,
($mode & 0100) ? "s" : "S");
}
return $modestr;
}
sub substchar
{
# substitutes a character in a string
my ($sref, $pos, $newchar) = @_;
my $string = $$sref;
my $newstring = substr($string,0,$pos) . $newchar . substr($string,$pos+1);
$$sref=$newstring;
}
示例输出:
$ mkdir -p /tmp/mydir/stuff
$ ln -s stuff /tmp/mydir/stuff2
$ cal > /tmp/mydir/stuff2/myfile
$ mkdir /tmp/mydir2
$ ls /tmp/mydir2/stuff2/myfile
ls: cannot access '/tmp/mydir2/stuff2/myfile': No such file or directory
$ ls /tmp/mydir/stuff2/
myfile
$ ln -s /tmp/mydir/stuff2/myfile /tmp/mydir/stuff2/thingy
$ chmod 700 /tmp/mydir
$ permsto /tmp/mydir/stuff2/thingy
------ /tmp/mydir/stuff2/thingy ------
drwxr-xr-x 755 root root /
drwxrwxrwt 1777 root root /tmp
drwx------ 700 myuser mygroup /tmp/mydir
lrwxrwxrwx 777 myuser mygroup /tmp/mydir/stuff2
-> stuff
drwxr-xr-x 755 myuser mygroup /tmp/mydir/stuff
lrwxrwxrwx 777 myuser mygroup /tmp/mydir/stuff/thingy
-> /tmp/mydir/stuff2/myfile
-rw-r--r-- 644 myuser mygroup /tmp/mydir/stuff/myfile
因此,您可以查看输出并一目了然地看到任何权限问题潜伏在哪里。
现在问题已更新为包含相关目录中脚本的输出,很明显问题出在以下目录的权限上:
drwxr--r-- 744 lucifer lucifer /home/lucifer
drwxr--r-- 744 segeeslice segeeslice /home/segeeslice
如果进程已读取但不执行对目录的访问,它将能够列出目录但不能访问其中包含的任何路径。对于具有八进制模式 744 的目录,任何不以所有者(或 root)身份运行的进程都是这种情况,这将依赖于“组”或“其他”权限。如果将其更改为八进制模式 755(即为“组”和“其他”添加执行权限),那么这些将具有必要的访问权限。
推荐阅读
- python - 什么是'|' 和 '<' 表示 numpy 的类型?
- python - 无法正确部署 Dash 1.4.0 到 CentOS Apache 服务器,网页一直处于上传状态,为什么?
- html - 如何从css中的所有相似类中选择第一个孩子
- ms-word - 基于另一个邮件合并字段抑制 Word 中的文本和邮件合并字段
- javascript - 我如何获得一个按钮来显示一个图像而不是数组中的所有图像
- sql-server - 如何克服子查询的“iif”限制?
- yesod - 使用 yesod 时如何查看特定文件生成的模板 haskell 代码
- vim - Taglist 不会动态更新
- python - 如何修复在 Python 中永远持续的 while 循环?
- django - 如果用户创建了对象,则 Django 重定向