- register struct a {
- u_int gidsetsize;
- int *gidset;
- } *uap = (struct a *)u.u_ap;
- register int *gp;
-
- if (!suser())
- return;
- if (uap->gidsetsize > sizeof (u.u_groups) / sizeof (u.u_groups[0])) {
- u.u_error = EINVAL;
- return;
- }
- if (copyin((caddr_t)uap->gidset, (caddr_t)u.u_groups,
- uap->gidsetsize * sizeof (u.u_groups[0]))) {
- u.u_error = EFAULT;
- return;
- }
- for (gp = &u.u_groups[uap->gidsetsize]; gp < &u.u_groups[NGROUPS]; gp++)
- *gp = -1;
+ register struct pcred *pc = p->p_cred;
+ struct seteuid_args args;
+
+ /*
+ * we assume that the intent of setting ruid is to be able to get
+ * back ruid priviledge. So we make sure that we will be able to
+ * do so, but do not actually set the ruid.
+ */
+ if (uap->ruid != (uid_t)-1 && uap->ruid != pc->p_ruid &&
+ uap->ruid != pc->p_svuid)
+ return (EPERM);
+ if (uap->euid == (uid_t)-1)
+ return (0);
+ args.euid = uap->euid;
+ return (seteuid(p, &args, retval));
+}
+
+struct setregid_args {
+ int rgid;
+ int egid;
+};
+/* ARGSUSED */
+osetregid(p, uap, retval)
+ register struct proc *p;
+ struct setregid_args *uap;
+ int *retval;
+{
+ register struct pcred *pc = p->p_cred;
+ struct setegid_args args;
+
+ /*
+ * we assume that the intent of setting rgid is to be able to get
+ * back rgid priviledge. So we make sure that we will be able to
+ * do so, but do not actually set the rgid.
+ */
+ if (uap->rgid != (gid_t)-1 && uap->rgid != pc->p_rgid &&
+ uap->rgid != pc->p_svgid)
+ return (EPERM);
+ if (uap->egid == (gid_t)-1)
+ return (0);
+ args.egid = uap->egid;
+ return (setegid(p, &args, retval));