- (dtucker) [configure.ac openbsd-compat/{Makefile.in,pwcache.c} Portability
   for pwcache.  Also, added caching of negative hits.
diff --git a/ChangeLog b/ChangeLog
index 5e2caf3..d7b0822 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -23,6 +23,8 @@
      ok dtucker@
  - (dtucker) [openbsd-compat.c/pwcache.c] Pull in pwcache.c from OpenBSD (no
    changes yet but there will be some to come).
+ - (dtucker) [configure.ac openbsd-compat/{Makefile.in,pwcache.c} Portability
+   for pwcache.  Also, added caching of negative hits.
 
 20100114
  - (djm) [platform.h] Add missing prototype for
diff --git a/configure.ac b/configure.ac
index e6e6259..3293e61 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,4 +1,4 @@
-# $Id: configure.ac,v 1.434 2010/01/09 23:26:58 dtucker Exp $
+# $Id: configure.ac,v 1.435 2010/01/15 01:38:30 dtucker Exp $
 #
 # Copyright (c) 1999-2004 Damien Miller
 #
@@ -15,7 +15,7 @@
 # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 
 AC_INIT(OpenSSH, Portable, openssh-unix-dev@mindrot.org)
-AC_REVISION($Revision: 1.434 $)
+AC_REVISION($Revision: 1.435 $)
 AC_CONFIG_SRCDIR([ssh.c])
 
 AC_CONFIG_HEADER(config.h)
@@ -1351,6 +1351,7 @@
 	getrlimit \
 	getttyent \
 	glob \
+	group_from_gid \
 	inet_aton \
 	inet_ntoa \
 	inet_ntop \
@@ -1377,8 +1378,10 @@
 	setegid \
 	setenv \
 	seteuid \
+	setgroupent \
 	setgroups \
 	setlogin \
+	setpassent\
 	setpcred \
 	setproctitle \
 	setregid \
@@ -1407,6 +1410,7 @@
 	truncate \
 	unsetenv \
 	updwtmpx \
+	user_from_uid \
 	vasprintf \
 	vhangup \
 	vsnprintf \
diff --git a/openbsd-compat/Makefile.in b/openbsd-compat/Makefile.in
index a60e5a6..d65b77b 100644
--- a/openbsd-compat/Makefile.in
+++ b/openbsd-compat/Makefile.in
@@ -1,4 +1,4 @@
-# $Id: Makefile.in,v 1.43 2008/06/08 17:32:29 dtucker Exp $
+# $Id: Makefile.in,v 1.44 2010/01/15 01:38:30 dtucker Exp $
 
 sysconfdir=@sysconfdir@
 piddir=@piddir@
@@ -16,7 +16,7 @@
 INSTALL=@INSTALL@
 LDFLAGS=-L. @LDFLAGS@
 
-OPENBSD=base64.o basename.o bindresvport.o daemon.o dirname.o fmt_scaled.o getcwd.o getgrouplist.o getopt.o getrrsetbyname.o glob.o inet_aton.o inet_ntoa.o inet_ntop.o mktemp.o readpassphrase.o realpath.o rresvport.o setenv.o setproctitle.o sha2.o sigact.o strlcat.o strlcpy.o strmode.o strsep.o strtonum.o strtoll.o strtoul.o vis.o
+OPENBSD=base64.o basename.o bindresvport.o daemon.o dirname.o fmt_scaled.o getcwd.o getgrouplist.o getopt.o getrrsetbyname.o glob.o inet_aton.o inet_ntoa.o inet_ntop.o mktemp.o pwcache.o readpassphrase.o realpath.o rresvport.o setenv.o setproctitle.o sha2.o sigact.o strlcat.o strlcpy.o strmode.o strsep.o strtonum.o strtoll.o strtoul.o vis.o
 
 COMPAT=bsd-arc4random.o bsd-asprintf.o bsd-closefrom.o bsd-cray.o bsd-cygwin_util.o bsd-getpeereid.o bsd-misc.o bsd-nextstep.o bsd-openpty.o bsd-poll.o bsd-snprintf.o bsd-statvfs.o bsd-waitpid.o fake-rfc2553.o openssl-compat.o xmmap.o xcrypt.o
 
diff --git a/openbsd-compat/pwcache.c b/openbsd-compat/pwcache.c
index 6f8e644..472505d 100644
--- a/openbsd-compat/pwcache.c
+++ b/openbsd-compat/pwcache.c
@@ -28,22 +28,26 @@
  * SUCH DAMAGE.
  */
 
+/* OPENBSD ORIGINAL: lib/libc/gen/pwcache.c */
+
 #include <sys/types.h>
 
 #include <grp.h>
 #include <pwd.h>
 #include <stdio.h>
+#include <stdlib.h>
 #include <string.h>
 
 #define	NCACHE	64			/* power of 2 */
 #define	MASK	(NCACHE - 1)		/* bits to store with */
 
+#ifndef HAVE_USER_FROM_UID
 char *
 user_from_uid(uid_t uid, int nouser)
 {
 	static struct ncache {
 		uid_t	uid;
-		char	name[_PW_NAME_LEN + 1];
+		char	*name;
 	} c_uid[NCACHE];
 	static int pwopen;
 	static char nbuf[15];		/* 32 bits == 10 digits */
@@ -51,29 +55,34 @@
 	struct ncache *cp;
 
 	cp = c_uid + (uid & MASK);
-	if (cp->uid != uid || !*cp->name) {
+	if (cp->uid != uid || cp->name == NULL) {
+#ifdef HAVE_SETPASSENT
 		if (pwopen == 0) {
 			setpassent(1);
 			pwopen = 1;
 		}
+#endif
 		if ((pw = getpwuid(uid)) == NULL) {
 			if (nouser)
 				return (NULL);
 			(void)snprintf(nbuf, sizeof(nbuf), "%u", uid);
-			return (nbuf);
 		}
 		cp->uid = uid;
-		strlcpy(cp->name, pw->pw_name, sizeof(cp->name));
+		if (cp->name != NULL)
+			free(cp->name);
+		cp->name = strdup(pw ? pw->pw_name : nbuf);
 	}
 	return (cp->name);
 }
+#endif
 
+#ifndef HAVE_GROUP_FROM_GID
 char *
 group_from_gid(gid_t gid, int nogroup)
 {
 	static struct ncache {
 		gid_t	gid;
-		char	name[_PW_NAME_LEN + 1];
+		char	*name;
 	} c_gid[NCACHE];
 	static int gropen;
 	static char nbuf[15];		/* 32 bits == 10 digits */
@@ -81,19 +90,23 @@
 	struct ncache *cp;
 
 	cp = c_gid + (gid & MASK);
-	if (cp->gid != gid || !*cp->name) {
+	if (cp->gid != gid || cp->name == NULL) {
+#ifdef HAVE_SETGROUPENT
 		if (gropen == 0) {
 			setgroupent(1);
 			gropen = 1;
 		}
+#endif
 		if ((gr = getgrgid(gid)) == NULL) {
 			if (nogroup)
 				return (NULL);
 			(void)snprintf(nbuf, sizeof(nbuf), "%u", gid);
-			return (nbuf);
 		}
 		cp->gid = gid;
-		strlcpy(cp->name, gr->gr_name, sizeof(cp->name));
+		if (cp->name != NULL)
+			free(cp->name);
+		cp->name = strdup(gr ? gr->gr_name : nbuf);
 	}
 	return (cp->name);
 }
+#endif