chiark / gitweb /
remove outdated documentation
[elogind.git] / udev_selinux.c
1 /*
2  * Copyright (C) 2004 Daniel Walsh
3  *
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.
12  * 
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.
16  *
17  */
18
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>
30
31 #include "udev.h"
32 #include "udev_selinux.h"
33
34 static security_context_t prev_scontext = NULL;
35
36 static int is_selinux_running(void)
37 {
38         static int selinux_enabled = -1;
39
40         if (selinux_enabled == -1) 
41                 selinux_enabled = (is_selinux_enabled() > 0);
42
43         dbg("selinux=%i", selinux_enabled);
44         return selinux_enabled;
45 }
46
47 static char *get_media(const char *devname, int mode)
48 {
49         FILE *fp;
50         char procfile[PATH_MAX];
51         char mediabuf[256];
52         int size;
53         char *media = NULL;
54
55         if (!(mode & S_IFBLK))
56                 return NULL;
57
58         snprintf(procfile, PATH_MAX, "/proc/ide/%s/media", devname);
59         procfile[PATH_MAX-1] = '\0';
60
61         fp = fopen(procfile, "r");
62         if (!fp)
63                 goto out;
64
65         if (fgets(mediabuf, sizeof(mediabuf), fp) == NULL)
66                 goto close_out;
67
68         size = strlen(mediabuf);
69         while (size-- > 0) {
70                 if (isspace(mediabuf[size])) {
71                         mediabuf[size] = '\0';
72                 } else {
73                         break;
74                 }
75         }
76
77         media = strdup(mediabuf);
78         info("selinux_get_media(%s)='%s'\n", devname, media);
79
80 close_out:
81         fclose(fp);
82 out:
83         return media;
84 }
85
86 void selinux_setfilecon(const char *file, const char *devname, unsigned int mode)
87 {
88         if (is_selinux_running()) {
89                 security_context_t scontext = NULL;
90                 char *media;
91                 int ret = -1;
92
93                 if(devname)
94                 {
95                         media = get_media(devname, mode);
96                         if (media) {
97                                 ret = matchmediacon(media, &scontext);
98                                 free(media);
99                         }
100                 }
101
102                 if (ret < 0)
103                         if (matchpathcon(file, mode, &scontext) < 0) {
104                                 err("matchpathcon(%s) failed\n", file);
105                                 return;
106                         } 
107
108                 if (lsetfilecon(file, scontext) < 0)
109                         err("setfilecon %s failed: %s", file, strerror(errno));
110
111                 freecon(scontext);
112         }
113 }
114
115 void selinux_setfscreatecon(const char *file, const char *devname, unsigned int mode)
116 {
117         if (is_selinux_running()) {
118                 security_context_t scontext = NULL;
119                 char *media;
120                 int ret = -1;
121
122                 media = get_media(devname, mode);
123                 if (media) {
124                         ret = matchmediacon(media, &scontext);
125                         free(media);
126                 }
127
128                 if (ret < 0)
129                         if (matchpathcon(file, mode, &scontext) < 0) {
130                                 err("matchpathcon(%s) failed\n", file);
131                                 return;
132                         }
133
134                 if (setfscreatecon(scontext) < 0)
135                         err("setfscreatecon %s failed: %s", file, strerror(errno));
136
137                 freecon(scontext);
138         }
139 }
140
141 void selinux_resetfscreatecon(void)
142 {
143         if (is_selinux_running()) {
144                 if (setfscreatecon(prev_scontext) < 0)
145                         err("setfscreatecon failed: %s", strerror(errno));
146         }
147 }
148
149 void selinux_init(void)
150 {
151         /*
152          * record the present security context, for file-creation
153          * restoration creation purposes.
154          */
155         if (is_selinux_running()) {
156                 matchpathcon_init_prefix(NULL, udev_root);
157                 if (getfscreatecon(&prev_scontext) < 0) {
158                         err("getfscreatecon failed\n");
159                         prev_scontext = NULL;
160                 }
161         }
162 }
163
164 void selinux_exit(void)
165 {
166         if (is_selinux_running() && prev_scontext) {
167                 freecon(prev_scontext);
168                 prev_scontext = NULL;
169         }
170 }