mountfsd: optionally accept an access mode for the dir created by MakeDirectory()
So far we expected the client to access the access mode themselves, and set a restrictive 0700 server-side. However, in some scenarios it's handy if the inode is created server-side already with the right mode, in particular when the client doesn't do anything with the dir just yet, and just needs it to be there with the right mode. If it has to adjust the mode client-side it might otherwise need to fork something off, join the selected userns, adjust the mode, and kill the child off again.
This commit is contained in:
@@ -1003,6 +1003,7 @@ static int vl_method_mount_directory(
|
||||
typedef struct MakeDirectoryParameters {
|
||||
unsigned parent_fd_idx;
|
||||
const char *name;
|
||||
mode_t mode;
|
||||
} MakeDirectoryParameters;
|
||||
|
||||
static int vl_method_make_directory(
|
||||
@@ -1012,14 +1013,16 @@ static int vl_method_make_directory(
|
||||
void *userdata) {
|
||||
|
||||
static const sd_json_dispatch_field dispatch_table[] = {
|
||||
{ "parentFileDescriptor", SD_JSON_VARIANT_UNSIGNED, sd_json_dispatch_uint, offsetof(MakeDirectoryParameters, parent_fd_idx), SD_JSON_MANDATORY },
|
||||
{ "name", SD_JSON_VARIANT_STRING, json_dispatch_const_filename, offsetof(MakeDirectoryParameters, name), SD_JSON_MANDATORY },
|
||||
{ "parentFileDescriptor", _SD_JSON_VARIANT_TYPE_INVALID, sd_json_dispatch_uint, offsetof(MakeDirectoryParameters, parent_fd_idx), SD_JSON_MANDATORY },
|
||||
{ "name", SD_JSON_VARIANT_STRING, json_dispatch_const_filename, offsetof(MakeDirectoryParameters, name), SD_JSON_MANDATORY },
|
||||
{ "mode", _SD_JSON_VARIANT_TYPE_INVALID, json_dispatch_access_mode, offsetof(MakeDirectoryParameters, mode), SD_JSON_STRICT },
|
||||
VARLINK_DISPATCH_POLKIT_FIELD,
|
||||
{}
|
||||
};
|
||||
|
||||
MakeDirectoryParameters p = {
|
||||
.parent_fd_idx = UINT_MAX,
|
||||
.mode = MODE_INVALID,
|
||||
};
|
||||
Hashmap **polkit_registry = ASSERT_PTR(userdata);
|
||||
int r;
|
||||
@@ -1028,6 +1031,11 @@ static int vl_method_make_directory(
|
||||
if (r != 0)
|
||||
return r;
|
||||
|
||||
if (p.mode == MODE_INVALID)
|
||||
p.mode = 0700;
|
||||
else
|
||||
p.mode &= 0775; /* refuse generating world writable dirs */
|
||||
|
||||
if (p.parent_fd_idx == UINT_MAX)
|
||||
return sd_varlink_error_invalid_parameter_name(link, "parentFileDescriptor");
|
||||
|
||||
@@ -1089,11 +1097,11 @@ static int vl_method_make_directory(
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
_cleanup_close_ int fd = open_mkdir_at(parent_fd, t, O_CLOEXEC, 0700);
|
||||
_cleanup_close_ int fd = open_mkdir_at(parent_fd, t, O_CLOEXEC, p.mode);
|
||||
if (fd < 0)
|
||||
return fd;
|
||||
|
||||
r = RET_NERRNO(fchmod(fd, 0700)); /* Set mode explicitly, as paranoia regarding umask games */
|
||||
r = RET_NERRNO(fchmod(fd, p.mode)); /* Set mode explicitly, as paranoia regarding umask games */
|
||||
if (r < 0)
|
||||
goto fail;
|
||||
|
||||
|
||||
@@ -113,6 +113,8 @@ static SD_VARLINK_DEFINE_METHOD(
|
||||
SD_VARLINK_DEFINE_INPUT(parentFileDescriptor, SD_VARLINK_INT, 0),
|
||||
SD_VARLINK_FIELD_COMMENT("Name of the directory to create."),
|
||||
SD_VARLINK_DEFINE_INPUT(name, SD_VARLINK_STRING, 0),
|
||||
SD_VARLINK_FIELD_COMMENT("Access mode of the directory to create. Note that the suid, sgid, sticky, world-writable bit is unconditionally masked off."),
|
||||
SD_VARLINK_DEFINE_INPUT(mode, SD_VARLINK_INT, SD_VARLINK_NULLABLE),
|
||||
VARLINK_DEFINE_POLKIT_INPUT,
|
||||
SD_VARLINK_FIELD_COMMENT("File descriptor referencing the newly created directory."),
|
||||
SD_VARLINK_DEFINE_OUTPUT(directoryFileDescriptor, SD_VARLINK_INT, 0));
|
||||
|
||||
Reference in New Issue
Block a user