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