return strdup(NOBODY_USER_NAME);
if (uid_is_valid(uid)) {
- long bufsize;
+ _cleanup_free_ struct passwd *pw = NULL;
- bufsize = sysconf(_SC_GETPW_R_SIZE_MAX);
- if (bufsize <= 0)
- bufsize = 4096;
-
- for (;;) {
- struct passwd pwbuf, *pw = NULL;
- _cleanup_free_ char *buf = NULL;
-
- buf = malloc(bufsize);
- if (!buf)
- return NULL;
-
- r = getpwuid_r(uid, &pwbuf, buf, (size_t) bufsize, &pw);
- if (r == 0 && pw)
- return strdup(pw->pw_name);
- if (r != ERANGE)
- break;
-
- if (bufsize > LONG_MAX/2) /* overflow check */
- return NULL;
-
- bufsize *= 2;
- }
+ r = getpwuid_malloc(uid, &pw);
+ if (r >= 0)
+ return strdup(pw->pw_name);
}
if (asprintf(&ret, UID_FMT, uid) < 0)
return strdup(NOBODY_GROUP_NAME);
if (gid_is_valid(gid)) {
- long bufsize;
+ _cleanup_free_ struct group *gr = NULL;
- bufsize = sysconf(_SC_GETGR_R_SIZE_MAX);
- if (bufsize <= 0)
- bufsize = 4096;
-
- for (;;) {
- struct group grbuf, *gr = NULL;
- _cleanup_free_ char *buf = NULL;
-
- buf = malloc(bufsize);
- if (!buf)
- return NULL;
-
- r = getgrgid_r(gid, &grbuf, buf, (size_t) bufsize, &gr);
- if (r == 0 && gr)
- return strdup(gr->gr_name);
- if (r != ERANGE)
- break;
-
- if (bufsize > LONG_MAX/2) /* overflow check */
- return NULL;
-
- bufsize *= 2;
- }
+ r = getgrgid_malloc(gid, &gr);
+ if (r >= 0)
+ return strdup(gr->gr_name);
}
if (asprintf(&ret, GID_FMT, gid) < 0)
}
int get_home_dir(char **ret) {
- struct passwd *p;
+ _cleanup_free_ struct passwd *p = NULL;
const char *e;
uid_t u;
+ int r;
assert(ret);
e = "/root";
goto found;
}
-
if (u == UID_NOBODY && synthesize_nobody()) {
e = "/";
goto found;
}
/* Check the database... */
- errno = 0;
- p = getpwuid(u);
- if (!p)
- return errno_or_else(ESRCH);
- e = p->pw_dir;
+ r = getpwuid_malloc(u, &p);
+ if (r < 0)
+ return r;
+ e = p->pw_dir;
if (!path_is_valid(e) || !path_is_absolute(e))
return -EINVAL;
}
int get_shell(char **ret) {
- struct passwd *p;
+ _cleanup_free_ struct passwd *p = NULL;
const char *e;
uid_t u;
+ int r;
assert(ret);
}
/* Check the database... */
- errno = 0;
- p = getpwuid(u);
- if (!p)
- return errno_or_else(ESRCH);
- e = p->pw_shell;
+ r = getpwuid_malloc(u, &p);
+ if (r < 0)
+ return r;
+ e = p->pw_shell;
if (!path_is_valid(e) || !path_is_absolute(e))
return -EINVAL;
return "/home";
}
+
+static size_t getpw_buffer_size(void) {
+ long bufsize = sysconf(_SC_GETPW_R_SIZE_MAX);
+ return bufsize <= 0 ? 4096U : (size_t) bufsize;
+}
+
+static bool errno_is_user_doesnt_exist(int error) {
+ /* See getpwnam(3) and getgrnam(3): those codes and others can be returned if the user or group are
+ * not found. */
+ return IN_SET(abs(error), ENOENT, ESRCH, EBADF, EPERM);
+}
+
+int getpwnam_malloc(const char *name, struct passwd **ret) {
+ size_t bufsize = getpw_buffer_size();
+ int r;
+
+ /* A wrapper around getpwnam_r() that allocates the necessary buffer on the heap. The caller must
+ * free() the returned sructured! */
+
+ if (isempty(name))
+ return -EINVAL;
+
+ for (;;) {
+ _cleanup_free_ void *buf = NULL;
+
+ buf = malloc(ALIGN(sizeof(struct passwd)) + bufsize);
+ if (!buf)
+ return -ENOMEM;
+
+ struct passwd *pw = NULL;
+ r = getpwnam_r(name, buf, (char*) buf + ALIGN(sizeof(struct passwd)), (size_t) bufsize, &pw);
+ if (r == 0) {
+ if (pw) {
+ if (ret)
+ *ret = TAKE_PTR(buf);
+ return 0;
+ }
+
+ return -ESRCH;
+ }
+
+ assert(r > 0);
+
+ /* getpwnam() may fail with ENOENT if /etc/passwd is missing. For us that is equivalent to
+ * the name not being defined. */
+ if (errno_is_user_doesnt_exist(r))
+ return -ESRCH;
+ if (r != ERANGE)
+ return -r;
+
+ if (bufsize > SIZE_MAX/2 - ALIGN(sizeof(struct passwd)))
+ return -ENOMEM;
+ bufsize *= 2;
+ }
+}
+
+int getpwuid_malloc(uid_t uid, struct passwd **ret) {
+ size_t bufsize = getpw_buffer_size();
+ int r;
+
+ if (!uid_is_valid(uid))
+ return -EINVAL;
+
+ for (;;) {
+ _cleanup_free_ void *buf = NULL;
+
+ buf = malloc(ALIGN(sizeof(struct passwd)) + bufsize);
+ if (!buf)
+ return -ENOMEM;
+
+ struct passwd *pw = NULL;
+ r = getpwuid_r(uid, buf, (char*) buf + ALIGN(sizeof(struct passwd)), (size_t) bufsize, &pw);
+ if (r == 0) {
+ if (pw) {
+ if (ret)
+ *ret = TAKE_PTR(buf);
+ return 0;
+ }
+
+ return -ESRCH;
+ }
+
+ assert(r > 0);
+
+ if (errno_is_user_doesnt_exist(r))
+ return -ESRCH;
+ if (r != ERANGE)
+ return -r;
+
+ if (bufsize > SIZE_MAX/2 - ALIGN(sizeof(struct passwd)))
+ return -ENOMEM;
+ bufsize *= 2;
+ }
+}
+
+static size_t getgr_buffer_size(void) {
+ long bufsize = sysconf(_SC_GETGR_R_SIZE_MAX);
+ return bufsize <= 0 ? 4096U : (size_t) bufsize;
+}
+
+int getgrnam_malloc(const char *name, struct group **ret) {
+ size_t bufsize = getgr_buffer_size();
+ int r;
+
+ if (isempty(name))
+ return -EINVAL;
+
+ for (;;) {
+ _cleanup_free_ void *buf = NULL;
+
+ buf = malloc(ALIGN(sizeof(struct group)) + bufsize);
+ if (!buf)
+ return -ENOMEM;
+
+ struct group *gr = NULL;
+ r = getgrnam_r(name, buf, (char*) buf + ALIGN(sizeof(struct group)), (size_t) bufsize, &gr);
+ if (r == 0) {
+ if (gr) {
+ if (ret)
+ *ret = TAKE_PTR(buf);
+ return 0;
+ }
+
+ return -ESRCH;
+ }
+
+ assert(r > 0);
+
+ if (errno_is_user_doesnt_exist(r))
+ return -ESRCH;
+ if (r != ERANGE)
+ return -r;
+
+ if (bufsize > SIZE_MAX/2 - ALIGN(sizeof(struct group)))
+ return -ENOMEM;
+ bufsize *= 2;
+ }
+}
+
+int getgrgid_malloc(gid_t gid, struct group **ret) {
+ size_t bufsize = getgr_buffer_size();
+ int r;
+
+ if (!gid_is_valid(gid))
+ return -EINVAL;
+
+ for (;;) {
+ _cleanup_free_ void *buf = NULL;
+
+ buf = malloc(ALIGN(sizeof(struct group)) + bufsize);
+ if (!buf)
+ return -ENOMEM;
+
+ struct group *gr = NULL;
+ r = getgrgid_r(gid, buf, (char*) buf + ALIGN(sizeof(struct group)), (size_t) bufsize, &gr);
+ if (r == 0) {
+ if (gr) {
+ if (ret)
+ *ret = TAKE_PTR(buf);
+ return 0;
+ }
+
+ return -ESRCH;
+ }
+
+ assert(r > 0);
+
+ if (errno_is_user_doesnt_exist(r))
+ return -ESRCH;
+ if (r != ERANGE)
+ return -r;
+
+ if (bufsize > SIZE_MAX/2 - ALIGN(sizeof(struct group)))
+ return -ENOMEM;
+ bufsize *= 2;
+ }
+}
* Also see https://github.com/systemd/systemd/pull/24680#pullrequestreview-1439464325.
*/
#define PASSWORD_UNPROVISIONED "!unprovisioned"
+
+int getpwuid_malloc(uid_t uid, struct passwd **ret);
+int getpwnam_malloc(const char *name, struct passwd **ret);
+
+int getgrnam_malloc(const char *name, struct group **ret);
+int getgrgid_malloc(gid_t gid, struct group **ret);
}
/* Some superficial check whether this UID/GID might already be taken by some static user */
- if (getpwuid(candidate) ||
- getgrgid((gid_t) candidate) ||
+ if (getpwuid_malloc(candidate, /* ret= */ NULL) >= 0 ||
+ getgrgid_malloc((gid_t) candidate, /* ret= */ NULL) >= 0 ||
search_ipc(candidate, (gid_t) candidate) != 0) {
(void) unlink(lock_path);
continue;
/* First, let's parse this as numeric UID */
r = parse_uid(d->name, &num);
if (r < 0) {
- struct passwd *p;
- struct group *g;
+ _cleanup_free_ struct passwd *p = NULL;
+ _cleanup_free_ struct group *g = NULL;
if (is_user) {
/* OK, this is not a numeric UID. Let's see if there's a user by this name */
- p = getpwnam(d->name);
- if (p) {
+ if (getpwnam_malloc(d->name, &p) >= 0) {
num = p->pw_uid;
gid = p->pw_gid;
} else {
/* if the user does not exist but the group with the same name exists, refuse operation */
- g = getgrnam(d->name);
- if (g)
+ if (getgrnam_malloc(d->name, /* ret= */ NULL) >= 0)
return -EILSEQ;
}
} else {
/* Let's see if there's a group by this name */
- g = getgrnam(d->name);
- if (g)
+ if (getgrnam_malloc(d->name, &g) >= 0)
num = (uid_t) g->gr_gid;
else {
/* if the group does not exist but the user with the same name exists, refuse operation */
- p = getpwnam(d->name);
- if (p)
+ if (getpwnam_malloc(d->name, /* ret= */ NULL) >= 0)
return -EILSEQ;
}
}
uid_lock_fd = new_uid_lock_fd;
}
} else if (is_user && !uid_is_dynamic(num)) {
- struct passwd *p;
+ _cleanup_free_ struct passwd *p = NULL;
/* Statically allocated user may have different uid and gid. So, let's obtain the gid. */
- errno = 0;
- p = getpwuid(num);
- if (!p)
- return errno_or_else(ESRCH);
+ r = getpwuid_malloc(num, &p);
+ if (r < 0)
+ return r;
gid = p->pw_gid;
}
return log_error_errno(k, "Failed to check if directory file descriptor is root: %m");
if (arg_copy_root_shell && k == 0) {
- struct passwd *p;
+ _cleanup_free_ struct passwd *p = NULL;
- errno = 0;
- p = getpwnam("root");
- if (!p)
- return log_error_errno(errno_or_else(EIO), "Failed to find passwd entry for root: %m");
+ r = getpwnam_malloc("root", &p);
+ if (r < 0)
+ return log_error_errno(r, "Failed to find passwd entry for root: %m");
r = free_and_strdup(&arg_root_shell, p->pw_shell);
if (r < 0)
static int validate_and_allocate_home(Manager *m, UserRecord *hr, Home **ret, sd_bus_error *error) {
_cleanup_(user_record_unrefp) UserRecord *signed_hr = NULL;
- struct passwd *pw;
- struct group *gr;
bool signed_locally;
Home *other;
int r;
if (other)
return sd_bus_error_setf(error, BUS_ERROR_USER_NAME_EXISTS, "Specified user name %s exists already, refusing.", hr->user_name);
- pw = getpwnam(hr->user_name);
- if (pw)
+ r = getpwnam_malloc(hr->user_name, /* ret= */ NULL);
+ if (r >= 0)
return sd_bus_error_setf(error, BUS_ERROR_USER_NAME_EXISTS, "Specified user name %s exists in the NSS user database, refusing.", hr->user_name);
+ if (r != -ESRCH)
+ return r;
- gr = getgrnam(hr->user_name);
- if (gr)
+ r = getgrnam_malloc(hr->user_name, /* ret= */ NULL);
+ if (r >= 0)
return sd_bus_error_setf(error, BUS_ERROR_USER_NAME_EXISTS, "Specified user name %s conflicts with an NSS group by the same name, refusing.", hr->user_name);
+ if (r != -ESRCH)
+ return r;
r = manager_verify_user_record(m, hr);
switch (r) {
}
if (uid_is_valid(hr->uid)) {
+ _cleanup_free_ struct passwd *pw = NULL;
+ _cleanup_free_ struct group *gr = NULL;
+
other = hashmap_get(m->homes_by_uid, UID_TO_PTR(hr->uid));
if (other)
return sd_bus_error_setf(error, BUS_ERROR_UID_IN_USE, "Specified UID " UID_FMT " already in use by home %s, refusing.", hr->uid, other->user_name);
- pw = getpwuid(hr->uid);
- if (pw)
+ r = getpwuid_malloc(hr->uid, &pw);
+ if (r >= 0)
return sd_bus_error_setf(error, BUS_ERROR_UID_IN_USE, "Specified UID " UID_FMT " already in use by NSS user %s, refusing.", hr->uid, pw->pw_name);
+ if (r != -ESRCH)
+ return r;
- gr = getgrgid(hr->uid);
- if (gr)
+ r = getgrgid_malloc(hr->uid, &gr);
+ if (r >= 0)
return sd_bus_error_setf(error, BUS_ERROR_UID_IN_USE, "Specified UID " UID_FMT " already in use as GID by NSS group %s, refusing.", hr->uid, gr->gr_name);
+ if (r != -ESRCH)
+ return r;
} else {
r = manager_augment_record_with_uid(m, hr);
if (r < 0)
assert(ret);
for (;;) {
- struct passwd *pw;
- struct group *gr;
+ _cleanup_free_ struct passwd *pw = NULL;
+ _cleanup_free_ struct group *gr = NULL;
uid_t candidate;
Home *other;
continue;
}
- pw = getpwuid(candidate);
- if (pw) {
+ r = getpwuid_malloc(candidate, &pw);
+ if (r >= 0) {
log_debug("Candidate UID " UID_FMT " already registered by another user in NSS (%s), let's try another.",
candidate, pw->pw_name);
continue;
}
+ if (r != -ESRCH) {
+ log_debug_errno(r, "Failed to check if an NSS user is already registered for candidate UID " UID_FMT ", assuming there might be: %m", candidate);
+ continue;
+ }
- gr = getgrgid((gid_t) candidate);
- if (gr) {
+ r = getgrgid_malloc((gid_t) candidate, &gr);
+ if (r >= 0) {
log_debug("Candidate UID " UID_FMT " already registered by another group in NSS (%s), let's try another.",
candidate, gr->gr_name);
continue;
}
+ if (r != -ESRCH) {
+ log_debug_errno(r, "Failed to check if an NSS group is already registered for candidate UID " UID_FMT ", assuming there might be: %m", candidate);
+ continue;
+ }
r = search_ipc(candidate, (gid_t) candidate);
if (r < 0)
}
} else {
/* Check NSS, in case there's another user or group by this name */
- if (getpwnam(user_name) || getgrnam(user_name)) {
+ if (getpwnam_malloc(user_name, /* ret= */ NULL) >= 0 || getgrnam_malloc(user_name, /* ret= */ NULL) >= 0) {
log_debug("Found an existing user or group by name '%s', ignoring image '%s'.", user_name, image_path);
return 0;
}
static int method_set_user_linger(sd_bus_message *message, void *userdata, sd_bus_error *error) {
_cleanup_(sd_bus_creds_unrefp) sd_bus_creds *creds = NULL;
+ _cleanup_free_ struct passwd *pw = NULL;
_cleanup_free_ char *cc = NULL;
Manager *m = ASSERT_PTR(userdata);
int r, b, interactive;
- struct passwd *pw;
const char *path;
uint32_t uid, auth_uid;
if (r < 0)
return r;
- errno = 0;
- pw = getpwuid(uid);
- if (!pw)
- return errno_or_else(ENOENT);
+ r = getpwuid_malloc(uid, &pw);
+ if (r < 0)
+ return r;
r = bus_verify_polkit_async_full(
message,
return r;
/* Make some superficial checks whether the range is currently known in the user database */
- if (getpwuid(candidate))
+ if (getpwuid_malloc(candidate, /* ret= */ NULL) >= 0)
goto next;
- if (getpwuid(candidate + UINT32_C(0xFFFE)))
+ if (getpwuid_malloc(candidate + UINT32_C(0xFFFE), /* ret= */ NULL) >= 0)
goto next;
- if (getgrgid(candidate))
+ if (getgrgid_malloc(candidate, /* ret= */ NULL) >= 0)
goto next;
- if (getgrgid(candidate + UINT32_C(0xFFFE)))
+ if (getgrgid_malloc(candidate + UINT32_C(0xFFFE), /* ret= */ NULL) >= 0)
goto next;
*ret_lock_file = lf;
bool with_shadow,
UserRecord **ret) {
- _cleanup_free_ char *buf = NULL, *sbuf = NULL;
- struct passwd pwd, *result;
+ _cleanup_free_ char *sbuf = NULL;
+ _cleanup_free_ struct passwd *result = NULL;
bool incomplete = false;
- size_t buflen = 4096;
struct spwd spwd, *sresult = NULL;
int r;
assert(name);
- for (;;) {
- buf = malloc(buflen);
- if (!buf)
- return -ENOMEM;
-
- r = getpwnam_r(name, &pwd, buf, buflen, &result);
- if (r == 0) {
- if (!result)
- return -ESRCH;
-
- break;
- }
-
- if (r < 0)
- return log_debug_errno(SYNTHETIC_ERRNO(EIO), "getpwnam_r() returned a negative value");
- if (r != ERANGE)
- return -r;
-
- if (buflen > SIZE_MAX / 2)
- return -ERANGE;
-
- buflen *= 2;
- buf = mfree(buf);
- }
+ r = getpwnam_malloc(name, &result);
+ if (r < 0)
+ return r;
if (with_shadow) {
r = nss_spwd_for_passwd(result, &spwd, &sbuf);
bool with_shadow,
UserRecord **ret) {
- _cleanup_free_ char *buf = NULL, *sbuf = NULL;
- struct passwd pwd, *result;
+ _cleanup_free_ char *sbuf = NULL;
+ _cleanup_free_ struct passwd *result = NULL;
bool incomplete = false;
- size_t buflen = 4096;
struct spwd spwd, *sresult = NULL;
int r;
- for (;;) {
- buf = malloc(buflen);
- if (!buf)
- return -ENOMEM;
-
- r = getpwuid_r(uid, &pwd, buf, buflen, &result);
- if (r == 0) {
- if (!result)
- return -ESRCH;
-
- break;
- }
- if (r < 0)
- return log_debug_errno(SYNTHETIC_ERRNO(EIO), "getpwuid_r() returned a negative value");
- if (r != ERANGE)
- return -r;
-
- if (buflen > SIZE_MAX / 2)
- return -ERANGE;
-
- buflen *= 2;
- buf = mfree(buf);
- }
+ r = getpwuid_malloc(uid, &result);
+ if (r < 0)
+ return r;
if (with_shadow) {
r = nss_spwd_for_passwd(result, &spwd, &sbuf);
bool with_shadow,
GroupRecord **ret) {
- _cleanup_free_ char *buf = NULL, *sbuf = NULL;
- struct group grp, *result;
+ _cleanup_free_ char *sbuf = NULL;
+ _cleanup_free_ struct group *result = NULL;
bool incomplete = false;
- size_t buflen = 4096;
struct sgrp sgrp, *sresult = NULL;
int r;
assert(name);
- for (;;) {
- buf = malloc(buflen);
- if (!buf)
- return -ENOMEM;
-
- r = getgrnam_r(name, &grp, buf, buflen, &result);
- if (r == 0) {
- if (!result)
- return -ESRCH;
-
- break;
- }
-
- if (r < 0)
- return log_debug_errno(SYNTHETIC_ERRNO(EIO), "getgrnam_r() returned a negative value");
- if (r != ERANGE)
- return -r;
- if (buflen > SIZE_MAX / 2)
- return -ERANGE;
-
- buflen *= 2;
- buf = mfree(buf);
- }
+ r = getgrnam_malloc(name, &result);
+ if (r < 0)
+ return r;
if (with_shadow) {
r = nss_sgrp_for_group(result, &sgrp, &sbuf);
bool with_shadow,
GroupRecord **ret) {
- _cleanup_free_ char *buf = NULL, *sbuf = NULL;
- struct group grp, *result;
+ _cleanup_free_ char *sbuf = NULL;
+ _cleanup_free_ struct group *result = NULL;
bool incomplete = false;
- size_t buflen = 4096;
struct sgrp sgrp, *sresult = NULL;
int r;
- for (;;) {
- buf = malloc(buflen);
- if (!buf)
- return -ENOMEM;
-
- r = getgrgid_r(gid, &grp, buf, buflen, &result);
- if (r == 0) {
- if (!result)
- return -ESRCH;
- break;
- }
-
- if (r < 0)
- return log_debug_errno(SYNTHETIC_ERRNO(EIO), "getgrgid_r() returned a negative value");
- if (r != ERANGE)
- return -r;
- if (buflen > SIZE_MAX / 2)
- return -ERANGE;
-
- buflen *= 2;
- buf = mfree(buf);
- }
+ r = getgrgid_malloc(gid, &result);
+ if (r < 0)
+ return r;
if (with_shadow) {
r = nss_sgrp_for_group(result, &sgrp, &sbuf);
uid_range_free(c->uid_range);
}
-static int errno_is_not_exists(int code) {
- /* See getpwnam(3) and getgrnam(3): those codes and others can be returned if the user or group are
- * not found. */
- return IN_SET(code, 0, ENOENT, ESRCH, EBADF, EPERM);
-}
-
/* Note: the lifetime of the compound literal is the immediately surrounding block,
* see C11 ยง6.5.2.5, and
* https://stackoverflow.com/questions/34880638/compound-literal-lifetime-and-if-blocks */
const char *name,
bool check_with_gid) {
+ int r;
assert(c);
/* Let's see if we already have assigned the UID a second time */
/* Let's also check via NSS, to avoid UID clashes over LDAP and such, just in case */
if (!arg_root) {
- struct passwd *p;
- struct group *g;
+ _cleanup_free_ struct group *g = NULL;
- errno = 0;
- p = getpwuid(uid);
- if (p)
+ r = getpwuid_malloc(uid, /* ret= */ NULL);
+ if (r >= 0)
return 0;
- if (!IN_SET(errno, 0, ENOENT))
- return -errno;
+ if (r != -ESRCH)
+ return r;
if (check_with_gid) {
- errno = 0;
- g = getgrgid((gid_t) uid);
- if (g) {
+ r = getgrgid_malloc((gid_t) uid, &g);
+ if (r >= 0) {
if (!streq(g->gr_name, name))
return 0;
- } else if (!IN_SET(errno, 0, ENOENT))
- return -errno;
+ } else if (r != -ESRCH)
+ return r;
}
}
}
if (!arg_root) {
- struct passwd *p;
+ _cleanup_free_ struct passwd *p = NULL;
/* Also check NSS */
- errno = 0;
- p = getpwnam(i->name);
- if (p) {
+ r = getpwnam_malloc(i->name, &p);
+ if (r >= 0) {
log_debug("User %s already exists.", i->name);
i->uid = p->pw_uid;
i->uid_set = true;
return 0;
}
- if (!errno_is_not_exists(errno))
- return log_error_errno(errno, "Failed to check if user %s already exists: %m", i->name);
+ if (r != -ESRCH)
+ return log_error_errno(r, "Failed to check if user %s already exists: %m", i->name);
}
/* Try to use the suggested numeric UID */
const char *groupname,
bool check_with_uid) {
- struct group *g;
- struct passwd *p;
Item *user;
char *username;
+ int r;
assert(c);
assert(groupname);
}
if (!arg_root) {
- errno = 0;
- g = getgrgid(gid);
- if (g)
+ r = getgrgid_malloc(gid, /* ret= */ NULL);
+ if (r >= 0)
return 0;
- if (!IN_SET(errno, 0, ENOENT))
- return -errno;
+ if (r != -ESRCH)
+ return r;
if (check_with_uid) {
- errno = 0;
- p = getpwuid((uid_t) gid);
- if (p)
+ r = getpwuid_malloc(gid, /* ret= */ NULL);
+ if (r >= 0)
return 0;
- if (!IN_SET(errno, 0, ENOENT))
- return -errno;
+ if (r != -ESRCH)
+ return r;
}
}
gid_t *ret_gid) {
void *z;
+ int r;
assert(c);
assert(ret_gid);
/* Also check NSS */
if (!arg_root) {
- struct group *g;
+ _cleanup_free_ struct group *g = NULL;
- errno = 0;
- g = getgrnam(name);
- if (g) {
+ r = getgrnam_malloc(name, &g);
+ if (r >= 0) {
*ret_gid = g->gr_gid;
return 0;
}
- if (!errno_is_not_exists(errno))
- return log_error_errno(errno, "Failed to check if group %s already exists: %m", name);
+ if (r != -ESRCH)
+ return log_error_errno(r, "Failed to check if group %s already exists: %m", name);
}
return -ENOENT;