Skip to content

Instantly share code, notes, and snippets.

@yshui
Last active December 23, 2015 16:09
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save yshui/6660283 to your computer and use it in GitHub Desktop.
Save yshui/6660283 to your computer and use it in GitHub Desktop.
From b5ab6d1ad67e38a11d5296d41a4c3b82145c4185 Mon Sep 17 00:00:00 2001
From: Yuxuan Shui <yshuiv7@gmail.com>
Date: Sun, 22 Sep 2013 01:17:57 +0800
Subject: [PATCH 1/2] core: Add a User= to scopes.
---
src/core/dbus-scope.c | 17 +++++++++++++++++
src/core/load-fragment-gperf.gperf.m4 | 1 +
src/core/scope.c | 27 +++++++++++++++++++++++++++
src/core/scope.h | 2 ++
4 files changed, 47 insertions(+)
diff --git a/src/core/dbus-scope.c b/src/core/dbus-scope.c
index 783a969..766fb99 100644
--- a/src/core/dbus-scope.c
+++ b/src/core/dbus-scope.c
@@ -143,6 +143,23 @@ static int bus_scope_set_transient_property(
}
return 1;
+
+ } else if (streq(name, "User")) {
+
+ if (dbus_message_iter_get_arg_type(i) != DBUS_TYPE_STRING)
+ return -EINVAL;
+
+ if (mode != UNIT_CHECK) {
+ char *t;
+
+ dbus_message_iter_get_basic(i, &t);
+
+ s->user = strdup(t);
+
+ unit_write_drop_in_format(UNIT(s), mode, name, "[Scope]\nUser=%s\n", t);
+ }
+
+ return 1;
}
return 0;
diff --git a/src/core/load-fragment-gperf.gperf.m4 b/src/core/load-fragment-gperf.gperf.m4
index 25bd3aa..a7170ca 100644
--- a/src/core/load-fragment-gperf.gperf.m4
+++ b/src/core/load-fragment-gperf.gperf.m4
@@ -264,6 +264,7 @@ m4_dnl
CGROUP_CONTEXT_CONFIG_ITEMS(Scope)m4_dnl
KILL_CONTEXT_CONFIG_ITEMS(Scope)m4_dnl
Scope.TimeoutStopSec, config_parse_sec, 0, offsetof(Scope, timeout_stop_usec)
+Scope.User, config_parse_unit_string_printf, 0, offsetof(Scope, user)
m4_dnl The [Install] section is ignored here.
Install.Alias, NULL, 0, 0
Install.WantedBy, NULL, 0, 0
diff --git a/src/core/scope.c b/src/core/scope.c
index b94f3ff..8cea7f5 100644
--- a/src/core/scope.c
+++ b/src/core/scope.c
@@ -48,6 +48,8 @@ static void scope_init(Unit *u) {
s->timeout_stop_usec = DEFAULT_TIMEOUT_USEC;
+ s->user = NULL;
+
watch_init(&s->timer_watch);
cgroup_context_init(&s->cgroup_context);
@@ -67,6 +69,9 @@ static void scope_done(Unit *u) {
set_free(s->pids);
s->pids = NULL;
+ free(s->user);
+ s->user = NULL;
+
unit_unwatch_timer(u, &s->timer_watch);
}
@@ -261,6 +266,28 @@ static int scope_start(Unit *u) {
if (r < 0)
return r;
+ if(s->user){
+ uid_t uid;
+ gid_t gid;
+ const char *username = s->user;
+
+ r = get_user_creds(&username, &uid, &gid, NULL, NULL);
+ if (r < 0)
+ return r;
+
+ r = cg_set_task_access(SYSTEMD_CGROUP_CONTROLLER, u->cgroup_path, 0644, uid, gid);
+ if (r < 0) {
+ log_error("Failed to set cgroup permission: %s", strerror(-r));
+ return r;
+ }
+
+ r = cg_set_group_access(SYSTEMD_CGROUP_CONTROLLER, u->cgroup_path, 0755, uid, gid);
+ if (r < 0) {
+ log_error("Failed to set cgroup permission: %s", strerror(-r));
+ return r;
+ }
+ }
+
set_free(s->pids);
s->pids = NULL;
diff --git a/src/core/scope.h b/src/core/scope.h
index 2a3dcb7..fb550a4 100644
--- a/src/core/scope.h
+++ b/src/core/scope.h
@@ -50,6 +50,8 @@ struct Scope {
CGroupContext cgroup_context;
KillContext kill_context;
+ char *user;
+
ScopeState state, deserialized_state;
ScopeResult result;
--
1.8.4
From 9d8d696eb55fdfcdd79eca254f17fbad5a7ff013 Mon Sep 17 00:00:00 2001
From: Yuxuan Shui <yshuiv7@gmail.com>
Date: Sun, 22 Sep 2013 01:18:18 +0800
Subject: [PATCH 2/2] logind: make the user owner of the session scope.
---
src/login/logind-dbus.c | 21 +++++++++++++++++++--
src/login/logind-session.c | 2 +-
src/login/logind.h | 2 +-
3 files changed, 21 insertions(+), 4 deletions(-)
diff --git a/src/login/logind-dbus.c b/src/login/logind-dbus.c
index e76381b..3197dd0 100644
--- a/src/login/logind-dbus.c
+++ b/src/login/logind-dbus.c
@@ -2545,20 +2545,25 @@ int manager_start_scope(
Manager *manager,
const char *scope,
pid_t pid,
- const char *slice,
+ User *user,
const char *description,
const char *after,
const char *kill_mode,
DBusError *error,
char **job) {
- const char *timeout_stop_property = "TimeoutStopUSec", *send_sighup_property = "SendSIGHUP", *pids_property = "PIDs";
+ const char *timeout_stop_property = "TimeoutStopUSec";
+ const char *send_sighup_property = "SendSIGHUP";
+ const char *pids_property = "PIDs", *user_property = "User";
_cleanup_dbus_message_unref_ DBusMessage *m = NULL, *reply = NULL;
DBusMessageIter iter, sub, sub2, sub3, sub4;
uint64_t timeout = 500 * USEC_PER_MSEC;
dbus_bool_t send_sighup = true;
const char *fail = "fail";
uint32_t u;
+ char *uid;
+
+ const char *slice = user->slice;
assert(manager);
assert(scope);
@@ -2645,6 +2650,18 @@ int manager_start_scope(
!dbus_message_iter_close_container(&sub, &sub2))
return log_oom();
+ asprintf(&uid, "%lu", (long unsigned int) user->uid);
+ if (!dbus_message_iter_open_container(&sub, DBUS_TYPE_STRUCT, NULL, &sub2) ||
+ !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_STRING, &user_property) ||
+ !dbus_message_iter_open_container(&sub2, DBUS_TYPE_VARIANT, "s", &sub3) ||
+ !dbus_message_iter_append_basic(&sub3, DBUS_TYPE_STRING, &uid) ||
+ !dbus_message_iter_close_container(&sub2, &sub3) ||
+ !dbus_message_iter_close_container(&sub, &sub2)){
+ free(uid);
+ return log_oom();
+ }
+ free(uid);
+
/* Make sure that the session shells are terminated with
* SIGHUP since bash and friends tend to ignore SIGTERM */
if (!dbus_message_iter_open_container(&sub, DBUS_TYPE_STRUCT, NULL, &sub2) ||
diff --git a/src/login/logind-session.c b/src/login/logind-session.c
index 27aa335..ce5725f 100644
--- a/src/login/logind-session.c
+++ b/src/login/logind-session.c
@@ -518,7 +518,7 @@ static int session_start_scope(Session *s) {
kill_mode = manager_shall_kill(s->manager, s->user->name) ? "control-group" : "none";
- r = manager_start_scope(s->manager, scope, s->leader, s->user->slice, description, "systemd-user-sessions.service", kill_mode, &error, &job);
+ r = manager_start_scope(s->manager, scope, s->leader, s->user, description, "systemd-user-sessions.service", kill_mode, &error, &job);
if (r < 0) {
log_error("Failed to start session scope %s: %s %s",
scope, bus_error(&error, r), error.name);
diff --git a/src/login/logind.h b/src/login/logind.h
index 9e6296c..e5b534f 100644
--- a/src/login/logind.h
+++ b/src/login/logind.h
@@ -183,7 +183,7 @@ int manager_send_changed(Manager *manager, const char *properties);
int manager_dispatch_delayed(Manager *manager);
-int manager_start_scope(Manager *manager, const char *scope, pid_t pid, const char *slice, const char *description, const char *after, const char *kill_mode, DBusError *error, char **job);
+int manager_start_scope(Manager *manager, const char *scope, pid_t pid, User *user, const char *description, const char *after, const char *kill_mode, DBusError *error, char **job);
int manager_start_unit(Manager *manager, const char *unit, DBusError *error, char **job);
int manager_stop_unit(Manager *manager, const char *unit, DBusError *error, char **job);
int manager_kill_unit(Manager *manager, const char *unit, KillWho who, int signo, DBusError *error);
--
1.8.4
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment