--- src/nsvs/grp.c 2005-05-31 17:46:40.000000000 -0700 +++ src/nsvs/grp.c 2008-10-23 21:33:57.000000000 -0700 @@ -328,18 +328,19 @@ if (++grent.cur_rec > grent.response_header.count) return NSS_NOTFOUND; - if (buflen < grent.response_header.response_size) + if (buflen < grent.response_header.response_size) { + /* Need to back out the grent rec counter for retry */ + --grent.cur_rec; EXHAUSTED_BUFFER; + } /* Load main group data */ memset (buf_out, 0, buflen); status = _load_group (grent.dp, result, buf_out, buflen, errnop); if (status != NSS_SUCCESS) + /* should be backing out here too? really long group name? prob not possible */ return status; - /* Move to next record NOW, as we may not have a member list below */ - grent.dp = (struct response_data *) &(((char *)grent.dp)[grent.dp->header.record_size]); - /* Skip ahead to where we'll put member list */ buf_out += grent.response_header.response_size; buflen -= grent.response_header.response_size; @@ -348,6 +349,19 @@ snprintf (key, 12, "%u", result->gr_gid); status = _get_response_data (GETGRMEMSBYGID, key, &response_header, &data, MULTI_READ_TIMEOUT); + + /* We need to check buffer adequacy for the member list before moving to + * the next record. Also back-out the incremented grent rec counter. */ + if (status == NSS_SUCCESS && + (((buflen - 1) - ((response_header.count + 1) * sizeof(char *))) < + (response_header.response_size - (response_header.count * RDS)))) { + --grent.cur_rec; + EXHAUSTED_BUFFER; + } + + /* Move to next record NOW, as we may not have a member list below */ + grent.dp = (struct response_data *) &(((char *)grent.dp)[grent.dp->header.record_size]); + if (status == NSS_NOTFOUND) { result->gr_mem = (char **) (uintptr_t)buf_out;