]>
Commit | Line | Data |
---|---|---|
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 |
20 | static pid_t agent_pid = 0; |
21 | ||
22 | int 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 | ||
65 | void 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 | ||
76 | int polkit_agent_open(void) { | |
77 | return 0; | |
78 | } | |
79 | ||
80 | void polkit_agent_close(void) { | |
81 | } | |
82 | ||
83 | #endif | |
385d581b LP |
84 | |
85 | int 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 | } |