typedef struct MakeDirectoryParameters {
unsigned parent_fd_idx;
const char *name;
+ mode_t mode;
} MakeDirectoryParameters;
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;
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");
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;
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));