From 6eebc4a6203175a5217afd33fb8aa45a8093a8e9 Mon Sep 17 00:00:00 2001 From: Alasdair Kergon Date: Wed, 5 Jan 2005 22:00:40 +0000 Subject: [PATCH] Configuration-time option for setting uid/gid/mode for /dev/mapper nodes. --- WHATS_NEW_DM | 1 + libdm/Makefile.in | 3 +++ libdm/ioctl/libdm-iface.c | 12 ++++++---- libdm/ioctl/libdm-targets.h | 4 ++++ libdm/libdm-common.c | 44 ++++++++++++++++++++++++++++--------- libdm/libdm-common.h.in | 3 ++- 6 files changed, 52 insertions(+), 15 deletions(-) diff --git a/WHATS_NEW_DM b/WHATS_NEW_DM index 940c18c80..05808537d 100644 --- a/WHATS_NEW_DM +++ b/WHATS_NEW_DM @@ -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/libdm/Makefile.in b/libdm/Makefile.in index 2785108c8..5f5309e41 100644 --- a/libdm/Makefile.in +++ b/libdm/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/libdm/ioctl/libdm-iface.c b/libdm/ioctl/libdm-iface.c index 2d48b0da9..555cdf627 100644 --- a/libdm/ioctl/libdm-iface.c +++ b/libdm/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/libdm/ioctl/libdm-targets.h b/libdm/ioctl/libdm-targets.h index 97fa8661d..ecd6eabfd 100644 --- a/libdm/ioctl/libdm-targets.h +++ b/libdm/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/libdm/libdm-common.c b/libdm/libdm-common.c index 6f1b085cc..2e9b05f27 100644 --- a/libdm/libdm-common.c +++ b/libdm/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/libdm/libdm-common.h.in b/libdm/libdm-common.h.in index b25550d31..c2a97e962 100644 --- a/libdm/libdm-common.h.in +++ b/libdm/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);