为什么在向用户求助时我的权限被拒绝?

Why am I getting a permission denied when su'ing to a user?

如果我从我的主目录 su user 获得 bash 完成的权限被拒绝,但是如果我从另一个目录 su user 则没有错误。

Can't locate strict.pm:   lib/strict.pm: Permission denied at 
/usr/bin/vendor_perl/bash-complete line 7.
BEGIN failed--compilation aborted at /usr/bin/vendor_perl/bash-complete line 7.

引用文件的第 7 行 use strict; ... 至少自 90 年代后期以来,每个版本的 perl 都包含该文件。

su user 来源 /etc/bash.bashrc 和被 su'd 的用户 .bashrc。为什么调用用户在文件系统中的位置会改变这个?

有关详细信息,请参阅 my repo,但我想我已经掌握了必要的基础知识。

编辑:设置的更多说明。

我已将以下行添加到 /etc/bash.bashrc(这是发生错误的地方):

if [[ $USER == 'testloginfiles' ]]; then
    echo "/etc/bash.bashrc (-: $-) ($(shopt login_shell))"
    printf '@INC: %s\n' $(perl -e 'print join ":", @INC')
fi

如果我在我的主目录中,这是输出:

$ pwd;su testloginfiles
/home/harleypig
Password: 
/etc/bash.bashrc (-: himBH) (login_shell        off)
@INC: lib:/usr/lib/perl5/5.28/site_perl:/usr/share/perl5/site_perl:/usr/lib/perl5/5.28/vendor_perl:/usr/share/perl5/vendor_perl:/usr/lib/perl5/5.28/core_perl:/usr/share/perl5/core_perl
Can't locate strict.pm:   lib/strict.pm: Permission denied at /usr/bin/vendor_perl/bash-complete line 7.
BEGIN failed--compilation aborted at /usr/bin/vendor_perl/bash-complete line 7.
/home/testloginfiles/.bashrc (-: himBH) (login_shell        off)
[testloginfiles@sweetums harleypig]$

如果我在另一个目录中(例如,/tmp),我会得到以下信息:

$ pwd ; su testloginfiles
/tmp
Password: 
/etc/bash.bashrc (-: himBH) (login_shell        off)
@INC: lib:/usr/lib/perl5/5.28/site_perl:/usr/share/perl5/site_perl:/usr/lib/perl5/5.28/vendor_perl:/usr/share/perl5/vendor_perl:/usr/lib/perl5/5.28/core_perl:/usr/share/perl5/core_perl
/home/testloginfiles/.bashrc (-: himBH) (login_shell            off)
[testloginfiles@sweetums tmp]$

@pcronin 建议有一个相对路径,但我的主目录和 /tmp 都没有 lib 目录。为什么一个会导致错误而另一个不会?

  1. 在 Perl 中,use strict 告诉 perl 从名为 strict.pm 的文件中查找、加载和导入符号。它通过在 @INC 列表中搜索目录的有序列表来完成此操作。有关如何构建的更多信息,请参阅 this answer。您看到的错误表明,在成功找到 strict.pm 之前,perl 在执行用户(可能是 testloginfiles)无权访问的路径中搜索。

  2. @INC 的内容会受到脚本所在目录 运行 以及环境变量的影响。在您的情况下,由于当程序 运行 来自一个目录而不是另一个目录时问题就会显现出来,因此 @INC 中的一个(或多个)条目可能是相对路径,例如 lib(而不是像 /usr/share/perl5 这样的东西),或者,可以影响 perl 的 @INC 列表的环境变量在目标用户的环境中是不同的。

  3. 运行ning perl -E 'print join("\n", @INC)'; 将生成一个要搜索的位置列表。 运行 在普通用户的 shell 中,将结果与将其添加到 testloginfiles 的 .bashrc 文件中时发生的结果进行比较。输出的差异应该可以解释行为的差异。

更新

  1. 根据您提供的新信息,我们发现 @INC 没有差异,这让我们了解了这两种情况对 @INC 的不同解释。正如您在 su 手册页中所见,su 并未更改当前目录,这意味着相对路径根本不会影响 @INC 的解释。但是,su 正在更改用户,因此这意味着 su 用户正在测试 /home/harleypig/lib/strict.pm 是否存在。我敢打赌 su 用户没有权限读取 harleypig 的主目录以查看该文件是否存在,从而导致错误。

我没有仔细阅读 su 手册页。答案在第一节:

For backward compatibility, su defaults to not change the current directory and to only set the environment variables HOME and SHELL (plus USER and LOGNAME if the target user is not root).

所以,我现有的环境,其中包括 PERL5LIB=lib。被留在原地。 /etc/bash.bashrc 正在使用我现有的任何环境执行。这似乎是一个可能的安全风险。

无论如何,以下解决了这个问题,尽管它仍然没有解释为什么它只是从我的主目录中给出错误:

$ pwd ; PERL5LIB= su testloginfiles
/home/harleypig
Password: 
/etc/bash.bashrc (-: himBH) (login_shell        off)
@INC: /usr/lib/perl5/5.28/site_perl:/usr/share/perl5/site_perl:/usr/lib/perl5/5.28/vendor_perl:/usr/share/perl5/vendor_perl:/usr/lib/perl5/5.28/core_perl:/usr/share/perl5/core_perl
/home/testloginfiles/.bashrc (-: himBH) (login_shell            off)
[testloginfiles@sweetums harleypig]$