From d77dded285b058e4242c8a3d2233f80e725ceefc Mon Sep 17 00:00:00 2001 From: =?utf8?q?J=C3=A9r=C3=A9mie=20Galarneau?= Date: Thu, 3 Sep 2015 15:09:00 -0400 Subject: [PATCH] Accept uid and gid parameters in utils_mkdir()/utils_mkdir_recursive() MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit utils_mkdir* utils may now be use in immediate or "run_as" mode. This is done since some of the code shared between daemons calls run_as directly, which doesn't support negative uid/gid (which we use to mean "run as current user"). Signed-off-by: Jérémie Galarneau --- src/bin/lttng-relayd/main.c | 6 ++-- src/common/runas.c | 6 +++- src/common/utils.c | 62 +++++++++++++++++++++++++++++++++++-- src/common/utils.h | 3 +- 4 files changed, 70 insertions(+), 7 deletions(-) diff --git a/src/bin/lttng-relayd/main.c b/src/bin/lttng-relayd/main.c index 8e1879f50..92d466df7 100644 --- a/src/bin/lttng-relayd/main.c +++ b/src/bin/lttng-relayd/main.c @@ -1285,7 +1285,8 @@ int relay_add_stream(struct lttcomm_relayd_hdr *recv_hdr, lttng_ht_node_init_u64(&stream->node, stream->stream_handle); pthread_mutex_init(&stream->lock, NULL); - ret = utils_mkdir_recursive(stream->path_name, S_IRWXU | S_IRWXG); + ret = utils_mkdir_recursive(stream->path_name, S_IRWXU | S_IRWXG, + -1, -1); if (ret < 0) { ERR("relay creating output directory"); goto err_free_stream; @@ -2828,7 +2829,8 @@ int main(int argc, char **argv) goto exit_options; } - ret = utils_mkdir_recursive(opt_output_path, S_IRWXU | S_IRWXG); + ret = utils_mkdir_recursive(opt_output_path, S_IRWXU | S_IRWXG, + -1, -1); if (ret < 0) { ERR("Unable to create %s", opt_output_path); retval = -1; diff --git a/src/common/runas.c b/src/common/runas.c index 9d9091638..36be188fa 100644 --- a/src/common/runas.c +++ b/src/common/runas.c @@ -101,6 +101,9 @@ int use_clone(void) } #endif +LTTNG_HIDDEN +int _utils_mkdir_recursive_unsafe(const char *path, mode_t mode); + /* * Create recursively directory using the FULL path. */ @@ -114,7 +117,8 @@ int _mkdir_recursive(void *_data) path = data->path; mode = data->mode; - return utils_mkdir_recursive(path, mode); + /* Safe to call as we have transitioned to the requested uid/gid. */ + return _utils_mkdir_recursive_unsafe(path, mode); } static diff --git a/src/common/utils.c b/src/common/utils.c index 766f224c7..db2ed8e7d 100644 --- a/src/common/utils.c +++ b/src/common/utils.c @@ -532,12 +532,42 @@ error: } /* - * Recursively create directory using the given path and mode. + * Create directory using the given path and mode. * * On success, return 0 else a negative error code. */ LTTNG_HIDDEN -int utils_mkdir_recursive(const char *path, mode_t mode) +int utils_mkdir(const char *path, mode_t mode, int uid, int gid) +{ + int ret; + + if (uid < 0 || gid < 0) { + ret = mkdir(path, mode); + } else { + ret = run_as_mkdir(path, mode, uid, gid); + } + if (ret < 0) { + if (errno != EEXIST) { + PERROR("mkdir %s, uid %d, gid %d", path ? path : "NULL", + uid, gid); + } else { + ret = 0; + } + } + + return ret; +} + +/* + * Internal version of mkdir_recursive. Runs as the current user. + * Don't call directly; use utils_mkdir_recursive(). + * + * This function is ominously marked as "unsafe" since it should only + * be called by a caller that has transitioned to the uid and gid under which + * the directory creation should occur. + */ +LTTNG_HIDDEN +int _utils_mkdir_recursive_unsafe(const char *path, mode_t mode) { char *p, tmp[PATH_MAX]; size_t len; @@ -582,7 +612,7 @@ int utils_mkdir_recursive(const char *path, mode_t mode) ret = mkdir(tmp, mode); if (ret < 0) { if (errno != EEXIST) { - PERROR("mkdir recursive last piece"); + PERROR("mkdir recursive last element"); ret = -errno; } else { ret = 0; @@ -593,8 +623,34 @@ error: return ret; } +/* + * Recursively create directory using the given path and mode, under the + * provided uid and gid. + * + * On success, return 0 else a negative error code. + */ +LTTNG_HIDDEN +int utils_mkdir_recursive(const char *path, mode_t mode, int uid, int gid) +{ + int ret; + + if (uid < 0 || gid < 0) { + /* Run as current user. */ + ret = _utils_mkdir_recursive_unsafe(path, mode); + } else { + ret = run_as_mkdir_recursive(path, mode, uid, gid); + } + if (ret < 0) { + PERROR("mkdir %s, uid %d, gid %d", path ? path : "NULL", + uid, gid); + } + + return ret; +} + /* * Create the stream tracefile on disk. + * path is the output parameter. It needs to be PATH_MAX len. * * Return 0 on success or else a negative value. */ diff --git a/src/common/utils.h b/src/common/utils.h index 05914cc37..e5af6fadd 100644 --- a/src/common/utils.h +++ b/src/common/utils.h @@ -37,7 +37,8 @@ void utils_close_pipe(int *src); char *utils_strdupdelim(const char *begin, const char *end); int utils_set_fd_cloexec(int fd); int utils_create_pid_file(pid_t pid, const char *filepath); -int utils_mkdir_recursive(const char *path, mode_t mode); +int utils_mkdir(const char *path, mode_t mode, int uid, int gid); +int utils_mkdir_recursive(const char *path, mode_t mode, int uid, int gid); int utils_create_stream_file(const char *path_name, char *file_name, uint64_t size, uint64_t count, int uid, int gid, char *suffix); int utils_rotate_stream_file(char *path_name, char *file_name, uint64_t size, -- 2.34.1