summaryrefslogtreecommitdiff
path: root/src/uaccess-command
diff options
context:
space:
mode:
authorArthur Taylor <art@ified.ca>2018-02-08 15:03:50 -0800
committerSven Eden <yamakuzure@gmx.net>2018-03-07 16:49:51 +0100
commit316e8d849fc1d34b61d27f2967e0ede84fe9f46d (patch)
tree29fe77b20e1d5ab44fbaf5771fee9b38110c2d6e /src/uaccess-command
parent6cb78f13ff944c725eb5b0b95fae34308e629057 (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.c98
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);
+}