]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/core/selinux-setup.c
build-sys: use #if Y instead of #ifdef Y everywhere
[thirdparty/systemd.git] / src / core / selinux-setup.c
CommitLineData
c4dcdb9f
LP
1/***
2 This file is part of systemd.
3
4 Copyright 2010 Lennart Poettering
5
6 systemd is free software; you can redistribute it and/or modify it
5430f7f2
LP
7 under the terms of the GNU Lesser General Public License as published by
8 the Free Software Foundation; either version 2.1 of the License, or
c4dcdb9f
LP
9 (at your option) any later version.
10
11 systemd is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
5430f7f2 14 Lesser General Public License for more details.
c4dcdb9f 15
5430f7f2 16 You should have received a copy of the GNU Lesser General Public License
c4dcdb9f
LP
17 along with systemd; If not, see <http://www.gnu.org/licenses/>.
18***/
19
c4dcdb9f 20#include <errno.h>
07630cea
LP
21#include <stdio.h>
22#include <unistd.h>
c4dcdb9f 23
349cc4a5 24#if HAVE_SELINUX
c4dcdb9f
LP
25#include <selinux/selinux.h>
26#endif
27
07630cea 28#include "log.h"
c4dcdb9f 29#include "macro.h"
cf0fbc49 30#include "selinux-setup.h"
07630cea
LP
31#include "selinux-util.h"
32#include "string-util.h"
c4dcdb9f 33#include "util.h"
0b3325e7 34
349cc4a5 35#if HAVE_SELINUX
82613b14 36_printf_(2,3)
dbc655d5
LP
37static int null_log(int type, const char *fmt, ...) {
38 return 0;
39}
f8e9f2cc 40#endif
dbc655d5 41
8a188de9 42int mac_selinux_setup(bool *loaded_policy) {
c4dcdb9f 43
349cc4a5 44#if HAVE_SELINUX
4ab72d6f
WW
45 int enforce = 0;
46 usec_t before_load, after_load;
2ed96880 47 char *con;
4ab72d6f
WW
48 int r;
49 union selinux_callback cb;
68d3acac 50 bool initialized = false;
4ab72d6f
WW
51
52 assert(loaded_policy);
53
54 /* Turn off all of SELinux' own logging, we want to do that */
55 cb.func_log = null_log;
56 selinux_set_callback(SELINUX_CB_LOG, cb);
57
58 /* Don't load policy in the initrd if we don't appear to have
59 * it. For the real root, we check below if we've already
60 * loaded policy, and return gracefully.
61 */
62 if (in_initrd() && access(selinux_path(), F_OK) < 0)
63 return 0;
64
65 /* Already initialized by somebody else? */
66 r = getcon_raw(&con);
67 if (r == 0) {
4ab72d6f
WW
68 initialized = !streq(con, "kernel");
69 freecon(con);
4ab72d6f
WW
70 }
71
72 /* Make sure we have no fds open while loading the policy and
73 * transitioning */
74 log_close();
75
76 /* Now load the policy */
77 before_load = now(CLOCK_MONOTONIC);
78 r = selinux_init_load_policy(&enforce);
79 if (r == 0) {
710a6b50 80 _cleanup_(mac_selinux_freep) char *label = NULL;
4ab72d6f 81 char timespan[FORMAT_TIMESPAN_MAX];
4ab72d6f 82
6baa7db0 83 mac_selinux_retest();
4ab72d6f
WW
84
85 /* Transition to the new context */
cc56fafe 86 r = mac_selinux_get_create_label_from_exe(SYSTEMD_BINARY_PATH, &label);
710a6b50 87 if (r < 0 || !label) {
4ab72d6f
WW
88 log_open();
89 log_error("Failed to compute init label, ignoring.");
90 } else {
a1d2de07 91 r = setcon_raw(label);
4ab72d6f
WW
92
93 log_open();
94 if (r < 0)
95 log_error("Failed to transition into init label '%s', ignoring.", label);
4ab72d6f
WW
96 }
97
98 after_load = now(CLOCK_MONOTONIC);
99
100 log_info("Successfully loaded SELinux policy in %s.",
101 format_timespan(timespan, sizeof(timespan), after_load - before_load, 0));
102
103 *loaded_policy = true;
104
105 } else {
106 log_open();
107
108 if (enforce > 0) {
68d3acac 109 if (!initialized) {
cb6531be 110 log_emergency("Failed to load SELinux policy.");
68d3acac
WW
111 return -EIO;
112 }
113
114 log_warning("Failed to load new SELinux policy. Continuing with old policy.");
4ab72d6f
WW
115 } else
116 log_debug("Unable to load SELinux policy. Ignoring.");
117 }
c4dcdb9f
LP
118#endif
119
4ab72d6f 120 return 0;
c4dcdb9f 121}