From 67f747d8095da3f240f71e33c4a1eb0f84aa5e41 Mon Sep 17 00:00:00 2001 From: Mathieu Desnoyers Date: Tue, 20 Dec 2011 16:42:58 -0500 Subject: [PATCH] Implement run_as wrappers for mkdir/mkdir_recursive/open Signed-off-by: Mathieu Desnoyers --- lttng-sessiond/main.c | 6 +-- lttng-sessiond/ust-app.c | 12 ++---- lttng-sessiond/utils.c | 93 ++++++++++++++++++++++++++++++++-------- lttng-sessiond/utils.h | 5 ++- 4 files changed, 86 insertions(+), 30 deletions(-) diff --git a/lttng-sessiond/main.c b/lttng-sessiond/main.c index fbf8d7975..80505b3ca 100644 --- a/lttng-sessiond/main.c +++ b/lttng-sessiond/main.c @@ -1744,7 +1744,7 @@ static int mount_debugfs(char *path) int ret; char *type = "debugfs"; - ret = mkdir_recursive(path, S_IRWXU | S_IRWXG, geteuid(), getegid()); + ret = mkdir_recursive_run_as(path, S_IRWXU | S_IRWXG, geteuid(), getegid()); if (ret < 0) { PERROR("Cannot create debugfs path"); goto error; @@ -1899,7 +1899,7 @@ static int create_ust_session(struct ltt_session *session, goto error; } - ret = mkdir_recursive(lus->pathname, S_IRWXU | S_IRWXG, + ret = mkdir_recursive_run_as(lus->pathname, S_IRWXU | S_IRWXG, session->uid, session->gid); if (ret < 0) { if (ret != -EEXIST) { @@ -1949,7 +1949,7 @@ static int create_kernel_session(struct ltt_session *session) session->kernel_session->consumer_fd = kconsumer_data.cmd_sock; } - ret = mkdir_recursive(session->kernel_session->trace_path, + ret = mkdir_recursive_run_as(session->kernel_session->trace_path, S_IRWXU | S_IRWXG, session->uid, session->gid); if (ret < 0) { if (ret != -EEXIST) { diff --git a/lttng-sessiond/ust-app.c b/lttng-sessiond/ust-app.c index 77dcc71a6..09989ff49 100644 --- a/lttng-sessiond/ust-app.c +++ b/lttng-sessiond/ust-app.c @@ -34,6 +34,7 @@ #include "ust-app.h" #include "ust-consumer.h" #include "ust-ctl.h" +#include "utils.h" /* * Delete ust context safely. RCU read lock must be held before calling @@ -1167,7 +1168,6 @@ static int create_ust_app_metadata(struct ust_app_session *ua_sess, char *pathname, struct ust_app *app) { int ret = 0; - mode_t old_umask; if (ua_sess->metadata == NULL) { /* Allocate UST metadata */ @@ -1193,18 +1193,12 @@ static int create_ust_app_metadata(struct ust_app_session *ua_sess, goto error; } - old_umask = umask(0); - ret = mkdir(ua_sess->path, S_IRWXU | S_IRWXG); + ret = mkdir_run_as(ua_sess->path, S_IRWXU | S_IRWXG, + ua_sess->uid, ua_sess->gid); if (ret < 0) { PERROR("mkdir UST metadata"); goto error; } - ret = chown(ua_sess->path, ua_sess->uid, ua_sess->gid); - if (ret < 0) { - ERR("Unable to change owner of %s", ua_sess->path); - perror("chown"); - } - umask(old_umask); ret = snprintf(ua_sess->metadata->pathname, PATH_MAX, "%s/metadata", ua_sess->path); diff --git a/lttng-sessiond/utils.c b/lttng-sessiond/utils.c index 489b61af8..1e08de77d 100644 --- a/lttng-sessiond/utils.c +++ b/lttng-sessiond/utils.c @@ -26,11 +26,23 @@ #include #include #include +#include #include #include "utils.h" +struct mkdir_data { + const char *path; + mode_t mode; +}; + +struct open_data { + const char *path; + int flags; + mode_t mode; +}; + /* * Write to writable pipe used to notify a thread. */ @@ -60,12 +72,18 @@ const char *get_home_dir(void) * Create recursively directory using the FULL path. */ static -int _mkdir_recursive(const char *path, mode_t mode, uid_t uid, gid_t gid) +int _mkdir_recursive(void *_data) { - int ret; + struct mkdir_data *data = _data; + const char *path; char *p, tmp[PATH_MAX]; + struct stat statbuf; + mode_t mode; size_t len; - mode_t old_umask; + int ret; + + path = data->path; + mode = data->mode; ret = snprintf(tmp, sizeof(tmp), "%s", path); if (ret < 0) { @@ -78,16 +96,18 @@ int _mkdir_recursive(const char *path, mode_t mode, uid_t uid, gid_t gid) tmp[len - 1] = 0; } - old_umask = umask(0); for (p = tmp + 1; *p; p++) { if (*p == '/') { *p = 0; - ret = mkdir(tmp, mode); + ret = stat(tmp, &statbuf); if (ret < 0) { - if (!(errno == EEXIST)) { - PERROR("mkdir recursive"); - ret = -errno; - goto umask_error; + ret = mkdir(tmp, mode); + if (ret < 0) { + if (!(errno == EEXIST)) { + PERROR("mkdir recursive"); + ret = -errno; + goto error; + } } } *p = '/'; @@ -104,15 +124,26 @@ int _mkdir_recursive(const char *path, mode_t mode, uid_t uid, gid_t gid) } } -umask_error: - umask(old_umask); error: return ret; } static -int run_as(int (*cmd)(const char *path, mode_t mode, uid_t uid, gid_t gid), - const char *path, mode_t mode, uid_t uid, gid_t gid) +int _mkdir(void *_data) +{ + struct mkdir_data *data = _data; + return mkdir(data->path, data->mode); +} + +static +int _open(void *_data) +{ + struct open_data *data = _data; + return open(data->path, data->flags, data->mode); +} + +static +int run_as(int (*cmd)(void *data), void *data, uid_t uid, gid_t gid) { int ret = 0; pid_t pid; @@ -126,7 +157,7 @@ int run_as(int (*cmd)(const char *path, mode_t mode, uid_t uid, gid_t gid), uid, geteuid()); return -EPERM; } - return (*cmd)(path, mode, uid, gid); + return (*cmd)(data); } pid = fork(); @@ -155,7 +186,8 @@ int run_as(int (*cmd)(const char *path, mode_t mode, uid_t uid, gid_t gid), perror("seteuid"); exit(EXIT_FAILURE); } - ret = (*cmd)(path, mode, uid, gid); + umask(0); + ret = (*cmd)(data); if (!ret) exit(EXIT_SUCCESS); else @@ -167,9 +199,36 @@ end: return ret; } -int mkdir_recursive(const char *path, mode_t mode, uid_t uid, gid_t gid) +int mkdir_recursive_run_as(const char *path, mode_t mode, uid_t uid, gid_t gid) { + struct mkdir_data data; + DBG3("mkdir() recursive %s with mode %d for uid %d and gid %d", path, mode, uid, gid); - return run_as(_mkdir_recursive, path, mode, uid, gid); + data.path = path; + data.mode = mode; + return run_as(_mkdir_recursive, &data, uid, gid); +} + +int mkdir_run_as(const char *path, mode_t mode, uid_t uid, gid_t gid) +{ + struct mkdir_data data; + + DBG3("mkdir() %s with mode %d for uid %d and gid %d", + path, mode, uid, gid); + data.path = path; + data.mode = mode; + return run_as(_mkdir, &data, uid, gid); +} + +int open_run_as(const char *path, int flags, mode_t mode, uid_t uid, gid_t gid) +{ + struct open_data data; + + DBG3("open() %s with flags %d mode %d for uid %d and gid %d", + path, flags, mode, uid, gid); + data.path = path; + data.flags = flags; + data.mode = mode; + return run_as(_open, &data, uid, gid); } diff --git a/lttng-sessiond/utils.h b/lttng-sessiond/utils.h index 415e0135b..b6c57c7e2 100644 --- a/lttng-sessiond/utils.h +++ b/lttng-sessiond/utils.h @@ -25,7 +25,10 @@ #define __stringify(x) __stringify1(x) #endif -int mkdir_recursive(const char *path, mode_t mode, uid_t uid, gid_t gid); +int mkdir_recursive_run_as(const char *path, mode_t mode, uid_t uid, gid_t gid); +int mkdir_run_as(const char *path, mode_t mode, uid_t uid, gid_t gid); +int open_run_as(const char *path, int flags, mode_t mode, uid_t uid, gid_t gid); + const char *get_home_dir(void); int notify_thread_pipe(int wpipe); -- 2.34.1