Annotation of 43BSDReno/sys/kern/kern_prot.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

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