diff --git a/CHANGELOG b/CHANGELOG index 2c815e7..f8260b1 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -43,6 +43,7 @@ - when default master map, auto.master, is used also check for auto_master. - fix schema selection in LDAP schema discovery. - update negative mount timeout handling. +- fix large group handling (Ryan Thomas). 18/06/2007 autofs-5.0.2 ----------------------- diff --git a/daemon/direct.c b/daemon/direct.c index 4ab4204..88e59ab 100644 --- a/daemon/direct.c +++ b/daemon/direct.c @@ -1218,11 +1218,11 @@ static void *do_mount_direct(void *arg) struct passwd *ppw = &pw; struct passwd **pppw = &ppw; struct group gr; - struct group *pgr = &gr; - struct group **ppgr = &pgr; + struct group *pgr; + struct group **ppgr; char *pw_tmp, *gr_tmp; struct thread_stdenv_vars *tsv; - int tmplen; + int tmplen, grplen; struct stat st; int status, state; @@ -1326,7 +1326,7 @@ static void *do_mount_direct(void *arg) /* Try to get group info */ - tmplen = sysconf(_SC_GETGR_R_SIZE_MAX); + grplen = sysconf(_SC_GETGR_R_SIZE_MAX); if (tmplen < 0) { error(ap->logopt, "failed to get buffer size for getgrgid_r"); free(tsv->user); @@ -1335,16 +1335,28 @@ static void *do_mount_direct(void *arg) goto cont; } - gr_tmp = malloc(tmplen + 1); - if (!gr_tmp) { - error(ap->logopt, "failed to malloc buffer for getgrgid_r"); - free(tsv->user); - free(tsv->home); - free(tsv); - goto cont; + gr_tmp = NULL; + tmplen = grplen; + while (1) { + char *tmp = realloc(gr_tmp, tmplen + 1); + if (!tmp) { + error(ap->logopt, "failed to malloc buffer for getgrgid_r"); + if (gr_tmp) + free(gr_tmp); + free(tsv->user); + free(tsv->home); + free(tsv); + goto cont; + } + gr_tmp = tmp; + pgr = &gr; + ppgr = &pgr; + status = getgrgid_r(mt->gid, pgr, gr_tmp, tmplen, ppgr); + if (status != ERANGE) + break; + tmplen += grplen; } - status = getgrgid_r(mt->gid, pgr, gr_tmp, tmplen, ppgr); if (status || !pgr) { error(ap->logopt, "failed to get group info from getgrgid_r"); free(tsv->user); diff --git a/daemon/indirect.c b/daemon/indirect.c index 5c422c8..f6b93d0 100644 --- a/daemon/indirect.c +++ b/daemon/indirect.c @@ -666,11 +666,11 @@ static void *do_mount_indirect(void *arg) struct passwd *ppw = &pw; struct passwd **pppw = &ppw; struct group gr; - struct group *pgr = &gr; - struct group **ppgr = &pgr; + struct group *pgr; + struct group **ppgr; char *pw_tmp, *gr_tmp; struct thread_stdenv_vars *tsv; - int len, tmplen, status, state; + int len, tmplen, grplen, status, state; mt = (struct pending_args *) arg; @@ -771,7 +771,7 @@ static void *do_mount_indirect(void *arg) /* Try to get group info */ - tmplen = sysconf(_SC_GETGR_R_SIZE_MAX); + grplen = sysconf(_SC_GETGR_R_SIZE_MAX); if (tmplen < 0) { error(ap->logopt, "failed to get buffer size for getgrgid_r"); free(tsv->user); @@ -780,16 +780,28 @@ static void *do_mount_indirect(void *arg) goto cont; } - gr_tmp = malloc(tmplen + 1); - if (!gr_tmp) { - error(ap->logopt, "failed to malloc buffer for getgrgid_r"); - free(tsv->user); - free(tsv->home); - free(tsv); - goto cont; + gr_tmp = NULL; + tmplen = grplen; + while (1) { + char *tmp = realloc(gr_tmp, tmplen + 1); + if (!tmp) { + error(ap->logopt, "failed to malloc buffer for getgrgid_r"); + if (gr_tmp) + free(gr_tmp); + free(tsv->user); + free(tsv->home); + free(tsv); + goto cont; + } + gr_tmp = tmp; + pgr = &gr; + ppgr = &pgr; + status = getgrgid_r(mt->gid, pgr, gr_tmp, tmplen, ppgr); + if (status != ERANGE) + break; + tmplen += grplen; } - status = getgrgid_r(mt->gid, pgr, gr_tmp, tmplen, ppgr); if (status || !pgr) { error(ap->logopt, "failed to get group info from getgrgid_r"); free(tsv->user);