{
int ret;
+ assert(len > 0);
+
if (!connected) {
ret = -LTTNG_ERR_NO_SESSIOND;
goto end;
ret = lttcomm_recv_unix_sock(sessiond_socket, buf, len);
if (ret < 0) {
ret = -LTTNG_ERR_FATAL;
+ } else if (ret == 0) {
+ ret = -LTTNG_ERR_NO_SESSIOND;
}
end:
cmd_header_view = lttng_buffer_view_from_dynamic_buffer(
&payload.buffer, 0, sizeof(*cmd_header));
- if (!cmd_header_view.data) {
+ if (!lttng_buffer_view_is_valid(&cmd_header_view)) {
ret = -LTTNG_ERR_INVALID_PROTOCOL;
goto end;
}
payload_view.buffer.data,
ext_comm->userspace_probe_location_len);
+ if (!lttng_payload_view_is_valid(&probe_location_view)) {
+ ret = -LTTNG_ERR_PROBE_LOCATION_INVAL;
+ goto end;
+ }
+
/*
* Create a temporary userspace probe location
* to determine the size needed by a "flattened"
payload_copy_view.buffer.data,
ext_comm->userspace_probe_location_len);
+ if (!lttng_payload_view_is_valid(&probe_location_view)) {
+ ret = -LTTNG_ERR_PROBE_LOCATION_INVAL;
+ goto free_dynamic_buffer;
+ }
+
ret = lttng_userspace_probe_location_create_from_payload(
&probe_location_view,
&probe_location);
struct lttcomm_session_msg *message_lsm;
struct lttng_payload message;
struct lttng_payload reply;
+ struct lttng_trigger *reply_trigger = NULL;
+ 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);
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;
}
}
+ {
+ struct lttng_payload_view reply_view =
+ lttng_payload_view_from_payload(
+ &reply, 0, reply.buffer.size);
+
+ ret = lttng_trigger_create_from_payload(
+ &reply_view, &reply_trigger);
+ if (ret < 0) {
+ ret = -LTTNG_ERR_FATAL;
+ goto end;
+ }
+ }
+
+ ret = lttng_trigger_assign_name(trigger, reply_trigger);
+ if (ret < 0) {
+ ret = -LTTNG_ERR_FATAL;
+ goto end;
+ }
+
ret = 0;
end:
lttng_payload_reset(&message);
lttng_payload_reset(&reply);
+ lttng_trigger_destroy(reply_trigger);
return ret;
}
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);
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;
return ret;
}
+/*
+ * Ask the session daemon for all registered triggers for the current user.
+ *
+ * Allocates and return an lttng_triggers set.
+ * On error, returns a suitable lttng_error_code.
+ */
+enum lttng_error_code lttng_list_triggers(struct lttng_triggers **triggers)
+{
+ int ret;
+ enum lttng_error_code ret_code = LTTNG_OK;
+ struct lttcomm_session_msg lsm = { .cmd_type = LTTNG_LIST_TRIGGERS };
+ struct lttng_triggers *local_triggers = NULL;
+ struct lttng_payload reply;
+ struct lttng_payload_view lsm_view =
+ lttng_payload_view_init_from_buffer(
+ (const char *) &lsm, 0, sizeof(lsm));
+
+ lttng_payload_init(&reply);
+
+ ret = lttng_ctl_ask_sessiond_payload(&lsm_view, &reply);
+ if (ret < 0) {
+ ret_code = (enum lttng_error_code) -ret;
+ goto end;
+ }
+
+ {
+ struct lttng_payload_view reply_view =
+ lttng_payload_view_from_payload(
+ &reply, 0, reply.buffer.size);
+
+ ret = lttng_triggers_create_from_payload(
+ &reply_view, &local_triggers);
+ if (ret < 0) {
+ ret_code = LTTNG_ERR_FATAL;
+ goto end;
+ }
+ }
+
+ *triggers = local_triggers;
+ local_triggers = NULL;
+end:
+ lttng_payload_reset(&reply);
+ lttng_triggers_destroy(local_triggers);
+ return ret_code;
+}
+
/*
* lib constructor.
*/