chiark / gitweb /
Make PrivateTmp dirs also inaccessible from the outside
[elogind.git] / src / core / service.c
index 3fbb0a136d185de521ea3187c47c86ba4163ed7a..080d583b69e763454a1983c982461dac29ffcb0e 100644 (file)
@@ -283,7 +283,7 @@ static void service_done(Unit *u) {
         free(s->status_text);
         s->status_text = NULL;
 
-        exec_context_done(&s->exec_context);
+        exec_context_done(&s->exec_context, manager_is_reloading_or_reexecuting(u->manager));
         exec_command_free_array(s->exec_command, _SERVICE_EXEC_COMMAND_MAX);
         s->control_command = NULL;
         s->main_command = NULL;
@@ -1932,6 +1932,9 @@ static void service_enter_dead(Service *s, ServiceResult f, bool allow_restart)
 
         s->forbid_restart = false;
 
+        /* we want fresh tmpdirs in case service is started again immediately */
+        exec_context_tmp_dirs_done(&s->exec_context);
+
         return;
 
 fail:
@@ -2638,6 +2641,12 @@ static int service_serialize(Unit *u, FILE *f, FDSet *fds) {
                 dual_timestamp_serialize(f, "watchdog-timestamp",
                                          &s->watchdog_timestamp);
 
+        if (s->exec_context.tmp_dir)
+                unit_serialize_item(u, f, "tmp-dir", s->exec_context.tmp_dir);
+
+        if (s->exec_context.var_tmp_dir)
+                unit_serialize_item(u, f, "var-tmp-dir", s->exec_context.var_tmp_dir);
+
         return 0;
 }
 
@@ -2756,7 +2765,23 @@ static int service_deserialize_item(Unit *u, const char *key, const char *value,
                 dual_timestamp_deserialize(value, &s->main_exec_status.exit_timestamp);
         else if (streq(key, "watchdog-timestamp"))
                 dual_timestamp_deserialize(value, &s->watchdog_timestamp);
-        else
+        else if (streq(key, "tmp-dir")) {
+                char *t;
+
+                t = strdup(value);
+                if (!t)
+                        return log_oom();
+
+                s->exec_context.tmp_dir = t;
+        } else if (streq(key, "var-tmp-dir")) {
+                char *t;
+
+                t = strdup(value);
+                if (!t)
+                        return log_oom();
+
+                s->exec_context.var_tmp_dir = t;
+        } else
                 log_debug_unit(u->id, "Unknown serialization key '%s'", key);
 
         return 0;
@@ -3711,65 +3736,7 @@ static void service_reset_failed(Unit *u) {
 
 static int service_kill(Unit *u, KillWho who, int signo, DBusError *error) {
         Service *s = SERVICE(u);
-        int r = 0;
-        Set *pid_set = NULL;
-
-        assert(s);
-
-        if (s->main_pid <= 0 && who == KILL_MAIN) {
-                dbus_set_error(error, BUS_ERROR_NO_SUCH_PROCESS, "No main process to kill");
-                return -ESRCH;
-        }
-
-        if (s->control_pid <= 0 && who == KILL_CONTROL) {
-                dbus_set_error(error, BUS_ERROR_NO_SUCH_PROCESS, "No control process to kill");
-                return -ESRCH;
-        }
-
-        if (who == KILL_CONTROL || who == KILL_ALL)
-                if (s->control_pid > 0)
-                        if (kill(s->control_pid, signo) < 0)
-                                r = -errno;
-
-        if (who == KILL_MAIN || who == KILL_ALL)
-                if (s->main_pid > 0)
-                        if (kill(s->main_pid, signo) < 0)
-                                r = -errno;
-
-        if (who == KILL_ALL) {
-                int q;
-
-                pid_set = set_new(trivial_hash_func, trivial_compare_func);
-                if (!pid_set)
-                        return -ENOMEM;
-
-                /* Exclude the control/main pid from being killed via the cgroup */
-                if (s->control_pid > 0) {
-                        q = set_put(pid_set, LONG_TO_PTR(s->control_pid));
-                        if (q < 0) {
-                                r = q;
-                                goto finish;
-                        }
-                }
-
-                if (s->main_pid > 0) {
-                        q = set_put(pid_set, LONG_TO_PTR(s->main_pid));
-                        if (q < 0) {
-                                r = q;
-                                goto finish;
-                        }
-                }
-
-                q = cgroup_bonding_kill_list(UNIT(s)->cgroup_bondings, signo, false, false, pid_set, NULL);
-                if (q < 0 && q != -EAGAIN && q != -ESRCH && q != -ENOENT)
-                        r = q;
-        }
-
-finish:
-        if (pid_set)
-                set_free(pid_set);
-
-        return r;
+        return unit_kill_common(u, who, signo, s->main_pid, s->control_pid, error);
 }
 
 static const char* const service_state_table[_SERVICE_STATE_MAX] = {