Branch data Line data Source code
1 : : /* SPDX-License-Identifier: LGPL-2.1+ */ 2 : : 3 : : #include <errno.h> 4 : : #include <poll.h> 5 : : #include <signal.h> 6 : : #include <stdlib.h> 7 : : #include <unistd.h> 8 : : 9 : : #include "fd-util.h" 10 : : #include "io-util.h" 11 : : #include "log.h" 12 : : #include "macro.h" 13 : : #include "process-util.h" 14 : : #include "spawn-polkit-agent.h" 15 : : #include "stdio-util.h" 16 : : #include "time-util.h" 17 : : #include "util.h" 18 : : 19 : : #if ENABLE_POLKIT 20 : : static pid_t agent_pid = 0; 21 : : 22 : 0 : int polkit_agent_open(void) { 23 : : char notify_fd[DECIMAL_STR_MAX(int) + 1]; 24 : : int pipe_fd[2], r; 25 : : 26 [ # # ]: 0 : if (agent_pid > 0) 27 : 0 : return 0; 28 : : 29 : : /* Clients that run as root don't need to activate/query polkit */ 30 [ # # ]: 0 : if (geteuid() == 0) 31 : 0 : return 0; 32 : : 33 : : /* We check STDIN here, not STDOUT, since this is about input, not output */ 34 [ # # ]: 0 : if (!isatty(STDIN_FILENO)) 35 : 0 : return 0; 36 : : 37 [ # # ]: 0 : if (!is_main_thread()) 38 : 0 : return -EPERM; 39 : : 40 [ # # ]: 0 : if (pipe2(pipe_fd, 0) < 0) 41 : 0 : return -errno; 42 : : 43 [ # # ]: 0 : xsprintf(notify_fd, "%i", pipe_fd[1]); 44 : : 45 : 0 : r = fork_agent("(polkit-agent)", 46 : : &pipe_fd[1], 1, 47 : : &agent_pid, 48 : : POLKIT_AGENT_BINARY_PATH, 49 : : POLKIT_AGENT_BINARY_PATH, "--notify-fd", notify_fd, "--fallback", NULL); 50 : : 51 : : /* Close the writing side, because that's the one for the agent */ 52 : 0 : safe_close(pipe_fd[1]); 53 : : 54 [ # # ]: 0 : if (r < 0) 55 [ # # ]: 0 : log_error_errno(r, "Failed to fork TTY ask password agent: %m"); 56 : : else 57 : : /* Wait until the agent closes the fd */ 58 : 0 : fd_wait_for_event(pipe_fd[0], POLLHUP, USEC_INFINITY); 59 : : 60 : 0 : safe_close(pipe_fd[0]); 61 : : 62 : 0 : return r; 63 : : } 64 : : 65 : 1124 : void polkit_agent_close(void) { 66 : : 67 [ + - ]: 1124 : if (agent_pid <= 0) 68 : 1124 : return; 69 : : 70 : : /* Inform agent that we are done */ 71 : 0 : (void) kill_and_sigcont(agent_pid, SIGTERM); 72 : 0 : (void) wait_for_terminate(agent_pid, NULL); 73 : 0 : agent_pid = 0; 74 : : } 75 : : 76 : : #else 77 : : 78 : : int polkit_agent_open(void) { 79 : : return 0; 80 : : } 81 : : 82 : : void polkit_agent_close(void) { 83 : : } 84 : : 85 : : #endif