mirror of
https://github.com/morgan9e/systemd
synced 2026-04-14 08:25:20 +09:00
nspawn-bind-user: Write membership records
This commit is contained in:
@@ -5,12 +5,16 @@
|
||||
#include "sd-json.h"
|
||||
|
||||
#include "alloc-util.h"
|
||||
#include "chase.h"
|
||||
#include "fd-util.h"
|
||||
#include "fileio.h"
|
||||
#include "format-util.h"
|
||||
#include "io-util.h"
|
||||
#include "log.h"
|
||||
#include "nspawn.h"
|
||||
#include "machine-bind-user.h"
|
||||
#include "nspawn-bind-user.h"
|
||||
#include "strv.h"
|
||||
#include "user-record.h"
|
||||
#include "group-record.h"
|
||||
#include "path-util.h"
|
||||
@@ -67,6 +71,40 @@ static int write_and_symlink(
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int write_membership(const char *root, const char *user, const char *group) {
|
||||
int r;
|
||||
|
||||
assert(user);
|
||||
assert(group);
|
||||
|
||||
_cleanup_free_ char *membership = strjoin(user, ":", group, ".membership");
|
||||
if (!membership)
|
||||
return log_oom();
|
||||
|
||||
_cleanup_free_ char *p = path_join("/run/host/userdb/", membership);
|
||||
if (!p)
|
||||
return log_oom();
|
||||
|
||||
_cleanup_close_ int fd = chase_and_open(
|
||||
p,
|
||||
root,
|
||||
CHASE_PREFIX_ROOT|CHASE_NO_AUTOFS,
|
||||
O_WRONLY|O_CREAT|O_CLOEXEC,
|
||||
/* ret_path= */ NULL);
|
||||
if (fd < 0)
|
||||
return log_error_errno(errno, "Failed to create %s: %m", p);
|
||||
|
||||
r = userns_chown_at(fd, /* fname= */ NULL, /* uid= */ 0, /* gid= */ 0, /* flags= */ 0);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to adjust access mode of '%s': %m", p);
|
||||
|
||||
r = loop_write(fd, "{}\n", SIZE_MAX);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to write empty JSON object into %s: %m", p);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int bind_user_setup(const MachineBindUserContext *c, const char *root) {
|
||||
static const UserRecordLoadFlags strip_flags = /* Removes privileged info */
|
||||
USER_RECORD_LOAD_MASK_PRIVILEGED|
|
||||
@@ -130,6 +168,12 @@ int bind_user_setup(const MachineBindUserContext *c, const char *root) {
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
STRV_FOREACH(u, stripped_group->members) {
|
||||
r = write_membership(root, *u, stripped_group->group_name);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
/* Third, write out user shadow data. i.e. extract privileged info from user record */
|
||||
r = user_record_clone(d->payload_user, shadow_flags, &shadow_user);
|
||||
if (r < 0)
|
||||
@@ -161,6 +205,12 @@ int bind_user_setup(const MachineBindUserContext *c, const char *root) {
|
||||
0);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
STRV_FOREACH(g, stripped_user->member_of) {
|
||||
r = write_membership(root, stripped_user->user_name, *g);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
||||
@@ -1733,7 +1733,7 @@ static int in_child_chown(void) {
|
||||
return IN_SET(arg_userns_mode, USER_NAMESPACE_PICK, USER_NAMESPACE_FIXED);
|
||||
}
|
||||
|
||||
static int userns_chown_at(int fd, const char *fname, uid_t uid, gid_t gid, int flags) {
|
||||
int userns_chown_at(int fd, const char *fname, uid_t uid, gid_t gid, int flags) {
|
||||
assert(fd >= 0 || fd == AT_FDCWD);
|
||||
|
||||
if (!in_child_chown())
|
||||
@@ -1756,6 +1756,9 @@ static int userns_chown_at(int fd, const char *fname, uid_t uid, gid_t gid, int
|
||||
return -EOVERFLOW;
|
||||
}
|
||||
|
||||
if (isempty(fname))
|
||||
flags |= AT_EMPTY_PATH;
|
||||
|
||||
return RET_NERRNO(fchownat(fd, strempty(fname), uid, gid, flags));
|
||||
}
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
#include "shared-forward.h"
|
||||
|
||||
int userns_chown_at(int fd, const char *fname, uid_t uid, gid_t gid, int flags);
|
||||
int userns_lchown(const char *p, uid_t uid, gid_t gid);
|
||||
int userns_mkdir(const char *root, const char *path, mode_t mode, uid_t uid, gid_t gid);
|
||||
int make_run_host(const char *root);
|
||||
|
||||
Reference in New Issue
Block a user