login, mount: fix __SC_GETPW_R_SIZE_MAX usage
sysconf(_SC_GETPW_R_SIZE_MAX) returns initial suggested size for pwd buffer (see getpwnam_r man page or POSIX). This is not large enough in some cases. Yes, this sysconf option is misnamed (should be _SC_GETPW_R_SIZE_MIN). Signed-off-by: Karel Zak <kzak@redhat.com>
This commit is contained in:
parent
b5febe0489
commit
f7ac9e71b1
|
@ -346,4 +346,13 @@ static inline int xusleep(useconds_t usec)
|
||||||
# define UL_ASAN_BLACKLIST /* nothing */
|
# define UL_ASAN_BLACKLIST /* nothing */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Note that sysconf(_SC_GETPW_R_SIZE_MAX) returns *initial* suggested size for
|
||||||
|
* pwd buffer and in some cases it is not large enough. See POSIX and
|
||||||
|
* getpwnam_r man page for more details.
|
||||||
|
*/
|
||||||
|
#define UL_GETPW_BUFSIZ (16 * 1024)
|
||||||
|
|
||||||
#endif /* UTIL_LINUX_C_H */
|
#endif /* UTIL_LINUX_C_H */
|
||||||
|
|
|
@ -635,16 +635,6 @@ int mnt_get_filesystems(char ***filesystems, const char *pattern)
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
static size_t get_pw_record_size(void)
|
|
||||||
{
|
|
||||||
#ifdef _SC_GETPW_R_SIZE_MAX
|
|
||||||
long sz = sysconf(_SC_GETPW_R_SIZE_MAX);
|
|
||||||
if (sz > 0)
|
|
||||||
return sz;
|
|
||||||
#endif
|
|
||||||
return 16384;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Returns an allocated string with username or NULL.
|
* Returns an allocated string with username or NULL.
|
||||||
*/
|
*/
|
||||||
|
@ -652,14 +642,13 @@ char *mnt_get_username(const uid_t uid)
|
||||||
{
|
{
|
||||||
struct passwd pwd;
|
struct passwd pwd;
|
||||||
struct passwd *res;
|
struct passwd *res;
|
||||||
size_t sz = get_pw_record_size();
|
|
||||||
char *buf, *username = NULL;
|
char *buf, *username = NULL;
|
||||||
|
|
||||||
buf = malloc(sz);
|
buf = malloc(UL_GETPW_BUFSIZ);
|
||||||
if (!buf)
|
if (!buf)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
if (!getpwuid_r(uid, &pwd, buf, sz, &res) && res)
|
if (!getpwuid_r(uid, &pwd, buf, UL_GETPW_BUFSIZ, &res) && res)
|
||||||
username = strdup(pwd.pw_name);
|
username = strdup(pwd.pw_name);
|
||||||
|
|
||||||
free(buf);
|
free(buf);
|
||||||
|
@ -671,17 +660,16 @@ int mnt_get_uid(const char *username, uid_t *uid)
|
||||||
int rc = -1;
|
int rc = -1;
|
||||||
struct passwd pwd;
|
struct passwd pwd;
|
||||||
struct passwd *pw;
|
struct passwd *pw;
|
||||||
size_t sz = get_pw_record_size();
|
|
||||||
char *buf;
|
char *buf;
|
||||||
|
|
||||||
if (!username || !uid)
|
if (!username || !uid)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
buf = malloc(sz);
|
buf = malloc(UL_GETPW_BUFSIZ);
|
||||||
if (!buf)
|
if (!buf)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
if (!getpwnam_r(username, &pwd, buf, sz, &pw) && pw) {
|
if (!getpwnam_r(username, &pwd, buf, UL_GETPW_BUFSIZ, &pw) && pw) {
|
||||||
*uid= pw->pw_uid;
|
*uid= pw->pw_uid;
|
||||||
rc = 0;
|
rc = 0;
|
||||||
} else {
|
} else {
|
||||||
|
@ -699,17 +687,16 @@ int mnt_get_gid(const char *groupname, gid_t *gid)
|
||||||
int rc = -1;
|
int rc = -1;
|
||||||
struct group grp;
|
struct group grp;
|
||||||
struct group *gr;
|
struct group *gr;
|
||||||
size_t sz = get_pw_record_size();
|
|
||||||
char *buf;
|
char *buf;
|
||||||
|
|
||||||
if (!groupname || !gid)
|
if (!groupname || !gid)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
buf = malloc(sz);
|
buf = malloc(UL_GETPW_BUFSIZ);
|
||||||
if (!buf)
|
if (!buf)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
if (!getgrnam_r(groupname, &grp, buf, sz, &gr) && gr) {
|
if (!getgrnam_r(groupname, &grp, buf, UL_GETPW_BUFSIZ, &gr) && gr) {
|
||||||
*gid= gr->gr_gid;
|
*gid= gr->gr_gid;
|
||||||
rc = 0;
|
rc = 0;
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -674,22 +674,14 @@ static struct passwd *get_passwd_entry(const char *username,
|
||||||
struct passwd *pwd)
|
struct passwd *pwd)
|
||||||
{
|
{
|
||||||
struct passwd *res = NULL;
|
struct passwd *res = NULL;
|
||||||
size_t sz = 16384;
|
|
||||||
int x;
|
int x;
|
||||||
|
|
||||||
if (!pwdbuf || !username)
|
if (!pwdbuf || !username)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
#ifdef _SC_GETPW_R_SIZE_MAX
|
*pwdbuf = xrealloc(*pwdbuf, UL_GETPW_BUFSIZ);
|
||||||
{
|
|
||||||
long xsz = sysconf(_SC_GETPW_R_SIZE_MAX);
|
|
||||||
if (xsz > 0)
|
|
||||||
sz = (size_t) xsz;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
*pwdbuf = xrealloc(*pwdbuf, sz);
|
|
||||||
|
|
||||||
x = getpwnam_r(username, pwd, *pwdbuf, sz, &res);
|
x = getpwnam_r(username, pwd, *pwdbuf, UL_GETPW_BUFSIZ, &res);
|
||||||
if (!res) {
|
if (!res) {
|
||||||
errno = x;
|
errno = x;
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
Loading…
Reference in New Issue