+ r = transient_scope_set_properties(m);
+ if (r < 0)
+ return bus_log_create_error(r);
+
+ r = sd_bus_message_close_container(m);
+ if (r < 0)
+ return bus_log_create_error(r);
+
+ /* aux */
+ r = sd_bus_message_append(m, "a(sa(sv))", 0);
+ if (r < 0)
+ return bus_log_create_error(r);
+
+ /* send dbus */
+ r = sd_bus_call(bus, m, 0, error, NULL);
+ if (r < 0)
+ return bus_log_create_error(r);
+
+ if (arg_nice_set) {
+ if (setpriority(PRIO_PROCESS, 0, arg_nice) < 0)
+ return log_error_errno(errno, "Failed to set nice level: %m");
+ }
+
+ if (arg_exec_group) {
+ gid_t gid;
+
+ r = get_group_creds(&arg_exec_group, &gid);
+ if (r < 0)
+ return log_error_errno(r, "Failed to resolve group %s: %m", arg_exec_group);
+
+ if (setresgid(gid, gid, gid) < 0)
+ return log_error_errno(errno, "Failed to change GID to " GID_FMT ": %m", gid);
+ }
+
+ if (arg_exec_user) {
+ const char *home, *shell;
+ uid_t uid;
+ gid_t gid;
+
+ r = get_user_creds(&arg_exec_user, &uid, &gid, &home, &shell);
+ if (r < 0)
+ return log_error_errno(r, "Failed to resolve user %s: %m", arg_exec_user);
+
+ r = strv_extendf(&user_env, "HOME=%s", home);
+ if (r < 0)
+ return log_oom();
+
+ r = strv_extendf(&user_env, "SHELL=%s", shell);
+ if (r < 0)
+ return log_oom();
+
+ r = strv_extendf(&user_env, "USER=%s", arg_exec_user);
+ if (r < 0)
+ return log_oom();
+
+ r = strv_extendf(&user_env, "LOGNAME=%s", arg_exec_user);
+ if (r < 0)
+ return log_oom();
+
+ if (!arg_exec_group) {
+ if (setresgid(gid, gid, gid) < 0)
+ return log_error_errno(errno, "Failed to change GID to " GID_FMT ": %m", gid);
+ }
+
+ if (setresuid(uid, uid, uid) < 0)
+ return log_error_errno(errno, "Failed to change UID to " UID_FMT ": %m", uid);
+ }
+
+ env = strv_env_merge(3, environ, user_env, arg_environment);
+ if (!env)
+ return log_oom();
+
+ if (!arg_quiet)
+ log_info("Running as unit %s.", scope);
+
+ execvpe(argv[0], argv, env);
+
+ return log_error_errno(errno, "Failed to execute: %m");
+}
+
+static int start_transient_timer(
+ sd_bus *bus,
+ char **argv,
+ sd_bus_error *error) {
+
+ _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
+ _cleanup_free_ char *timer = NULL, *service = NULL;
+ int r;
+
+ assert(bus);
+ assert(argv);
+
+ if (arg_unit) {
+ switch(unit_name_to_type(arg_unit)) {
+
+ case UNIT_SERVICE:
+ service = strdup(arg_unit);
+ if (!service)
+ return log_oom();
+
+ timer = unit_name_change_suffix(service, ".timer");
+ if (!timer)
+ return log_oom();
+ break;
+
+ case UNIT_TIMER:
+ timer = strdup(arg_unit);
+ if (!timer)
+ return log_oom();
+
+ service = unit_name_change_suffix(timer, ".service");
+ if (!service)
+ return log_oom();
+ break;
+
+ default:
+ service = unit_name_mangle_with_suffix(arg_unit, MANGLE_NOGLOB, ".service");
+ if (!service)
+ return log_oom();
+
+ timer = unit_name_mangle_with_suffix(arg_unit, MANGLE_NOGLOB, ".timer");
+ if (!timer)
+ return log_oom();
+
+ break;
+ }
+ } else if ((asprintf(&service, "run-"PID_FMT".service", getpid()) < 0) ||
+ (asprintf(&timer, "run-"PID_FMT".timer", getpid()) < 0))
+ return log_oom();
+
+ r = sd_bus_message_new_method_call(
+ bus,
+ &m,
+ "org.freedesktop.systemd1",
+ "/org/freedesktop/systemd1",
+ "org.freedesktop.systemd1.Manager",
+ "StartTransientUnit");
+ if (r < 0)
+ return bus_log_create_error(r);
+
+ /* Name and Mode */
+ r = sd_bus_message_append(m, "ss", timer, "fail");
+ if (r < 0)
+ return bus_log_create_error(r);
+
+ /* Properties */
+ r = sd_bus_message_open_container(m, 'a', "(sv)");
+ if (r < 0)
+ return bus_log_create_error(r);
+
+ r = transient_timer_set_properties(m);
+ if (r < 0)
+ return bus_log_create_error(r);
+
+ r = sd_bus_message_close_container(m);
+ if (r < 0)
+ return bus_log_create_error(r);
+
+ r = sd_bus_message_open_container(m, 'a', "(sa(sv))");
+ if (r < 0)
+ return bus_log_create_error(r);
+
+ if (argv[0]) {
+ r = sd_bus_message_open_container(m, 'r', "sa(sv)");
+ if (r < 0)
+ return bus_log_create_error(r);
+
+ r = sd_bus_message_append(m, "s", service);
+ if (r < 0)
+ return bus_log_create_error(r);
+
+ r = sd_bus_message_open_container(m, 'a', "(sv)");
+ if (r < 0)
+ return bus_log_create_error(r);
+
+ r = transient_service_set_properties(m, argv, NULL);
+ if (r < 0)
+ return bus_log_create_error(r);
+
+ r = sd_bus_message_close_container(m);
+ if (r < 0)
+ return bus_log_create_error(r);
+
+ r = sd_bus_message_close_container(m);
+ if (r < 0)
+ return bus_log_create_error(r);
+ }
+
+ r = sd_bus_message_close_container(m);
+ if (r < 0)
+ return bus_log_create_error(r);
+
+ /* send dbus */
+ r = sd_bus_call(bus, m, 0, error, NULL);
+ if (r < 0)
+ return bus_log_create_error(r);
+
+ log_info("Running as unit %s.", timer);
+ if (argv[0])
+ log_info("Will run as unit %s.", service);
+
+ return 0;