Create all trace directories and files with client user credentials
authorMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Tue, 20 Dec 2011 20:19:01 +0000 (15:19 -0500)
committerMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Tue, 20 Dec 2011 20:19:01 +0000 (15:19 -0500)
Keep the client user credentials that created a session along with the
session. Use exactly those credentials to chown the created directories
and files.

Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
14 files changed:
include/lttng-sessiond-comm.h
include/lttng/lttng-consumer.h
liblttng-consumer/lttng-consumer.c
liblttng-kconsumer/lttng-kconsumer.c
liblttng-ustconsumer/lttng-ustconsumer.c
lttng-sessiond/main.c
lttng-sessiond/session.c
lttng-sessiond/session.h
lttng-sessiond/trace-kernel.h
lttng-sessiond/trace-ust.h
lttng-sessiond/ust-app.c
lttng-sessiond/ust-app.h
lttng-sessiond/ust-consumer.c
tests/test_sessions.c

index 0fa6569da28f04e56769a4e1ec2b6c95174b858f..c72a2471e85005b0727a4ecc882ccb2fb56779ec 100644 (file)
@@ -229,6 +229,8 @@ struct lttcomm_consumer_msg {
                        uint32_t state;    /* enum lttcomm_consumer_fd_state */
                        enum lttng_event_output output; /* use splice or mmap to consume this fd */
                        uint64_t mmap_len;
+                       uid_t uid;         /* User ID owning the session */
+                       gid_t gid;         /* Group ID owning the session */
                        char path_name[PATH_MAX];
                } stream;
        } u;
index e5672d7b78ef81f45d7ea8134bb288f78253f8dc..81fd83e0ff4845574f4ddf3762129a2935bf7138 100644 (file)
@@ -22,6 +22,7 @@
 
 #include <limits.h>
 #include <poll.h>
+#include <unistd.h>
 #include <urcu/list.h>
 #include <lttng/lttng.h>
 
@@ -120,6 +121,9 @@ struct lttng_consumer_stream {
        struct lttng_ust_lib_ring_buffer *buf;
        int cpu;
        int hangup_flush_done;
+       /* UID/GID of the user owning the session to which stream belongs */
+       uid_t uid;
+       gid_t gid;
 };
 
 /*
@@ -265,7 +269,9 @@ extern struct lttng_consumer_stream *consumer_allocate_stream(
                enum lttng_consumer_stream_state state,
                uint64_t mmap_len,
                enum lttng_event_output output,
-               const char *path_name);
+               const char *path_name,
+               uid_t uid,
+               gid_t gid);
 extern int consumer_add_stream(struct lttng_consumer_stream *stream);
 extern void consumer_del_stream(struct lttng_consumer_stream *stream);
 extern void consumer_change_stream_state(int stream_key,
index 893df720882b7afd6798e789ca7fd90c967836fd..0811e68ca8e8368c7695f92f37a44c906b42b7c0 100644 (file)
@@ -174,7 +174,9 @@ struct lttng_consumer_stream *consumer_allocate_stream(
                enum lttng_consumer_stream_state state,
                uint64_t mmap_len,
                enum lttng_event_output output,
-               const char *path_name)
+               const char *path_name,
+               uid_t uid,
+               gid_t gid)
 {
        struct lttng_consumer_stream *stream;
        int ret;
@@ -199,6 +201,8 @@ struct lttng_consumer_stream *consumer_allocate_stream(
        stream->mmap_len = mmap_len;
        stream->mmap_base = NULL;
        stream->output = output;
+       stream->uid = uid;
+       stream->gid = gid;
        strncpy(stream->path_name, path_name, PATH_MAX - 1);
        stream->path_name[PATH_MAX - 1] = '\0';
 
index e9861f20fb6b2e11103dacfc8bf36c7e0b77c527..242047ef0237a9af9f6914a6a2cbc969bde2f1ed 100644 (file)
@@ -256,7 +256,9 @@ int lttng_kconsumer_recv_cmd(struct lttng_consumer_local_data *ctx,
                                msg.u.stream.state,
                                msg.u.stream.mmap_len,
                                msg.u.stream.output,
-                               msg.u.stream.path_name);
+                               msg.u.stream.path_name,
+                               msg.u.stream.uid,
+                               msg.u.stream.gid);
                if (new_stream == NULL) {
                        lttng_consumer_send_error(ctx, CONSUMERD_OUTFD_ERROR);
                        goto end;
@@ -401,6 +403,11 @@ int lttng_kconsumer_on_recv_stream(struct lttng_consumer_stream *stream)
                        goto error;
                }
                stream->out_fd = ret;
+               ret = chown(stream->path_name, stream->uid, stream->gid);
+               if (ret < 0) {
+                       ERR("Changing ownership of %s", stream->path_name);
+                       perror("chown");
+               }
        }
 
        if (stream->output == LTTNG_EVENT_MMAP) {
index 89dbefa361380ad2c317bf161a6d65cc7baae0e5..efb6be42490812d45f911b7f650254264efdc57f 100644 (file)
@@ -215,7 +215,9 @@ int lttng_ustconsumer_recv_cmd(struct lttng_consumer_local_data *ctx,
                                msg.u.stream.state,
                                msg.u.stream.mmap_len,
                                msg.u.stream.output,
-                               msg.u.stream.path_name);
+                               msg.u.stream.path_name,
+                               msg.u.stream.uid,
+                               msg.u.stream.gid);
                if (new_stream == NULL) {
                        lttng_consumer_send_error(ctx, CONSUMERD_OUTFD_ERROR);
                        goto end;
@@ -403,6 +405,11 @@ int lttng_ustconsumer_on_recv_stream(struct lttng_consumer_stream *stream)
                        goto error;
                }
                stream->out_fd = ret;
+               ret = chown(stream->path_name, stream->uid, stream->gid);
+               if (ret < 0) {
+                       ERR("Changing ownership of %s", stream->path_name);
+                       perror("chown");
+               }
        }
 
        /* we return 0 to let the library handle the FD internally */
index 759b276a650e546e8447e1fd8f6b8442969839af..fbf8d7975330414cf6589d2aa80f707f25dde88e 100644 (file)
@@ -512,7 +512,8 @@ static void clean_command_ctx(struct command_ctx **cmd_ctx)
  * Send all stream fds of kernel channel to the consumer.
  */
 static int send_kconsumer_channel_streams(struct consumer_data *consumer_data,
-               int sock, struct ltt_kernel_channel *channel)
+               int sock, struct ltt_kernel_channel *channel,
+               uid_t uid, gid_t gid)
 {
        int ret;
        struct ltt_kernel_stream *stream;
@@ -544,6 +545,8 @@ static int send_kconsumer_channel_streams(struct consumer_data *consumer_data,
                lkm.u.stream.state = stream->state;
                lkm.u.stream.output = channel->channel->attr.output;
                lkm.u.stream.mmap_len = 0;      /* for kernel */
+               lkm.u.stream.uid = uid;
+               lkm.u.stream.gid = gid;
                strncpy(lkm.u.stream.path_name, stream->pathname, PATH_MAX - 1);
                lkm.u.stream.path_name[PATH_MAX - 1] = '\0';
                DBG("Sending stream %d to consumer", lkm.u.stream.stream_key);
@@ -605,6 +608,8 @@ static int send_kconsumer_session_streams(struct consumer_data *consumer_data,
                lkm.u.stream.state = LTTNG_CONSUMER_ACTIVE_STREAM;
                lkm.u.stream.output = DEFAULT_KERNEL_CHANNEL_OUTPUT;
                lkm.u.stream.mmap_len = 0;      /* for kernel */
+               lkm.u.stream.uid = session->uid;
+               lkm.u.stream.gid = session->gid;
                strncpy(lkm.u.stream.path_name, session->metadata->pathname, PATH_MAX - 1);
                lkm.u.stream.path_name[PATH_MAX - 1] = '\0';
                DBG("Sending metadata stream %d to consumer", lkm.u.stream.stream_key);
@@ -621,7 +626,8 @@ static int send_kconsumer_session_streams(struct consumer_data *consumer_data,
        }
 
        cds_list_for_each_entry(chan, &session->channel_list.head, list) {
-               ret = send_kconsumer_channel_streams(consumer_data, sock, chan);
+               ret = send_kconsumer_channel_streams(consumer_data, sock, chan,
+                               session->uid, session->gid);
                if (ret < 0) {
                        goto error;
                }
@@ -777,7 +783,8 @@ static int update_kernel_stream(struct consumer_data *consumer_data, int fd)
                                 */
                                if (session->kernel_session->consumer_fds_sent == 1) {
                                        ret = send_kconsumer_channel_streams(consumer_data,
-                                                       session->kernel_session->consumer_fd, channel);
+                                                       session->kernel_session->consumer_fd, channel,
+                                                       session->uid, session->gid);
                                        if (ret < 0) {
                                                goto error;
                                        }
@@ -1871,11 +1878,10 @@ error:
  * Create an UST session and add it to the session ust list.
  */
 static int create_ust_session(struct ltt_session *session,
-               struct lttng_domain *domain, struct ucred *creds)
+               struct lttng_domain *domain)
 {
-       int ret;
-       gid_t gid;
        struct ltt_ust_session *lus = NULL;
+       int ret;
 
        switch (domain->type) {
        case LTTNG_DOMAIN_UST:
@@ -1893,16 +1899,8 @@ static int create_ust_session(struct ltt_session *session,
                goto error;
        }
 
-       /*
-        * Get the right group ID. To use the tracing group, the daemon must be
-        * running with root credentials or else it's the user GID used.
-        */
-       gid = allowed_group();
-       if (gid < 0 || !is_root) {
-               gid = creds->gid;
-       }
-
-       ret = mkdir_recursive(lus->pathname, S_IRWXU | S_IRWXG, creds->uid, gid);
+       ret = mkdir_recursive(lus->pathname, S_IRWXU | S_IRWXG,
+                       session->uid, session->gid);
        if (ret < 0) {
                if (ret != -EEXIST) {
                        ERR("Trace directory creation error");
@@ -1920,6 +1918,8 @@ static int create_ust_session(struct ltt_session *session,
                ERR("Unknown UST domain on create session %d", domain->type);
                goto error;
        }
+       lus->uid = session->uid;
+       lus->gid = session->gid;
        session->ust_session = lus;
 
        return LTTCOMM_OK;
@@ -1932,11 +1932,9 @@ error:
 /*
  * Create a kernel tracer session then create the default channel.
  */
-static int create_kernel_session(struct ltt_session *session,
-               struct ucred *creds)
+static int create_kernel_session(struct ltt_session *session)
 {
        int ret;
-       gid_t gid;
 
        DBG("Creating kernel session");
 
@@ -1951,23 +1949,16 @@ static int create_kernel_session(struct ltt_session *session,
                session->kernel_session->consumer_fd = kconsumer_data.cmd_sock;
        }
 
-       gid = allowed_group();
-       if (gid < 0) {
-               /*
-                * Use GID 0 has a fallback since kernel session is only allowed under
-                * root or the gid of the calling user
-                */
-               is_root ? (gid = 0) : (gid = creds->gid);
-       }
-
        ret = mkdir_recursive(session->kernel_session->trace_path,
-                       S_IRWXU | S_IRWXG, creds->uid, gid);
+                       S_IRWXU | S_IRWXG, session->uid, session->gid);
        if (ret < 0) {
                if (ret != -EEXIST) {
                        ERR("Trace directory creation error");
                        goto error;
                }
        }
+       session->kernel_session->uid = session->uid;
+       session->kernel_session->gid = session->gid;
 
 error:
        return ret;
@@ -2934,11 +2925,11 @@ error:
 /*
  * Command LTTNG_CREATE_SESSION processed by the client thread.
  */
-static int cmd_create_session(char *name, char *path)
+static int cmd_create_session(char *name, char *path, struct ucred *creds)
 {
        int ret;
 
-       ret = session_create(name, path);
+       ret = session_create(name, path, creds->uid, creds->gid);
        if (ret != LTTCOMM_OK) {
                goto error;
        }
@@ -3252,7 +3243,7 @@ static int process_client_msg(struct command_ctx *cmd_ctx)
                /* Need a session for kernel command */
                if (need_tracing_session) {
                        if (cmd_ctx->session->kernel_session == NULL) {
-                               ret = create_kernel_session(cmd_ctx->session, &cmd_ctx->creds);
+                               ret = create_kernel_session(cmd_ctx->session);
                                if (ret < 0) {
                                        ret = LTTCOMM_KERN_SESS_FAIL;
                                        goto error;
@@ -3279,7 +3270,7 @@ static int process_client_msg(struct command_ctx *cmd_ctx)
                if (need_tracing_session) {
                        if (cmd_ctx->session->ust_session == NULL) {
                                ret = create_ust_session(cmd_ctx->session,
-                                               &cmd_ctx->lsm->domain, &cmd_ctx->creds);
+                                               &cmd_ctx->lsm->domain);
                                if (ret != LTTCOMM_OK) {
                                        goto error;
                                }
@@ -3421,7 +3412,7 @@ static int process_client_msg(struct command_ctx *cmd_ctx)
        case LTTNG_CREATE_SESSION:
        {
                ret = cmd_create_session(cmd_ctx->lsm->session.name,
-                               cmd_ctx->lsm->session.path);
+                               cmd_ctx->lsm->session.path, &cmd_ctx->creds);
                break;
        }
        case LTTNG_DESTROY_SESSION:
index 30ae681b353b7d4929f9921951f8cd70364b0736..7a580fdd9b07cfb6ff9b31f4eb5b529f306fc4d4 100644 (file)
@@ -164,7 +164,7 @@ int session_destroy(struct ltt_session *session)
 /*
  * Create a brand new session and add it to the session list.
  */
-int session_create(char *name, char *path)
+int session_create(char *name, char *path, uid_t uid, gid_t gid)
 {
        int ret;
        struct ltt_session *new_session;
@@ -214,12 +214,17 @@ int session_create(char *name, char *path)
        /* Init lock */
        pthread_mutex_init(&new_session->lock, NULL);
 
+       new_session->uid = uid;
+       new_session->gid = gid;
+
        /* Add new session to the session list */
        session_lock_list();
        new_session->id = add_session_list(new_session);
        session_unlock_list();
 
-       DBG("Tracing session %s created in %s with ID %d", name, path, new_session->id);
+       DBG("Tracing session %s created in %s with ID %d by UID %d GID %d",
+               name, path, new_session->id,
+               new_session->uid, new_session->gid);
 
        return LTTCOMM_OK;
 
index fd164007f9048fc46ce9f1d57d10d6a6dd946c5f..6264e14ac4f0b6430fd06f9960e0c9915e539fa2 100644 (file)
@@ -20,6 +20,7 @@
 #define _LTT_SESSION_H
 
 #include <pthread.h>
+#include <unistd.h>
 #include <urcu/list.h>
 
 #include "trace-kernel.h"
@@ -69,10 +70,13 @@ struct ltt_session {
        struct cds_list_head list;
        int enabled;    /* enabled/started flag */
        int id;         /* session unique identifier */
+       /* UID/GID of the user owning the session */
+       uid_t uid;
+       gid_t gid;
 };
 
 /* Prototypes */
-int session_create(char *name, char *path);
+int session_create(char *name, char *path, uid_t uid, gid_t gid);
 int session_destroy(struct ltt_session *session);
 
 void session_lock(struct ltt_session *session);
index bcea65148be4d5994f0d5eec805e40449555cddb..1057c1e07a04eb2255b7f1624b3570ed11d61357 100644 (file)
@@ -97,6 +97,9 @@ struct ltt_kernel_session {
        char *trace_path;
        struct ltt_kernel_metadata *metadata;
        struct ltt_kernel_channel_list channel_list;
+       /* UID/GID of the user owning the session */
+       uid_t uid;
+       gid_t gid;
 };
 
 /*
index a2ed3cb91ff16f2c488b1f980fb839c877a06f40..5a6cade9ab7fb1c19e31a202ff26bcdd984a297d 100644 (file)
@@ -110,6 +110,9 @@ struct ltt_ust_session {
         */
        struct cds_lfht *domain_pid;
        struct cds_lfht *domain_exec;
+       /* UID/GID of the user owning the session */
+       uid_t uid;
+       gid_t gid;
 };
 
 #ifdef HAVE_LIBLTTNG_UST_CTL
index 1b5d6fbf136ff4c29cf133a41ce9b945eee64868..77dcc71a6fee77bbcc28d1298eb90355566fb630 100644 (file)
@@ -770,6 +770,8 @@ static void shadow_copy_session(struct ust_app_session *ua_sess,
        DBG2("Shadow copy of session handle %d", ua_sess->handle);
 
        ua_sess->id = usess->id;
+       ua_sess->uid = usess->uid;
+       ua_sess->gid = usess->gid;
 
        ret = snprintf(ua_sess->path, PATH_MAX,
                        "%s/%s-%d-%s",
@@ -1197,6 +1199,11 @@ static int create_ust_app_metadata(struct ust_app_session *ua_sess,
                        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,
index 00a42186406cf761f9661241cca9d0daad9359f1..0c753ab36eb66c72056c722fd1e2b75cfbd047b3 100644 (file)
@@ -93,6 +93,9 @@ struct ust_app_session {
        struct ltt_ust_metadata *metadata;
        struct cds_lfht *channels; /* Registered channels */
        struct cds_lfht_node node;
+       /* UID/GID of the user owning the session */
+       uid_t uid;
+       gid_t gid;
        char path[PATH_MAX];
 };
 
index 8a2ba728d76dc0b8a6e34c66a90819bc6a12e7f4..b87d61120faa2473f7d42a9609a432e31bc7bebf 100644 (file)
@@ -34,7 +34,8 @@
  * Send all stream fds of UST channel to the consumer.
  */
 static int send_channel_streams(int sock,
-               struct ust_app_channel *uchan)
+               struct ust_app_channel *uchan,
+               uid_t uid, gid_t gid)
 {
        int ret, fd;
        struct lttcomm_consumer_msg lum;
@@ -84,6 +85,8 @@ static int send_channel_streams(int sock,
                 */
                lum.u.stream.output = DEFAULT_UST_CHANNEL_OUTPUT;
                lum.u.stream.mmap_len = stream->obj->memory_map_size;
+               lum.u.stream.uid = uid;
+               lum.u.stream.gid = gid;
                strncpy(lum.u.stream.path_name, stream->pathname, PATH_MAX - 1);
                lum.u.stream.path_name[PATH_MAX - 1] = '\0';
                DBG("Sending stream %d to consumer", lum.u.stream.stream_key);
@@ -158,6 +161,8 @@ int ust_consumer_send_session(int consumer_fd, struct ust_app_session *usess)
                lum.u.stream.state = LTTNG_CONSUMER_ACTIVE_STREAM;
                lum.u.stream.output = DEFAULT_UST_CHANNEL_OUTPUT;
                lum.u.stream.mmap_len = usess->metadata->stream_obj->memory_map_size;
+               lum.u.stream.uid = usess->uid;
+               lum.u.stream.gid = usess->gid;
                strncpy(lum.u.stream.path_name, usess->metadata->pathname, PATH_MAX - 1);
                lum.u.stream.path_name[PATH_MAX - 1] = '\0';
                DBG("Sending metadata stream %d to consumer", lum.u.stream.stream_key);
@@ -181,7 +186,8 @@ int ust_consumer_send_session(int consumer_fd, struct ust_app_session *usess)
        while ((node = hashtable_iter_get_node(&iter)) != NULL) {
                uchan = caa_container_of(node, struct ust_app_channel, node);
 
-               ret = send_channel_streams(sock, uchan);
+               ret = send_channel_streams(sock, uchan, usess->uid,
+                               usess->gid);
                if (ret < 0) {
                        rcu_read_unlock();
                        goto error;
index 3e45c21b669563846e41dbfd0e624496cf95b9df..01a54b3ce27eb0d91b09992d7a3aae0f36d1c359 100644 (file)
@@ -24,6 +24,7 @@
 #include <string.h>
 #include <unistd.h>
 #include <time.h>
+#include <sys/types.h>
 
 #include <lttng-sessiond-comm.h>
 
@@ -118,7 +119,7 @@ static int create_one_session(char *name, char *path)
 {
        int ret;
 
-       ret = session_create(name, path);
+       ret = session_create(name, path, geteuid(), getegid());
        if (ret == LTTCOMM_OK) {
                /* Validate */
                ret = find_session_name(name);
This page took 0.035161 seconds and 4 git commands to generate.