- (dtucker) [acconfig.h configure.ac uidswap.c] Bug #645: Check for
   setres[ug]id() present but not implemented (eg some Linux/glibc
   combinations).
diff --git a/ChangeLog b/ChangeLog
index 5c63b2a..f768edc 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -33,6 +33,9 @@
      [dh.c]
      use <= instead of < in dh_estimate; ok provos/hshoexer; 
      do not return < DH_GRP_MIN
+ - (dtucker) [acconfig.h configure.ac uidswap.c] Bug #645: Check for
+   setres[ug]id() present but not implemented (eg some Linux/glibc
+   combinations).
 
 20031209
  - (dtucker) OpenBSD CVS Sync
@@ -1602,4 +1605,4 @@
  - Fix sshd BindAddress and -b options for systems using fake-getaddrinfo.
    Report from murple@murple.net, diagnosis from dtucker@zip.com.au
 
-$Id: ChangeLog,v 1.3147 2003/12/17 05:33:53 djm Exp $
+$Id: ChangeLog,v 1.3148 2003/12/17 07:53:26 dtucker Exp $
diff --git a/acconfig.h b/acconfig.h
index 80907f0..10ffd6b 100644
--- a/acconfig.h
+++ b/acconfig.h
@@ -1,4 +1,4 @@
-/* $Id: acconfig.h,v 1.168 2003/10/15 06:57:57 dtucker Exp $ */
+/* $Id: acconfig.h,v 1.169 2003/12/17 07:53:26 dtucker Exp $ */
 
 /*
  * Copyright (c) 1999-2003 Damien Miller.  All rights reserved.
@@ -41,6 +41,12 @@
 /* Define if your setregid() is broken */
 #undef BROKEN_SETREGID
 
+/* Define if your setresuid() is broken */
+#undef BROKEN_SETRESUID
+
+/* Define if your setresgid() is broken */
+#undef BROKEN_SETRESGID
+
 /* Define to a Set Process Title type if your system is */
 /* supported by bsd-setproctitle.c */
 #undef SPT_TYPE
diff --git a/configure.ac b/configure.ac
index e7249b9..50b43ae 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,4 +1,4 @@
-# $Id: configure.ac,v 1.176 2003/12/08 20:35:59 tim Exp $
+# $Id: configure.ac,v 1.177 2003/12/17 07:53:26 dtucker Exp $
 
 AC_INIT
 AC_CONFIG_SRCDIR([ssh.c])
@@ -780,6 +780,30 @@
 	[#include <termios.h>]
 )
 
+dnl Some platorms have setresuid that isn't implemented
+AC_MSG_CHECKING(if setresuid seems to work)
+AC_TRY_RUN([
+#include <stdlib.h>
+#include <errno.h>
+int main(){errno=0; setresuid(0,0,0); if (errno==ENOSYS) exit(1); else exit(0);}
+	],
+	[AC_MSG_RESULT(yes)],
+	[AC_DEFINE(BROKEN_SETRESUID),
+	 AC_MSG_RESULT(not implemented)]
+)
+
+dnl Some platorms have setresgid that isn't implemented
+AC_MSG_CHECKING(if setresgid seems to work)
+AC_TRY_RUN([
+#include <stdlib.h>
+#include <errno.h>
+int main(){errno=0; setresgid(0,0,0); if (errno==ENOSYS) exit(1); else exit(0);}
+	],
+	[AC_MSG_RESULT(yes)],
+	[AC_DEFINE(BROKEN_SETRESGID)
+	 AC_MSG_RESULT(not implemented)]
+)
+
 dnl    Checks for time functions
 AC_CHECK_FUNCS(gettimeofday time)
 dnl    Checks for utmp functions
diff --git a/uidswap.c b/uidswap.c
index a5f76fd..4cabaa4 100644
--- a/uidswap.c
+++ b/uidswap.c
@@ -151,7 +151,7 @@
 	debug("permanently_set_uid: %u/%u", (u_int)pw->pw_uid,
 	    (u_int)pw->pw_gid);
 
-#if defined(HAVE_SETRESGID)
+#if defined(HAVE_SETRESGID) && !defined(BROKEN_SETRESGID)
 	if (setresgid(pw->pw_gid, pw->pw_gid, pw->pw_gid) < 0)
 		fatal("setresgid %u: %.100s", (u_int)pw->pw_gid, strerror(errno));
 #elif defined(HAVE_SETREGID) && !defined(BROKEN_SETREGID)
@@ -164,7 +164,7 @@
 		fatal("setgid %u: %.100s", (u_int)pw->pw_gid, strerror(errno));
 #endif
 
-#if defined(HAVE_SETRESUID)
+#if defined(HAVE_SETRESUID) && !defined(BROKEN_SETRESUID)
 	if (setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid) < 0)
 		fatal("setresuid %u: %.100s", (u_int)pw->pw_uid, strerror(errno));
 #elif defined(HAVE_SETREUID) && !defined(BROKEN_SETREUID)