From 58109c17667483583032bf1b8a3b6991976b68b7 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Thu, 22 Mar 2018 12:38:01 +0100 Subject: [PATCH] basic/mkdir: convert bool flag to enum In preparation for subsequent changes... --- src/basic/mkdir-label.c | 4 ++-- src/basic/mkdir.c | 11 ++++++---- src/basic/mkdir.h | 10 ++++++--- src/login/logind-dbus.c | 43 ++++++++++++++++++++++++-------------- src/login/logind-inhibit.c | 4 ++-- src/login/logind-seat.c | 5 +++-- src/login/logind-session.c | 3 ++- src/login/logind-user.c | 4 ++-- src/test/test-fs-util.c | 2 +- 9 files changed, 53 insertions(+), 33 deletions(-) diff --git a/src/basic/mkdir-label.c b/src/basic/mkdir-label.c index 3fa642578..4e5b7c961 100644 --- a/src/basic/mkdir-label.c +++ b/src/basic/mkdir-label.c @@ -47,8 +47,8 @@ int mkdir_label(const char *path, mode_t mode) { return mac_smack_fix(path, false, false); } -int mkdir_safe_label(const char *path, mode_t mode, uid_t uid, gid_t gid, bool follow_symlink) { - return mkdir_safe_internal(path, mode, uid, gid, follow_symlink, mkdir_label); +int mkdir_safe_label(const char *path, mode_t mode, uid_t uid, gid_t gid, MkdirFlags flags) { + return mkdir_safe_internal(path, mode, uid, gid, flags, mkdir_label); } #if 0 /// UNNEEDED by elogind diff --git a/src/basic/mkdir.c b/src/basic/mkdir.c index 198d815c1..139318523 100644 --- a/src/basic/mkdir.c +++ b/src/basic/mkdir.c @@ -35,6 +35,7 @@ #include "missing.h" int mkdir_safe_internal(const char *path, mode_t mode, uid_t uid, gid_t gid, bool follow_symlink, mkdir_func_t _mkdir) { +int mkdir_safe_internal(const char *path, mode_t mode, uid_t uid, gid_t gid, MkdirFlags flags, mkdir_func_t _mkdir) { struct stat st; int r; @@ -49,14 +50,16 @@ int mkdir_safe_internal(const char *path, mode_t mode, uid_t uid, gid_t gid, boo if (lstat(path, &st) < 0) return -errno; - if (follow_symlink && S_ISLNK(st.st_mode)) { + if ((flags & MKDIR_FOLLOW_SYMLINK) && S_ISLNK(st.st_mode)) { _cleanup_free_ char *p = NULL; r = chase_symlinks(path, NULL, CHASE_NONEXISTENT, &p); if (r < 0) return r; if (r == 0) - return mkdir_safe_internal(p, mode, uid, gid, false, _mkdir); + return mkdir_safe_internal(p, mode, uid, gid, + flags & ~MKDIR_FOLLOW_SYMLINK, + _mkdir); if (lstat(p, &st) < 0) return -errno; @@ -79,8 +82,8 @@ int mkdir_errno_wrapper(const char *pathname, mode_t mode) { return 0; } -int mkdir_safe(const char *path, mode_t mode, uid_t uid, gid_t gid, bool follow_symlink) { - return mkdir_safe_internal(path, mode, uid, gid, follow_symlink, mkdir_errno_wrapper); +int mkdir_safe(const char *path, mode_t mode, uid_t uid, gid_t gid, MkdirFlags flags) { + return mkdir_safe_internal(path, mode, uid, gid, flags, mkdir_errno_wrapper); } int mkdir_parents_internal(const char *prefix, const char *path, mode_t mode, mkdir_func_t _mkdir) { diff --git a/src/basic/mkdir.h b/src/basic/mkdir.h index 428cfb2a9..0f089bc72 100644 --- a/src/basic/mkdir.h +++ b/src/basic/mkdir.h @@ -23,13 +23,17 @@ #include +typedef enum MkdirFlags { + MKDIR_FOLLOW_SYMLINK = 1 << 0, +} MkdirFlags; + int mkdir_errno_wrapper(const char *pathname, mode_t mode); -int mkdir_safe(const char *path, mode_t mode, uid_t uid, gid_t gid, bool follow_symlink); +int mkdir_safe(const char *path, mode_t mode, uid_t uid, gid_t gid, MkdirFlags flags); int mkdir_parents(const char *path, mode_t mode); int mkdir_p(const char *path, mode_t mode); /* mandatory access control(MAC) versions */ -int mkdir_safe_label(const char *path, mode_t mode, uid_t uid, gid_t gid, bool follow_symlink); +int mkdir_safe_label(const char *path, mode_t mode, uid_t uid, gid_t gid, MkdirFlags flags); #if 0 /// UNNEEDED by elogind int mkdir_parents_label(const char *path, mode_t mode); #endif // 0 @@ -37,6 +41,6 @@ int mkdir_p_label(const char *path, mode_t mode); /* internally used */ typedef int (*mkdir_func_t)(const char *pathname, mode_t mode); -int mkdir_safe_internal(const char *path, mode_t mode, uid_t uid, gid_t gid, bool follow_symlink, mkdir_func_t _mkdir); +int mkdir_safe_internal(const char *path, mode_t mode, uid_t uid, gid_t gid, MkdirFlags flags, mkdir_func_t _mkdir); int mkdir_parents_internal(const char *prefix, const char *path, mode_t mode, mkdir_func_t _mkdir); int mkdir_p_internal(const char *prefix, const char *path, mode_t mode, mkdir_func_t _mkdir); diff --git a/src/login/logind-dbus.c b/src/login/logind-dbus.c index 00a6a1e7b..3da51259e 100644 --- a/src/login/logind-dbus.c +++ b/src/login/logind-dbus.c @@ -661,9 +661,10 @@ static int method_list_inhibitors(sd_bus_message *message, void *userdata, sd_bu static int method_create_session(sd_bus_message *message, void *userdata, sd_bus_error *error) { const char *service, *type, *class, *cseat, *tty, *display, *remote_user, *remote_host, *desktop; - _cleanup_free_ char *unit = NULL, *id = NULL; - Session *session = NULL; uint32_t audit_id = 0; + _cleanup_free_ char *unit = NULL; + _cleanup_free_ char *id = NULL; + Session *session = NULL; Manager *m = userdata; User *user = NULL; Seat *seat = NULL; @@ -687,7 +688,7 @@ static int method_create_session(sd_bus_message *message, void *userdata, sd_bus if (!uid_is_valid(uid)) return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid UID"); - if (leader < 0 || leader == 1 || leader == getpid_cached()) + if (leader < 0 || leader == 1) return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid leader PID"); if (isempty(type)) @@ -733,7 +734,7 @@ static int method_create_session(sd_bus_message *message, void *userdata, sd_bus if (v <= 0) return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Cannot determine VT number from virtual console TTY %s", tty); - if (vtnr == 0) + if (!vtnr) vtnr = (uint32_t) v; else if (vtnr != (uint32_t) v) return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Specified TTY and VT number do not match"); @@ -751,7 +752,7 @@ static int method_create_session(sd_bus_message *message, void *userdata, sd_bus if (seat) { if (seat_has_vts(seat)) { - if (vtnr <= 0 || vtnr > 63) + if (!vtnr || vtnr > 63) return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "VT number out of range"); } else { if (vtnr != 0) @@ -791,13 +792,16 @@ static int method_create_session(sd_bus_message *message, void *userdata, sd_bus return r; } - /* Check if we are already in a logind session. Or if we are in user@.service which is a special PAM session - * that avoids creating a logind session. */ - r = manager_get_user_by_pid(m, leader, NULL); + /* + * Check if we are already in a logind session. Or if we are in user@.service + * which is a special PAM session that avoids creating a logind session. + */ + r = cg_pid_get_unit(leader, &unit); if (r < 0) return r; - if (r > 0) - return sd_bus_error_setf(error, BUS_ERROR_SESSION_BUSY, "Already running in a session or user slice"); + if (hashmap_get(m->session_units, unit) || + hashmap_get(m->user_units, unit)) + return sd_bus_error_setf(error, BUS_ERROR_SESSION_BUSY, "Already running in a session"); /* * Old gdm and lightdm start the user-session on the same VT as @@ -831,8 +835,9 @@ static int method_create_session(sd_bus_message *message, void *userdata, sd_bus * the audit data and let's better register a new * ID */ if (hashmap_get(m->sessions, id)) { - log_warning("Existing logind session ID %s used by new audit session, ignoring.", id); + log_warning("Existing logind session ID %s used by new audit session, ignoring", id); audit_id = AUDIT_SESSION_INVALID; + id = mfree(id); } } @@ -925,7 +930,8 @@ static int method_create_session(sd_bus_message *message, void *userdata, sd_bus session->create_message = sd_bus_message_ref(message); #if 0 /// UNNEEDED by elogind - /* Now, let's wait until the slice unit and stuff got created. We send the reply back from + /* Now, let's wait until the slice unit and stuff got + * created. We send the reply back from * session_send_create_reply(). */ #else /* We reply directly. */ @@ -1233,7 +1239,7 @@ static int method_set_user_linger(sd_bus_message *message, void *userdata, sd_bu mkdir_p_label("/var/lib/elogind", 0755); - r = mkdir_safe_label("/var/lib/elogind/linger", 0755, 0, 0, false); + r = mkdir_safe_label("/var/lib/elogind/linger", 0755, 0, 0, 0); if (r < 0) return r; @@ -2078,7 +2084,7 @@ static int update_schedule_file(Manager *m) { assert(m); - r = mkdir_safe_label("/run/systemd/shutdown", 0755, 0, 0, false); + r = mkdir_safe_label("/run/systemd/shutdown", 0755, 0, 0, 0); if (r < 0) return log_error_errno(r, "Failed to create shutdown subdirectory: %m"); @@ -3247,8 +3253,13 @@ int manager_start_scope( return r; } - /* Make sure that the session shells are terminated with SIGHUP since bash and friends tend to ignore - * SIGTERM */ + /* cgroup empty notification is not available in containers + * currently. To make this less problematic, let's shorten the + * stop timeout for sessions, so that we don't wait + * forever. */ + + /* Make sure that the session shells are terminated with + * SIGHUP since bash and friends tend to ignore SIGTERM */ r = sd_bus_message_append(m, "(sv)", "SendSIGHUP", "b", true); if (r < 0) return r; diff --git a/src/login/logind-inhibit.c b/src/login/logind-inhibit.c index e14835292..0c84e5ed9 100644 --- a/src/login/logind-inhibit.c +++ b/src/login/logind-inhibit.c @@ -87,7 +87,7 @@ int inhibitor_save(Inhibitor *i) { assert(i); - r = mkdir_safe_label("/run/systemd/inhibit", 0755, 0, 0, false); + r = mkdir_safe_label("/run/systemd/inhibit", 0755, 0, 0, 0); if (r < 0) goto fail; @@ -291,7 +291,7 @@ int inhibitor_create_fifo(Inhibitor *i) { /* Create FIFO */ if (!i->fifo_path) { - r = mkdir_safe_label("/run/systemd/inhibit", 0755, 0, 0, false); + r = mkdir_safe_label("/run/systemd/inhibit", 0755, 0, 0, 0); if (r < 0) return r; diff --git a/src/login/logind-seat.c b/src/login/logind-seat.c index b109148e6..5cd9126b9 100644 --- a/src/login/logind-seat.c +++ b/src/login/logind-seat.c @@ -95,7 +95,7 @@ int seat_save(Seat *s) { if (!s->started) return 0; - r = mkdir_safe_label("/run/systemd/seats", 0755, 0, 0, false); + r = mkdir_safe_label("/run/systemd/seats", 0755, 0, 0, 0); if (r < 0) goto fail; @@ -566,7 +566,8 @@ void seat_complete_switch(Seat *s) { if (!s->pending_switch) return; - session = TAKE_PTR(s->pending_switch); + session = s->pending_switch; + s->pending_switch = NULL; seat_set_active(s, session); } diff --git a/src/login/logind-session.c b/src/login/logind-session.c index b03a89bba..fdf22f315 100644 --- a/src/login/logind-session.c +++ b/src/login/logind-session.c @@ -185,7 +185,7 @@ int session_save(Session *s) { if (!s->started) return 0; - r = mkdir_safe_label("/run/systemd/sessions", 0755, 0, 0, false); + r = mkdir_safe_label("/run/systemd/sessions", 0755, 0, 0, 0); if (r < 0) goto fail; @@ -992,6 +992,7 @@ int session_create_fifo(Session *s) { /* Create FIFO */ if (!s->fifo_path) { r = mkdir_safe_label("/run/systemd/sessions", 0755, 0, 0, false); + r = mkdir_safe_label("/run/systemd/sessions", 0755, 0, 0, 0); if (r < 0) return r; diff --git a/src/login/logind-user.c b/src/login/logind-user.c index 86bb49406..daa4ab6a7 100644 --- a/src/login/logind-user.c +++ b/src/login/logind-user.c @@ -145,7 +145,7 @@ static int user_save_internal(User *u) { assert(u); assert(u->state_file); - r = mkdir_safe_label("/run/systemd/users", 0755, 0, 0, false); + r = mkdir_safe_label("/run/systemd/users", 0755, 0, 0, 0); if (r < 0) goto fail; @@ -343,7 +343,7 @@ static int user_mkdir_runtime_path(User *u) { assert(u); - r = mkdir_safe_label("/run/user", 0755, 0, 0, false); + r = mkdir_safe_label("/run/user", 0755, 0, 0, 0); if (r < 0) return log_error_errno(r, "Failed to create /run/user: %m"); diff --git a/src/test/test-fs-util.c b/src/test/test-fs-util.c index 62a3f1622..6fd756752 100644 --- a/src/test/test-fs-util.c +++ b/src/test/test-fs-util.c @@ -317,7 +317,7 @@ static void test_readlink_and_make_absolute(void) { char *r = NULL; _cleanup_free_ char *pwd = NULL; - assert_se(mkdir_safe(tempdir, 0755, getuid(), getgid(), false) >= 0); + assert_se(mkdir_safe(tempdir, 0755, getuid(), getgid(), 0) >= 0); assert_se(touch(name) >= 0); assert_se(symlink(name, name_alias) >= 0); -- 2.30.2