+ /*
+ * Otherwise we assume that the intent of setting ruid is to be
+ * able to get back ruid priviledge (i.e. swapping ruid and euid).
+ * So we make sure that we will be able to do so, but do not
+ * actually set the ruid.
+ */
+ if (SCARG(uap, ruid) != (uid_t)-1 && SCARG(uap, ruid) != pc->p_ruid &&
+ SCARG(uap, ruid) != pc->p_svuid)
+ return (EPERM);
+ if (SCARG(uap, euid) == (uid_t)-1)
+ return (0);
+ SCARG(&args.ea, euid) = SCARG(uap, euid);
+ return (seteuid(p, &args.ea, retval));
+}
+
+/* ARGSUSED */
+int
+compat_43_setregid(p, uap, retval)
+ register struct proc *p;
+ struct compat_43_setregid_args /* {
+ syscallarg(int) rgid;
+ syscallarg(int) egid;
+ } */ *uap;
+ register_t *retval;
+{
+ register struct pcred *pc = p->p_cred;
+ union {
+ struct setgid_args sa;
+ struct setegid_args ea;
+ } args;
+
+ /*
+ * If rgid == egid then setreuid is being used to emulate setgid,
+ * just do it.
+ */
+ if (SCARG(uap, rgid) != -1 && SCARG(uap, rgid) == SCARG(uap, egid)) {
+ SCARG(&args.sa, gid) = SCARG(uap, rgid);
+ return (setgid(p, &args.sa, retval));
+ }
+ /*
+ * Otherwise we assume that the intent of setting rgid is to be
+ * able to get back rgid priviledge (i.e. swapping rgid and egid).
+ * So we make sure that we will be able to do so, but do not
+ * actually set the rgid.
+ */
+ if (SCARG(uap, rgid) != (gid_t)-1 && SCARG(uap, rgid) != pc->p_rgid &&
+ SCARG(uap, rgid) != pc->p_svgid)
+ return (EPERM);
+ if (SCARG(uap, egid) == (gid_t)-1)
+ return (0);
+ SCARG(&args.ea, egid) = SCARG(uap, egid);
+ return (setegid(p, &args.ea, retval));