Annotation of Net2/kern/kern_prot.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Copyright (c) 1982, 1986, 1989, 1990, 1991 Regents of the University
                      3:  * of California.  All rights reserved.
                      4:  *
                      5:  * Redistribution and use in source and binary forms, with or without
                      6:  * modification, are permitted provided that the following conditions
                      7:  * are met:
                      8:  * 1. Redistributions of source code must retain the above copyright
                      9:  *    notice, this list of conditions and the following disclaimer.
                     10:  * 2. Redistributions in binary form must reproduce the above copyright
                     11:  *    notice, this list of conditions and the following disclaimer in the
                     12:  *    documentation and/or other materials provided with the distribution.
                     13:  * 3. All advertising materials mentioning features or use of this software
                     14:  *    must display the following acknowledgement:
                     15:  *     This product includes software developed by the University of
                     16:  *     California, Berkeley and its contributors.
                     17:  * 4. Neither the name of the University nor the names of its contributors
                     18:  *    may be used to endorse or promote products derived from this software
                     19:  *    without specific prior written permission.
                     20:  *
                     21:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
                     22:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
                     23:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
                     24:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
                     25:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
                     26:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
                     27:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     28:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
                     29:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
                     30:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
                     31:  * SUCH DAMAGE.
                     32:  *
                     33:  *     @(#)kern_prot.c 7.21 (Berkeley) 5/3/91
                     34:  */
                     35: 
                     36: /*
                     37:  * System calls related to processes and protection
                     38:  */
                     39: 
                     40: #include "param.h"
                     41: #include "acct.h"
                     42: #include "systm.h"
                     43: #include "ucred.h"
                     44: #include "proc.h"
                     45: #include "timeb.h"
                     46: #include "times.h"
                     47: #include "malloc.h"
                     48: 
                     49: /* ARGSUSED */
                     50: getpid(p, uap, retval)
                     51:        struct proc *p;
                     52:        void *uap;
                     53:        int *retval;
                     54: {
                     55: 
                     56:        *retval = p->p_pid;
                     57: #ifdef COMPAT_43
                     58:        retval[1] = p->p_pptr->p_pid;
                     59: #endif
                     60:        return (0);
                     61: }
                     62: 
                     63: /* ARGSUSED */
                     64: getppid(p, uap, retval)
                     65:        struct proc *p;
                     66:        void *uap;
                     67:        int *retval;
                     68: {
                     69: 
                     70:        *retval = p->p_pptr->p_pid;
                     71:        return (0);
                     72: }
                     73: 
                     74: /* Get process group ID; note that POSIX getpgrp takes no parameter */
                     75: getpgrp(p, uap, retval)
                     76:        struct proc *p;
                     77:        void *uap;
                     78:        int *retval;
                     79: {
                     80: 
                     81:        *retval = p->p_pgrp->pg_id;
                     82:        return (0);
                     83: }
                     84: 
                     85: /* ARGSUSED */
                     86: getuid(p, uap, retval)
                     87:        struct proc *p;
                     88:        void *uap;
                     89:        int *retval;
                     90: {
                     91: 
                     92:        *retval = p->p_cred->p_ruid;
                     93: #ifdef COMPAT_43
                     94:        retval[1] = p->p_ucred->cr_uid;
                     95: #endif
                     96:        return (0);
                     97: }
                     98: 
                     99: /* ARGSUSED */
                    100: geteuid(p, uap, retval)
                    101:        struct proc *p;
                    102:        void *uap;
                    103:        int *retval;
                    104: {
                    105: 
                    106:        *retval = p->p_ucred->cr_uid;
                    107:        return (0);
                    108: }
                    109: 
                    110: /* ARGSUSED */
                    111: getgid(p, uap, retval)
                    112:        struct proc *p;
                    113:        void *uap;
                    114:        int *retval;
                    115: {
                    116: 
                    117:        *retval = p->p_cred->p_rgid;
                    118: #ifdef COMPAT_43
                    119:        retval[1] = p->p_ucred->cr_groups[0];
                    120: #endif
                    121:        return (0);
                    122: }
                    123: 
                    124: /*
                    125:  * Get effective group ID.  The "egid" is groups[0], and could be obtained
                    126:  * via getgroups.  This syscall exists because it is somewhat painful to do
                    127:  * correctly in a library function.
                    128:  */
                    129: /* ARGSUSED */
                    130: getegid(p, uap, retval)
                    131:        struct proc *p;
                    132:        void *uap;
                    133:        int *retval;
                    134: {
                    135: 
                    136:        *retval = p->p_ucred->cr_groups[0];
                    137:        return (0);
                    138: }
                    139: 
                    140: getgroups(p, uap, retval)
                    141:        struct proc *p;
                    142:        register struct arg {
                    143:                u_int   gidsetsize;
                    144:                int     *gidset;                /* XXX not yet POSIX */
                    145:        } *uap;
                    146:        int *retval;
                    147: {
                    148:        register struct pcred *pc = p->p_cred;
                    149:        register gid_t *gp;
                    150:        register int *lp;
                    151:        register u_int ngrp;
                    152:        int groups[NGROUPS];
                    153:        int error;
                    154: 
                    155:        if ((ngrp = uap->gidsetsize) == 0) {
                    156:                *retval = pc->pc_ucred->cr_ngroups;
                    157:                return (0);
                    158:        }
                    159:        if (ngrp < pc->pc_ucred->cr_ngroups)
                    160:                return (EINVAL);
                    161:        ngrp = pc->pc_ucred->cr_ngroups;
                    162:        for (gp = pc->pc_ucred->cr_groups, lp = groups; lp < &groups[ngrp]; )
                    163:                *lp++ = *gp++;
                    164:        if (error = copyout((caddr_t)groups, (caddr_t)uap->gidset,
                    165:            ngrp * sizeof (groups[0])))
                    166:                return (error);
                    167:        *retval = ngrp;
                    168:        return (0);
                    169: }
                    170: 
                    171: /* ARGSUSED */
                    172: setsid(p, uap, retval)
                    173:        register struct proc *p;
                    174:        void *uap;
                    175:        int *retval;
                    176: {
                    177: 
                    178:        if (p->p_pgid == p->p_pid || pgfind(p->p_pid)) {
                    179:                return (EPERM);
                    180:        } else {
                    181:                enterpgrp(p, p->p_pid, 1);
                    182:                *retval = p->p_pid;
                    183:                return (0);
                    184:        }
                    185: }
                    186: 
                    187: /*
                    188:  * set process group (setpgid/old setpgrp)
                    189:  *
                    190:  * caller does setpgid(targpid, targpgid)
                    191:  *
                    192:  * pid must be caller or child of caller (ESRCH)
                    193:  * if a child
                    194:  *     pid must be in same session (EPERM)
                    195:  *     pid can't have done an exec (EACCES)
                    196:  * if pgid != pid
                    197:  *     there must exist some pid in same session having pgid (EPERM)
                    198:  * pid must not be session leader (EPERM)
                    199:  */
                    200: /* ARGSUSED */
                    201: setpgid(curp, uap, retval)
                    202:        struct proc *curp;
                    203:        register struct args {
                    204:                int     pid;    /* target process id */
                    205:                int     pgid;   /* target pgrp id */
                    206:        } *uap;
                    207:        int *retval;
                    208: {
                    209:        register struct proc *targp;            /* target process */
                    210:        register struct pgrp *pgrp;             /* target pgrp */
                    211: 
                    212:        if (uap->pid != 0 && uap->pid != curp->p_pid) {
                    213:                if ((targp = pfind(uap->pid)) == 0 || !inferior(targp))
                    214:                        return (ESRCH);
                    215:                if (targp->p_session != curp->p_session)
                    216:                        return (EPERM);
                    217:                if (targp->p_flag&SEXEC)
                    218:                        return (EACCES);
                    219:        } else
                    220:                targp = curp;
                    221:        if (SESS_LEADER(targp))
                    222:                return (EPERM);
                    223:        if (uap->pgid == 0)
                    224:                uap->pgid = targp->p_pid;
                    225:        else if (uap->pgid != targp->p_pid)
                    226:                if ((pgrp = pgfind(uap->pgid)) == 0 ||
                    227:                    pgrp->pg_session != curp->p_session)
                    228:                        return (EPERM);
                    229:        enterpgrp(targp, uap->pgid, 0);
                    230:        return (0);
                    231: }
                    232: 
                    233: /* ARGSUSED */
                    234: setuid(p, uap, retval)
                    235:        struct proc *p;
                    236:        struct args {
                    237:                int     uid;
                    238:        } *uap;
                    239:        int *retval;
                    240: {
                    241:        register struct pcred *pc = p->p_cred;
                    242:        register uid_t uid;
                    243:        int error;
                    244: 
                    245:        uid = uap->uid;
                    246:        if (uid != pc->p_ruid &&
                    247:            (error = suser(pc->pc_ucred, &p->p_acflag)))
                    248:                return (error);
                    249:        /*
                    250:         * Everything's okay, do it.  Copy credentials so other references do
                    251:         * not see our changes.
                    252:         */
                    253:        pc->pc_ucred = crcopy(pc->pc_ucred);
                    254:        pc->pc_ucred->cr_uid = uid;
                    255:        pc->p_ruid = uid;
                    256:        pc->p_svuid = uid;
                    257:        return (0);
                    258: }
                    259: 
                    260: /* ARGSUSED */
                    261: seteuid(p, uap, retval)
                    262:        struct proc *p;
                    263:        struct args {
                    264:                int     euid;
                    265:        } *uap;
                    266:        int *retval;
                    267: {
                    268:        register struct pcred *pc = p->p_cred;
                    269:        register uid_t euid;
                    270:        int error;
                    271: 
                    272:        euid = uap->euid;
                    273:        if (euid != pc->p_ruid && euid != pc->p_svuid &&
                    274:            (error = suser(pc->pc_ucred, &p->p_acflag)))
                    275:                return (error);
                    276:        /*
                    277:         * Everything's okay, do it.  Copy credentials so other references do
                    278:         * not see our changes.
                    279:         */
                    280:        pc->pc_ucred = crcopy(pc->pc_ucred);
                    281:        pc->pc_ucred->cr_uid = euid;
                    282:        return (0);
                    283: }
                    284: 
                    285: /* ARGSUSED */
                    286: setgid(p, uap, retval)
                    287:        struct proc *p;
                    288:        struct args {
                    289:                int     gid;
                    290:        } *uap;
                    291:        int *retval;
                    292: {
                    293:        register struct pcred *pc = p->p_cred;
                    294:        register gid_t gid;
                    295:        int error;
                    296: 
                    297:        gid = uap->gid;
                    298:        if (gid != pc->p_rgid && (error = suser(pc->pc_ucred, &p->p_acflag)))
                    299:                return (error);
                    300:        pc->pc_ucred = crcopy(pc->pc_ucred);
                    301:        pc->pc_ucred->cr_groups[0] = gid;
                    302:        pc->p_rgid = gid;
                    303:        pc->p_svgid = gid;              /* ??? */
                    304:        return (0);
                    305: }
                    306: 
                    307: /* ARGSUSED */
                    308: setegid(p, uap, retval)
                    309:        struct proc *p;
                    310:        struct args {
                    311:                int     egid;
                    312:        } *uap;
                    313:        int *retval;
                    314: {
                    315:        register struct pcred *pc = p->p_cred;
                    316:        register gid_t egid;
                    317:        int error;
                    318: 
                    319:        egid = uap->egid;
                    320:        if (egid != pc->p_rgid && egid != pc->p_svgid &&
                    321:            (error = suser(pc->pc_ucred, &p->p_acflag)))
                    322:                return (error);
                    323:        pc->pc_ucred = crcopy(pc->pc_ucred);
                    324:        pc->pc_ucred->cr_groups[0] = egid;
                    325:        return (0);
                    326: }
                    327: 
                    328: #ifdef COMPAT_43
                    329: /* ARGSUSED */
                    330: osetreuid(p, uap, retval)
                    331:        register struct proc *p;
                    332:        struct args {
                    333:                int     ruid;
                    334:                int     euid;
                    335:        } *uap;
                    336:        int *retval;
                    337: {
                    338:        register struct pcred *pc = p->p_cred;
                    339:        register uid_t ruid, euid;
                    340:        int error;
                    341: 
                    342:        if (uap->ruid == -1)
                    343:                ruid = pc->p_ruid;
                    344:        else
                    345:                ruid = uap->ruid;
                    346:        /*
                    347:         * Allow setting real uid to previous effective, for swapping real and
                    348:         * effective.  This should be:
                    349:         *
                    350:         * if (ruid != pc->p_ruid &&
                    351:         *     (error = suser(pc->pc_ucred, &p->p_acflag)))
                    352:         */
                    353:        if (ruid != pc->p_ruid && ruid != pc->pc_ucred->cr_uid /* XXX */ &&
                    354:            (error = suser(pc->pc_ucred, &p->p_acflag)))
                    355:                return (error);
                    356:        if (uap->euid == -1)
                    357:                euid = pc->pc_ucred->cr_uid;
                    358:        else
                    359:                euid = uap->euid;
                    360:        if (euid != pc->pc_ucred->cr_uid && euid != pc->p_ruid &&
                    361:            euid != pc->p_svuid && (error = suser(pc->pc_ucred, &p->p_acflag)))
                    362:                return (error);
                    363:        /*
                    364:         * Everything's okay, do it.  Copy credentials so other references do
                    365:         * not see our changes.
                    366:         */
                    367:        pc->pc_ucred = crcopy(pc->pc_ucred);
                    368:        pc->pc_ucred->cr_uid = euid;
                    369:        pc->p_ruid = ruid;
                    370:        return (0);
                    371: }
                    372: 
                    373: /* ARGSUSED */
                    374: osetregid(p, uap, retval)
                    375:        register struct proc *p;
                    376:        struct args {
                    377:                int     rgid;
                    378:                int     egid;
                    379:        } *uap;
                    380:        int *retval;
                    381: {
                    382:        register struct pcred *pc = p->p_cred;
                    383:        register gid_t rgid, egid;
                    384:        int error;
                    385: 
                    386:        if (uap->rgid == -1)
                    387:                rgid = pc->p_rgid;
                    388:        else
                    389:                rgid = uap->rgid;
                    390:        /*
                    391:         * Allow setting real gid to previous effective, for swapping real and
                    392:         * effective.  This didn't really work correctly in 4.[23], but is
                    393:         * preserved so old stuff doesn't fail.  This should be:
                    394:         *
                    395:         * if (rgid != pc->p_rgid &&
                    396:         *     (error = suser(pc->pc_ucred, &p->p_acflag)))
                    397:         */
                    398:        if (rgid != pc->p_rgid && rgid != pc->pc_ucred->cr_groups[0] /* XXX */ &&
                    399:            (error = suser(pc->pc_ucred, &p->p_acflag)))
                    400:                return (error);
                    401:        if (uap->egid == -1)
                    402:                egid = pc->pc_ucred->cr_groups[0];
                    403:        else
                    404:                egid = uap->egid;
                    405:        if (egid != pc->pc_ucred->cr_groups[0] && egid != pc->p_rgid &&
                    406:            egid != pc->p_svgid && (error = suser(pc->pc_ucred, &p->p_acflag)))
                    407:                return (error);
                    408:        pc->pc_ucred = crcopy(pc->pc_ucred);
                    409:        pc->pc_ucred->cr_groups[0] = egid;
                    410:        pc->p_rgid = rgid;
                    411:        return (0);
                    412: }
                    413: #endif
                    414: 
                    415: /* ARGSUSED */
                    416: setgroups(p, uap, retval)
                    417:        struct proc *p;
                    418:        struct args {
                    419:                u_int   gidsetsize;
                    420:                int     *gidset;
                    421:        } *uap;
                    422:        int *retval;
                    423: {
                    424:        register struct pcred *pc = p->p_cred;
                    425:        register gid_t *gp;
                    426:        register u_int ngrp;
                    427:        register int *lp;
                    428:        int error, groups[NGROUPS];
                    429: 
                    430:        if (error = suser(pc->pc_ucred, &p->p_acflag))
                    431:                return (error);
                    432:        if ((ngrp = uap->gidsetsize) > NGROUPS)
                    433:                return (EINVAL);
                    434:        if (error = copyin((caddr_t)uap->gidset, (caddr_t)groups,
                    435:            ngrp * sizeof (groups[0])))
                    436:                return (error);
                    437:        pc->pc_ucred = crcopy(pc->pc_ucred);
                    438:        pc->pc_ucred->cr_ngroups = ngrp;
                    439:        /* convert from int's to gid_t's */
                    440:        for (gp = pc->pc_ucred->cr_groups, lp = groups; ngrp--; )
                    441:                *gp++ = *lp++;
                    442:        return (0);
                    443: }
                    444: 
                    445: /*
                    446:  * Check if gid is a member of the group set.
                    447:  */
                    448: groupmember(gid, cred)
                    449:        gid_t gid;
                    450:        register struct ucred *cred;
                    451: {
                    452:        register gid_t *gp;
                    453:        gid_t *egp;
                    454: 
                    455:        egp = &(cred->cr_groups[cred->cr_ngroups]);
                    456:        for (gp = cred->cr_groups; gp < egp; gp++)
                    457:                if (*gp == gid)
                    458:                        return (1);
                    459:        return (0);
                    460: }
                    461: 
                    462: /*
                    463:  * Test whether the specified credentials imply "super-user"
                    464:  * privilege; if so, and we have accounting info, set the flag
                    465:  * indicating use of super-powers.
                    466:  * Returns 0 or error.
                    467:  */
                    468: suser(cred, acflag)
                    469:        struct ucred *cred;
                    470:        short *acflag;
                    471: {
                    472:        if (cred->cr_uid == 0) {
                    473:                if (acflag)
                    474:                        *acflag |= ASU;
                    475:                return (0);
                    476:        }
                    477:        return (EPERM);
                    478: }
                    479: 
                    480: /*
                    481:  * Allocate a zeroed cred structure.
                    482:  */
                    483: struct ucred *
                    484: crget()
                    485: {
                    486:        register struct ucred *cr;
                    487: 
                    488:        MALLOC(cr, struct ucred *, sizeof(*cr), M_CRED, M_WAITOK);
                    489:        bzero((caddr_t)cr, sizeof(*cr));
                    490:        cr->cr_ref = 1;
                    491:        return (cr);
                    492: }
                    493: 
                    494: /*
                    495:  * Free a cred structure.
                    496:  * Throws away space when ref count gets to 0.
                    497:  */
                    498: crfree(cr)
                    499:        struct ucred *cr;
                    500: {
                    501:        int s = splimp();                       /* ??? */
                    502: 
                    503:        if (--cr->cr_ref != 0) {
                    504:                (void) splx(s);
                    505:                return;
                    506:        }
                    507:        FREE((caddr_t)cr, M_CRED);
                    508:        (void) splx(s);
                    509: }
                    510: 
                    511: /*
                    512:  * Copy cred structure to a new one and free the old one.
                    513:  */
                    514: struct ucred *
                    515: crcopy(cr)
                    516:        struct ucred *cr;
                    517: {
                    518:        struct ucred *newcr;
                    519: 
                    520:        if (cr->cr_ref == 1)
                    521:                return (cr);
                    522:        newcr = crget();
                    523:        *newcr = *cr;
                    524:        crfree(cr);
                    525:        newcr->cr_ref = 1;
                    526:        return (newcr);
                    527: }
                    528: 
                    529: /*
                    530:  * Dup cred struct to a new held one.
                    531:  */
                    532: struct ucred *
                    533: crdup(cr)
                    534:        struct ucred *cr;
                    535: {
                    536:        struct ucred *newcr;
                    537: 
                    538:        newcr = crget();
                    539:        *newcr = *cr;
                    540:        newcr->cr_ref = 1;
                    541:        return (newcr);
                    542: }
                    543: 
                    544: /*
                    545:  * Get login name, if available.
                    546:  */
                    547: /* ARGSUSED */
                    548: getlogin(p, uap, retval)
                    549:        struct proc *p;
                    550:        struct args {
                    551:                char    *namebuf;
                    552:                u_int   namelen;
                    553:        } *uap;
                    554:        int *retval;
                    555: {
                    556: 
                    557:        if (uap->namelen > sizeof (p->p_pgrp->pg_session->s_login))
                    558:                uap->namelen = sizeof (p->p_pgrp->pg_session->s_login);
                    559:        return (copyout((caddr_t) p->p_pgrp->pg_session->s_login,
                    560:            (caddr_t) uap->namebuf, uap->namelen));
                    561: }
                    562: 
                    563: /*
                    564:  * Set login name.
                    565:  */
                    566: /* ARGSUSED */
                    567: setlogin(p, uap, retval)
                    568:        struct proc *p;
                    569:        struct args {
                    570:                char    *namebuf;
                    571:        } *uap;
                    572:        int *retval;
                    573: {
                    574:        int error;
                    575: 
                    576:        if (error = suser(p->p_ucred, &p->p_acflag))
                    577:                return (error);
                    578:        error = copyinstr((caddr_t) uap->namebuf,
                    579:            (caddr_t) p->p_pgrp->pg_session->s_login,
                    580:            sizeof (p->p_pgrp->pg_session->s_login) - 1, (u_int *)0);
                    581:        if (error == ENAMETOOLONG)
                    582:                error = EINVAL;
                    583:        return (error);
                    584: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.