所以这是我的代码:
#include <stdio.h>
#include <string.h>
#include <systemd/sd-journal.h>
int main(int argc, char *argv[]) {
setgid(1000);
setuid(1000);
int r;
sd_journal *j;
r = sd_journal_open(&j, SD_JOURNAL_LOCAL_ONLY);
if (r < 0) {
fprintf(stderr, "Failed to open journal: %s\n", strerror(-r));
return 1;
}
for (;;) {
const void *d;
size_t l;
r = sd_journal_next(j);
if (r < 0) {
fprintf(stderr, "Failed to iterate to next entry: %s\n", strerror(-r));
break;
}
if (r == 0) {
/* Reached the end, let's wait for changes, and try again */
r = sd_journal_wait(j, (uint64_t) -1);
if (r < 0) {
fprintf(stderr, "Failed to wait for changes: %s\n", strerror(-r));
break;
}
continue;
}
r = sd_journal_get_data(j, "MESSAGE", &d, &l);
if (r < 0) {
fprintf(stderr, "Failed to read message field: %s\n", strerror(-r));
continue;
}
printf("%.*s\n", (int) l, (const char*) d);
}
sd_journal_close(j);
return 0;
}
这是“man sd_journal_get_fd”中的示例,在开头添加了 setgid/setuid 调用。它无法从日志中读取。
uid 为 1000 的用户在 systemd-journal 组中,并且可以使用 journalctl 命令成功读取日志。
当从 root 或从具有 uid 1000 且没有 setgid/setuid 调用的用户运行时,它工作正常。
我试图涵盖的用例如下:它是一个 systemd 服务,应该以 root 身份运行,做一些“root”相关的事情并开始从一些文件/期刊中读取。问题是“某些文件”是可配置的,我们不能允许它在未经许可的情况下访问文件,因为它会造成安全漏洞。这就是为什么在它执行过程中的某个时候调用 setgid/setuid 的原因。它也不能作为非根服务启动,因为它正在做一些“仅限根”预定义的东西。上面的代码只是一个简化。
这不适用于具有 systemd 219 的 CentOS 7,但它适用于具有 systemd 245 的 Ubuntu 20.04
任何有关如何解决问题的建议、systemd-journal 错误报告或为什么上述方案不适用的文档都值得赞赏。