user-util: add get{pw,gr}{uid,gid,name}_malloc() helpers
These are wrappers around getpwuid_r() and friends, and will allocate the right-sized buffer for this call. We so far had multiple implementations of a buffer allocation loop around getpwuid_r() and friends, and they all suck in some way. Let's clean this up and add a common implementation, and use it everywhere. Also, be more careful with error numbers, in particular systematically turn ENOENT into ENOSRCH (the former is what is returned if /etc/passwd is absent, which we want to consider identical to user not existing, which is ENOSRCH). We so far did this at some invocations, but not all. There are some invocations of getpwuid() left in the codebase. We really should fix those too, and have a single unified implementation of the logic, but those are not as trivial to convert, so left for another time.
This commit is contained in:
+20
-104
@@ -208,39 +208,17 @@ int nss_user_record_by_name(
|
||||
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);
|
||||
@@ -266,36 +244,15 @@ int nss_user_record_by_uid(
|
||||
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);
|
||||
@@ -422,38 +379,17 @@ int nss_group_record_by_name(
|
||||
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);
|
||||
@@ -479,35 +415,15 @@ int nss_group_record_by_gid(
|
||||
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);
|
||||
|
||||
Reference in New Issue
Block a user