mirror of
https://github.com/systemd/systemd-stable.git
synced 2025-01-08 21:17:47 +03:00
Merge pull request #7973 from mvo5/sysusers-uid-gid
sysusers: allow uid:gid in sysusers.conf files
This commit is contained in:
commit
786b8fa0fb
@ -191,7 +191,10 @@ u root 0 "Superuser" /root</programlisting>
|
||||
in the file system. In this case, the UID/GID is read from the
|
||||
path's owner/group. This is useful to create users whose UID/GID
|
||||
match the owners of pre-existing files (such as SUID or SGID
|
||||
binaries).</para>
|
||||
binaries).
|
||||
The syntax <literal><replaceable>uid</replaceable>:<replaceable>gid</replaceable></literal> is also supported to
|
||||
allow creating user and group pairs with different numeric UID and GID values. The group with the indicated GID must get created explicitly before or it must already exist.
|
||||
</para>
|
||||
|
||||
<para>For <varname>m</varname> lines, this field should contain
|
||||
the group name to add to a user to.</para>
|
||||
|
@ -64,6 +64,7 @@ typedef struct Item {
|
||||
uid_t uid;
|
||||
|
||||
bool gid_set:1;
|
||||
bool gid_must_exist:1;
|
||||
bool uid_set:1;
|
||||
|
||||
bool todo_user:1;
|
||||
@ -74,9 +75,9 @@ static char *arg_root = NULL;
|
||||
|
||||
static const char conf_file_dirs[] = CONF_PATHS_NULSTR("sysusers.d");
|
||||
|
||||
static Hashmap *users = NULL, *groups = NULL;
|
||||
static Hashmap *todo_uids = NULL, *todo_gids = NULL;
|
||||
static Hashmap *members = NULL;
|
||||
static OrderedHashmap *users = NULL, *groups = NULL;
|
||||
static OrderedHashmap *todo_uids = NULL, *todo_gids = NULL;
|
||||
static OrderedHashmap *members = NULL;
|
||||
|
||||
static Hashmap *database_uid = NULL, *database_user = NULL;
|
||||
static Hashmap *database_gid = NULL, *database_group = NULL;
|
||||
@ -256,7 +257,7 @@ static int putgrent_with_members(const struct group *gr, FILE *group) {
|
||||
assert(gr);
|
||||
assert(group);
|
||||
|
||||
a = hashmap_get(members, gr->gr_name);
|
||||
a = ordered_hashmap_get(members, gr->gr_name);
|
||||
if (a) {
|
||||
_cleanup_strv_free_ char **l = NULL;
|
||||
bool added = false;
|
||||
@ -307,7 +308,7 @@ static int putsgent_with_members(const struct sgrp *sg, FILE *gshadow) {
|
||||
assert(sg);
|
||||
assert(gshadow);
|
||||
|
||||
a = hashmap_get(members, sg->sg_namp);
|
||||
a = ordered_hashmap_get(members, sg->sg_namp);
|
||||
if (a) {
|
||||
_cleanup_strv_free_ char **l = NULL;
|
||||
bool added = false;
|
||||
@ -387,7 +388,7 @@ static int write_temporary_passwd(const char *passwd_path, FILE **tmpfile, char
|
||||
Item *i;
|
||||
int r;
|
||||
|
||||
if (hashmap_size(todo_uids) == 0)
|
||||
if (ordered_hashmap_size(todo_uids) == 0)
|
||||
return 0;
|
||||
|
||||
r = fopen_temporary_label("/etc/passwd", passwd_path, &passwd, &passwd_tmp);
|
||||
@ -405,13 +406,13 @@ static int write_temporary_passwd(const char *passwd_path, FILE **tmpfile, char
|
||||
errno = 0;
|
||||
while ((pw = fgetpwent(original))) {
|
||||
|
||||
i = hashmap_get(users, pw->pw_name);
|
||||
i = ordered_hashmap_get(users, pw->pw_name);
|
||||
if (i && i->todo_user) {
|
||||
log_error("%s: User \"%s\" already exists.", passwd_path, pw->pw_name);
|
||||
return -EEXIST;
|
||||
}
|
||||
|
||||
if (hashmap_contains(todo_uids, UID_TO_PTR(pw->pw_uid))) {
|
||||
if (ordered_hashmap_contains(todo_uids, UID_TO_PTR(pw->pw_uid))) {
|
||||
log_error("%s: Detected collision for UID " UID_FMT ".", passwd_path, pw->pw_uid);
|
||||
return -EEXIST;
|
||||
}
|
||||
@ -432,7 +433,7 @@ static int write_temporary_passwd(const char *passwd_path, FILE **tmpfile, char
|
||||
return -errno;
|
||||
}
|
||||
|
||||
HASHMAP_FOREACH(i, todo_uids, iterator) {
|
||||
ORDERED_HASHMAP_FOREACH(i, todo_uids, iterator) {
|
||||
struct passwd n = {
|
||||
.pw_name = i->name,
|
||||
.pw_uid = i->uid,
|
||||
@ -474,7 +475,7 @@ static int write_temporary_shadow(const char *shadow_path, FILE **tmpfile, char
|
||||
Item *i;
|
||||
int r;
|
||||
|
||||
if (hashmap_size(todo_uids) == 0)
|
||||
if (ordered_hashmap_size(todo_uids) == 0)
|
||||
return 0;
|
||||
|
||||
r = fopen_temporary_label("/etc/shadow", shadow_path, &shadow, &shadow_tmp);
|
||||
@ -494,7 +495,7 @@ static int write_temporary_shadow(const char *shadow_path, FILE **tmpfile, char
|
||||
errno = 0;
|
||||
while ((sp = fgetspent(original))) {
|
||||
|
||||
i = hashmap_get(users, sp->sp_namp);
|
||||
i = ordered_hashmap_get(users, sp->sp_namp);
|
||||
if (i && i->todo_user) {
|
||||
/* we will update the existing entry */
|
||||
sp->sp_lstchg = lstchg;
|
||||
@ -502,7 +503,7 @@ static int write_temporary_shadow(const char *shadow_path, FILE **tmpfile, char
|
||||
/* only the /etc/shadow stage is left, so we can
|
||||
* safely remove the item from the todo set */
|
||||
i->todo_user = false;
|
||||
hashmap_remove(todo_uids, UID_TO_PTR(i->uid));
|
||||
ordered_hashmap_remove(todo_uids, UID_TO_PTR(i->uid));
|
||||
}
|
||||
|
||||
errno = 0;
|
||||
@ -521,7 +522,7 @@ static int write_temporary_shadow(const char *shadow_path, FILE **tmpfile, char
|
||||
return -errno;
|
||||
}
|
||||
|
||||
HASHMAP_FOREACH(i, todo_uids, iterator) {
|
||||
ORDERED_HASHMAP_FOREACH(i, todo_uids, iterator) {
|
||||
struct spwd n = {
|
||||
.sp_namp = i->name,
|
||||
.sp_pwdp = (char*) "!!",
|
||||
@ -558,7 +559,7 @@ static int write_temporary_group(const char *group_path, FILE **tmpfile, char **
|
||||
Item *i;
|
||||
int r;
|
||||
|
||||
if (hashmap_size(todo_gids) == 0 && hashmap_size(members) == 0)
|
||||
if (ordered_hashmap_size(todo_gids) == 0 && ordered_hashmap_size(members) == 0)
|
||||
return 0;
|
||||
|
||||
r = fopen_temporary_label("/etc/group", group_path, &group, &group_tmp);
|
||||
@ -580,13 +581,13 @@ static int write_temporary_group(const char *group_path, FILE **tmpfile, char **
|
||||
* entries anyway here, let's make an extra verification
|
||||
* step that we don't generate duplicate entries. */
|
||||
|
||||
i = hashmap_get(groups, gr->gr_name);
|
||||
i = ordered_hashmap_get(groups, gr->gr_name);
|
||||
if (i && i->todo_group) {
|
||||
log_error("%s: Group \"%s\" already exists.", group_path, gr->gr_name);
|
||||
return -EEXIST;
|
||||
}
|
||||
|
||||
if (hashmap_contains(todo_gids, GID_TO_PTR(gr->gr_gid))) {
|
||||
if (ordered_hashmap_contains(todo_gids, GID_TO_PTR(gr->gr_gid))) {
|
||||
log_error("%s: Detected collision for GID " GID_FMT ".", group_path, gr->gr_gid);
|
||||
return -EEXIST;
|
||||
}
|
||||
@ -609,7 +610,7 @@ static int write_temporary_group(const char *group_path, FILE **tmpfile, char **
|
||||
return -errno;
|
||||
}
|
||||
|
||||
HASHMAP_FOREACH(i, todo_gids, iterator) {
|
||||
ORDERED_HASHMAP_FOREACH(i, todo_gids, iterator) {
|
||||
struct group n = {
|
||||
.gr_name = i->name,
|
||||
.gr_gid = i->gid,
|
||||
@ -645,7 +646,7 @@ static int write_temporary_gshadow(const char * gshadow_path, FILE **tmpfile, ch
|
||||
Item *i;
|
||||
int r;
|
||||
|
||||
if (hashmap_size(todo_gids) == 0 && hashmap_size(members) == 0)
|
||||
if (ordered_hashmap_size(todo_gids) == 0 && ordered_hashmap_size(members) == 0)
|
||||
return 0;
|
||||
|
||||
r = fopen_temporary_label("/etc/gshadow", gshadow_path, &gshadow, &gshadow_tmp);
|
||||
@ -663,7 +664,7 @@ static int write_temporary_gshadow(const char * gshadow_path, FILE **tmpfile, ch
|
||||
errno = 0;
|
||||
while ((sg = fgetsgent(original))) {
|
||||
|
||||
i = hashmap_get(groups, sg->sg_namp);
|
||||
i = ordered_hashmap_get(groups, sg->sg_namp);
|
||||
if (i && i->todo_group) {
|
||||
log_error("%s: Group \"%s\" already exists.", gshadow_path, sg->sg_namp);
|
||||
return -EEXIST;
|
||||
@ -687,7 +688,7 @@ static int write_temporary_gshadow(const char * gshadow_path, FILE **tmpfile, ch
|
||||
return -errno;
|
||||
}
|
||||
|
||||
HASHMAP_FOREACH(i, todo_gids, iterator) {
|
||||
ORDERED_HASHMAP_FOREACH(i, todo_gids, iterator) {
|
||||
struct sgrp n = {
|
||||
.sg_namp = i->name,
|
||||
.sg_passwd = (char*) "!!",
|
||||
@ -807,12 +808,12 @@ static int uid_is_ok(uid_t uid, const char *name) {
|
||||
Item *i;
|
||||
|
||||
/* Let's see if we already have assigned the UID a second time */
|
||||
if (hashmap_get(todo_uids, UID_TO_PTR(uid)))
|
||||
if (ordered_hashmap_get(todo_uids, UID_TO_PTR(uid)))
|
||||
return 0;
|
||||
|
||||
/* Try to avoid using uids that are already used by a group
|
||||
* that doesn't have the same name as our new user. */
|
||||
i = hashmap_get(todo_gids, GID_TO_PTR(uid));
|
||||
i = ordered_hashmap_get(todo_gids, GID_TO_PTR(uid));
|
||||
if (i && !streq(i->name, name))
|
||||
return 0;
|
||||
|
||||
@ -1012,11 +1013,11 @@ static int add_user(Item *i) {
|
||||
i->uid = search_uid;
|
||||
}
|
||||
|
||||
r = hashmap_ensure_allocated(&todo_uids, NULL);
|
||||
r = ordered_hashmap_ensure_allocated(&todo_uids, NULL);
|
||||
if (r < 0)
|
||||
return log_oom();
|
||||
|
||||
r = hashmap_put(todo_uids, UID_TO_PTR(i->uid), i);
|
||||
r = ordered_hashmap_put(todo_uids, UID_TO_PTR(i->uid), i);
|
||||
if (r < 0)
|
||||
return log_oom();
|
||||
|
||||
@ -1030,11 +1031,11 @@ static int gid_is_ok(gid_t gid) {
|
||||
struct group *g;
|
||||
struct passwd *p;
|
||||
|
||||
if (hashmap_get(todo_gids, GID_TO_PTR(gid)))
|
||||
if (ordered_hashmap_get(todo_gids, GID_TO_PTR(gid)))
|
||||
return 0;
|
||||
|
||||
/* Avoid reusing gids that are already used by a different user */
|
||||
if (hashmap_get(todo_uids, UID_TO_PTR(gid)))
|
||||
if (ordered_hashmap_get(todo_uids, UID_TO_PTR(gid)))
|
||||
return 0;
|
||||
|
||||
if (hashmap_contains(database_gid, GID_TO_PTR(gid)))
|
||||
@ -1098,6 +1099,18 @@ static int add_group(Item *i) {
|
||||
r = gid_is_ok(i->gid);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to verify gid " GID_FMT ": %m", i->gid);
|
||||
if (i->gid_must_exist) {
|
||||
/* If we require the gid to already exist we can return here:
|
||||
* r > 0: means the gid does not exist -> fail
|
||||
* r == 0: means the gid exists -> nothing more to do.
|
||||
*/
|
||||
if (r > 0) {
|
||||
log_error("Failed to create %s: please create GID %d", i->name, i->gid);
|
||||
return -EINVAL;
|
||||
}
|
||||
if (r == 0)
|
||||
return 0;
|
||||
}
|
||||
if (r == 0) {
|
||||
log_debug("Suggested group ID " GID_FMT " for %s already used.", i->gid, i->name);
|
||||
i->gid_set = false;
|
||||
@ -1157,11 +1170,11 @@ static int add_group(Item *i) {
|
||||
i->gid = search_uid;
|
||||
}
|
||||
|
||||
r = hashmap_ensure_allocated(&todo_gids, NULL);
|
||||
r = ordered_hashmap_ensure_allocated(&todo_gids, NULL);
|
||||
if (r < 0)
|
||||
return log_oom();
|
||||
|
||||
r = hashmap_put(todo_gids, GID_TO_PTR(i->gid), i);
|
||||
r = ordered_hashmap_put(todo_gids, GID_TO_PTR(i->gid), i);
|
||||
if (r < 0)
|
||||
return log_oom();
|
||||
|
||||
@ -1185,30 +1198,8 @@ static int process_item(Item *i) {
|
||||
|
||||
return add_user(i);
|
||||
|
||||
case ADD_GROUP: {
|
||||
Item *j;
|
||||
|
||||
j = hashmap_get(users, i->name);
|
||||
if (j) {
|
||||
/* There's already user to be created for this
|
||||
* name, let's process that in one step */
|
||||
|
||||
if (i->gid_set) {
|
||||
j->gid = i->gid;
|
||||
j->gid_set = true;
|
||||
}
|
||||
|
||||
if (i->gid_path) {
|
||||
r = free_and_strdup(&j->gid_path, i->gid_path);
|
||||
if (r < 0)
|
||||
return log_oom();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
case ADD_GROUP:
|
||||
return add_group(i);
|
||||
}
|
||||
|
||||
default:
|
||||
assert_not_reached("Unknown item type");
|
||||
@ -1237,15 +1228,15 @@ static int add_implicit(void) {
|
||||
|
||||
/* Implicitly create additional users and groups, if they were listed in "m" lines */
|
||||
|
||||
HASHMAP_FOREACH_KEY(l, g, members, iterator) {
|
||||
ORDERED_HASHMAP_FOREACH_KEY(l, g, members, iterator) {
|
||||
Item *i;
|
||||
char **m;
|
||||
|
||||
i = hashmap_get(groups, g);
|
||||
i = ordered_hashmap_get(groups, g);
|
||||
if (!i) {
|
||||
_cleanup_(item_freep) Item *j = NULL;
|
||||
|
||||
r = hashmap_ensure_allocated(&groups, &string_hash_ops);
|
||||
r = ordered_hashmap_ensure_allocated(&groups, &string_hash_ops);
|
||||
if (r < 0)
|
||||
return log_oom();
|
||||
|
||||
@ -1258,7 +1249,7 @@ static int add_implicit(void) {
|
||||
if (!j->name)
|
||||
return log_oom();
|
||||
|
||||
r = hashmap_put(groups, j->name, j);
|
||||
r = ordered_hashmap_put(groups, j->name, j);
|
||||
if (r < 0)
|
||||
return log_oom();
|
||||
|
||||
@ -1268,11 +1259,11 @@ static int add_implicit(void) {
|
||||
|
||||
STRV_FOREACH(m, l) {
|
||||
|
||||
i = hashmap_get(users, *m);
|
||||
i = ordered_hashmap_get(users, *m);
|
||||
if (!i) {
|
||||
_cleanup_(item_freep) Item *j = NULL;
|
||||
|
||||
r = hashmap_ensure_allocated(&users, &string_hash_ops);
|
||||
r = ordered_hashmap_ensure_allocated(&users, &string_hash_ops);
|
||||
if (r < 0)
|
||||
return log_oom();
|
||||
|
||||
@ -1285,7 +1276,7 @@ static int add_implicit(void) {
|
||||
if (!j->name)
|
||||
return log_oom();
|
||||
|
||||
r = hashmap_put(users, j->name, j);
|
||||
r = ordered_hashmap_put(users, j->name, j);
|
||||
if (r < 0)
|
||||
return log_oom();
|
||||
|
||||
@ -1348,7 +1339,7 @@ static int parse_line(const char *fname, unsigned line, const char *buffer) {
|
||||
_cleanup_free_ char *action = NULL, *name = NULL, *id = NULL, *resolved_name = NULL, *resolved_id = NULL, *description = NULL, *home = NULL;
|
||||
_cleanup_(item_freep) Item *i = NULL;
|
||||
Item *existing;
|
||||
Hashmap *h;
|
||||
OrderedHashmap *h;
|
||||
int r;
|
||||
const char *p;
|
||||
|
||||
@ -1494,11 +1485,11 @@ static int parse_line(const char *fname, unsigned line, const char *buffer) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
r = hashmap_ensure_allocated(&members, &string_hash_ops);
|
||||
r = ordered_hashmap_ensure_allocated(&members, &string_hash_ops);
|
||||
if (r < 0)
|
||||
return log_oom();
|
||||
|
||||
l = hashmap_get(members, resolved_id);
|
||||
l = ordered_hashmap_get(members, resolved_id);
|
||||
if (l) {
|
||||
/* A list for this group name already exists, let's append to it */
|
||||
r = strv_push(&l, resolved_name);
|
||||
@ -1507,7 +1498,7 @@ static int parse_line(const char *fname, unsigned line, const char *buffer) {
|
||||
|
||||
resolved_name = NULL;
|
||||
|
||||
assert_se(hashmap_update(members, resolved_id, l) >= 0);
|
||||
assert_se(ordered_hashmap_update(members, resolved_id, l) >= 0);
|
||||
} else {
|
||||
/* No list for this group name exists yet, create one */
|
||||
|
||||
@ -1518,7 +1509,7 @@ static int parse_line(const char *fname, unsigned line, const char *buffer) {
|
||||
l[0] = resolved_name;
|
||||
l[1] = NULL;
|
||||
|
||||
r = hashmap_put(members, resolved_id, l);
|
||||
r = ordered_hashmap_put(members, resolved_id, l);
|
||||
if (r < 0) {
|
||||
free(l);
|
||||
return log_oom();
|
||||
@ -1536,7 +1527,7 @@ static int parse_line(const char *fname, unsigned line, const char *buffer) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
r = hashmap_ensure_allocated(&users, &string_hash_ops);
|
||||
r = ordered_hashmap_ensure_allocated(&users, &string_hash_ops);
|
||||
if (r < 0)
|
||||
return log_oom();
|
||||
|
||||
@ -1551,11 +1542,18 @@ static int parse_line(const char *fname, unsigned line, const char *buffer) {
|
||||
|
||||
path_kill_slashes(i->uid_path);
|
||||
} else {
|
||||
r = parse_uid(resolved_id, &i->uid);
|
||||
if (r < 0) {
|
||||
log_error("Failed to parse UID: %s", id);
|
||||
return -EBADMSG;
|
||||
_cleanup_free_ char *uid = NULL, *gid = NULL;
|
||||
if (split_pair(resolved_id, ":", &uid, &gid) == 0) {
|
||||
r = parse_gid(gid, &i->gid);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to parse GID: '%s': %m", id);
|
||||
i->gid_set = true;
|
||||
i->gid_must_exist = true;
|
||||
free_and_replace(resolved_id, uid);
|
||||
}
|
||||
r = parse_uid(resolved_id, &i->uid);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to parse UID: '%s': %m", id);
|
||||
|
||||
i->uid_set = true;
|
||||
}
|
||||
@ -1586,7 +1584,7 @@ static int parse_line(const char *fname, unsigned line, const char *buffer) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
r = hashmap_ensure_allocated(&groups, &string_hash_ops);
|
||||
r = ordered_hashmap_ensure_allocated(&groups, &string_hash_ops);
|
||||
if (r < 0)
|
||||
return log_oom();
|
||||
|
||||
@ -1602,10 +1600,8 @@ static int parse_line(const char *fname, unsigned line, const char *buffer) {
|
||||
path_kill_slashes(i->gid_path);
|
||||
} else {
|
||||
r = parse_gid(resolved_id, &i->gid);
|
||||
if (r < 0) {
|
||||
log_error("Failed to parse GID: %s", id);
|
||||
return -EBADMSG;
|
||||
}
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to parse GID: '%s': %m", id);
|
||||
|
||||
i->gid_set = true;
|
||||
}
|
||||
@ -1622,7 +1618,7 @@ static int parse_line(const char *fname, unsigned line, const char *buffer) {
|
||||
i->name = resolved_name;
|
||||
resolved_name = NULL;
|
||||
|
||||
existing = hashmap_get(h, i->name);
|
||||
existing = ordered_hashmap_get(h, i->name);
|
||||
if (existing) {
|
||||
|
||||
/* Two identical items are fine */
|
||||
@ -1632,7 +1628,7 @@ static int parse_line(const char *fname, unsigned line, const char *buffer) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
r = hashmap_put(h, i->name, i);
|
||||
r = ordered_hashmap_put(h, i->name, i);
|
||||
if (r < 0)
|
||||
return log_oom();
|
||||
|
||||
@ -1853,10 +1849,10 @@ int main(int argc, char *argv[]) {
|
||||
goto finish;
|
||||
}
|
||||
|
||||
HASHMAP_FOREACH(i, groups, iterator)
|
||||
ORDERED_HASHMAP_FOREACH(i, groups, iterator)
|
||||
process_item(i);
|
||||
|
||||
HASHMAP_FOREACH(i, users, iterator)
|
||||
ORDERED_HASHMAP_FOREACH(i, users, iterator)
|
||||
process_item(i);
|
||||
|
||||
r = write_files();
|
||||
@ -1864,17 +1860,17 @@ int main(int argc, char *argv[]) {
|
||||
log_error_errno(r, "Failed to write files: %m");
|
||||
|
||||
finish:
|
||||
hashmap_free_with_destructor(groups, item_free);
|
||||
hashmap_free_with_destructor(users, item_free);
|
||||
ordered_hashmap_free_with_destructor(groups, item_free);
|
||||
ordered_hashmap_free_with_destructor(users, item_free);
|
||||
|
||||
while ((n = hashmap_first_key(members))) {
|
||||
strv_free(hashmap_steal_first(members));
|
||||
while ((n = ordered_hashmap_first_key(members))) {
|
||||
strv_free(ordered_hashmap_steal_first(members));
|
||||
free(n);
|
||||
}
|
||||
hashmap_free(members);
|
||||
ordered_hashmap_free(members);
|
||||
|
||||
hashmap_free(todo_uids);
|
||||
hashmap_free(todo_gids);
|
||||
ordered_hashmap_free(todo_uids);
|
||||
ordered_hashmap_free(todo_gids);
|
||||
|
||||
free_database(database_user, database_uid);
|
||||
free_database(database_group, database_gid);
|
||||
|
4
test/TEST-21-SYSUSERS/Makefile
Normal file
4
test/TEST-21-SYSUSERS/Makefile
Normal file
@ -0,0 +1,4 @@
|
||||
BUILD_DIR=$(shell ../../tools/find-build-dir.sh)
|
||||
|
||||
all setup clean run:
|
||||
@basedir=../.. TEST_BASE_DIR=../ BUILD_DIR=$(BUILD_DIR) ./test.sh --$@
|
2
test/TEST-21-SYSUSERS/test-1.expected-group
Normal file
2
test/TEST-21-SYSUSERS/test-1.expected-group
Normal file
@ -0,0 +1,2 @@
|
||||
g1:x:111:
|
||||
u1:x:222:
|
1
test/TEST-21-SYSUSERS/test-1.expected-passwd
Normal file
1
test/TEST-21-SYSUSERS/test-1.expected-passwd
Normal file
@ -0,0 +1 @@
|
||||
u1:x:222:222::/:/sbin/nologin
|
3
test/TEST-21-SYSUSERS/test-1.input
Normal file
3
test/TEST-21-SYSUSERS/test-1.input
Normal file
@ -0,0 +1,3 @@
|
||||
#Type Name ID GECOS HOMEDIR
|
||||
u u1 222 - -
|
||||
g g1 111 - -
|
1
test/TEST-21-SYSUSERS/test-2.expected-group
Normal file
1
test/TEST-21-SYSUSERS/test-2.expected-group
Normal file
@ -0,0 +1 @@
|
||||
u1:x:999:
|
1
test/TEST-21-SYSUSERS/test-2.expected-passwd
Normal file
1
test/TEST-21-SYSUSERS/test-2.expected-passwd
Normal file
@ -0,0 +1 @@
|
||||
u1:x:999:999:some gecos:/random/dir:/sbin/nologin
|
2
test/TEST-21-SYSUSERS/test-2.input
Normal file
2
test/TEST-21-SYSUSERS/test-2.input
Normal file
@ -0,0 +1,2 @@
|
||||
#Type Name ID GECOS HOMEDIR
|
||||
u u1 - "some gecos" /random/dir
|
4
test/TEST-21-SYSUSERS/test-3.expected-group
Normal file
4
test/TEST-21-SYSUSERS/test-3.expected-group
Normal file
@ -0,0 +1,4 @@
|
||||
hoge:x:300:
|
||||
baz:x:302:
|
||||
foo:x:301:
|
||||
ccc:x:305:
|
4
test/TEST-21-SYSUSERS/test-3.expected-passwd
Normal file
4
test/TEST-21-SYSUSERS/test-3.expected-passwd
Normal file
@ -0,0 +1,4 @@
|
||||
foo:x:301:301::/:/sbin/nologin
|
||||
aaa:x:303:302::/:/sbin/nologin
|
||||
bbb:x:304:302::/:/sbin/nologin
|
||||
ccc:x:305:305::/:/sbin/nologin
|
7
test/TEST-21-SYSUSERS/test-3.input
Normal file
7
test/TEST-21-SYSUSERS/test-3.input
Normal file
@ -0,0 +1,7 @@
|
||||
g hoge 300 - -
|
||||
u foo 301 - -
|
||||
|
||||
g baz 302 - -
|
||||
u aaa 303:302 - -
|
||||
u bbb 304:302 - -
|
||||
u ccc 305 - -
|
1
test/TEST-21-SYSUSERS/test-4.expected-group
Normal file
1
test/TEST-21-SYSUSERS/test-4.expected-group
Normal file
@ -0,0 +1 @@
|
||||
xxx:x:310:
|
2
test/TEST-21-SYSUSERS/test-4.expected-passwd
Normal file
2
test/TEST-21-SYSUSERS/test-4.expected-passwd
Normal file
@ -0,0 +1,2 @@
|
||||
yyy:x:311:310::/:/sbin/nologin
|
||||
xxx:x:312:310::/:/sbin/nologin
|
3
test/TEST-21-SYSUSERS/test-4.input
Normal file
3
test/TEST-21-SYSUSERS/test-4.input
Normal file
@ -0,0 +1,3 @@
|
||||
g xxx 310
|
||||
u yyy 311:310
|
||||
u xxx 312:310
|
49
test/TEST-21-SYSUSERS/test.sh
Executable file
49
test/TEST-21-SYSUSERS/test.sh
Executable file
@ -0,0 +1,49 @@
|
||||
#!/bin/bash
|
||||
# -*- mode: shell-script; indent-tabs-mode: nil; sh-basic-offset: 4; -*-
|
||||
# ex: ts=8 sw=4 sts=4 et filetype=sh
|
||||
set -e
|
||||
TEST_DESCRIPTION="Sysuser-related tests"
|
||||
|
||||
. $TEST_BASE_DIR/test-functions
|
||||
|
||||
test_setup() {
|
||||
mkdir -p $TESTDIR/etc $TESTDIR/usr/lib/sysusers.d $TESTDIR/tmp
|
||||
}
|
||||
|
||||
test_run() {
|
||||
# ensure our build of systemd-sysusers is run
|
||||
PATH=${BUILD_DIR}:$PATH
|
||||
|
||||
# happy tests
|
||||
for f in test-*.input; do
|
||||
echo "*** Running $f"
|
||||
rm -f $TESTDIR/etc/*
|
||||
cp $f $TESTDIR/usr/lib/sysusers.d/test.conf
|
||||
systemd-sysusers --root=$TESTDIR
|
||||
|
||||
if ! diff -u $TESTDIR/etc/passwd ${f%.*}.expected-passwd; then
|
||||
echo "**** Unexpected output for $f"
|
||||
exit 1
|
||||
fi
|
||||
if ! diff -u $TESTDIR/etc/group ${f%.*}.expected-group; then
|
||||
echo "**** Unexpected output for $f"
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
|
||||
# tests for error conditions
|
||||
for f in unhappy-*.input; do
|
||||
echo "*** Running test $f"
|
||||
rm -f $TESTDIR/etc/*
|
||||
cp $f $TESTDIR/usr/lib/sysusers.d/test.conf
|
||||
systemd-sysusers --root=$TESTDIR 2> /dev/null
|
||||
journalctl -t systemd-sysusers -o cat | tail -n1 > $TESTDIR/tmp/err
|
||||
if ! diff -u $TESTDIR/tmp/err ${f%.*}.expected-err; then
|
||||
echo "**** Unexpected error output for $f"
|
||||
cat $TESTDIR/tmp/err
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
do_test "$@"
|
1
test/TEST-21-SYSUSERS/unhappy-1.expected-err
Normal file
1
test/TEST-21-SYSUSERS/unhappy-1.expected-err
Normal file
@ -0,0 +1 @@
|
||||
Failed to parse UID: '9999999999': Numerical result out of range
|
1
test/TEST-21-SYSUSERS/unhappy-1.input
Normal file
1
test/TEST-21-SYSUSERS/unhappy-1.input
Normal file
@ -0,0 +1 @@
|
||||
u u1 9999999999 - -
|
1
test/TEST-21-SYSUSERS/unhappy-2.expected-err
Normal file
1
test/TEST-21-SYSUSERS/unhappy-2.expected-err
Normal file
@ -0,0 +1 @@
|
||||
Failed to create u1: please create GID 100
|
2
test/TEST-21-SYSUSERS/unhappy-2.input
Normal file
2
test/TEST-21-SYSUSERS/unhappy-2.input
Normal file
@ -0,0 +1,2 @@
|
||||
# it is not allowed to create groups implicitely in the uid:gid syntax
|
||||
u u1 100:100 -
|
Loading…
Reference in New Issue
Block a user