You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

嵌入式设备非root调用DBus Suspend方法报Permission Denied如何解决?

非root用户调用DBus休眠方法权限问题

问题描述

我刚接触DBus,正在使用sdbus-cpp库在自研C++应用中调用org.freedesktop.login1.Manager.Suspend方法,目标是控制设备进入休眠模式。
应用以root用户运行时功能完全正常,但出于安全考虑需要以非root用户(用户名为embuser)运行。
我查阅资料后在/etc/dbus-1/system.d/目录下创建了suspend.conf配置文件,内容如下:

root@colibri:/etc/dbus-1/system.d$ cat suspend.conf
<!DOCTYPE busconfig PUBLIC
          "-//freedesktop//DTD D-BUS Bus Configuration 1.0//EN"
          "http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">
<busconfig>

  <!-- Only root or user embuser can own the login1 service -->
  <policy user="embuser">
    <allow own="org.freedesktop.login1"/>
  </policy>
  <policy user="root">
    <allow own="org.freedesktop.login1"/>
  </policy>

  <!-- Allow anyone to invoke methods on login1 server -->
  <policy context="default">
    <allow send_destination="org.freedesktop.login1"/>
    <allow receive_sender="org.freedesktop.login1"/>
  </policy>
</busconfig>

我执行systemctl restart dbus重启DBus守护进程后,以embuser用户启动应用,程序输出如下信息后终止:

terminate called after throwing an instance of 'sdbus::Error'
what(): [org.freedesktop.DBus.Error.AccessDenied] Permission denied
Aborted

应用以root用户启动时可正常触发设备休眠,因此排除C++应用本身的问题。
请问我该如何配置才能让非root用户正常调用该DBus方法?现有配置文件是否存在遗漏?还有其他可行的解决路径吗?
我的设备运行在搭载ARM iMX7d处理器的Colibri嵌入式Linux模块上,内核和systemd版本信息如下:

$ uname -r
5.4.91-5.2.0-devel+git.c59b3c2da1e9

$ systemctl --version
systemd 244 (244.5+)
+PAM -AUDIT -SELINUX +IMA -APPARMOR -SMACK +SYSVINIT +UTMP -LIBCRYPTSETUP -GCRYPT -GNUTLS +ACL +XZ -LZ4 -SECCOMP +BLKID -ELFUTILS +KMOD -IDN2 -IDN -PCRE2 default-hierarchy=hybrid

解决方案

问题根因

现有配置存在两个核心问题:

  1. 多余的服务所有权配置:<allow own="org.freedesktop.login1"/>是允许用户注册该DBus服务的权限,但org.freedesktop.login1本身由systemd-logind服务以root身份持有,你的应用仅作为调用方不需要该权限,属于无效配置。
  2. 遗漏PolicyKit校验:systemd-logind默认会通过Polkit做二次权限校验,即使DBus层面放行了调用请求,普通用户默认也没有休眠操作的Polkit权限,这是触发AccessDenied报错的核心原因。

解决方法

方案1:配置Polkit规则(推荐,安全性最高)

该方案仅开放embuser用户的休眠权限,不影响其他用户和服务的权限配置:

  1. 在/etc/polkit-1/rules.d/目录下创建规则文件50-allow-embuser-suspend.rules,内容如下:
polkit.addRule(function(action, subject) {
    if (action.id == "org.freedesktop.login1.suspend" && subject.user == "embuser") {
        return polkit.Result.YES;
    }
});
  1. 设置规则文件权限:
    chmod 644 /etc/polkit-1/rules.d/50-allow-embuser-suspend.rules
  2. 重启Polkit服务生效:
    systemctl restart polkit

方案2:调整DBus配置(适配无Polkit的精简嵌入式环境)

如果你的嵌入式系统裁剪了Polkit组件,可以直接修正DBus配置实现权限开放:

  1. 把你原来的suspend.conf替换为如下内容,删除多余的服务所有权配置,仅放开Suspend方法的调用权限:
<!DOCTYPE busconfig PUBLIC
          "-//freedesktop//DTD D-BUS Bus Configuration 1.0//EN"
          "http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">
<busconfig>
  <policy user="embuser">
    <allow send_destination="org.freedesktop.login1"
           send_interface="org.freedesktop.login1.Manager"
           send_member="Suspend"/>
  </policy>
</busconfig>
  1. 重启DBus服务生效:
    systemctl restart dbus
  2. 确认/etc/systemd/logind.conf中AllowSuspend=yes,如果修改了该配置需要重启systemd-logind服务:
    systemctl restart systemd-logind

方案3:快速适配方案

绝大多数Linux发行版默认power用户组拥有休眠、关机等电源操作权限,直接把embuser加入该组即可:
usermod -aG power embuser
执行后重新登录embuser用户即可生效。


内容的提问来源于stack exchange,提问作者Rob123

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.30 05:06:04