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;
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);
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;
}