X-Git-Url: https://git.subgeniuskitty.com/unix-history/.git/blobdiff_plain/544bbb173f984ee034b67ae2d22c4fe884301dc9..82b95dadf0c41114ff61f957305f0a6a7201f335:/sys/kern/kern_prot.c diff --git a/sys/kern/kern_prot.c b/sys/kern/kern_prot.c index d886dbba27..e2ba54a9cb 100644 --- a/sys/kern/kern_prot.c +++ b/sys/kern/kern_prot.c @@ -31,7 +31,7 @@ * SUCH DAMAGE. * * from: @(#)kern_prot.c 7.21 (Berkeley) 5/3/91 - * $Id: kern_prot.c,v 1.4 1993/11/25 01:33:04 wollman Exp $ + * $Id: kern_prot.c,v 1.5 1993/12/19 00:51:29 wollman Exp $ */ /* @@ -273,6 +273,7 @@ setuid(p, uap, retval) pc->pc_ucred->cr_uid = uid; pc->p_ruid = uid; pc->p_svuid = uid; + p->p_flag |= SUGID; return (0); } @@ -301,6 +302,7 @@ seteuid(p, uap, retval) */ pc->pc_ucred = crcopy(pc->pc_ucred); pc->pc_ucred->cr_uid = euid; + p->p_flag |= SUGID; return (0); } @@ -325,7 +327,8 @@ setgid(p, uap, retval) pc->pc_ucred = crcopy(pc->pc_ucred); pc->pc_ucred->cr_groups[0] = gid; pc->p_rgid = gid; - pc->p_svgid = gid; /* ??? */ + pc->p_svgid = gid; + p->p_flag |= SUGID; return (0); } @@ -350,6 +353,7 @@ setegid(p, uap, retval) return (error); pc->pc_ucred = crcopy(pc->pc_ucred); pc->pc_ucred->cr_groups[0] = egid; + p->p_flag |= SUGID; return (0); } @@ -368,38 +372,30 @@ osetreuid(p, uap, retval) int *retval; { register struct pcred *pc = p->p_cred; - register uid_t ruid, euid; - int error; + struct seteuid_args e_args; - if (uap->ruid == -1) - ruid = pc->p_ruid; - else - ruid = uap->ruid; - /* - * Allow setting real uid to previous effective, for swapping real and - * effective. This should be: - * - * if (ruid != pc->p_ruid && - * (error = suser(pc->pc_ucred, &p->p_acflag))) - */ - if (ruid != pc->p_ruid && ruid != pc->pc_ucred->cr_uid /* XXX */ && - (error = suser(pc->pc_ucred, &p->p_acflag))) - return (error); - if (uap->euid == -1) - euid = pc->pc_ucred->cr_uid; - else - euid = uap->euid; - if (euid != pc->pc_ucred->cr_uid && euid != pc->p_ruid && - euid != pc->p_svuid && (error = suser(pc->pc_ucred, &p->p_acflag))) - return (error); /* - * Everything's okay, do it. Copy credentials so other references do - * not see our changes. + * Most calls to setreuid() are done in order to swap real and + * effective uids. In old versions of BSD, this was the only + * way to temporarily renounce privileges and be able to get + * them back. In the presence of the POSIX saved id, however, + * we can do this without modifying the real uid, which could have + * opened up a security hole. So, we implement this: when the user + * attempts to set its real uid, we just check to make sure + * that they will be able to seteuid() back to that id at some + * later time, but don't actually change the real uid. + * Logic taken from 4.4BSD. */ - pc->pc_ucred = crcopy(pc->pc_ucred); - pc->pc_ucred->cr_uid = euid; - pc->p_ruid = ruid; - return (0); + if(uap->ruid != -1 && uap->ruid != pc->p_ruid + && uap->ruid != pc->p_svuid) { + return EPERM; + } + + if(uap->euid == -1) { + return 0; + } + e_args.euid = uap->euid; + return seteuid(p, &e_args, retval); } struct osetregid_args { @@ -415,35 +411,22 @@ osetregid(p, uap, retval) int *retval; { register struct pcred *pc = p->p_cred; - register gid_t rgid, egid; - int error; + struct setegid_args e_args; - if (uap->rgid == -1) - rgid = pc->p_rgid; - else - rgid = uap->rgid; /* - * Allow setting real gid to previous effective, for swapping real and - * effective. This didn't really work correctly in 4.[23], but is - * preserved so old stuff doesn't fail. This should be: - * - * if (rgid != pc->p_rgid && - * (error = suser(pc->pc_ucred, &p->p_acflag))) + * Same comments as for setreuid() apply here. */ - if (rgid != pc->p_rgid && rgid != pc->pc_ucred->cr_groups[0] /* XXX */ && - (error = suser(pc->pc_ucred, &p->p_acflag))) - return (error); - if (uap->egid == -1) - egid = pc->pc_ucred->cr_groups[0]; - else - egid = uap->egid; - if (egid != pc->pc_ucred->cr_groups[0] && egid != pc->p_rgid && - egid != pc->p_svgid && (error = suser(pc->pc_ucred, &p->p_acflag))) - return (error); - pc->pc_ucred = crcopy(pc->pc_ucred); - pc->pc_ucred->cr_groups[0] = egid; - pc->p_rgid = rgid; - return (0); + if(uap->rgid != -1 + && uap->rgid != pc->p_rgid + && uap->rgid != pc->p_svgid) { + return EPERM; + } + + if(uap->egid == -1) { + return 0; + } + e_args.egid = uap->egid; + return setegid(p, &e_args, retval); } #endif