]>
Commit | Line | Data |
---|---|---|
fbda4a34 KS |
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) | |
4d772639 | 108 | dbg("setfilecon %s failed with error '%s'", file, strerror(errno)); |
fbda4a34 KS |
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) | |
4d772639 | 134 | dbg("setfscreatecon %s failed with error '%s'", file, strerror(errno)); |
fbda4a34 KS |
135 | |
136 | freecon(scontext); | |
137 | } | |
138 | } | |
139 | ||
4d772639 GKH |
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 | ||
fbda4a34 KS |
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()) { | |
4d772639 | 155 | if (getfscreatecon(&prev_scontext) < 0) { |
fbda4a34 | 156 | dbg("getfscreatecon failed\n"); |
4d772639 GKH |
157 | prev_scontext = NULL; |
158 | } | |
fbda4a34 KS |
159 | } |
160 | } | |
161 | ||
4d772639 | 162 | void selinux_exit(void) |
fbda4a34 | 163 | { |
4d772639 GKH |
164 | if (is_selinux_running() && prev_scontext) { |
165 | freecon(prev_scontext); | |
166 | prev_scontext = NULL; | |
fbda4a34 KS |
167 | } |
168 | } |