diff options
author | Matthew Thode <[email protected]> | 2013-12-19 00:24:14 -0600 |
---|---|---|
committer | Brian Behlendorf <[email protected]> | 2013-12-19 10:37:31 -0800 |
commit | 11b9ec23b98eefe1e7bde0033dc8285f94cb0b90 (patch) | |
tree | 6be0568aea0dcbb0a76443768a70a26ae692b2bc /cmd | |
parent | d1d7e2689db9e03f11c069ebc9f1ba12829e5dac (diff) |
Add full SELinux support
Four new dataset properties have been added to support SELinux. They
are 'context', 'fscontext', 'defcontext' and 'rootcontext' which map
directly to the context options described in mount(8). When one of
these properties is set to something other than 'none'. That string
will be passed verbatim as a mount option for the given context when
the filesystem is mounted.
For example, if you wanted the rootcontext for a filesystem to be set
to 'system_u:object_r:fs_t' you would set the property as follows:
$ zfs set rootcontext="system_u:object_r:fs_t" storage-pool/media
This will ensure the filesystem is automatically mounted with that
rootcontext. It is equivalent to manually specifying the rootcontext
with the -o option like this:
$ zfs mount -o rootcontext=system_u:object_r:fs_t storage-pool/media
By default all four contexts are set to 'none'. Further information
on SELinux contexts is detailed in mount(8) and selinux(8) man pages.
Signed-off-by: Matthew Thode <[email protected]>
Signed-off-by: Brian Behlendorf <[email protected]>
Signed-off-by: Richard Yao <[email protected]>
Closes #1504
Diffstat (limited to 'cmd')
-rw-r--r-- | cmd/mount_zfs/Makefile.am | 2 | ||||
-rw-r--r-- | cmd/mount_zfs/mount_zfs.c | 88 |
2 files changed, 58 insertions, 32 deletions
diff --git a/cmd/mount_zfs/Makefile.am b/cmd/mount_zfs/Makefile.am index fe34c96b7..e5f3d083b 100644 --- a/cmd/mount_zfs/Makefile.am +++ b/cmd/mount_zfs/Makefile.am @@ -20,5 +20,3 @@ mount_zfs_LDADD = \ $(top_builddir)/lib/libzpool/libzpool.la \ $(top_builddir)/lib/libzfs/libzfs.la \ $(top_builddir)/lib/libzfs_core/libzfs_core.la - -mount_zfs_LDADD += $(LIBSELINUX) diff --git a/cmd/mount_zfs/mount_zfs.c b/cmd/mount_zfs/mount_zfs.c index 82fa67c93..6cb23d1c6 100644 --- a/cmd/mount_zfs/mount_zfs.c +++ b/cmd/mount_zfs/mount_zfs.c @@ -31,9 +31,6 @@ #include <sys/stat.h> #include <libzfs.h> #include <locale.h> -#ifdef HAVE_LIBSELINUX -#include <selinux/selinux.h> -#endif /* HAVE_LIBSELINUX */ libzfs_handle_t *g_zfs; @@ -77,11 +74,10 @@ static const option_map_t option_map[] = { #ifdef MS_STRICTATIME { MNTOPT_DFRATIME, MS_STRICTATIME, ZS_COMMENT }, #endif - { MNTOPT_CONTEXT, MS_COMMENT, ZS_NOCONTEXT }, - { MNTOPT_NOCONTEXT, MS_COMMENT, ZS_NOCONTEXT }, - { MNTOPT_FSCONTEXT, MS_COMMENT, ZS_NOCONTEXT }, - { MNTOPT_DEFCONTEXT, MS_COMMENT, ZS_NOCONTEXT }, - { MNTOPT_ROOTCONTEXT, MS_COMMENT, ZS_NOCONTEXT }, + { MNTOPT_CONTEXT, MS_COMMENT, ZS_COMMENT }, + { MNTOPT_FSCONTEXT, MS_COMMENT, ZS_COMMENT }, + { MNTOPT_DEFCONTEXT, MS_COMMENT, ZS_COMMENT }, + { MNTOPT_ROOTCONTEXT, MS_COMMENT, ZS_COMMENT }, #ifdef MS_I_VERSION { MNTOPT_IVERSION, MS_I_VERSION, ZS_COMMENT }, #endif @@ -338,11 +334,35 @@ mtab_update(char *dataset, char *mntpoint, char *type, char *mntopts) return (MOUNT_SUCCESS); } +static void +__zfs_selinux_setcontext(const char *name, const char *context, char *mntopts, + char *mtabopt) +{ + char tmp[MNT_LINE_MAX]; + + snprintf(tmp, MNT_LINE_MAX, ",%s=\"%s\"", name, context); + strlcat(mntopts, tmp, MNT_LINE_MAX); + strlcat(mtabopt, tmp, MNT_LINE_MAX); +} + +static void +zfs_selinux_setcontext(zfs_handle_t *zhp, zfs_prop_t zpt, const char *name, + char *mntopts, char *mtabopt) +{ + char context[ZFS_MAXPROPLEN]; + + if (zfs_prop_get(zhp, zpt, context, sizeof (context), + NULL, NULL, 0, B_FALSE) == 0) { + if (strcmp(context, "none") != 0) + __zfs_selinux_setcontext(name, context, mntopts, mtabopt); + } +} + int main(int argc, char **argv) { zfs_handle_t *zhp; - char legacy[ZFS_MAXPROPLEN]; + char prop[ZFS_MAXPROPLEN]; char mntopts[MNT_LINE_MAX] = { '\0' }; char badopt[MNT_LINE_MAX] = { '\0' }; char mtabopt[MNT_LINE_MAX] = { '\0' }; @@ -437,22 +457,6 @@ main(int argc, char **argv) } } -#ifdef HAVE_LIBSELINUX - /* - * Automatically add the default zfs context when selinux is enabled - * and the caller has not specified their own context. This must be - * done until zfs is added to the default selinux policy configuration - * as a known filesystem type which supports xattrs. - */ - if (is_selinux_enabled() && !(zfsflags & ZS_NOCONTEXT)) { - (void) strlcat(mntopts, ",context=\"system_u:" - "object_r:file_t:s0\"", sizeof (mntopts)); - (void) strlcat(mtabopt, ",context=\"system_u:" - "object_r:file_t:s0\"", sizeof (mtabopt)); - } -#endif /* HAVE_LIBSELINUX */ - - if (verbose) (void) fprintf(stdout, gettext("mount.zfs:\n" " dataset: \"%s\"\n mountpoint: \"%s\"\n" @@ -480,12 +484,36 @@ main(int argc, char **argv) return (MOUNT_USAGE); } + /* + * Checks to see if the ZFS_PROP_SELINUX_CONTEXT exists + * if it does, create a tmp variable in case it's needed + * checks to see if the selinux context is set to the default + * if it is, allow the setting of the other context properties + * this is needed because the 'context' property overrides others + * if it is not the default, set the 'context' property + */ + if (zfs_prop_get(zhp, ZFS_PROP_SELINUX_CONTEXT, prop, sizeof (prop), + NULL, NULL, 0, B_FALSE) == 0) { + if (strcmp(prop, "none") == 0) { + zfs_selinux_setcontext(zhp, ZFS_PROP_SELINUX_FSCONTEXT, + MNTOPT_FSCONTEXT, mntopts, mtabopt); + zfs_selinux_setcontext(zhp, ZFS_PROP_SELINUX_DEFCONTEXT, + MNTOPT_DEFCONTEXT, mntopts, mtabopt); + zfs_selinux_setcontext(zhp, + ZFS_PROP_SELINUX_ROOTCONTEXT, MNTOPT_ROOTCONTEXT, + mntopts, mtabopt); + } else { + __zfs_selinux_setcontext(MNTOPT_CONTEXT, + prop, mntopts, mtabopt); + } + } + /* treat all snapshots as legacy mount points */ if (zfs_get_type(zhp) == ZFS_TYPE_SNAPSHOT) - (void) strlcpy(legacy, ZFS_MOUNTPOINT_LEGACY, ZFS_MAXPROPLEN); + (void) strlcpy(prop, ZFS_MOUNTPOINT_LEGACY, ZFS_MAXPROPLEN); else - (void) zfs_prop_get(zhp, ZFS_PROP_MOUNTPOINT, legacy, - sizeof (legacy), NULL, NULL, 0, B_FALSE); + (void) zfs_prop_get(zhp, ZFS_PROP_MOUNTPOINT, prop, + sizeof (prop), NULL, NULL, 0, B_FALSE); zfs_close(zhp); libzfs_fini(g_zfs); @@ -501,7 +529,7 @@ main(int argc, char **argv) * using zfs as your root file system both rc.sysinit/umountroot and * systemd depend on 'mount -o remount <mountpoint>' to work. */ - if (zfsutil && (strcmp(legacy, ZFS_MOUNTPOINT_LEGACY) == 0)) { + if (zfsutil && (strcmp(prop, ZFS_MOUNTPOINT_LEGACY) == 0)) { (void) fprintf(stderr, gettext( "filesystem '%s' cannot be mounted using 'zfs mount'.\n" "Use 'zfs set mountpoint=%s' or 'mount -t zfs %s %s'.\n" @@ -511,7 +539,7 @@ main(int argc, char **argv) } if (!zfsutil && !(remount || fake) && - strcmp(legacy, ZFS_MOUNTPOINT_LEGACY)) { + strcmp(prop, ZFS_MOUNTPOINT_LEGACY)) { (void) fprintf(stderr, gettext( "filesystem '%s' cannot be mounted using 'mount'.\n" "Use 'zfs set mountpoint=%s' or 'zfs mount %s'.\n" |