summaryrefslogtreecommitdiff
path: root/src/sysusers
diff options
context:
space:
mode:
authorZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>2023-01-31 14:16:48 +0100
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>2023-02-01 11:30:26 +0100
commit9a87bdd7ed9fb78fdcd404ef87746f37544e7966 (patch)
tree21ca209ea374d15fc5551ceeec4555f9295636dd /src/sysusers
parent5afdb4629aeb2cd20f3f7ba7e4b10f5d92be6a76 (diff)
downloadsystemd-9a87bdd7ed9fb78fdcd404ef87746f37544e7966.tar.gz
sysusers: add helper to create new Item
Diffstat (limited to 'src/sysusers')
-rw-r--r--src/sysusers/sysusers.c84
1 files changed, 50 insertions, 34 deletions
diff --git a/src/sysusers/sysusers.c b/src/sysusers/sysusers.c
index 4c31f96301..c34f3991b3 100644
--- a/src/sysusers/sysusers.c
+++ b/src/sysusers/sysusers.c
@@ -76,6 +76,9 @@ typedef struct Item {
gid_t gid;
uid_t uid;
+ char *filename;
+ unsigned line;
+
bool gid_set;
/* When set the group with the specified GID must exist
@@ -1412,12 +1415,33 @@ static Item* item_free(Item *i) {
free(i->description);
free(i->home);
free(i->shell);
+ free(i->filename);
return mfree(i);
}
DEFINE_TRIVIAL_CLEANUP_FUNC(Item*, item_free);
DEFINE_PRIVATE_HASH_OPS_WITH_VALUE_DESTRUCTOR(item_hash_ops, char, string_hash_func, string_compare_func, Item, item_free);
+static Item* item_new(ItemType type, const char *name, const char *filename, unsigned line) {
+ assert(name);
+ assert(!!filename == (line > 0));
+
+ _cleanup_(item_freep) Item *new = new(Item, 1);
+ if (!new)
+ return NULL;
+
+ *new = (Item) {
+ .type = type,
+ .line = line,
+ };
+
+ if (free_and_strdup(&new->name, name) < 0 ||
+ free_and_strdup(&new->filename, filename) < 0)
+ return NULL;
+
+ return TAKE_PTR(new);
+}
+
static int add_implicit(void) {
char *g, **l;
int r;
@@ -1426,17 +1450,11 @@ static int add_implicit(void) {
ORDERED_HASHMAP_FOREACH_KEY(l, g, members) {
STRV_FOREACH(m, l)
if (!ordered_hashmap_get(users, *m)) {
- _cleanup_(item_freep) Item *j = NULL;
-
- j = new0(Item, 1);
+ _cleanup_(item_freep) Item *j =
+ item_new(ADD_USER, *m, /* filename= */ NULL, /* line= */ 0);
if (!j)
return log_oom();
- j->type = ADD_USER;
- j->name = strdup(*m);
- if (!j->name)
- return log_oom();
-
r = ordered_hashmap_ensure_put(&users, &item_hash_ops, j->name, j);
if (r == -ENOMEM)
return log_oom();
@@ -1449,17 +1467,11 @@ static int add_implicit(void) {
if (!(ordered_hashmap_get(users, g) ||
ordered_hashmap_get(groups, g))) {
- _cleanup_(item_freep) Item *j = NULL;
-
- j = new0(Item, 1);
+ _cleanup_(item_freep) Item *j =
+ item_new(ADD_GROUP, g, /* filename= */ NULL, /* line= */ 0);
if (!j)
return log_oom();
- j->type = ADD_GROUP;
- j->name = strdup(g);
- if (!j->name)
- return log_oom();
-
r = ordered_hashmap_ensure_put(&groups, &item_hash_ops, j->name, j);
if (r == -ENOMEM)
return log_oom();
@@ -1720,15 +1732,14 @@ static int parse_line(const char *fname, unsigned line, const char *buffer) {
if (r < 0)
return log_oom();
- i = new0(Item, 1);
+ i = item_new(ADD_USER, resolved_name, fname, line);
if (!i)
return log_oom();
if (resolved_id) {
- if (path_is_absolute(resolved_id)) {
- i->uid_path = TAKE_PTR(resolved_id);
- path_simplify(i->uid_path);
- } else {
+ if (path_is_absolute(resolved_id))
+ i->uid_path = path_simplify(TAKE_PTR(resolved_id));
+ else {
_cleanup_free_ char *uid = NULL, *gid = NULL;
if (split_pair(resolved_id, ":", &uid, &gid) == 0) {
r = parse_gid(gid, &i->gid);
@@ -1776,15 +1787,14 @@ static int parse_line(const char *fname, unsigned line, const char *buffer) {
if (r < 0)
return log_oom();
- i = new0(Item, 1);
+ i = item_new(ADD_GROUP, resolved_name, fname, line);
if (!i)
return log_oom();
if (resolved_id) {
- if (path_is_absolute(resolved_id)) {
- i->gid_path = TAKE_PTR(resolved_id);
- path_simplify(i->gid_path);
- } else {
+ if (path_is_absolute(resolved_id))
+ i->gid_path = path_simplify(TAKE_PTR(resolved_id));
+ else {
r = parse_gid(resolved_id, &i->gid);
if (r < 0)
return log_syntax(NULL, LOG_ERR, fname, line, r,
@@ -1798,22 +1808,28 @@ static int parse_line(const char *fname, unsigned line, const char *buffer) {
break;
default:
- return -EBADMSG;
+ assert_not_reached();
}
- i->type = action[0];
- i->name = TAKE_PTR(resolved_name);
-
existing = ordered_hashmap_get(h, i->name);
if (existing) {
/* Two functionally-equivalent items are fine */
r = item_equivalent(existing, i);
if (r < 0)
return r;
- if (r == 0)
- log_syntax(NULL, LOG_WARNING, fname, line, 0,
- "Conflict with earlier configuration for %s '%s', ignoring line.",
- item_type_to_string(i->type), i->name);
+ if (r == 0) {
+ if (existing->filename)
+ log_syntax(NULL, LOG_WARNING, fname, line, 0,
+ "Conflict with earlier configuration for %s '%s' in %s:%u, ignoring line.",
+ item_type_to_string(i->type),
+ i->name,
+ existing->filename, existing->line);
+ else
+ log_syntax(NULL, LOG_WARNING, fname, line, 0,
+ "Conflict with earlier configuration for %s '%s', ignoring line.",
+ item_type_to_string(i->type),
+ i->name);
+ }
return 0;
}