Discussion:
[PATCH 0/3] using firstboot and sysusers to construct an initramfs
(too old to reply)
Ivan Shapovalov
2015-02-25 23:46:22 UTC
Permalink
Hi there.

These patches allow using firstboot and sysusers together to construct an
initramfs with a fully functional emergency.service and rescue.service.

Moreover, they allow to build a "clean" passwd for the initramfs and don't
resort to copying it from the host system (as it has been done in Arch's
mkinitcpio).

The first one allows sysusers to take configuration from the real root
but to apply it to a specified alternate root.

The next two patches fix an apparent integration problem between firstboot
and sysusers, as previously described here:
http://lists.freedesktop.org/archives/systemd-devel/2015-February/028355.html

All in all, with this series I'm able to do a simple

systemd-firstboot --root="$BUILDROOT" --root-password=""
systemd-sysusers --dest-root="$BUILDROOT"

and, after adding respective units and /sbin/sulogin to the initramfs,
to use "rd.systemd.unit=rescue.target" as a complete alternative to pre-systemd
arch-specific "break=premount" kernel parameter.

Ivan Shapovalov (3):
sysusers: allow separate alternate roots for configs and modifications
firstboot: set all spwd fields to -1 for consistency with sysusers
sysusers: do not reject users with already present /etc/shadow entries

src/firstboot/firstboot.c | 6 +--
src/sysusers/sysusers.c | 120 +++++++++++++++++++++++++++++-----------------
2 files changed, 78 insertions(+), 48 deletions(-)
--
2.3.0
Ivan Shapovalov
2015-02-25 23:46:23 UTC
Permalink
This is useful, for example, to create system accounts on an initramfs
using the host's configuration.
---
src/sysusers/sysusers.c | 97 +++++++++++++++++++++++++++++++++----------------
1 file changed, 66 insertions(+), 31 deletions(-)

diff --git a/src/sysusers/sysusers.c b/src/sysusers/sysusers.c
index 0b5668a..9d39bd4 100644
--- a/src/sysusers/sysusers.c
+++ b/src/sysusers/sysusers.c
@@ -64,7 +64,7 @@ typedef struct Item {
bool todo_group:1;
} Item;

-static char *arg_root = NULL;
+static char *arg_root_config = NULL, *arg_root_dest = NULL;

static const char conf_file_dirs[] = CONF_DIRS_NULSTR("sysusers");

@@ -79,7 +79,7 @@ static uid_t search_uid = UID_INVALID;
static UidRange *uid_range = NULL;
static unsigned n_uid_range = 0;

-#define fix_root(x) (arg_root ? strjoina(arg_root, x) : x)
+#define fix_root_dest(x) (arg_root_dest ? strjoina(arg_root_dest, x) : x)

static int load_user_database(void) {
_cleanup_fclose_ FILE *f = NULL;
@@ -87,7 +87,7 @@ static int load_user_database(void) {
struct passwd *pw;
int r;

- passwd_path = fix_root("/etc/passwd");
+ passwd_path = fix_root_dest("/etc/passwd");
f = fopen(passwd_path, "re");
if (!f)
return errno == ENOENT ? 0 : -errno;
@@ -139,7 +139,7 @@ static int load_group_database(void) {
struct group *gr;
int r;

- group_path = fix_root("/etc/group");
+ group_path = fix_root_dest("/etc/group");
f = fopen(group_path, "re");
if (!f)
return errno == ENOENT ? 0 : -errno;
@@ -368,7 +368,7 @@ static int write_files(void) {
_cleanup_fclose_ FILE *original = NULL;

/* First we update the actual group list file */
- group_path = fix_root("/etc/group");
+ group_path = fix_root_dest("/etc/group");
r = fopen_temporary_label("/etc/group", group_path, &group, &group_tmp);
if (r < 0)
goto finish;
@@ -447,7 +447,7 @@ static int write_files(void) {
}

/* OK, now also update the shadow file for the group list */
- gshadow_path = fix_root("/etc/gshadow");
+ gshadow_path = fix_root_dest("/etc/gshadow");
r = fopen_temporary_label("/etc/gshadow", gshadow_path, &gshadow, &gshadow_tmp);
if (r < 0)
goto finish;
@@ -513,7 +513,7 @@ static int write_files(void) {
long lstchg;

/* First we update the user database itself */
- passwd_path = fix_root("/etc/passwd");
+ passwd_path = fix_root_dest("/etc/passwd");
r = fopen_temporary_label("/etc/passwd", passwd_path, &passwd, &passwd_tmp);
if (r < 0)
goto finish;
@@ -598,7 +598,7 @@ static int write_files(void) {
}

/* The we update the shadow database */
- shadow_path = fix_root("/etc/shadow");
+ shadow_path = fix_root_dest("/etc/shadow");
r = fopen_temporary_label("/etc/shadow", shadow_path, &shadow, &shadow_tmp);
if (r < 0)
goto finish;
@@ -772,7 +772,7 @@ static int uid_is_ok(uid_t uid, const char *name) {
return 0;

/* Let's also check via NSS, to avoid UID clashes over LDAP and such, just in case */
- if (!arg_root) {
+ if (!arg_root_dest) {
errno = 0;
p = getpwuid(uid);
if (p)
@@ -792,10 +792,10 @@ static int uid_is_ok(uid_t uid, const char *name) {
return 1;
}

-static int root_stat(const char *p, struct stat *st) {
+static int root_dest_stat(const char *p, struct stat *st) {
const char *fix;

- fix = fix_root(p);
+ fix = fix_root_dest(p);
if (stat(fix, st) < 0)
return -errno;

@@ -811,7 +811,7 @@ static int read_id_from_file(Item *i, uid_t *_uid, gid_t *_gid) {
assert(i);

/* First, try to get the gid directly */
- if (_gid && i->gid_path && root_stat(i->gid_path, &st) >= 0) {
+ if (_gid && i->gid_path && root_dest_stat(i->gid_path, &st) >= 0) {
gid = st.st_gid;
found_gid = true;
}
@@ -819,7 +819,7 @@ static int read_id_from_file(Item *i, uid_t *_uid, gid_t *_gid) {
/* Then, try to get the uid directly */
if ((_uid || (_gid && !found_gid))
&& i->uid_path
- && root_stat(i->uid_path, &st) >= 0) {
+ && root_dest_stat(i->uid_path, &st) >= 0) {

uid = st.st_uid;
found_uid = true;
@@ -837,7 +837,7 @@ static int read_id_from_file(Item *i, uid_t *_uid, gid_t *_gid) {
if (found_gid) {
uid = (uid_t) gid;
found_uid = true;
- } else if (root_stat(i->gid_path, &st) >= 0) {
+ } else if (root_dest_stat(i->gid_path, &st) >= 0) {
uid = (uid_t) st.st_gid;
found_uid = true;
}
@@ -875,7 +875,7 @@ static int add_user(Item *i) {
return 0;
}

- if (!arg_root) {
+ if (!arg_root_dest) {
struct passwd *p;
struct spwd *sp;

@@ -999,7 +999,7 @@ static int gid_is_ok(gid_t gid) {
if (hashmap_contains(database_uid, UID_TO_PTR(gid)))
return 0;

- if (!arg_root) {
+ if (!arg_root_dest) {
errno = 0;
g = getgrgid(gid);
if (g)
@@ -1034,7 +1034,7 @@ static int add_group(Item *i) {
}

/* Also check NSS */
- if (!arg_root) {
+ if (!arg_root_dest) {
struct group *g;

errno = 0;
@@ -1691,7 +1691,7 @@ static int read_config_file(const char *fn, bool ignore_enoent) {
if (streq(fn, "-"))
f = stdin;
else {
- r = search_and_fopen_nulstr(fn, "re", arg_root, conf_file_dirs, &rf);
+ r = search_and_fopen_nulstr(fn, "re", arg_root_config, conf_file_dirs, &rf);
if (r < 0) {
if (ignore_enoent && r == -ENOENT)
return 0;
@@ -1752,25 +1752,46 @@ static void help(void) {
"Creates system user accounts.\n\n"
" -h --help Show this help\n"
" --version Show package version\n"
- " --root=PATH Operate on an alternate filesystem root\n"
+ " --root=PATH Operate on an alternate filesystem root (equivalent to a combination of --dest-root and --config-root)\n"
+ " --dest-root=PATH Create user accounts on an alternate filesystem root\n"
+ " --config-root=PATH Search for the configuration files on an alternate filesystem root\n"
, program_invocation_short_name);
}

+static int set_arg_root(char **arg_root, const char *option)
+{
+ assert(arg_root);
+ assert(option);
+
+ free(*arg_root);
+ *arg_root = path_make_absolute_cwd(option);
+ if(!*arg_root)
+ return log_oom();
+
+ path_kill_slashes(*arg_root);
+
+ return 0;
+}
+
static int parse_argv(int argc, char *argv[]) {

enum {
ARG_VERSION = 0x100,
ARG_ROOT,
+ ARG_ROOT_CONFIG,
+ ARG_ROOT_DEST
};

static const struct option options[] = {
- { "help", no_argument, NULL, 'h' },
- { "version", no_argument, NULL, ARG_VERSION },
- { "root", required_argument, NULL, ARG_ROOT },
+ { "help", no_argument, NULL, 'h' },
+ { "version", no_argument, NULL, ARG_VERSION },
+ { "root", required_argument, NULL, ARG_ROOT },
+ { "dest-root", required_argument, NULL, ARG_ROOT_DEST },
+ { "config-root", required_argument, NULL, ARG_ROOT_CONFIG },
{}
};

- int c;
+ int c, r;

assert(argc >= 0);
assert(argv);
@@ -1789,12 +1810,25 @@ static int parse_argv(int argc, char *argv[]) {
return 0;

case ARG_ROOT:
- free(arg_root);
- arg_root = path_make_absolute_cwd(optarg);
- if (!arg_root)
- return log_oom();
+ r = set_arg_root(&arg_root_config, optarg);
+ if (r < 0)
+ return r;

- path_kill_slashes(arg_root);
+ r = set_arg_root(&arg_root_dest, optarg);
+ if (r < 0)
+ return r;
+ break;
+
+ case ARG_ROOT_CONFIG:
+ r = set_arg_root(&arg_root_config, optarg);
+ if (r < 0)
+ return r;
+ break;
+
+ case ARG_ROOT_DEST:
+ r = set_arg_root(&arg_root_dest, optarg);
+ if (r < 0)
+ return r;
break;

case '?':
@@ -1843,7 +1877,7 @@ int main(int argc, char *argv[]) {
_cleanup_strv_free_ char **files = NULL;
char **f;

- r = conf_files_list_nulstr(&files, ".conf", arg_root, conf_file_dirs);
+ r = conf_files_list_nulstr(&files, ".conf", arg_root_config, conf_file_dirs);
if (r < 0) {
log_error_errno(r, "Failed to enumerate sysusers.d files: %m");
goto finish;
@@ -1869,7 +1903,7 @@ int main(int argc, char *argv[]) {
if (r < 0)
goto finish;

- lock = take_password_lock(arg_root);
+ lock = take_password_lock(arg_root_dest);
if (lock < 0) {
log_error_errno(lock, "Failed to take lock: %m");
goto finish;
@@ -1918,7 +1952,8 @@ finish:
free_database(database_user, database_uid);
free_database(database_group, database_gid);

- free(arg_root);
+ free(arg_root_config);
+ free(arg_root_dest);

return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
}
--
2.3.0
Lennart Poettering
2015-04-23 12:11:02 UTC
Permalink
Post by Ivan Shapovalov
This is useful, for example, to create system accounts on an initramfs
using the host's configuration.
Hmm, but you can already do this, by specifiying the config files on
the command line, no?

Lennart
--
Lennart Poettering, Red Hat
Ivan Shapovalov
2015-04-23 14:46:15 UTC
Permalink
Post by Lennart Poettering
Post by Ivan Shapovalov
This is useful, for example, to create system accounts on an
initramfs
using the host's configuration.
Hmm, but you can already do this, by specifiying the config files on
the command line, no?
Actually, this means duplicating the logic of determining of the
directory list (/usr/lib vs /lib, ...).
--
Ivan Shapovalov / intelfx /
Lennart Poettering
2015-04-23 14:48:13 UTC
Permalink
Post by Ivan Shapovalov
Post by Lennart Poettering
Post by Ivan Shapovalov
This is useful, for example, to create system accounts on an initramfs
using the host's configuration.
Hmm, but you can already do this, by specifiying the config files on
the command line, no?
Actually, this means duplicating the logic of determining of the
directory list (/usr/lib vs /lib, ...).
True, but it's not *that* complex in that case...

Lennart
--
Lennart Poettering, Red Hat
Ivan Shapovalov
2015-04-23 15:09:21 UTC
Permalink
Post by Lennart Poettering
Post by Ivan Shapovalov
Post by Lennart Poettering
Post by Ivan Shapovalov
This is useful, for example, to create system accounts on an initramfs
using the host's configuration.
Hmm, but you can already do this, by specifiying the config files on
the command line, no?
Actually, this means duplicating the logic of determining of the
directory list (/usr/lib vs /lib, ...).
True, but it's not *that* complex in that case...
Not really, because it is then also needed to do priority-overriding
of the configuration snippets by hand. I would really like to avoid re
-implementing this logic.

There is an alternative to bind-mount all configuration directories
into the destination root, but it's not "atomic" against killing of
the process (if we get killed in between, stale bind mounts will
remain). So I won't like to do this either. I'm sure that mkinitcpio
maintainer in arch will not accept this solution as well.

Any other options?
--
Ivan Shapovalov / intelfx /
Lennart Poettering
2015-04-23 15:15:58 UTC
Permalink
Post by Ivan Shapovalov
Post by Lennart Poettering
Post by Ivan Shapovalov
Post by Lennart Poettering
Post by Ivan Shapovalov
This is useful, for example, to create system accounts on an initramfs
using the host's configuration.
Hmm, but you can already do this, by specifiying the config files on
the command line, no?
Actually, this means duplicating the logic of determining of the
directory list (/usr/lib vs /lib, ...).
True, but it's not *that* complex in that case...
Not really, because it is then also needed to do priority-overriding
of the configuration snippets by hand. I would really like to avoid re
-implementing this logic.
There is an alternative to bind-mount all configuration directories
into the destination root, but it's not "atomic" against killing of
the process (if we get killed in between, stale bind mounts will
remain). So I won't like to do this either. I'm sure that mkinitcpio
maintainer in arch will not accept this solution as well.
Any other options?
Hmm, I don't really see the use for this I must say. That said, I
figure I would accept a patch that adds a new switch
--configuration-root= or so, similar to your original patch, but
leaves --root= as it is right now, and really only adds a new
--configuration-root= that if specified overrides the root directory
otherwise specified for the reading of the configuration files.

If you add this tmpfiles should probably get something similar, to
make this match up nicely...

Lennart
--
Lennart Poettering, Red Hat
Ivan Shapovalov
2015-04-23 19:37:13 UTC
Permalink
Post by Lennart Poettering
Post by Ivan Shapovalov
Post by Lennart Poettering
Post by Ivan Shapovalov
Post by Lennart Poettering
)
Post by Ivan Shapovalov
This is useful, for example, to create system accounts on an
initramfs
using the host's configuration.
Hmm, but you can already do this, by specifiying the config files on
the command line, no?
Actually, this means duplicating the logic of determining of the
directory list (/usr/lib vs /lib, ...).
True, but it's not *that* complex in that case...
Not really, because it is then also needed to do priority
-overriding
of the configuration snippets by hand. I would really like to avoid re
-implementing this logic.
There is an alternative to bind-mount all configuration directories
into the destination root, but it's not "atomic" against killing of
the process (if we get killed in between, stale bind mounts will
remain). So I won't like to do this either. I'm sure that
mkinitcpio
maintainer in arch will not accept this solution as well.
Any other options?
Hmm, I don't really see the use for this I must say. That said, I
figure I would accept a patch that adds a new switch
--configuration-root= or so, similar to your original patch, but
leaves --root= as it is right now, and really only adds a new
--configuration-root= that if specified overrides the root directory
otherwise specified for the reading of the configuration files.
If you add this tmpfiles should probably get something similar, to
make this match up nicely...
Actually, thinking about this once more, I've realized that my usecase
is broken. I wanted to use systemd-sysusers to generate new
passwd/group for the initcpio, but never realized that newly created
UIDs and GIDs can mismatch the host ones (and we are copying files
from the host).

So, disregard this patch, there is indeed no usecase so far.
--
Ivan Shapovalov / intelfx /
Ivan Shapovalov
2015-02-25 23:46:24 UTC
Permalink
---
src/firstboot/firstboot.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/src/firstboot/firstboot.c b/src/firstboot/firstboot.c
index a765d6d..a37ca17 100644
--- a/src/firstboot/firstboot.c
+++ b/src/firstboot/firstboot.c
@@ -525,9 +525,9 @@ static int process_root_password(void) {

struct spwd item = {
.sp_namp = (char*) "root",
- .sp_min = 0,
- .sp_max = 99999,
- .sp_warn = 7,
+ .sp_min = -1,
+ .sp_max = -1,
+ .sp_warn = -1,
.sp_inact = -1,
.sp_expire = -1,
.sp_flag = (unsigned long) -1, /* this appears to be what everybody does ... */
--
2.3.0
Zbigniew Jędrzejewski-Szmek
2015-03-07 14:09:11 UTC
Permalink
Post by Ivan Shapovalov
---
src/firstboot/firstboot.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
Applied.

Zbyszek
Ivan Shapovalov
2015-02-25 23:46:25 UTC
Permalink
This is needed to interoperate firstboot and sysusers. The former one is started
first, and it writes only /etc/shadow when it is told to set the root password.
It's better to relax checks here than to duplicate functionality in firstboot.
---
src/sysusers/sysusers.c | 23 +++++++++--------------
1 file changed, 9 insertions(+), 14 deletions(-)

diff --git a/src/sysusers/sysusers.c b/src/sysusers/sysusers.c
index 9d39bd4..ec3e8ad 100644
--- a/src/sysusers/sysusers.c
+++ b/src/sysusers/sysusers.c
@@ -603,6 +603,8 @@ static int write_files(void) {
if (r < 0)
goto finish;

+ lstchg = (long) (now(CLOCK_REALTIME) / USEC_PER_DAY);
+
original = fopen(shadow_path, "re");
if (original) {
struct spwd *sp;
@@ -616,8 +618,13 @@ static int write_files(void) {

i = hashmap_get(users, sp->sp_namp);
if (i && i->todo_user) {
- r = -EEXIST;
- goto finish;
+ /* we will update the existing entry */
+ sp->sp_lstchg = lstchg;
+
+ /* 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));
}

errno = 0;
@@ -640,7 +647,6 @@ static int write_files(void) {
goto finish;
}

- lstchg = (long) (now(CLOCK_REALTIME) / USEC_PER_DAY);
HASHMAP_FOREACH(i, todo_uids, iterator) {
struct spwd n = {
.sp_namp = i->name,
@@ -877,7 +883,6 @@ static int add_user(Item *i) {

if (!arg_root_dest) {
struct passwd *p;
- struct spwd *sp;

/* Also check NSS */
errno = 0;
@@ -893,16 +898,6 @@ static int add_user(Item *i) {
}
if (!IN_SET(errno, 0, ENOENT))
return log_error_errno(errno, "Failed to check if user %s already exists: %m", i->name);
-
- /* And shadow too, just to be sure */
- errno = 0;
- sp = getspnam(i->name);
- if (sp) {
- log_error("User %s already exists in shadow database, but not in user database.", i->name);
- return -EBADMSG;
- }
- if (!IN_SET(errno, 0, ENOENT))
- return log_error_errno(errno, "Failed to check if user %s already exists in shadow database: %m", i->name);
}

/* Try to use the suggested numeric uid */
--
2.3.0
Zbigniew Jędrzejewski-Szmek
2015-03-07 14:09:46 UTC
Permalink
Post by Ivan Shapovalov
This is needed to interoperate firstboot and sysusers. The former one is started
first, and it writes only /etc/shadow when it is told to set the root password.
It's better to relax checks here than to duplicate functionality in firstboot.
Does not apply on top of git... Could you rebase?

Zbyszek
Post by Ivan Shapovalov
---
src/sysusers/sysusers.c | 23 +++++++++--------------
1 file changed, 9 insertions(+), 14 deletions(-)
diff --git a/src/sysusers/sysusers.c b/src/sysusers/sysusers.c
index 9d39bd4..ec3e8ad 100644
--- a/src/sysusers/sysusers.c
+++ b/src/sysusers/sysusers.c
@@ -603,6 +603,8 @@ static int write_files(void) {
if (r < 0)
goto finish;
+ lstchg = (long) (now(CLOCK_REALTIME) / USEC_PER_DAY);
+
original = fopen(shadow_path, "re");
if (original) {
struct spwd *sp;
@@ -616,8 +618,13 @@ static int write_files(void) {
i = hashmap_get(users, sp->sp_namp);
if (i && i->todo_user) {
- r = -EEXIST;
- goto finish;
+ /* we will update the existing entry */
+ sp->sp_lstchg = lstchg;
+
+ /* 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));
}
errno = 0;
@@ -640,7 +647,6 @@ static int write_files(void) {
goto finish;
}
- lstchg = (long) (now(CLOCK_REALTIME) / USEC_PER_DAY);
HASHMAP_FOREACH(i, todo_uids, iterator) {
struct spwd n = {
.sp_namp = i->name,
@@ -877,7 +883,6 @@ static int add_user(Item *i) {
if (!arg_root_dest) {
struct passwd *p;
- struct spwd *sp;
/* Also check NSS */
errno = 0;
@@ -893,16 +898,6 @@ static int add_user(Item *i) {
}
if (!IN_SET(errno, 0, ENOENT))
return log_error_errno(errno, "Failed to check if user %s already exists: %m", i->name);
-
- /* And shadow too, just to be sure */
- errno = 0;
- sp = getspnam(i->name);
- if (sp) {
- log_error("User %s already exists in shadow database, but not in user database.", i->name);
- return -EBADMSG;
- }
- if (!IN_SET(errno, 0, ENOENT))
- return log_error_errno(errno, "Failed to check if user %s already exists in shadow database: %m", i->name);
}
/* Try to use the suggested numeric uid */
--
2.3.0
_______________________________________________
systemd-devel mailing list
http://lists.freedesktop.org/mailman/listinfo/systemd-devel
Ivan Shapovalov
2015-03-07 15:11:32 UTC
Permalink
This is needed to interoperate firstboot and sysusers. The former one is started
first, and it writes only /etc/shadow when it is told to set the root password.
It's better to relax checks here than to duplicate functionality in firstboot.
---

v2: rebased on top of master

src/sysusers/sysusers.c | 23 +++++++++--------------
1 file changed, 9 insertions(+), 14 deletions(-)

diff --git a/src/sysusers/sysusers.c b/src/sysusers/sysusers.c
index 0b5668a..9c59792 100644
--- a/src/sysusers/sysusers.c
+++ b/src/sysusers/sysusers.c
@@ -603,6 +603,8 @@ static int write_files(void) {
if (r < 0)
goto finish;

+ lstchg = (long) (now(CLOCK_REALTIME) / USEC_PER_DAY);
+
original = fopen(shadow_path, "re");
if (original) {
struct spwd *sp;
@@ -616,8 +618,13 @@ static int write_files(void) {

i = hashmap_get(users, sp->sp_namp);
if (i && i->todo_user) {
- r = -EEXIST;
- goto finish;
+ /* we will update the existing entry */
+ sp->sp_lstchg = lstchg;
+
+ /* 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));
}

errno = 0;
@@ -640,7 +647,6 @@ static int write_files(void) {
goto finish;
}

- lstchg = (long) (now(CLOCK_REALTIME) / USEC_PER_DAY);
HASHMAP_FOREACH(i, todo_uids, iterator) {
struct spwd n = {
.sp_namp = i->name,
@@ -877,7 +883,6 @@ static int add_user(Item *i) {

if (!arg_root) {
struct passwd *p;
- struct spwd *sp;

/* Also check NSS */
errno = 0;
@@ -893,16 +898,6 @@ static int add_user(Item *i) {
}
if (!IN_SET(errno, 0, ENOENT))
return log_error_errno(errno, "Failed to check if user %s already exists: %m", i->name);
-
- /* And shadow too, just to be sure */
- errno = 0;
- sp = getspnam(i->name);
- if (sp) {
- log_error("User %s already exists in shadow database, but not in user database.", i->name);
- return -EBADMSG;
- }
- if (!IN_SET(errno, 0, ENOENT))
- return log_error_errno(errno, "Failed to check if user %s already exists in shadow database: %m", i->name);
}

/* Try to use the suggested numeric uid */
--
2.3.1
Zbigniew Jędrzejewski-Szmek
2015-03-07 18:12:10 UTC
Permalink
Post by Ivan Shapovalov
This is needed to interoperate firstboot and sysusers. The former one is started
first, and it writes only /etc/shadow when it is told to set the root password.
It's better to relax checks here than to duplicate functionality in firstboot.
Thanks, applied.

Zbyszek
Ivan Shapovalov
2015-02-25 23:53:43 UTC
Permalink
Post by Ivan Shapovalov
Hi there.
These patches allow using firstboot and sysusers together to construct an
initramfs with a fully functional emergency.service and rescue.service.
Moreover, they allow to build a "clean" passwd for the initramfs and don't
resort to copying it from the host system (as it has been done in Arch's
mkinitcpio).
The first one allows sysusers to take configuration from the real root
but to apply it to a specified alternate root.
The next two patches fix an apparent integration problem between firstboot
http://lists.freedesktop.org/archives/systemd-devel/2015-February/028355.html
All in all, with this series I'm able to do a simple
systemd-firstboot --root="$BUILDROOT" --root-password=""
systemd-sysusers --dest-root="$BUILDROOT"
and, after adding respective units and /sbin/sulogin to the initramfs,
to use "rd.systemd.unit=rescue.target" as a complete alternative to pre-systemd
arch-specific "break=premount" kernel parameter.
[...]
Forgot to add Dave Reisner to Cc:.

Dave, what do you think about all this? If this is a bad idea, then I'm
open for suggestions.
I just miss these "break=..." from the pre-systemd era.
--
Ivan Shapovalov / intelfx /
Ivan Shapovalov
2015-03-05 18:09:54 UTC
Permalink
Post by Ivan Shapovalov
Post by Ivan Shapovalov
Hi there.
These patches allow using firstboot and sysusers together to construct an
initramfs with a fully functional emergency.service and rescue.service.
Moreover, they allow to build a "clean" passwd for the initramfs and don't
resort to copying it from the host system (as it has been done in Arch's
mkinitcpio).
The first one allows sysusers to take configuration from the real root
but to apply it to a specified alternate root.
The next two patches fix an apparent integration problem between firstboot
http://lists.freedesktop.org/archives/systemd-devel/2015-February/028355.html
All in all, with this series I'm able to do a simple
systemd-firstboot --root="$BUILDROOT" --root-password=""
systemd-sysusers --dest-root="$BUILDROOT"
and, after adding respective units and /sbin/sulogin to the initramfs,
to use "rd.systemd.unit=rescue.target" as a complete alternative to pre-systemd
arch-specific "break=premount" kernel parameter.
[...]
Forgot to add Dave Reisner to Cc:.
Dave, what do you think about all this? If this is a bad idea, then I'm
open for suggestions.
I just miss these "break=..." from the pre-systemd era.
Anyone?
--
Ivan Shapovalov / intelfx /
Zbigniew Jędrzejewski-Szmek
2015-03-05 18:16:59 UTC
Permalink
Post by Ivan Shapovalov
Post by Ivan Shapovalov
Post by Ivan Shapovalov
Hi there.
These patches allow using firstboot and sysusers together to construct an
initramfs with a fully functional emergency.service and rescue.service.
Moreover, they allow to build a "clean" passwd for the initramfs and don't
resort to copying it from the host system (as it has been done in Arch's
mkinitcpio).
The first one allows sysusers to take configuration from the real root
but to apply it to a specified alternate root.
The next two patches fix an apparent integration problem between firstboot
http://lists.freedesktop.org/archives/systemd-devel/2015-February/028355.html
All in all, with this series I'm able to do a simple
systemd-firstboot --root="$BUILDROOT" --root-password=""
systemd-sysusers --dest-root="$BUILDROOT"
and, after adding respective units and /sbin/sulogin to the initramfs,
to use "rd.systemd.unit=rescue.target" as a complete alternative to pre-systemd
arch-specific "break=premount" kernel parameter.
[...]
Forgot to add Dave Reisner to Cc:.
Dave, what do you think about all this? If this is a bad idea, then I'm
open for suggestions.
I just miss these "break=..." from the pre-systemd era.
Anyone?
2/3 and 3/3 look fine. For 1/3 I was wondering if it wouldn't be simpler
to simply copy the sysuser files into the tree. The semantics are then
clear. But right now, if there are sysuser files in the source root, and
in the destination root, it becomes unclear how to sort and merge them.

Zbyszek
Ivan Shapovalov
2015-03-05 18:42:17 UTC
Permalink
Post by Zbigniew Jędrzejewski-Szmek
Post by Ivan Shapovalov
Post by Ivan Shapovalov
Post by Ivan Shapovalov
Hi there.
These patches allow using firstboot and sysusers together to construct an
initramfs with a fully functional emergency.service and rescue.service.
Moreover, they allow to build a "clean" passwd for the initramfs and don't
resort to copying it from the host system (as it has been done in Arch's
mkinitcpio).
The first one allows sysusers to take configuration from the real root
but to apply it to a specified alternate root.
The next two patches fix an apparent integration problem between firstboot
http://lists.freedesktop.org/archives/systemd-devel/2015-February/028355.html
All in all, with this series I'm able to do a simple
systemd-firstboot --root="$BUILDROOT" --root-password=""
systemd-sysusers --dest-root="$BUILDROOT"
and, after adding respective units and /sbin/sulogin to the initramfs,
to use "rd.systemd.unit=rescue.target" as a complete alternative to pre-systemd
arch-specific "break=premount" kernel parameter.
[...]
Forgot to add Dave Reisner to Cc:.
Dave, what do you think about all this? If this is a bad idea, then I'm
open for suggestions.
I just miss these "break=..." from the pre-systemd era.
Anyone?
2/3 and 3/3 look fine. For 1/3 I was wondering if it wouldn't be simpler
to simply copy the sysuser files into the tree. The semantics are then
clear. But right now, if there are sysuser files in the source root, and
in the destination root, it becomes unclear how to sort and merge them.
Well, the intended semantics are pretty clear as well: simply ignore
configs everywhere except the --config-root. (Just like we ignore
configs in / when --root is given, for example.)

Yes, copying/symlinking sysusers.d directories or individual files into
the initramfs build root is less intrusive from the code perspective.
But what if people add their own sysusers.d (people tend to have crazy
setups...)? That'll need to be worked around.

OTOH, the proposed changes are quite simple, and if needed, people with
strange setups could just rm the generated files.

However, no strong preference.
--
Ivan Shapovalov / intelfx /
Zbigniew Jędrzejewski-Szmek
2015-03-07 14:01:11 UTC
Permalink
Post by Ivan Shapovalov
Post by Zbigniew Jędrzejewski-Szmek
Post by Ivan Shapovalov
Post by Ivan Shapovalov
Post by Ivan Shapovalov
Hi there.
These patches allow using firstboot and sysusers together to construct an
initramfs with a fully functional emergency.service and rescue.service.
Moreover, they allow to build a "clean" passwd for the initramfs and don't
resort to copying it from the host system (as it has been done in Arch's
mkinitcpio).
The first one allows sysusers to take configuration from the real root
but to apply it to a specified alternate root.
The next two patches fix an apparent integration problem between firstboot
http://lists.freedesktop.org/archives/systemd-devel/2015-February/028355.html
All in all, with this series I'm able to do a simple
systemd-firstboot --root="$BUILDROOT" --root-password=""
systemd-sysusers --dest-root="$BUILDROOT"
and, after adding respective units and /sbin/sulogin to the initramfs,
to use "rd.systemd.unit=rescue.target" as a complete alternative to pre-systemd
arch-specific "break=premount" kernel parameter.
[...]
Forgot to add Dave Reisner to Cc:.
Dave, what do you think about all this? If this is a bad idea, then I'm
open for suggestions.
I just miss these "break=..." from the pre-systemd era.
Anyone?
2/3 and 3/3 look fine. For 1/3 I was wondering if it wouldn't be simpler
to simply copy the sysuser files into the tree. The semantics are then
clear. But right now, if there are sysuser files in the source root, and
in the destination root, it becomes unclear how to sort and merge them.
Well, the intended semantics are pretty clear as well: simply ignore
configs everywhere except the --config-root. (Just like we ignore
configs in / when --root is given, for example.)
Right, the semantics are clear as far as the patch goes and they fit your
use case. But I think they would be less intuitive to users in general.
The main idea of sysusers (and tmpfiles) is that after wiping /etc the
can be restored to "factory defaults". If the configuration is created
using external files in --config-root, this property is lost.

Even if you don't intend / don't support wiping /etc, I still see value
in seeing that certain parts of the configuration came from sysusers.
Post by Ivan Shapovalov
Yes, copying/symlinking sysusers.d directories or individual files into
the initramfs build root is less intrusive from the code perspective.
But what if people add their own sysusers.d (people tend to have crazy
setups...)? That'll need to be worked around.
I don't understand. If they do something crazy in the root they are building,
that's ok.

Zbyszek
Ivan Shapovalov
2015-03-07 15:25:19 UTC
Permalink
Post by Zbigniew Jędrzejewski-Szmek
Post by Ivan Shapovalov
Post by Zbigniew Jędrzejewski-Szmek
Post by Ivan Shapovalov
Post by Ivan Shapovalov
Post by Ivan Shapovalov
Hi there.
These patches allow using firstboot and sysusers together to construct an
initramfs with a fully functional emergency.service and rescue.service.
Moreover, they allow to build a "clean" passwd for the initramfs and don't
resort to copying it from the host system (as it has been done in Arch's
mkinitcpio).
The first one allows sysusers to take configuration from the real root
but to apply it to a specified alternate root.
The next two patches fix an apparent integration problem between firstboot
http://lists.freedesktop.org/archives/systemd-devel/2015-February/028355.html
All in all, with this series I'm able to do a simple
systemd-firstboot --root="$BUILDROOT" --root-password=""
systemd-sysusers --dest-root="$BUILDROOT"
and, after adding respective units and /sbin/sulogin to the initramfs,
to use "rd.systemd.unit=rescue.target" as a complete alternative to pre-systemd
arch-specific "break=premount" kernel parameter.
[...]
Forgot to add Dave Reisner to Cc:.
Dave, what do you think about all this? If this is a bad idea, then I'm
open for suggestions.
I just miss these "break=..." from the pre-systemd era.
Anyone?
2/3 and 3/3 look fine. For 1/3 I was wondering if it wouldn't be simpler
to simply copy the sysuser files into the tree. The semantics are then
clear. But right now, if there are sysuser files in the source root, and
in the destination root, it becomes unclear how to sort and merge them.
Well, the intended semantics are pretty clear as well: simply ignore
configs everywhere except the --config-root. (Just like we ignore
configs in / when --root is given, for example.)
Right, the semantics are clear as far as the patch goes and they fit your
use case. But I think they would be less intuitive to users in general.
The main idea of sysusers (and tmpfiles) is that after wiping /etc the
can be restored to "factory defaults". If the configuration is created
using external files in --config-root, this property is lost.
Even if you don't intend / don't support wiping /etc, I still see value
in seeing that certain parts of the configuration came from sysusers.
Post by Ivan Shapovalov
Yes, copying/symlinking sysusers.d directories or individual files into
the initramfs build root is less intrusive from the code perspective.
But what if people add their own sysusers.d (people tend to have crazy
setups...)? That'll need to be worked around.
I don't understand. If they do something crazy in the root they are building,
that's ok.
I mean that the code which will do the building will have to work around
if sysusers.d directories already exist due to some user-imposed
craziness. But well, this is a minor issue. If you are sure that this
functionality has no place in sysusers - let it be so.
--
Ivan Shapovalov / intelfx /
Loading...