aboutsummaryrefslogtreecommitdiff
path: root/crypto/openssh/uidswap.c
diff options
context:
space:
mode:
Diffstat (limited to 'crypto/openssh/uidswap.c')
-rw-r--r--crypto/openssh/uidswap.c15
1 files changed, 15 insertions, 0 deletions
diff --git a/crypto/openssh/uidswap.c b/crypto/openssh/uidswap.c
index 6ed3024d0180..0143f4994611 100644
--- a/crypto/openssh/uidswap.c
+++ b/crypto/openssh/uidswap.c
@@ -14,6 +14,9 @@
#include "includes.h"
+#ifdef __FreeBSD__
+#include <assert.h>
+#endif
#include <errno.h>
#include <pwd.h>
#include <string.h>
@@ -121,8 +124,20 @@ temporarily_use_uid(struct passwd *pw)
fatal("setgroups: %.100s", strerror(errno));
#ifndef SAVED_IDS_WORK_WITH_SETEUID
/* Propagate the privileged gid to all of our gids. */
+#ifdef __FreeBSD__
+ /*
+ * FreeBSD traditionally includes the egid as the first element. If we
+ * use getegid() here then we effectively propagate user_groups[0],
+ * which is probably pw->pw_gid. Fix it to work as intended by using
+ * the egid we already have stashed off.
+ */
+ assert(saved_egroupslen > 0);
+ if (setgid(saved_egroups[0]) == -1)
+ debug("setgid %u: %.100s", (u_int) saved_egroups[0], strerror(errno));
+#else
if (setgid(getegid()) == -1)
debug("setgid %u: %.100s", (u_int) getegid(), strerror(errno));
+#endif
/* Propagate the privileged uid to all of our uids. */
if (setuid(geteuid()) == -1)
debug("setuid %u: %.100s", (u_int) geteuid(), strerror(errno));