- (djm) Some systems (SCO3, NeXT) have weird saved uid semantics.
   Based on patch from Tim Rice <tim@multitalents.net>
diff --git a/ChangeLog b/ChangeLog
index 14374aa..465b26c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,7 @@
 20010226
  - (bal) Fixed bsd-snprinf.c so it now honors 'BROKEN_SNPRINTF' again.
+ - (djm) Some systems (SCO3, NeXT) have weird saved uid semantics. 
+   Based on patch from Tim Rice <tim@multitalents.net>
 
 20010225
  - (djm) Use %{_libexecdir} rather than hardcoded path in RPM specfile
@@ -4129,4 +4131,4 @@
  - Wrote replacements for strlcpy and mkdtemp
  - Released 1.0pre1
 
-$Id: ChangeLog,v 1.822 2001/02/25 23:20:40 mouring Exp $
+$Id: ChangeLog,v 1.823 2001/02/26 09:49:58 djm Exp $
diff --git a/acconfig.h b/acconfig.h
index 01dfb4b..5617d83 100644
--- a/acconfig.h
+++ b/acconfig.h
@@ -1,4 +1,4 @@
-/* $Id: acconfig.h,v 1.103 2001/02/24 21:41:10 mouring Exp $ */
+/* $Id: acconfig.h,v 1.104 2001/02/26 09:49:59 djm Exp $ */
 
 #ifndef _CONFIG_H
 #define _CONFIG_H
@@ -296,6 +296,9 @@
 /* Define if X11 doesn't support AF_UNIX sockets on that system */
 #undef NO_X11_UNIX_SOCKETS
 
+/* Needed for SCO and NeXT */
+#undef SAVED_IDS_WORK_WITH_SETEUID
+
 @BOTTOM@
 
 /* ******************* Shouldn't need to edit below this line ************** */
diff --git a/configure.in b/configure.in
index 4ed1eb7..7f571bb 100644
--- a/configure.in
+++ b/configure.in
@@ -1,4 +1,4 @@
-# $Id: configure.in,v 1.253 2001/02/24 21:41:11 mouring Exp $
+# $Id: configure.in,v 1.254 2001/02/26 09:49:59 djm Exp $
 
 AC_INIT(ssh.c)
 
@@ -152,6 +152,7 @@
 	AC_DEFINE(HAVE_NEXT)
 	AC_DEFINE(BROKEN_REALPATH)
 	AC_DEFINE(USE_PIPES)
+	AC_DEFINE(SAVED_IDS_WORK_WITH_SETEUID)
 	CPPFLAGS="$CPPFLAGS -I/usr/local/include"
 	CFLAGS="$CFLAGS"
 	;;
@@ -238,6 +239,7 @@
 	AC_DEFINE(HAVE_SCO_PROTECTED_PW)
 	AC_DEFINE(DISABLE_SHADOW)
 	AC_DEFINE(HAVE_BOGUS_SYS_QUEUE_H)
+	AC_DEFINE(SAVED_IDS_WORK_WITH_SETEUID)
 	AC_CHECK_FUNCS(getluid setluid)
 	;;
 *-*-sco3.2v5*)
@@ -252,6 +254,7 @@
 	AC_DEFINE(HAVE_SCO_PROTECTED_PW)
 	AC_DEFINE(DISABLE_SHADOW)
 	AC_DEFINE(HAVE_BOGUS_SYS_QUEUE_H)
+	AC_DEFINE(SAVED_IDS_WORK_WITH_SETEUID)
 	AC_CHECK_FUNCS(getluid setluid)
 	;;
 *-dec-osf*)
diff --git a/entropy.c b/entropy.c
index 5a85009..daff1e6 100644
--- a/entropy.c
+++ b/entropy.c
@@ -39,7 +39,7 @@
 #include "pathnames.h"
 #include "log.h"
 
-RCSID("$Id: entropy.c,v 1.29 2001/02/18 11:34:32 stevesk Exp $");
+RCSID("$Id: entropy.c,v 1.30 2001/02/26 09:49:59 djm Exp $");
 
 #ifndef offsetof
 # define offsetof(type, member) ((size_t) &((type *)0)->member)
@@ -825,13 +825,34 @@
 	prng_seed_saved = 0;
 
 	/* Give up privs while reading seed file */
+#ifdef SAVED_IDS_WORK_WITH_SETEUID
 	if ((original_uid != original_euid) && (seteuid(original_uid) == -1))
 		fatal("Couldn't give up privileges");
+#else /* SAVED_IDS_WORK_WITH_SETEUID */
+	/*
+	 * Propagate the privileged uid to all of our uids.
+	 * Set the effective uid to the given (unprivileged) uid. 
+	 */
+	if (original_uid != original_euid && setuid(original_euid) == -1 || 
+	    seteuid(original_uid) == -1)
+		fatal("Couldn't give up privileges");
+#endif /* SAVED_IDS_WORK_WITH_SETEUID */
 
 	prng_read_seedfile();
 
+#ifdef SAVED_IDS_WORK_WITH_SETEUID
 	if ((original_uid != original_euid) && (seteuid(original_euid) == -1))
 		fatal("Couldn't restore privileges");
+#else /* SAVED_IDS_WORK_WITH_SETEUID */
+	/*
+	 * We are unable to restore the real uid to its unprivileged value.
+	 * Propagate the real uid (usually more privileged) to effective uid
+	 * as well.
+	 */
+	if (original_uid != original_euid && seteuid(original_euid) == -1 || 
+	    setuid(original_uid) == -1)
+		fatal("Couldn't restore privileges");
+#endif /* SAVED_IDS_WORK_WITH_SETEUID */
 
 	fatal_add_cleanup(prng_seed_cleanup, NULL);
 	atexit(prng_write_seedfile);