mirror of
https://github.com/systemd/systemd.git
synced 2025-01-11 09:18:07 +03:00
udev: allow final assignments :=
The use of KEY:=<value> will make the key unchangeable by later rules. Signed-off-by: Kay Sievers <kay.sievers@suse.de>
This commit is contained in:
parent
a15f42c46a
commit
c974742bf4
@ -1304,6 +1304,29 @@ EOF
|
||||
KERNEL=="sda", NAME="ok2", RUN+="/bin/ln -s ok2 %r/testsymlink2"
|
||||
KERNEL=="sda", ACTION=="remove", RUN+="/bin/rm -f %r/testsymlink2"
|
||||
KERNEL=="sda", NAME="not-ok2"
|
||||
EOF
|
||||
},
|
||||
{
|
||||
desc => "final assignment",
|
||||
subsys => "block",
|
||||
devpath => "/block/sda",
|
||||
exp_name => "ok",
|
||||
exp_perms => "root:nobody:0640",
|
||||
rules => <<EOF
|
||||
KERNEL=="sda", GROUP:="nobody"
|
||||
KERNEL=="sda", GROUP="not-ok", MODE="0640", NAME="ok"
|
||||
EOF
|
||||
},
|
||||
{
|
||||
desc => "final assignment",
|
||||
subsys => "block",
|
||||
devpath => "/block/sda",
|
||||
exp_name => "ok",
|
||||
exp_perms => "root:nobody:0640",
|
||||
rules => <<EOF
|
||||
KERNEL=="sda", GROUP:="nobody"
|
||||
SUBSYSTEM=="block", MODE:="640"
|
||||
KERNEL=="sda", GROUP="not-ok", MODE="0666", NAME="ok"
|
||||
EOF
|
||||
},
|
||||
);
|
||||
|
5
udev.h
5
udev.h
@ -64,11 +64,16 @@ struct udevice {
|
||||
char name[PATH_SIZE];
|
||||
char devname[PATH_SIZE];
|
||||
struct list_head symlink_list;
|
||||
int symlink_final;
|
||||
char owner[USER_SIZE];
|
||||
int owner_final;
|
||||
char group[USER_SIZE];
|
||||
int group_final;
|
||||
mode_t mode;
|
||||
int mode_final;
|
||||
dev_t devt;
|
||||
struct list_head run_list;
|
||||
int run_final;
|
||||
|
||||
char tmp_node[PATH_SIZE];
|
||||
int partitions;
|
||||
|
20
udev_rules.c
20
udev_rules.c
@ -754,26 +754,34 @@ int udev_rules_get_name(struct udevice *udev, struct sysfs_class_device *class_d
|
||||
}
|
||||
|
||||
/* apply permissions */
|
||||
if (rule->mode != 0000) {
|
||||
if (!udev->mode_final && rule->mode != 0000) {
|
||||
if (rule->mode_operation == KEY_OP_ASSIGN_FINAL)
|
||||
udev->mode_final = 1;
|
||||
udev->mode = rule->mode;
|
||||
dbg("applied mode=%#o to '%s'", udev->mode, udev->kernel_name);
|
||||
}
|
||||
if (rule->owner[0] != '\0') {
|
||||
if (!udev->owner_final && rule->owner[0] != '\0') {
|
||||
if (rule->owner_operation == KEY_OP_ASSIGN_FINAL)
|
||||
udev->owner_final = 1;
|
||||
strlcpy(udev->owner, rule->owner, sizeof(udev->owner));
|
||||
apply_format(udev, udev->owner, sizeof(udev->owner), class_dev, sysfs_device);
|
||||
dbg("applied owner='%s' to '%s'", udev->owner, udev->kernel_name);
|
||||
}
|
||||
if (rule->group[0] != '\0') {
|
||||
if (!udev->group_final && rule->group[0] != '\0') {
|
||||
if (rule->group_operation == KEY_OP_ASSIGN_FINAL)
|
||||
udev->group_final = 1;
|
||||
strlcpy(udev->group, rule->group, sizeof(udev->group));
|
||||
apply_format(udev, udev->group, sizeof(udev->group), class_dev, sysfs_device);
|
||||
dbg("applied group='%s' to '%s'", udev->group, udev->kernel_name);
|
||||
}
|
||||
|
||||
/* collect symlinks */
|
||||
if (rule->symlink[0] != '\0') {
|
||||
if (!udev->symlink_final && rule->symlink[0] != '\0') {
|
||||
char temp[PATH_SIZE];
|
||||
char *pos, *next;
|
||||
|
||||
if (rule->symlink_operation == KEY_OP_ASSIGN_FINAL)
|
||||
udev->symlink_final = 1;
|
||||
info("configured rule in '%s[%i]' applied, added symlink '%s'",
|
||||
rule->config_file, rule->config_line, rule->symlink);
|
||||
strlcpy(temp, rule->symlink, sizeof(temp));
|
||||
@ -808,9 +816,11 @@ int udev_rules_get_name(struct udevice *udev, struct sysfs_class_device *class_d
|
||||
udev->name, udev->owner, udev->group, udev->mode, udev->partitions);
|
||||
}
|
||||
|
||||
if (rule->run[0] != '\0') {
|
||||
if (!udev->run_final && rule->run[0] != '\0') {
|
||||
char program[PATH_SIZE];
|
||||
|
||||
if (rule->run_operation == KEY_OP_ASSIGN_FINAL)
|
||||
udev->run_final = 1;
|
||||
strlcpy(program, rule->run, sizeof(program));
|
||||
apply_format(udev, program, sizeof(program), class_dev, sysfs_device);
|
||||
dbg("add run '%s'", program);
|
||||
|
@ -62,6 +62,7 @@ enum key_operation {
|
||||
KEY_OP_NOMATCH,
|
||||
KEY_OP_ADD,
|
||||
KEY_OP_ASSIGN,
|
||||
KEY_OP_ASSIGN_FINAL,
|
||||
};
|
||||
|
||||
struct key_pair {
|
||||
@ -96,10 +97,15 @@ struct udev_rule {
|
||||
|
||||
char name[PATH_SIZE];
|
||||
char symlink[PATH_SIZE];
|
||||
enum key_operation symlink_operation;
|
||||
char owner[USER_SIZE];
|
||||
enum key_operation owner_operation;
|
||||
char group[USER_SIZE];
|
||||
enum key_operation group_operation;
|
||||
mode_t mode;
|
||||
enum key_operation mode_operation;
|
||||
char run[PATH_SIZE];
|
||||
enum key_operation run_operation;
|
||||
|
||||
int last_rule;
|
||||
int ignore_device;
|
||||
|
@ -89,6 +89,8 @@ static int get_key(char **line, char **key, enum key_operation *operation, char
|
||||
break;
|
||||
if (linepos[0] == '!')
|
||||
break;
|
||||
if (linepos[0] == ':')
|
||||
break;
|
||||
}
|
||||
|
||||
/* remember end of key */
|
||||
@ -115,6 +117,10 @@ static int get_key(char **line, char **key, enum key_operation *operation, char
|
||||
*operation = KEY_OP_ASSIGN;
|
||||
linepos++;
|
||||
dbg("operator=assign");
|
||||
} else if (linepos[0] == ':' && linepos[1] == '=') {
|
||||
*operation = KEY_OP_ASSIGN_FINAL;
|
||||
linepos += 2;
|
||||
dbg("operator=assign_final");
|
||||
} else
|
||||
return -1;
|
||||
|
||||
@ -364,30 +370,35 @@ static int rules_parse(const char *filename)
|
||||
|
||||
if (strcasecmp(key, KEY_SYMLINK) == 0) {
|
||||
strlcpy(rule.symlink, value, sizeof(rule.symlink));
|
||||
rule.symlink_operation = operation;
|
||||
valid = 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (strcasecmp(key, KEY_OWNER) == 0) {
|
||||
strlcpy(rule.owner, value, sizeof(rule.owner));
|
||||
rule.owner_operation = operation;
|
||||
valid = 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (strcasecmp(key, KEY_GROUP) == 0) {
|
||||
strlcpy(rule.group, value, sizeof(rule.group));
|
||||
rule.group_operation = operation;
|
||||
valid = 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (strcasecmp(key, KEY_MODE) == 0) {
|
||||
rule.mode = strtol(value, NULL, 8);
|
||||
rule.mode_operation = operation;
|
||||
valid = 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (strcasecmp(key, KEY_RUN) == 0) {
|
||||
strlcpy(rule.run, value, sizeof(rule.run));
|
||||
rule.run_operation = operation;
|
||||
valid = 1;
|
||||
continue;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user