2 * Copyright (C) 2004 Daniel Walsh
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License as published by the
6 * Free Software Foundation version 2 of the License.
8 * This program is distributed in the hope that it will be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 * General Public License for more details.
13 * You should have received a copy of the GNU General Public License along
14 * with this program; if not, write to the Free Software Foundation, Inc.,
15 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
31 #include <selinux/selinux.h>
34 #include "udev_selinux.h"
36 static security_context_t prev_scontext = NULL;
38 static int is_selinux_running(struct udev *udev)
40 static int selinux_enabled = -1;
42 if (selinux_enabled == -1)
43 selinux_enabled = (is_selinux_enabled() > 0);
45 dbg(udev, "selinux=%i\n", selinux_enabled);
46 return selinux_enabled;
49 static char *get_media(struct udev *udev, const char *devname, int mode)
52 char procfile[PATH_MAX];
57 if (!(mode & S_IFBLK))
60 snprintf(procfile, PATH_MAX, "/proc/ide/%s/media", devname);
61 procfile[PATH_MAX-1] = '\0';
63 fp = fopen(procfile, "r");
67 if (fgets(mediabuf, sizeof(mediabuf), fp) == NULL)
70 size = strlen(mediabuf);
72 if (isspace(mediabuf[size])) {
73 mediabuf[size] = '\0';
79 media = strdup(mediabuf);
80 info(udev, "selinux_get_media(%s)='%s'\n", devname, media);
88 void selinux_setfilecon(struct udev *udev, const char *file, const char *devname, unsigned int mode)
90 if (is_selinux_running(udev)) {
91 security_context_t scontext = NULL;
96 media = get_media(udev, devname, mode);
98 ret = matchmediacon(media, &scontext);
104 if (matchpathcon(file, mode, &scontext) < 0) {
105 err(udev, "matchpathcon(%s) failed\n", file);
109 if (lsetfilecon(file, scontext) < 0)
110 err(udev, "setfilecon %s failed: %s\n", file, strerror(errno));
116 void selinux_setfscreatecon(struct udev *udev, const char *file, const char *devname, unsigned int mode)
118 if (is_selinux_running(udev)) {
119 security_context_t scontext = NULL;
124 media = get_media(udev, devname, mode);
126 ret = matchmediacon(media, &scontext);
132 if (matchpathcon(file, mode, &scontext) < 0) {
133 err(udev, "matchpathcon(%s) failed\n", file);
137 if (setfscreatecon(scontext) < 0)
138 err(udev, "setfscreatecon %s failed: %s\n", file, strerror(errno));
144 void selinux_resetfscreatecon(struct udev *udev)
146 if (is_selinux_running(udev)) {
147 if (setfscreatecon(prev_scontext) < 0)
148 err(udev, "setfscreatecon failed: %s\n", strerror(errno));
152 void selinux_init(struct udev *udev)
155 * record the present security context, for file-creation
156 * restoration creation purposes.
158 if (is_selinux_running(udev)) {
159 if (!udev_get_dev_path(udev)[0])
160 err(udev, "selinux_init: udev_root not set\n");
161 matchpathcon_init_prefix(NULL, udev_get_dev_path(udev));
162 if (getfscreatecon(&prev_scontext) < 0) {
163 err(udev, "getfscreatecon failed\n");
164 prev_scontext = NULL;
169 void selinux_exit(struct udev *udev)
171 if (is_selinux_running(udev) && prev_scontext) {
172 freecon(prev_scontext);
173 prev_scontext = NULL;