sessiond: clarify the role of notification credentials
[lttng-tools.git] / src / bin / lttng-sessiond / notification-thread-events.c
index 7b86fb39c3902e2ac15d8aecae3d38dffea9ef85..6f0ee7d7942cf762b38c6c7edc37ab97caa8972b 100644 (file)
@@ -491,7 +491,7 @@ enum lttng_object_type get_condition_binding_object(
        case LTTNG_CONDITION_TYPE_BUFFER_USAGE_LOW:
        case LTTNG_CONDITION_TYPE_BUFFER_USAGE_HIGH:
        case LTTNG_CONDITION_TYPE_SESSION_CONSUMED_SIZE:
-               return LTTNG_OBJECT_TYPE_CHANNEL;
+               return LTTNG_OBJECT_TYPE_CHANNEL;
        case LTTNG_CONDITION_TYPE_SESSION_ROTATION_ONGOING:
        case LTTNG_CONDITION_TYPE_SESSION_ROTATION_COMPLETED:
                return LTTNG_OBJECT_TYPE_SESSION;
@@ -682,7 +682,7 @@ struct notification_client_list *get_client_list_from_condition(
                        &iter);
        node = cds_lfht_iter_get_node(&iter);
 
-        return node ? caa_container_of(node,
+       return node ? caa_container_of(node,
                        struct notification_client_list,
                        notification_trigger_ht_node) : NULL;
 }
@@ -1306,7 +1306,7 @@ struct lttng_session_trigger_list *get_session_trigger_list(
                goto end;
        }
 
-        list = caa_container_of(node,
+       list = caa_container_of(node,
                        struct lttng_session_trigger_list,
                        session_triggers_ht_node);
 end:
@@ -2146,10 +2146,6 @@ error_free_ht_element:
        free(trigger_ht_element);
 error:
        if (free_trigger) {
-               struct lttng_action *action = lttng_trigger_get_action(trigger);
-
-               lttng_condition_destroy(condition);
-               lttng_action_destroy(action);
                lttng_trigger_destroy(trigger);
        }
        rcu_read_unlock();
@@ -2184,7 +2180,6 @@ int handle_notification_thread_command_unregister_trigger(
        struct lttng_trigger_ht_element *trigger_ht_element = NULL;
        struct lttng_condition *condition = lttng_trigger_get_condition(
                        trigger);
-       struct lttng_action *action;
        enum lttng_error_code cmd_reply;
 
        rcu_read_lock();
@@ -2246,10 +2241,7 @@ int handle_notification_thread_command_unregister_trigger(
                        struct lttng_trigger_ht_element, node);
        cds_lfht_del(state->triggers_ht, triggers_ht_node);
 
-       condition = lttng_trigger_get_condition(trigger_ht_element->trigger);
-       lttng_condition_destroy(condition);
-       action = lttng_trigger_get_action(trigger_ht_element->trigger);
-       lttng_action_destroy(action);
+       /* Release the ownership of the trigger. */
        lttng_trigger_destroy(trigger_ht_element->trigger);
        call_rcu(&trigger_ht_element->rcu_node, free_lttng_trigger_ht_element_rcu);
 end:
@@ -2426,7 +2418,7 @@ int handle_notification_thread_client_connect(
        ret = client_reset_inbound_state(client);
        if (ret) {
                ERR("[notification-thread] Failed to reset client communication's inbound state");
-               ret = 0;
+               ret = 0;
                goto error;
        }
 
@@ -2498,7 +2490,7 @@ int handle_notification_thread_client_disconnect(
        if (ret) {
                ERR("[notification-thread] Failed to remove client socket from poll set");
        }
-        cds_lfht_del(state->client_socket_ht,
+       cds_lfht_del(state->client_socket_ht,
                        &client->client_socket_ht_node);
        notification_client_destroy(client, state);
 end:
@@ -3088,8 +3080,7 @@ end:
 }
 
 static
-int client_enqueue_dropped_notification(struct notification_client *client,
-               struct notification_thread_state *state)
+int client_enqueue_dropped_notification(struct notification_client *client)
 {
        int ret;
        struct lttng_notification_channel_message msg = {
@@ -3103,12 +3094,45 @@ int client_enqueue_dropped_notification(struct notification_client *client,
        return ret;
 }
 
+/*
+ * Permission checks relative to notification channel clients are performed
+ * here. Notice how object, client, and trigger credentials are involved in
+ * this check.
+ *
+ * The `object` credentials are the credentials associated with the "subject"
+ * of a condition. For instance, a `rotation completed` condition applies
+ * to a session. When that condition is met, it will produce an evaluation
+ * against a session. Hence, in this case, the `object` credentials are the
+ * credentials of the "subject" session.
+ *
+ * The `trigger` credentials are the credentials of the user that registered the
+ * trigger.
+ *
+ * The `client` credentials are the credentials of the user that created a given
+ * notification channel.
+ *
+ * In terms of visibility, it is expected that non-privilieged users can only
+ * register triggers against "their" objects (their own sessions and
+ * applications they are allowed to interact with). They can then open a
+ * notification channel and subscribe to notifications associated with those
+ * triggers.
+ *
+ * As for privilieged users, they can register triggers against the objects of
+ * other users. They can then subscribe to the notifications associated to their
+ * triggers. Privilieged users _can't_ subscribe to the notifications of
+ * triggers owned by other users; they must create their own triggers.
+ *
+ * This is more a concern of usability than security. It would be difficult for
+ * a root user reliably subscribe to a specific set of conditions without
+ * interference from external users (those could, for instance, unregister
+ * their triggers).
+ */
 static
 int send_evaluation_to_clients(const struct lttng_trigger *trigger,
                const struct lttng_evaluation *evaluation,
                struct notification_client_list* client_list,
                struct notification_thread_state *state,
-               uid_t channel_uid, gid_t channel_gid)
+               uid_t object_uid, gid_t object_gid)
 {
        int ret = 0;
        struct lttng_payload msg_payload;
@@ -3120,6 +3144,7 @@ int send_evaluation_to_clients(const struct lttng_trigger *trigger,
        struct lttng_notification_channel_message msg_header = {
                .type = (int8_t) LTTNG_NOTIFICATION_CHANNEL_MESSAGE_TYPE_NOTIFICATION,
        };
+       const struct lttng_credentials *trigger_creds = lttng_trigger_get_credentials(trigger);
 
        lttng_payload_init(&msg_payload);
 
@@ -3145,10 +3170,15 @@ int send_evaluation_to_clients(const struct lttng_trigger *trigger,
                struct notification_client *client =
                                client_list_element->client;
 
-               if (client->uid != channel_uid && client->gid != channel_gid &&
+               if (client->uid != object_uid && client->gid != object_gid &&
                                client->uid != 0) {
                        /* Client is not allowed to monitor this channel. */
-                       DBG("[notification-thread] Skipping client at it does not have the permission to receive notification for this channel");
+                       DBG("[notification-thread] Skipping client at it does not have the object permission to receive notification for this trigger");
+                       continue;
+               }
+
+               if (client->uid != trigger_creds->uid && client->gid != trigger_creds->gid) {
+                       DBG("[notification-thread] Skipping client at it does not have the permission to receive notification for this trigger");
                        continue;
                }
 
@@ -3167,7 +3197,7 @@ int send_evaluation_to_clients(const struct lttng_trigger *trigger,
                        if (!client->communication.outbound.dropped_notification) {
                                client->communication.outbound.dropped_notification = true;
                                ret = client_enqueue_dropped_notification(
-                                               client, state);
+                                               client);
                                if (ret) {
                                        goto end;
                                }
@@ -3328,7 +3358,7 @@ int handle_notification_thread_channel_sample(
        trigger_list = caa_container_of(node, struct lttng_channel_trigger_list,
                        channel_triggers_ht_node);
        cds_list_for_each_entry(trigger_list_element, &trigger_list->list,
-                       node) {
+                       node) {
                const struct lttng_condition *condition;
                const struct lttng_action *action;
                const struct lttng_trigger *trigger;
This page took 0.025517 seconds and 4 git commands to generate.