Ant*_*gan 6 setuid permissions locate
我通常会找到所有已作为问答发布的 Unix 相关问题的答案。然而,这个特殊的问题在过去的一个小时里让我很难过,所以我想我会在这个网站上问我的第一个问题。
我有一个运行 CentOS 5.11 的开发/登台服务器。locate
以普通用户身份运行不会产生任何输出(甚至没有错误消息):
locate readdir
Run Code Online (Sandbox Code Playgroud)
但是,以超级用户身份运行命令会打印有效结果列表:
$ sudo locate readdir
/home/anthony/repos/php-src/TSRM/readdir.h
/home/anthony/repos/php-src/ext/standard/tests/dir/readdir_basic.phpt
... etc.
Run Code Online (Sandbox Code Playgroud)
strace
通常可以帮助我调试任何此类问题并运行strace locate readdir
显示:
stat64("/var/lib/mlocate/mlocate.db", 0xbff65398) = -1 EACCES (Permission denied)
access("/", R_OK|X_OK) = -1 EACCES (Permission denied)
exit_group(1) = ?
Run Code Online (Sandbox Code Playgroud)
我检查了locate
二进制文件及其默认数据库的所有权和权限。如所预期的命令是setgid
与slocate
作为该组所有者而数据库具有适当的所有权和权限。
$ ls -l /usr/bin/locate
-rwx--s--x 1 root slocate 22280 Sep 3 2009 /usr/bin/locate
$ sudo ls -l /var/lib/mlocate/mlocate.db
-rw-r----- 1 root slocate 78395703 May 8 04:02 /var/lib/mlocate/mlocate.db
$ sudo ls -ld /var/lib/mlocate/
drwxr-x--- 2 root slocate 4096 Sep 3 2009 /var/lib/mlocate/
Run Code Online (Sandbox Code Playgroud)
也没有异常的文件属性:
$ sudo lsattr /usr/bin/locate /var/lib/mlocate/mlocate.db
------------- /usr/bin/locate
------------- /var/lib/mlocate/mlocate.db
Run Code Online (Sandbox Code Playgroud)
同时,在生产服务器上一切正常。locate readdir
以普通(非 root)用户身份运行会返回一个结果列表,因为它应该:
$ locate readdir
/usr/include/php/TSRM/readdir.h
/usr/lib/perl5/5.8.8/i386-linux-thread-multi/auto/POSIX/readdir.al
/usr/share/man/man2/readdir.2.gz
Run Code Online (Sandbox Code Playgroud)
为了进行比较,我也运行了此命令,strace
但随后遇到了与登台服务器上相同的权限被拒绝错误。我想知道这是怎么回事,直到我阅读了sudo
. 在错误部分列出:
使用 setuid 位的程序在被跟踪时没有有效的用户 ID 权限。
所以,不幸的是,我不能strace
用于调试。
我在 Staging 和 Production 服务器之间比较了上述所有命令的结果,它们之间没有区别。两个系统都有mlocate-0.15-1.el5.2
RPM,没有修改它们的文件,如rpm -V mlocate
.
我认为这可能与以下事实有关:在有问题的登台服务器上,我的登录名是使用 Winbind 进行身份验证的,但我在同一个盒子上创建了一个普通的本地用户,但我仍然遇到同样的问题。显然还有一些我想念的东西,但我根本不知道它是什么。
我怀疑它与 setgid 文件权限有关,可能是 PAM 或可能是 SELinux。我对 PAM 或 SELinux 不太了解:我只在配置 Winbind 身份验证时查看过 PAM,而 SELinux 是随操作系统一起安装的,但我从未使用过它。
注意:生产服务器受到的修改远远少于进行了一些实验的开发服务器。
问题是/
(根目录)的权限以及从strace
输出中找到这一行的线索:
access("/", R_OK|X_OK) = -1 EACCES (Permission denied)
Run Code Online (Sandbox Code Playgroud)
您缺少 的组读取权限设置/
。但是因为您仍然拥有x
(执行)权限,它允许您遍历目录,所以您仍然可以访问文件系统上的所有文件,这就是为什么在这些权限有效时大多数一切都继续工作的原因。您唯一不能做的就是列出/
. 大多数命令不需要 list /
,它们要么使用相对于当前目录的路径名,要么使用访问根外特定众所周知目录的绝对路径名(如/etc
和/var
)。
出于安全原因,locate
即使它可以访问由特权用户生成的完整文件名清单,也坚持只报告调用用户可以通过从根扫描整个文件系统来找到的结果。由于您无法列出/
,这使得直接从根扫描任何内容都无法启动,因此locate
根本不会报告任何内容。