From 5ec1c28867cc831823aa9d848fa6fb9012148ff8 Mon Sep 17 00:00:00 2001 From: araujo Date: Thu, 19 Nov 2015 13:36:53 +0000 Subject: If a NIS server has long entries on its database that is bigger than 1024 specified on YPMAXRECORD the ypmatch can get in an infinite retry loop when is requesting the information from the NIS server. The ypmatch(1) will return an error until the command receives an kill(1). To avoid this problem, we check the MAX_RETRIES that is by default set to 20 and avoid get in infinet loop at the client side. NOTE: FreeBSD nis(8) server doesn't present this issue. Submitted by: Ravi Pokala , Lakshmi N. Sundararajan , Lewis, Fred , Pushkar Kothavade Approved by: bapt (mentor) MFC after: 1 month Differential Revision: D4095 --- lib/libc/yp/yplib.c | 33 ++++++++++++++++++++++++++++----- 1 file changed, 28 insertions(+), 5 deletions(-) (limited to 'lib/libc') diff --git a/lib/libc/yp/yplib.c b/lib/libc/yp/yplib.c index 1778c6a..1a6df69 100644 --- a/lib/libc/yp/yplib.c +++ b/lib/libc/yp/yplib.c @@ -655,7 +655,7 @@ yp_match(char *indomain, char *inmap, const char *inkey, int inkeylen, struct timeval tv; struct ypreq_key yprk; int r; - + int retries = 0; *outval = NULL; *outvallen = 0; @@ -700,6 +700,11 @@ yp_match(char *indomain, char *inmap, const char *inkey, int inkeylen, #endif again: + if (retries > MAX_RETRIES) { + YPUNLOCK(); + return (YPERR_RPC); + } + if (_yp_dobind(indomain, &ysd) != 0) { YPUNLOCK(); return (YPERR_DOMAIN); @@ -716,6 +721,7 @@ again: if (r != RPC_SUCCESS) { clnt_perror(ysd->dom_client, "yp_match: clnt_call"); _yp_unbind(ysd); + retries++; goto again; } @@ -772,7 +778,7 @@ yp_first(char *indomain, char *inmap, char **outkey, int *outkeylen, struct dom_binding *ysd; struct timeval tv; int r; - + int retries = 0; /* Sanity check */ if (indomain == NULL || !strlen(indomain) || @@ -784,6 +790,11 @@ yp_first(char *indomain, char *inmap, char **outkey, int *outkeylen, YPLOCK(); again: + if (retries > MAX_RETRIES) { + YPUNLOCK(); + return (YPERR_RPC); + } + if (_yp_dobind(indomain, &ysd) != 0) { YPUNLOCK(); return (YPERR_DOMAIN); @@ -802,6 +813,7 @@ again: if (r != RPC_SUCCESS) { clnt_perror(ysd->dom_client, "yp_first: clnt_call"); _yp_unbind(ysd); + retries++; goto again; } if (!(r = ypprot_err(yprkv.stat))) { @@ -844,7 +856,7 @@ yp_next(char *indomain, char *inmap, char *inkey, int inkeylen, struct dom_binding *ysd; struct timeval tv; int r; - + int retries = 0; /* Sanity check */ if (inkey == NULL || !strlen(inkey) || inkeylen <= 0 || @@ -857,6 +869,11 @@ yp_next(char *indomain, char *inmap, char *inkey, int inkeylen, YPLOCK(); again: + if (retries > MAX_RETRIES) { + YPUNLOCK(); + return (YPERR_RPC); + } + if (_yp_dobind(indomain, &ysd) != 0) { YPUNLOCK(); return (YPERR_DOMAIN); @@ -877,6 +894,7 @@ again: if (r != RPC_SUCCESS) { clnt_perror(ysd->dom_client, "yp_next: clnt_call"); _yp_unbind(ysd); + retries++; goto again; } if (!(r = ypprot_err(yprkv.stat))) { @@ -920,7 +938,7 @@ yp_all(char *indomain, char *inmap, struct ypall_callback *incallback) CLIENT *clnt; u_long status, savstat; int clnt_sock; - + int retries = 0; /* Sanity check */ if (indomain == NULL || !strlen(indomain) || @@ -929,6 +947,10 @@ yp_all(char *indomain, char *inmap, struct ypall_callback *incallback) YPLOCK(); again: + if (retries > MAX_RETRIES) { + YPUNLOCK(); + return (YPERR_RPC); + } if (_yp_dobind(indomain, &ysd) != 0) { YPUNLOCK(); @@ -958,9 +980,10 @@ again: if (clnt_call(clnt, YPPROC_ALL, (xdrproc_t)xdr_ypreq_nokey, &yprnk, (xdrproc_t)xdr_ypresp_all_seq, &status, tv) != RPC_SUCCESS) { - clnt_perror(ysd->dom_client, "yp_all: clnt_call"); + clnt_perror(clnt, "yp_all: clnt_call"); clnt_destroy(clnt); _yp_unbind(ysd); + retries++; goto again; } -- cgit v1.1