chiark / gitweb /
usb_id: use libudev
[elogind.git] / udev / udev_selinux.c
index 2e76a7431f34da863c9c67aea72ffd44f2f9bba0..499f53c9169ca55ef204b745d0d85389dcedd78f 100644 (file)
 /*
- * Copyright (C) 2004 Daniel Walsh
+ * libudev - interface to udev device information
  *
- *     This program is free software; you can redistribute it and/or modify it
- *     under the terms of the GNU General Public License as published by the
- *     Free Software Foundation version 2 of the License.
- * 
- *     This program is distributed in the hope that it will be useful, but
- *     WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *     General Public License for more details.
- * 
- *     You should have received a copy of the GNU General Public License along
- *     with this program; if not, write to the Free Software Foundation, Inc.,
- *     51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ * Copyright (C) 2008 Kay Sievers <kay.sievers@vrfy.org>
  *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
-#include "config.h"
-
-#include <stdlib.h>
 #include <stdio.h>
+#include <stdlib.h>
 #include <stddef.h>
+#include <stdarg.h>
 #include <unistd.h>
-#include <string.h>
-#include <fcntl.h>
-#include <ctype.h>
-#include <limits.h>
-#include <errno.h>
-#include <sys/stat.h>
-#include <selinux/selinux.h>
 
 #include "udev.h"
-#include "udev_selinux.h"
-
-static security_context_t prev_scontext = NULL;
-
-static int is_selinux_running(struct udev *udev)
-{
-       static int selinux_enabled = -1;
 
-       if (selinux_enabled == -1) 
-               selinux_enabled = (is_selinux_enabled() > 0);
+#ifndef USE_SELINUX
+void selinux_init(struct udev *udev) {}
+void selinux_exit(struct udev *udev) {}
+void udev_selinux_lsetfilecon(struct udev *udev, const char *file, unsigned int mode) {}
+void udev_selinux_setfscreatecon(struct udev *udev, const char *file, unsigned int mode) {}
+void udev_selinux_resetfscreatecon(struct udev *udev) {}
+#else
+#include <selinux/selinux.h>
 
-       dbg(udev, "selinux=%i\n", selinux_enabled);
-       return selinux_enabled;
-}
+static int selinux_enabled;
+security_context_t selinux_prev_scontext;
 
-static char *get_media(struct udev *udev, const char *devname, int mode)
+void selinux_init(struct udev *udev)
 {
-       FILE *fp;
-       char procfile[PATH_MAX];
-       char mediabuf[256];
-       int size;
-       char *media = NULL;
-
-       if (!(mode & S_IFBLK))
-               return NULL;
-
-       snprintf(procfile, PATH_MAX, "/proc/ide/%s/media", devname);
-       procfile[PATH_MAX-1] = '\0';
-
-       fp = fopen(procfile, "r");
-       if (!fp)
-               goto out;
-
-       if (fgets(mediabuf, sizeof(mediabuf), fp) == NULL)
-               goto close_out;
-
-       size = strlen(mediabuf);
-       while (size-- > 0) {
-               if (isspace(mediabuf[size])) {
-                       mediabuf[size] = '\0';
-               } else {
-                       break;
-               }
+       /* record the present security context */
+       selinux_enabled = (is_selinux_enabled() > 0);
+       info(udev, "selinux=%i\n", selinux_enabled);
+       if (!selinux_enabled)
+               return;
+       matchpathcon_init_prefix(NULL, udev_get_dev_path(udev));
+       if (getfscreatecon(&selinux_prev_scontext) < 0) {
+               err(udev, "getfscreatecon failed\n");
+               selinux_prev_scontext = NULL;
        }
-
-       media = strdup(mediabuf);
-       info(udev, "selinux_get_media(%s)='%s'\n", devname, media);
-
-close_out:
-       fclose(fp);
-out:
-       return media;
 }
 
-void selinux_setfilecon(struct udev *udev, const char *file, const char *devname, unsigned int mode)
+void selinux_exit(struct udev *udev)
 {
-       if (is_selinux_running(udev)) {
-               security_context_t scontext = NULL;
-               char *media;
-               int ret = -1;
-
-               if (devname) {
-                       media = get_media(udev, devname, mode);
-                       if (media) {
-                               ret = matchmediacon(media, &scontext);
-                               free(media);
-                       }
-               }
-
-               if (ret < 0)
-                       if (matchpathcon(file, mode, &scontext) < 0) {
-                               err(udev, "matchpathcon(%s) failed\n", file);
-                               return;
-                       } 
-
-               if (lsetfilecon(file, scontext) < 0)
-                       err(udev, "setfilecon %s failed: %s\n", file, strerror(errno));
-
-               freecon(scontext);
-       }
+       if (!selinux_enabled)
+               return;
+       freecon(selinux_prev_scontext);
+       selinux_prev_scontext = NULL;
 }
 
-void selinux_setfscreatecon(struct udev *udev, const char *file, const char *devname, unsigned int mode)
+void udev_selinux_lsetfilecon(struct udev *udev, const char *file, unsigned int mode)
 {
-       if (is_selinux_running(udev)) {
-               security_context_t scontext = NULL;
-               char *media;
-               int ret = -1;
-
-               if (devname) {
-                       media = get_media(udev, devname, mode);
-                       if (media) {
-                               ret = matchmediacon(media, &scontext);
-                               free(media);
-                       }
-               }
-
-               if (ret < 0)
-                       if (matchpathcon(file, mode, &scontext) < 0) {
-                               err(udev, "matchpathcon(%s) failed\n", file);
-                               return;
-                       }
-
-               if (setfscreatecon(scontext) < 0)
-                       err(udev, "setfscreatecon %s failed: %s\n", file, strerror(errno));
-
-               freecon(scontext);
-       }
+       security_context_t scontext = NULL;
+
+       if (!selinux_enabled)
+               return;
+       if (matchpathcon(file, mode, &scontext) < 0) {
+               err(udev, "matchpathcon(%s) failed\n", file);
+               return;
+       } 
+       if (lsetfilecon(file, scontext) < 0)
+               err(udev, "setfilecon %s failed: %m\n", file);
+       freecon(scontext);
 }
 
-void selinux_resetfscreatecon(struct udev *udev)
+void udev_selinux_setfscreatecon(struct udev *udev, const char *file, unsigned int mode)
 {
-       if (is_selinux_running(udev)) {
-               if (setfscreatecon(prev_scontext) < 0)
-                       err(udev, "setfscreatecon failed: %s\n", strerror(errno));
-       }
-}
+       security_context_t scontext = NULL;
 
-void selinux_init(struct udev *udev)
-{
-       /*
-        * record the present security context, for file-creation
-        * restoration creation purposes.
-        */
-       if (is_selinux_running(udev)) {
-               if (!udev_get_dev_path(udev)[0])
-                       err(udev, "selinux_init: udev_root not set\n");
-               matchpathcon_init_prefix(NULL, udev_get_dev_path(udev));
-               if (getfscreatecon(&prev_scontext) < 0) {
-                       err(udev, "getfscreatecon failed\n");
-                       prev_scontext = NULL;
-               }
+       if (!selinux_enabled)
+               return;
+       if (matchpathcon(file, mode, &scontext) < 0) {
+               err(udev, "matchpathcon(%s) failed\n", file);
+               return;
        }
+       if (setfscreatecon(scontext) < 0)
+               err(udev, "setfscreatecon %s failed: %m\n", file);
+       freecon(scontext);
 }
 
-void selinux_exit(struct udev *udev)
+void udev_selinux_resetfscreatecon(struct udev *udev)
 {
-       if (is_selinux_running(udev) && prev_scontext) {
-               freecon(prev_scontext);
-               prev_scontext = NULL;
-       }
+       if (!selinux_enabled)
+               return;
+       if (setfscreatecon(selinux_prev_scontext) < 0)
+               err(udev, "setfscreatecon failed: %m\n");
 }
+#endif