From 1edefa4f1d7bae6cc19aa4a97238400c5a04f7a4 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Mon, 31 Dec 2012 04:48:44 +0100 Subject: [PATCH] udev: in addition to DEVMODE, honor DEVUID, DEVGID from the uevent --- src/libudev/libudev-device.c | 40 +++++++++++++++++++++++++++++++++++ src/libudev/libudev-private.h | 2 ++ src/udev/udev-event.c | 6 ++++++ src/udev/udev-rules.c | 4 ++++ src/udev/udev.h | 2 ++ 5 files changed, 54 insertions(+) diff --git a/src/libudev/libudev-device.c b/src/libudev/libudev-device.c index d246d012b..f218b0278 100644 --- a/src/libudev/libudev-device.c +++ b/src/libudev/libudev-device.c @@ -60,6 +60,8 @@ struct udev_device { const char *sysnum; char *devnode; mode_t devnode_mode; + uid_t devnode_uid; + gid_t devnode_gid; char *subsystem; char *devtype; char *driver; @@ -323,6 +325,40 @@ static int udev_device_set_devnode_mode(struct udev_device *udev_device, mode_t return 0; } +uid_t udev_device_get_devnode_uid(struct udev_device *udev_device) +{ + if (!udev_device->info_loaded) + udev_device_read_uevent_file(udev_device); + return udev_device->devnode_uid; +} + +static int udev_device_set_devnode_uid(struct udev_device *udev_device, uid_t uid) +{ + char num[32]; + + udev_device->devnode_uid = uid; + snprintf(num, sizeof(num), "%u", uid); + udev_device_add_property(udev_device, "DEVUID", num); + return 0; +} + +gid_t udev_device_get_devnode_gid(struct udev_device *udev_device) +{ + if (!udev_device->info_loaded) + udev_device_read_uevent_file(udev_device); + return udev_device->devnode_gid; +} + +static int udev_device_set_devnode_gid(struct udev_device *udev_device, gid_t gid) +{ + char num[32]; + + udev_device->devnode_gid = gid; + snprintf(num, sizeof(num), "%u", gid); + udev_device_add_property(udev_device, "DEVGID", num); + return 0; +} + struct udev_list_entry *udev_device_add_property(struct udev_device *udev_device, const char *key, const char *value) { udev_device->envp_uptodate = false; @@ -430,6 +466,10 @@ void udev_device_add_property_from_string_parse(struct udev_device *udev_device, udev_device_set_ifindex(udev_device, strtoull(&property[8], NULL, 10)); } else if (startswith(property, "DEVMODE=")) { udev_device_set_devnode_mode(udev_device, strtoul(&property[8], NULL, 8)); + } else if (startswith(property, "DEVUID=")) { + udev_device_set_devnode_uid(udev_device, strtoul(&property[7], NULL, 10)); + } else if (startswith(property, "DEVGID=")) { + udev_device_set_devnode_gid(udev_device, strtoul(&property[7], NULL, 10)); } else { udev_device_add_property_from_string(udev_device, property); } diff --git a/src/libudev/libudev-private.h b/src/libudev/libudev-private.h index ff1cc8cef..5b7f0021e 100644 --- a/src/libudev/libudev-private.h +++ b/src/libudev/libudev-private.h @@ -56,6 +56,8 @@ struct udev_list_entry *udev_get_properties_list_entry(struct udev *udev); /* libudev-device.c */ struct udev_device *udev_device_new(struct udev *udev); mode_t udev_device_get_devnode_mode(struct udev_device *udev_device); +uid_t udev_device_get_devnode_uid(struct udev_device *udev_device); +gid_t udev_device_get_devnode_gid(struct udev_device *udev_device); int udev_device_set_subsystem(struct udev_device *udev_device, const char *subsystem); int udev_device_set_syspath(struct udev_device *udev_device, const char *syspath); int udev_device_set_devnode(struct udev_device *udev_device, const char *devnode); diff --git a/src/udev/udev-event.c b/src/udev/udev-event.c index b75ed33fb..5eedf4f0d 100644 --- a/src/udev/udev-event.c +++ b/src/udev/udev-event.c @@ -842,6 +842,12 @@ int udev_event_execute_rules(struct udev_event *event, struct udev_rules *rules, if (event->dev_db != NULL) udev_node_update_old_links(dev, event->dev_db); + if (!event->owner_set) + event->uid = udev_device_get_devnode_uid(dev); + + if (!event->group_set) + event->gid = udev_device_get_devnode_gid(dev); + if (!event->mode_set) { if (udev_device_get_devnode_mode(dev) > 0) { /* kernel supplied value */ diff --git a/src/udev/udev-rules.c b/src/udev/udev-rules.c index e6f0f5da7..9743243a3 100644 --- a/src/udev/udev-rules.c +++ b/src/udev/udev-rules.c @@ -2224,6 +2224,7 @@ int udev_rules_apply_to_event(struct udev_rules *rules, struct udev_event *event if (cur->key.op == OP_ASSIGN_FINAL) event->owner_final = true; udev_event_apply_format(event, rules_str(rules, cur->key.value_off), owner, sizeof(owner)); + event->owner_set = true; event->uid = util_lookup_user(event->udev, owner); log_debug("OWNER %u %s:%u\n", event->uid, @@ -2239,6 +2240,7 @@ int udev_rules_apply_to_event(struct udev_rules *rules, struct udev_event *event if (cur->key.op == OP_ASSIGN_FINAL) event->group_final = true; udev_event_apply_format(event, rules_str(rules, cur->key.value_off), group, sizeof(group)); + event->group_set = true; event->gid = util_lookup_group(event->udev, group); log_debug("GROUP %u %s:%u\n", event->gid, @@ -2274,6 +2276,7 @@ int udev_rules_apply_to_event(struct udev_rules *rules, struct udev_event *event break; if (cur->key.op == OP_ASSIGN_FINAL) event->owner_final = true; + event->owner_set = true; event->uid = cur->key.uid; log_debug("OWNER %u %s:%u\n", event->uid, @@ -2285,6 +2288,7 @@ int udev_rules_apply_to_event(struct udev_rules *rules, struct udev_event *event break; if (cur->key.op == OP_ASSIGN_FINAL) event->group_final = true; + event->group_set = true; event->gid = cur->key.gid; log_debug("GROUP %u %s:%u\n", event->gid, diff --git a/src/udev/udev.h b/src/udev/udev.h index 32779ba48..72a7623e3 100644 --- a/src/udev/udev.h +++ b/src/udev/udev.h @@ -49,7 +49,9 @@ struct udev_event { bool sigterm; bool inotify_watch; bool inotify_watch_final; + bool group_set; bool group_final; + bool owner_set; bool owner_final; bool mode_set; bool mode_final; -- 2.30.2