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
***/
#include <getopt.h>
-#include <grp.h>
-#include <gshadow.h>
-#include <pwd.h>
-#include <shadow.h>
#include <utmp.h>
#include "alloc-util.h"
if (r < 0)
return r;
- errno = 0;
- while ((pw = fgetpwent(f))) {
+ while ((r = fgetpwent_sane(f, &pw)) > 0) {
char *n;
int k, q;
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) {
if (added) {
struct group t;
+ int r;
strv_uniq(l);
strv_sort(l);
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
if (added) {
struct sgrp t;
+ int r;
strv_uniq(l);
strv_sort(l);
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
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) {
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)
.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)
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) {
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)
.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;
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
return -EEXIST;
}
- errno = 0;
-
/* Make sure we keep the NIS entries (if any) at the end. */
if (IN_SET(gr->gr_name[0], '+', '-'))
break;
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)
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)
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) {
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)