diff options
author | Arthur Taylor <art@ified.ca> | 2018-02-08 15:03:50 -0800 |
---|---|---|
committer | Sven Eden <yamakuzure@gmx.net> | 2018-03-07 16:49:51 +0100 |
commit | 316e8d849fc1d34b61d27f2967e0ede84fe9f46d (patch) | |
tree | 29fe77b20e1d5ab44fbaf5771fee9b38110c2d6e /src/uaccess-command | |
parent | 6cb78f13ff944c725eb5b0b95fae34308e629057 (diff) |
Introduce elogind-uaccess-command to replace uaccess builtin.
The uaccess udev builtin command is only used by logind and contains
functionality only implemented in logind. As such, while we cannot
write udev-builtin commands in elogind (not being udev), we can write
standalone binaries and rewrite our udev rules to use them instead.
This fixes the feature of granting users access to devices using a user
ACL which is toggled only when the user is associated with an active
session. Currently this functionality is half broken, as while the ACL
is granted and revoked while VT-switching, it is not granted to new
devices as they are plugged in. This issue is fixed by this commit.
Diffstat (limited to 'src/uaccess-command')
-rw-r--r-- | src/uaccess-command/uaccess-command.c | 98 |
1 files changed, 98 insertions, 0 deletions
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); +} |