]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/shared/spawn-polkit-agent.c
Merge pull request #32664 from DaanDeMeyer/no-build
[thirdparty/systemd.git] / src / shared / spawn-polkit-agent.c
CommitLineData
db9ecf05 1/* SPDX-License-Identifier: LGPL-2.1-or-later */
6bb92a16 2
9bdc770c 3#include <errno.h>
0a6f50c0 4#include <poll.h>
cf0fbc49
TA
5#include <signal.h>
6#include <stdlib.h>
7#include <unistd.h>
6bb92a16 8
3e24e8cd 9#include "exec-util.h"
c004493c
LP
10#include "fd-util.h"
11#include "io-util.h"
6bb92a16 12#include "log.h"
a8fbdf54 13#include "macro.h"
0b452006 14#include "process-util.h"
6bb92a16 15#include "spawn-polkit-agent.h"
15a5e950 16#include "stdio-util.h"
a8fbdf54 17#include "time-util.h"
6bb92a16 18
349cc4a5 19#if ENABLE_POLKIT
6bb92a16
LP
20static pid_t agent_pid = 0;
21
22int polkit_agent_open(void) {
5ffa8c81 23 char notify_fd[DECIMAL_STR_MAX(int) + 1];
78752f2e 24 int pipe_fd[2], r;
6bb92a16
LP
25
26 if (agent_pid > 0)
27 return 0;
28
89d03482
MP
29 /* Clients that run as root don't need to activate/query polkit */
30 if (geteuid() == 0)
31 return 0;
32
78752f2e 33 /* We check STDIN here, not STDOUT, since this is about input, not output */
6bb92a16
LP
34 if (!isatty(STDIN_FILENO))
35 return 0;
36
85afeae8
LP
37 if (!is_main_thread())
38 return -EPERM;
39
9bdc770c
LP
40 if (pipe2(pipe_fd, 0) < 0)
41 return -errno;
42
5ffa8c81 43 xsprintf(notify_fd, "%i", pipe_fd[1]);
9bdc770c 44
78752f2e 45 r = fork_agent("(polkit-agent)",
9bdc770c 46 &pipe_fd[1], 1,
78752f2e 47 &agent_pid,
9bdc770c 48 POLKIT_AGENT_BINARY_PATH,
8aec53fb 49 POLKIT_AGENT_BINARY_PATH, "--notify-fd", notify_fd, "--fallback", NULL);
9bdc770c
LP
50
51 /* Close the writing side, because that's the one for the agent */
03e334a1 52 safe_close(pipe_fd[1]);
9bdc770c 53
6bb92a16 54 if (r < 0)
da927ba9 55 log_error_errno(r, "Failed to fork TTY ask password agent: %m");
9bdc770c
LP
56 else
57 /* Wait until the agent closes the fd */
a30c9e71 58 (void) fd_wait_for_event(pipe_fd[0], POLLHUP, USEC_INFINITY);
9bdc770c 59
03e334a1 60 safe_close(pipe_fd[0]);
6bb92a16
LP
61
62 return r;
63}
64
65void polkit_agent_close(void) {
66
67 if (agent_pid <= 0)
68 return;
69
70 /* Inform agent that we are done */
8f03de53 71 sigterm_wait(TAKE_PID(agent_pid));
6bb92a16 72}
46ba8aae
LP
73
74#else
75
76int polkit_agent_open(void) {
77 return 0;
78}
79
80void polkit_agent_close(void) {
81}
82
83#endif
385d581b
LP
84
85int polkit_agent_open_if_enabled(BusTransport transport, bool ask_password) {
86
87 /* Open the polkit agent as a child process if necessary */
88
89 if (transport != BUS_TRANSPORT_LOCAL)
90 return 0;
91
92 if (!ask_password)
93 return 0;
94
95 return polkit_agent_open();
96}