trigger: expose trigger owner uid
[lttng-tools.git] / src / lib / lttng-ctl / lttng-ctl.c
index 60e820bd25e4a1089a0854b3bd771ce4f9a85bf6..60dcdc7d33872cbf190e79b1dfe9e3385f72e545 100644 (file)
@@ -2956,6 +2956,10 @@ int lttng_register_trigger(struct lttng_trigger *trigger)
        struct lttcomm_session_msg *message_lsm;
        struct lttng_payload message;
        struct lttng_payload reply;
        struct lttcomm_session_msg *message_lsm;
        struct lttng_payload message;
        struct lttng_payload reply;
+       const struct lttng_credentials user_creds = {
+               .uid = LTTNG_OPTIONAL_INIT_VALUE(geteuid()),
+               .gid = LTTNG_OPTIONAL_INIT_UNSET,
+       };
 
        lttng_payload_init(&message);
        lttng_payload_init(&reply);
 
        lttng_payload_init(&message);
        lttng_payload_init(&reply);
@@ -2965,6 +2969,31 @@ int lttng_register_trigger(struct lttng_trigger *trigger)
                goto end;
        }
 
                goto end;
        }
 
+       if (!trigger->creds.uid.is_set) {
+               /* Use the client's credentials as the trigger credentials. */
+               lttng_trigger_set_credentials(trigger, &user_creds);
+       } else {
+               /*
+                * Validate that either the current trigger credentials and the
+                * client credentials are identical or that the current user is
+                * root. The root user can register, unregister triggers for
+                * himself and other users.
+                *
+                * This check is also present on the sessiond side, using the
+                * credentials passed on the socket. These check are all
+                * "safety" checks.
+                */
+               const struct lttng_credentials *trigger_creds =
+                               lttng_trigger_get_credentials(trigger);
+
+               if (!lttng_credentials_is_equal_uid(trigger_creds, &user_creds)) {
+                       if (lttng_credentials_get_uid(&user_creds) != 0) {
+                               ret = -LTTNG_ERR_EPERM;
+                               goto end;
+                       }
+               }
+       }
+
        if (!lttng_trigger_validate(trigger)) {
                ret = -LTTNG_ERR_INVALID_TRIGGER;
                goto end;
        if (!lttng_trigger_validate(trigger)) {
                ret = -LTTNG_ERR_INVALID_TRIGGER;
                goto end;
@@ -3017,6 +3046,10 @@ int lttng_unregister_trigger(struct lttng_trigger *trigger)
        struct lttcomm_session_msg *message_lsm;
        struct lttng_payload message;
        struct lttng_payload reply;
        struct lttcomm_session_msg *message_lsm;
        struct lttng_payload message;
        struct lttng_payload reply;
+       const struct lttng_credentials user_creds = {
+               .uid = LTTNG_OPTIONAL_INIT_VALUE(geteuid()),
+               .gid = LTTNG_OPTIONAL_INIT_UNSET,
+       };
 
        lttng_payload_init(&message);
        lttng_payload_init(&reply);
 
        lttng_payload_init(&message);
        lttng_payload_init(&reply);
@@ -3026,6 +3059,31 @@ int lttng_unregister_trigger(struct lttng_trigger *trigger)
                goto end;
        }
 
                goto end;
        }
 
+       if (!trigger->creds.uid.is_set) {
+               /* Use the client's credentials as the trigger credentials. */
+               lttng_trigger_set_credentials(trigger, &user_creds);
+       } else {
+               /*
+                * Validate that either the current trigger credentials and the
+                * client credentials are identical or that the current user is
+                * root. The root user can register, unregister triggers for
+                * himself and other users.
+                *
+                * This check is also present on the sessiond side, using the
+                * credentials passed on the socket. These check are all
+                * "safety" checks.
+                */
+               const struct lttng_credentials *trigger_creds =
+                               lttng_trigger_get_credentials(trigger);
+
+               if (!lttng_credentials_is_equal_uid(trigger_creds, &user_creds)) {
+                       if (lttng_credentials_get_uid(&user_creds) != 0) {
+                               ret = -LTTNG_ERR_EPERM;
+                               goto end;
+                       }
+               }
+       }
+
        if (!lttng_trigger_validate(trigger)) {
                ret = -LTTNG_ERR_INVALID_TRIGGER;
                goto end;
        if (!lttng_trigger_validate(trigger)) {
                ret = -LTTNG_ERR_INVALID_TRIGGER;
                goto end;
This page took 0.034038 seconds and 4 git commands to generate.