summaryrefslogtreecommitdiff
path: root/nis/nss_compat/compat-grp.c
diff options
context:
space:
mode:
Diffstat (limited to 'nis/nss_compat/compat-grp.c')
-rw-r--r--nis/nss_compat/compat-grp.c94
1 files changed, 81 insertions, 13 deletions
diff --git a/nis/nss_compat/compat-grp.c b/nis/nss_compat/compat-grp.c
index 59165ea590..9726784b2d 100644
--- a/nis/nss_compat/compat-grp.c
+++ b/nis/nss_compat/compat-grp.c
@@ -218,6 +218,10 @@ getgrent_next_nis (struct group *result, ent_t *ent, char *buffer,
do
{
+ char *save_oldkey;
+ int save_oldlen;
+ bool_t save_nis_first;
+
if (ent->nis_first)
{
if (yp_first (domain, "group.byname", &outkey, &outkeylen,
@@ -226,7 +230,9 @@ getgrent_next_nis (struct group *result, ent_t *ent, char *buffer,
ent->nis = 0;
return NSS_STATUS_UNAVAIL;
}
-
+ save_oldkey = ent->oldkey;
+ save_oldlen = ent->oldkeylen;
+ save_nis_first = TRUE;
ent->oldkey = outkey;
ent->oldkeylen = outkeylen;
ent->nis_first = FALSE;
@@ -241,7 +247,9 @@ getgrent_next_nis (struct group *result, ent_t *ent, char *buffer,
return NSS_STATUS_NOTFOUND;
}
- free (ent->oldkey);
+ save_oldkey = ent->oldkey;
+ save_oldlen = ent->oldkeylen;
+ save_nis_first = FALSE;
ent->oldkey = outkey;
ent->oldkeylen = outkeylen;
}
@@ -255,8 +263,21 @@ getgrent_next_nis (struct group *result, ent_t *ent, char *buffer,
while (isspace (*p))
++p;
- parse_res = _nss_files_parse_grent (p, result, data, buflen);
-
+ if ((parse_res = _nss_files_parse_grent (p, result, data, buflen)) == -1)
+ {
+ free (ent->oldkey);
+ ent->oldkey = save_oldkey;
+ ent->oldkeylen = save_oldlen;
+ ent->nis_first = save_nis_first;
+ __set_errno (ERANGE);
+ return NSS_STATUS_TRYAGAIN;
+ }
+ else
+ {
+ if (!save_nis_first)
+ free (save_oldkey);
+ }
+
if (parse_res &&
in_blacklist (result->gr_name, strlen (result->gr_name), ent))
parse_res = 0; /* if result->gr_name in blacklist,search next entry */
@@ -274,8 +295,13 @@ getgrent_next_nisplus (struct group *result, ent_t *ent, char *buffer,
do
{
+ nis_result *save_oldres;
+ bool_t save_nis_first;
+
if (ent->nis_first)
{
+ save_oldres = ent->result;
+ save_nis_first = TRUE;
ent->result = nis_first_entry(grptable);
if (niserr2nss (ent->result->status) != NSS_STATUS_SUCCESS)
{
@@ -288,8 +314,9 @@ getgrent_next_nisplus (struct group *result, ent_t *ent, char *buffer,
{
nis_result *res;
+ save_oldres = ent->result;
+ save_nis_first = FALSE;
res = nis_next_entry(grptable, &ent->result->cookie);
- nis_freeresult (ent->result);
ent->result = res;
if (niserr2nss (ent->result->status) != NSS_STATUS_SUCCESS)
{
@@ -297,8 +324,21 @@ getgrent_next_nisplus (struct group *result, ent_t *ent, char *buffer,
return niserr2nss (ent->result->status);
}
}
- parse_res = _nss_nisplus_parse_grent (ent->result, 0, result, buffer,
- buflen);
+ if ((parse_res = _nss_nisplus_parse_grent (ent->result, 0, result,
+ buffer, buflen)) == -1)
+ {
+ nis_freeresult (ent->result);
+ ent->result = save_oldres;
+ ent->nis_first = save_nis_first;
+ __set_errno (ERANGE);
+ return NSS_STATUS_TRYAGAIN;
+ }
+ else
+ {
+ if (!save_nis_first)
+ nis_freeresult (save_oldres);
+ }
+
if (parse_res &&
in_blacklist (result->gr_name, strlen (result->gr_name), ent))
parse_res = 0; /* if result->gr_name in blacklist,search next entry */
@@ -330,7 +370,13 @@ getgrent_next_file_plusgroup (struct group *result, char *buffer,
nis_freeresult (res);
return status;
}
- parse_res = _nss_nisplus_parse_grent (res, 0, result, buffer, buflen);
+ if ((parse_res = _nss_nisplus_parse_grent (res, 0, result, buffer,
+ buflen)) == -1)
+ {
+ __set_errno (ERANGE);
+ nis_freeresult (res);
+ return NSS_STATUS_TRYAGAIN;
+ }
nis_freeresult (res);
}
else /* Use NIS */
@@ -350,7 +396,11 @@ getgrent_next_file_plusgroup (struct group *result, char *buffer,
free (outval);
while (isspace (*p))
p++;
- parse_res = _nss_files_parse_grent (p, result, data, buflen);
+ if ((parse_res = _nss_files_parse_grent (p, result, data, buflen)) == -1)
+ {
+ __set_errno (ERANGE);
+ return NSS_STATUS_TRYAGAIN;
+ }
}
if (parse_res)
@@ -368,13 +418,24 @@ getgrent_next_file (struct group *result, ent_t *ent,
struct parser_data *data = (void *) buffer;
while (1)
{
+ fpos_t pos;
+ int parse_res = 0;
char *p;
do
{
+ fgetpos (ent->stream, &pos);
p = fgets (buffer, buflen, ent->stream);
if (p == NULL)
- return NSS_STATUS_NOTFOUND;
+ {
+ if (feof (ent->stream))
+ return NSS_STATUS_NOTFOUND;
+ else
+ {
+ __set_errno (ERANGE);
+ return NSS_STATUS_TRYAGAIN;
+ }
+ }
/* Terminate the line for any case. */
buffer[buflen - 1] = '\0';
@@ -383,11 +444,18 @@ getgrent_next_file (struct group *result, ent_t *ent,
while (isspace (*p))
++p;
}
- /* Ignore empty and comment lines. */
- while (*p == '\0' || *p == '#' ||
+ while (*p == '\0' || *p == '#' || /* Ignore empty and comment lines. */
/* Parse the line. If it is invalid, loop to
get the next line of the file to parse. */
- !_nss_files_parse_grent (p, result, data, buflen));
+ !(parse_res = _nss_files_parse_grent (p, result, data, buflen)));
+
+ if (parse_res == -1)
+ {
+ /* The parser ran out of space. */
+ fsetpos (ent->stream, &pos);
+ __set_errno (ERANGE);
+ return NSS_STATUS_TRYAGAIN;
+ }
if (result->gr_name[0] != '+' && result->gr_name[0] != '-')
/* This is a real entry. */