diff options
author | Lennart Poettering <lennart@poettering.net> | 2016-07-14 12:28:06 +0200 |
---|---|---|
committer | Lennart Poettering <lennart@poettering.net> | 2016-07-22 15:53:45 +0200 |
commit | 66dccd8d85aac9f029c626aac8d2b7e58d239b47 (patch) | |
tree | c17ce6b4b19b2c8b753319e1b971c3f7b786dd7a /src/core/load-fragment.c | |
parent | e4631b48e17e63a3859456df639482063a0276fd (diff) |
core: be stricter when parsing User=/Group= fields
Let's verify the validity of the syntax of the user/group names set.
Diffstat (limited to 'src/core/load-fragment.c')
-rw-r--r-- | src/core/load-fragment.c | 118 |
1 files changed, 118 insertions, 0 deletions
diff --git a/src/core/load-fragment.c b/src/core/load-fragment.c index 782e420e4c..d8aaf4ef40 100644 --- a/src/core/load-fragment.c +++ b/src/core/load-fragment.c @@ -64,6 +64,7 @@ #include "unit-name.h" #include "unit-printf.h" #include "unit.h" +#include "user-util.h" #include "utf8.h" #include "web-util.h" @@ -1763,6 +1764,123 @@ int config_parse_sec_fix_0( return 0; } +int config_parse_user_group( + const char *unit, + const char *filename, + unsigned line, + const char *section, + unsigned section_line, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + + char **user = data, *n; + Unit *u = userdata; + int r; + + assert(filename); + assert(lvalue); + assert(rvalue); + assert(u); + + if (isempty(rvalue)) + n = NULL; + else { + _cleanup_free_ char *k = NULL; + + r = unit_full_printf(u, rvalue, &k); + if (r < 0) { + log_syntax(unit, LOG_ERR, filename, line, r, "Failed to resolve unit specifiers in %s, ignoring: %m", rvalue); + return 0; + } + + if (!valid_user_group_name_or_id(k)) { + log_syntax(unit, LOG_ERR, filename, line, 0, "Invalid user/group name or numeric ID, ignoring: %s", k); + return 0; + } + + n = k; + k = NULL; + } + + free(*user); + *user = n; + + return 0; +} + +int config_parse_user_group_strv( + const char *unit, + const char *filename, + unsigned line, + const char *section, + unsigned section_line, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + + char ***users = data; + Unit *u = userdata; + const char *p; + int r; + + assert(filename); + assert(lvalue); + assert(rvalue); + assert(u); + + if (isempty(rvalue)) { + char **empty; + + empty = new0(char*, 1); + if (!empty) + return log_oom(); + + strv_free(*users); + *users = empty; + + return 0; + } + + p = rvalue; + for (;;) { + _cleanup_free_ char *word = NULL, *k = NULL; + + r = extract_first_word(&p, &word, WHITESPACE, 0); + if (r == 0) + break; + if (r == -ENOMEM) + return log_oom(); + if (r < 0) { + log_syntax(unit, LOG_ERR, filename, line, r, "Invalid syntax, ignoring: %s", rvalue); + break; + } + + r = unit_full_printf(u, word, &k); + if (r < 0) { + log_syntax(unit, LOG_ERR, filename, line, r, "Failed to resolve unit specifiers in %s, ignoring: %m", word); + continue; + } + + if (!valid_user_group_name_or_id(k)) { + log_syntax(unit, LOG_ERR, filename, line, 0, "Invalid user/group name or numeric ID, ignoring: %s", k); + continue; + } + + r = strv_push(users, k); + if (r < 0) + return log_oom(); + + k = NULL; + } + + return 0; +} + int config_parse_busname_service( const char *unit, const char *filename, |