Issue #243: Cannot look up group "shellinabox" at service start
_SC_GETGR_R_SIZE_MAX was treated as a maximum buffer size while it should only be a proposition for an initial size. The buffer size is now increased dynamically if the initial size is not sufficient.
This commit is contained in:
parent
5372964801
commit
5f1aaea6f1
1 changed files with 42 additions and 20 deletions
|
@ -363,8 +363,12 @@ static int getgrnam_r(const char *name, struct group *grp, char *buf,
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
gid_t getGroupId(const char *name) {
|
gid_t getGroupId(const char *name) {
|
||||||
|
static const long gr_max = 64 * 1024;
|
||||||
struct group grbuf, *gr;
|
struct group grbuf, *gr;
|
||||||
|
char *temp;
|
||||||
char *buf;
|
char *buf;
|
||||||
|
int ret;
|
||||||
|
int gr_baselen;
|
||||||
#ifdef _SC_GETGR_R_SIZE_MAX
|
#ifdef _SC_GETGR_R_SIZE_MAX
|
||||||
int gr_len = sysconf(_SC_GETGR_R_SIZE_MAX);
|
int gr_len = sysconf(_SC_GETGR_R_SIZE_MAX);
|
||||||
if (gr_len <= 0) {
|
if (gr_len <= 0) {
|
||||||
|
@ -373,11 +377,17 @@ gid_t getGroupId(const char *name) {
|
||||||
#else
|
#else
|
||||||
int gr_len = 4096;
|
int gr_len = 4096;
|
||||||
#endif
|
#endif
|
||||||
|
gr_baselen = gr_len;
|
||||||
check(buf = malloc(gr_len));
|
check(buf = malloc(gr_len));
|
||||||
if (getgrnam_r(name, &grbuf, buf, gr_len, &gr) || !gr) {
|
for(;;) {
|
||||||
|
errno = 0;
|
||||||
|
ret = getgrnam_r(name, &grbuf, buf, gr_len, &gr);
|
||||||
|
if(!ret) {
|
||||||
|
if(gr) {
|
||||||
|
break;
|
||||||
|
} else if(!strcmp(name, "nogroup")) {
|
||||||
// Maybe, this system does not have a "nogroup" group. Substitute the
|
// Maybe, this system does not have a "nogroup" group. Substitute the
|
||||||
// group of the "nobody" user.
|
// group of the "nobody" user.
|
||||||
if (!strcmp(name, "nogroup")) {
|
|
||||||
struct passwd pwbuf, *pw;
|
struct passwd pwbuf, *pw;
|
||||||
#ifdef _SC_GETPW_R_SIZE_MAX
|
#ifdef _SC_GETPW_R_SIZE_MAX
|
||||||
int pw_len = sysconf(_SC_GETPW_R_SIZE_MAX);
|
int pw_len = sysconf(_SC_GETPW_R_SIZE_MAX);
|
||||||
|
@ -397,6 +407,18 @@ gid_t getGroupId(const char *name) {
|
||||||
return gid;
|
return gid;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
if(ret && errno == ERANGE) {
|
||||||
|
if ((gr_len + gr_baselen) < gr_len || (gr_len + gr_baselen) > gr_max) {
|
||||||
|
fatal("Cannot look up group \"%s\": buffer limit reached", name);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// grow the buffer by 'gr_baselen' each time getgrnam_r fails
|
||||||
|
gr_len += gr_baselen;
|
||||||
|
check(temp = realloc (buf, gr_len));
|
||||||
|
buf = temp;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
fatal("Cannot look up group \"%s\"", name);
|
fatal("Cannot look up group \"%s\"", name);
|
||||||
}
|
}
|
||||||
gid_t gid = gr->gr_gid;
|
gid_t gid = gr->gr_gid;
|
||||||
|
|
Loading…
Reference in a new issue