mirror of
https://github.com/systemd/systemd.git
synced 2024-11-30 13:53:39 +08:00
udev: convert 'uaccess' to a builtin
This commit is contained in:
parent
f1ff47be17
commit
83cd6b754b
45
Makefile.am
45
Makefile.am
@ -1271,7 +1271,9 @@ udev_common_sources = \
|
||||
src/udev/udev-builtin-input_id.c \
|
||||
src/udev/udev-builtin-kmod.c \
|
||||
src/udev/udev-builtin-path_id.c \
|
||||
src/udev/udev-builtin-usb_id.c
|
||||
src/udev/udev-builtin-usb_id.c \
|
||||
src/systemd/sd-daemon.h \
|
||||
src/sd-daemon.c
|
||||
|
||||
udev_common_CFLAGS = \
|
||||
$(BLKID_CFLAGS) \
|
||||
@ -1287,11 +1289,23 @@ udev_common_CPPFLAGS = \
|
||||
-DFIRMWARE_PATH="$(FIRMWARE_PATH)" \
|
||||
-DUSB_DATABASE=\"$(USB_DATABASE)\" -DPCI_DATABASE=\"$(PCI_DATABASE)\"
|
||||
|
||||
if HAVE_ACL
|
||||
udev_common_sources += \
|
||||
src/udev/udev-builtin-uaccess.c \
|
||||
src/login/logind-acl.c \
|
||||
src/acl-util.c
|
||||
|
||||
udev_common_CFLAGS += \
|
||||
$(ACL_CFLAGS)
|
||||
|
||||
udev_common_LDADD += \
|
||||
libsystemd-login.la \
|
||||
$(ACL_LIBS)
|
||||
endif
|
||||
|
||||
udevd_SOURCES = \
|
||||
$(udev_common_sources) \
|
||||
src/udev/udevd.c \
|
||||
src/systemd/sd-daemon.h \
|
||||
src/sd-daemon.c
|
||||
src/udev/udevd.c
|
||||
|
||||
udevd_CFLAGS = \
|
||||
$(udev_common_CFLAGS)
|
||||
@ -2597,29 +2611,6 @@ systemd_multi_seat_x_LDADD = \
|
||||
rootlibexec_PROGRAMS += \
|
||||
systemd-multi-seat-x
|
||||
|
||||
systemd_uaccess_SOURCES = \
|
||||
src/login/uaccess.c
|
||||
|
||||
if HAVE_ACL
|
||||
systemd_uaccess_SOURCES += \
|
||||
src/login/logind-acl.c \
|
||||
src/acl-util.c
|
||||
endif
|
||||
|
||||
systemd_uaccess_CFLAGS = \
|
||||
$(AM_CFLAGS) \
|
||||
$(ACL_CFLAGS)
|
||||
|
||||
systemd_uaccess_LDADD = \
|
||||
libsystemd-basic.la \
|
||||
libsystemd-daemon.la \
|
||||
libsystemd-login.la \
|
||||
libudev.la \
|
||||
$(ACL_LIBS)
|
||||
|
||||
rootlibexec_PROGRAMS += \
|
||||
systemd-uaccess
|
||||
|
||||
dist_udevrules_DATA += \
|
||||
src/login/70-uaccess.rules
|
||||
|
||||
|
@ -7,6 +7,6 @@ SUBSYSTEM=="tifm", ENV{TIFM_CARD_TYPE}=="SD", IMPORT{builtin}="kmod load tifm_sd
|
||||
SUBSYSTEM=="tifm", ENV{TIFM_CARD_TYPE}=="MS", IMPORT{builtin}="kmod load tifm_ms"
|
||||
SUBSYSTEM=="memstick", IMPORT{builtin}="kmod load ms_block mspro_block"
|
||||
SUBSYSTEM=="i2o", IMPORT{builtin}="kmod load i2o_block"
|
||||
SUBSYSTEM=="module", KERNEL=="parport_pc", IMPORT{builtin}="kmod load ppdev"
|
||||
SUBSYSTEM=="module", KERNEL=="parport_pc", RUN{builtin}="kmod load ppdev"
|
||||
|
||||
LABEL="drivers_end"
|
||||
|
@ -9,7 +9,7 @@ ACTION=="remove", GOTO="uaccess_end"
|
||||
ENV{MAJOR}=="", GOTO="uaccess_end"
|
||||
|
||||
# PTP/MTP protocol devices, cameras, portable media players
|
||||
SUBSYSTEM=="usb", ENV{ID_USB_INTERFACES}=="", ENV{DEVTYPE}=="usb_device", IMPORT{program}="usb_id --export %p"
|
||||
SUBSYSTEM=="usb", ENV{ID_USB_INTERFACES}=="", ENV{DEVTYPE}=="usb_device", IMPORT{builtin}="usb_id"
|
||||
SUBSYSTEM=="usb", ENV{ID_USB_INTERFACES}=="*:060101:*", TAG+="uaccess"
|
||||
|
||||
# Digicams with proprietary protocol
|
||||
|
@ -12,6 +12,6 @@ ENV{ID_SEAT}=="", IMPORT{parent}="ID_SEAT"
|
||||
|
||||
ENV{ID_SEAT}!="", TAG+="$env{ID_SEAT}"
|
||||
|
||||
TAG=="uaccess", ENV{MAJOR}!="", RUN+="@rootlibexecdir@/systemd-uaccess $env{DEVNAME} $env{ID_SEAT}"
|
||||
TAG=="uaccess", ENV{MAJOR}!="", RUN{builtin}+="uaccess"
|
||||
|
||||
LABEL="seat_late_end"
|
||||
|
@ -88,7 +88,7 @@ int main(int argc, char *argv[])
|
||||
|
||||
/* do what devtmpfs usually provides us */
|
||||
if (udev_device_get_devnode(dev) != NULL) {
|
||||
mode_t mode;
|
||||
mode_t mode = 0600;
|
||||
|
||||
if (strcmp(udev_device_get_subsystem(dev), "block") == 0)
|
||||
mode |= S_IFBLK;
|
||||
|
@ -28,7 +28,7 @@ if len(sys.argv) < 2:
|
||||
no_args_tests = re.compile('(ACTION|DEVPATH|KERNELS?|NAME|SYMLINK|SUBSYSTEMS?|DRIVERS?|TAG|RESULT|TEST)\s*(?:=|!)=\s*"([^"]*)"$')
|
||||
args_tests = re.compile('(ATTRS?|ENV|TEST){([a-zA-Z0-9/_.*%-]+)}\s*(?:=|!)=\s*"([^"]*)"$')
|
||||
no_args_assign = re.compile('(NAME|SYMLINK|OWNER|GROUP|MODE|TAG|PROGRAM|RUN|LABEL|GOTO|WAIT_FOR|OPTIONS|IMPORT)\s*(?:\+=|:=|=)\s*"([^"]*)"$')
|
||||
args_assign = re.compile('(ATTR|ENV|IMPORT){([a-zA-Z0-9/_.*%-]+)}\s*=\s*"([^"]*)"$')
|
||||
args_assign = re.compile('(ATTR|ENV|IMPORT|RUN){([a-zA-Z0-9/_.*%-]+)}\s*=\s*"([^"]*)"$')
|
||||
|
||||
result = 0
|
||||
buffer = ''
|
||||
|
@ -21,8 +21,8 @@ use warnings;
|
||||
use strict;
|
||||
|
||||
my $PWD = $ENV{PWD};
|
||||
my $sysfs = "test/sys";
|
||||
my $udev_bin = "./test-udev";
|
||||
my $sysfs = "src/udev/test/sys";
|
||||
my $udev_bin = ".libs/test-udev";
|
||||
my $valgrind = 0;
|
||||
my $udev_bin_valgrind = "valgrind --tool=memcheck --leak-check=yes --quiet $udev_bin";
|
||||
my $udev_root = "udev-root";
|
||||
@ -1347,7 +1347,7 @@ sub udev {
|
||||
if ($valgrind > 0) {
|
||||
system("$udev_bin_valgrind $action $devpath");
|
||||
} else {
|
||||
system("$udev_bin $action $devpath");
|
||||
system("$udev_bin", "$action", "$devpath");
|
||||
}
|
||||
}
|
||||
|
||||
|
99
src/udev/udev-builtin-uaccess.c
Normal file
99
src/udev/udev-builtin-uaccess.c
Normal file
@ -0,0 +1,99 @@
|
||||
/*
|
||||
* 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 <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <dirent.h>
|
||||
#include <getopt.h>
|
||||
|
||||
#include <systemd/sd-daemon.h>
|
||||
#include <systemd/sd-login.h>
|
||||
#include "logind-acl.h"
|
||||
#include "udev.h"
|
||||
#include "util.h"
|
||||
|
||||
static int builtin_uaccess(struct udev_device *dev, int argc, char *argv[], bool test)
|
||||
{
|
||||
int r;
|
||||
const char *path = NULL, *seat;
|
||||
bool changed_acl = false;
|
||||
uid_t uid;
|
||||
|
||||
log_set_target(LOG_TARGET_AUTO);
|
||||
log_parse_environment();
|
||||
log_open();
|
||||
|
||||
umask(0022);
|
||||
|
||||
/* don't muck around with ACLs when the system is not running systemd */
|
||||
if (!sd_booted())
|
||||
return 0;
|
||||
|
||||
path = udev_device_get_devnode(dev);
|
||||
seat = udev_device_get_property_value(dev, "ID_SEAT");
|
||||
if (!seat)
|
||||
seat = "seat0";
|
||||
|
||||
r = sd_seat_get_active(seat, NULL, &uid);
|
||||
if (r == -ENOENT) {
|
||||
/* 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_error("Failed to apply ACL on %s: %s", path, strerror(-r));
|
||||
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_error("Failed to apply ACL on %s: %s", path, strerror(-k));
|
||||
if (r >= 0)
|
||||
r = k;
|
||||
}
|
||||
}
|
||||
|
||||
return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
const struct udev_builtin udev_builtin_uaccess = {
|
||||
.name = "uaccess",
|
||||
.cmd = builtin_uaccess,
|
||||
.help = "manage device node user ACL",
|
||||
};
|
@ -34,6 +34,9 @@ static const struct udev_builtin *builtins[] = {
|
||||
[UDEV_BUILTIN_PCI_DB] = &udev_builtin_pci_db,
|
||||
[UDEV_BUILTIN_USB_DB] = &udev_builtin_usb_db,
|
||||
[UDEV_BUILTIN_USB_ID] = &udev_builtin_usb_id,
|
||||
#ifdef HAVE_ACL
|
||||
[UDEV_BUILTIN_UACCESS] = &udev_builtin_uaccess,
|
||||
#endif
|
||||
};
|
||||
|
||||
int udev_builtin_init(struct udev *udev)
|
||||
|
@ -943,15 +943,20 @@ out:
|
||||
return err;
|
||||
}
|
||||
|
||||
int udev_event_execute_run(struct udev_event *event, const sigset_t *sigmask)
|
||||
void udev_event_execute_run(struct udev_event *event, const sigset_t *sigmask)
|
||||
{
|
||||
struct udev_list_entry *list_entry;
|
||||
int err = 0;
|
||||
|
||||
udev_list_entry_foreach(list_entry, udev_list_get_entry(&event->run_list)) {
|
||||
const char *cmd = udev_list_entry_get_name(list_entry);
|
||||
enum udev_builtin_cmd builtin_cmd = udev_list_entry_get_num(list_entry);
|
||||
|
||||
if (strncmp(cmd, "socket:", strlen("socket:")) == 0) {
|
||||
if (builtin_cmd < UDEV_BUILTIN_MAX) {
|
||||
char command[UTIL_PATH_SIZE];
|
||||
|
||||
udev_event_apply_format(event, cmd, command, sizeof(command));
|
||||
udev_builtin_run(event->dev, builtin_cmd, command, false);
|
||||
} else if (strncmp(cmd, "socket:", strlen("socket:")) == 0) {
|
||||
struct udev_monitor *monitor;
|
||||
|
||||
monitor = udev_monitor_new_from_socket(event->udev, &cmd[strlen("socket:")]);
|
||||
@ -970,11 +975,7 @@ int udev_event_execute_run(struct udev_event *event, const sigset_t *sigmask)
|
||||
|
||||
udev_event_apply_format(event, cmd, program, sizeof(program));
|
||||
envp = udev_device_get_properties_envp(event->dev);
|
||||
if (udev_event_spawn(event, program, envp, sigmask, NULL, 0) < 0) {
|
||||
if (udev_list_entry_get_num(list_entry))
|
||||
err = -1;
|
||||
}
|
||||
udev_event_spawn(event, program, envp, sigmask, NULL, 0);
|
||||
}
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
@ -168,7 +168,8 @@ enum token_type {
|
||||
TK_A_NAME, /* val */
|
||||
TK_A_DEVLINK, /* val */
|
||||
TK_A_ATTR, /* val, attr */
|
||||
TK_A_RUN, /* val, bool */
|
||||
TK_A_RUN_BUILTIN, /* val, bool */
|
||||
TK_A_RUN_PROGRAM, /* val, bool */
|
||||
TK_A_GOTO, /* size_t */
|
||||
|
||||
TK_END,
|
||||
@ -305,7 +306,8 @@ static const char *token_str(enum token_type type)
|
||||
[TK_A_NAME] = "A NAME",
|
||||
[TK_A_DEVLINK] = "A DEVLINK",
|
||||
[TK_A_ATTR] = "A ATTR",
|
||||
[TK_A_RUN] = "A RUN",
|
||||
[TK_A_RUN_BUILTIN] = "A RUN_BUILTIN",
|
||||
[TK_A_RUN_PROGRAM] = "A RUN_PROGRAM",
|
||||
[TK_A_GOTO] = "A GOTO",
|
||||
|
||||
[TK_END] = "END",
|
||||
@ -359,7 +361,8 @@ static void dump_token(struct udev_rules *rules, struct token *token)
|
||||
case TK_A_OWNER:
|
||||
case TK_A_GROUP:
|
||||
case TK_A_MODE:
|
||||
case TK_A_RUN:
|
||||
case TK_A_RUN_BUILTIN:
|
||||
case TK_A_RUN_PROGRAM:
|
||||
log_debug("%s %s '%s'(%s)\n",
|
||||
token_str(type), operation_str(op), value, string_glob_str(glob));
|
||||
break;
|
||||
@ -1049,7 +1052,9 @@ static int rule_add_key(struct rule_tmp *rule_tmp, enum token_type type,
|
||||
case TK_A_STRING_ESCAPE_REPLACE:
|
||||
case TK_A_DB_PERSIST:
|
||||
break;
|
||||
case TK_A_RUN:
|
||||
case TK_A_RUN_BUILTIN:
|
||||
token->key.builtin_cmd = *(enum udev_builtin_cmd *)data;
|
||||
case TK_A_RUN_PROGRAM:
|
||||
token->key.value_off = add_string(rule_tmp->rules, value);
|
||||
break;
|
||||
case TK_A_INOTIFY_WATCH:
|
||||
@ -1379,7 +1384,7 @@ static int add_rule(struct udev_rules *rules, char *line,
|
||||
log_error("IMPORT{} type missing, ignoring IMPORT %s:%u\n", filename, lineno);
|
||||
continue;
|
||||
}
|
||||
if (strstr(attr, "program")) {
|
||||
if (strcmp(attr, "program") == 0) {
|
||||
/* find known built-in command */
|
||||
if (value[0] != '/') {
|
||||
enum udev_builtin_cmd cmd;
|
||||
@ -1393,22 +1398,23 @@ static int add_rule(struct udev_rules *rules, char *line,
|
||||
}
|
||||
}
|
||||
rule_add_key(&rule_tmp, TK_M_IMPORT_PROG, op, value, NULL);
|
||||
} else if (strstr(attr, "builtin")) {
|
||||
} else if (strcmp(attr, "builtin") == 0) {
|
||||
enum udev_builtin_cmd cmd = udev_builtin_lookup(value);
|
||||
|
||||
if (cmd < UDEV_BUILTIN_MAX)
|
||||
rule_add_key(&rule_tmp, TK_M_IMPORT_BUILTIN, op, value, &cmd);
|
||||
else
|
||||
log_error("IMPORT{builtin}: '%s' unknown %s:%u\n", value, filename, lineno);
|
||||
} else if (strstr(attr, "file")) {
|
||||
} else if (strcmp(attr, "file") == 0) {
|
||||
rule_add_key(&rule_tmp, TK_M_IMPORT_FILE, op, value, NULL);
|
||||
} else if (strstr(attr, "db")) {
|
||||
} else if (strcmp(attr, "db") == 0) {
|
||||
rule_add_key(&rule_tmp, TK_M_IMPORT_DB, op, value, NULL);
|
||||
} else if (strstr(attr, "cmdline")) {
|
||||
} else if (strcmp(attr, "cmdline") == 0) {
|
||||
rule_add_key(&rule_tmp, TK_M_IMPORT_CMDLINE, op, value, NULL);
|
||||
} else if (strstr(attr, "parent")) {
|
||||
} else if (strcmp(attr, "parent") == 0) {
|
||||
rule_add_key(&rule_tmp, TK_M_IMPORT_PARENT, op, value, NULL);
|
||||
}
|
||||
} else
|
||||
log_error("IMPORT{} unknown type, ignoring IMPORT %s:%u\n", filename, lineno);
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -1429,11 +1435,29 @@ static int add_rule(struct udev_rules *rules, char *line,
|
||||
continue;
|
||||
}
|
||||
|
||||
if (strcmp(key, "RUN") == 0) {
|
||||
if (strncmp(value, "socket:", 7) == 0)
|
||||
log_error("RUN+=\"socket:...\" support will be removed from a future udev release. "
|
||||
"Please remove it from: %s:%u and use libudev to subscribe to events.\n", filename, lineno);
|
||||
rule_add_key(&rule_tmp, TK_A_RUN, op, value, NULL);
|
||||
if (strncmp(key, "RUN", sizeof("RUN")-1) == 0) {
|
||||
attr = get_key_attribute(rules->udev, key + sizeof("RUN")-1);
|
||||
if (attr == NULL)
|
||||
attr = "program";
|
||||
|
||||
if (strcmp(attr, "builtin") == 0) {
|
||||
enum udev_builtin_cmd cmd = udev_builtin_lookup(value);
|
||||
|
||||
if (cmd < UDEV_BUILTIN_MAX)
|
||||
rule_add_key(&rule_tmp, TK_A_RUN_BUILTIN, op, value, &cmd);
|
||||
else
|
||||
log_error("IMPORT{builtin}: '%s' unknown %s:%u\n", value, filename, lineno);
|
||||
} else if (strcmp(attr, "program") == 0) {
|
||||
enum udev_builtin_cmd cmd = UDEV_BUILTIN_MAX;
|
||||
|
||||
if (strncmp(value, "socket:", 7) == 0)
|
||||
log_error("RUN+=\"socket:...\" support will be removed from a future udev release. "
|
||||
"Please remove it from: %s:%u and use libudev to subscribe to events.\n", filename, lineno);
|
||||
rule_add_key(&rule_tmp, TK_A_RUN_PROGRAM, op, value, &cmd);
|
||||
} else {
|
||||
log_error("RUN{} unknown type, ignoring RUN %s:%u\n", filename, lineno);
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -2602,14 +2626,18 @@ int udev_rules_apply_to_event(struct udev_rules *rules, struct udev_event *event
|
||||
}
|
||||
break;
|
||||
}
|
||||
case TK_A_RUN: {
|
||||
case TK_A_RUN_BUILTIN:
|
||||
case TK_A_RUN_PROGRAM: {
|
||||
struct udev_list_entry *entry;
|
||||
|
||||
if (cur->key.op == OP_ASSIGN || cur->key.op == OP_ASSIGN_FINAL)
|
||||
udev_list_cleanup(&event->run_list);
|
||||
log_debug("RUN '%s' %s:%u\n",
|
||||
&rules->buf[cur->key.value_off],
|
||||
&rules->buf[rule->rule.filename_off],
|
||||
rule->rule.filename_line);
|
||||
udev_list_entry_add(&event->run_list, &rules->buf[cur->key.value_off], NULL);
|
||||
entry = udev_list_entry_add(&event->run_list, &rules->buf[cur->key.value_off], NULL);
|
||||
udev_list_entry_set_num(entry, cur->key.builtin_cmd);
|
||||
break;
|
||||
}
|
||||
case TK_A_GOTO:
|
||||
|
@ -78,7 +78,7 @@ int udev_event_spawn(struct udev_event *event,
|
||||
const char *cmd, char **envp, const sigset_t *sigmask,
|
||||
char *result, size_t ressize);
|
||||
int udev_event_execute_rules(struct udev_event *event, struct udev_rules *rules, const sigset_t *sigset);
|
||||
int udev_event_execute_run(struct udev_event *event, const sigset_t *sigset);
|
||||
void udev_event_execute_run(struct udev_event *event, const sigset_t *sigset);
|
||||
int udev_build_argv(struct udev *udev, char *cmd, int *argc, char *argv[]);
|
||||
|
||||
/* udev-watch.c */
|
||||
@ -138,6 +138,9 @@ enum udev_builtin_cmd {
|
||||
UDEV_BUILTIN_PCI_DB,
|
||||
UDEV_BUILTIN_USB_DB,
|
||||
UDEV_BUILTIN_USB_ID,
|
||||
#ifdef HAVE_ACL
|
||||
UDEV_BUILTIN_UACCESS,
|
||||
#endif
|
||||
UDEV_BUILTIN_MAX
|
||||
};
|
||||
struct udev_builtin {
|
||||
@ -157,6 +160,7 @@ extern const struct udev_builtin udev_builtin_path_id;
|
||||
extern const struct udev_builtin udev_builtin_pci_db;
|
||||
extern const struct udev_builtin udev_builtin_usb_db;
|
||||
extern const struct udev_builtin udev_builtin_usb_id;
|
||||
extern const struct udev_builtin udev_builtin_uaccess;
|
||||
int udev_builtin_init(struct udev *udev);
|
||||
void udev_builtin_exit(struct udev *udev);
|
||||
enum udev_builtin_cmd udev_builtin_lookup(const char *command);
|
||||
|
Loading…
Reference in New Issue
Block a user