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

1.1       root        1: /*
                      2:  * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
                      3:  *
                      4:  * @APPLE_LICENSE_HEADER_START@
                      5:  * 
                      6:  * The contents of this file constitute Original Code as defined in and
                      7:  * are subject to the Apple Public Source License Version 1.1 (the
                      8:  * "License").  You may not use this file except in compliance with the
                      9:  * License.  Please obtain a copy of the License at
                     10:  * http://www.apple.com/publicsource and read it before using this file.
                     11:  * 
                     12:  * This Original Code and all software distributed under the License are
                     13:  * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
                     14:  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
                     15:  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
                     16:  * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
                     17:  * License for the specific language governing rights and limitations
                     18:  * under the License.
                     19:  * 
                     20:  * @APPLE_LICENSE_HEADER_END@
                     21:  */
                     22: /* Copyright (c) 1995 NeXT Computer, Inc. All Rights Reserved */
                     23: /*
                     24:  * Copyright (c) 1982, 1986, 1989, 1990, 1991, 1993
                     25:  *     The Regents of the University of California.  All rights reserved.
                     26:  * (c) UNIX System Laboratories, Inc.
                     27:  * All or some portions of this file are derived from material licensed
                     28:  * to the University of California by American Telephone and Telegraph
                     29:  * Co. or Unix System Laboratories, Inc. and are reproduced herein with
                     30:  * the permission of UNIX System Laboratories, Inc.
                     31:  *
                     32:  * Redistribution and use in source and binary forms, with or without
                     33:  * modification, are permitted provided that the following conditions
                     34:  * are met:
                     35:  * 1. Redistributions of source code must retain the above copyright
                     36:  *    notice, this list of conditions and the following disclaimer.
                     37:  * 2. Redistributions in binary form must reproduce the above copyright
                     38:  *    notice, this list of conditions and the following disclaimer in the
                     39:  *    documentation and/or other materials provided with the distribution.
                     40:  * 3. All advertising materials mentioning features or use of this software
                     41:  *    must display the following acknowledgement:
                     42:  *     This product includes software developed by the University of
                     43:  *     California, Berkeley and its contributors.
                     44:  * 4. Neither the name of the University nor the names of its contributors
                     45:  *    may be used to endorse or promote products derived from this software
                     46:  *    without specific prior written permission.
                     47:  *
                     48:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
                     49:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
                     50:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
                     51:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
                     52:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
                     53:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
                     54:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     55:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
                     56:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
                     57:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
                     58:  * SUCH DAMAGE.
                     59:  *
                     60:  *     @(#)kern_prot.c 8.9 (Berkeley) 2/14/95
                     61:  */
                     62: 
                     63: /*
                     64:  * System calls related to processes and protection
                     65:  */
                     66: 
                     67: #include <sys/param.h>
                     68: #include <sys/acct.h>
                     69: #include <sys/systm.h>
                     70: #include <sys/ucred.h>
                     71: #include <sys/proc.h>
                     72: #include <sys/timeb.h>
                     73: #include <sys/times.h>
                     74: #include <sys/malloc.h>
                     75: 
                     76: #include <sys/mount.h>
                     77: #include <mach/message.h>
                     78: 
                     79: 
                     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:        set_security_token(p);
                    314:        p->p_flag |= P_SUGID;
                    315:        return (0);
                    316: }
                    317: 
                    318: struct seteuid_args {
                    319:        uid_t euid;
                    320: };
                    321: /* ARGSUSED */
                    322: seteuid(p, uap, retval)
                    323:        struct proc *p;
                    324:        struct seteuid_args *uap;
                    325:        register_t *retval;
                    326: {
                    327:        register struct pcred *pc = p->p_cred;
                    328:        register uid_t euid;
                    329:        int error;
                    330: 
                    331:        euid = uap->euid;
                    332:        if (euid != pc->p_ruid && euid != pc->p_svuid &&
                    333:            (error = suser(pc->pc_ucred, &p->p_acflag)))
                    334:                return (error);
                    335:        /*
                    336:         * Everything's okay, do it.  Copy credentials so other references do
                    337:         * not see our changes.
                    338:         */
                    339:        pcred_writelock(p);
                    340:        pc->pc_ucred = crcopy(pc->pc_ucred);
                    341:        pc->pc_ucred->cr_uid = euid;
                    342:        pcred_unlock(p);
                    343:        set_security_token(p);
                    344:        p->p_flag |= P_SUGID;
                    345:        return (0);
                    346: }
                    347: 
                    348: struct setgid_args {
                    349:        gid_t   gid;
                    350: };
                    351: /* ARGSUSED */
                    352: setgid(p, uap, retval)
                    353:        struct proc *p;
                    354:        struct setgid_args *uap;
                    355:        register_t *retval;
                    356: {
                    357:        register struct pcred *pc = p->p_cred;
                    358:        register gid_t gid;
                    359:        int error;
                    360: 
                    361:        gid = uap->gid;
                    362:        if (gid != pc->p_rgid && (error = suser(pc->pc_ucred, &p->p_acflag)))
                    363:                return (error);
                    364:        pcred_writelock(p);
                    365:        pc->pc_ucred = crcopy(pc->pc_ucred);
                    366:        pc->pc_ucred->cr_groups[0] = gid;
                    367:        pc->p_rgid = gid;
                    368:        pc->p_svgid = gid;              /* ??? */
                    369:        pcred_unlock(p);
                    370:        set_security_token(p);
                    371:        p->p_flag |= P_SUGID;
                    372:        return (0);
                    373: }
                    374: 
                    375: struct setegid_args {
                    376:        gid_t   egid;
                    377: };
                    378: /* ARGSUSED */
                    379: setegid(p, uap, retval)
                    380:        struct proc *p;
                    381:        struct setegid_args *uap;
                    382:        register_t *retval;
                    383: {
                    384:        register struct pcred *pc = p->p_cred;
                    385:        register gid_t egid;
                    386:        int error;
                    387: 
                    388:        egid = uap->egid;
                    389:        if (egid != pc->p_rgid && egid != pc->p_svgid &&
                    390:            (error = suser(pc->pc_ucred, &p->p_acflag)))
                    391:                return (error);
                    392:        pcred_writelock(p);
                    393:        pc->pc_ucred = crcopy(pc->pc_ucred);
                    394:        pc->pc_ucred->cr_groups[0] = egid;
                    395:        pcred_unlock(p);
                    396:        set_security_token(p);
                    397:        p->p_flag |= P_SUGID;
                    398:        return (0);
                    399: }
                    400: 
                    401: struct setgroups_args{
                    402:        u_int   gidsetsize;
                    403:        gid_t   *gidset;
                    404: };
                    405: 
                    406: /* ARGSUSED */
                    407: setgroups(p, uap, retval)
                    408:        struct proc *p;
                    409:        struct setgroups_args *uap;
                    410:        register_t *retval;
                    411: {
                    412:        register struct pcred *pc = p->p_cred;
                    413:        struct ucred *new, *old;
                    414:        register u_int ngrp;
                    415:        int error;
                    416: 
                    417:        if (error = suser(pc->pc_ucred, &p->p_acflag))
                    418:                return (error);
                    419:        ngrp = uap->gidsetsize;
                    420:        if (ngrp < 1 || ngrp > NGROUPS)
                    421:                return (EINVAL);
                    422:        new = crget();
                    423:        error = copyin((caddr_t)uap->gidset,
                    424:            (caddr_t)new->cr_groups, ngrp * sizeof(gid_t));
                    425:        if (error) {
                    426:                crfree(new);
                    427:                return (error);
                    428:        }
                    429:        new->cr_ngroups = ngrp;
                    430:        pcred_writelock(p);
                    431:        old = pc->pc_ucred;
                    432:        new->cr_uid = old->cr_uid;
                    433:        pc->pc_ucred = new;
                    434:        pcred_unlock(p);
                    435:        set_security_token(p);
                    436:        p->p_flag |= P_SUGID;
                    437:        if (old != NOCRED)
                    438:                crfree(old);
                    439:        return (0);
                    440: }
                    441: 
                    442: #if COMPAT_43
                    443: struct osetreuid_args{
                    444:        int     ruid;
                    445:        int     euid;
                    446: };
                    447: /* ARGSUSED */
                    448: osetreuid(p, uap, retval)
                    449:        register struct proc *p;
                    450:        struct osetreuid_args *uap;
                    451:        register_t *retval;
                    452: {
                    453:        struct seteuid_args seuidargs;
                    454:        struct setuid_args suidargs;
                    455: 
                    456:        /*
                    457:         * There are five cases, and we attempt to emulate them in
                    458:         * the following fashion:
                    459:         * -1, -1: return 0. This is correct emulation.
                    460:         * -1,  N: call seteuid(N). This is correct emulation.
                    461:         *  N, -1: if we called setuid(N), our euid would be changed
                    462:         *         to N as well. the theory is that we don't want to
                    463:         *         revoke root access yet, so we call seteuid(N)
                    464:         *         instead. This is incorrect emulation, but often
                    465:         *         suffices enough for binary compatibility.
                    466:         *  N,  N: call setuid(N). This is correct emulation.
                    467:         *  N,  M: call setuid(N). This is close to correct emulation.
                    468:         */
                    469:        if (uap->ruid == (uid_t)-1) {
                    470:                if (uap->euid == (uid_t)-1)
                    471:                        return (0);                             /* -1, -1 */
                    472:                seuidargs.euid = uap->euid;     /* -1,  N */
                    473:                return (seteuid(p, &seuidargs, retval));
                    474:        }
                    475:        if (uap->euid == (uid_t)-1) {
                    476:                seuidargs.euid = uap->ruid;     /* N, -1 */
                    477:                return (seteuid(p, &seuidargs, retval));
                    478:        }
                    479:        suidargs.uid = uap->ruid;       /* N, N and N, M */
                    480:        return (setuid(p, &suidargs, retval));
                    481: }
                    482: 
                    483: struct osetregid_args {
                    484:        int     rgid;
                    485:        int egid;
                    486: };
                    487: /* ARGSUSED */
                    488: osetregid(p, uap, retval)
                    489:        register struct proc *p;
                    490:        struct osetregid_args *uap;
                    491:        register_t *retval;
                    492: {
                    493:        struct setegid_args segidargs;
                    494:        struct setgid_args sgidargs;
                    495: 
                    496:        /*
                    497:         * There are five cases, described above in osetreuid()
                    498:         */
                    499:        if (uap->rgid == (gid_t)-1) {
                    500:                if (uap->egid == (gid_t)-1)
                    501:                        return (0);                             /* -1, -1 */
                    502:                segidargs.egid = uap->egid;     /* -1,  N */
                    503:                return (setegid(p, &segidargs, retval));
                    504:        }
                    505:        if (uap->egid == (gid_t)-1) {
                    506:                segidargs.egid = uap->rgid;     /* N, -1 */
                    507:                return (setegid(p, &segidargs, retval));
                    508:        }
                    509:        sgidargs.gid = uap->rgid;       /* N, N and N, M */
                    510:        return (setgid(p, &sgidargs, retval));
                    511: }
                    512: #endif /* COMPAT_43 */
                    513: 
                    514: /*
                    515:  * Check if gid is a member of the group set.
                    516:  */
                    517: groupmember(gid, cred)
                    518:        gid_t gid;
                    519:        register struct ucred *cred;
                    520: {
                    521:        register gid_t *gp;
                    522:        gid_t *egp;
                    523: 
                    524:        egp = &(cred->cr_groups[cred->cr_ngroups]);
                    525:        for (gp = cred->cr_groups; gp < egp; gp++)
                    526:                if (*gp == gid)
                    527:                        return (1);
                    528:        return (0);
                    529: }
                    530: 
                    531: /*
                    532:  * Test whether the specified credentials imply "super-user"
                    533:  * privilege; if so, and we have accounting info, set the flag
                    534:  * indicating use of super-powers.
                    535:  * Returns 0 or error.
                    536:  */
                    537: suser(cred, acflag)
                    538:        struct ucred *cred;
                    539:        u_short *acflag;
                    540: {
                    541: #if DIAGNOSTIC
                    542:        if (cred == NOCRED || cred == FSCRED)
                    543:                panic("suser");
                    544: #endif
                    545:        if (cred->cr_uid == 0) {
                    546:                if (acflag)
                    547:                        *acflag |= ASU;
                    548:                return (0);
                    549:        }
                    550:        return (EPERM);
                    551: }
                    552: 
                    553: int
                    554: is_suser(void)
                    555: {
                    556:        struct proc *p = current_proc();
                    557: 
                    558:        if (!p)
                    559:                return (0);
                    560: 
                    561:        return (suser(p->p_ucred, &p->p_acflag) == 0);
                    562: }
                    563: 
                    564: int
                    565: is_suser1(void)
                    566: {
                    567:        struct proc *p = current_proc();
                    568: 
                    569:        if (!p)
                    570:                return (0);
                    571: 
                    572:        return (suser(p->p_ucred, &p->p_acflag) == 0 ||
                    573:                        p->p_cred->p_ruid == 0 || p->p_cred->p_svuid == 0);
                    574: }
                    575: 
                    576: /*
                    577:  * Allocate a zeroed cred structure.
                    578:  */
                    579: struct ucred *
                    580: crget()
                    581: {
                    582:        register struct ucred *cr;
                    583: 
                    584:        MALLOC_ZONE(cr, struct ucred *, sizeof(*cr), M_CRED, M_WAITOK);
                    585:        bzero((caddr_t)cr, sizeof(*cr));
                    586:        cr->cr_ref = 1;
                    587:        return (cr);
                    588: }
                    589: 
                    590: /*
                    591:  * Free a cred structure.
                    592:  * Throws away space when ref count gets to 0.
                    593:  */
                    594: void
                    595: crfree(cr)
                    596:        struct ucred *cr;
                    597: {
                    598: #if DIAGNOSTIC
                    599:        if (cr == NOCRED || cr == FSCRED)
                    600:                panic("crfree");
                    601: #endif
                    602:        if (--cr->cr_ref == 0)
                    603:                FREE_ZONE((caddr_t)cr, sizeof *cr, M_CRED);
                    604: }
                    605: 
                    606: /*
                    607:  * Copy cred structure to a new one and free the old one.
                    608:  */
                    609: struct ucred *
                    610: crcopy(cr)
                    611:        struct ucred *cr;
                    612: {
                    613:        struct ucred *newcr;
                    614: 
                    615: #if DIAGNOSTIC
                    616:        if (cr == NOCRED || cr == FSCRED)
                    617:                panic("crcopy");
                    618: #endif
                    619:        if (cr->cr_ref == 1)
                    620:                return (cr);
                    621:        newcr = crget();
                    622:        *newcr = *cr;
                    623:        crfree(cr);
                    624:        newcr->cr_ref = 1;
                    625:        return (newcr);
                    626: }
                    627: 
                    628: /*
                    629:  * Dup cred struct to a new held one.
                    630:  */
                    631: struct ucred *
                    632: crdup(cr)
                    633:        struct ucred *cr;
                    634: {
                    635:        struct ucred *newcr;
                    636: 
                    637: #if DIAGNOSTIC
                    638:        if (cr == NOCRED || cr == FSCRED)
                    639:                panic("crdup");
                    640: #endif
                    641:        newcr = crget();
                    642:        *newcr = *cr;
                    643:        newcr->cr_ref = 1;
                    644:        return (newcr);
                    645: }
                    646: 
                    647: /*
                    648:  * Get login name, if available.
                    649:  */
                    650: struct getlogin_args {
                    651:        char    *namebuf;
                    652:        u_int   namelen;
                    653: };
                    654: /* ARGSUSED */
                    655: getlogin(p, uap, retval)
                    656:        struct proc *p;
                    657:        struct getlogin_args *uap;
                    658:        register_t *retval;
                    659: {
                    660: 
                    661:        if (uap->namelen > sizeof (p->p_pgrp->pg_session->s_login))
                    662:                uap->namelen = sizeof (p->p_pgrp->pg_session->s_login);
                    663:        return (copyout((caddr_t) p->p_pgrp->pg_session->s_login,
                    664:            (caddr_t)uap->namebuf, uap->namelen));
                    665: }
                    666: 
                    667: /*
                    668:  * Set login name.
                    669:  */
                    670: struct setlogin_args {
                    671:        char    *namebuf;
                    672: };
                    673: /* ARGSUSED */
                    674: setlogin(p, uap, retval)
                    675:        struct proc *p;
                    676:        struct setlogin_args *uap;
                    677:        register_t *retval;
                    678: {
                    679:        int error;
                    680:        int dummy=0;
                    681: 
                    682:        if (error = suser(p->p_ucred, &p->p_acflag))
                    683:                return (error);
                    684:        error = copyinstr((caddr_t) uap->namebuf,
                    685:            (caddr_t) p->p_pgrp->pg_session->s_login,
                    686:            sizeof (p->p_pgrp->pg_session->s_login) - 1, (size_t *)&dummy);
                    687:        if (error == ENAMETOOLONG)
                    688:                error = EINVAL;
                    689:        return (error);
                    690: }
                    691: 
                    692: 
                    693: /* Set the secrity token of the task with current euid and eguid */
                    694: void
                    695: set_security_token(struct proc * p)
                    696: {
                    697: #define BSD_DUMMY_HOST 1
                    698:        security_token_t sec_token;
                    699: 
                    700:        sec_token.val[0] = p->p_ucred->cr_uid;
                    701:        sec_token.val[1] = p->p_ucred->cr_gid;
                    702:        (void)host_security_set_task_token(BSD_DUMMY_HOST, p->task, sec_token);
                    703: }

unix.superglobalmegacorp.com

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