]> git.ipfire.org Git - thirdparty/systemd.git/blob - udev_selinux.c
add ID_BUS to *_id programs
[thirdparty/systemd.git] / udev_selinux.c
1 /*
2 * udev_selinux.h
3 *
4 * Copyright (C) 2004 Daniel Walsh
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation version 2 of the License.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 675 Mass Ave, Cambridge, MA 02139, USA.
18 *
19 */
20
21 #include <stdlib.h>
22 #include <stdio.h>
23 #include <stddef.h>
24 #include <unistd.h>
25 #include <string.h>
26 #include <fcntl.h>
27 #include <ctype.h>
28 #include <limits.h>
29 #include <libgen.h>
30 #include <errno.h>
31 #include <selinux/selinux.h>
32
33 #include "udev_selinux.h"
34 #include "logging.h"
35
36 static security_context_t prev_scontext = NULL;
37
38 static int is_selinux_running(void)
39 {
40 static int selinux_enabled = -1;
41
42 if (selinux_enabled == -1)
43 selinux_enabled = (is_selinux_enabled() > 0);
44
45 dbg("selinux=%i", selinux_enabled);
46 return selinux_enabled;
47 }
48
49 static char *get_media(const char *devname, int mode)
50 {
51 FILE *fp;
52 char procfile[PATH_MAX];
53 char mediabuf[256];
54 int size;
55 char *media = NULL;
56
57 if (!(mode && S_IFBLK))
58 return NULL;
59
60 snprintf(procfile, PATH_MAX, "/proc/ide/%s/media", devname);
61 procfile[PATH_MAX-1] = '\0';
62
63 fp = fopen(procfile, "r");
64 if (!fp)
65 goto out;
66
67 if (fgets(mediabuf, sizeof(mediabuf), fp) == NULL)
68 goto close_out;
69
70 size = strlen(mediabuf);
71 while (size-- > 0) {
72 if (isspace(mediabuf[size])) {
73 mediabuf[size] = '\0';
74 } else {
75 break;
76 }
77 }
78
79 media = strdup(mediabuf);
80 info("selinux_get_media(%s)='%s'\n", devname, media);
81
82 close_out:
83 fclose(fp);
84 out:
85 return media;
86 }
87
88 void selinux_setfilecon(const char *file, const char *devname, unsigned int mode)
89 {
90 if (is_selinux_running()) {
91 security_context_t scontext = NULL;
92 char *media;
93 int ret = -1;
94
95 media = get_media(devname, mode);
96 if (media) {
97 ret = matchmediacon(media, &scontext);
98 free(media);
99 }
100
101 if (ret < 0)
102 if (matchpathcon(file, mode, &scontext) < 0) {
103 dbg("matchpathcon(%s) failed\n", file);
104 return;
105 }
106
107 if (setfilecon(file, scontext) < 0)
108 dbg("setfilecon %s failed with error '%s'", file, strerror(errno));
109
110 freecon(scontext);
111 }
112 }
113
114 void selinux_setfscreatecon(const char *file, const char *devname, unsigned int mode)
115 {
116 if (is_selinux_running()) {
117 security_context_t scontext = NULL;
118 char *media;
119 int ret = -1;
120
121 media = get_media(devname, mode);
122 if (media) {
123 ret = matchmediacon(media, &scontext);
124 free(media);
125 }
126
127 if (ret < 0)
128 if (matchpathcon(file, mode, &scontext) < 0) {
129 dbg("matchpathcon(%s) failed\n", file);
130 return;
131 }
132
133 if (setfscreatecon(scontext) < 0)
134 dbg("setfscreatecon %s failed with error '%s'", file, strerror(errno));
135
136 freecon(scontext);
137 }
138 }
139
140 void selinux_resetfscreatecon(void)
141 {
142 if (is_selinux_running()) {
143 if (setfscreatecon(prev_scontext) < 0)
144 dbg("setfscreatecon %s failed with error '%s'", file, strerror(errno));
145 }
146 }
147
148 void selinux_init(void)
149 {
150 /*
151 * record the present security context, for file-creation
152 * restoration creation purposes.
153 */
154 if (is_selinux_running()) {
155 if (getfscreatecon(&prev_scontext) < 0) {
156 dbg("getfscreatecon failed\n");
157 prev_scontext = NULL;
158 }
159 }
160 }
161
162 void selinux_exit(void)
163 {
164 if (is_selinux_running() && prev_scontext) {
165 freecon(prev_scontext);
166 prev_scontext = NULL;
167 }
168 }