Annotation of kernel/bsd/kern/kern_prot.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
                      3:  *
                      4:  * @APPLE_LICENSE_HEADER_START@
                      5:  * 
                      6:  * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
                      7:  * Reserved.  This file contains Original Code and/or Modifications of
                      8:  * Original Code as defined in and that are subject to the Apple Public
                      9:  * Source License Version 1.1 (the "License").  You may not use this file
                     10:  * except in compliance with the License.  Please obtain a copy of the
                     11:  * License at http://www.apple.com/publicsource and read it before using
                     12:  * this file.
                     13:  * 
                     14:  * The Original Code and all software distributed under the License are
                     15:  * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
                     16:  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
                     17:  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
                     18:  * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
                     19:  * License for the specific language governing rights and limitations
                     20:  * under the License.
                     21:  * 
                     22:  * @APPLE_LICENSE_HEADER_END@
                     23:  */
                     24: 
                     25: /* Copyright (c) 1995 NeXT Computer, Inc. All Rights Reserved */
                     26: /*
                     27:  * Copyright (c) 1982, 1986, 1989, 1990, 1991, 1993
                     28:  *     The Regents of the University of California.  All rights reserved.
                     29:  * (c) UNIX System Laboratories, Inc.
                     30:  * All or some portions of this file are derived from material licensed
                     31:  * to the University of California by American Telephone and Telegraph
                     32:  * Co. or Unix System Laboratories, Inc. and are reproduced herein with
                     33:  * the permission of UNIX System Laboratories, Inc.
                     34:  *
                     35:  * Redistribution and use in source and binary forms, with or without
                     36:  * modification, are permitted provided that the following conditions
                     37:  * are met:
                     38:  * 1. Redistributions of source code must retain the above copyright
                     39:  *    notice, this list of conditions and the following disclaimer.
                     40:  * 2. Redistributions in binary form must reproduce the above copyright
                     41:  *    notice, this list of conditions and the following disclaimer in the
                     42:  *    documentation and/or other materials provided with the distribution.
                     43:  * 3. All advertising materials mentioning features or use of this software
                     44:  *    must display the following acknowledgement:
                     45:  *     This product includes software developed by the University of
                     46:  *     California, Berkeley and its contributors.
                     47:  * 4. Neither the name of the University nor the names of its contributors
                     48:  *    may be used to endorse or promote products derived from this software
                     49:  *    without specific prior written permission.
                     50:  *
                     51:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
                     52:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
                     53:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
                     54:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
                     55:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
                     56:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
                     57:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     58:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
                     59:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
                     60:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
                     61:  * SUCH DAMAGE.
                     62:  *
                     63:  *     @(#)kern_prot.c 8.9 (Berkeley) 2/14/95
                     64:  */
                     65: 
                     66: /*
                     67:  * System calls related to processes and protection
                     68:  */
                     69: 
                     70: #include <sys/param.h>
                     71: #include <sys/acct.h>
                     72: #include <sys/systm.h>
                     73: #include <sys/ucred.h>
                     74: #include <sys/proc.h>
                     75: #include <sys/timeb.h>
                     76: #include <sys/times.h>
                     77: #include <sys/malloc.h>
                     78: 
                     79: #include <sys/mount.h>
                     80: 
                     81: /*
                     82:  * setprivexec:  (dis)allow this process to hold
                     83:  * task, thread, or execption ports of processes about to exec.
                     84:  */
                     85: struct setprivexec_args {
                     86:        int flag;
                     87: }; 
                     88: int
                     89: setprivexec(p, uap, retval)
                     90:        struct proc *p;
                     91:        register struct setprivexec_args *uap;
                     92:        register_t *retval;
                     93: {
                     94:        *retval = p->p_debugger;
                     95:        p->p_debugger = (uap->flag != 0);
                     96:        return(0);
                     97: }
                     98: 
                     99: /* ARGSUSED */
                    100: getpid(p, uap, retval)
                    101:        struct proc *p;
                    102:        void *uap;
                    103:        register_t *retval;
                    104: {
                    105: 
                    106:        *retval = p->p_pid;
                    107: #if COMPAT_43
                    108:        retval[1] = p->p_pptr->p_pid;
                    109: #endif
                    110:        return (0);
                    111: }
                    112: 
                    113: /* ARGSUSED */
                    114: getppid(p, uap, retval)
                    115:        struct proc *p;
                    116:        void *uap;
                    117:        register_t *retval;
                    118: {
                    119: 
                    120:        *retval = p->p_pptr->p_pid;
                    121:        return (0);
                    122: }
                    123: 
                    124: /* Get process group ID; note that POSIX getpgrp takes no parameter */
                    125: getpgrp(p, uap, retval)
                    126:        struct proc *p;
                    127:        void *uap;
                    128:        register_t *retval;
                    129: {
                    130: 
                    131:        *retval = p->p_pgrp->pg_id;
                    132:        return (0);
                    133: }
                    134: 
                    135: /* ARGSUSED */
                    136: getuid(p, uap, retval)
                    137:        struct proc *p;
                    138:        void *uap;
                    139:        register_t *retval;
                    140: {
                    141: 
                    142:        *retval = p->p_cred->p_ruid;
                    143: #if COMPAT_43
                    144:        retval[1] = p->p_ucred->cr_uid;
                    145: #endif
                    146:        return (0);
                    147: }
                    148: 
                    149: /* ARGSUSED */
                    150: geteuid(p, uap, retval)
                    151:        struct proc *p;
                    152:        void *uap;
                    153:        register_t *retval;
                    154: {
                    155: 
                    156:        *retval = p->p_ucred->cr_uid;
                    157:        return (0);
                    158: }
                    159: 
                    160: /* ARGSUSED */
                    161: getgid(p, uap, retval)
                    162:        struct proc *p;
                    163:        void *uap;
                    164:        register_t *retval;
                    165: {
                    166: 
                    167:        *retval = p->p_cred->p_rgid;
                    168: #if COMPAT_43
                    169:        retval[1] = p->p_ucred->cr_groups[0];
                    170: #endif
                    171:        return (0);
                    172: }
                    173: 
                    174: /*
                    175:  * Get effective group ID.  The "egid" is groups[0], and could be obtained
                    176:  * via getgroups.  This syscall exists because it is somewhat painful to do
                    177:  * correctly in a library function.
                    178:  */
                    179: /* ARGSUSED */
                    180: getegid(p, uap, retval)
                    181:        struct proc *p;
                    182:        void *uap;
                    183:        register_t *retval;
                    184: {
                    185: 
                    186:        *retval = p->p_ucred->cr_groups[0];
                    187:        return (0);
                    188: }
                    189: 
                    190: struct getgroups_args {
                    191:        u_int   gidsetsize;
                    192:        gid_t   *gidset;
                    193: };
                    194: getgroups(p, uap, retval)
                    195:        struct proc *p;
                    196:        register struct getgroups_args *uap;
                    197:        register_t *retval;
                    198: {
                    199:        register struct pcred *pc = p->p_cred;
                    200:        register u_int ngrp;
                    201:        int error;
                    202: 
                    203:        if ((ngrp = uap->gidsetsize) == 0) {
                    204:                *retval = pc->pc_ucred->cr_ngroups;
                    205:                return (0);
                    206:        }
                    207:        if (ngrp < pc->pc_ucred->cr_ngroups)
                    208:                return (EINVAL);
                    209:        pcred_readlock(p);
                    210:        ngrp = pc->pc_ucred->cr_ngroups;
                    211:        if (error = copyout((caddr_t)pc->pc_ucred->cr_groups,
                    212:            (caddr_t)uap->gidset, ngrp * sizeof(gid_t))) {
                    213:                pcred_unlock(p);
                    214:                return (error);
                    215:        }
                    216:        pcred_unlock(p);
                    217:        *retval = ngrp;
                    218:        return (0);
                    219: }
                    220: 
                    221: /* ARGSUSED */
                    222: setsid(p, uap, retval)
                    223:        register struct proc *p;
                    224:        void *uap;
                    225:        register_t *retval;
                    226: {
                    227: 
                    228:        if (p->p_pgid == p->p_pid || pgfind(p->p_pid)) {
                    229:                return (EPERM);
                    230:        } else {
                    231:                (void)enterpgrp(p, p->p_pid, 1);
                    232:                *retval = p->p_pid;
                    233:                return (0);
                    234:        }
                    235: }
                    236: 
                    237: /*
                    238:  * set process group (setpgid/old setpgrp)
                    239:  *
                    240:  * caller does setpgid(targpid, targpgid)
                    241:  *
                    242:  * pid must be caller or child of caller (ESRCH)
                    243:  * if a child
                    244:  *     pid must be in same session (EPERM)
                    245:  *     pid can't have done an exec (EACCES)
                    246:  * if pgid != pid
                    247:  *     there must exist some pid in same session having pgid (EPERM)
                    248:  * pid must not be session leader (EPERM)
                    249:  */
                    250: struct setpgid_args {
                    251:        int     pid;
                    252:        int     pgid;
                    253: };
                    254: /* ARGSUSED */
                    255: setpgid(curp, uap, retval)
                    256:        struct proc *curp;
                    257:        register struct setpgid_args *uap;
                    258:        register_t *retval;
                    259: {
                    260:        register struct proc *targp;            /* target process */
                    261:        register struct pgrp *pgrp;             /* target pgrp */
                    262: 
                    263:        if (uap->pid != 0 && uap->pid != curp->p_pid) {
                    264:                if ((targp = pfind(uap->pid)) == 0 || !inferior(targp))
                    265:                        return (ESRCH);
                    266:                if (targp->p_session != curp->p_session)
                    267:                        return (EPERM);
                    268:                if (targp->p_flag & P_EXEC)
                    269:                        return (EACCES);
                    270:        } else
                    271:                targp = curp;
                    272:        if (SESS_LEADER(targp))
                    273:                return (EPERM);
                    274:        if (uap->pgid == 0)
                    275:                uap->pgid = targp->p_pid;
                    276:        else if (uap->pgid != targp->p_pid)
                    277:                if ((pgrp = pgfind(uap->pgid)) == 0 ||
                    278:                    pgrp->pg_session != curp->p_session)
                    279:                        return (EPERM);
                    280:        return (enterpgrp(targp, uap->pgid, 0));
                    281: }
                    282: 
                    283: struct setuid_args {
                    284:        uid_t   uid;
                    285: };
                    286: /* ARGSUSED */
                    287: setuid(p, uap, retval)
                    288:        struct proc *p;
                    289:        struct setuid_args *uap;
                    290:        register_t *retval;
                    291: {
                    292:        register struct pcred *pc = p->p_cred;
                    293:        register uid_t uid;
                    294:        int error;
                    295: 
                    296:        uid = uap->uid;
                    297:        if (uid != pc->p_ruid &&
                    298:            (error = suser(pc->pc_ucred, &p->p_acflag)))
                    299:                return (error);
                    300:        /*
                    301:         * Everything's okay, do it.
                    302:         * Transfer proc count to new user.
                    303:         * Copy credentials so other references do not see our changes.
                    304:         */
                    305:        pcred_writelock(p);
                    306:        (void)chgproccnt(pc->p_ruid, -1);
                    307:        (void)chgproccnt(uid, 1);
                    308:        pc->pc_ucred = crcopy(pc->pc_ucred);
                    309:        pc->pc_ucred->cr_uid = uid;
                    310:        pc->p_ruid = uid;
                    311:        pc->p_svuid = uid;
                    312:        pcred_unlock(p);
                    313:        p->p_flag |= P_SUGID;
                    314:        return (0);
                    315: }
                    316: 
                    317: struct seteuid_args {
                    318:        uid_t euid;
                    319: };
                    320: /* ARGSUSED */
                    321: seteuid(p, uap, retval)
                    322:        struct proc *p;
                    323:        struct seteuid_args *uap;
                    324:        register_t *retval;
                    325: {
                    326:        register struct pcred *pc = p->p_cred;
                    327:        register uid_t euid;
                    328:        int error;
                    329: 
                    330:        euid = uap->euid;
                    331:        if (euid != pc->p_ruid && euid != pc->p_svuid &&
                    332:            (error = suser(pc->pc_ucred, &p->p_acflag)))
                    333:                return (error);
                    334:        /*
                    335:         * Everything's okay, do it.  Copy credentials so other references do
                    336:         * not see our changes.
                    337:         */
                    338:        pcred_writelock(p);
                    339:        pc->pc_ucred = crcopy(pc->pc_ucred);
                    340:        pc->pc_ucred->cr_uid = euid;
                    341:        pcred_unlock(p);
                    342:        p->p_flag |= P_SUGID;
                    343:        return (0);
                    344: }
                    345: 
                    346: struct setgid_args {
                    347:        gid_t   gid;
                    348: };
                    349: /* ARGSUSED */
                    350: setgid(p, uap, retval)
                    351:        struct proc *p;
                    352:        struct setgid_args *uap;
                    353:        register_t *retval;
                    354: {
                    355:        register struct pcred *pc = p->p_cred;
                    356:        register gid_t gid;
                    357:        int error;
                    358: 
                    359:        gid = uap->gid;
                    360:        if (gid != pc->p_rgid && (error = suser(pc->pc_ucred, &p->p_acflag)))
                    361:                return (error);
                    362:        pcred_writelock(p);
                    363:        pc->pc_ucred = crcopy(pc->pc_ucred);
                    364:        pc->pc_ucred->cr_groups[0] = gid;
                    365:        pc->p_rgid = gid;
                    366:        pc->p_svgid = gid;              /* ??? */
                    367:        pcred_unlock(p);
                    368:        p->p_flag |= P_SUGID;
                    369:        return (0);
                    370: }
                    371: 
                    372: struct setegid_args {
                    373:        gid_t   egid;
                    374: };
                    375: /* ARGSUSED */
                    376: setegid(p, uap, retval)
                    377:        struct proc *p;
                    378:        struct setegid_args *uap;
                    379:        register_t *retval;
                    380: {
                    381:        register struct pcred *pc = p->p_cred;
                    382:        register gid_t egid;
                    383:        int error;
                    384: 
                    385:        egid = uap->egid;
                    386:        if (egid != pc->p_rgid && egid != pc->p_svgid &&
                    387:            (error = suser(pc->pc_ucred, &p->p_acflag)))
                    388:                return (error);
                    389:        pcred_writelock(p);
                    390:        pc->pc_ucred = crcopy(pc->pc_ucred);
                    391:        pc->pc_ucred->cr_groups[0] = egid;
                    392:        pcred_unlock(p);
                    393:        p->p_flag |= P_SUGID;
                    394:        return (0);
                    395: }
                    396: 
                    397: struct setgroups_args{
                    398:        u_int   gidsetsize;
                    399:        gid_t   *gidset;
                    400: };
                    401: 
                    402: /* ARGSUSED */
                    403: setgroups(p, uap, retval)
                    404:        struct proc *p;
                    405:        struct setgroups_args *uap;
                    406:        register_t *retval;
                    407: {
                    408:        register struct pcred *pc = p->p_cred;
                    409:        struct ucred *new, *old;
                    410:        register u_int ngrp;
                    411:        int error;
                    412: 
                    413:        if (error = suser(pc->pc_ucred, &p->p_acflag))
                    414:                return (error);
                    415:        ngrp = uap->gidsetsize;
                    416:        if (ngrp < 1 || ngrp > NGROUPS)
                    417:                return (EINVAL);
                    418:        new = crget();
                    419:        error = copyin((caddr_t)uap->gidset,
                    420:            (caddr_t)new->cr_groups, ngrp * sizeof(gid_t));
                    421:        if (error) {
                    422:                crfree(new);
                    423:                return (error);
                    424:        }
                    425:        new->cr_ngroups = ngrp;
                    426:        pcred_writelock(p);
                    427:        old = pc->pc_ucred;
                    428:        new->cr_uid = old->cr_uid;
                    429:        pc->pc_ucred = new;
                    430:        pcred_unlock(p);
                    431:        p->p_flag |= P_SUGID;
                    432:        if (old != NOCRED)
                    433:                crfree(old);
                    434:        return (0);
                    435: }
                    436: 
                    437: #if COMPAT_43
                    438: struct osetreuid_args{
                    439:        int     ruid;
                    440:        int     euid;
                    441: };
                    442: /* ARGSUSED */
                    443: osetreuid(p, uap, retval)
                    444:        register struct proc *p;
                    445:        struct osetreuid_args *uap;
                    446:        register_t *retval;
                    447: {
                    448:        struct seteuid_args seuidargs;
                    449:        struct setuid_args suidargs;
                    450: 
                    451:        /*
                    452:         * There are five cases, and we attempt to emulate them in
                    453:         * the following fashion:
                    454:         * -1, -1: return 0. This is correct emulation.
                    455:         * -1,  N: call seteuid(N). This is correct emulation.
                    456:         *  N, -1: if we called setuid(N), our euid would be changed
                    457:         *         to N as well. the theory is that we don't want to
                    458:         *         revoke root access yet, so we call seteuid(N)
                    459:         *         instead. This is incorrect emulation, but often
                    460:         *         suffices enough for binary compatibility.
                    461:         *  N,  N: call setuid(N). This is correct emulation.
                    462:         *  N,  M: call setuid(N). This is close to correct emulation.
                    463:         */
                    464:        if (uap->ruid == (uid_t)-1) {
                    465:                if (uap->euid == (uid_t)-1)
                    466:                        return (0);                             /* -1, -1 */
                    467:                seuidargs.euid = uap->euid;     /* -1,  N */
                    468:                return (seteuid(p, &seuidargs, retval));
                    469:        }
                    470:        if (uap->euid == (uid_t)-1) {
                    471:                seuidargs.euid = uap->ruid;     /* N, -1 */
                    472:                return (seteuid(p, &seuidargs, retval));
                    473:        }
                    474:        suidargs.uid = uap->ruid;       /* N, N and N, M */
                    475:        return (setuid(p, &suidargs, retval));
                    476: }
                    477: 
                    478: struct osetregid_args {
                    479:        int     rgid;
                    480:        int egid;
                    481: };
                    482: /* ARGSUSED */
                    483: osetregid(p, uap, retval)
                    484:        register struct proc *p;
                    485:        struct osetregid_args *uap;
                    486:        register_t *retval;
                    487: {
                    488:        struct setegid_args segidargs;
                    489:        struct setgid_args sgidargs;
                    490: 
                    491:        /*
                    492:         * There are five cases, described above in osetreuid()
                    493:         */
                    494:        if (uap->rgid == (gid_t)-1) {
                    495:                if (uap->egid == (gid_t)-1)
                    496:                        return (0);                             /* -1, -1 */
                    497:                segidargs.egid = uap->egid;     /* -1,  N */
                    498:                return (setegid(p, &segidargs, retval));
                    499:        }
                    500:        if (uap->egid == (gid_t)-1) {
                    501:                segidargs.egid = uap->rgid;     /* N, -1 */
                    502:                return (setegid(p, &segidargs, retval));
                    503:        }
                    504:        sgidargs.gid = uap->rgid;       /* N, N and N, M */
                    505:        return (setgid(p, &sgidargs, retval));
                    506: }
                    507: #endif /* COMPAT_43 */
                    508: 
                    509: /*
                    510:  * Check if gid is a member of the group set.
                    511:  */
                    512: groupmember(gid, cred)
                    513:        gid_t gid;
                    514:        register struct ucred *cred;
                    515: {
                    516:        register gid_t *gp;
                    517:        gid_t *egp;
                    518: 
                    519:        egp = &(cred->cr_groups[cred->cr_ngroups]);
                    520:        for (gp = cred->cr_groups; gp < egp; gp++)
                    521:                if (*gp == gid)
                    522:                        return (1);
                    523:        return (0);
                    524: }
                    525: 
                    526: /*
                    527:  * Test whether the specified credentials imply "super-user"
                    528:  * privilege; if so, and we have accounting info, set the flag
                    529:  * indicating use of super-powers.
                    530:  * Returns 0 or error.
                    531:  */
                    532: suser(cred, acflag)
                    533:        struct ucred *cred;
                    534:        u_short *acflag;
                    535: {
                    536: #if DIAGNOSTIC
                    537:        if (cred == NOCRED || cred == FSCRED)
                    538:                panic("suser");
                    539: #endif
                    540:        if (cred->cr_uid == 0) {
                    541:                if (acflag)
                    542:                        *acflag |= ASU;
                    543:                return (0);
                    544:        }
                    545:        return (EPERM);
                    546: }
                    547: 
                    548: int
                    549: is_suser(void)
                    550: {
                    551:        struct proc *p = current_thread()->task->proc;
                    552: 
                    553:        if (!p)
                    554:                return (0);
                    555: 
                    556:        return (suser(p->p_ucred, &p->p_acflag) == 0);
                    557: }
                    558: 
                    559: int
                    560: is_suser1(void)
                    561: {
                    562:        struct proc *p = current_thread()->task->proc;
                    563: 
                    564:        if (!p)
                    565:                return (0);
                    566: 
                    567:        return (suser(p->p_ucred, &p->p_acflag) == 0 ||
                    568:                        p->p_cred->p_ruid == 0 || p->p_cred->p_svuid == 0);
                    569: }
                    570: 
                    571: /*
                    572:  * Allocate a zeroed cred structure.
                    573:  */
                    574: struct ucred *
                    575: crget()
                    576: {
                    577:        register struct ucred *cr;
                    578: 
                    579:        MALLOC_ZONE(cr, struct ucred *, sizeof(*cr), M_CRED, M_WAITOK);
                    580:        bzero((caddr_t)cr, sizeof(*cr));
                    581:        cr->cr_ref = 1;
                    582:        return (cr);
                    583: }
                    584: 
                    585: /*
                    586:  * Free a cred structure.
                    587:  * Throws away space when ref count gets to 0.
                    588:  */
                    589: void
                    590: crfree(cr)
                    591:        struct ucred *cr;
                    592: {
                    593: #if DIAGNOSTIC
                    594:        if (cr == NOCRED || cr == FSCRED)
                    595:                panic("crfree");
                    596: #endif
                    597:        if (--cr->cr_ref == 0)
                    598:                FREE_ZONE((caddr_t)cr, sizeof *cr, M_CRED);
                    599: }
                    600: 
                    601: /*
                    602:  * Copy cred structure to a new one and free the old one.
                    603:  */
                    604: struct ucred *
                    605: crcopy(cr)
                    606:        struct ucred *cr;
                    607: {
                    608:        struct ucred *newcr;
                    609: 
                    610: #if DIAGNOSTIC
                    611:        if (cr == NOCRED || cr == FSCRED)
                    612:                panic("crcopy");
                    613: #endif
                    614:        if (cr->cr_ref == 1)
                    615:                return (cr);
                    616:        newcr = crget();
                    617:        *newcr = *cr;
                    618:        crfree(cr);
                    619:        newcr->cr_ref = 1;
                    620:        return (newcr);
                    621: }
                    622: 
                    623: /*
                    624:  * Dup cred struct to a new held one.
                    625:  */
                    626: struct ucred *
                    627: crdup(cr)
                    628:        struct ucred *cr;
                    629: {
                    630:        struct ucred *newcr;
                    631: 
                    632: #if DIAGNOSTIC
                    633:        if (cr == NOCRED || cr == FSCRED)
                    634:                panic("crdup");
                    635: #endif
                    636:        newcr = crget();
                    637:        *newcr = *cr;
                    638:        newcr->cr_ref = 1;
                    639:        return (newcr);
                    640: }
                    641: 
                    642: /*
                    643:  * Get login name, if available.
                    644:  */
                    645: struct getlogin_args {
                    646:        char    *namebuf;
                    647:        u_int   namelen;
                    648: };
                    649: /* ARGSUSED */
                    650: getlogin(p, uap, retval)
                    651:        struct proc *p;
                    652:        struct getlogin_args *uap;
                    653:        register_t *retval;
                    654: {
                    655: 
                    656:        if (uap->namelen > sizeof (p->p_pgrp->pg_session->s_login))
                    657:                uap->namelen = sizeof (p->p_pgrp->pg_session->s_login);
                    658:        return (copyout((caddr_t) p->p_pgrp->pg_session->s_login,
                    659:            (caddr_t)uap->namebuf, uap->namelen));
                    660: }
                    661: 
                    662: /*
                    663:  * Set login name.
                    664:  */
                    665: struct setlogin_args {
                    666:        char    *namebuf;
                    667: };
                    668: /* ARGSUSED */
                    669: setlogin(p, uap, retval)
                    670:        struct proc *p;
                    671:        struct setlogin_args *uap;
                    672:        register_t *retval;
                    673: {
                    674:        int error;
                    675: 
                    676:        if (error = suser(p->p_ucred, &p->p_acflag))
                    677:                return (error);
                    678:        error = copyinstr((caddr_t) uap->namebuf,
                    679:            (caddr_t) p->p_pgrp->pg_session->s_login,
                    680:            sizeof (p->p_pgrp->pg_session->s_login) - 1, (size_t *)0);
                    681:        if (error == ENAMETOOLONG)
                    682:                error = EINVAL;
                    683:        return (error);
                    684: }

unix.superglobalmegacorp.com

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