mirror of
https://github.com/morgan9e/systemd
synced 2026-04-14 00:14:32 +09:00
chattr-util: add helpers to read and set project IDs
This commit is contained in:
@@ -10,6 +10,7 @@
|
||||
#include "fd-util.h"
|
||||
#include "fs-util.h"
|
||||
#include "log.h"
|
||||
#include "recurse-dir.h"
|
||||
#include "string-util.h"
|
||||
|
||||
int chattr_full(
|
||||
@@ -169,3 +170,81 @@ int read_attr_at(int dir_fd, const char *path, unsigned *ret) {
|
||||
|
||||
return read_attr_fd(fd, ret);
|
||||
}
|
||||
|
||||
int read_fs_xattr_fd(int fd, uint32_t *ret_xflags, uint32_t *ret_projid) {
|
||||
struct fsxattr attrs;
|
||||
_cleanup_close_ int fd_reopened = -EBADF;
|
||||
|
||||
assert(fd >= 0);
|
||||
|
||||
fd = fd_reopen_condition(fd, O_RDONLY|O_CLOEXEC|O_NOCTTY, O_PATH, &fd_reopened);
|
||||
if (fd < 0)
|
||||
return fd;
|
||||
|
||||
if (ioctl(fd, FS_IOC_FSGETXATTR, &attrs) < 0)
|
||||
return -errno;
|
||||
|
||||
if (ret_xflags)
|
||||
*ret_xflags = attrs.fsx_xflags;
|
||||
|
||||
if (ret_projid)
|
||||
*ret_projid = attrs.fsx_projid;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int set_proj_id(int fd, uint32_t proj_id) {
|
||||
struct fsxattr attrs;
|
||||
_cleanup_close_ int fd_reopened = -EBADF;
|
||||
|
||||
assert(fd >= 0);
|
||||
|
||||
fd = fd_reopen_condition(fd, O_RDONLY|O_CLOEXEC|O_NOCTTY, O_PATH, &fd_reopened);
|
||||
if (fd < 0)
|
||||
return fd;
|
||||
|
||||
if (ioctl(fd, FS_IOC_FSGETXATTR, &attrs) < 0)
|
||||
return -errno;
|
||||
|
||||
struct stat statbuf;
|
||||
if (fstat(fd, &statbuf) < 0)
|
||||
return -errno;
|
||||
|
||||
if (attrs.fsx_projid == proj_id && (!S_ISDIR(statbuf.st_mode) || FLAGS_SET(attrs.fsx_xflags, FS_XFLAG_PROJINHERIT)))
|
||||
return 0;
|
||||
|
||||
attrs.fsx_projid = proj_id;
|
||||
if (S_ISDIR(statbuf.st_mode))
|
||||
attrs.fsx_xflags |= FS_XFLAG_PROJINHERIT;
|
||||
|
||||
return RET_NERRNO(ioctl(fd, FS_IOC_FSSETXATTR, &attrs));
|
||||
}
|
||||
|
||||
static int set_proj_id_cb(
|
||||
RecurseDirEvent event,
|
||||
const char *path,
|
||||
int dir_fd,
|
||||
int inode_fd,
|
||||
const struct dirent *de,
|
||||
const struct statx *sx,
|
||||
void *userdata) {
|
||||
|
||||
if (!IN_SET(event, RECURSE_DIR_ENTER, RECURSE_DIR_ENTRY))
|
||||
return RECURSE_DIR_CONTINUE;
|
||||
|
||||
if (de && !IN_SET(de->d_type, DT_DIR, DT_REG))
|
||||
return RECURSE_DIR_CONTINUE;
|
||||
|
||||
return set_proj_id(inode_fd, PTR_TO_UINT32(userdata));
|
||||
}
|
||||
|
||||
int set_proj_id_recursive(int fd, uint32_t proj_id) {
|
||||
return recurse_dir_at(
|
||||
fd,
|
||||
/* path = */ NULL,
|
||||
/* statx_mask = */ 0,
|
||||
/* n_depth_max = */ UINT_MAX,
|
||||
RECURSE_DIR_ENSURE_TYPE|RECURSE_DIR_TOPLEVEL|RECURSE_DIR_INODE_FD,
|
||||
set_proj_id_cb,
|
||||
UINT32_TO_PTR(proj_id));
|
||||
}
|
||||
|
||||
@@ -50,6 +50,10 @@ static inline int chattr_path(const char *path, unsigned value, unsigned mask) {
|
||||
|
||||
int read_attr_fd(int fd, unsigned *ret);
|
||||
int read_attr_at(int dir_fd, const char *path, unsigned *ret);
|
||||
int read_fs_xattr_fd(int fd, uint32_t *ret_xflags, uint32_t *ret_projid);
|
||||
|
||||
int set_proj_id(int fd, uint32_t proj_id);
|
||||
int set_proj_id_recursive(int fd, uint32_t proj_id);
|
||||
|
||||
/* Combination of chattr flags, that should be appropriate for secrets stored on disk: Secure Remove +
|
||||
* Exclusion from Dumping + Synchronous Writing (i.e. not caching in memory) + In-Place Updating (i.e. not
|
||||
|
||||
Reference in New Issue
Block a user