]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/shared/spawn-polkit-agent.c
Add a snprinf wrapper which checks that the buffer was big enough
[thirdparty/systemd.git] / src / shared / spawn-polkit-agent.c
CommitLineData
6bb92a16
LP
1/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
3/***
4 This file is part of systemd.
5
6 Copyright 2011 Lennart Poettering
7
8 systemd is free software; you can redistribute it and/or modify it
5430f7f2
LP
9 under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 2.1 of the License, or
6bb92a16
LP
11 (at your option) any later version.
12
13 systemd is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
5430f7f2 16 Lesser General Public License for more details.
6bb92a16 17
5430f7f2 18 You should have received a copy of the GNU Lesser General Public License
6bb92a16
LP
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
20***/
21
22#include <sys/types.h>
23#include <stdlib.h>
24#include <unistd.h>
25#include <string.h>
26#include <sys/prctl.h>
27#include <signal.h>
28#include <fcntl.h>
9bdc770c
LP
29#include <errno.h>
30#include <sys/poll.h>
6bb92a16
LP
31
32#include "log.h"
33#include "util.h"
34#include "spawn-polkit-agent.h"
35
46ba8aae 36#ifdef ENABLE_POLKIT
6bb92a16
LP
37static pid_t agent_pid = 0;
38
39int polkit_agent_open(void) {
40 int r;
9bdc770c 41 int pipe_fd[2];
5ffa8c81 42 char notify_fd[DECIMAL_STR_MAX(int) + 1];
6bb92a16
LP
43
44 if (agent_pid > 0)
45 return 0;
46
47 /* We check STDIN here, not STDOUT, since this is about input,
48 * not output */
49 if (!isatty(STDIN_FILENO))
50 return 0;
51
9bdc770c
LP
52 if (pipe2(pipe_fd, 0) < 0)
53 return -errno;
54
5ffa8c81 55 xsprintf(notify_fd, "%i", pipe_fd[1]);
9bdc770c
LP
56
57 r = fork_agent(&agent_pid,
58 &pipe_fd[1], 1,
59 POLKIT_AGENT_BINARY_PATH,
8aec53fb 60 POLKIT_AGENT_BINARY_PATH, "--notify-fd", notify_fd, "--fallback", NULL);
9bdc770c
LP
61
62 /* Close the writing side, because that's the one for the agent */
03e334a1 63 safe_close(pipe_fd[1]);
9bdc770c 64
6bb92a16 65 if (r < 0)
da927ba9 66 log_error_errno(r, "Failed to fork TTY ask password agent: %m");
9bdc770c
LP
67 else
68 /* Wait until the agent closes the fd */
3a43da28 69 fd_wait_for_event(pipe_fd[0], POLLHUP, USEC_INFINITY);
9bdc770c 70
03e334a1 71 safe_close(pipe_fd[0]);
6bb92a16
LP
72
73 return r;
74}
75
76void polkit_agent_close(void) {
77
78 if (agent_pid <= 0)
79 return;
80
81 /* Inform agent that we are done */
82 kill(agent_pid, SIGTERM);
83 kill(agent_pid, SIGCONT);
c73d180d 84 (void) wait_for_terminate(agent_pid, NULL);
6bb92a16
LP
85 agent_pid = 0;
86}
46ba8aae
LP
87
88#else
89
90int polkit_agent_open(void) {
91 return 0;
92}
93
94void polkit_agent_close(void) {
95}
96
97#endif