usbmodeswitch: Updated to v.1.2.6 from shibby's branch.
[tomato.git] / release / src / router / udev / udev_selinux.c
blob1ad6e8ad122f51985601cbfc80ab0ada61120cce
1 /*
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.
7 *
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.
19 #include <stdlib.h>
20 #include <stdio.h>
21 #include <stddef.h>
22 #include <unistd.h>
23 #include <string.h>
24 #include <fcntl.h>
25 #include <ctype.h>
26 #include <limits.h>
27 #include <libgen.h>
28 #include <errno.h>
29 #include <selinux/selinux.h>
31 #include "udev.h"
32 #include "udev_selinux.h"
34 static security_context_t prev_scontext = NULL;
36 static int is_selinux_running(void)
38 static int selinux_enabled = -1;
40 if (selinux_enabled == -1)
41 selinux_enabled = (is_selinux_enabled() > 0);
43 dbg("selinux=%i", selinux_enabled);
44 return selinux_enabled;
47 static char *get_media(const char *devname, int mode)
49 FILE *fp;
50 char procfile[PATH_MAX];
51 char mediabuf[256];
52 int size;
53 char *media = NULL;
55 if (!(mode & S_IFBLK))
56 return NULL;
58 snprintf(procfile, PATH_MAX, "/proc/ide/%s/media", devname);
59 procfile[PATH_MAX-1] = '\0';
61 fp = fopen(procfile, "r");
62 if (!fp)
63 goto out;
65 if (fgets(mediabuf, sizeof(mediabuf), fp) == NULL)
66 goto close_out;
68 size = strlen(mediabuf);
69 while (size-- > 0) {
70 if (isspace(mediabuf[size])) {
71 mediabuf[size] = '\0';
72 } else {
73 break;
77 media = strdup(mediabuf);
78 info("selinux_get_media(%s)='%s'", devname, media);
80 close_out:
81 fclose(fp);
82 out:
83 return media;
86 void selinux_setfilecon(const char *file, const char *devname, unsigned int mode)
88 if (is_selinux_running()) {
89 security_context_t scontext = NULL;
90 char *media;
91 int ret = -1;
93 if (devname) {
94 media = get_media(devname, mode);
95 if (media) {
96 ret = matchmediacon(media, &scontext);
97 free(media);
101 if (ret < 0)
102 if (matchpathcon(file, mode, &scontext) < 0) {
103 err("matchpathcon(%s) failed", file);
104 return;
107 if (lsetfilecon(file, scontext) < 0)
108 err("setfilecon %s failed: %s", file, strerror(errno));
110 freecon(scontext);
114 void selinux_setfscreatecon(const char *file, const char *devname, unsigned int mode)
116 if (is_selinux_running()) {
117 security_context_t scontext = NULL;
118 char *media;
119 int ret = -1;
121 if (devname) {
122 media = get_media(devname, mode);
123 if (media) {
124 ret = matchmediacon(media, &scontext);
125 free(media);
129 if (ret < 0)
130 if (matchpathcon(file, mode, &scontext) < 0) {
131 err("matchpathcon(%s) failed", file);
132 return;
135 if (setfscreatecon(scontext) < 0)
136 err("setfscreatecon %s failed: %s", file, strerror(errno));
138 freecon(scontext);
142 void selinux_resetfscreatecon(void)
144 if (is_selinux_running()) {
145 if (setfscreatecon(prev_scontext) < 0)
146 err("setfscreatecon failed: %s", strerror(errno));
150 void selinux_init(void)
153 * record the present security context, for file-creation
154 * restoration creation purposes.
156 if (is_selinux_running()) {
157 if (!udev_root[0])
158 err("selinux_init: udev_root not set");
159 matchpathcon_init_prefix(NULL, udev_root);
160 if (getfscreatecon(&prev_scontext) < 0) {
161 err("getfscreatecon failed");
162 prev_scontext = NULL;
167 void selinux_exit(void)
169 if (is_selinux_running() && prev_scontext) {
170 freecon(prev_scontext);
171 prev_scontext = NULL;