diff options
-rw-r--r-- | meson.build | 13 | ||||
-rw-r--r-- | src/basic/login-util.h | 2 | ||||
-rw-r--r-- | src/login/73-seat-late.rules.in | 2 | ||||
-rw-r--r-- | src/uaccess-command/uaccess-command.c | 98 |
4 files changed, 112 insertions, 3 deletions
diff --git a/meson.build b/meson.build index f47def257..469c2b9bc 100644 --- a/meson.build +++ b/meson.build @@ -205,6 +205,7 @@ conf.set_quoted('SYSTEM_CONFIG_UNIT_PATH', join_paths(pkgsysc # conf.set_quoted('SYSTEMD_STDIO_BRIDGE_BINARY_PATH', join_paths(bindir, 'systemd-stdio-bridge')) #else conf.set_quoted('SYSTEMD_CGROUP_AGENT_PATH', join_paths(rootlibexecdir, 'elogind-cgroups-agent')) +conf.set_quoted('ELOGIND_UACCESS_COMMAND_PATH', join_paths(rootlibexecdir, 'elogind-uaccess-command')) conf.set_quoted('SYSTEMD_BINARY_PATH', join_paths(rootlibexecdir, 'elogind')) #endif // 0 conf.set_quoted('ROOTPREFIX', rootprefixdir) @@ -2519,6 +2520,18 @@ executable('elogind-cgroups-agent', # public_programs += [exe] # endif #endif // 0 + +executable('elogind-uaccess-command', + 'src/uaccess-command/uaccess-command.c', + include_directories : includes, + link_with : [liblogind_core, + libshared_static], + dependencies: [libacl, + libudev], + install_rpath : rootlibexecdir, + install : true, + install_dir : rootlibexecdir) + ############################################################ foreach tuple : tests diff --git a/src/basic/login-util.h b/src/basic/login-util.h index a71ebd4ef..b01ee25c8 100644 --- a/src/basic/login-util.h +++ b/src/basic/login-util.h @@ -24,8 +24,6 @@ bool session_id_valid(const char *id); -#if 0 /// UNNEEDED by elogind static inline bool logind_running(void) { return access("/run/systemd/seats/", F_OK) >= 0; } -#endif // 0 diff --git a/src/login/73-seat-late.rules.in b/src/login/73-seat-late.rules.in index 901df750f..a44976b6d 100644 --- a/src/login/73-seat-late.rules.in +++ b/src/login/73-seat-late.rules.in @@ -12,6 +12,6 @@ ENV{ID_SEAT}=="", IMPORT{parent}="ID_SEAT" ENV{ID_SEAT}!="", TAG+="$env{ID_SEAT}" -TAG=="uaccess", ENV{MAJOR}!="", RUN{builtin}+="uaccess" +TAG=="uaccess", ENV{MAJOR}!="", RUN{program}+="@rootlibexecdir@/elogind-uaccess-command %N $env{ID_SEAT}" LABEL="seat_late_end" diff --git a/src/uaccess-command/uaccess-command.c b/src/uaccess-command/uaccess-command.c new file mode 100644 index 000000000..efb9dcd62 --- /dev/null +++ b/src/uaccess-command/uaccess-command.c @@ -0,0 +1,98 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * manage device node user ACL + * + * Copyright 2010-2012 Kay Sievers <kay@vrfy.org> + * Copyright 2010 Lennart Poettering + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <errno.h> +#include <stdio.h> +#include <stdlib.h> + +#include "sd-login.h" + +#include "login-util.h" +#include "logind-acl.h" +#include "util.h" + +/* + * Copy of builtin_uaccess() from + * systemd/src/udev/udev-builtin-uaccess.c + */ +static int dev_uaccess(const char *path, const char *seat) { + int r; + bool changed_acl = false; + uid_t uid; + + umask(0022); + + /* don't muck around with ACLs when the system is not running systemd */ + if (!logind_running()) + return 0; + + if (!seat || !strlen(seat)) + seat = "seat0"; + + r = sd_seat_get_active(seat, NULL, &uid); + if (IN_SET(r, -ENXIO, -ENODATA)) { + /* No active session on this seat */ + r = 0; + goto finish; + } else if (r < 0) { + log_error("Failed to determine active user on seat %s.", seat); + goto finish; + } + + r = devnode_acl(path, true, false, 0, true, uid); + if (r < 0) { + log_full_errno(r == -ENOENT ? LOG_DEBUG : LOG_ERR, r, "Failed to apply ACL on %s: %m", path); + goto finish; + } + + changed_acl = true; + r = 0; + +finish: + if (path && !changed_acl) { + int k; + + /* Better be safe than sorry and reset ACL */ + k = devnode_acl(path, true, false, 0, false, 0); + if (k < 0) { + log_full_errno(errno == ENOENT ? LOG_DEBUG : LOG_ERR, k, "Failed to apply ACL on %s: %m", path); + if (r >= 0) + r = k; + } + } + + return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS; +} + +int main(int argc, char *argv[]) { + + if (argc < 2) { + printf("Usage: %s DEVPATH [SEAT]\n", argv[0]); + return 0; + } + + elogind_set_program_name(argv[0]); + log_set_target(LOG_TARGET_AUTO); + log_parse_environment(); + log_open(); + + return dev_uaccess(argv[1], argc > 2 ? argv[2] : NULL); +} |