]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
basic/mkdir: introduce safe recursive variants
authorLuca Boccassi <luca.boccassi@microsoft.com>
Mon, 15 Jun 2020 14:36:00 +0000 (15:36 +0100)
committerLuca Boccassi <luca.boccassi@microsoft.com>
Tue, 23 Jun 2020 11:57:05 +0000 (12:57 +0100)
Add mkdir_p_safe and mkdir_parents_safe. Will be used by nspawn.

src/basic/mkdir-label.c
src/basic/mkdir.c
src/basic/mkdir.h

index 0eba7fc514b2cea8ff7eedacd6e4fe126bee826c..e844a598060d3e6485ecd126e1e9378dee3d5166 100644 (file)
@@ -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);
 }
index ff20cec98585fcdf68bd7a9398a319165a37c3ce..ed5c4546e4074461755f791510d0ebde6559942c 100644 (file)
@@ -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);
 }
index eb54853ea78b45dc46d9ab2c8215ebfea3951d39..8bfaaf405bcb888a93611d1b9a00f938560a180d 100644 (file)
@@ -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);