1
0
mirror of https://github.com/systemd/systemd.git synced 2024-10-29 21:55:36 +03:00

basic/mkdir: introduce safe recursive variants

Add mkdir_p_safe and mkdir_parents_safe. Will be used by nspawn.
This commit is contained in:
Luca Boccassi 2020-06-15 15:36:00 +01:00
parent cc479760b4
commit 17b99e377b
3 changed files with 39 additions and 16 deletions

View 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);
}

View 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_p_internal(const char *prefix, const char *path, mode_t mode, mkdir_func_t _mkdir) {
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, 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);
}

View 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);