我写了一个简单的 php crontab 管理程序,像这样更新了“someuser”的 crontab
crontab -u someuser /path/to/new/cronfile
然而我需要以 root 身份运行一些 php 脚本,因此我决定编辑 root 的 crontab,并将所需的用户字段添加到每个脚本:
crontab -u root /path/to/new/cronfile
令人惊奇的是,它有效!
我真的很想知道这是怎么可能的,并检查了/etc/crontab
它的权限。
rw-r--r--
那么,任何用户如何能够以 root 的名义运行各种计划的脚本并让每个用户都有访问权限呢?
那肯定是一个错误,是吗?
// 编辑(根据评论添加 php 脚本)
$crontabCacheFile = PATH_CACHE . 'crontab.cache';
$cronFile = PATH_ROOT . '.crontab';
if(!is_file($crontabCacheFile) || (filemtime($cronFile) > filemtime($crontabCacheFile))) {
# install new cronfile
if(false === $result = system("crontab -u root $cronFile"))
logWrite("failed to install new crontab $cronFile", true);
else
file_put_contents($crontabCacheFile, date('Y-m-d H:i:s') . " installed new crontab $result\n", FILE_APPEND);
}
该脚本在 www 用户(拥有 /var/www/projectdir 中的 PATH_* 目录)上运行
lsb_release -a
吐出:
No LSB modules are available.
Distributor ID: Ubuntu
Description: Ubuntu 18.04.6 LTS
Release: 18.04
Codename: bionic
答案1
由于您编写 PHP 脚本的方式,可能会造成混淆。您检查返回的是否正好是false
,但system()
即使调用失败,它也会返回一个空字符串(因为错误消息打印在 STDERR 上,而不是 STDOUT 上)。
那么,您是否检查过 crontab 确实已安装?或者您只是检查日志中是否没有“安装失败...”消息?
我是这样检查的:
php -a
php > if (false === system('crontab -u root /tmp/foo')) echo "false returned"; else echo "not false returned";
must be privileged to use -u
not false returned
这会返回一个错误,但是仍然会转到 if 的 else 分支!
如果您使用它==
进行比较,它会记录消息:
php > if (false == system('crontab -u root /tmp/foo')) echo "false returned"; else echo "not false returned";
must be privileged to use -u
false returned
但你最好检查一下返回代码...
system("crontab -u root $cronFile", $result)
if ($result === 0) //success