Subject: lib/20931: patch to fix NIS support in getusershell(3)
To: None <gnats-bugs@gnats.netbsd.org>
From: None <robert@FreeBSD.org>
List: netbsd-bugs
Date: 03/29/2003 08:36:39
>Number:         20931
>Category:       lib
>Synopsis:       patch to fix NIS support in getusershell(3)
>Confidential:   no
>Severity:       serious
>Priority:       low
>Responsible:    lib-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Fri Mar 28 23:37:00 PST 2003
>Closed-Date:
>Last-Modified:
>Originator:     
>Release:        NetBSD 1.6Q, 20030323
>Organization:
>Environment:
System: NetBSD rice 1.6Q NetBSD 1.6Q (GENERIC) #0: Sun Mar 23 23:32:39 UTC 2003 robert@rice:/home/robert/NetBSD-current/src/sys/arch/i386/compile/GENERIC i386
Architecture: i386
Machine: i386
>Description:
	NIS support for getusershell() is broken.

>How-To-Repeat:
	Look at src/lib/libc/gen/getusershell.c or try to set
	'shells:    nis' in /etc/nsswitch.conf and call getusershell().
>Fix:

Index: getusershell.c
===================================================================
RCS file: /cvsroot/src/lib/libc/gen/getusershell.c,v
retrieving revision 1.22
diff -u -r1.22 getusershell.c
--- getusershell.c	26 May 2002 14:03:20 -0000	1.22
+++ getusershell.c	29 Mar 2003 07:28:58 -0000
@@ -222,6 +222,10 @@
 	va_list	 ap;
 {
 	static char *ypdomain;
+	char	*key, *data;
+	char	*lastkey;
+	int	 keylen, datalen;
+	int	 r;
 
 	if (sl)
 		sl_free(sl, 1);
@@ -240,43 +244,32 @@
 		}
 	}
 
-	for (;;) {
-		char	*ypcur = NULL;
-		int	 ypcurlen = 0;	/* XXX: GCC */
-		char	*key, *data;
-		int	 keylen, datalen;
-		int	 r;
-
-		key = data = NULL;
-		if (ypcur) {
-			r = yp_next(ypdomain, "shells", ypcur, ypcurlen,
-					&key, &keylen, &data, &datalen);
-			free(ypcur);
-			switch (r) {
-			case 0:
-				break;
-			case YPERR_NOMORE:
-				free(key);
-				free(data);
-				return (NS_SUCCESS);
-			default:
-				free(key);
-				free(data);
-				return (NS_UNAVAIL);
-			}
-			ypcur = key;
-			ypcurlen = keylen;
-		} else {
-			if (yp_first(ypdomain, "shells", &ypcur,
-				    &ypcurlen, &data, &datalen)) {
-				free(data);
-				return (NS_UNAVAIL);
-			}
-		}
+	/*
+	 * `key' and `data' point to strings dynamically allocated by
+	 * the yp_... functions.
+	 * `data' is directly put into the stringlist of shells.
+	 */
+	key = data = NULL;
+	if (yp_first(ypdomain, "shells", &key, &keylen, &data, &datalen))
+		return (NS_UNAVAIL);
+	do {
 		data[datalen] = '\0';		/* clear trailing \n */
-		if (sl_add(sl, data) == -1)
-			return (NS_UNAVAIL);
+		sl_add(sl, data);
+
+		lastkey = key;
+		r = yp_next(ypdomain, "shells", lastkey, keylen,
+		    &key, &keylen, &data, &datalen);
+		free(lastkey);
+	} while (r == 0);
+	
+	if (r == YPERR_NOMORE) {
+		/*
+		 * `data' and `key' ought to be NULL - do not try to free them.
+		 */
+		return (NS_SUCCESS);
 	}
+
+	return (NS_UNAVAIL);
 }
 #endif /* YP */
 
>Release-Note:
>Audit-Trail:
>Unformatted: