summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuca Boccassi <luca.boccassi@microsoft.com>2020-06-15 15:36:00 +0100
committerLuca Boccassi <luca.boccassi@microsoft.com>2020-06-23 12:57:05 +0100
commit17b99e377be493b557934740807c2b2679aa23f3 (patch)
tree1abe88f8c56883bdc2f0b54a53935e7b840b9e2c
parentcc479760b4736082d26ec332f2423a9ab23d59c5 (diff)
downloadsystemd-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.c5
-rw-r--r--src/basic/mkdir.c42
-rw-r--r--src/basic/mkdir.h8
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);