You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
207 lines
8.5 KiB
207 lines
8.5 KiB
From d23386f61d810dab77e9d9d9130adbd826ea823f Mon Sep 17 00:00:00 2001 |
|
From: Michal Sekletar <msekleta@redhat.com> |
|
Date: Thu, 7 Sep 2017 15:49:08 +0200 |
|
Subject: [PATCH] tmpfiles: substitute % specifiers in arguments for writing |
|
files and xattrs |
|
|
|
(cherry-picked from commit bd550f78eb261c757cbff85acdb55563c56521f2) |
|
|
|
Related: #1299714 |
|
--- |
|
src/tmpfiles/tmpfiles.c | 79 ++++++++++++++++++++++------------------- |
|
1 file changed, 42 insertions(+), 37 deletions(-) |
|
|
|
diff --git a/src/tmpfiles/tmpfiles.c b/src/tmpfiles/tmpfiles.c |
|
index 70e0cc2fa3..ddb274fcec 100644 |
|
--- a/src/tmpfiles/tmpfiles.c |
|
+++ b/src/tmpfiles/tmpfiles.c |
|
@@ -151,6 +151,14 @@ static const char conf_file_dirs[] = CONF_DIRS_NULSTR("tmpfiles"); |
|
static Hashmap *items = NULL, *globs = NULL; |
|
static Set *unix_sockets = NULL; |
|
|
|
+static const Specifier specifier_table[] = { |
|
+ { 'm', specifier_machine_id, NULL }, |
|
+ { 'b', specifier_boot_id, NULL }, |
|
+ { 'H', specifier_host_name, NULL }, |
|
+ { 'v', specifier_kernel_release, NULL }, |
|
+ {} |
|
+}; |
|
+ |
|
static bool needs_glob(ItemType t) { |
|
return IN_SET(t, |
|
WRITE_FILE, |
|
@@ -657,8 +665,7 @@ static int path_set_perms(Item *i, const char *path) { |
|
return label_fix(path, false, false); |
|
} |
|
|
|
-static int get_xattrs_from_arg(Item *i) { |
|
- char *xattr; |
|
+static int parse_xattrs_from_arg(Item *i) { |
|
const char *p; |
|
int r; |
|
|
|
@@ -667,35 +674,37 @@ static int get_xattrs_from_arg(Item *i) { |
|
|
|
p = i->argument; |
|
|
|
- while ((r = unquote_first_word(&p, &xattr, false)) > 0) { |
|
- _cleanup_free_ char *tmp = NULL, *name = NULL, |
|
- *value = NULL, *value2 = NULL, *_xattr = xattr; |
|
+ for (;;) { |
|
+ _cleanup_free_ char *name = NULL, *value = NULL, *xattr = NULL, *xattr_replaced = NULL; |
|
+ |
|
+ r = unquote_first_word(&p, &xattr, false); |
|
+ if (r < 0) |
|
+ log_warning_errno(r, "Failed to parse extended attribute '%s', ignoring: %m", p); |
|
+ if (r <= 0) |
|
+ break; |
|
+ |
|
+ r = specifier_printf(xattr, specifier_table, NULL, &xattr_replaced); |
|
+ if (r < 0) |
|
+ return log_error_errno(r, "Failed to replace specifiers in extended attribute '%s': %m", xattr); |
|
|
|
- r = split_pair(xattr, "=", &name, &value); |
|
+ r = split_pair(xattr_replaced, "=", &name, &value); |
|
if (r < 0) { |
|
log_warning("Illegal xattr found: \"%s\" - ignoring.", xattr); |
|
continue; |
|
} |
|
|
|
- if (strempty(name) || strempty(value)) { |
|
- log_warning("Malformed xattr found: \"%s\" - ignoring.", xattr); |
|
+ if (isempty(name) || isempty(value)) { |
|
+ log_warning("Malformed extended attribute found, ignoring: %s", xattr); |
|
continue; |
|
} |
|
|
|
- tmp = unquote(value, "\""); |
|
- if (!tmp) |
|
- return log_oom(); |
|
- |
|
- value2 = cunescape(tmp); |
|
- if (!value2) |
|
+ if (strv_push_pair(&i->xattrs, name, value) < 0) |
|
return log_oom(); |
|
|
|
- if (strv_push_pair(&i->xattrs, name, value2) < 0) |
|
- return log_oom(); |
|
- name = value2 = NULL; |
|
+ name = value = NULL; |
|
} |
|
|
|
- return r; |
|
+ return 0; |
|
} |
|
|
|
static int path_set_xattrs(Item *i, const char *path) { |
|
@@ -708,17 +717,16 @@ static int path_set_xattrs(Item *i, const char *path) { |
|
int n; |
|
|
|
n = strlen(*value); |
|
- log_debug("\"%s\": setting xattr \"%s=%s\"", path, *name, *value); |
|
+ log_debug("Setting extended attribute '%s=%s' on %s.", *name, *value, path); |
|
if (lsetxattr(path, *name, *value, n, 0) < 0) { |
|
- log_error("Setting extended attribute %s=%s on %s failed: %m", |
|
- *name, *value, path); |
|
+ log_error("Setting extended attribute %s=%s on %s failed: %m", *name, *value, path); |
|
return -errno; |
|
} |
|
} |
|
return 0; |
|
} |
|
|
|
-static int get_acls_from_arg(Item *item) { |
|
+static int parse_acls_from_arg(Item *item) { |
|
#ifdef HAVE_ACL |
|
int r; |
|
|
|
@@ -726,6 +734,7 @@ static int get_acls_from_arg(Item *item) { |
|
|
|
/* If force (= modify) is set, we will not modify the acl |
|
* afterwards, so the mask can be added now if necessary. */ |
|
+ |
|
r = parse_acl(item->argument, &item->acl_access, &item->acl_default, !item->force); |
|
if (r < 0) |
|
log_warning_errno(r, "Failed to parse ACL \"%s\": %m. Ignoring", |
|
@@ -839,7 +848,7 @@ static int path_set_acls(Item *item, const char *path) { |
|
FS_TOPDIR_FL | \ |
|
FS_NOCOW_FL) |
|
|
|
-static int get_attribute_from_arg(Item *item) { |
|
+static int parse_attribute_from_arg(Item *item) { |
|
|
|
static const struct { |
|
char character; |
|
@@ -993,7 +1002,7 @@ static int write_one_file(Item *i, const char *path) { |
|
} |
|
|
|
if (i->argument) { |
|
- _cleanup_free_ char *unescaped; |
|
+ _cleanup_free_ char *unescaped = NULL, *replaced = NULL; |
|
|
|
log_debug("%s to \"%s\".", |
|
i->type == CREATE_FILE ? "Appending" : "Writing", path); |
|
@@ -1002,7 +1011,11 @@ static int write_one_file(Item *i, const char *path) { |
|
if (!unescaped) |
|
return log_oom(); |
|
|
|
- r = loop_write(fd, unescaped, strlen(unescaped), false); |
|
+ r = specifier_printf(unescaped, specifier_table, NULL, &replaced); |
|
+ if (r < 0) |
|
+ return log_error_errno(r, "Failed to replace specifiers in parameter to write '%s': %m", unescaped); |
|
+ |
|
+ r = loop_write(fd, replaced, strlen(replaced), false); |
|
if (r < 0) |
|
return log_error_errno(r, "Failed to write file \"%s\": %m", path); |
|
} else |
|
@@ -1712,14 +1725,6 @@ static bool should_include_path(const char *path) { |
|
|
|
static int parse_line(const char *fname, unsigned line, const char *buffer) { |
|
|
|
- static const Specifier specifier_table[] = { |
|
- { 'm', specifier_machine_id, NULL }, |
|
- { 'b', specifier_boot_id, NULL }, |
|
- { 'H', specifier_host_name, NULL }, |
|
- { 'v', specifier_kernel_release, NULL }, |
|
- {} |
|
- }; |
|
- |
|
_cleanup_free_ char *action = NULL, *mode = NULL, *user = NULL, *group = NULL, *age = NULL, *path = NULL; |
|
_cleanup_(item_free_contents) Item i = {}; |
|
ItemArray *existing; |
|
@@ -1801,7 +1806,7 @@ static int parse_line(const char *fname, unsigned line, const char *buffer) { |
|
case RELABEL_PATH: |
|
case RECURSIVE_RELABEL_PATH: |
|
if (i.argument) |
|
- log_warning("[%s:%u] %c lines don't take argument field, ignoring.", fname, line, i.type); |
|
+ log_warning("[%s:%u] %c lines don't take argument fields, ignoring.", fname, line, i.type); |
|
|
|
break; |
|
|
|
@@ -1861,7 +1866,7 @@ static int parse_line(const char *fname, unsigned line, const char *buffer) { |
|
log_error("[%s:%u] Set extended attribute requires argument.", fname, line); |
|
return -EBADMSG; |
|
} |
|
- r = get_xattrs_from_arg(&i); |
|
+ r = parse_xattrs_from_arg(&i); |
|
if (r < 0) |
|
return r; |
|
break; |
|
@@ -1872,7 +1877,7 @@ static int parse_line(const char *fname, unsigned line, const char *buffer) { |
|
log_error("[%s:%u] Set ACLs requires argument.", fname, line); |
|
return -EBADMSG; |
|
} |
|
- r = get_acls_from_arg(&i); |
|
+ r = parse_acls_from_arg(&i); |
|
if (r < 0) |
|
return r; |
|
break; |
|
@@ -1883,7 +1888,7 @@ static int parse_line(const char *fname, unsigned line, const char *buffer) { |
|
log_error("[%s:%u] Set file attribute requires argument.", fname, line); |
|
return -EBADMSG; |
|
} |
|
- r = get_attribute_from_arg(&i); |
|
+ r = parse_attribute_from_arg(&i); |
|
if (r < 0) |
|
return r; |
|
break;
|
|
|