NeXT // Broken _POSIX_SAVED_ID patch

mouring at etoh.eviladmin.org mouring at etoh.eviladmin.org
Wed Apr 25 16:19:36 EST 2001


Ok, for those running NeXT and other platforms with broken/missing
_POSIX_SAVED_ID please try this patch, and anyone that has spent any
amount of time dealing with this problem.

I believe it's right.

BTW, this patch is no where near as big as it looks.  The patch was
done against an earily version of the tree which had an issue with
white space.

- Ben

--- ../openssh/uidswap.c	Sun Apr 22 06:58:50 2001
+++ uidswap.c.new	Tue Apr 24 20:13:22 2001
@@ -26,17 +26,21 @@
  * POSIX saved uids or not.
  */

+#if defined(_POSIX_SAVED_IDS) && !defined(BROKEN_SAVED_UIDS)
 /* Lets assume that posix saved ids also work with seteuid, even though that
    is not part of the posix specification. */
-
+#define SAVED_IDS_WORK_WITH_SETEUID
+/* Saved effective uid. */
+static uid_t 	saved_euid = 0;
+static gid_t	saved_egid = 0;
+#endif
+
 /* Saved effective uid. */
 static int	privileged = 0;
 static int	temporarily_use_uid_effective = 0;
-static uid_t	saved_euid = 0;
-static gid_t	saved_egid;
 static gid_t	saved_egroups[NGROUPS_MAX], user_groups[NGROUPS_MAX];
 static int	saved_egroupslen = -1, user_groupslen = -1;
-
+
 /*
  * Temporarily changes to the given uid.  If the effective user
  * id is not root, this does nothing.  This call cannot be nested.
@@ -44,42 +48,57 @@
 void
 temporarily_use_uid(struct passwd *pw)
 {
- 	/* Save the current euid, and egroups. */
-  	saved_euid = geteuid();
- 	debug("temporarily_use_uid: %d/%d (e=%d)",
- 	    pw->pw_uid, pw->pw_gid, saved_euid);
- 	if (saved_euid != 0) {
- 		privileged = 0;
- 		return;
- 	}
- 	privileged = 1;
- 	temporarily_use_uid_effective = 1;
+	/* Save the current euid, and egroups. */
+#ifdef SAVED_IDS_WORK_WITH_SETEUID
+	saved_euid = geteuid();
 	saved_egid = getegid();
-	saved_egroupslen = getgroups(NGROUPS_MAX, saved_egroups);
- 	if (saved_egroupslen < 0)
- 		fatal("getgroups: %.100s", strerror(errno));
-
- 	/* set and save the user's groups */
- 	if (user_groupslen == -1) {
- 		if (initgroups(pw->pw_name, pw->pw_gid) < 0)
- 			fatal("initgroups: %s: %.100s", pw->pw_name,
- 			    strerror(errno));
- 		user_groupslen = getgroups(NGROUPS_MAX, user_groups);
- 		if (user_groupslen < 0)
- 			fatal("getgroups: %.100s", strerror(errno));
- 	}
-  	/* Set the effective uid to the given (unprivileged) uid. */
+	debug("temporarily_use_uid: %d/%d (e=%d)",
+	    pw->pw_uid, pw->pw_gid, saved_euid);
+	if (saved_euid != 0) {
+		privileged = 0;
+		return;
+	}
+#else
+	if (geteuid() != 0) {
+		privileged = 0;
+		return;
+	}
+#endif /* SAVED_IDS_WORK_WITH_SETEUID */
+
+	privileged = 1;
+	temporarily_use_uid_effective = 1;
+	saved_egroupslen = getgroups(NGROUPS_MAX, saved_egroups);
+	if (saved_egroupslen < 0)
+		fatal("getgroups: %.100s", strerror(errno));
+
+	/* set and save the user's groups */
+	if (user_groupslen == -1) {
+		if (initgroups(pw->pw_name, pw->pw_gid) < 0)
+			fatal("initgroups: %s: %.100s", pw->pw_name,
+			    strerror(errno));
+		user_groupslen = getgroups(NGROUPS_MAX, user_groups);
+		if (user_groupslen < 0)
+			fatal("getgroups: %.100s", strerror(errno));
+	}
+	/* Set the effective uid to the given (unprivileged) uid. */
 	if (setgroups(user_groupslen, user_groups) < 0)
 		fatal("setgroups: %.100s", strerror(errno));
-	pw->pw_gid = pw->pw_gid;
+#ifndef SAVED_IDS_WORK_WITH_SETEUID
+	/* Propagate the privileged gid to all of our gids. */
+	if (setgid(getegid()) < 0)
+		debug("setgid %u: %.100s", (u_int) getegid(), strerror(errno));
+	/* Propagate the privileged uid to all of our uids. */
+	if (setuid(geteuid()) < 0)
+		debug("setuid %u: %.100s", (u_int) geteuid(), strerror(errno));
+#endif /* SAVED_IDS_WORK_WITH_SETEUID */
 	if (setegid(pw->pw_gid) < 0)
- 		fatal("setegid %u: %.100s", (u_int) pw->pw_gid,
- 		    strerror(errno));
- 	if (seteuid(pw->pw_uid) == -1)
- 		fatal("seteuid %u: %.100s", (u_int) pw->pw_uid,
- 		    strerror(errno));
+		fatal("setegid %u: %.100s", (u_int) pw->pw_gid,
+		    strerror(errno));
+	if (seteuid(pw->pw_uid) == -1)
+		fatal("seteuid %u: %.100s", (u_int) pw->pw_uid,
+		    strerror(errno));
 }
-
+
 /*
  * Restores to the original (privileged) uid.
  */
@@ -92,13 +111,27 @@
 		return;
 	if (!temporarily_use_uid_effective)
 		fatal("restore_uid: temporarily_use_uid not effective");
+
+#ifdef SAVED_IDS_WORK_WITH_SETEUID
 	/* Set the effective uid back to the saved privileged uid. */
 	if (seteuid(saved_euid) < 0)
-		fatal("seteuid %u: %.100s", (u_int) saved_euid, strerror(errno));
+		fatal("seteuid %u: %.100s", (u_int) saved_euid,
+		    strerror(errno));
+	if (setegid(saved_egid) < 0)
+		fatal("setegid %u: %.100s", (u_int) saved_egid,
+		    strerror(errno));
+#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.
+	 */
+	setuid(getuid());
+	setgid(getgid());
+#endif /* SAVED_IDS_WORK_WITH_SETEUID */
+
 	if (setgroups(saved_egroupslen, saved_egroups) < 0)
 		fatal("setgroups: %.100s", strerror(errno));
-	if (setegid(saved_egid) < 0)
-		fatal("setegid %u: %.100s", (u_int) saved_egid, strerror(errno));
 	temporarily_use_uid_effective = 0;
 }






More information about the openssh-unix-dev mailing list