From 974ff2acc890403c43767eeabfe9292b7fd75c86 Mon Sep 17 00:00:00 2001 From: Alasdair Kergon Date: Wed, 5 Jan 2005 22:00:39 +0000 Subject: [PATCH] Configuration-time option for setting uid/gid/mode for /dev/mapper nodes. --- WHATS_NEW | 1 + configure | 60 +++++++++++++++++++++++++++++++++++++-- configure.in | 34 ++++++++++++++++++++-- lib/Makefile.in | 3 ++ lib/ioctl/libdm-iface.c | 12 +++++--- lib/ioctl/libdm-targets.h | 4 +++ lib/libdm-common.c | 44 +++++++++++++++++++++------- lib/libdm-common.h.in | 3 +- 8 files changed, 141 insertions(+), 20 deletions(-) diff --git a/WHATS_NEW b/WHATS_NEW index 940c18c..0580853 100644 --- a/WHATS_NEW +++ b/WHATS_NEW @@ -1,5 +1,6 @@ Version 1.00.20 - ============================= + Configuration-time option for setting uid/gid/mode for /dev/mapper nodes. Update kernel patches for 2.4.27/2.4.28-pre-4 (includes minor fixes). Add --noheadings columns option for colon-separated dmsetup output. Support device referencing by uuid or major/minor. diff --git a/configure b/configure index 94e416f..88ea7ad 100755 --- a/configure +++ b/configure @@ -309,7 +309,7 @@ ac_includes_default="\ #endif" ac_default_prefix=/usr -ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS build build_cpu build_vendor build_os host host_cpu host_vendor host_os target target_cpu target_vendor target_os AWK CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT CPP EGREP INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA LN_S SET_MAKE RANLIB ac_ct_RANLIB LIBOBJS MSGFMT JOBS STATIC_LINK OWNER GROUP interface kerneldir missingkernel kernelvsn tmpdir COPTIMISE_FLAG CLDFLAGS LDDEPS SOFLAG DEBUG DM_LIB_VERSION COMPAT LOCALEDIR INTL_PACKAGE INTL LTLIBOBJS' +ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS build build_cpu build_vendor build_os host host_cpu host_vendor host_os target target_cpu target_vendor target_os AWK CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT CPP EGREP INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA LN_S SET_MAKE RANLIB ac_ct_RANLIB LIBOBJS MSGFMT JOBS STATIC_LINK OWNER GROUP interface kerneldir missingkernel kernelvsn tmpdir COPTIMISE_FLAG CLDFLAGS LDDEPS SOFLAG DEBUG DM_LIB_VERSION COMPAT LOCALEDIR INTL_PACKAGE INTL DEVICE_UID DEVICE_GID DEVICE_MODE LTLIBOBJS' ac_subst_files='' # Initialize some variables set by options. @@ -855,8 +855,11 @@ Optional Features: Optional Packages: --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) - --with-user=USER Set the owner of installed files - --with-group=GROUP Set the group owner of installed files + --with-user=USER Set the owner of installed files [USER=root] + --with-group=GROUP Set the group owner of installed files [GROUP=root] + --with-device-uid=UID Set the owner used for new device nodes [UID=0] + --with-device-gid=UID Set the group used for new device nodes [GID=0] + --with-device-mode=MODE Set the mode used for new device nodes [MODE=0600] --with-optimisation=OPT C optimisation flag OPT=-O2 --with-localedir=DIR Translation files in DIR PREFIX/share/locale --with-kernel-dir=DIR linux kernel source in DIR @@ -4747,6 +4750,51 @@ if test x$GROUP != x; then GROUP="-g $GROUP" fi +################################################################################ +echo "$as_me:$LINENO: checking device node uid" >&5 +echo $ECHO_N "checking device node uid... $ECHO_C" >&6 + + +# Check whether --with-device-uid or --without-device-uid was given. +if test "${with_device_uid+set}" = set; then + withval="$with_device_uid" + DEVICE_UID="$withval" +else + DEVICE_UID="0" +fi; +echo "$as_me:$LINENO: result: $DEVICE_UID" >&5 +echo "${ECHO_T}$DEVICE_UID" >&6 + +################################################################################ +echo "$as_me:$LINENO: checking device node gid" >&5 +echo $ECHO_N "checking device node gid... $ECHO_C" >&6 + + +# Check whether --with-device-gid or --without-device-gid was given. +if test "${with_device_gid+set}" = set; then + withval="$with_device_gid" + DEVICE_GID="$withval" +else + DEVICE_GID="0" +fi; +echo "$as_me:$LINENO: result: $DEVICE_GID" >&5 +echo "${ECHO_T}$DEVICE_GID" >&6 + +################################################################################ +echo "$as_me:$LINENO: checking device node mode" >&5 +echo $ECHO_N "checking device node mode... $ECHO_C" >&6 + + +# Check whether --with-device-mode or --without-device-mode was given. +if test "${with_device_mode+set}" = set; then + withval="$with_device_mode" + DEVICE_MODE="$withval" +else + DEVICE_MODE="0600" +fi; +echo "$as_me:$LINENO: result: $DEVICE_MODE" >&5 +echo "${ECHO_T}$DEVICE_MODE" >&6 + ################################################################################ echo "$as_me:$LINENO: checking whether to enable debugging" >&5 echo $ECHO_N "checking whether to enable debugging... $ECHO_C" >&6 @@ -5219,6 +5267,9 @@ fi + + + @@ -5917,6 +5968,9 @@ s,@COMPAT@,$COMPAT,;t t s,@LOCALEDIR@,$LOCALEDIR,;t t s,@INTL_PACKAGE@,$INTL_PACKAGE,;t t s,@INTL@,$INTL,;t t +s,@DEVICE_UID@,$DEVICE_UID,;t t +s,@DEVICE_GID@,$DEVICE_GID,;t t +s,@DEVICE_MODE@,$DEVICE_MODE,;t t s,@LTLIBOBJS@,$LTLIBOBJS,;t t CEOF diff --git a/configure.in b/configure.in index 6356933..124ee64 100644 --- a/configure.in +++ b/configure.in @@ -92,7 +92,7 @@ AC_MSG_CHECKING(file owner) OWNER="root" AC_ARG_WITH(user, - [ --with-user=USER Set the owner of installed files ], + [ --with-user=USER Set the owner of installed files [[USER=root]] ], [ OWNER="$withval" ]) AC_MSG_RESULT($OWNER) @@ -105,7 +105,7 @@ dnl -- Setup the group ownership of the files AC_MSG_CHECKING(group owner) GROUP="root" AC_ARG_WITH(group, - [ --with-group=GROUP Set the group owner of installed files ], + [ --with-group=GROUP Set the group owner of installed files [[GROUP=root]] ], [ GROUP="$withval" ]) AC_MSG_RESULT($GROUP) @@ -113,6 +113,33 @@ if test x$GROUP != x; then GROUP="-g $GROUP" fi +################################################################################ +dnl -- Setup device node ownership +AC_MSG_CHECKING(device node uid) + +AC_ARG_WITH(device-uid, + [ --with-device-uid=UID Set the owner used for new device nodes [[UID=0]] ], + [ DEVICE_UID="$withval" ], [ DEVICE_UID="0" ] ) +AC_MSG_RESULT($DEVICE_UID) + +################################################################################ +dnl -- Setup device group ownership +AC_MSG_CHECKING(device node gid) + +AC_ARG_WITH(device-gid, + [ --with-device-gid=UID Set the group used for new device nodes [[GID=0]] ], + [ DEVICE_GID="$withval" ], [ DEVICE_GID="0" ] ) +AC_MSG_RESULT($DEVICE_GID) + +################################################################################ +dnl -- Setup device mode +AC_MSG_CHECKING(device node mode) + +AC_ARG_WITH(device-mode, + [ --with-device-mode=MODE Set the mode used for new device nodes [[MODE=0600]] ], + [ DEVICE_MODE="$withval" ], [ DEVICE_MODE="0600" ] ) +AC_MSG_RESULT($DEVICE_MODE) + ################################################################################ dnl -- Enable Debugging AC_MSG_CHECKING(whether to enable debugging) @@ -302,6 +329,9 @@ AC_SUBST(MSGFMT) AC_SUBST(LOCALEDIR) AC_SUBST(INTL_PACKAGE) AC_SUBST(INTL) +AC_SUBST(DEVICE_UID) +AC_SUBST(DEVICE_GID) +AC_SUBST(DEVICE_MODE) ################################################################################ diff --git a/lib/Makefile.in b/lib/Makefile.in index 2785108..5f5309e 100644 --- a/lib/Makefile.in +++ b/lib/Makefile.in @@ -24,6 +24,9 @@ INCLUDES = -I$(interface) LIB_STATIC = $(interface)/libdevmapper.a LIB_SHARED = $(interface)/libdevmapper.so +CFLAGS += -DDEVICE_UID=@DEVICE_UID@ -DDEVICE_GID=@DEVICE_GID@ \ + -DDEVICE_MODE=@DEVICE_MODE@ + include ../make.tmpl .PHONY: install_dynamic install_static \ diff --git a/lib/ioctl/libdm-iface.c b/lib/ioctl/libdm-iface.c index 2d48b0d..555cdf6 100644 --- a/lib/ioctl/libdm-iface.c +++ b/lib/ioctl/libdm-iface.c @@ -501,7 +501,8 @@ static int _dm_task_run_v1(struct dm_task *dmt) switch (dmt->type) { case DM_DEVICE_CREATE: - add_dev_node(dmt->dev_name, MAJOR(dmi->dev), MINOR(dmi->dev)); + add_dev_node(dmt->dev_name, MAJOR(dmi->dev), MINOR(dmi->dev), + dmt->uid, dmt->gid, dmt->mode); break; case DM_DEVICE_REMOVE: @@ -515,7 +516,8 @@ static int _dm_task_run_v1(struct dm_task *dmt) case DM_DEVICE_MKNODES: if (dmi->flags & DM_EXISTS_FLAG) add_dev_node(dmt->dev_name, MAJOR(dmi->dev), - MINOR(dmi->dev)); + MINOR(dmi->dev), + dmt->uid, dmt->gid, dmt->mode); else rm_dev_node(dmt->dev_name); break; @@ -1194,7 +1196,8 @@ int dm_task_run(struct dm_task *dmt) ignore_error: switch (dmt->type) { case DM_DEVICE_CREATE: - add_dev_node(dmt->dev_name, MAJOR(dmi->dev), MINOR(dmi->dev)); + add_dev_node(dmt->dev_name, MAJOR(dmi->dev), MINOR(dmi->dev), + dmt->uid, dmt->gid, dmt->mode); break; case DM_DEVICE_REMOVE: @@ -1212,7 +1215,8 @@ int dm_task_run(struct dm_task *dmt) case DM_DEVICE_MKNODES: if (dmi->flags & DM_EXISTS_FLAG) add_dev_node(dmi->name, MAJOR(dmi->dev), - MINOR(dmi->dev)); + MINOR(dmi->dev), + dmt->uid, dmt->gid, dmt->mode); else if (dmt->dev_name) rm_dev_node(dmt->dev_name); break; diff --git a/lib/ioctl/libdm-targets.h b/lib/ioctl/libdm-targets.h index 97fa866..ecd6eab 100644 --- a/lib/ioctl/libdm-targets.h +++ b/lib/ioctl/libdm-targets.h @@ -17,6 +17,7 @@ #define LIB_DMTARGETS_H #include +#include struct dm_ioctl; struct dm_ioctl_v1; @@ -40,6 +41,9 @@ struct dm_task { uint32_t event_nr; int major; int minor; + uid_t uid; + gid_t gid; + mode_t mode; union { struct dm_ioctl *v4; struct dm_ioctl_v1 *v1; diff --git a/lib/libdm-common.c b/lib/libdm-common.c index 6f1b085..2e9b05f 100644 --- a/lib/libdm-common.c +++ b/lib/libdm-common.c @@ -113,6 +113,9 @@ struct dm_task *dm_task_create(int type) dmt->type = type; dmt->minor = -1; dmt->major = -1; + dmt->uid = DEVICE_UID; + dmt->gid = DEVICE_GID; + dmt->mode = DEVICE_MODE; return dmt; } @@ -226,11 +229,13 @@ static int _set_selinux_context(const char *path) } #endif -static int _add_dev_node(const char *dev_name, uint32_t major, uint32_t minor) +static int _add_dev_node(const char *dev_name, uint32_t major, uint32_t minor, + uid_t uid, gid_t gid, mode_t mode) { char path[PATH_MAX]; struct stat info; dev_t dev = MKDEV(major, minor); + mode_t old_mask; _build_dev_path(path, sizeof(path), dev_name); @@ -241,6 +246,7 @@ static int _add_dev_node(const char *dev_name, uint32_t major, uint32_t minor) return 0; } + /* If right inode already exists we don't touch uid etc. */ if (info.st_rdev == dev) return 1; @@ -251,10 +257,18 @@ static int _add_dev_node(const char *dev_name, uint32_t major, uint32_t minor) } } - if (mknod(path, S_IFBLK | S_IRUSR | S_IWUSR | S_IRGRP, dev) < 0) { + old_mask = umask(0); + if (mknod(path, S_IFBLK | mode, dev) < 0) { log_error("Unable to make device node for '%s'", dev_name); return 0; } + umask(old_mask); + + if (chown(path, uid, gid) < 0) { + log_error("%s: chown failed: %s", path, strerror(errno)); + return 0; + } + #ifdef HAVE_SELINUX if (!_set_selinux_context(path)) return 0; @@ -324,11 +338,12 @@ typedef enum { } node_op_t; static int _do_node_op(node_op_t type, const char *dev_name, uint32_t major, - uint32_t minor, const char *old_name) + uint32_t minor, uid_t uid, gid_t gid, mode_t mode, + const char *old_name) { switch (type) { case NODE_ADD: - return _add_dev_node(dev_name, major, minor); + return _add_dev_node(dev_name, major, minor, uid, gid, mode); case NODE_DEL: return _rm_dev_node(dev_name); case NODE_RENAME: @@ -346,6 +361,9 @@ struct node_op_parms { char *dev_name; uint32_t major; uint32_t minor; + uid_t uid; + gid_t gid; + mode_t mode; char *old_name; char names[0]; }; @@ -358,7 +376,8 @@ static void _store_str(char **pos, char **ptr, const char *str) } static int _stack_node_op(node_op_t type, const char *dev_name, uint32_t major, - uint32_t minor, const char *old_name) + uint32_t minor, uid_t uid, gid_t gid, mode_t mode, + const char *old_name) { struct node_op_parms *nop; size_t len = strlen(dev_name) + strlen(old_name) + 2; @@ -373,6 +392,9 @@ static int _stack_node_op(node_op_t type, const char *dev_name, uint32_t major, nop->type = type; nop->major = major; nop->minor = minor; + nop->uid = uid; + nop->gid = gid; + nop->mode = mode; _store_str(&pos, &nop->dev_name, dev_name); _store_str(&pos, &nop->old_name, old_name); @@ -390,25 +412,27 @@ static void _pop_node_ops(void) list_iterate_safe(noph, nopht, &_node_ops) { nop = list_item(noph, struct node_op_parms); _do_node_op(nop->type, nop->dev_name, nop->major, nop->minor, - nop->old_name); + nop->uid, nop->gid, nop->mode, nop->old_name); list_del(&nop->list); free(nop); } } -int add_dev_node(const char *dev_name, uint32_t major, uint32_t minor) +int add_dev_node(const char *dev_name, uint32_t major, uint32_t minor, + uid_t uid, gid_t gid, mode_t mode) { - return _stack_node_op(NODE_ADD, dev_name, major, minor, ""); + return _stack_node_op(NODE_ADD, dev_name, major, minor, uid, gid, mode, + ""); } int rename_dev_node(const char *old_name, const char *new_name) { - return _stack_node_op(NODE_RENAME, new_name, 0, 0, old_name); + return _stack_node_op(NODE_RENAME, new_name, 0, 0, 0, 0, 0, old_name); } int rm_dev_node(const char *dev_name) { - return _stack_node_op(NODE_DEL, dev_name, 0, 0, ""); + return _stack_node_op(NODE_DEL, dev_name, 0, 0, 0, 0, 0, ""); } void update_devs(void) diff --git a/lib/libdm-common.h.in b/lib/libdm-common.h.in index b25550d..c2a97e9 100644 --- a/lib/libdm-common.h.in +++ b/lib/libdm-common.h.in @@ -22,7 +22,8 @@ struct target *create_target(uint64_t start, uint64_t len, const char *type, const char *params); -int add_dev_node(const char *dev_name, uint32_t minor, uint32_t major); +int add_dev_node(const char *dev_name, uint32_t minor, uint32_t major, + uid_t uid, gid_t gid, mode_t mode); int rm_dev_node(const char *dev_name); int rename_dev_node(const char *old_name, const char *new_name); void update_devs(void); -- 2.43.5