/run/user/NNNN/dconf/user 文件权限错误的原因有哪些?我们该如何解决它们?

/run/user/NNNN/dconf/user 文件权限错误的原因有哪些?我们该如何解决它们?

关于 GUI 应用程序有几个悬而未决的问题,其控制台输出显示类似于以下内容的重复错误:

(XXXX:YYYY): dconf-CRITICAL **: unable to create file '/run/user/NNNN/dconf/user': Permission denied.  dconf will not work properly.

或者

(XXXX:YYYY): dconf-CRITICAL **: unable to create directory '/run/user/NNNN/dconf': Permission denied.  dconf will not work properly.

其中 XXX 是应用程序名称,YYY 是数字,NNN 是用户 ID 号 (?)。

这些问题往往没有得到答复,或者得到的答案不能解决问题(或者可能是没有反应的海报)。

我希望引起社区对这个问题的足够关注(如果必要的话可能会提供赏金),以提供对该问题的可能原因的正确描述,并列出应该解决的几个行动(例如在 90% 的情况下),以便将来,人们可以轻松地将这些问题的另一种变体标记为与此问题重复。

答案1

最简单的原因是整个/run/user/<UID>目录不存在 – 它不是由 systemd-logind 创建的,通常是因为有问题的 UID 没有经过标准的“用户登录”过程,而只是su'd 或sudo'd到,而不调用 pam_systemd。

(“权限被拒绝”来自 dconf 尝试 mkdir 所有父目录,但它无法执行此操作,因为 /run 和 /run/user 本身只能由 root 写入。)

当至少创建该 UID 的一个会话时,就会创建此目录 - 同样,当 systemd-logind 看到用户的会话计数下降到 0 时,该目录也会被删除。例如,在您的一篇文章中,使用su -l而不是su可以解决问题是因为它使 su 使用不同的 PAM 配置,其中 pam_systemd已启用。

因此,如果在通过 VNC 使用桌面时开始显示您自己的 UID 的错误消息,则可能意味着整个 VNC 进程树存在于任何 systemd-logind“会话”之外(即启动时未使用 PAM) VNC 服务器),因此不是引用计数的一部分,这会阻止 systemd-logind/run/user/<UID>在注销时删除目录。

(例如,如果您通过 SSH 连接到远程主机,则会创建用户运行时目录;然后您启动类似“vncserver.service”的内容,一切看起来都很好;但是一旦您与 SSH 断开连接,运行时目录就会被删除再次因为那是你的最后一次会议。)

(您可以在 中看到这一点journalctl,可能是间接的 – 当名为“UID <UID> 的用户管理器”的“systemd --user”实例启动/停止时,运行时目录会同时创建/删除。)

在这些情况下,使运行时目录“永久”的一种方法是设置 systemd-logind萦绕该用户的标志,使用loginctl enable-linger <USERNAME>.这将导致该用户的运行时目录(及其systemd --user实例)在启动时启动并保留到关闭为止。

或者,如果通过 systemd 启动 VNC,PAMName=则应使用其 .service 参数创建完整的 PAM 会话,该会话将向 systemd-logind 注册,并在 VNC .service 运行时创建运行时目录。


第二个相关原因是 dconf 被告知使用另一个用户的运行时目录。 “/run/user/<UID>”模式不是由 dconf 直接确定的 - 相反,整个路径取自XDG_RUNTIME_DIRPAM 设置的环境变量。

如果您使用诸如sudo -E以不同用户身份运行图形程序之类的东西,它们将继承您的所有环境 - 如果它是世界可读的,它们可能能够与您的 $HOME 一起使用,但它们将无法使用您的 $XDG_RUNTIME_DIR因为它只能由您访问(根据设计)。

解决方案是“不要这样做”,即不要让在其他 UID 下运行的程序继承您的 $XDG_RUNTIME_DIR 和相关环境。特别是对于 dconf,如果需要,它将回退到用户的 ~/.cache/dconf(尽管这假设它也没有继承错误的 $HOME)。

答案2

su -l 用户名 -c "(export DISPLAY=:5; dbus-launch --exit-with-session; vncserver -geometry 1792x899 -深度 24 :5)"

命令“dbus-launch --exit-with-session”将 dbus 变量设置为特定于运行 vncserver 的用户,否则它可能会从其他地方获取它们或根本不设置它们。这些需要正确设置,否则您将得到黑屏或权限被拒绝。例如

DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/1003/bus

答案3

Debian 拉伸

在 12 小时的会话中,我的 xsession-errors 文件有时会被超过 50 万个主题行炸毁(我可以使用tail -f -n +1 .~/xsession-errors | nl- 临时缓解措施是运行来查看在终端窗口中发生的大屠杀chown -R 1000:1000 /run/user/1000/*,但是,仍然如此。 ..)。以下是我为阻止这些情况发生而采取的措施的总结:

首先,我清理了所有个人脚本、桌面文件和键盘快捷键片段以查找sugksu命令的出现,并将其替换为su -lgksu -l命令。另外,我用Xfce还有一些/usr/共享/应用程序/需要进行如此更改的桌面文件(主要是我创建/修改的文件)。

然后,由于我的用户桌面文件中至少有一个调用su 至 root可执行文件(在 Debian 中找到菜单包),我复制了/usr/bin/su 到 root/usr/local/bin/并将其重命名为“su-root-gksu-l”。然后,在该文件中,我替换了以下行:

gksu) gksu -u "$PRIV" "$COMMAND";;

gksu) gksu -l -u "$PRIV" "$COMMAND";;

接下来,我清理了所有个人脚本、桌面文件和键盘快捷键片段以使用上述内容su 至 root可执行文件并将对相同内容的任何引用更改为su-root-gksu-l。我做过找到一些桌面文件/usr/共享/应用程序/那个使用了su 至 root脚本,但没有对它们进行任何更改,因为我认为没有必要。我也擦掉了所有的图纳尔自定义操作。

最后,我创建了一个系统范围的别名(插入到等/bash.bashrc文件):function su() { if [[ $1 == "--" ]]; then command su "$@"; else command su -l "$@"; fi; }

仅供参考,还有关于此 shell 函数的附加讨论这里

相关内容