Coverage Report

Created: 2025-11-16 06:36

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/systemd/src/shared/polkit-agent.c
Line
Count
Source
1
/* SPDX-License-Identifier: LGPL-2.1-or-later */
2
3
#include <poll.h>
4
#include <signal.h>
5
#include <unistd.h>
6
7
#include "bus-util.h"
8
#include "exec-util.h"
9
#include "fd-util.h"
10
#include "io-util.h"
11
#include "log.h"
12
#include "polkit-agent.h"
13
#include "process-util.h"
14
#include "stdio-util.h"
15
16
#if ENABLE_POLKIT
17
static pid_t agent_pid = 0;
18
19
int polkit_agent_open(void) {
20
        _cleanup_close_pair_ int pipe_fd[2] = EBADF_PAIR;
21
        char notify_fd[DECIMAL_STR_MAX(int) + 1];
22
        int r;
23
24
        if (agent_pid > 0)
25
                return 0;
26
27
        /* Clients that run as root don't need to activate/query polkit */
28
        if (geteuid() == 0)
29
                return 0;
30
31
        r = shall_fork_agent();
32
        if (r <= 0)
33
                return r;
34
35
        if (pipe2(pipe_fd, 0) < 0)
36
                return -errno;
37
38
        xsprintf(notify_fd, "%i", pipe_fd[1]);
39
40
        r = fork_agent("(polkit-agent)",
41
                       &pipe_fd[1],
42
                       1,
43
                       &agent_pid,
44
                       POLKIT_AGENT_BINARY_PATH,
45
                       "--notify-fd", notify_fd,
46
                       "--fallback");
47
        if (r < 0)
48
                return log_error_errno(r, "Failed to fork polkit agent: %m");
49
50
        /* Close the writing side, because that's the one for the agent */
51
        pipe_fd[1] = safe_close(pipe_fd[1]);
52
53
        /* Wait until the agent closes the fd */
54
        (void) fd_wait_for_event(pipe_fd[0], POLLHUP, USEC_INFINITY);
55
56
        return 1;
57
}
58
59
void polkit_agent_close(void) {
60
61
        if (agent_pid <= 0)
62
                return;
63
64
        /* Inform agent that we are done */
65
        sigterm_wait(TAKE_PID(agent_pid));
66
}
67
68
#else
69
70
0
int polkit_agent_open(void) {
71
0
        return 0;
72
0
}
73
74
0
void polkit_agent_close(void) {
75
0
}
76
77
#endif
78
79
0
int polkit_agent_open_if_enabled(BusTransport transport, bool ask_password) {
80
81
        /* Open the polkit agent as a child process if necessary */
82
83
0
        if (transport != BUS_TRANSPORT_LOCAL)
84
0
                return 0;
85
86
0
        if (!ask_password)
87
0
                return 0;
88
89
0
        return polkit_agent_open();
90
0
}