Introduce LTTNG_RELAYD_WORKING_DIRECTORY environment variable
[lttng-tools.git] / src / bin / lttng-relayd / main.c
index 2836c489ce9647325dc5a8da7d25d18ba0c684b1..5f72c32a906f700ec14009766d056ead3e49b375 100644 (file)
@@ -96,7 +96,7 @@ enum relay_connection_status {
 };
 
 /* command line options */
-char *opt_output_path;
+char *opt_output_path, *opt_working_directory;
 static int opt_daemon, opt_background, opt_print_version;
 
 /*
@@ -184,6 +184,7 @@ static struct option long_options[] = {
        { "verbose", 0, 0, 'v', },
        { "config", 1, 0, 'f' },
        { "version", 0, 0, 'V' },
+       { "working-directory", 1, 0, 'w', },
        { NULL, 0, 0, 0, },
 };
 
@@ -311,6 +312,20 @@ static int set_option(int opt, const char *arg, const char *optname)
                        }
                }
                break;
+       case 'w':
+               if (lttng_is_setuid_setgid()) {
+                       WARN("Getting '%s' argument from setuid/setgid binary refused for security reasons.",
+                               "-w, --working-directory");
+               } else {
+                       ret = asprintf(&opt_working_directory, "%s", arg);
+                       if (ret < 0) {
+                               ret = -errno;
+                               PERROR("asprintf opt_working_directory");
+                               goto end;
+                       }
+               }
+               break;
+
        case 'v':
                /* Verbose level can increase using multiple -v */
                if (arg) {
@@ -391,6 +406,23 @@ end:
        return ret;
 }
 
+static int parse_env_options(void)
+{
+       int ret = 0;
+       char *value = NULL;
+
+       value = lttng_secure_getenv(DEFAULT_LTTNG_RELAYD_WORKING_DIRECTORY_ENV);
+       if (value) {
+               opt_working_directory = strdup(value);
+               if (!opt_working_directory) {
+                       ERR("Failed to allocate working directory string (\"%s\")",
+                                       value);
+                       ret = -1;
+               }
+       }
+       return ret;
+}
+
 static int set_options(int argc, char **argv)
 {
        int c, ret = 0, option_index = 0, retval = 0;
@@ -541,8 +573,8 @@ static void relayd_cleanup(void)
        if (sessions_ht)
                lttng_ht_destroy(sessions_ht);
 
-       /* free the dynamically allocated opt_output_path */
        free(opt_output_path);
+       free(opt_working_directory);
 
        /* Close thread quit pipes */
        utils_close_pipe(thread_quit_pipe);
@@ -3671,7 +3703,17 @@ int main(int argc, char **argv)
        int ret = 0, retval = 0;
        void *status;
 
-       /* Parse arguments */
+       /* Parse environment variables */
+       ret = parse_env_options();
+       if (ret) {
+               retval = -1;
+               goto exit_options;
+       }
+
+       /*
+        * Parse arguments.
+        * Command line arguments overwrite environment.
+        */
        progname = argv[0];
        if (set_options(argc, argv)) {
                retval = -1;
@@ -3729,6 +3771,14 @@ int main(int argc, char **argv)
                }
        }
 
+       if (opt_working_directory) {
+               ret = utils_change_working_directory(opt_working_directory);
+               if (ret) {
+                       /* All errors are already logged. */
+                       goto exit_options;
+               }
+       }
+
        sessiond_trace_chunk_registry = sessiond_trace_chunk_registry_create();
        if (!sessiond_trace_chunk_registry) {
                ERR("Failed to initialize session daemon trace chunk registry");
This page took 0.024909 seconds and 4 git commands to generate.