]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
user-util: add new wrappers for reading/writing {passwd,shadow,gshadow} database...
authorFranck Bui <fbui@suse.com>
Wed, 21 Mar 2018 14:26:02 +0000 (15:26 +0100)
committerLennart Poettering <lennart@poettering.net>
Wed, 21 Mar 2018 14:26:02 +0000 (15:26 +0100)
The API povided by the glibc is too error-prone as one has to deal directly
with errno in order to detect if errors occured.

Suggested by Zbigniew.

src/basic/user-util.c
src/basic/user-util.h
src/firstboot/firstboot.c
src/sysusers/sysusers.c

index ceb71b61e8d1586bffdc4d27c5f2ee997cc1675f..0f750be65f17be18558ea16469d2eb1517924bcb 100644 (file)
@@ -734,3 +734,123 @@ bool synthesize_nobody(void) {
         return cache;
 #endif
 }
+
+int putpwent_sane(const struct passwd *pw, FILE *stream) {
+        assert(pw);
+        assert(stream);
+
+        errno = 0;
+        if (putpwent(pw, stream) != 0)
+                return errno > 0 ? -errno : -EIO;
+
+        return 0;
+}
+
+int putspent_sane(const struct spwd *sp, FILE *stream) {
+        assert(sp);
+        assert(stream);
+
+        errno = 0;
+        if (putspent(sp, stream) != 0)
+                return errno > 0 ? -errno : -EIO;
+
+        return 0;
+}
+
+int putgrent_sane(const struct group *gr, FILE *stream) {
+        assert(gr);
+        assert(stream);
+
+        errno = 0;
+        if (putgrent(gr, stream) != 0)
+                return errno > 0 ? -errno : -EIO;
+
+        return 0;
+}
+
+#if ENABLE_GSHADOW
+int putsgent_sane(const struct sgrp *sg, FILE *stream) {
+        assert(sg);
+        assert(stream);
+
+        errno = 0;
+        if (putsgent(sg, stream) != 0)
+                return errno > 0 ? -errno : -EIO;
+
+        return 0;
+}
+#endif
+
+int fgetpwent_sane(FILE *stream, struct passwd **pw) {
+        struct passwd *p;
+
+        assert(pw);
+        assert(stream);
+
+        errno = 0;
+        p = fgetpwent(stream);
+        if (p == NULL) {
+                if (errno == ENOENT)
+                        return false;
+                return errno > 0 ? -errno : -EIO;
+        }
+
+        *pw = p;
+        return true;
+}
+
+int fgetspent_sane(FILE *stream, struct spwd **sp) {
+        struct spwd *s;
+
+        assert(sp);
+        assert(stream);
+
+        errno = 0;
+        s = fgetspent(stream);
+        if (s == NULL) {
+                if (errno == ENOENT)
+                        return false;
+                return errno > 0 ? -errno : -EIO;
+        }
+
+        *sp = s;
+        return true;
+}
+
+int fgetgrent_sane(FILE *stream, struct group **gr) {
+        struct group *g;
+
+        assert(gr);
+        assert(stream);
+
+        errno = 0;
+        g = fgetgrent(stream);
+        if (g == NULL) {
+                if (errno == ENOENT)
+                        return false;
+                return errno > 0 ? -errno : -EIO;
+        }
+
+        *gr = g;
+        return true;
+}
+
+#if ENABLE_GSHADOW
+int fgetsgent_sane(FILE *stream, struct sgrp **sg) {
+        struct sgrp *s;
+
+        assert(sg);
+        assert(stream);
+
+        errno = 0;
+        s = fgetsgent(stream);
+        if (s == NULL) {
+                if (errno == ENOENT)
+                        return false;
+                return errno > 0 ? -errno : -EIO;
+        }
+
+        *sg = s;
+        return true;
+}
+#endif
index e1259a1582648096af516cd3ac54bf9e80340ed5..66a22ac88f4095224ff94dc3fda1537ee878a6a5 100644 (file)
   along with systemd; If not, see <http://www.gnu.org/licenses/>.
 ***/
 
+#include <grp.h>
+#include <gshadow.h>
+#include <pwd.h>
+#include <shadow.h>
 #include <stdbool.h>
 #include <stdint.h>
 #include <sys/types.h>
@@ -110,3 +114,14 @@ static inline bool valid_shell(const char *p) {
 int maybe_setgroups(size_t size, const gid_t *list);
 
 bool synthesize_nobody(void);
+
+int fgetpwent_sane(FILE *stream, struct passwd **pw);
+int fgetspent_sane(FILE *stream, struct spwd **sp);
+int fgetgrent_sane(FILE *stream, struct group **gr);
+int putpwent_sane(const struct passwd *pw, FILE *stream);
+int putspent_sane(const struct spwd *sp, FILE *stream);
+int putgrent_sane(const struct group *gr, FILE *stream);
+#ifdef ENABLE_GSHADOW
+int fgetsgent_sane(FILE *stream, struct sgrp **sg);
+int putsgent_sane(const struct sgrp *sg, FILE *stream);
+#endif
index 3d8a59029d9fb5de2b8b14a30382b5dc3b721588..308ef9d750759471d7e8392ab9d676fa3dfaacdd 100644 (file)
@@ -20,7 +20,6 @@
 
 #include <fcntl.h>
 #include <getopt.h>
-#include <shadow.h>
 #include <unistd.h>
 
 #ifdef HAVE_CRYPT_H
@@ -586,6 +585,8 @@ static int prompt_root_password(void) {
 
 static int write_root_shadow(const char *path, const struct spwd *p) {
         _cleanup_fclose_ FILE *f = NULL;
+        int r;
+
         assert(path);
         assert(p);
 
@@ -594,9 +595,9 @@ static int write_root_shadow(const char *path, const struct spwd *p) {
         if (!f)
                 return -errno;
 
-        errno = 0;
-        if (putspent(p, f) != 0)
-                return errno > 0 ? -errno : -EIO;
+        r = putspent_sane(p, f);
+        if (r < 0)
+                return r;
 
         return fflush_sync_and_check(f);
 }
index 43952e5f194d76b66aeb96150766d0fdf5278d5c..f6878a9c0107662cabe16e8a4b476b3bbd876b46 100644 (file)
 ***/
 
 #include <getopt.h>
-#include <grp.h>
-#include <gshadow.h>
-#include <pwd.h>
-#include <shadow.h>
 #include <utmp.h>
 
 #include "alloc-util.h"
@@ -113,8 +109,7 @@ static int load_user_database(void) {
         if (r < 0)
                 return r;
 
-        errno = 0;
-        while ((pw = fgetpwent(f))) {
+        while ((r = fgetpwent_sane(f, &pw)) > 0) {
                 char *n;
                 int k, q;
 
@@ -137,13 +132,8 @@ static int load_user_database(void) {
 
                 if (q < 0 && k < 0)
                         free(n);
-
-                errno = 0;
         }
-        if (!IN_SET(errno, 0, ENOENT))
-                return -errno;
-
-        return 0;
+        return r;
 }
 
 static int load_group_database(void) {
@@ -287,6 +277,7 @@ static int putgrent_with_members(const struct group *gr, FILE *group) {
 
                 if (added) {
                         struct group t;
+                        int r;
 
                         strv_uniq(l);
                         strv_sort(l);
@@ -294,19 +285,12 @@ static int putgrent_with_members(const struct group *gr, FILE *group) {
                         t = *gr;
                         t.gr_mem = l;
 
-                        errno = 0;
-                        if (putgrent(&t, group) != 0)
-                                return errno > 0 ? -errno : -EIO;
-
-                        return 1;
+                        r = putgrent_sane(&t, group);
+                        return r < 0 ? r : 1;
                 }
         }
 
-        errno = 0;
-        if (putgrent(gr, group) != 0)
-                return errno > 0 ? -errno : -EIO;
-
-        return 0;
+        return putgrent_sane(gr, group);
 }
 
 #if ENABLE_GSHADOW
@@ -338,6 +322,7 @@ static int putsgent_with_members(const struct sgrp *sg, FILE *gshadow) {
 
                 if (added) {
                         struct sgrp t;
+                        int r;
 
                         strv_uniq(l);
                         strv_sort(l);
@@ -345,19 +330,12 @@ static int putsgent_with_members(const struct sgrp *sg, FILE *gshadow) {
                         t = *sg;
                         t.sg_mem = l;
 
-                        errno = 0;
-                        if (putsgent(&t, gshadow) != 0)
-                                return errno > 0 ? -errno : -EIO;
-
-                        return 1;
+                        r = putsgent_sane(&t, gshadow);
+                        return r < 0 ? r : 1;
                 }
         }
 
-        errno = 0;
-        if (putsgent(sg, gshadow) != 0)
-                return errno > 0 ? -errno : -EIO;
-
-        return 0;
+        return putsgent_sane(sg, gshadow);
 }
 #endif
 
@@ -415,8 +393,7 @@ static int write_temporary_passwd(const char *passwd_path, FILE **tmpfile, char
                 if (r < 0)
                         return r;
 
-                errno = 0;
-                while ((pw = fgetpwent(original))) {
+                while ((r = fgetpwent_sane(original, &pw)) > 0) {
 
                         i = ordered_hashmap_get(users, pw->pw_name);
                         if (i && i->todo_user) {
@@ -429,19 +406,16 @@ static int write_temporary_passwd(const char *passwd_path, FILE **tmpfile, char
                                 return -EEXIST;
                         }
 
-                        errno = 0;
-
                         /* Make sure we keep the NIS entries (if any) at the end. */
                         if (IN_SET(pw->pw_name[0], '+', '-'))
                                 break;
 
-                        if (putpwent(pw, passwd) < 0)
-                                return errno ? -errno : -EIO;
-
-                        errno = 0;
+                        r = putpwent_sane(pw, passwd);
+                        if (r < 0)
+                                return r;
                 }
-                if (!IN_SET(errno, 0, ENOENT))
-                        return -errno;
+                if (r < 0)
+                        return r;
 
         } else {
                 if (errno != ENOENT)
@@ -468,23 +442,23 @@ static int write_temporary_passwd(const char *passwd_path, FILE **tmpfile, char
                         .pw_shell = i->shell ?: (char*) default_shell(i->uid),
                 };
 
-                errno = 0;
-                if (putpwent(&n, passwd) != 0)
-                        return errno ? -errno : -EIO;
+                r = putpwent_sane(&n, passwd);
+                if (r < 0)
+                        return r;
         }
-        errno = 0;
 
         /* Append the remaining NIS entries if any */
         while (pw) {
-                errno = 0;
-                if (putpwent(pw, passwd) < 0)
-                        return errno ? -errno : -EIO;
+                r = putpwent_sane(pw, passwd);
+                if (r < 0)
+                        return r;
 
-                errno = 0;
-                pw = fgetpwent(original);
+                r = fgetpwent_sane(original, &pw);
+                if (r < 0)
+                        return r;
+                if (r == 0)
+                        break;
         }
-        if (!IN_SET(errno, 0, ENOENT))
-                return -errno;
 
         r = fflush_and_check(passwd);
         if (r < 0)
@@ -522,8 +496,7 @@ static int write_temporary_shadow(const char *shadow_path, FILE **tmpfile, char
                 if (r < 0)
                         return r;
 
-                errno = 0;
-                while ((sp = fgetspent(original))) {
+                while ((r = fgetspent_sane(original, &sp)) > 0) {
 
                         i = ordered_hashmap_get(users, sp->sp_namp);
                         if (i && i->todo_user) {
@@ -536,19 +509,16 @@ static int write_temporary_shadow(const char *shadow_path, FILE **tmpfile, char
                                 ordered_hashmap_remove(todo_uids, UID_TO_PTR(i->uid));
                         }
 
-                        errno = 0;
-
                         /* Make sure we keep the NIS entries (if any) at the end. */
                         if (IN_SET(sp->sp_namp[0], '+', '-'))
                                 break;
 
-                        if (putspent(sp, shadow) < 0)
-                                return errno ? -errno : -EIO;
-
-                        errno = 0;
+                        r = putspent_sane(sp, shadow);
+                        if (r < 0)
+                                return r;
                 }
-                if (!IN_SET(errno, 0, ENOENT))
-                        return -errno;
+                if (r < 0)
+                        return r;
 
         } else {
                 if (errno != ENOENT)
@@ -570,20 +540,22 @@ static int write_temporary_shadow(const char *shadow_path, FILE **tmpfile, char
                         .sp_flag = (unsigned long) -1, /* this appears to be what everybody does ... */
                 };
 
-                errno = 0;
-                if (putspent(&n, shadow) != 0)
-                        return errno ? -errno : -EIO;
+                r = putspent_sane(&n, shadow);
+                if (r < 0)
+                        return r;
         }
-        errno = 0;
 
         /* Append the remaining NIS entries if any */
         while (sp) {
-                errno = 0;
-                if (putspent(sp, shadow) < 0)
-                        return errno ? -errno : -EIO;
+                r = putspent_sane(sp, shadow);
+                if (r < 0)
+                        return r;
 
-                errno = 0;
-                sp = fgetspent(original);
+                r = fgetspent_sane(original, &sp);
+                if (r < 0)
+                        return r;
+                if (r == 0)
+                        break;
         }
         if (!IN_SET(errno, 0, ENOENT))
                 return -errno;
@@ -622,8 +594,7 @@ static int write_temporary_group(const char *group_path, FILE **tmpfile, char **
                 if (r < 0)
                         return r;
 
-                errno = 0;
-                while ((gr = fgetgrent(original))) {
+                while ((r = fgetgrent_sane(original, &gr)) > 0) {
                         /* Safety checks against name and GID collisions. Normally,
                          * this should be unnecessary, but given that we look at the
                          * entries anyway here, let's make an extra verification
@@ -640,8 +611,6 @@ static int write_temporary_group(const char *group_path, FILE **tmpfile, char **
                                 return  -EEXIST;
                         }
 
-                        errno = 0;
-
                         /* Make sure we keep the NIS entries (if any) at the end. */
                         if (IN_SET(gr->gr_name[0], '+', '-'))
                                 break;
@@ -651,11 +620,9 @@ static int write_temporary_group(const char *group_path, FILE **tmpfile, char **
                                 return r;
                         if (r > 0)
                                 group_changed = true;
-
-                        errno = 0;
                 }
-                if (!IN_SET(errno, 0, ENOENT))
-                        return -errno;
+                if (r < 0)
+                        return r;
 
         } else {
                 if (errno != ENOENT)
@@ -677,19 +644,19 @@ static int write_temporary_group(const char *group_path, FILE **tmpfile, char **
 
                 group_changed = true;
         }
-        errno = 0;
 
         /* Append the remaining NIS entries if any */
         while (gr) {
-                errno = 0;
-                if (putgrent(gr, group) != 0)
-                        return errno > 0 ? -errno : -EIO;
+                r = putgrent_sane(gr, group);
+                if (r < 0)
+                        return r;
 
-                errno = 0;
-                gr = fgetgrent(original);
+                r = fgetgrent_sane(original, &gr);
+                if (r < 0)
+                        return r;
+                if (r == 0)
+                        break;
         }
-        if (!IN_SET(errno, 0, ENOENT))
-                return -errno;
 
         r = fflush_sync_and_check(group);
         if (r < 0)
@@ -728,8 +695,7 @@ static int write_temporary_gshadow(const char * gshadow_path, FILE **tmpfile, ch
                 if (r < 0)
                         return r;
 
-                errno = 0;
-                while ((sg = fgetsgent(original))) {
+                while ((r = fgetsgent_sane(original, &sg)) > 0) {
 
                         i = ordered_hashmap_get(groups, sg->sg_namp);
                         if (i && i->todo_group) {
@@ -742,11 +708,9 @@ static int write_temporary_gshadow(const char * gshadow_path, FILE **tmpfile, ch
                                 return r;
                         if (r > 0)
                                 group_changed = true;
-
-                        errno = 0;
                 }
-                if (!IN_SET(errno, 0, ENOENT))
-                        return -errno;
+                if (r < 0)
+                        return r;
 
         } else {
                 if (errno != ENOENT)