[systemd-devel] [PATCH] sysusers: Preserve ownership and mode on /etc/passwd and friends

Colin Guthrie gmane at colin.guthr.ie
Wed Oct 29 10:27:28 PDT 2014


FWIW, I tested this now and it seems to have worked fine and properly
preserved both mode and ownership of the files in question.

OK to push this one?

Col

Colin Guthrie wrote on 29/10/14 14:34:
> 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.
> ---
>  src/sysusers/sysusers.c | 61 +++++++++++++++++++++++++++++++++----------------
>  1 file changed, 41 insertions(+), 20 deletions(-)
> 
> diff --git a/src/sysusers/sysusers.c b/src/sysusers/sysusers.c
> index 9b9be96..c133dc5 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);
> 


-- 

Colin Guthrie
gmane(at)colin.guthr.ie
http://colin.guthr.ie/

Day Job:
  Tribalogic Limited http://www.tribalogic.net/
Open Source:
  Mageia Contributor http://www.mageia.org/
  PulseAudio Hacker http://www.pulseaudio.org/
  Trac Hacker http://trac.edgewall.org/



More information about the systemd-devel mailing list