diff options
author | Yu Watanabe <watanabe.yu+github@gmail.com> | 2022-04-06 02:31:19 +0900 |
---|---|---|
committer | Yu Watanabe <watanabe.yu+github@gmail.com> | 2022-04-06 14:52:36 +0900 |
commit | 26dd37f6d565dd28d15b3401491589b5a7c86ecb (patch) | |
tree | 4846719beeaa947852e578d659556bbd22315f7a /src/udev/udev-node.c | |
parent | e5ddfe3ec586c9ab174d39f4b6202155d92d24e4 (diff) | |
download | systemd-26dd37f6d565dd28d15b3401491589b5a7c86ecb.tar.gz |
udev: move apply_static_dev_perms() to udev-node.c
and make it internally use udev_node_apply_permissions_impl().
Diffstat (limited to 'src/udev/udev-node.c')
-rw-r--r-- | src/udev/udev-node.c | 62 |
1 files changed, 62 insertions, 0 deletions
diff --git a/src/udev/udev-node.c b/src/udev/udev-node.c index 493feffe00..deacbc31c5 100644 --- a/src/udev/udev-node.c +++ b/src/udev/udev-node.c @@ -13,6 +13,7 @@ #include "device-private.h" #include "device-util.h" #include "dirent-util.h" +#include "escape.h" #include "fd-util.h" #include "format-util.h" #include "fs-util.h" @@ -718,3 +719,64 @@ int udev_node_apply_permissions( return udev_node_apply_permissions_impl(dev, node_fd, devnode, apply_mac, mode, uid, gid, seclabel_list); } + +int static_node_apply_permissions( + const char *name, + mode_t mode, + uid_t uid, + gid_t gid, + char **tags) { + + _cleanup_free_ char *unescaped_filename = NULL; + _cleanup_close_ int node_fd = -1; + const char *devnode; + struct stat stats; + int r; + + assert(name); + + if (uid == UID_INVALID && gid == GID_INVALID && mode == MODE_INVALID && !tags) + return 0; + + devnode = strjoina("/dev/", name); + + node_fd = open(devnode, O_PATH|O_CLOEXEC); + if (node_fd < 0) { + if (errno != ENOENT) + return log_error_errno(errno, "Failed to open %s: %m", devnode); + return 0; + } + + if (fstat(node_fd, &stats) < 0) + return log_error_errno(errno, "Failed to stat %s: %m", devnode); + + if (!S_ISBLK(stats.st_mode) && !S_ISCHR(stats.st_mode)) { + log_warning("%s is neither block nor character device, ignoring.", devnode); + return 0; + } + + if (!strv_isempty(tags)) { + unescaped_filename = xescape(name, "/."); + if (!unescaped_filename) + return log_oom(); + } + + /* export the tags to a directory as symlinks, allowing otherwise dead nodes to be tagged */ + STRV_FOREACH(t, tags) { + _cleanup_free_ char *p = NULL; + + p = path_join("/run/udev/static_node-tags/", *t, unescaped_filename); + if (!p) + return log_oom(); + + r = mkdir_parents(p, 0755); + if (r < 0) + return log_error_errno(r, "Failed to create parent directory for %s: %m", p); + + r = symlink(devnode, p); + if (r < 0 && errno != EEXIST) + return log_error_errno(errno, "Failed to create symlink %s -> %s: %m", p, devnode); + } + + return udev_node_apply_permissions_impl(NULL, node_fd, devnode, false, mode, uid, gid, NULL); +} |