diff options
author | Luca Boccassi <luca.boccassi@microsoft.com> | 2020-06-15 15:36:00 +0100 |
---|---|---|
committer | Luca Boccassi <luca.boccassi@microsoft.com> | 2020-06-23 12:57:05 +0100 |
commit | 17b99e377be493b557934740807c2b2679aa23f3 (patch) | |
tree | 1abe88f8c56883bdc2f0b54a53935e7b840b9e2c | |
parent | cc479760b4736082d26ec332f2423a9ab23d59c5 (diff) | |
download | systemd-17b99e377be493b557934740807c2b2679aa23f3.tar.gz |
basic/mkdir: introduce safe recursive variants
Add mkdir_p_safe and mkdir_parents_safe. Will be used by nspawn.
-rw-r--r-- | src/basic/mkdir-label.c | 5 | ||||
-rw-r--r-- | src/basic/mkdir.c | 42 | ||||
-rw-r--r-- | src/basic/mkdir.h | 8 |
3 files changed, 39 insertions, 16 deletions
diff --git a/src/basic/mkdir-label.c b/src/basic/mkdir-label.c index 0eba7fc514..e844a59806 100644 --- a/src/basic/mkdir-label.c +++ b/src/basic/mkdir-label.c @@ -10,6 +10,7 @@ #include "mkdir.h" #include "selinux-util.h" #include "smack-util.h" +#include "user-util.h" int mkdir_label(const char *path, mode_t mode) { int r; @@ -50,9 +51,9 @@ int mkdir_safe_label(const char *path, mode_t mode, uid_t uid, gid_t gid, MkdirF } int mkdir_parents_label(const char *path, mode_t mode) { - return mkdir_parents_internal(NULL, path, mode, mkdir_label); + return mkdir_parents_internal(NULL, path, mode, UID_INVALID, UID_INVALID, 0, mkdir_label); } int mkdir_p_label(const char *path, mode_t mode) { - return mkdir_p_internal(NULL, path, mode, mkdir_label); + return mkdir_p_internal(NULL, path, mode, UID_INVALID, UID_INVALID, 0, mkdir_label); } diff --git a/src/basic/mkdir.c b/src/basic/mkdir.c index ff20cec985..ed5c4546e4 100644 --- a/src/basic/mkdir.c +++ b/src/basic/mkdir.c @@ -93,7 +93,7 @@ int mkdir_safe(const char *path, mode_t mode, uid_t uid, gid_t gid, MkdirFlags f return mkdir_safe_internal(path, mode, uid, gid, flags, mkdir_errno_wrapper); } -int mkdir_parents_internal(const char *prefix, const char *path, mode_t mode, mkdir_func_t _mkdir) { +int mkdir_parents_internal(const char *prefix, const char *path, mode_t mode, uid_t uid, gid_t gid, MkdirFlags flags, mkdir_func_t _mkdir) { const char *p, *e; int r; @@ -136,34 +136,54 @@ int mkdir_parents_internal(const char *prefix, const char *path, mode_t mode, mk if (prefix && path_startswith(prefix, t)) continue; - r = _mkdir(t, mode); - if (r < 0 && r != -EEXIST) - return r; + if (uid == UID_INVALID && gid == UID_INVALID && flags == 0) { + r = _mkdir(t, mode); + if (r < 0 && r != -EEXIST) + return r; + } else { + r = mkdir_safe_internal(t, mode, uid, gid, flags, _mkdir); + if (r < 0 && r != -EEXIST) + return r; + } } } int mkdir_parents(const char *path, mode_t mode) { - return mkdir_parents_internal(NULL, path, mode, mkdir_errno_wrapper); + return mkdir_parents_internal(NULL, path, mode, UID_INVALID, UID_INVALID, 0, mkdir_errno_wrapper); +} + +int mkdir_parents_safe(const char *prefix, const char *path, mode_t mode, uid_t uid, gid_t gid, MkdirFlags flags) { + return mkdir_parents_internal(prefix, path, mode, uid, gid, flags, mkdir_errno_wrapper); } -int mkdir_p_internal(const char *prefix, const char *path, mode_t mode, mkdir_func_t _mkdir) { +int mkdir_p_internal(const char *prefix, const char *path, mode_t mode, uid_t uid, gid_t gid, MkdirFlags flags, mkdir_func_t _mkdir) { int r; /* Like mkdir -p */ assert(_mkdir != mkdir); - r = mkdir_parents_internal(prefix, path, mode, _mkdir); + r = mkdir_parents_internal(prefix, path, mode, uid, gid, flags, _mkdir); if (r < 0) return r; - r = _mkdir(path, mode); - if (r < 0 && (r != -EEXIST || is_dir(path, true) <= 0)) - return r; + if (uid == UID_INVALID && gid == UID_INVALID && flags == 0) { + r = _mkdir(path, mode); + if (r < 0 && (r != -EEXIST || is_dir(path, true) <= 0)) + return r; + } else { + r = mkdir_safe_internal(path, mode, uid, gid, flags, _mkdir); + if (r < 0 && r != -EEXIST) + return r; + } return 0; } int mkdir_p(const char *path, mode_t mode) { - return mkdir_p_internal(NULL, path, mode, mkdir_errno_wrapper); + return mkdir_p_internal(NULL, path, mode, UID_INVALID, UID_INVALID, 0, mkdir_errno_wrapper); +} + +int mkdir_p_safe(const char *prefix, const char *path, mode_t mode, uid_t uid, gid_t gid, MkdirFlags flags) { + return mkdir_p_internal(prefix, path, mode, uid, gid, flags, mkdir_errno_wrapper); } diff --git a/src/basic/mkdir.h b/src/basic/mkdir.h index eb54853ea7..8bfaaf405b 100644 --- a/src/basic/mkdir.h +++ b/src/basic/mkdir.h @@ -12,15 +12,17 @@ int mkdir_errno_wrapper(const char *pathname, mode_t mode); int mkdirat_errno_wrapper(int dirfd, const char *pathname, mode_t mode); int mkdir_safe(const char *path, mode_t mode, uid_t uid, gid_t gid, MkdirFlags flags); int mkdir_parents(const char *path, mode_t mode); +int mkdir_parents_safe(const char *prefix, const char *path, mode_t mode, uid_t uid, gid_t gid, MkdirFlags flags); int mkdir_p(const char *path, mode_t mode); +int mkdir_p_safe(const char *prefix, const char *path, mode_t mode, uid_t uid, gid_t gid, MkdirFlags flags); /* mandatory access control(MAC) versions */ int mkdir_safe_label(const char *path, mode_t mode, uid_t uid, gid_t gid, MkdirFlags flags); -int mkdir_parents_label(const char *path, mode_t mode); +int mkdir_parents_label(const char *path, mode_t mod); int mkdir_p_label(const char *path, mode_t mode); /* internally used */ typedef int (*mkdir_func_t)(const char *pathname, mode_t mode); int mkdir_safe_internal(const char *path, mode_t mode, uid_t uid, gid_t gid, MkdirFlags flags, mkdir_func_t _mkdir); -int mkdir_parents_internal(const char *prefix, const char *path, mode_t mode, mkdir_func_t _mkdir); -int mkdir_p_internal(const char *prefix, const char *path, mode_t mode, mkdir_func_t _mkdir); +int mkdir_parents_internal(const char *prefix, const char *path, mode_t mode, uid_t uid, gid_t gid, MkdirFlags flags, mkdir_func_t _mkdir); +int mkdir_p_internal(const char *prefix, const char *path, mode_t mode, uid_t uid, gid_t gid, MkdirFlags flags, mkdir_func_t _mkdir); |