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 281 : void polkit_agent_close(void) { 66 : 67 281 : if (agent_pid <= 0) 68 281 : 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