xmlChar *node_content = xmlNodeGetContent(node);
if (!node_content) {
ret = -LTTNG_ERR_NOMEM;
- goto end;
+ goto error;
}
name = (char *) node_content;
xmlChar *node_content = xmlNodeGetContent(node);
if (!node_content) {
ret = -LTTNG_ERR_NOMEM;
- goto end;
+ goto error;
}
ret = parse_bool(node_content, &started);
free(node_content);
if (ret) {
ret = -LTTNG_ERR_LOAD_INVALID_CONFIG;
- goto end;
+ goto error;
}
} else if (!output_node && !strcmp((const char *) node->name,
config_element_output)) {
xmlNodeGetContent(attributes_child);
if (!snapshot_mode_content) {
ret = -LTTNG_ERR_NOMEM;
- goto end;
+ goto error;
}
ret = parse_bool(snapshot_mode_content, &snapshot_mode);
free(snapshot_mode_content);
if (ret) {
ret = -LTTNG_ERR_LOAD_INVALID_CONFIG;
- goto end;
+ goto error;
}
} else {
/* live_timer_interval */
xmlNodeGetContent(attributes_child);
if (!timer_interval_content) {
ret = -LTTNG_ERR_NOMEM;
- goto end;
+ goto error;
}
ret = parse_uint(timer_interval_content, &live_timer_interval);
free(timer_interval_content);
if (ret) {
ret = -LTTNG_ERR_LOAD_INVALID_CONFIG;
- goto end;
+ goto error;
}
}
}
if (!name) {
/* Mandatory attribute, as defined in the session XSD */
ret = -LTTNG_ERR_LOAD_INVALID_CONFIG;
- goto end;
+ goto error;
}
if (session_name && strcmp(name, session_name)) {
/* This is not the session we are looking for */
- ret = -LTTNG_ERR_LOAD_SESSION_NOENT;
- goto end;
+ ret = -LTTNG_ERR_NO_SESSION;
+ goto error;
}
/* Init domains to create the session handles */
domain = zmalloc(sizeof(*domain));
if (!domain) {
ret = -LTTNG_ERR_NOMEM;
- goto end;
+ goto error;
}
ret = init_domain(node, domain);
domain_init_error:
free(domain);
ret = -LTTNG_ERR_LOAD_INVALID_CONFIG;
- goto end;
+ goto error;
}
if (override) {
ret = lttng_destroy_session(name);
if (ret && ret != -LTTNG_ERR_SESS_NOT_FOUND) {
ERR("Failed to destroy existing session.");
- goto end;
+ goto error;
}
}
ret = create_session(name, kernel_domain, ust_domain, jul_domain,
output_node, UINT64_MAX);
}
-
if (ret) {
- goto end;
+ goto error;
}
for (node = xmlFirstElementChild(domains_node); node;
goto end;
}
}
+
end:
if (ret < 0) {
ERR("Failed to load session %s: %s", name, lttng_strerror(ret));
lttng_destroy_session(name);
}
+error:
free(kernel_domain);
free(ust_domain);
free(jul_domain);
return ret;
}
+/*
+ * Validate that the given path's credentials and the current process have the
+ * same UID. If so, return 0 else return 1 if it does NOT match.
+ */
+static int validate_path_creds(const char *path)
+{
+ int ret, uid = getuid();
+ struct stat buf;
+
+ assert(path);
+
+ if (uid != 0) {
+ goto valid;
+ }
+
+ ret = stat(path, &buf);
+ if (ret < 0) {
+ if (errno != ENOENT) {
+ PERROR("stat");
+ }
+ ret = -LTTNG_ERR_INVALID;
+ goto valid;
+ }
+
+ if (buf.st_uid != uid) {
+ goto invalid;
+ }
+
+valid:
+ return 0;
+invalid:
+ return 1;
+}
+
LTTNG_HIDDEN
int config_load_session(const char *path, const char *session_name,
- int override)
+ int override, unsigned int autoload)
{
int ret;
struct session_config_validation_ctx validation_ctx = { 0 };
}
if (!path) {
+ char *home_path;
+ const char *sys_path;
+
+ /*
+ * Try system session configuration path. Ignore error here so we can
+ * continue loading the home sessions. The above call should print an
+ * error to inform the user.
+ */
+ if (autoload) {
+ sys_path = DEFAULT_SESSION_SYSTEM_CONFIGPATH "/"
+ DEFAULT_SESSION_CONFIG_AUTOLOAD;
+ } else {
+ sys_path = DEFAULT_SESSION_HOME_CONFIGPATH;
+ }
+
+ ret = validate_path_creds(sys_path);
+ if (!ret && autoload) {
+ (void) load_session_from_path(sys_path, session_name,
+ &validation_ctx, override);
+ }
+
/* Try home path */
- char *home_path = utils_get_home_dir();
+ home_path = utils_get_home_dir();
if (home_path) {
- char *path;
+ char path[PATH_MAX];
- ret = asprintf(&path, DEFAULT_SESSION_HOME_CONFIGPATH,
- home_path);
+ if (autoload) {
+ ret = snprintf(path, sizeof(path),
+ DEFAULT_SESSION_HOME_CONFIGPATH "/"
+ DEFAULT_SESSION_CONFIG_AUTOLOAD, home_path);
+ } else {
+ ret = snprintf(path, sizeof(path),
+ DEFAULT_SESSION_HOME_CONFIGPATH, home_path);
+ }
if (ret < 0) {
goto end;
}
+ ret = validate_path_creds(path);
+ if (ret && autoload) {
+ ret = 0;
+ goto end;
+ }
+
ret = load_session_from_path(path, session_name,
- &validation_ctx, 0);
+ &validation_ctx, override);
if (!ret || (ret && ret != -LTTNG_ERR_LOAD_SESSION_NOENT)) {
/* Session found or an error occured */
- free(path);
goto end;
}
-
- free(path);
- }
-
- /* Try system session configuration path */
- ret = load_session_from_path(DEFAULT_SESSION_SYSTEM_CONFIGPATH,
- session_name, &validation_ctx, 0);
- if (!ret || (ret && ret != -LTTNG_ERR_LOAD_SESSION_NOENT)) {
- /* Session found or an error occured */
- goto end;
}
} else {
ret = access(path, F_OK);