diff options
author | Colin Guthrie <colin@mageia.org> | 2014-10-29 14:03:41 +0000 |
---|---|---|
committer | Colin Guthrie <colin@mageia.org> | 2014-10-30 13:38:10 +0000 |
commit | e3c72c21d62aadabf4df436c3e2c7219eeeccc1c (patch) | |
tree | 875b718acf386df8a7550895b25c7495c0919caf /src/sysusers/sysusers.c | |
parent | aba248ee6b1eb10baf3d89eca2ad7569459af6ab (diff) |
sysusers: Preserve ownership and mode on /etc/passwd and friends
When running sysusers we would clobber file ownership and permissions
on the files /etc/passwd, /etc/group and /etc/[g]shadow.
This simply preserves the ownership and mode if existing files are
found.
Diffstat (limited to 'src/sysusers/sysusers.c')
-rw-r--r-- | src/sysusers/sysusers.c | 61 |
1 files changed, 41 insertions, 20 deletions
diff --git a/src/sysusers/sysusers.c b/src/sysusers/sysusers.c index 9b9be96a0a..c133dc5f10 100644 --- a/src/sysusers/sysusers.c +++ b/src/sysusers/sysusers.c @@ -358,6 +358,7 @@ static int write_files(void) { _cleanup_fclose_ FILE *passwd = NULL, *group = NULL, *shadow = NULL, *gshadow = NULL; _cleanup_free_ char *passwd_tmp = NULL, *group_tmp = NULL, *shadow_tmp = NULL, *gshadow_tmp = NULL; const char *passwd_path = NULL, *group_path = NULL, *shadow_path = NULL, *gshadow_path = NULL; + struct stat st; bool group_changed = false; Iterator iterator; Item *i; @@ -372,15 +373,17 @@ static int write_files(void) { if (r < 0) goto finish; - if (fchmod(fileno(group), 0644) < 0) { - r = -errno; - goto finish; - } - original = fopen(group_path, "re"); if (original) { struct group *gr; + if (fstat(fileno(original), &st) < 0 || + fchmod(fileno(group), st.st_mode & 07777) < 0 || + fchown(fileno(group), st.st_uid, st.st_gid) < 0) { + r = -errno; + goto finish; + } + errno = 0; while ((gr = fgetgrent(original))) { /* Safety checks against name and GID @@ -418,6 +421,9 @@ static int write_files(void) { } else if (errno != ENOENT) { r = -errno; goto finish; + } else if (fchmod(fileno(group), 0644) < 0) { + r = -errno; + goto finish; } HASHMAP_FOREACH(i, todo_gids, iterator) { @@ -449,15 +455,17 @@ static int write_files(void) { if (r < 0) goto finish; - if (fchmod(fileno(gshadow), 0000) < 0) { - r = -errno; - goto finish; - } - original = fopen(gshadow_path, "re"); if (original) { struct sgrp *sg; + if (fstat(fileno(original), &st) < 0 || + fchmod(fileno(gshadow), st.st_mode & 07777) < 0 || + fchown(fileno(gshadow), st.st_uid, st.st_gid) < 0) { + r = -errno; + goto finish; + } + errno = 0; while ((sg = fgetsgent(original))) { @@ -483,6 +491,9 @@ static int write_files(void) { } else if (errno != ENOENT) { r = -errno; goto finish; + } else if (fchmod(fileno(gshadow), 0000) < 0) { + r = -errno; + goto finish; } HASHMAP_FOREACH(i, todo_gids, iterator) { @@ -513,15 +524,17 @@ static int write_files(void) { if (r < 0) goto finish; - if (fchmod(fileno(passwd), 0644) < 0) { - r = -errno; - goto finish; - } - original = fopen(passwd_path, "re"); if (original) { struct passwd *pw; + if (fstat(fileno(original), &st) < 0 || + fchmod(fileno(passwd), st.st_mode & 07777) < 0 || + fchown(fileno(passwd), st.st_uid, st.st_gid) < 0) { + r = -errno; + goto finish; + } + errno = 0; while ((pw = fgetpwent(original))) { @@ -552,6 +565,9 @@ static int write_files(void) { } else if (errno != ENOENT) { r = -errno; goto finish; + } else if (fchmod(fileno(passwd), 0644) < 0) { + r = -errno; + goto finish; } HASHMAP_FOREACH(i, todo_uids, iterator) { @@ -596,15 +612,17 @@ static int write_files(void) { if (r < 0) goto finish; - if (fchmod(fileno(shadow), 0000) < 0) { - r = -errno; - goto finish; - } - original = fopen(shadow_path, "re"); if (original) { struct spwd *sp; + if (fstat(fileno(original), &st) < 0 || + fchmod(fileno(shadow), st.st_mode & 07777) < 0 || + fchown(fileno(shadow), st.st_uid, st.st_gid) < 0) { + r = -errno; + goto finish; + } + errno = 0; while ((sp = fgetspent(original))) { @@ -629,6 +647,9 @@ static int write_files(void) { } else if (errno != ENOENT) { r = -errno; goto finish; + } else if (fchmod(fileno(shadow), 0000) < 0) { + r = -errno; + goto finish; } lstchg = (long) (now(CLOCK_REALTIME) / USEC_PER_DAY); |