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