我想让我的用户/etc
从我的图形 C 应用程序中编辑配置文件。一种方法是:
fprintf( fopen("/tmp/tmpfile", "w+") , "content\n"); // Write to a tmpfile
system("pkexec mv /tmp/tmpfile /etc/myapp.conf"); // Use pkexec to move that tmpfile to our file
但是,我想实现一个 polkit客户(因为我要做的比单次写入稍微复杂一些)。这将导致桌面的 polkit 代理弹出,要求以管理员(root)身份进行身份验证。一旦通过身份验证,它将执行该操作,然后返回到非特权使用。
我已经实施了客户端参考API并累加/usr/share/polkit-1/actions
直到该函数(此处为简化版本)返回的点TRUE
;
int IsAuthorized(const char* action) {
PolkutAuthorizationResult* r = polkit_authority_check_authorization_sync(
polkit_authority_get_sync(NULL, &error),
polkit_unix_process_new_for_owner( getpid(), 0, getuid() ),
"org.myapp.editconfig",
NULL, /* details */
POLKIT_CHECK_AUTHORIZATION_FLAGS_ALLOW_USER_INTERACTION,
NULL, /* cancellable */
&error
);
return polkit_authorization_result_get_is_authorized( r );
}
这授权此操作:
<action id="org.myapp.editconfig">
<description>Edit myapp config</description>
<message>Authentication is required to edit this system-wide config file</message>
<defaults>
<allow_any>auth_admin</allow_any>
<allow_inactive>auth_admin</allow_inactive>
<allow_active>auth_admin</allow_active>
</defaults>
</action>
但我的问题是:现在怎么办?我不确定“被授权”对我有什么作用。如果我尝试打开root:root
文件进行写入,我的权限会被拒绝。如果我创建一个新文件,则它由用户拥有,而不是 root。
调查来源执行程序我看到它改变了它自己的 uid/gid 。身份验证是否简单地给出CAP_SETUID
和CAP_SETGID
到过程?
假设这是真的,我尝试使用setreuid()
和setregid()
:
int uid = getuid(); int euid = geteuid();
int gid = getgid(); int egid = getegid();
setregid(0,0); // Switch to root
setreuid(0,0);
fprintf( fopen("/etc/myapp.conf", "w+"), "content\n"); // Write the file
setregid(gid,egid); // Switch back
setreuid(uid,euid);
我发现这setreuid(0,0)
失败了,我从来没有像这样切换用户执行程序做。注意我跳过了一些事情pkexec
,例如设置环境和set_close_exec
所有文件描述符。
我肯定错过了什么。
答案1
polkit_authority_check_authorization_sync
只需检查调用者是否有权根据 polkit 规则执行操作即可。这通常意味着已经以 root 身份运行的应用程序/守护程序想要检查调用者是否确实被允许执行某些操作,然后代表调用者执行该操作。 Polkit 本身不授予任何额外的权限,您的应用程序已经需要能够执行该操作。pkexec <command>
有效,因为pkexec
是setuid 二进制文件因此该进程以 root 身份运行,并且仅检查您是否有权运行您尝试运行的命令。