udev-builtin-uaccess.c revision 79d860fe78ff9e53fe3150fb55a8a8b03c4f6470
83cd6b754b270091840456a2c8a66dae19f5a7dcKay Sievers/*
83cd6b754b270091840456a2c8a66dae19f5a7dcKay Sievers * manage device node user ACL
83cd6b754b270091840456a2c8a66dae19f5a7dcKay Sievers *
83cd6b754b270091840456a2c8a66dae19f5a7dcKay Sievers * Copyright 2010-2012 Kay Sievers <kay@vrfy.org>
83cd6b754b270091840456a2c8a66dae19f5a7dcKay Sievers * Copyright 2010 Lennart Poettering
83cd6b754b270091840456a2c8a66dae19f5a7dcKay Sievers *
83cd6b754b270091840456a2c8a66dae19f5a7dcKay Sievers * This program is free software: you can redistribute it and/or modify
83cd6b754b270091840456a2c8a66dae19f5a7dcKay Sievers * it under the terms of the GNU General Public License as published by
83cd6b754b270091840456a2c8a66dae19f5a7dcKay Sievers * the Free Software Foundation, either version 2 of the License, or
83cd6b754b270091840456a2c8a66dae19f5a7dcKay Sievers * (at your option) any later version.
83cd6b754b270091840456a2c8a66dae19f5a7dcKay Sievers *
83cd6b754b270091840456a2c8a66dae19f5a7dcKay Sievers * This program is distributed in the hope that it will be useful,
83cd6b754b270091840456a2c8a66dae19f5a7dcKay Sievers * but WITHOUT ANY WARRANTY; without even the implied warranty of
83cd6b754b270091840456a2c8a66dae19f5a7dcKay Sievers * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
83cd6b754b270091840456a2c8a66dae19f5a7dcKay Sievers * GNU General Public License for more details.
83cd6b754b270091840456a2c8a66dae19f5a7dcKay Sievers *
83cd6b754b270091840456a2c8a66dae19f5a7dcKay Sievers * You should have received a copy of the GNU General Public License
83cd6b754b270091840456a2c8a66dae19f5a7dcKay Sievers * along with this program. If not, see <http://www.gnu.org/licenses/>.
83cd6b754b270091840456a2c8a66dae19f5a7dcKay Sievers */
83cd6b754b270091840456a2c8a66dae19f5a7dcKay Sievers
83cd6b754b270091840456a2c8a66dae19f5a7dcKay Sievers#include <stdio.h>
83cd6b754b270091840456a2c8a66dae19f5a7dcKay Sievers#include <stdlib.h>
83cd6b754b270091840456a2c8a66dae19f5a7dcKay Sievers#include <stdarg.h>
83cd6b754b270091840456a2c8a66dae19f5a7dcKay Sievers#include <unistd.h>
83cd6b754b270091840456a2c8a66dae19f5a7dcKay Sievers#include <string.h>
83cd6b754b270091840456a2c8a66dae19f5a7dcKay Sievers#include <ctype.h>
83cd6b754b270091840456a2c8a66dae19f5a7dcKay Sievers#include <fcntl.h>
83cd6b754b270091840456a2c8a66dae19f5a7dcKay Sievers#include <errno.h>
83cd6b754b270091840456a2c8a66dae19f5a7dcKay Sievers#include <dirent.h>
83cd6b754b270091840456a2c8a66dae19f5a7dcKay Sievers#include <getopt.h>
83cd6b754b270091840456a2c8a66dae19f5a7dcKay Sievers
83cd6b754b270091840456a2c8a66dae19f5a7dcKay Sievers#include <systemd/sd-login.h>
83cd6b754b270091840456a2c8a66dae19f5a7dcKay Sievers#include "logind-acl.h"
83cd6b754b270091840456a2c8a66dae19f5a7dcKay Sievers#include "udev.h"
83cd6b754b270091840456a2c8a66dae19f5a7dcKay Sievers#include "util.h"
83cd6b754b270091840456a2c8a66dae19f5a7dcKay Sievers
83cd6b754b270091840456a2c8a66dae19f5a7dcKay Sieversstatic int builtin_uaccess(struct udev_device *dev, int argc, char *argv[], bool test)
83cd6b754b270091840456a2c8a66dae19f5a7dcKay Sievers{
83cd6b754b270091840456a2c8a66dae19f5a7dcKay Sievers int r;
83cd6b754b270091840456a2c8a66dae19f5a7dcKay Sievers const char *path = NULL, *seat;
83cd6b754b270091840456a2c8a66dae19f5a7dcKay Sievers bool changed_acl = false;
83cd6b754b270091840456a2c8a66dae19f5a7dcKay Sievers uid_t uid;
83cd6b754b270091840456a2c8a66dae19f5a7dcKay Sievers
83cd6b754b270091840456a2c8a66dae19f5a7dcKay Sievers log_set_target(LOG_TARGET_AUTO);
83cd6b754b270091840456a2c8a66dae19f5a7dcKay Sievers log_parse_environment();
83cd6b754b270091840456a2c8a66dae19f5a7dcKay Sievers log_open();
83cd6b754b270091840456a2c8a66dae19f5a7dcKay Sievers
83cd6b754b270091840456a2c8a66dae19f5a7dcKay Sievers umask(0022);
83cd6b754b270091840456a2c8a66dae19f5a7dcKay Sievers
83cd6b754b270091840456a2c8a66dae19f5a7dcKay Sievers /* don't muck around with ACLs when the system is not running systemd */
79d860fe78ff9e53fe3150fb55a8a8b03c4f6470Martin Pitt if (!logind_running())
83cd6b754b270091840456a2c8a66dae19f5a7dcKay Sievers return 0;
83cd6b754b270091840456a2c8a66dae19f5a7dcKay Sievers
83cd6b754b270091840456a2c8a66dae19f5a7dcKay Sievers path = udev_device_get_devnode(dev);
83cd6b754b270091840456a2c8a66dae19f5a7dcKay Sievers seat = udev_device_get_property_value(dev, "ID_SEAT");
83cd6b754b270091840456a2c8a66dae19f5a7dcKay Sievers if (!seat)
83cd6b754b270091840456a2c8a66dae19f5a7dcKay Sievers seat = "seat0";
83cd6b754b270091840456a2c8a66dae19f5a7dcKay Sievers
83cd6b754b270091840456a2c8a66dae19f5a7dcKay Sievers r = sd_seat_get_active(seat, NULL, &uid);
83cd6b754b270091840456a2c8a66dae19f5a7dcKay Sievers if (r == -ENOENT) {
83cd6b754b270091840456a2c8a66dae19f5a7dcKay Sievers /* No active session on this seat */
83cd6b754b270091840456a2c8a66dae19f5a7dcKay Sievers r = 0;
83cd6b754b270091840456a2c8a66dae19f5a7dcKay Sievers goto finish;
83cd6b754b270091840456a2c8a66dae19f5a7dcKay Sievers } else if (r < 0) {
83cd6b754b270091840456a2c8a66dae19f5a7dcKay Sievers log_error("Failed to determine active user on seat %s.", seat);
83cd6b754b270091840456a2c8a66dae19f5a7dcKay Sievers goto finish;
83cd6b754b270091840456a2c8a66dae19f5a7dcKay Sievers }
83cd6b754b270091840456a2c8a66dae19f5a7dcKay Sievers
83cd6b754b270091840456a2c8a66dae19f5a7dcKay Sievers r = devnode_acl(path, true, false, 0, true, uid);
83cd6b754b270091840456a2c8a66dae19f5a7dcKay Sievers if (r < 0) {
83cd6b754b270091840456a2c8a66dae19f5a7dcKay Sievers log_error("Failed to apply ACL on %s: %s", path, strerror(-r));
83cd6b754b270091840456a2c8a66dae19f5a7dcKay Sievers goto finish;
83cd6b754b270091840456a2c8a66dae19f5a7dcKay Sievers }
83cd6b754b270091840456a2c8a66dae19f5a7dcKay Sievers
83cd6b754b270091840456a2c8a66dae19f5a7dcKay Sievers changed_acl = true;
83cd6b754b270091840456a2c8a66dae19f5a7dcKay Sievers r = 0;
83cd6b754b270091840456a2c8a66dae19f5a7dcKay Sievers
83cd6b754b270091840456a2c8a66dae19f5a7dcKay Sieversfinish:
83cd6b754b270091840456a2c8a66dae19f5a7dcKay Sievers if (path && !changed_acl) {
83cd6b754b270091840456a2c8a66dae19f5a7dcKay Sievers int k;
83cd6b754b270091840456a2c8a66dae19f5a7dcKay Sievers
83cd6b754b270091840456a2c8a66dae19f5a7dcKay Sievers /* Better be safe than sorry and reset ACL */
83cd6b754b270091840456a2c8a66dae19f5a7dcKay Sievers k = devnode_acl(path, true, false, 0, false, 0);
83cd6b754b270091840456a2c8a66dae19f5a7dcKay Sievers if (k < 0) {
83cd6b754b270091840456a2c8a66dae19f5a7dcKay Sievers log_error("Failed to apply ACL on %s: %s", path, strerror(-k));
83cd6b754b270091840456a2c8a66dae19f5a7dcKay Sievers if (r >= 0)
83cd6b754b270091840456a2c8a66dae19f5a7dcKay Sievers r = k;
83cd6b754b270091840456a2c8a66dae19f5a7dcKay Sievers }
83cd6b754b270091840456a2c8a66dae19f5a7dcKay Sievers }
83cd6b754b270091840456a2c8a66dae19f5a7dcKay Sievers
83cd6b754b270091840456a2c8a66dae19f5a7dcKay Sievers return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
83cd6b754b270091840456a2c8a66dae19f5a7dcKay Sievers}
83cd6b754b270091840456a2c8a66dae19f5a7dcKay Sievers
83cd6b754b270091840456a2c8a66dae19f5a7dcKay Sieversconst struct udev_builtin udev_builtin_uaccess = {
83cd6b754b270091840456a2c8a66dae19f5a7dcKay Sievers .name = "uaccess",
83cd6b754b270091840456a2c8a66dae19f5a7dcKay Sievers .cmd = builtin_uaccess,
83cd6b754b270091840456a2c8a66dae19f5a7dcKay Sievers .help = "manage device node user ACL",
83cd6b754b270091840456a2c8a66dae19f5a7dcKay Sievers};