我想让我的用户从我的图形C应用程序中编辑/etc中的配置文件。一种方法是:
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 客户端 (因为我要做的事情比一次写要复杂一些),.This将导致桌面的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文件,则会被拒绝权限。如果我创建了一个新文件,那么它是用户拥有的,而不是根文件。
查看pkexec的来源,我发现它改变了自己的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那样切换用户。注意,我跳过了pkexec所做的一些事情,比如设置环境,以及为所有文件描述符设置set_close_exec。
我一定是漏掉了什么。
发布于 2021-02-05 15:20:02
polkit_authority_check_authorization_sync只需检查调用者是否有权根据polkit规则执行操作,仅此而已。这通常意味着已经作为root运行的应用程序/守护进程希望检查调用方是否实际被允许执行某些操作,然后代表调用方执行它。Polkit本身不授予任何额外的权限,您的应用程序已经需要能够执行该操作。pkexec <command>之所以工作,是因为pkexec是一个setuid二进制,因此进程以根用户的身份运行,并且只检查您是否被授权运行您试图运行的命令。
https://unix.stackexchange.com/questions/632830
复制相似问题